=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/session.c,v retrieving revision 1.186.2.3 retrieving revision 1.187 diff -u -r1.186.2.3 -r1.187 --- src/usr.bin/ssh/session.c 2006/11/08 00:44:05 1.186.2.3 +++ src/usr.bin/ssh/session.c 2005/10/10 10:23:08 1.187 @@ -1,4 +1,3 @@ -/* $OpenBSD: session.c,v 1.186.2.3 2006/11/08 00:44:05 brad Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -33,27 +32,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include +#include "includes.h" +RCSID("$OpenBSD: session.c,v 1.187 2005/10/10 10:23:08 djm Exp $"); -#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 +46,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 +56,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 +172,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. */ @@ -222,6 +206,15 @@ { setproctitle("%s", authctxt->pw->pw_name); + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } /* setup the channel layer */ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) channel_permit_all_opens(); @@ -335,11 +328,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 +380,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 +413,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 +448,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 +459,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 +491,7 @@ server_loop(pid, inout[1], inout[1], err[1]); /* server_loop has closed inout[1] and err[1]. */ } +#endif /* USE_PIPES */ } /* @@ -543,14 +581,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 +628,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 +730,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 +797,7 @@ /* Initialize the environment. */ envsize = 100; - env = xcalloc(envsize, sizeof(char *)); + env = xmalloc(envsize * sizeof(char *)); env[0] = NULL; #ifdef GSSAPI @@ -1048,7 +1082,7 @@ endpwent(); /* - * Close any extra open file descriptors so that we don't have them + * Close any extra open file descriptors so that we don\'t have them * hanging around in clients. Note that we want to do this after * initgroups, because at least on Solaris 2.3 it leaves file * descriptors open. @@ -1156,7 +1190,7 @@ } #endif - /* Change current directory to the user's home directory. */ + /* Change current directory to the user\'s home directory. */ if (chdir(pw->pw_dir) < 0) { fprintf(stderr, "Could not chdir to home directory %s: %s\n", pw->pw_dir, strerror(errno)); @@ -1170,7 +1204,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 +1468,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 +1476,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; } @@ -1472,7 +1505,7 @@ if (s->auth_proto != NULL || s->auth_data != NULL) { error("session_x11_req: session %d: " - "x11 forwarding already active", s->self); + "x11 fowarding already active", s->self); return 0; } s->single_connection = packet_get_char(); @@ -1542,8 +1575,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++; @@ -1704,7 +1737,7 @@ { Channel *c; - if ((c = channel_by_id(id)) == NULL) { + if ((c = channel_lookup(id)) == NULL) { debug("session_close_x11: x11 channel %d missing", id); } else { /* Detach X11 listener */ @@ -1784,10 +1817,11 @@ /* disconnect channel */ debug("session_exit_message: release channel %d", s->chanid); + s->pid = 0; /* * 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 +1857,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); } @@ -1846,7 +1879,6 @@ session_exit_message(s, status); if (s->ttyfd != -1) session_pty_cleanup(s); - s->pid = 0; } /* @@ -2021,7 +2053,7 @@ return; called = 1; - if (authctxt == NULL || !authctxt->authenticated) + if (authctxt == NULL) return; #ifdef KRB5 if (options.kerberos_ticket_cleanup &&