1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
static struct ssh * ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) { struct ssh *ssh; char *command_string, *tmp; int pin[2], pout[2]; pid_t pid; char *shell, strport[NI_MAXSERV];
if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL;
snprintf(strport, sizeof strport, "%hu", port);
xasprintf(&tmp, "exec %s", proxy_command); command_string = percent_expand(tmp, "h", host, "p", strport, "r", options.user, (char *)NULL); xfree(tmp);
if (pipe(pin) < 0 || pipe(pout) < 0) fatal("Could not create pipes to communicate with the proxy: %.100s", strerror(errno));
debug("Executing proxy command: %.500s", command_string);
if ((pid = fork()) == 0) { char *argv[10];
permanently_drop_suid(original_real_uid);
close(pin[1]); if (pin[0] != 0) { if (dup2(pin[0], 0) < 0) perror("dup2 stdin"); close(pin[0]); } close(pout[0]); if (dup2(pout[1], 1) < 0) perror("dup2 stdout"); close(pout[1]);
argv[0] = shell; argv[1] = "-c"; argv[2] = command_string; argv[3] = NULL;
signal(SIGPIPE, SIG_DFL); execv(argv[0], argv); perror(argv[0]); exit(1); } if (pid < 0) fatal("fork failed: %.100s", strerror(errno)); else proxy_command_pid = pid;
close(pin[0]); close(pout[1]);
xfree(command_string);
ssh = ssh_packet_set_connection(NULL, pout[0], pin[1]); ssh_packet_set_timeout(ssh, options.server_alive_interval, options.server_alive_count_max);
return (ssh); }
|