diff options
author | Darren Tucker <dtucker@zip.com.au> | 2003-10-02 16:12:36 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2003-10-02 16:12:36 +1000 |
commit | 3e33cecf71860f73656a73b754cc7b7b9ec0b0ce (patch) | |
tree | 4c993022225dc70faeb42e23ff3323fd1deb717a /session.c | |
parent | b210aa2cfa546d8c31f8c725d1de3050c747bd6e (diff) |
- markus@cvs.openbsd.org 2003/09/23 20:17:11
[Makefile.in auth1.c auth2.c auth.c auth.h auth-krb5.c canohost.c
cleanup.c clientloop.c fatal.c gss-serv.c log.c log.h monitor.c monitor.h
monitor_wrap.c monitor_wrap.h packet.c serverloop.c session.c session.h
ssh-agent.c sshd.c]
replace fatal_cleanup() and linked list of fatal callbacks with static
cleanup_exit() function. re-refine cleanup_exit() where appropriate,
allocate sshd's authctxt eary to allow simpler cleanup in sshd.
tested by many, ok deraadt@
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 94 |
1 files changed, 55 insertions, 39 deletions
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.165 2003/09/23 20:17:11 markus Exp $"); |
37 | 37 | ||
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | #include "ssh1.h" | 39 | #include "ssh1.h" |
@@ -66,7 +66,7 @@ RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $"); | |||
66 | 66 | ||
67 | Session *session_new(void); | 67 | Session *session_new(void); |
68 | void session_set_fds(Session *, int, int, int); | 68 | void session_set_fds(Session *, int, int, int); |
69 | void session_pty_cleanup(void *); | 69 | void session_pty_cleanup(Session *); |
70 | void session_proctitle(Session *); | 70 | void session_proctitle(Session *); |
71 | int session_setup_x11fwd(Session *); | 71 | int session_setup_x11fwd(Session *); |
72 | void do_exec_pty(Session *, const char *); | 72 | void do_exec_pty(Session *, const char *); |
@@ -106,6 +106,8 @@ Session sessions[MAX_SESSIONS]; | |||
106 | login_cap_t *lc; | 106 | login_cap_t *lc; |
107 | #endif | 107 | #endif |
108 | 108 | ||
109 | static int is_child = 0; | ||
110 | |||
109 | /* Name and directory of socket for authentication agent forwarding. */ | 111 | /* Name and directory of socket for authentication agent forwarding. */ |
110 | static char *auth_sock_name = NULL; | 112 | static char *auth_sock_name = NULL; |
111 | static char *auth_sock_dir = NULL; | 113 | static char *auth_sock_dir = NULL; |
@@ -113,10 +115,8 @@ static char *auth_sock_dir = NULL; | |||
113 | /* removes the agent forwarding socket */ | 115 | /* removes the agent forwarding socket */ |
114 | 116 | ||
115 | static void | 117 | static void |
116 | auth_sock_cleanup_proc(void *_pw) | 118 | auth_sock_cleanup_proc(struct passwd *pw) |
117 | { | 119 | { |
118 | struct passwd *pw = _pw; | ||
119 | |||
120 | if (auth_sock_name != NULL) { | 120 | if (auth_sock_name != NULL) { |
121 | temporarily_use_uid(pw); | 121 | temporarily_use_uid(pw); |
122 | unlink(auth_sock_name); | 122 | unlink(auth_sock_name); |
@@ -160,9 +160,6 @@ auth_input_request_forwarding(struct passwd * pw) | |||
160 | snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", | 160 | snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", |
161 | auth_sock_dir, (long) getpid()); | 161 | auth_sock_dir, (long) getpid()); |
162 | 162 | ||
163 | /* delete agent socket on fatal() */ | ||
164 | fatal_add_cleanup(auth_sock_cleanup_proc, pw); | ||
165 | |||
166 | /* Create the socket. */ | 163 | /* Create the socket. */ |
167 | sock = socket(AF_UNIX, SOCK_STREAM, 0); | 164 | sock = socket(AF_UNIX, SOCK_STREAM, 0); |
168 | if (sock < 0) | 165 | if (sock < 0) |
@@ -217,13 +214,7 @@ do_authenticated(Authctxt *authctxt) | |||
217 | else | 214 | else |
218 | do_authenticated1(authctxt); | 215 | do_authenticated1(authctxt); |
219 | 216 | ||
220 | /* remove agent socket */ | 217 | do_cleanup(authctxt); |
221 | if (auth_sock_name != NULL) | ||
222 | auth_sock_cleanup_proc(authctxt->pw); | ||
223 | #ifdef KRB5 | ||
224 | if (options.kerberos_ticket_cleanup) | ||
225 | krb5_cleanup_proc(authctxt); | ||
226 | #endif | ||
227 | } | 218 | } |
228 | 219 | ||
229 | /* | 220 | /* |
@@ -405,7 +396,7 @@ do_exec_no_pty(Session *s, const char *command) | |||
405 | 396 | ||
406 | /* Fork the child. */ | 397 | /* Fork the child. */ |
407 | if ((pid = fork()) == 0) { | 398 | if ((pid = fork()) == 0) { |
408 | fatal_remove_all_cleanups(); | 399 | is_child = 1; |
409 | 400 | ||
410 | /* Child. Reinitialize the log since the pid has changed. */ | 401 | /* Child. Reinitialize the log since the pid has changed. */ |
411 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 402 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
@@ -531,7 +522,7 @@ do_exec_pty(Session *s, const char *command) | |||
531 | 522 | ||
532 | /* Fork the child. */ | 523 | /* Fork the child. */ |
533 | if ((pid = fork()) == 0) { | 524 | if ((pid = fork()) == 0) { |
534 | fatal_remove_all_cleanups(); | 525 | is_child = 1; |
535 | 526 | ||
536 | /* Child. Reinitialize the log because the pid has changed. */ | 527 | /* Child. Reinitialize the log because the pid has changed. */ |
537 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 528 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
@@ -627,7 +618,7 @@ do_pre_login(Session *s) | |||
627 | if (getpeername(packet_get_connection_in(), | 618 | if (getpeername(packet_get_connection_in(), |
628 | (struct sockaddr *) & from, &fromlen) < 0) { | 619 | (struct sockaddr *) & from, &fromlen) < 0) { |
629 | debug("getpeername: %.100s", strerror(errno)); | 620 | debug("getpeername: %.100s", strerror(errno)); |
630 | fatal_cleanup(); | 621 | cleanup_exit(255); |
631 | } | 622 | } |
632 | } | 623 | } |
633 | 624 | ||
@@ -687,7 +678,7 @@ do_login(Session *s, const char *command) | |||
687 | if (getpeername(packet_get_connection_in(), | 678 | if (getpeername(packet_get_connection_in(), |
688 | (struct sockaddr *) & from, &fromlen) < 0) { | 679 | (struct sockaddr *) & from, &fromlen) < 0) { |
689 | debug("getpeername: %.100s", strerror(errno)); | 680 | debug("getpeername: %.100s", strerror(errno)); |
690 | fatal_cleanup(); | 681 | cleanup_exit(255); |
691 | } | 682 | } |
692 | } | 683 | } |
693 | 684 | ||
@@ -1178,7 +1169,7 @@ do_rc_files(Session *s, const char *shell) | |||
1178 | if (debug_flag) { | 1169 | if (debug_flag) { |
1179 | fprintf(stderr, | 1170 | fprintf(stderr, |
1180 | "Running %.500s remove %.100s\n", | 1171 | "Running %.500s remove %.100s\n", |
1181 | options.xauth_location, s->auth_display); | 1172 | options.xauth_location, s->auth_display); |
1182 | fprintf(stderr, | 1173 | fprintf(stderr, |
1183 | "%.500s add %.100s %.100s %.100s\n", | 1174 | "%.500s add %.100s %.100s %.100s\n", |
1184 | options.xauth_location, s->auth_display, | 1175 | options.xauth_location, s->auth_display, |
@@ -1663,11 +1654,6 @@ session_pty_req(Session *s) | |||
1663 | n_bytes = packet_remaining(); | 1654 | n_bytes = packet_remaining(); |
1664 | tty_parse_modes(s->ttyfd, &n_bytes); | 1655 | tty_parse_modes(s->ttyfd, &n_bytes); |
1665 | 1656 | ||
1666 | /* | ||
1667 | * Add a cleanup function to clear the utmp entry and record logout | ||
1668 | * time in case we call fatal() (e.g., the connection gets closed). | ||
1669 | */ | ||
1670 | fatal_add_cleanup(session_pty_cleanup, (void *)s); | ||
1671 | if (!use_privsep) | 1657 | if (!use_privsep) |
1672 | pty_setowner(s->pw, s->tty); | 1658 | pty_setowner(s->pw, s->tty); |
1673 | 1659 | ||
@@ -1849,10 +1835,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr) | |||
1849 | * (e.g., due to a dropped connection). | 1835 | * (e.g., due to a dropped connection). |
1850 | */ | 1836 | */ |
1851 | void | 1837 | void |
1852 | session_pty_cleanup2(void *session) | 1838 | session_pty_cleanup2(Session *s) |
1853 | { | 1839 | { |
1854 | Session *s = session; | ||
1855 | |||
1856 | if (s == NULL) { | 1840 | if (s == NULL) { |
1857 | error("session_pty_cleanup: no session"); | 1841 | error("session_pty_cleanup: no session"); |
1858 | return; | 1842 | return; |
@@ -1883,9 +1867,9 @@ session_pty_cleanup2(void *session) | |||
1883 | } | 1867 | } |
1884 | 1868 | ||
1885 | void | 1869 | void |
1886 | session_pty_cleanup(void *session) | 1870 | session_pty_cleanup(Session *s) |
1887 | { | 1871 | { |
1888 | PRIVSEP(session_pty_cleanup2(session)); | 1872 | PRIVSEP(session_pty_cleanup2(s)); |
1889 | } | 1873 | } |
1890 | 1874 | ||
1891 | static char * | 1875 | static char * |
@@ -1958,10 +1942,8 @@ void | |||
1958 | session_close(Session *s) | 1942 | session_close(Session *s) |
1959 | { | 1943 | { |
1960 | debug("session_close: session %d pid %ld", s->self, (long)s->pid); | 1944 | debug("session_close: session %d pid %ld", s->self, (long)s->pid); |
1961 | if (s->ttyfd != -1) { | 1945 | if (s->ttyfd != -1) |
1962 | fatal_remove_cleanup(session_pty_cleanup, (void *)s); | ||
1963 | session_pty_cleanup(s); | 1946 | session_pty_cleanup(s); |
1964 | } | ||
1965 | if (s->term) | 1947 | if (s->term) |
1966 | xfree(s->term); | 1948 | xfree(s->term); |
1967 | if (s->display) | 1949 | if (s->display) |
@@ -2010,10 +1992,8 @@ session_close_by_channel(int id, void *arg) | |||
2010 | * delay detach of session, but release pty, since | 1992 | * delay detach of session, but release pty, since |
2011 | * the fd's to the child are already closed | 1993 | * the fd's to the child are already closed |
2012 | */ | 1994 | */ |
2013 | if (s->ttyfd != -1) { | 1995 | if (s->ttyfd != -1) |
2014 | fatal_remove_cleanup(session_pty_cleanup, (void *)s); | ||
2015 | session_pty_cleanup(s); | 1996 | session_pty_cleanup(s); |
2016 | } | ||
2017 | return; | 1997 | return; |
2018 | } | 1998 | } |
2019 | /* detach by removing callback */ | 1999 | /* detach by removing callback */ |
@@ -2154,8 +2134,44 @@ static void | |||
2154 | do_authenticated2(Authctxt *authctxt) | 2134 | do_authenticated2(Authctxt *authctxt) |
2155 | { | 2135 | { |
2156 | server_loop2(authctxt); | 2136 | server_loop2(authctxt); |
2157 | #if defined(GSSAPI) | 2137 | } |
2158 | if (options.gss_cleanup_creds) | 2138 | |
2159 | ssh_gssapi_cleanup_creds(NULL); | 2139 | void |
2140 | do_cleanup(Authctxt *authctxt) | ||
2141 | { | ||
2142 | static int called = 0; | ||
2143 | |||
2144 | debug("do_cleanup"); | ||
2145 | |||
2146 | /* no cleanup if we're in the child for login shell */ | ||
2147 | if (is_child) | ||
2148 | return; | ||
2149 | |||
2150 | /* avoid double cleanup */ | ||
2151 | if (called) | ||
2152 | return; | ||
2153 | called = 1; | ||
2154 | |||
2155 | if (authctxt == NULL) | ||
2156 | return; | ||
2157 | #ifdef KRB5 | ||
2158 | if (options.kerberos_ticket_cleanup && | ||
2159 | authctxt->krb5_ctx) | ||
2160 | krb5_cleanup_proc(authctxt); | ||
2160 | #endif | 2161 | #endif |
2162 | |||
2163 | #ifdef GSSAPI | ||
2164 | if (compat20 && options.gss_cleanup_creds) | ||
2165 | ssh_gssapi_cleanup_creds(); | ||
2166 | #endif | ||
2167 | |||
2168 | /* remove agent socket */ | ||
2169 | auth_sock_cleanup_proc(authctxt->pw); | ||
2170 | |||
2171 | /* | ||
2172 | * Cleanup ptys/utmp only if privsep is disabled, | ||
2173 | * or if running in monitor. | ||
2174 | */ | ||
2175 | if (!use_privsep || mm_is_monitor()) | ||
2176 | session_destroy_all(session_pty_cleanup2); | ||
2161 | } | 2177 | } |