Exemplo n.º 1
0
/*
 * Connect to the given ssh server using a proxy command.
 */
static int
ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
{
  /*
   * Win32 code.
   */

  #ifdef WIN32_FIXME
  
    PROCESS_INFORMATION pi = {0};
  
    STARTUPINFO si = {0};
    
    char *fullCmd = NULL;

    char strport[NI_MAXSERV] = {0};
    
    int sockin[2]  = {-1, -1};
    int sockout[2] = {-1, -1};
    
    int exitCode = -1;
  
    /*
     * Create command to execute as proxy.
     */

    debug("Creating proxy command...");
    
    snprintf(strport, sizeof strport, "%hu", port);
    
    fullCmd = percent_expand(proxy_command, "h", host, 
                                 "p", strport, (char *) NULL);
                                 
    FAIL(fullCmd == NULL);                             

    /*
     * Create socket pairs for stdin and stdout.
     */

    debug("Creating socket pairs for proxy process...");

    socketpair(sockin);
    socketpair(sockout);
    
    debug("sockin[0]: %d sockin[1]: %d", sockin[0], sockin[1]);
    debug("sockout[0]: %d sockout[1]: %d", sockout[0], sockout[1]);

    permanently_drop_suid(original_real_uid);
    
    /*
     * Assign sockets to StartupInfo
     */

    si.cb          = sizeof(STARTUPINFO);
    si.hStdInput   = (HANDLE) sfd_to_handle(sockin[0]);
    si.hStdOutput  = (HANDLE) sfd_to_handle(sockout[0]);
    si.hStdError   = GetStdHandle(STD_ERROR_HANDLE);
    si.wShowWindow = SW_HIDE;
    si.dwFlags     = STARTF_USESTDHANDLES;
    si.lpDesktop   = NULL;

    /*               
     * Create proxy process with given stdout/stdin.
     */
    
    debug("Executing proxy command: \"%.500s\"...\n", fullCmd);

    FAIL(CreateProcess(NULL, fullCmd, NULL, NULL, TRUE, 
                           CREATE_NEW_PROCESS_GROUP, NULL, 
                               NULL, &si, &pi) == FALSE);

    proxy_command_handle = pi.hProcess;
    proxy_command_pid    = pi.dwProcessId;
    
    /*
     * Redirect network in/out to proxy sockets.
     */
    
    packet_set_connection(sockout[1], sockin[1]);

    
    exitCode = 0;
   
    fail:
  
    /*
     / Clean up.
     */

    close(sockout[0]);
    close(sockin[0]);

    CloseHandle(pi.hThread);
    
    free(fullCmd);
    
    /*
     * Error handler.
     */
    
    if (exitCode)
    {
      debug("Error cannot create proxy process (%u).\n", (unsigned int) GetLastError());
      
      close(sockout[1]);
      close(sockin[1]);
      
      CloseHandle(pi.hProcess);
    }
 
    return exitCode;

  #else

  /*
   * Original OpenSSH code.
   */
	char *command_string;
	int pin[2], pout[2];
	pid_t pid;
	char *shell;

	if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
		shell = _PATH_BSHELL;

	/* Create pipes for communicating with the proxy. */
	if (pipe(pin) < 0 || pipe(pout) < 0)
		fatal("Could not create pipes to communicate with the proxy: %.100s",
		    strerror(errno));

	command_string = expand_proxy_command(proxy_command, options.user,
	    host, port);
	debug("Executing proxy command: %.500s", command_string);

	/* Fork and execute the proxy command. */
	if ((pid = fork()) == 0) {
		char *argv[10];

		/* Child.  Permanently give up superuser privileges. */
		permanently_drop_suid(original_real_uid);

		/* Redirect stdin and stdout. */
		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");
		/* Cannot be 1 because pin allocated two descriptors. */
		close(pout[1]);

		/* Stderr is left as it is so that error messages get
		   printed on the user's terminal. */
		argv[0] = shell;
		argv[1] = "-c";
		argv[2] = command_string;
		argv[3] = NULL;

		/* Execute the proxy command.  Note that we gave up any
		   extra privileges above. */
		signal(SIGPIPE, SIG_DFL);
		execv(argv[0], argv);
		perror(argv[0]);
		exit(1);
	}
	/* Parent. */
	if (pid < 0)
		fatal("fork failed: %.100s", strerror(errno));
	else
		proxy_command_pid = pid; /* save pid to clean up later */

	/* Close child side of the descriptors. */
	close(pin[0]);
	close(pout[1]);

	/* Free the command name. */
	free(command_string);

	/* Set the connection file descriptors. */
	packet_set_connection(pout[0], pin[1]);

	/* Indicate OK return */
	return 0;
#endif /* else WIN32_FIXME */
}
Exemplo n.º 2
0
/*
 * Connect to the given ssh server using a proxy command that passes a
 * a connected fd back to us.
 */
