diff options
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 393 |
1 files changed, 74 insertions, 319 deletions
diff --git a/session.c b/session.c index 2235f26acb78..a08aa69d1679 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.282 2016/03/10 11:47:57 djm Exp $ */ +/* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -66,7 +66,6 @@ #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" -#include "ssh1.h" #include "ssh2.h" #include "sshpty.h" #include "packet.h" @@ -128,7 +127,6 @@ void do_child(Session *, const char *); void do_motd(void); int check_quietlogin(Session *, const char *); -static void do_authenticated1(Authctxt *); static void do_authenticated2(Authctxt *); static int session_pty_req(Session *); @@ -259,7 +257,7 @@ do_authenticated(Authctxt *authctxt) /* setup the channel layer */ /* XXX - streamlocal? */ - if (no_port_forwarding_flag || + if (no_port_forwarding_flag || options.disable_forwarding || (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) channel_disable_adm_local_opens(); else @@ -267,11 +265,7 @@ do_authenticated(Authctxt *authctxt) auth_debug_send(); - if (compat20) - do_authenticated2(authctxt); - else - do_authenticated1(authctxt); - + do_authenticated2(authctxt); do_cleanup(authctxt); } @@ -290,164 +284,6 @@ xauth_valid_string(const char *s) return 1; } -/* - * Prepares for an interactive session. This is called after the user has - * been successfully authenticated. During this message exchange, pseudo - * terminals are allocated, X11, TCP/IP, and authentication agent forwardings - * are requested, etc. - */ -static void -do_authenticated1(Authctxt *authctxt) -{ - Session *s; - char *command; - int success, type, screen_flag; - int enable_compression_after_reply = 0; - u_int proto_len, data_len, dlen, compression_level = 0; - - s = session_new(); - if (s == NULL) { - error("no more sessions"); - return; - } - s->authctxt = authctxt; - s->pw = authctxt->pw; - - /* - * We stay in this loop until the client requests to execute a shell - * or a command. - */ - for (;;) { - success = 0; - - /* Get a packet from the client. */ - type = packet_read(); - - /* Process the packet. */ - switch (type) { - case SSH_CMSG_REQUEST_COMPRESSION: - compression_level = packet_get_int(); - packet_check_eom(); - if (compression_level < 1 || compression_level > 9) { - packet_send_debug("Received invalid compression level %d.", - compression_level); - break; - } - if (options.compression == COMP_NONE) { - debug2("compression disabled"); - break; - } - /* Enable compression after we have responded with SUCCESS. */ - enable_compression_after_reply = 1; - success = 1; - break; - - case SSH_CMSG_REQUEST_PTY: - success = session_pty_req(s); - break; - - case SSH_CMSG_X11_REQUEST_FORWARDING: - s->auth_proto = packet_get_string(&proto_len); - s->auth_data = packet_get_string(&data_len); - - screen_flag = packet_get_protocol_flags() & - SSH_PROTOFLAG_SCREEN_NUMBER; - debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag); - - if (packet_remaining() == 4) { - if (!screen_flag) - debug2("Buggy client: " - "X11 screen flag missing"); - s->screen = packet_get_int(); - } else { - s->screen = 0; - } - packet_check_eom(); - if (xauth_valid_string(s->auth_proto) && - xauth_valid_string(s->auth_data)) - success = session_setup_x11fwd(s); - else { - success = 0; - error("Invalid X11 forwarding data"); - } - if (!success) { - free(s->auth_proto); - free(s->auth_data); - s->auth_proto = NULL; - s->auth_data = NULL; - } - break; - - case SSH_CMSG_AGENT_REQUEST_FORWARDING: - if (!options.allow_agent_forwarding || - no_agent_forwarding_flag || compat13) { - debug("Authentication agent forwarding not permitted for this authentication."); - break; - } - debug("Received authentication agent forwarding request."); - success = auth_input_request_forwarding(s->pw); - break; - - case SSH_CMSG_PORT_FORWARD_REQUEST: - if (no_port_forwarding_flag) { - debug("Port forwarding not permitted for this authentication."); - break; - } - if (!(options.allow_tcp_forwarding & FORWARD_REMOTE)) { - debug("Port forwarding not permitted."); - break; - } - debug("Received TCP/IP port forwarding request."); - if (channel_input_port_forward_request(s->pw->pw_uid == 0, - &options.fwd_opts) < 0) { - debug("Port forwarding failed."); - break; - } - success = 1; - break; - - case SSH_CMSG_MAX_PACKET_SIZE: - if (packet_set_maxsize(packet_get_int()) > 0) - success = 1; - break; - - case SSH_CMSG_EXEC_SHELL: - case SSH_CMSG_EXEC_CMD: - if (type == SSH_CMSG_EXEC_CMD) { - command = packet_get_string(&dlen); - debug("Exec command '%.500s'", command); - if (do_exec(s, command) != 0) - packet_disconnect( - "command execution failed"); - free(command); - } else { - if (do_exec(s, NULL) != 0) - packet_disconnect( - "shell execution failed"); - } - packet_check_eom(); - session_close(s); - return; - - default: - /* - * Any unknown messages in this phase are ignored, - * and a failure message is returned. - */ - logit("Unknown packet type received after authentication: %d", type); - } - packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); - packet_send(); - packet_write_wait(); - - /* Enable compression now that we have replied if appropriate. */ - if (enable_compression_after_reply) { - enable_compression_after_reply = 0; - packet_start_compression(compression_level); - } - } -} - #define USE_PIPES 1 /* * This is called to fork and execute a command when we have no tty. This @@ -615,14 +451,8 @@ do_exec_no_pty(Session *s, const char *command) close(pout[1]); close(perr[1]); - if (compat20) { - session_set_fds(s, pin[1], pout[0], perr[0], - s->is_subsystem, 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]. */ - } + session_set_fds(s, pin[1], pout[0], perr[0], + s->is_subsystem, 0); #else /* We are the parent. Close the child sides of the socket pairs. */ close(inout[0]); @@ -632,13 +462,8 @@ do_exec_no_pty(Session *s, const char *command) * Enter the interactive session. Note: server_loop must be able to * handle the case that fdin and fdout are the same. */ - if (compat20) { - session_set_fds(s, inout[1], inout[1], err[1], - s->is_subsystem, 0); - } else { - server_loop(pid, inout[1], inout[1], err[1]); - /* server_loop has closed inout[1] and err[1]. */ - } + session_set_fds(s, inout[1], inout[1], err[1], + s->is_subsystem, 0); #endif return 0; } @@ -718,17 +543,11 @@ do_exec_pty(Session *s, const char *command) close(ttyfd); /* record login, etc. similar to login(1) */ -#ifndef HAVE_OSF_SIA - if (!(options.use_login && command == NULL)) { #ifdef _UNICOS - cray_init_job(s->pw); /* set up cray jid and tmpdir */ + cray_init_job(s->pw); /* set up cray jid and tmpdir */ #endif /* _UNICOS */ - do_login(s, command); - } -# ifdef LOGIN_NEEDS_UTMPX - else - do_pre_login(s); -# endif +#ifndef HAVE_OSF_SIA + do_login(s, command); #endif /* * Do common processing for the child, such as execing @@ -756,12 +575,7 @@ do_exec_pty(Session *s, const char *command) s->ptymaster = ptymaster; packet_set_interactive(1, options.ip_qos_interactive, options.ip_qos_bulk); - if (compat20) { - session_set_fds(s, ptyfd, fdout, -1, 1, 1); - } else { - server_loop(pid, ptyfd, fdout, -1); - /* server_loop _has_ closed ptyfd and fdout. */ - } + session_set_fds(s, ptyfd, fdout, -1, 1, 1); return 0; } @@ -1199,69 +1013,63 @@ do_setup_env(Session *s, const char *shell) ssh_gssapi_do_child(&env, &envsize); #endif - if (!options.use_login) { - /* Set basic environment. */ - for (i = 0; i < s->num_env; i++) - child_set_env(&env, &envsize, s->env[i].name, - s->env[i].val); + /* Set basic environment. */ + for (i = 0; i < s->num_env; i++) + child_set_env(&env, &envsize, s->env[i].name, s->env[i].val); - child_set_env(&env, &envsize, "USER", pw->pw_name); - child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); + child_set_env(&env, &envsize, "USER", pw->pw_name); + child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); #ifdef _AIX - child_set_env(&env, &envsize, "LOGIN", pw->pw_name); + child_set_env(&env, &envsize, "LOGIN", pw->pw_name); #endif - child_set_env(&env, &envsize, "HOME", pw->pw_dir); + child_set_env(&env, &envsize, "HOME", pw->pw_dir); #ifdef HAVE_LOGIN_CAP - if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) - child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); - else - child_set_env(&env, &envsize, "PATH", getenv("PATH")); + if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) + child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); + else + child_set_env(&env, &envsize, "PATH", getenv("PATH")); #else /* HAVE_LOGIN_CAP */ # ifndef HAVE_CYGWIN - /* - * There's no standard path on Windows. The path contains - * important components pointing to the system directories, - * needed for loading shared libraries. So the path better - * remains intact here. - */ + /* + * There's no standard path on Windows. The path contains + * important components pointing to the system directories, + * needed for loading shared libraries. So the path better + * remains intact here. + */ # ifdef HAVE_ETC_DEFAULT_LOGIN - read_etc_default_login(&env, &envsize, pw->pw_uid); - path = child_get_env(env, "PATH"); + read_etc_default_login(&env, &envsize, pw->pw_uid); + path = child_get_env(env, "PATH"); # endif /* HAVE_ETC_DEFAULT_LOGIN */ - if (path == NULL || *path == '\0') { - child_set_env(&env, &envsize, "PATH", - s->pw->pw_uid == 0 ? - SUPERUSER_PATH : _PATH_STDPATH); - } + if (path == NULL || *path == '\0') { + child_set_env(&env, &envsize, "PATH", + s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); + } # endif /* HAVE_CYGWIN */ #endif /* HAVE_LOGIN_CAP */ - snprintf(buf, sizeof buf, "%.200s/%.50s", - _PATH_MAILDIR, pw->pw_name); - child_set_env(&env, &envsize, "MAIL", buf); + snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); + child_set_env(&env, &envsize, "MAIL", buf); + + /* Normal systems set SHELL by default. */ + child_set_env(&env, &envsize, "SHELL", shell); - /* Normal systems set SHELL by default. */ - child_set_env(&env, &envsize, "SHELL", shell); - } if (getenv("TZ")) child_set_env(&env, &envsize, "TZ", getenv("TZ")); /* Set custom environment options from RSA authentication. */ - if (!options.use_login) { - while (custom_environment) { - struct envstring *ce = custom_environment; - char *str = ce->s; - - for (i = 0; str[i] != '=' && str[i]; i++) - ; - if (str[i] == '=') { - str[i] = 0; - child_set_env(&env, &envsize, str, str + i + 1); - } - custom_environment = ce->next; - free(ce->s); - free(ce); + while (custom_environment) { + struct envstring *ce = custom_environment; + char *str = ce->s; + + for (i = 0; str[i] != '=' && str[i]; i++) + ; + if (str[i] == '=') { + str[i] = 0; + child_set_env(&env, &envsize, str, str + i + 1); } + custom_environment = ce->next; + free(ce->s); + free(ce); } /* SSH_CLIENT deprecated */ @@ -1323,7 +1131,7 @@ do_setup_env(Session *s, const char *shell) * Pull in any environment variables that may have * been set by PAM. */ - if (options.use_pam && !options.use_login) { + if (options.use_pam) { char **p; p = fetch_pam_child_environment(); @@ -1341,7 +1149,7 @@ do_setup_env(Session *s, const char *shell) auth_sock_name); /* read $HOME/.ssh/environment. */ - if (options.permit_user_env && !options.use_login) { + if (options.permit_user_env) { snprintf(buf, sizeof buf, "%.200s/.ssh/environment", strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); read_environment_file(&env, &envsize, buf); @@ -1623,27 +1431,6 @@ do_pwchange(Session *s) } static void -launch_login(struct passwd *pw, const char *hostname) -{ - /* Launch login(1). */ - - execl(LOGIN_PROGRAM, "login", "-h", hostname, -#ifdef xxxLOGIN_NEEDS_TERM - (s->term ? s->term : "unknown"), -#endif /* LOGIN_NEEDS_TERM */ -#ifdef LOGIN_NO_ENDOPT - "-p", "-f", pw->pw_name, (char *)NULL); -#else - "-p", "-f", "--", pw->pw_name, (char *)NULL); -#endif - - /* Login couldn't be executed, die. */ - - perror("login"); - exit(1); -} - -static void child_close_fds(void) { extern int auth_sock; @@ -1690,11 +1477,10 @@ child_close_fds(void) void do_child(Session *s, const char *command) { - struct ssh *ssh = active_state; /* XXX */ extern char **environ; char **env; char *argv[ARGV_MAX]; - const char *shell, *shell0, *hostname = NULL; + const char *shell, *shell0; struct passwd *pw = s->pw; int r = 0; @@ -1709,10 +1495,6 @@ do_child(Session *s, const char *command) exit(1); } - /* login(1) is only called if we execute the login shell */ - if (options.use_login && command != NULL) - options.use_login = 0; - #ifdef _UNICOS cray_setup(pw->pw_uid, pw->pw_name, command); #endif /* _UNICOS */ @@ -1721,28 +1503,26 @@ do_child(Session *s, const char *command) * Login(1) does this as well, and it needs uid 0 for the "-h" * switch, so we let login(1) to this for us. */ - if (!options.use_login) { #ifdef HAVE_OSF_SIA - session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); - if (!check_quietlogin(s, command)) - do_motd(); + session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); + if (!check_quietlogin(s, command)) + do_motd(); #else /* HAVE_OSF_SIA */ - /* When PAM is enabled we rely on it to do the nologin check */ - if (!options.use_pam) - do_nologin(pw); - do_setusercontext(pw); - /* - * PAM session modules in do_setusercontext may have - * generated messages, so if this in an interactive - * login then display them too. - */ - if (!check_quietlogin(s, command)) - display_loginmsg(); + /* When PAM is enabled we rely on it to do the nologin check */ + if (!options.use_pam) + do_nologin(pw); + do_setusercontext(pw); + /* + * PAM session modules in do_setusercontext may have + * generated messages, so if this in an interactive + * login then display them too. + */ + if (!check_quietlogin(s, command)) + display_loginmsg(); #endif /* HAVE_OSF_SIA */ - } #ifdef USE_PAM - if (options.use_pam && !options.use_login && !is_pam_session_open()) { + if (options.use_pam && !is_pam_session_open()) { debug3("PAM session not opened, exiting"); display_loginmsg(); exit(254); @@ -1765,10 +1545,6 @@ do_child(Session *s, const char *command) shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); #endif - /* we have to stash the hostname before we close our socket. */ - if (options.use_login) - hostname = session_get_remote_name_or_ip(ssh, utmp_len, - options.use_dns); /* * Close the connection descriptors; note that this is the child, and * the server will still have the socket open, and it is important @@ -1827,8 +1603,7 @@ do_child(Session *s, const char *command) closefrom(STDERR_FILENO + 1); - if (!options.use_login) - do_rc_files(s, shell); + do_rc_files(s, shell); /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); @@ -1858,11 +1633,6 @@ do_child(Session *s, const char *command) fflush(NULL); - if (options.use_login) { - launch_login(pw, hostname); - /* NEVERREACHED */ - } - /* Get the last component of the shell name. */ if ((shell0 = strrchr(shell, '/')) != NULL) shell0++; @@ -2106,14 +1876,8 @@ session_pty_req(Session *s) } s->term = packet_get_string(&len); - - if (compat20) { - s->col = packet_get_int(); - s->row = packet_get_int(); - } else { - s->row = packet_get_int(); - s->col = packet_get_int(); - } + s->col = packet_get_int(); + s->row = packet_get_int(); s->xpixel = packet_get_int(); s->ypixel = packet_get_int(); @@ -2135,9 +1899,7 @@ session_pty_req(Session *s) } debug("session_pty_req: session %d alloc %s", s->self, s->tty); - /* for SSH1 the tty modes length is not given */ - if (!compat20) - n_bytes = packet_remaining(); + n_bytes = packet_remaining(); tty_parse_modes(s->ttyfd, &n_bytes); if (!use_privsep) @@ -2353,8 +2115,6 @@ void session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, int is_tty) { - if (!compat20) - fatal("session_set_fds: called for proto != 2.0"); /* * now that have a child and a pipe to the child, * we can activate our channel and register the fd's @@ -2692,11 +2452,6 @@ session_setup_x11fwd(Session *s) packet_send_debug("No xauth program; cannot forward with spoofing."); return 0; } - if (options.use_login) { - packet_send_debug("X11 forwarding disabled; " - "not compatible with UseLogin=yes."); - return 0; - } if (s->display != NULL) { debug("X11 display already set."); return 0; @@ -2794,7 +2549,7 @@ do_cleanup(Authctxt *authctxt) #endif #ifdef GSSAPI - if (compat20 && options.gss_cleanup_creds) + if (options.gss_cleanup_creds) ssh_gssapi_cleanup_creds(); #endif |