Пример #1
0
int	get_value_ssh(DC_ITEM *item, AGENT_RESULT *result)
{
	char	cmd[MAX_STRING_LEN], params[MAX_STRING_LEN], dns[INTERFACE_DNS_LEN_MAX],
		port[8], encoding[32];

	if (ZBX_COMMAND_ERROR == parse_command(item->key, cmd, sizeof(cmd), params, sizeof(params)))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
		return NOTSUPPORTED;
	}

	if (0 != strcmp(SSH_RUN_KEY, cmd))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported item key for this item type."));
		return NOTSUPPORTED;
	}

	if (4 < num_param(params))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		return NOTSUPPORTED;
	}

	if (0 != get_param(params, 2, dns, sizeof(dns)))
		*dns = '\0';

	if ('\0' != *dns)
	{
		strscpy(item->interface.dns_orig, dns);
		item->interface.addr = item->interface.dns_orig;
	}

	if (0 != get_param(params, 3, port, sizeof(port)))
		*port = '\0';

	if (0 != get_param(params, 4, encoding, sizeof(encoding)))
		*encoding = '\0';

	if ('\0' != *port)
	{
		if (FAIL == is_ushort(port, &item->interface.port))
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
			return NOTSUPPORTED;
		}
	}
	else
		item->interface.port = ZBX_DEFAULT_SSH_PORT;

	return ssh_run(item, result, encoding);
}
Пример #2
0
int	get_value_ssh(DC_ITEM *item, AGENT_RESULT *result)
{
	AGENT_REQUEST	request;
	int		ret = NOTSUPPORTED;
	const char	*port, *encoding, *dns;

	init_request(&request);

	if (SUCCEED != parse_item_key(item->key, &request))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format."));
		goto out;
	}

	if (0 != strcmp(SSH_RUN_KEY, get_rkey(&request)))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported item key for this item type."));
		goto out;
	}

	if (4 < get_rparams_num(&request))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		goto out;
	}

	if (NULL != (dns = get_rparam(&request, 1)) && '\0' != *dns)
	{
		strscpy(item->interface.dns_orig, dns);
		item->interface.addr = item->interface.dns_orig;
	}

	if (NULL != (port = get_rparam(&request, 2)) && '\0' != *port)
	{
		if (FAIL == is_ushort(port, &item->interface.port))
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
			goto out;
		}
	}
	else
		item->interface.port = ZBX_DEFAULT_SSH_PORT;

	encoding = get_rparam(&request, 3);

	ret = ssh_run(item, result, ZBX_NULL2EMPTY_STR(encoding));
