=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/session.c,v retrieving revision 1.197.2.2 retrieving revision 1.198 diff -u -r1.197.2.2 -r1.198 --- src/usr.bin/ssh/session.c 2006/11/08 00:17:14 1.197.2.2 +++ src/usr.bin/ssh/session.c 2006/03/19 18:51:18 1.198 @@ -1,4 +1,3 @@ -/* $OpenBSD: session.c,v 1.197.2.2 2006/11/08 00:17:14 brad Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -33,27 +32,20 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "includes.h" + #include #include #include #include -#include -#include -#include -#include #include -#include #include -#include -#include -#include -#include -#include "xmalloc.h" #include "ssh.h" #include "ssh1.h" #include "ssh2.h" +#include "xmalloc.h" #include "sshpty.h" #include "packet.h" #include "buffer.h" @@ -61,10 +53,7 @@ #include "uidswap.h" #include "compat.h" #include "channels.h" -#include "key.h" -#include "cipher.h" -#include "kex.h" -#include "hostfile.h" +#include "bufaux.h" #include "auth.h" #include "auth-options.h" #include "pathnames.h" @@ -74,15 +63,17 @@ #include "serverloop.h" #include "canohost.h" #include "session.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif +#include "kex.h" #include "monitor_wrap.h" #ifdef KRB5 #include #endif +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* func */ Session *session_new(void); @@ -188,7 +179,7 @@ sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); - if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) + if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) packet_disconnect("bind: %.100s", strerror(errno)); /* Restore the privileged uid. */ @@ -335,11 +326,7 @@ break; } debug("Received TCP/IP port forwarding request."); - if (channel_input_port_forward_request(s->pw->pw_uid == 0, - options.gateway_ports) < 0) { - debug("Port forwarding failed."); - break; - } + channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports); success = 1; break; @@ -391,12 +378,20 @@ { pid_t pid; +#ifdef USE_PIPES + int pin[2], pout[2], perr[2]; + /* Allocate pipes for communicating with the program. */ + if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) + packet_disconnect("Could not create pipes: %.100s", + strerror(errno)); +#else /* USE_PIPES */ int inout[2], err[2]; /* Uses socket pairs to communicate with the program. */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) packet_disconnect("Could not create socket pairs: %.100s", strerror(errno)); +#endif /* USE_PIPES */ if (s == NULL) fatal("do_exec_no_pty: no session"); @@ -416,7 +411,29 @@ if (setsid() < 0) error("setsid failed: %.100s", strerror(errno)); +#ifdef USE_PIPES /* + * Redirect stdin. We close the parent side of the socket + * pair, and make the child side the standard input. + */ + close(pin[1]); + if (dup2(pin[0], 0) < 0) + perror("dup2 stdin"); + close(pin[0]); + + /* Redirect stdout. */ + close(pout[0]); + if (dup2(pout[1], 1) < 0) + perror("dup2 stdout"); + close(pout[1]); + + /* Redirect stderr. */ + close(perr[0]); + if (dup2(perr[1], 2) < 0) + perror("dup2 stderr"); + close(perr[1]); +#else /* USE_PIPES */ + /* * Redirect stdin, stdout, and stderr. Stdin and stdout will * use the same socket, as some programs (particularly rdist) * seem to depend on it. @@ -429,6 +446,7 @@ perror("dup2 stdout"); if (dup2(err[0], 2) < 0) /* stderr */ perror("dup2 stderr"); +#endif /* USE_PIPES */ /* Do processing for the child (exec command etc). */ do_child(s, command); @@ -439,7 +457,24 @@ s->pid = pid; /* Set interactive/non-interactive mode. */ packet_set_interactive(s->display != NULL); +#ifdef USE_PIPES + /* We are the parent. Close the child sides of the pipes. */ + close(pin[0]); + close(pout[1]); + close(perr[1]); + if (compat20) { + if (s->is_subsystem) { + close(perr[0]); + perr[0] = -1; + } + session_set_fds(s, pin[1], pout[0], perr[0]); + } else { + /* Enter the interactive session. */ + server_loop(pid, pin[1], pout[0], perr[0]); + /* server_loop has closed pin[1], pout[0], and perr[0]. */ + } +#else /* USE_PIPES */ /* We are the parent. Close the child sides of the socket pairs. */ close(inout[0]); close(err[0]); @@ -454,6 +489,7 @@ server_loop(pid, inout[1], inout[1], err[1]); /* server_loop has closed inout[1] and err[1]. */ } +#endif /* USE_PIPES */ } /* @@ -543,14 +579,10 @@ void do_exec(Session *s, const char *command) { - if (options.adm_forced_command) { + if (forced_command) { original_command = command; - command = options.adm_forced_command; - debug("Forced command (config) '%.900s'", command); - } else if (forced_command) { - original_command = command; command = forced_command; - debug("Forced command (key option) '%.900s'", command); + debug("Forced command '%.900s'", command); } #ifdef GSSAPI @@ -594,7 +626,7 @@ fromlen = sizeof(from); if (packet_connection_is_on_socket()) { if (getpeername(packet_get_connection_in(), - (struct sockaddr *)&from, &fromlen) < 0) { + (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); cleanup_exit(255); } @@ -696,7 +728,7 @@ if (envsize >= 1000) fatal("child_set_env: too many env vars"); envsize += 50; - env = (*envp) = xrealloc(env, envsize, sizeof(char *)); + env = (*envp) = xrealloc(env, envsize * sizeof(char *)); *envsizep = envsize; } /* Need to set the NULL pointer at end of array beyond the new slot. */ @@ -763,7 +795,7 @@ /* Initialize the environment. */ envsize = 100; - env = xcalloc(envsize, sizeof(char *)); + env = xmalloc(envsize * sizeof(char *)); env[0] = NULL; #ifdef GSSAPI @@ -1170,7 +1202,7 @@ do_rc_files(s, shell); /* restore SIGPIPE for child */ - signal(SIGPIPE, SIG_DFL); + signal(SIGPIPE, SIG_DFL); if (options.use_login) { launch_login(pw, hostname); @@ -1434,7 +1466,7 @@ struct stat st; u_int len; int success = 0; - char *prog, *cmd, *subsys = packet_get_string(&len); + char *cmd, *subsys = packet_get_string(&len); u_int i; packet_check_eom(); @@ -1442,10 +1474,9 @@ for (i = 0; i < options.num_subsystems; i++) { if (strcmp(subsys, options.subsystem_name[i]) == 0) { - prog = options.subsystem_command[i]; - cmd = options.subsystem_args[i]; - if (stat(prog, &st) < 0) { - error("subsystem: cannot stat %s: %s", prog, + cmd = options.subsystem_command[i]; + if (stat(cmd, &st) < 0) { + error("subsystem: cannot stat %s: %s", cmd, strerror(errno)); break; } @@ -1542,8 +1573,8 @@ for (i = 0; i < options.num_accept_env; i++) { if (match_pattern(name, options.accept_env[i])) { debug2("Setting env %d: %s=%s", s->num_env, name, val); - s->env = xrealloc(s->env, s->num_env + 1, - sizeof(*s->env)); + s->env = xrealloc(s->env, sizeof(*s->env) * + (s->num_env + 1)); s->env[s->num_env].name = name; s->env[s->num_env].val = val; s->num_env++; @@ -1787,7 +1818,7 @@ /* * Adjust cleanup callback attachment to send close messages when - * the channel gets EOF. The session will be then be closed + * the channel gets EOF. The session will be then be closed * by session_close_by_channel when the childs close their fds. */ channel_register_cleanup(c->self, session_close_by_channel, 1); @@ -1823,13 +1854,12 @@ if (s->auth_proto) xfree(s->auth_proto); s->used = 0; - if (s->env != NULL) { - for (i = 0; i < s->num_env; i++) { - xfree(s->env[i].name); - xfree(s->env[i].val); - } - xfree(s->env); + for (i = 0; i < s->num_env; i++) { + xfree(s->env[i].name); + xfree(s->env[i].val); } + if (s->env != NULL) + xfree(s->env); session_proctitle(s); } @@ -2021,7 +2051,7 @@ return; called = 1; - if (authctxt == NULL || !authctxt->authenticated) + if (authctxt == NULL) return; #ifdef KRB5 if (options.kerberos_ticket_cleanup &&