diff options
author | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-10-05 23:58:12 +0100 |
commit | 0556ea972b15607b7e13ff31bc05840881c91dd3 (patch) | |
tree | d6b8d48062d0278b5ae0eeff42d0e9afa9f26860 /session.c | |
parent | db2122d97eb1ecdd8d99b7bf79b0dd2b5addfd92 (diff) | |
parent | 801a62eedaaf47b20dbf4b426dc3e084bf0c8d49 (diff) |
New upstream release (7.6p1)
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 377 |
1 files changed, 185 insertions, 192 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 djm Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -94,6 +94,7 @@ | |||
94 | #include "kex.h" | 94 | #include "kex.h" |
95 | #include "monitor_wrap.h" | 95 | #include "monitor_wrap.h" |
96 | #include "sftp.h" | 96 | #include "sftp.h" |
97 | #include "atomicio.h" | ||
97 | 98 | ||
98 | #if defined(KRB5) && defined(USE_AFS) | 99 | #if defined(KRB5) && defined(USE_AFS) |
99 | #include <kafs.h> | 100 | #include <kafs.h> |
@@ -112,29 +113,28 @@ | |||
112 | /* func */ | 113 | /* func */ |
113 | 114 | ||
114 | Session *session_new(void); | 115 | Session *session_new(void); |
115 | void session_set_fds(Session *, int, int, int, int, int); | 116 | void session_set_fds(struct ssh *, Session *, int, int, int, int, int); |
116 | void session_pty_cleanup(Session *); | 117 | void session_pty_cleanup(Session *); |
117 | void session_proctitle(Session *); | 118 | void session_proctitle(Session *); |
118 | int session_setup_x11fwd(Session *); | 119 | int session_setup_x11fwd(struct ssh *, Session *); |
119 | int do_exec_pty(Session *, const char *); | 120 | int do_exec_pty(struct ssh *, Session *, const char *); |
120 | int do_exec_no_pty(Session *, const char *); | 121 | int do_exec_no_pty(struct ssh *, Session *, const char *); |
121 | int do_exec(Session *, const char *); | 122 | int do_exec(struct ssh *, Session *, const char *); |
122 | void do_login(Session *, const char *); | 123 | void do_login(struct ssh *, Session *, const char *); |
124 | void do_child(struct ssh *, Session *, const char *); | ||
123 | #ifdef LOGIN_NEEDS_UTMPX | 125 | #ifdef LOGIN_NEEDS_UTMPX |
124 | static void do_pre_login(Session *s); | 126 | static void do_pre_login(Session *s); |
125 | #endif | 127 | #endif |
126 | void do_child(Session *, const char *); | ||
127 | void do_motd(void); | 128 | void do_motd(void); |
128 | int check_quietlogin(Session *, const char *); | 129 | int check_quietlogin(Session *, const char *); |
129 | 130 | ||
130 | static void do_authenticated2(Authctxt *); | 131 | static void do_authenticated2(struct ssh *, Authctxt *); |
131 | 132 | ||
132 | static int session_pty_req(Session *); | 133 | static int session_pty_req(struct ssh *, Session *); |
133 | 134 | ||
134 | /* import */ | 135 | /* import */ |
135 | extern ServerOptions options; | 136 | extern ServerOptions options; |
136 | extern char *__progname; | 137 | extern char *__progname; |
137 | extern int log_stderr; | ||
138 | extern int debug_flag; | 138 | extern int debug_flag; |
139 | extern u_int utmp_len; | 139 | extern u_int utmp_len; |
140 | extern int startup_pipe; | 140 | extern int startup_pipe; |
@@ -161,6 +161,9 @@ login_cap_t *lc; | |||
161 | static int is_child = 0; | 161 | static int is_child = 0; |
162 | static int in_chroot = 0; | 162 | static int in_chroot = 0; |
163 | 163 | ||
164 | /* File containing userauth info, if ExposeAuthInfo set */ | ||
165 | static char *auth_info_file = NULL; | ||
166 | |||
164 | /* Name and directory of socket for authentication agent forwarding. */ | 167 | /* Name and directory of socket for authentication agent forwarding. */ |
165 | static char *auth_sock_name = NULL; | 168 | static char *auth_sock_name = NULL; |
166 | static char *auth_sock_dir = NULL; | 169 | static char *auth_sock_dir = NULL; |
@@ -180,7 +183,7 @@ auth_sock_cleanup_proc(struct passwd *pw) | |||
180 | } | 183 | } |
181 | 184 | ||
182 | static int | 185 | static int |
183 | auth_input_request_forwarding(struct passwd * pw) | 186 | auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) |
184 | { | 187 | { |
185 | Channel *nc; | 188 | Channel *nc; |
186 | int sock = -1; | 189 | int sock = -1; |
@@ -220,7 +223,7 @@ auth_input_request_forwarding(struct passwd * pw) | |||
220 | goto authsock_err; | 223 | goto authsock_err; |
221 | 224 | ||
222 | /* Allocate a channel for the authentication agent socket. */ | 225 | /* Allocate a channel for the authentication agent socket. */ |
223 | nc = channel_new("auth socket", | 226 | nc = channel_new(ssh, "auth socket", |
224 | SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, | 227 | SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, |
225 | CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, | 228 | CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, |
226 | 0, "auth socket", 1); | 229 | 0, "auth socket", 1); |
@@ -250,8 +253,42 @@ display_loginmsg(void) | |||
250 | } | 253 | } |
251 | } | 254 | } |
252 | 255 | ||
256 | static void | ||
257 | prepare_auth_info_file(struct passwd *pw, struct sshbuf *info) | ||
258 | { | ||
259 | int fd = -1, success = 0; | ||
260 | |||
261 | if (!options.expose_userauth_info || info == NULL) | ||
262 | return; | ||
263 | |||
264 | temporarily_use_uid(pw); | ||
265 | auth_info_file = xstrdup("/tmp/sshauth.XXXXXXXXXXXXXXX"); | ||
266 | if ((fd = mkstemp(auth_info_file)) == -1) { | ||
267 | error("%s: mkstemp: %s", __func__, strerror(errno)); | ||
268 | goto out; | ||
269 | } | ||
270 | if (atomicio(vwrite, fd, sshbuf_mutable_ptr(info), | ||
271 | sshbuf_len(info)) != sshbuf_len(info)) { | ||
272 | error("%s: write: %s", __func__, strerror(errno)); | ||
273 | goto out; | ||
274 | } | ||
275 | if (close(fd) != 0) { | ||
276 | error("%s: close: %s", __func__, strerror(errno)); | ||
277 | goto out; | ||
278 | } | ||
279 | success = 1; | ||
280 | out: | ||
281 | if (!success) { | ||
282 | if (fd != -1) | ||
283 | close(fd); | ||
284 | free(auth_info_file); | ||
285 | auth_info_file = NULL; | ||
286 | } | ||
287 | restore_uid(); | ||
288 | } | ||
289 | |||
253 | void | 290 | void |
254 | do_authenticated(Authctxt *authctxt) | 291 | do_authenticated(struct ssh *ssh, Authctxt *authctxt) |
255 | { | 292 | { |
256 | setproctitle("%s", authctxt->pw->pw_name); | 293 | setproctitle("%s", authctxt->pw->pw_name); |
257 | 294 | ||
@@ -259,14 +296,17 @@ do_authenticated(Authctxt *authctxt) | |||
259 | /* XXX - streamlocal? */ | 296 | /* XXX - streamlocal? */ |
260 | if (no_port_forwarding_flag || options.disable_forwarding || | 297 | if (no_port_forwarding_flag || options.disable_forwarding || |
261 | (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) | 298 | (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) |
262 | channel_disable_adm_local_opens(); | 299 | channel_disable_adm_local_opens(ssh); |
263 | else | 300 | else |
264 | channel_permit_all_opens(); | 301 | channel_permit_all_opens(ssh); |
265 | 302 | ||
266 | auth_debug_send(); | 303 | auth_debug_send(); |
267 | 304 | ||
268 | do_authenticated2(authctxt); | 305 | prepare_auth_info_file(authctxt->pw, authctxt->session_info); |
269 | do_cleanup(authctxt); | 306 | |
307 | do_authenticated2(ssh, authctxt); | ||
308 | |||
309 | do_cleanup(ssh, authctxt); | ||
270 | } | 310 | } |
271 | 311 | ||
272 | /* Check untrusted xauth strings for metacharacters */ | 312 | /* Check untrusted xauth strings for metacharacters */ |
@@ -291,7 +331,7 @@ xauth_valid_string(const char *s) | |||
291 | * setting up file descriptors and such. | 331 | * setting up file descriptors and such. |
292 | */ | 332 | */ |
293 | int | 333 | int |
294 | do_exec_no_pty(Session *s, const char *command) | 334 | do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) |
295 | { | 335 | { |
296 | pid_t pid; | 336 | pid_t pid; |
297 | 337 | ||
@@ -364,10 +404,6 @@ do_exec_no_pty(Session *s, const char *command) | |||
364 | case 0: | 404 | case 0: |
365 | is_child = 1; | 405 | is_child = 1; |
366 | 406 | ||
367 | /* Child. Reinitialize the log since the pid has changed. */ | ||
368 | log_init(__progname, options.log_level, | ||
369 | options.log_facility, log_stderr); | ||
370 | |||
371 | /* | 407 | /* |
372 | * Create a new session and process group since the 4.4BSD | 408 | * Create a new session and process group since the 4.4BSD |
373 | * setlogin() affects the entire process group. | 409 | * setlogin() affects the entire process group. |
@@ -420,7 +456,7 @@ do_exec_no_pty(Session *s, const char *command) | |||
420 | #endif | 456 | #endif |
421 | 457 | ||
422 | /* Do processing for the child (exec command etc). */ | 458 | /* Do processing for the child (exec command etc). */ |
423 | do_child(s, command); | 459 | do_child(ssh, s, command); |
424 | /* NOTREACHED */ | 460 | /* NOTREACHED */ |
425 | default: | 461 | default: |
426 | break; | 462 | break; |
@@ -451,7 +487,7 @@ do_exec_no_pty(Session *s, const char *command) | |||
451 | close(pout[1]); | 487 | close(pout[1]); |
452 | close(perr[1]); | 488 | close(perr[1]); |
453 | 489 | ||
454 | session_set_fds(s, pin[1], pout[0], perr[0], | 490 | session_set_fds(ssh, s, pin[1], pout[0], perr[0], |
455 | s->is_subsystem, 0); | 491 | s->is_subsystem, 0); |
456 | #else | 492 | #else |
457 | /* We are the parent. Close the child sides of the socket pairs. */ | 493 | /* We are the parent. Close the child sides of the socket pairs. */ |
@@ -475,7 +511,7 @@ do_exec_no_pty(Session *s, const char *command) | |||
475 | * lastlog, and other such operations. | 511 | * lastlog, and other such operations. |
476 | */ | 512 | */ |
477 | int | 513 | int |
478 | do_exec_pty(Session *s, const char *command) | 514 | do_exec_pty(struct ssh *ssh, Session *s, const char *command) |
479 | { | 515 | { |
480 | int fdout, ptyfd, ttyfd, ptymaster; | 516 | int fdout, ptyfd, ttyfd, ptymaster; |
481 | pid_t pid; | 517 | pid_t pid; |
@@ -522,9 +558,6 @@ do_exec_pty(Session *s, const char *command) | |||
522 | close(fdout); | 558 | close(fdout); |
523 | close(ptymaster); | 559 | close(ptymaster); |
524 | 560 | ||
525 | /* Child. Reinitialize the log because the pid has changed. */ | ||
526 | log_init(__progname, options.log_level, | ||
527 | options.log_facility, log_stderr); | ||
528 | /* Close the master side of the pseudo tty. */ | 561 | /* Close the master side of the pseudo tty. */ |
529 | close(ptyfd); | 562 | close(ptyfd); |
530 | 563 | ||
@@ -547,13 +580,13 @@ do_exec_pty(Session *s, const char *command) | |||
547 | cray_init_job(s->pw); /* set up cray jid and tmpdir */ | 580 | cray_init_job(s->pw); /* set up cray jid and tmpdir */ |
548 | #endif /* _UNICOS */ | 581 | #endif /* _UNICOS */ |
549 | #ifndef HAVE_OSF_SIA | 582 | #ifndef HAVE_OSF_SIA |
550 | do_login(s, command); | 583 | do_login(ssh, s, command); |
551 | #endif | 584 | #endif |
552 | /* | 585 | /* |
553 | * Do common processing for the child, such as execing | 586 | * Do common processing for the child, such as execing |
554 | * the command. | 587 | * the command. |
555 | */ | 588 | */ |
556 | do_child(s, command); | 589 | do_child(ssh, s, command); |
557 | /* NOTREACHED */ | 590 | /* NOTREACHED */ |
558 | default: | 591 | default: |
559 | break; | 592 | break; |
@@ -575,7 +608,7 @@ do_exec_pty(Session *s, const char *command) | |||
575 | s->ptymaster = ptymaster; | 608 | s->ptymaster = ptymaster; |
576 | packet_set_interactive(1, | 609 | packet_set_interactive(1, |
577 | options.ip_qos_interactive, options.ip_qos_bulk); | 610 | options.ip_qos_interactive, options.ip_qos_bulk); |
578 | session_set_fds(s, ptyfd, fdout, -1, 1, 1); | 611 | session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); |
579 | return 0; | 612 | return 0; |
580 | } | 613 | } |
581 | 614 | ||
@@ -613,9 +646,8 @@ do_pre_login(Session *s) | |||
613 | * to be forced, execute that instead. | 646 | * to be forced, execute that instead. |
614 | */ | 647 | */ |
615 | int | 648 | int |
616 | do_exec(Session *s, const char *command) | 649 | do_exec(struct ssh *ssh, Session *s, const char *command) |
617 | { | 650 | { |
618 | struct ssh *ssh = active_state; /* XXX */ | ||
619 | int ret; | 651 | int ret; |
620 | const char *forced = NULL, *tty = NULL; | 652 | const char *forced = NULL, *tty = NULL; |
621 | char session_type[1024]; | 653 | char session_type[1024]; |
@@ -674,9 +706,9 @@ do_exec(Session *s, const char *command) | |||
674 | } | 706 | } |
675 | #endif | 707 | #endif |
676 | if (s->ttyfd != -1) | 708 | if (s->ttyfd != -1) |
677 | ret = do_exec_pty(s, command); | 709 | ret = do_exec_pty(ssh, s, command); |
678 | else | 710 | else |
679 | ret = do_exec_no_pty(s, command); | 711 | ret = do_exec_no_pty(ssh, s, command); |
680 | 712 | ||
681 | original_command = NULL; | 713 | original_command = NULL; |
682 | 714 | ||
@@ -692,9 +724,8 @@ do_exec(Session *s, const char *command) | |||
692 | 724 | ||
693 | /* administrative, login(1)-like work */ | 725 | /* administrative, login(1)-like work */ |
694 | void | 726 | void |
695 | do_login(Session *s, const char *command) | 727 | do_login(struct ssh *ssh, Session *s, const char *command) |
696 | { | 728 | { |
697 | struct ssh *ssh = active_state; /* XXX */ | ||
698 | socklen_t fromlen; | 729 | socklen_t fromlen; |
699 | struct sockaddr_storage from; | 730 | struct sockaddr_storage from; |
700 | struct passwd * pw = s->pw; | 731 | struct passwd * pw = s->pw; |
@@ -792,65 +823,6 @@ check_quietlogin(Session *s, const char *command) | |||
792 | } | 823 | } |
793 | 824 | ||
794 | /* | 825 | /* |
795 | * Sets the value of the given variable in the environment. If the variable | ||
796 | * already exists, its value is overridden. | ||
797 | */ | ||
798 | void | ||
799 | child_set_env(char ***envp, u_int *envsizep, const char *name, | ||
800 | const char *value) | ||
801 | { | ||
802 | char **env; | ||
803 | u_int envsize; | ||
804 | u_int i, namelen; | ||
805 | |||
806 | if (strchr(name, '=') != NULL) { | ||
807 | error("Invalid environment variable \"%.100s\"", name); | ||
808 | return; | ||
809 | } | ||
810 | |||
811 | /* | ||
812 | * If we're passed an uninitialized list, allocate a single null | ||
813 | * entry before continuing. | ||
814 | */ | ||
815 | if (*envp == NULL && *envsizep == 0) { | ||
816 | *envp = xmalloc(sizeof(char *)); | ||
817 | *envp[0] = NULL; | ||
818 | *envsizep = 1; | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * Find the slot where the value should be stored. If the variable | ||
823 | * already exists, we reuse the slot; otherwise we append a new slot | ||
824 | * at the end of the array, expanding if necessary. | ||
825 | */ | ||
826 | env = *envp; | ||
827 | namelen = strlen(name); | ||
828 | for (i = 0; env[i]; i++) | ||
829 | if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') | ||
830 | break; | ||
831 | if (env[i]) { | ||
832 | /* Reuse the slot. */ | ||
833 | free(env[i]); | ||
834 | } else { | ||
835 | /* New variable. Expand if necessary. */ | ||
836 | envsize = *envsizep; | ||
837 | if (i >= envsize - 1) { | ||
838 | if (envsize >= 1000) | ||
839 | fatal("child_set_env: too many env vars"); | ||
840 | envsize += 50; | ||
841 | env = (*envp) = xreallocarray(env, envsize, sizeof(char *)); | ||
842 | *envsizep = envsize; | ||
843 | } | ||
844 | /* Need to set the NULL pointer at end of array beyond the new slot. */ | ||
845 | env[i + 1] = NULL; | ||
846 | } | ||
847 | |||
848 | /* Allocate space and format the variable in the appropriate slot. */ | ||
849 | env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); | ||
850 | snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); | ||
851 | } | ||
852 | |||
853 | /* | ||
854 | * Reads environment variables from the given file and adds/overrides them | 826 | * Reads environment variables from the given file and adds/overrides them |
855 | * into the environment. If the file does not exist, this does nothing. | 827 | * into the environment. If the file does not exist, this does nothing. |
856 | * Otherwise, it must consist of empty lines, comments (line starts with '#') | 828 | * Otherwise, it must consist of empty lines, comments (line starts with '#') |
@@ -951,8 +923,9 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid) | |||
951 | } | 923 | } |
952 | #endif /* HAVE_ETC_DEFAULT_LOGIN */ | 924 | #endif /* HAVE_ETC_DEFAULT_LOGIN */ |
953 | 925 | ||
954 | void | 926 | static void |
955 | copy_environment(char **source, char ***env, u_int *envsize) | 927 | copy_environment_blacklist(char **source, char ***env, u_int *envsize, |
928 | const char *blacklist) | ||
956 | { | 929 | { |
957 | char *var_name, *var_val; | 930 | char *var_name, *var_val; |
958 | int i; | 931 | int i; |
@@ -968,17 +941,25 @@ copy_environment(char **source, char ***env, u_int *envsize) | |||
968 | } | 941 | } |
969 | *var_val++ = '\0'; | 942 | *var_val++ = '\0'; |
970 | 943 | ||
971 | debug3("Copy environment: %s=%s", var_name, var_val); | 944 | if (blacklist == NULL || |
972 | child_set_env(env, envsize, var_name, var_val); | 945 | match_pattern_list(var_name, blacklist, 0) != 1) { |
946 | debug3("Copy environment: %s=%s", var_name, var_val); | ||
947 | child_set_env(env, envsize, var_name, var_val); | ||
948 | } | ||
973 | 949 | ||
974 | free(var_name); | 950 | free(var_name); |
975 | } | 951 | } |
976 | } | 952 | } |
977 | 953 | ||
954 | void | ||
955 | copy_environment(char **source, char ***env, u_int *envsize) | ||
956 | { | ||
957 | copy_environment_blacklist(source, env, envsize, NULL); | ||
958 | } | ||
959 | |||
978 | static char ** | 960 | static char ** |
979 | do_setup_env(Session *s, const char *shell) | 961 | do_setup_env(struct ssh *ssh, Session *s, const char *shell) |
980 | { | 962 | { |
981 | struct ssh *ssh = active_state; /* XXX */ | ||
982 | char buf[256]; | 963 | char buf[256]; |
983 | u_int i, envsize; | 964 | u_int i, envsize; |
984 | char **env, *laddr; | 965 | char **env, *laddr; |
@@ -1085,6 +1066,8 @@ do_setup_env(Session *s, const char *shell) | |||
1085 | free(laddr); | 1066 | free(laddr); |
1086 | child_set_env(&env, &envsize, "SSH_CONNECTION", buf); | 1067 | child_set_env(&env, &envsize, "SSH_CONNECTION", buf); |
1087 | 1068 | ||
1069 | if (auth_info_file != NULL) | ||
1070 | child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file); | ||
1088 | if (s->ttyfd != -1) | 1071 | if (s->ttyfd != -1) |
1089 | child_set_env(&env, &envsize, "SSH_TTY", s->tty); | 1072 | child_set_env(&env, &envsize, "SSH_TTY", s->tty); |
1090 | if (s->term) | 1073 | if (s->term) |
@@ -1134,12 +1117,16 @@ do_setup_env(Session *s, const char *shell) | |||
1134 | if (options.use_pam) { | 1117 | if (options.use_pam) { |
1135 | char **p; | 1118 | char **p; |
1136 | 1119 | ||
1120 | /* | ||
1121 | * Don't allow SSH_AUTH_INFO variables posted to PAM to leak | ||
1122 | * back into the environment. | ||
1123 | */ | ||
1137 | p = fetch_pam_child_environment(); | 1124 | p = fetch_pam_child_environment(); |
1138 | copy_environment(p, &env, &envsize); | 1125 | copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*"); |
1139 | free_pam_environment(p); | 1126 | free_pam_environment(p); |
1140 | 1127 | ||
1141 | p = fetch_pam_environment(); | 1128 | p = fetch_pam_environment(); |
1142 | copy_environment(p, &env, &envsize); | 1129 | copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*"); |
1143 | free_pam_environment(p); | 1130 | free_pam_environment(p); |
1144 | } | 1131 | } |
1145 | #endif /* USE_PAM */ | 1132 | #endif /* USE_PAM */ |
@@ -1431,7 +1418,7 @@ do_pwchange(Session *s) | |||
1431 | } | 1418 | } |
1432 | 1419 | ||
1433 | static void | 1420 | static void |
1434 | child_close_fds(void) | 1421 | child_close_fds(struct ssh *ssh) |
1435 | { | 1422 | { |
1436 | extern int auth_sock; | 1423 | extern int auth_sock; |
1437 | 1424 | ||
@@ -1451,7 +1438,7 @@ child_close_fds(void) | |||
1451 | * open in the parent. | 1438 | * open in the parent. |
1452 | */ | 1439 | */ |
1453 | /* XXX better use close-on-exec? -markus */ | 1440 | /* XXX better use close-on-exec? -markus */ |
1454 | channel_close_all(); | 1441 | channel_close_all(ssh); |
1455 | 1442 | ||
1456 | /* | 1443 | /* |
1457 | * Close any extra file descriptors. Note that there may still be | 1444 | * Close any extra file descriptors. Note that there may still be |
@@ -1475,7 +1462,7 @@ child_close_fds(void) | |||
1475 | */ | 1462 | */ |
1476 | #define ARGV_MAX 10 | 1463 | #define ARGV_MAX 10 |
1477 | void | 1464 | void |
1478 | do_child(Session *s, const char *command) | 1465 | do_child(struct ssh *ssh, Session *s, const char *command) |
1479 | { | 1466 | { |
1480 | extern char **environ; | 1467 | extern char **environ; |
1481 | char **env; | 1468 | char **env; |
@@ -1486,11 +1473,12 @@ do_child(Session *s, const char *command) | |||
1486 | 1473 | ||
1487 | /* remove hostkey from the child's memory */ | 1474 | /* remove hostkey from the child's memory */ |
1488 | destroy_sensitive_data(); | 1475 | destroy_sensitive_data(); |
1476 | packet_clear_keys(); | ||
1489 | 1477 | ||
1490 | /* Force a password change */ | 1478 | /* Force a password change */ |
1491 | if (s->authctxt->force_pwchange) { | 1479 | if (s->authctxt->force_pwchange) { |
1492 | do_setusercontext(pw, s->authctxt->role); | 1480 | do_setusercontext(pw, s->authctxt->role); |
1493 | child_close_fds(); | 1481 | child_close_fds(ssh); |
1494 | do_pwchange(s); | 1482 | do_pwchange(s); |
1495 | exit(1); | 1483 | exit(1); |
1496 | } | 1484 | } |
@@ -1539,7 +1527,7 @@ do_child(Session *s, const char *command) | |||
1539 | * Make sure $SHELL points to the shell from the password file, | 1527 | * Make sure $SHELL points to the shell from the password file, |
1540 | * even if shell is overridden from login.conf | 1528 | * even if shell is overridden from login.conf |
1541 | */ | 1529 | */ |
1542 | env = do_setup_env(s, shell); | 1530 | env = do_setup_env(ssh, s, shell); |
1543 | 1531 | ||
1544 | #ifdef HAVE_LOGIN_CAP | 1532 | #ifdef HAVE_LOGIN_CAP |
1545 | shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); | 1533 | shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); |
@@ -1552,7 +1540,7 @@ do_child(Session *s, const char *command) | |||
1552 | * closed before building the environment, as we call | 1540 | * closed before building the environment, as we call |
1553 | * ssh_remote_ipaddr there. | 1541 | * ssh_remote_ipaddr there. |
1554 | */ | 1542 | */ |
1555 | child_close_fds(); | 1543 | child_close_fds(ssh); |
1556 | 1544 | ||
1557 | /* | 1545 | /* |
1558 | * Must take new environment into use so that .ssh/rc, | 1546 | * Must take new environment into use so that .ssh/rc, |
@@ -1710,8 +1698,8 @@ session_new(void) | |||
1710 | return NULL; | 1698 | return NULL; |
1711 | debug2("%s: allocate (allocated %d max %d)", | 1699 | debug2("%s: allocate (allocated %d max %d)", |
1712 | __func__, sessions_nalloc, options.max_sessions); | 1700 | __func__, sessions_nalloc, options.max_sessions); |
1713 | tmp = xreallocarray(sessions, sessions_nalloc + 1, | 1701 | tmp = xrecallocarray(sessions, sessions_nalloc, |
1714 | sizeof(*sessions)); | 1702 | sessions_nalloc + 1, sizeof(*sessions)); |
1715 | if (tmp == NULL) { | 1703 | if (tmp == NULL) { |
1716 | error("%s: cannot allocate %d sessions", | 1704 | error("%s: cannot allocate %d sessions", |
1717 | __func__, sessions_nalloc + 1); | 1705 | __func__, sessions_nalloc + 1); |
@@ -1849,7 +1837,7 @@ session_by_pid(pid_t pid) | |||
1849 | } | 1837 | } |
1850 | 1838 | ||
1851 | static int | 1839 | static int |
1852 | session_window_change_req(Session *s) | 1840 | session_window_change_req(struct ssh *ssh, Session *s) |
1853 | { | 1841 | { |
1854 | s->col = packet_get_int(); | 1842 | s->col = packet_get_int(); |
1855 | s->row = packet_get_int(); | 1843 | s->row = packet_get_int(); |
@@ -1861,7 +1849,7 @@ session_window_change_req(Session *s) | |||
1861 | } | 1849 | } |
1862 | 1850 | ||
1863 | static int | 1851 | static int |
1864 | session_pty_req(Session *s) | 1852 | session_pty_req(struct ssh *ssh, Session *s) |
1865 | { | 1853 | { |
1866 | u_int len; | 1854 | u_int len; |
1867 | int n_bytes; | 1855 | int n_bytes; |
@@ -1914,7 +1902,7 @@ session_pty_req(Session *s) | |||
1914 | } | 1902 | } |
1915 | 1903 | ||
1916 | static int | 1904 | static int |
1917 | session_subsystem_req(Session *s) | 1905 | session_subsystem_req(struct ssh *ssh, Session *s) |
1918 | { | 1906 | { |
1919 | struct stat st; | 1907 | struct stat st; |
1920 | u_int len; | 1908 | u_int len; |
@@ -1941,7 +1929,7 @@ session_subsystem_req(Session *s) | |||
1941 | s->is_subsystem = SUBSYSTEM_EXT; | 1929 | s->is_subsystem = SUBSYSTEM_EXT; |
1942 | debug("subsystem: exec() %s", cmd); | 1930 | debug("subsystem: exec() %s", cmd); |
1943 | } | 1931 | } |
1944 | success = do_exec(s, cmd) == 0; | 1932 | success = do_exec(ssh, s, cmd) == 0; |
1945 | break; | 1933 | break; |
1946 | } | 1934 | } |
1947 | } | 1935 | } |
@@ -1954,7 +1942,7 @@ session_subsystem_req(Session *s) | |||
1954 | } | 1942 | } |
1955 | 1943 | ||
1956 | static int | 1944 | static int |
1957 | session_x11_req(Session *s) | 1945 | session_x11_req(struct ssh *ssh, Session *s) |
1958 | { | 1946 | { |
1959 | int success; | 1947 | int success; |
1960 | 1948 | ||
@@ -1971,7 +1959,7 @@ session_x11_req(Session *s) | |||
1971 | 1959 | ||
1972 | if (xauth_valid_string(s->auth_proto) && | 1960 | if (xauth_valid_string(s->auth_proto) && |
1973 | xauth_valid_string(s->auth_data)) | 1961 | xauth_valid_string(s->auth_data)) |
1974 | success = session_setup_x11fwd(s); | 1962 | success = session_setup_x11fwd(ssh, s); |
1975 | else { | 1963 | else { |
1976 | success = 0; | 1964 | success = 0; |
1977 | error("Invalid X11 forwarding data"); | 1965 | error("Invalid X11 forwarding data"); |
@@ -1986,26 +1974,26 @@ session_x11_req(Session *s) | |||
1986 | } | 1974 | } |
1987 | 1975 | ||
1988 | static int | 1976 | static int |
1989 | session_shell_req(Session *s) | 1977 | session_shell_req(struct ssh *ssh, Session *s) |
1990 | { | 1978 | { |
1991 | packet_check_eom(); | 1979 | packet_check_eom(); |
1992 | return do_exec(s, NULL) == 0; | 1980 | return do_exec(ssh, s, NULL) == 0; |
1993 | } | 1981 | } |
1994 | 1982 | ||
1995 | static int | 1983 | static int |
1996 | session_exec_req(Session *s) | 1984 | session_exec_req(struct ssh *ssh, Session *s) |
1997 | { | 1985 | { |
1998 | u_int len, success; | 1986 | u_int len, success; |
1999 | 1987 | ||
2000 | char *command = packet_get_string(&len); | 1988 | char *command = packet_get_string(&len); |
2001 | packet_check_eom(); | 1989 | packet_check_eom(); |
2002 | success = do_exec(s, command) == 0; | 1990 | success = do_exec(ssh, s, command) == 0; |
2003 | free(command); | 1991 | free(command); |
2004 | return success; | 1992 | return success; |
2005 | } | 1993 | } |
2006 | 1994 | ||
2007 | static int | 1995 | static int |
2008 | session_break_req(Session *s) | 1996 | session_break_req(struct ssh *ssh, Session *s) |
2009 | { | 1997 | { |
2010 | 1998 | ||
2011 | packet_get_int(); /* ignored */ | 1999 | packet_get_int(); /* ignored */ |
@@ -2017,7 +2005,7 @@ session_break_req(Session *s) | |||
2017 | } | 2005 | } |
2018 | 2006 | ||
2019 | static int | 2007 | static int |
2020 | session_env_req(Session *s) | 2008 | session_env_req(struct ssh *ssh, Session *s) |
2021 | { | 2009 | { |
2022 | char *name, *val; | 2010 | char *name, *val; |
2023 | u_int name_len, val_len, i; | 2011 | u_int name_len, val_len, i; |
@@ -2035,8 +2023,8 @@ session_env_req(Session *s) | |||
2035 | for (i = 0; i < options.num_accept_env; i++) { | 2023 | for (i = 0; i < options.num_accept_env; i++) { |
2036 | if (match_pattern(name, options.accept_env[i])) { | 2024 | if (match_pattern(name, options.accept_env[i])) { |
2037 | debug2("Setting env %d: %s=%s", s->num_env, name, val); | 2025 | debug2("Setting env %d: %s=%s", s->num_env, name, val); |
2038 | s->env = xreallocarray(s->env, s->num_env + 1, | 2026 | s->env = xrecallocarray(s->env, s->num_env, |
2039 | sizeof(*s->env)); | 2027 | s->num_env + 1, sizeof(*s->env)); |
2040 | s->env[s->num_env].name = name; | 2028 | s->env[s->num_env].name = name; |
2041 | s->env[s->num_env].val = val; | 2029 | s->env[s->num_env].val = val; |
2042 | s->num_env++; | 2030 | s->num_env++; |
@@ -2052,7 +2040,7 @@ session_env_req(Session *s) | |||
2052 | } | 2040 | } |
2053 | 2041 | ||
2054 | static int | 2042 | static int |
2055 | session_auth_agent_req(Session *s) | 2043 | session_auth_agent_req(struct ssh *ssh, Session *s) |
2056 | { | 2044 | { |
2057 | static int called = 0; | 2045 | static int called = 0; |
2058 | packet_check_eom(); | 2046 | packet_check_eom(); |
@@ -2064,22 +2052,21 @@ session_auth_agent_req(Session *s) | |||
2064 | return 0; | 2052 | return 0; |
2065 | } else { | 2053 | } else { |
2066 | called = 1; | 2054 | called = 1; |
2067 | return auth_input_request_forwarding(s->pw); | 2055 | return auth_input_request_forwarding(ssh, s->pw); |
2068 | } | 2056 | } |
2069 | } | 2057 | } |
2070 | 2058 | ||
2071 | int | 2059 | int |
2072 | session_input_channel_req(Channel *c, const char *rtype) | 2060 | session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype) |
2073 | { | 2061 | { |
2074 | int success = 0; | 2062 | int success = 0; |
2075 | Session *s; | 2063 | Session *s; |
2076 | 2064 | ||
2077 | if ((s = session_by_channel(c->self)) == NULL) { | 2065 | if ((s = session_by_channel(c->self)) == NULL) { |
2078 | logit("session_input_channel_req: no session %d req %.100s", | 2066 | logit("%s: no session %d req %.100s", __func__, c->self, rtype); |
2079 | c->self, rtype); | ||
2080 | return 0; | 2067 | return 0; |
2081 | } | 2068 | } |
2082 | debug("session_input_channel_req: session %d req %s", s->self, rtype); | 2069 | debug("%s: session %d req %s", __func__, s->self, rtype); |
2083 | 2070 | ||
2084 | /* | 2071 | /* |
2085 | * a session is in LARVAL state until a shell, a command | 2072 | * a session is in LARVAL state until a shell, a command |
@@ -2087,33 +2074,33 @@ session_input_channel_req(Channel *c, const char *rtype) | |||
2087 | */ | 2074 | */ |
2088 | if (c->type == SSH_CHANNEL_LARVAL) { | 2075 | if (c->type == SSH_CHANNEL_LARVAL) { |
2089 | if (strcmp(rtype, "shell") == 0) { | 2076 | if (strcmp(rtype, "shell") == 0) { |
2090 | success = session_shell_req(s); | 2077 | success = session_shell_req(ssh, s); |
2091 | } else if (strcmp(rtype, "exec") == 0) { | 2078 | } else if (strcmp(rtype, "exec") == 0) { |
2092 | success = session_exec_req(s); | 2079 | success = session_exec_req(ssh, s); |
2093 | } else if (strcmp(rtype, "pty-req") == 0) { | 2080 | } else if (strcmp(rtype, "pty-req") == 0) { |
2094 | success = session_pty_req(s); | 2081 | success = session_pty_req(ssh, s); |
2095 | } else if (strcmp(rtype, "x11-req") == 0) { | 2082 | } else if (strcmp(rtype, "x11-req") == 0) { |
2096 | success = session_x11_req(s); | 2083 | success = session_x11_req(ssh, s); |
2097 | } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { | 2084 | } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { |
2098 | success = session_auth_agent_req(s); | 2085 | success = session_auth_agent_req(ssh, s); |
2099 | } else if (strcmp(rtype, "subsystem") == 0) { | 2086 | } else if (strcmp(rtype, "subsystem") == 0) { |
2100 | success = session_subsystem_req(s); | 2087 | success = session_subsystem_req(ssh, s); |
2101 | } else if (strcmp(rtype, "env") == 0) { | 2088 | } else if (strcmp(rtype, "env") == 0) { |
2102 | success = session_env_req(s); | 2089 | success = session_env_req(ssh, s); |
2103 | } | 2090 | } |
2104 | } | 2091 | } |
2105 | if (strcmp(rtype, "window-change") == 0) { | 2092 | if (strcmp(rtype, "window-change") == 0) { |
2106 | success = session_window_change_req(s); | 2093 | success = session_window_change_req(ssh, s); |
2107 | } else if (strcmp(rtype, "break") == 0) { | 2094 | } else if (strcmp(rtype, "break") == 0) { |
2108 | success = session_break_req(s); | 2095 | success = session_break_req(ssh, s); |
2109 | } | 2096 | } |
2110 | 2097 | ||
2111 | return success; | 2098 | return success; |
2112 | } | 2099 | } |
2113 | 2100 | ||
2114 | void | 2101 | void |
2115 | session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, | 2102 | session_set_fds(struct ssh *ssh, Session *s, |
2116 | int is_tty) | 2103 | int fdin, int fdout, int fderr, int ignore_fderr, int is_tty) |
2117 | { | 2104 | { |
2118 | /* | 2105 | /* |
2119 | * now that have a child and a pipe to the child, | 2106 | * now that have a child and a pipe to the child, |
@@ -2121,7 +2108,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, | |||
2121 | */ | 2108 | */ |
2122 | if (s->chanid == -1) | 2109 | if (s->chanid == -1) |
2123 | fatal("no channel for session %d", s->self); | 2110 | fatal("no channel for session %d", s->self); |
2124 | channel_set_fds(s->chanid, | 2111 | channel_set_fds(ssh, s->chanid, |
2125 | fdout, fdin, fderr, | 2112 | fdout, fdin, fderr, |
2126 | ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, | 2113 | ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, |
2127 | 1, is_tty, CHAN_SES_WINDOW_DEFAULT); | 2114 | 1, is_tty, CHAN_SES_WINDOW_DEFAULT); |
@@ -2192,40 +2179,40 @@ sig2name(int sig) | |||
2192 | } | 2179 | } |
2193 | 2180 | ||
2194 | static void | 2181 | static void |
2195 | session_close_x11(int id) | 2182 | session_close_x11(struct ssh *ssh, int id) |
2196 | { | 2183 | { |
2197 | Channel *c; | 2184 | Channel *c; |
2198 | 2185 | ||
2199 | if ((c = channel_by_id(id)) == NULL) { | 2186 | if ((c = channel_by_id(ssh, id)) == NULL) { |
2200 | debug("session_close_x11: x11 channel %d missing", id); | 2187 | debug("%s: x11 channel %d missing", __func__, id); |
2201 | } else { | 2188 | } else { |
2202 | /* Detach X11 listener */ | 2189 | /* Detach X11 listener */ |
2203 | debug("session_close_x11: detach x11 channel %d", id); | 2190 | debug("%s: detach x11 channel %d", __func__, id); |
2204 | channel_cancel_cleanup(id); | 2191 | channel_cancel_cleanup(ssh, id); |
2205 | if (c->ostate != CHAN_OUTPUT_CLOSED) | 2192 | if (c->ostate != CHAN_OUTPUT_CLOSED) |
2206 | chan_mark_dead(c); | 2193 | chan_mark_dead(ssh, c); |
2207 | } | 2194 | } |
2208 | } | 2195 | } |
2209 | 2196 | ||
2210 | static void | 2197 | static void |
2211 | session_close_single_x11(int id, void *arg) | 2198 | session_close_single_x11(struct ssh *ssh, int id, void *arg) |
2212 | { | 2199 | { |
2213 | Session *s; | 2200 | Session *s; |
2214 | u_int i; | 2201 | u_int i; |
2215 | 2202 | ||
2216 | debug3("session_close_single_x11: channel %d", id); | 2203 | debug3("%s: channel %d", __func__, id); |
2217 | channel_cancel_cleanup(id); | 2204 | channel_cancel_cleanup(ssh, id); |
2218 | if ((s = session_by_x11_channel(id)) == NULL) | 2205 | if ((s = session_by_x11_channel(id)) == NULL) |
2219 | fatal("session_close_single_x11: no x11 channel %d", id); | 2206 | fatal("%s: no x11 channel %d", __func__, id); |
2220 | for (i = 0; s->x11_chanids[i] != -1; i++) { | 2207 | for (i = 0; s->x11_chanids[i] != -1; i++) { |
2221 | debug("session_close_single_x11: session %d: " | 2208 | debug("%s: session %d: closing channel %d", |
2222 | "closing channel %d", s->self, s->x11_chanids[i]); | 2209 | __func__, s->self, s->x11_chanids[i]); |
2223 | /* | 2210 | /* |
2224 | * The channel "id" is already closing, but make sure we | 2211 | * The channel "id" is already closing, but make sure we |
2225 | * close all of its siblings. | 2212 | * close all of its siblings. |
2226 | */ | 2213 | */ |
2227 | if (s->x11_chanids[i] != id) | 2214 | if (s->x11_chanids[i] != id) |
2228 | session_close_x11(s->x11_chanids[i]); | 2215 | session_close_x11(ssh, s->x11_chanids[i]); |
2229 | } | 2216 | } |
2230 | free(s->x11_chanids); | 2217 | free(s->x11_chanids); |
2231 | s->x11_chanids = NULL; | 2218 | s->x11_chanids = NULL; |
@@ -2240,22 +2227,22 @@ session_close_single_x11(int id, void *arg) | |||
2240 | } | 2227 | } |
2241 | 2228 | ||
2242 | static void | 2229 | static void |
2243 | session_exit_message(Session *s, int status) | 2230 | session_exit_message(struct ssh *ssh, Session *s, int status) |
2244 | { | 2231 | { |
2245 | Channel *c; | 2232 | Channel *c; |
2246 | 2233 | ||
2247 | if ((c = channel_lookup(s->chanid)) == NULL) | 2234 | if ((c = channel_lookup(ssh, s->chanid)) == NULL) |
2248 | fatal("session_exit_message: session %d: no channel %d", | 2235 | fatal("%s: session %d: no channel %d", |
2249 | s->self, s->chanid); | 2236 | __func__, s->self, s->chanid); |
2250 | debug("session_exit_message: session %d channel %d pid %ld", | 2237 | debug("%s: session %d channel %d pid %ld", |
2251 | s->self, s->chanid, (long)s->pid); | 2238 | __func__, s->self, s->chanid, (long)s->pid); |
2252 | 2239 | ||
2253 | if (WIFEXITED(status)) { | 2240 | if (WIFEXITED(status)) { |
2254 | channel_request_start(s->chanid, "exit-status", 0); | 2241 | channel_request_start(ssh, s->chanid, "exit-status", 0); |
2255 | packet_put_int(WEXITSTATUS(status)); | 2242 | packet_put_int(WEXITSTATUS(status)); |
2256 | packet_send(); | 2243 | packet_send(); |
2257 | } else if (WIFSIGNALED(status)) { | 2244 | } else if (WIFSIGNALED(status)) { |
2258 | channel_request_start(s->chanid, "exit-signal", 0); | 2245 | channel_request_start(ssh, s->chanid, "exit-signal", 0); |
2259 | packet_put_cstring(sig2name(WTERMSIG(status))); | 2246 | packet_put_cstring(sig2name(WTERMSIG(status))); |
2260 | #ifdef WCOREDUMP | 2247 | #ifdef WCOREDUMP |
2261 | packet_put_char(WCOREDUMP(status)? 1 : 0); | 2248 | packet_put_char(WCOREDUMP(status)? 1 : 0); |
@@ -2271,14 +2258,14 @@ session_exit_message(Session *s, int status) | |||
2271 | } | 2258 | } |
2272 | 2259 | ||
2273 | /* disconnect channel */ | 2260 | /* disconnect channel */ |
2274 | debug("session_exit_message: release channel %d", s->chanid); | 2261 | debug("%s: release channel %d", __func__, s->chanid); |
2275 | 2262 | ||
2276 | /* | 2263 | /* |
2277 | * Adjust cleanup callback attachment to send close messages when | 2264 | * Adjust cleanup callback attachment to send close messages when |
2278 | * the channel gets EOF. The session will be then be closed | 2265 | * the channel gets EOF. The session will be then be closed |
2279 | * by session_close_by_channel when the childs close their fds. | 2266 | * by session_close_by_channel when the childs close their fds. |
2280 | */ | 2267 | */ |
2281 | channel_register_cleanup(c->self, session_close_by_channel, 1); | 2268 | channel_register_cleanup(ssh, c->self, session_close_by_channel, 1); |
2282 | 2269 | ||
2283 | /* | 2270 | /* |
2284 | * emulate a write failure with 'chan_write_failed', nobody will be | 2271 | * emulate a write failure with 'chan_write_failed', nobody will be |
@@ -2287,13 +2274,12 @@ session_exit_message(Session *s, int status) | |||
2287 | * be some more data waiting in the pipe. | 2274 | * be some more data waiting in the pipe. |
2288 | */ | 2275 | */ |
2289 | if (c->ostate != CHAN_OUTPUT_CLOSED) | 2276 | if (c->ostate != CHAN_OUTPUT_CLOSED) |
2290 | chan_write_failed(c); | 2277 | chan_write_failed(ssh, c); |
2291 | } | 2278 | } |
2292 | 2279 | ||
2293 | void | 2280 | void |
2294 | session_close(Session *s) | 2281 | session_close(struct ssh *ssh, Session *s) |
2295 | { | 2282 | { |
2296 | struct ssh *ssh = active_state; /* XXX */ | ||
2297 | u_int i; | 2283 | u_int i; |
2298 | 2284 | ||
2299 | verbose("Close session: user %s from %.200s port %d id %d", | 2285 | verbose("Close session: user %s from %.200s port %d id %d", |
@@ -2323,16 +2309,15 @@ session_close(Session *s) | |||
2323 | } | 2309 | } |
2324 | 2310 | ||
2325 | void | 2311 | void |
2326 | session_close_by_pid(pid_t pid, int status) | 2312 | session_close_by_pid(struct ssh *ssh, pid_t pid, int status) |
2327 | { | 2313 | { |
2328 | Session *s = session_by_pid(pid); | 2314 | Session *s = session_by_pid(pid); |
2329 | if (s == NULL) { | 2315 | if (s == NULL) { |
2330 | debug("session_close_by_pid: no session for pid %ld", | 2316 | debug("%s: no session for pid %ld", __func__, (long)pid); |
2331 | (long)pid); | ||
2332 | return; | 2317 | return; |
2333 | } | 2318 | } |
2334 | if (s->chanid != -1) | 2319 | if (s->chanid != -1) |
2335 | session_exit_message(s, status); | 2320 | session_exit_message(ssh, s, status); |
2336 | if (s->ttyfd != -1) | 2321 | if (s->ttyfd != -1) |
2337 | session_pty_cleanup(s); | 2322 | session_pty_cleanup(s); |
2338 | s->pid = 0; | 2323 | s->pid = 0; |
@@ -2343,19 +2328,18 @@ session_close_by_pid(pid_t pid, int status) | |||
2343 | * the session 'child' itself dies | 2328 | * the session 'child' itself dies |
2344 | */ | 2329 | */ |
2345 | void | 2330 | void |
2346 | session_close_by_channel(int id, void *arg) | 2331 | session_close_by_channel(struct ssh *ssh, int id, void *arg) |
2347 | { | 2332 | { |
2348 | Session *s = session_by_channel(id); | 2333 | Session *s = session_by_channel(id); |
2349 | u_int i; | 2334 | u_int i; |
2350 | 2335 | ||
2351 | if (s == NULL) { | 2336 | if (s == NULL) { |
2352 | debug("session_close_by_channel: no session for id %d", id); | 2337 | debug("%s: no session for id %d", __func__, id); |
2353 | return; | 2338 | return; |
2354 | } | 2339 | } |
2355 | debug("session_close_by_channel: channel %d child %ld", | 2340 | debug("%s: channel %d child %ld", __func__, id, (long)s->pid); |
2356 | id, (long)s->pid); | ||
2357 | if (s->pid != 0) { | 2341 | if (s->pid != 0) { |
2358 | debug("session_close_by_channel: channel %d: has child", id); | 2342 | debug("%s: channel %d: has child", __func__, id); |
2359 | /* | 2343 | /* |
2360 | * delay detach of session, but release pty, since | 2344 | * delay detach of session, but release pty, since |
2361 | * the fd's to the child are already closed | 2345 | * the fd's to the child are already closed |
@@ -2365,22 +2349,22 @@ session_close_by_channel(int id, void *arg) | |||
2365 | return; | 2349 | return; |
2366 | } | 2350 | } |
2367 | /* detach by removing callback */ | 2351 | /* detach by removing callback */ |
2368 | channel_cancel_cleanup(s->chanid); | 2352 | channel_cancel_cleanup(ssh, s->chanid); |
2369 | 2353 | ||
2370 | /* Close any X11 listeners associated with this session */ | 2354 | /* Close any X11 listeners associated with this session */ |
2371 | if (s->x11_chanids != NULL) { | 2355 | if (s->x11_chanids != NULL) { |
2372 | for (i = 0; s->x11_chanids[i] != -1; i++) { | 2356 | for (i = 0; s->x11_chanids[i] != -1; i++) { |
2373 | session_close_x11(s->x11_chanids[i]); | 2357 | session_close_x11(ssh, s->x11_chanids[i]); |
2374 | s->x11_chanids[i] = -1; | 2358 | s->x11_chanids[i] = -1; |
2375 | } | 2359 | } |
2376 | } | 2360 | } |
2377 | 2361 | ||
2378 | s->chanid = -1; | 2362 | s->chanid = -1; |
2379 | session_close(s); | 2363 | session_close(ssh, s); |
2380 | } | 2364 | } |
2381 | 2365 | ||
2382 | void | 2366 | void |
2383 | session_destroy_all(void (*closefunc)(Session *)) | 2367 | session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *)) |
2384 | { | 2368 | { |
2385 | int i; | 2369 | int i; |
2386 | for (i = 0; i < sessions_nalloc; i++) { | 2370 | for (i = 0; i < sessions_nalloc; i++) { |
@@ -2389,7 +2373,7 @@ session_destroy_all(void (*closefunc)(Session *)) | |||
2389 | if (closefunc != NULL) | 2373 | if (closefunc != NULL) |
2390 | closefunc(s); | 2374 | closefunc(s); |
2391 | else | 2375 | else |
2392 | session_close(s); | 2376 | session_close(ssh, s); |
2393 | } | 2377 | } |
2394 | } | 2378 | } |
2395 | } | 2379 | } |
@@ -2432,7 +2416,7 @@ session_proctitle(Session *s) | |||
2432 | } | 2416 | } |
2433 | 2417 | ||
2434 | int | 2418 | int |
2435 | session_setup_x11fwd(Session *s) | 2419 | session_setup_x11fwd(struct ssh *ssh, Session *s) |
2436 | { | 2420 | { |
2437 | struct stat st; | 2421 | struct stat st; |
2438 | char display[512], auth_display[512]; | 2422 | char display[512], auth_display[512]; |
@@ -2456,14 +2440,14 @@ session_setup_x11fwd(Session *s) | |||
2456 | debug("X11 display already set."); | 2440 | debug("X11 display already set."); |
2457 | return 0; | 2441 | return 0; |
2458 | } | 2442 | } |
2459 | if (x11_create_display_inet(options.x11_display_offset, | 2443 | if (x11_create_display_inet(ssh, options.x11_display_offset, |
2460 | options.x11_use_localhost, s->single_connection, | 2444 | options.x11_use_localhost, s->single_connection, |
2461 | &s->display_number, &s->x11_chanids) == -1) { | 2445 | &s->display_number, &s->x11_chanids) == -1) { |
2462 | debug("x11_create_display_inet failed."); | 2446 | debug("x11_create_display_inet failed."); |
2463 | return 0; | 2447 | return 0; |
2464 | } | 2448 | } |
2465 | for (i = 0; s->x11_chanids[i] != -1; i++) { | 2449 | for (i = 0; s->x11_chanids[i] != -1; i++) { |
2466 | channel_register_cleanup(s->x11_chanids[i], | 2450 | channel_register_cleanup(ssh, s->x11_chanids[i], |
2467 | session_close_single_x11, 0); | 2451 | session_close_single_x11, 0); |
2468 | } | 2452 | } |
2469 | 2453 | ||
@@ -2508,13 +2492,13 @@ session_setup_x11fwd(Session *s) | |||
2508 | } | 2492 | } |
2509 | 2493 | ||
2510 | static void | 2494 | static void |
2511 | do_authenticated2(Authctxt *authctxt) | 2495 | do_authenticated2(struct ssh *ssh, Authctxt *authctxt) |
2512 | { | 2496 | { |
2513 | server_loop2(authctxt); | 2497 | server_loop2(ssh, authctxt); |
2514 | } | 2498 | } |
2515 | 2499 | ||
2516 | void | 2500 | void |
2517 | do_cleanup(Authctxt *authctxt) | 2501 | do_cleanup(struct ssh *ssh, Authctxt *authctxt) |
2518 | { | 2502 | { |
2519 | static int called = 0; | 2503 | static int called = 0; |
2520 | 2504 | ||
@@ -2556,12 +2540,21 @@ do_cleanup(Authctxt *authctxt) | |||
2556 | /* remove agent socket */ | 2540 | /* remove agent socket */ |
2557 | auth_sock_cleanup_proc(authctxt->pw); | 2541 | auth_sock_cleanup_proc(authctxt->pw); |
2558 | 2542 | ||
2543 | /* remove userauth info */ | ||
2544 | if (auth_info_file != NULL) { | ||
2545 | temporarily_use_uid(authctxt->pw); | ||
2546 | unlink(auth_info_file); | ||
2547 | restore_uid(); | ||
2548 | free(auth_info_file); | ||
2549 | auth_info_file = NULL; | ||
2550 | } | ||
2551 | |||
2559 | /* | 2552 | /* |
2560 | * Cleanup ptys/utmp only if privsep is disabled, | 2553 | * Cleanup ptys/utmp only if privsep is disabled, |
2561 | * or if running in monitor. | 2554 | * or if running in monitor. |
2562 | */ | 2555 | */ |
2563 | if (!use_privsep || mm_is_monitor()) | 2556 | if (!use_privsep || mm_is_monitor()) |
2564 | session_destroy_all(session_pty_cleanup2); | 2557 | session_destroy_all(ssh, session_pty_cleanup2); |
2565 | } | 2558 | } |
2566 | 2559 | ||
2567 | /* Return a name for the remote host that fits inside utmp_size */ | 2560 | /* Return a name for the remote host that fits inside utmp_size */ |