out:
	free_request(&request);

	return ret;
}
Пример #3
0
int	get_value_ssh(DC_ITEM *item, AGENT_RESULT *result)
{
	char	cmd[MAX_STRING_LEN], params[MAX_STRING_LEN], dns[INTERFACE_DNS_LEN_MAX],
		port[8], encoding[32];

	if (0 == parse_command(item->key, cmd, sizeof(cmd), params, sizeof(params)))
		return NOTSUPPORTED;

	if (0 != strcmp(SSH_RUN_KEY, cmd))
		return NOTSUPPORTED;

	if (num_param(params) > 4)
		return NOTSUPPORTED;

	if (0 != get_param(params, 2, dns, sizeof(dns)))
		*dns = '\0';

	if ('\0' != *dns)
	{
		strscpy(item->interface.dns_orig, dns);
		item->interface.addr = item->interface.dns_orig;
	}

	if (0 != get_param(params, 3, port, sizeof(port)))
		*port = '\0';

	if (0 != get_param(params, 4, encoding, sizeof(encoding)))
		*encoding = '\0';

	if ('\0' != *port)
	{
		if (FAIL == is_ushort(port, &item->interface.port))
			return NOTSUPPORTED;
	}
	else
		item->interface.port = ZBX_DEFAULT_SSH_PORT;

	return ssh_run(item, result, encoding);
}
Пример #4
0
int
main(int argc, char **argv)
{
	int	i;
	int	n;
	int	ch;
	char	*s;
	int	wp, rp, ep = 0;
	char	wmbuf[256], rmbuf[256];
	FILE	*pid_file;

	int	sock = -1;
	int	done_fwds = 0;
	int	runasdaemon = 0;
	int	sawargstop = 0;
#if defined(__CYGWIN__)
	int	sawoptionn = 0;
#endif

#ifndef HAVE___PROGNAME
	__progname = "autossh";
#endif	

	/* 
	 * set up options from environment
	 */
	get_env_args();

	/*
	 * We accept all ssh args, and quietly pass them on
	 * to ssh when we call it.
	 */
	while ((ch = getopt(argc, argv, OPTION_STRING)) != -1) {
		switch(ch) {
		case 'M':
			if (!env_port)
				writep = optarg;
			break;
		case 'V':
			fprintf(stdout, "%s %s\n", __progname, VER);
			exit(0);
			break;
		case 'f':
			runasdaemon = 1;
			break;
#if defined(__CYGWIN__)
		case 'N':
			sawoptionn = 1;
			break;
#endif
		case '?':
			usage(1);
			break;
		default:
			/* other options get passed to ssh */
			break;
		}
	}

	/* if we got it from the environment */
	if (env_port)
		writep = env_port;

	/*
	 * We must at least have a monitor port and a remote host.
	 */
	if (env_port) { 
		if (argc < 2)
			usage(1);
	} else if (!writep || argc < 4)
		usage(1);

	if (logtype & L_SYSLOG)
		openlog(__progname, LOG_PID|syslog_perror, LOG_USER);

	/*
	 * Check for echo port
	 */
	if ((s = strchr(writep, ':')) != NULL) {
		*s = '\0';
		echop = s + 1;
		ep = strtoul(echop, &s, 0);
		if (*echop == '\0' || *s != '\0' || ep == 0)
			xerrlog(LOG_ERR, "invalid echo port  \"%s\"", echop);
	}

	/* 
	 * Check, and get the read port (write port + 1);
	 * then construct port-forwarding arguments for ssh.
	 */
	wp = strtoul(writep, &s, 0);
	if (*writep == '\0' || *s != '\0')
		xerrlog(LOG_ERR, "invalid port \"%s\"", writep);
	if (wp == 0) {
		errlog(LOG_INFO, "port set to 0, monitoring disabled");
		writep = NULL;
	}
	else if (wp > 65534 || wp < 0)
		xerrlog(LOG_ERR, "monitor port (%d) out of range", wp);
	else {
		rp = wp+1;
		/* all this for solaris; we could use asprintf() */
		(void)snprintf(readp, sizeof(readp), "%d", rp);

		/* port-forward arg strings */
		n = snprintf(wmbuf, sizeof(wmbuf), "%d:%s:%d", wp, mhost, 
		        echop ? ep : wp);
		if (n > sizeof(wmbuf))
			xerrlog(LOG_ERR, 
			    "overflow building forwarding string");
		if (!echop) {
			n = snprintf(rmbuf, sizeof(rmbuf), "%d:%s:%d", 
			        wp, mhost, rp);
			if (n > sizeof(rmbuf))
				xerrlog(LOG_ERR, 
				    "overflow building forwarding string");
		}
	}

	/* 
	 * Adjust timeouts if necessary: net_timeout is first
	 * the timeout for accept and then for io, so if the 
	 * poll_time is set less than 2 timeouts, the timeouts need 
	 * to be adjusted to be at least 1/2. Perhaps there should be
	 * be some padding here as well....
	 */
	if ((poll_time * 1000) / 2 < net_timeout) {
		net_timeout = (poll_time * 1000) / 2;
		errlog(LOG_INFO,
		    "short poll time: adjusting net timeouts to %d",
		    net_timeout);
	}

	/*
	 * Build a new arg list, skipping -f, -M and inserting 
	 * port forwards.
	 */
	add_arg(ssh_path);

#if defined(__CYGWIN__)
	if (ntservice && !sawoptionn)
		add_arg("-N");
#endif

	for (i = 1; i < argc; i++) {
		/* 
		 * We step past the first '--', taking it as ours
		 * (autossh's). Any further ones we pass to ssh.
		 */
		if (argv[i][0] == '-' && argv[i][1] == '-') {
			if (!sawargstop) {
				sawargstop = 1;
				continue;
			}
		}
 		if (wp && env_port && !done_fwds) {
			add_arg("-L");
			add_arg(wmbuf);
			if (!echop) {
				add_arg("-R");
				add_arg(rmbuf);
			}
			done_fwds = 1;
		} else if (!sawargstop && argv[i][0] == '-' && argv[i][1] == 'M') {
			if (argv[i][2] == '\0')
				i++;
			if (wp && !done_fwds) {
				add_arg("-L");
				add_arg(wmbuf);
				if (!echop) {
					add_arg("-R");
					add_arg(rmbuf);
				}
				done_fwds = 1;
			}
			continue;
		}
		/* look for -f in option args and strip out */
		strip_arg(argv[i], 'f', OPTION_STRING);
		add_arg(argv[i]);
	}

	if (runasdaemon) {
		if (daemon(0, 0) == -1) {
			xerrlog(LOG_ERR, "run as daemon failed: %s", 
			    strerror(errno));
		}
		/* 
		 * If running as daemon, the user likely wants it
		 * to just run and not fail early (perhaps machines
		 * are coming up, etc.)
		 */ 
		gate_time = 0;
	}

	/* 
	 * Only if we're doing the network monitor thing.
	 * Socket once opened stays open for listening for 
	 * the duration of the program.
	 */
	if (writep) {
		if (!echop) {
			sock = conn_listen(mhost, readp);
			/* set close-on-exec */
			(void)fcntl(sock, F_SETFD, FD_CLOEXEC);
		} else
			sock = NO_RD_SOCK;
	}

	if (pid_file_name) {
		pid_file = fopen(pid_file_name, "w");
		if (!pid_file) {
			xerrlog(LOG_ERR, "cannot open pid file \"%s\": %s",
			    pid_file_name, strerror(errno));
		}
		pid_file_created = 1;
		atexit(unlink_pid_file);
		if (fprintf(pid_file, "%d\n", (int)getpid()) == 0)
			xerrlog(LOG_ERR, "write failed to pid file \"%s\": %s",
			    pid_file_name, strerror(errno));
		fflush(pid_file);
		fclose(pid_file);
	}

	ssh_run(sock, newav);

	if (sock >= 0) {
		shutdown(sock, SHUT_RDWR);
		close(sock);
	}

	if (logtype & L_SYSLOG)
		closelog();

	exit(0);
}