static int
ssh_proxy_fdpass_connect(const char *host, u_short port,
    const char *proxy_command)
{
#ifdef WIN32_FIXME
//PRAGMA:TODO
	return 0;
#else
	
	char *command_string;
	int sp[2], sock;
	pid_t pid;
	char *shell;

	if ((shell = getenv("SHELL")) == NULL)
		shell = _PATH_BSHELL;

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0)
		fatal("Could not create socketpair to communicate with "
		    "proxy dialer: %.100s", strerror(errno));

	command_string = expand_proxy_command(proxy_command, options.user,
	    host, port);
	debug("Executing proxy dialer command: %.500s", command_string);

	/* Fork and execute the proxy command. */
	if ((pid = fork()) == 0) {
		char *argv[10];

		/* Child.  Permanently give up superuser privileges. */
		permanently_drop_suid(original_real_uid);

		close(sp[1]);
		/* Redirect stdin and stdout. */
		if (sp[0] != 0) {
			if (dup2(sp[0], 0) < 0)
				perror("dup2 stdin");
		}
		if (sp[0] != 1) {
			if (dup2(sp[0], 1) < 0)
				perror("dup2 stdout");
		}
		if (sp[0] >= 2)
			close(sp[0]);

		/*
		 * Stderr is left as it is so that error messages get
		 * printed on the user's terminal.
		 */
		argv[0] = shell;
		argv[1] = "-c";
		argv[2] = command_string;
		argv[3] = NULL;

		/*
		 * Execute the proxy command.
		 * Note that we gave up any extra privileges above.
		 */
		execv(argv[0], argv);
		perror(argv[0]);
		exit(1);
	}
	/* Parent. */
	if (pid < 0)
		fatal("fork failed: %.100s", strerror(errno));
	close(sp[0]);
	free(command_string);

	if ((sock = mm_receive_fd(sp[1])) == -1)
		fatal("proxy dialer did not pass back a connection");

	while (waitpid(pid, NULL, 0) == -1)
		if (errno != EINTR)
			fatal("Couldn't wait for child: %s", strerror(errno));

	/* Set the connection file descriptors. */
	packet_set_connection(sock, sock);

	return 0;
#endif
}
Exemplo n.º 3
0
/*
 * Connect to the given ssh server using a proxy command.
 */
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;

	/* Convert the port number into a string. */
	snprintf(strport, sizeof strport, "%hu", port);

	/*
	 * Build the final command string in the buffer by making the
	 * appropriate substitutions to the given proxy command.
	 *
	 * Use "exec" to avoid "sh -c" processes on some platforms
	 * (e.g. Solaris)
	 */
	xasprintf(&tmp, "exec %s", proxy_command);
	command_string = percent_expand(tmp, "h", host, "p", strport,
	    "r", options.user, (char *)NULL);
	xfree(tmp);

	/* Create pipes for communicating with the proxy. */
	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);

	/* Fork and execute the proxy command. */
	if ((pid = fork()) == 0) {
		char *argv[10];

		/* Child.  Permanently give up superuser privileges. */
		permanently_drop_suid(original_real_uid);

		/* Redirect stdin and stdout. */
		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");
		/* Cannot be 1 because pin allocated two descriptors. */
		close(pout[1]);

		/* Stderr is left as it is so that error messages get
		   printed on the user's terminal. */
		argv[0] = shell;
		argv[1] = "-c";
		argv[2] = command_string;
		argv[3] = NULL;

		/* Execute the proxy command.  Note that we gave up any
		   extra privileges above. */
		signal(SIGPIPE, SIG_DFL);
		execv(argv[0], argv);
		perror(argv[0]);
		exit(1);
	}
	/* Parent. */
	if (pid < 0)
		fatal("fork failed: %.100s", strerror(errno));
	else
		proxy_command_pid = pid; /* save pid to clean up later */

	/* Close child side of the descriptors. */
	close(pin[0]);
	close(pout[1]);

	/* Free the command name. */
	xfree(command_string);

	/* Set the connection file descriptors. */
	ssh = ssh_packet_set_connection(NULL, pout[0], pin[1]);
	ssh_packet_set_timeout(ssh, options.server_alive_interval,
	    options.server_alive_count_max);

	/* Indicate OK return */
	return (ssh);
}
Exemplo n.º 4
0
/*
 * Connect to the given ssh server using a proxy command.
 */
