diff options
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 133 |
1 files changed, 121 insertions, 12 deletions
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.186 2005/07/25 11:59:40 markus Exp $"); |
37 | 37 | ||
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | #include "ssh1.h" | 39 | #include "ssh1.h" |
@@ -56,6 +56,7 @@ RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $"); | |||
56 | #include "serverloop.h" | 56 | #include "serverloop.h" |
57 | #include "canohost.h" | 57 | #include "canohost.h" |
58 | #include "session.h" | 58 | #include "session.h" |
59 | #include "kex.h" | ||
59 | #include "monitor_wrap.h" | 60 | #include "monitor_wrap.h" |
60 | 61 | ||
61 | #include "selinux.h" | 62 | #include "selinux.h" |
@@ -198,11 +199,11 @@ auth_input_request_forwarding(struct passwd * pw) | |||
198 | static void | 199 | static void |
199 | display_loginmsg(void) | 200 | display_loginmsg(void) |
200 | { | 201 | { |
201 | if (buffer_len(&loginmsg) > 0) { | 202 | if (buffer_len(&loginmsg) > 0) { |
202 | buffer_append(&loginmsg, "\0", 1); | 203 | buffer_append(&loginmsg, "\0", 1); |
203 | printf("%s", (char *)buffer_ptr(&loginmsg)); | 204 | printf("%s", (char *)buffer_ptr(&loginmsg)); |
204 | buffer_clear(&loginmsg); | 205 | buffer_clear(&loginmsg); |
205 | } | 206 | } |
206 | } | 207 | } |
207 | 208 | ||
208 | void | 209 | void |
@@ -274,7 +275,7 @@ do_authenticated1(Authctxt *authctxt) | |||
274 | compression_level); | 275 | compression_level); |
275 | break; | 276 | break; |
276 | } | 277 | } |
277 | if (!options.compression) { | 278 | if (options.compression == COMP_NONE) { |
278 | debug2("compression disabled"); | 279 | debug2("compression disabled"); |
279 | break; | 280 | break; |
280 | } | 281 | } |
@@ -948,7 +949,8 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid) | |||
948 | } | 949 | } |
949 | #endif /* HAVE_ETC_DEFAULT_LOGIN */ | 950 | #endif /* HAVE_ETC_DEFAULT_LOGIN */ |
950 | 951 | ||
951 | void copy_environment(char **source, char ***env, u_int *envsize) | 952 | void |
953 | copy_environment(char **source, char ***env, u_int *envsize) | ||
952 | { | 954 | { |
953 | char *var_name, *var_val; | 955 | char *var_name, *var_val; |
954 | int i; | 956 | int i; |
@@ -1334,6 +1336,11 @@ do_setusercontext(struct passwd *pw) | |||
1334 | # ifdef _AIX | 1336 | # ifdef _AIX |
1335 | aix_usrinfo(pw); | 1337 | aix_usrinfo(pw); |
1336 | # endif /* _AIX */ | 1338 | # endif /* _AIX */ |
1339 | #if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) | ||
1340 | if (set_id(pw->pw_name) != 0) { | ||
1341 | exit(1); | ||
1342 | } | ||
1343 | #endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ | ||
1337 | /* Permanently switch to the desired uid. */ | 1344 | /* Permanently switch to the desired uid. */ |
1338 | permanently_set_uid(pw); | 1345 | permanently_set_uid(pw); |
1339 | #endif | 1346 | #endif |
@@ -1533,7 +1540,7 @@ do_child(Session *s, const char *command) | |||
1533 | */ | 1540 | */ |
1534 | 1541 | ||
1535 | if (options.kerberos_get_afs_token && k_hasafs() && | 1542 | if (options.kerberos_get_afs_token && k_hasafs() && |
1536 | (s->authctxt->krb5_ctx != NULL)) { | 1543 | (s->authctxt->krb5_ctx != NULL)) { |
1537 | char cell[64]; | 1544 | char cell[64]; |
1538 | 1545 | ||
1539 | debug("Getting AFS token"); | 1546 | debug("Getting AFS token"); |
@@ -1637,6 +1644,7 @@ session_new(void) | |||
1637 | s->ttyfd = -1; | 1644 | s->ttyfd = -1; |
1638 | s->used = 1; | 1645 | s->used = 1; |
1639 | s->self = i; | 1646 | s->self = i; |
1647 | s->x11_chanids = NULL; | ||
1640 | debug("session_new: session %d", i); | 1648 | debug("session_new: session %d", i); |
1641 | return s; | 1649 | return s; |
1642 | } | 1650 | } |
@@ -1710,6 +1718,29 @@ session_by_channel(int id) | |||
1710 | } | 1718 | } |
1711 | 1719 | ||
1712 | static Session * | 1720 | static Session * |
1721 | session_by_x11_channel(int id) | ||
1722 | { | ||
1723 | int i, j; | ||
1724 | |||
1725 | for (i = 0; i < MAX_SESSIONS; i++) { | ||
1726 | Session *s = &sessions[i]; | ||
1727 | |||
1728 | if (s->x11_chanids == NULL || !s->used) | ||
1729 | continue; | ||
1730 | for (j = 0; s->x11_chanids[j] != -1; j++) { | ||
1731 | if (s->x11_chanids[j] == id) { | ||
1732 | debug("session_by_x11_channel: session %d " | ||
1733 | "channel %d", s->self, id); | ||
1734 | return s; | ||
1735 | } | ||
1736 | } | ||
1737 | } | ||
1738 | debug("session_by_x11_channel: unknown channel %d", id); | ||
1739 | session_dump(); | ||
1740 | return NULL; | ||
1741 | } | ||
1742 | |||
1743 | static Session * | ||
1713 | session_by_pid(pid_t pid) | 1744 | session_by_pid(pid_t pid) |
1714 | { | 1745 | { |
1715 | int i; | 1746 | int i; |
@@ -1804,7 +1835,7 @@ session_subsystem_req(Session *s) | |||
1804 | u_int len; | 1835 | u_int len; |
1805 | int success = 0; | 1836 | int success = 0; |
1806 | char *cmd, *subsys = packet_get_string(&len); | 1837 | char *cmd, *subsys = packet_get_string(&len); |
1807 | int i; | 1838 | u_int i; |
1808 | 1839 | ||
1809 | packet_check_eom(); | 1840 | packet_check_eom(); |
1810 | logit("subsystem request for %.100s", subsys); | 1841 | logit("subsystem request for %.100s", subsys); |
@@ -1838,6 +1869,11 @@ session_x11_req(Session *s) | |||
1838 | { | 1869 | { |
1839 | int success; | 1870 | int success; |
1840 | 1871 | ||
1872 | if (s->auth_proto != NULL || s->auth_data != NULL) { | ||
1873 | error("session_x11_req: session %d: " | ||
1874 | "x11 fowarding already active", s->self); | ||
1875 | return 0; | ||
1876 | } | ||
1841 | s->single_connection = packet_get_char(); | 1877 | s->single_connection = packet_get_char(); |
1842 | s->auth_proto = packet_get_string(NULL); | 1878 | s->auth_proto = packet_get_string(NULL); |
1843 | s->auth_data = packet_get_string(NULL); | 1879 | s->auth_data = packet_get_string(NULL); |
@@ -2063,9 +2099,66 @@ sig2name(int sig) | |||
2063 | } | 2099 | } |
2064 | 2100 | ||
2065 | static void | 2101 | static void |
2102 | session_close_x11(int id) | ||
2103 | { | ||
2104 | Channel *c; | ||
2105 | |||
2106 | if ((c = channel_lookup(id)) == NULL) { | ||
2107 | debug("session_close_x11: x11 channel %d missing", id); | ||
2108 | } else { | ||
2109 | /* Detach X11 listener */ | ||
2110 | debug("session_close_x11: detach x11 channel %d", id); | ||
2111 | channel_cancel_cleanup(id); | ||
2112 | if (c->ostate != CHAN_OUTPUT_CLOSED) | ||
2113 | chan_mark_dead(c); | ||
2114 | } | ||
2115 | } | ||
2116 | |||
2117 | static void | ||
2118 | session_close_single_x11(int id, void *arg) | ||
2119 | { | ||
2120 | Session *s; | ||
2121 | u_int i; | ||
2122 | |||
2123 | debug3("session_close_single_x11: channel %d", id); | ||
2124 | channel_cancel_cleanup(id); | ||
2125 | if ((s = session_by_x11_channel(id)) == NULL) | ||
2126 | fatal("session_close_single_x11: no x11 channel %d", id); | ||
2127 | for (i = 0; s->x11_chanids[i] != -1; i++) { | ||
2128 | debug("session_close_single_x11: session %d: " | ||
2129 | "closing channel %d", s->self, s->x11_chanids[i]); | ||
2130 | /* | ||
2131 | * The channel "id" is already closing, but make sure we | ||
2132 | * close all of its siblings. | ||
2133 | */ | ||
2134 | if (s->x11_chanids[i] != id) | ||
2135 | session_close_x11(s->x11_chanids[i]); | ||
2136 | } | ||
2137 | xfree(s->x11_chanids); | ||
2138 | s->x11_chanids = NULL; | ||
2139 | if (s->display) { | ||
2140 | xfree(s->display); | ||
2141 | s->display = NULL; | ||
2142 | } | ||
2143 | if (s->auth_proto) { | ||
2144 | xfree(s->auth_proto); | ||
2145 | s->auth_proto = NULL; | ||
2146 | } | ||
2147 | if (s->auth_data) { | ||
2148 | xfree(s->auth_data); | ||
2149 | s->auth_data = NULL; | ||
2150 | } | ||
2151 | if (s->auth_display) { | ||
2152 | xfree(s->auth_display); | ||
2153 | s->auth_display = NULL; | ||
2154 | } | ||
2155 | } | ||
2156 | |||
2157 | static void | ||
2066 | session_exit_message(Session *s, int status) | 2158 | session_exit_message(Session *s, int status) |
2067 | { | 2159 | { |
2068 | Channel *c; | 2160 | Channel *c; |
2161 | u_int i; | ||
2069 | 2162 | ||
2070 | if ((c = channel_lookup(s->chanid)) == NULL) | 2163 | if ((c = channel_lookup(s->chanid)) == NULL) |
2071 | fatal("session_exit_message: session %d: no channel %d", | 2164 | fatal("session_exit_message: session %d: no channel %d", |
@@ -2105,12 +2198,20 @@ session_exit_message(Session *s, int status) | |||
2105 | if (c->ostate != CHAN_OUTPUT_CLOSED) | 2198 | if (c->ostate != CHAN_OUTPUT_CLOSED) |
2106 | chan_write_failed(c); | 2199 | chan_write_failed(c); |
2107 | s->chanid = -1; | 2200 | s->chanid = -1; |
2201 | |||
2202 | /* Close any X11 listeners associated with this session */ | ||
2203 | if (s->x11_chanids != NULL) { | ||
2204 | for (i = 0; s->x11_chanids[i] != -1; i++) { | ||
2205 | session_close_x11(s->x11_chanids[i]); | ||
2206 | s->x11_chanids[i] = -1; | ||
2207 | } | ||
2208 | } | ||
2108 | } | 2209 | } |
2109 | 2210 | ||
2110 | void | 2211 | void |
2111 | session_close(Session *s) | 2212 | session_close(Session *s) |
2112 | { | 2213 | { |
2113 | int i; | 2214 | u_int i; |
2114 | 2215 | ||
2115 | debug("session_close: session %d pid %ld", s->self, (long)s->pid); | 2216 | debug("session_close: session %d pid %ld", s->self, (long)s->pid); |
2116 | if (s->ttyfd != -1) | 2217 | if (s->ttyfd != -1) |
@@ -2119,6 +2220,8 @@ session_close(Session *s) | |||
2119 | xfree(s->term); | 2220 | xfree(s->term); |
2120 | if (s->display) | 2221 | if (s->display) |
2121 | xfree(s->display); | 2222 | xfree(s->display); |
2223 | if (s->x11_chanids) | ||
2224 | xfree(s->x11_chanids); | ||
2122 | if (s->auth_display) | 2225 | if (s->auth_display) |
2123 | xfree(s->auth_display); | 2226 | xfree(s->auth_display); |
2124 | if (s->auth_data) | 2227 | if (s->auth_data) |
@@ -2157,6 +2260,7 @@ void | |||
2157 | session_close_by_channel(int id, void *arg) | 2260 | session_close_by_channel(int id, void *arg) |
2158 | { | 2261 | { |
2159 | Session *s = session_by_channel(id); | 2262 | Session *s = session_by_channel(id); |
2263 | |||
2160 | if (s == NULL) { | 2264 | if (s == NULL) { |
2161 | debug("session_close_by_channel: no session for id %d", id); | 2265 | debug("session_close_by_channel: no session for id %d", id); |
2162 | return; | 2266 | return; |
@@ -2237,6 +2341,7 @@ session_setup_x11fwd(Session *s) | |||
2237 | struct stat st; | 2341 | struct stat st; |
2238 | char display[512], auth_display[512]; | 2342 | char display[512], auth_display[512]; |
2239 | char hostname[MAXHOSTNAMELEN]; | 2343 | char hostname[MAXHOSTNAMELEN]; |
2344 | u_int i; | ||
2240 | 2345 | ||
2241 | if (no_x11_forwarding_flag) { | 2346 | if (no_x11_forwarding_flag) { |
2242 | packet_send_debug("X11 forwarding disabled in user configuration file."); | 2347 | packet_send_debug("X11 forwarding disabled in user configuration file."); |
@@ -2262,10 +2367,14 @@ session_setup_x11fwd(Session *s) | |||
2262 | } | 2367 | } |
2263 | if (x11_create_display_inet(options.x11_display_offset, | 2368 | if (x11_create_display_inet(options.x11_display_offset, |
2264 | options.x11_use_localhost, s->single_connection, | 2369 | options.x11_use_localhost, s->single_connection, |
2265 | &s->display_number) == -1) { | 2370 | &s->display_number, &s->x11_chanids) == -1) { |
2266 | debug("x11_create_display_inet failed."); | 2371 | debug("x11_create_display_inet failed."); |
2267 | return 0; | 2372 | return 0; |
2268 | } | 2373 | } |
2374 | for (i = 0; s->x11_chanids[i] != -1; i++) { | ||
2375 | channel_register_cleanup(s->x11_chanids[i], | ||
2376 | session_close_single_x11); | ||
2377 | } | ||
2269 | 2378 | ||
2270 | /* Set up a suitable value for the DISPLAY variable. */ | 2379 | /* Set up a suitable value for the DISPLAY variable. */ |
2271 | if (gethostname(hostname, sizeof(hostname)) < 0) | 2380 | if (gethostname(hostname, sizeof(hostname)) < 0) |