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); }
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; }
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); }
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); }