static int
ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
{
	char *command_string;
	int pin[2], pout[2];
	pid_t pid;
	char *shell;

	if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
		shell = _PATH_BSHELL;

	/* Create pipes for communicating with the proxy. */
	if (pipe(pin) < 0 || pipe(pout) < 0)
		fatal("Could not create pipes to communicate with the proxy: %.100s",
		    strerror(errno));

	command_string = expand_proxy_command(proxy_command, options.user,
	    host, port);
	debug("Executing proxy command: %.500s", command_string);

	/* Fork and execute the proxy command. */
	if ((pid = fork()) == 0) {
		char *argv[10];

		/* Child.  Permanently give up superuser privileges. */
		permanently_drop_suid(original_real_uid);

		/* Redirect stdin and stdout. */
		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");
		/* Cannot be 1 because pin allocated two descriptors. */
		close(pout[1]);

		/* Stderr is left as it is so that error messages get
		   printed on the user's terminal. */
		argv[0] = shell;
		argv[1] = "-c";
		argv[2] = command_string;
		argv[3] = NULL;

		/* Execute the proxy command.  Note that we gave up any
		   extra privileges above. */
		signal(SIGPIPE, SIG_DFL);
		execv(argv[0], argv);
		perror(argv[0]);
		exit(1);
	}
	/* Parent. */
	if (pid < 0)
		fatal("fork failed: %.100s", strerror(errno));
	else
		proxy_command_pid = pid; /* save pid to clean up later */

	/* Close child side of the descriptors. */
	close(pin[0]);
	close(pout[1]);

	/* Free the command name. */
	free(command_string);

	/* Set the connection file descriptors. */
	packet_set_connection(pout[0], pin[1]);

	/* Indicate OK return */
	return 0;
}
Exemplo n.º 5
0
static char *
ssh_askpass(char *askpass, const char *msg)
{
	pid_t pid, ret;
	size_t len;
	char *pass;
	int p[2], status;
	char buf[1024];
	void (*osigchld)(int);

	if (fflush(stdout) != 0)
		error("ssh_askpass: fflush: %s", strerror(errno));
	if (askpass == NULL)
		fatal("internal error: askpass undefined");
	if (pipe(p) < 0) {
		error("ssh_askpass: pipe: %s", strerror(errno));
		return NULL;
	}
	osigchld = signal(SIGCHLD, SIG_DFL);
	if ((pid = fork()) < 0) {
		error("ssh_askpass: fork: %s", strerror(errno));
		signal(SIGCHLD, osigchld);
		return NULL;
	}
	if (pid == 0) {
		permanently_drop_suid(getuid());
		close(p[0]);
		if (dup2(p[1], STDOUT_FILENO) < 0)
			fatal("ssh_askpass: dup2: %s", strerror(errno));
		execlp(askpass, askpass, msg, (char *) 0);
		fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
	}
	close(p[1]);

	len = 0;
	do {
		ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len);

		if (r == -1 && errno == EINTR)
			continue;
		if (r <= 0)
			break;
		len += r;
	} while (sizeof(buf) - 1 - len > 0);
	buf[len] = '\0';

	close(p[0]);
	while ((ret = waitpid(pid, &status, 0)) < 0)
		if (errno != EINTR)
			break;
	signal(SIGCHLD, osigchld);
	if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
		memset(buf, 0, sizeof(buf));
		return NULL;
	}

	buf[strcspn(buf, "\r\n")] = '\0';
	pass = xstrdup(buf);
	memset(buf, 0, sizeof(buf));
	return pass;
}