X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/0179484859673100ce63b74de5131fecf2c3ef1a..1d3c30dbe232d224145556c245d27d1be1e01a1e:/session.c?ds=sidebyside diff --git a/session.c b/session.c index 9c4828ac..13fe0187 100644 --- a/session.c +++ b/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.61 2001/03/16 19:06:30 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.67 2001/03/23 14:28:32 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -100,7 +100,6 @@ typedef struct Session Session; struct Session { int used; int self; - int extended; struct passwd *pw; pid_t pid; /* tty */ @@ -116,6 +115,7 @@ struct Session { int single_connection; /* proto 2 */ int chanid; + int is_subsystem; }; /* func */ @@ -124,11 +124,14 @@ Session *session_new(void); void session_set_fds(Session *s, int fdin, int fdout, int fderr); void session_pty_cleanup(Session *s); void session_proctitle(Session *s); -void do_exec_pty(Session *s, const char *command, struct passwd * pw); -void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); +void do_exec_pty(Session *s, const char *command); +void do_exec_no_pty(Session *s, const char *command); void do_login(Session *s, const char *command); void do_child(Session *s, const char *command); +void do_authenticated1(Authctxt *authctxt); +void do_authenticated2(Authctxt *authctxt); + /* import */ extern ServerOptions options; extern char *__progname; @@ -157,6 +160,34 @@ char *aixloginmsg; static login_cap_t *lc; #endif +void +do_authenticated(Authctxt *authctxt) +{ + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } +#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD) + if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) { + error("unable to get login class"); + return; + } +#endif + /* setup the channel layer */ + if (!no_port_forwarding_flag && options.allow_tcp_forwarding) + channel_permit_all_opens(); + + if (compat20) + do_authenticated2(authctxt); + else + do_authenticated1(authctxt); +} + /* * Remove local Xauthority file. */ @@ -206,47 +237,23 @@ pty_cleanup_proc(void *session) * are requested, etc. */ void -do_authenticated(struct passwd * pw) +do_authenticated1(Authctxt *authctxt) { Session *s; - int type, fd; - int compression_level = 0, enable_compression_after_reply = 0; - int have_pty = 0; char *command; - int n_bytes; - int plen; + int success, type, fd, n_bytes, plen, screen_flag, have_pty = 0; + int compression_level = 0, enable_compression_after_reply = 0; u_int proto_len, data_len, dlen; - int screen_flag; - - /* - * Cancel the alarm we set to limit the time taken for - * authentication. - */ - alarm(0); - if (startup_pipe != -1) { - close(startup_pipe); - startup_pipe = -1; - } - - if (!no_port_forwarding_flag && options.allow_tcp_forwarding) - channel_permit_all_opens(); s = session_new(); - s->pw = pw; - -#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD) - if ((lc = login_getclass(pw->pw_class)) == NULL) { - error("unable to get login class"); - return; - } -#endif + s->pw = authctxt->pw; /* * We stay in this loop until the client requests to execute a shell * or a command. */ for (;;) { - int success = 0; + success = 0; /* Get a packet from the client. */ type = packet_read(&plen); @@ -283,7 +290,7 @@ do_authenticated(struct passwd * pw) break; } fatal_add_cleanup(pty_cleanup_proc, (void *)s); - pty_setowner(pw, s->tty); + pty_setowner(s->pw, s->tty); /* Get TERM from the packet. Note that the value may be of arbitrary length. */ s->term = packet_get_string(&dlen); @@ -358,7 +365,7 @@ do_authenticated(struct passwd * pw) /* Setup to always have a local .Xauthority. */ xauthfile = xmalloc(MAXPATHLEN); strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN); - temporarily_use_uid(pw->pw_uid); + temporarily_use_uid(s->pw->pw_uid); if (mkdtemp(xauthfile) == NULL) { restore_uid(); error("private X11 dir: mkdtemp %s failed: %s", @@ -383,7 +390,7 @@ do_authenticated(struct passwd * pw) break; } debug("Received authentication agent forwarding request."); - success = auth_input_request_forwarding(pw); + success = auth_input_request_forwarding(s->pw); break; case SSH_CMSG_PORT_FORWARD_REQUEST: @@ -396,7 +403,7 @@ do_authenticated(struct passwd * pw) break; } debug("Received TCP/IP port forwarding request."); - channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports); + channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports); success = 1; break; @@ -421,9 +428,9 @@ do_authenticated(struct passwd * pw) debug("Forced command '%.500s'", forced_command); } if (have_pty) - do_exec_pty(s, command, pw); + do_exec_pty(s, command); else - do_exec_no_pty(s, command, pw); + do_exec_no_pty(s, command); if (command != NULL) xfree(command); @@ -457,7 +464,7 @@ do_authenticated(struct passwd * pw) * setting up file descriptors and such. */ void -do_exec_no_pty(Session *s, const char *command, struct passwd * pw) +do_exec_no_pty(Session *s, const char *command) { int pid; @@ -555,11 +562,11 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) close(perr[1]); if (compat20) { - session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1); + session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]); } else { /* Enter the interactive session. */ server_loop(pid, pin[1], pout[0], perr[0]); - /* server_loop has closed pin[1], pout[1], and perr[1]. */ + /* 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. */ @@ -571,7 +578,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) * handle the case that fdin and fdout are the same. */ if (compat20) { - session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1); + session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]); } else { server_loop(pid, inout[1], inout[1], err[1]); /* server_loop has closed inout[1] and err[1]. */ @@ -586,7 +593,7 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) * lastlog, and other such operations. */ void -do_exec_pty(Session *s, const char *command, struct passwd * pw) +do_exec_pty(Session *s, const char *command) { int fdout, ptyfd, ttyfd, ptymaster; pid_t pid; @@ -597,7 +604,7 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) ttyfd = s->ttyfd; #if defined(USE_PAM) - do_pam_session(pw->pw_name, s->tty); + do_pam_session(s->pw->pw_name, s->tty); do_pam_setcred(); #endif @@ -1053,7 +1060,7 @@ do_child(Session *s, const char *command) switch, so we let login(1) to this for us. */ if (!options.use_login) { #ifdef HAVE_OSF_SIA - session_setup_sia(pw->pw_name, ttyname); + session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty); #else /* HAVE_OSF_SIA */ #ifdef HAVE_CYGWIN if (is_winnt) { @@ -1134,10 +1141,12 @@ do_child(Session *s, const char *command) * other stuff is stored - a few applications * actually use this and die if it's not set */ - cp = xmalloc(22 + strlen(ttyname) + + if (s->ttyfd == -1) + s->tty[0] = '\0'; + cp = xmalloc(22 + strlen(s->tty) + 2 * strlen(pw->pw_name)); i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c", - pw->pw_name, 0, pw->pw_name, 0, ttyname, 0,0); + pw->pw_name, 0, pw->pw_name, 0, s->tty, 0, 0); if (usrinfo(SETUINFO, cp, i) == -1) fatal("Couldn't set usrinfo: %s", strerror(errno)); @@ -1418,6 +1427,10 @@ do_child(Session *s, const char *command) else cp = shell; } + + /* restore SIGPIPE for child */ + signal(SIGPIPE, SIG_DFL); + /* * If we have no command, execute the shell. In this case, the shell * name to be passed in argv[0] is preceded by '-' to indicate that @@ -1502,10 +1515,11 @@ session_new(void) Session *s = &sessions[i]; if (! s->used) { s->pid = 0; - s->extended = 0; + s->is_subsystem = 0; s->chanid = -1; s->ptyfd = -1; s->ttyfd = -1; + s->tty[0] = '\0'; s->term = NULL; s->pw = NULL; s->display = NULL; @@ -1659,7 +1673,8 @@ session_subsystem_req(Session *s) for (i = 0; i < options.num_subsystems; i++) { if(strcmp(subsys, options.subsystem_name[i]) == 0) { debug("subsystem: exec() %s", options.subsystem_command[i]); - do_exec_no_pty(s, options.subsystem_command[i], s->pw); + s->is_subsystem = 1; + do_exec_no_pty(s, options.subsystem_command[i]); success = 1; } } @@ -1733,11 +1748,10 @@ session_shell_req(Session *s) /* if forced_command == NULL, the shell is execed */ char *shell = forced_command; packet_done(); - s->extended = 1; if (s->ttyfd == -1) - do_exec_no_pty(s, shell, s->pw); + do_exec_no_pty(s, shell); else - do_exec_pty(s, shell, s->pw); + do_exec_pty(s, shell); return 1; } @@ -1752,11 +1766,10 @@ session_exec_req(Session *s) command = forced_command; debug("Forced command '%.500s'", forced_command); } - s->extended = 1; if (s->ttyfd == -1) - do_exec_no_pty(s, command, s->pw); + do_exec_no_pty(s, command); else - do_exec_pty(s, command, s->pw); + do_exec_pty(s, command); if (forced_command == NULL) xfree(command); return 1; @@ -1803,8 +1816,8 @@ session_input_channel_req(int id, void *arg) s->self, id, rtype, reply); /* - * a session is in LARVAL state until a shell - * or programm is executed + * a session is in LARVAL state until a shell, a command + * or a subsystem is executed */ if (c->type == SSH_CHANNEL_LARVAL) { if (strcmp(rtype, "shell") == 0) { @@ -2021,23 +2034,7 @@ session_proctitle(Session *s) void do_authenticated2(Authctxt *authctxt) { - /* - * Cancel the alarm we set to limit the time taken for - * authentication. - */ - alarm(0); - if (startup_pipe != -1) { - close(startup_pipe); - startup_pipe = -1; - } - if (!no_port_forwarding_flag && options.allow_tcp_forwarding) - channel_permit_all_opens(); -#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD) - if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) { - error("unable to get login class"); - return; - } -#endif + server_loop2(); if (xauthfile) xauthfile_cleanup_proc(NULL);