diff options
author | Damien Miller <djm@mindrot.org> | 2005-07-17 17:19:24 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-07-17 17:19:24 +1000 |
commit | 2b9b045d930b8d724f768fafdd9a46fa453b9a3e (patch) | |
tree | f127eb67a0f4818cbb429b7faa76330e7659a6c5 | |
parent | 37294fb6307202e6f52d7046b3ddb56a4786d27f (diff) |
- (djm) [auth-pam.c sftp.c] spaces vs. tabs at start of line
- djm@cvs.openbsd.org 2005/07/17 06:49:04
[channels.c channels.h session.c session.h]
Fix a number of X11 forwarding channel leaks:
1. Refuse multiple X11 forwarding requests on the same session
2. Clean up all listeners after a single_connection X11 forward, not just
the one that made the single connection
3. Destroy X11 listeners when the session owning them goes away
testing and ok dtucker@
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | channels.c | 10 | ||||
-rw-r--r-- | channels.h | 4 | ||||
-rw-r--r-- | session.c | 106 | ||||
-rw-r--r-- | session.h | 3 |
5 files changed, 125 insertions, 8 deletions
@@ -8,6 +8,14 @@ | |||
8 | [cipher-acss.c loginrec.c ssh-rand-helper.c sshd.c] Fix whitespace at EOL | 8 | [cipher-acss.c loginrec.c ssh-rand-helper.c sshd.c] Fix whitespace at EOL |
9 | in portable too ("perl -p -i -e 's/\s+$/\n/' *.[ch]") | 9 | in portable too ("perl -p -i -e 's/\s+$/\n/' *.[ch]") |
10 | - (djm) [auth-pam.c sftp.c] spaces vs. tabs at start of line | 10 | - (djm) [auth-pam.c sftp.c] spaces vs. tabs at start of line |
11 | - djm@cvs.openbsd.org 2005/07/17 06:49:04 | ||
12 | [channels.c channels.h session.c session.h] | ||
13 | Fix a number of X11 forwarding channel leaks: | ||
14 | 1. Refuse multiple X11 forwarding requests on the same session | ||
15 | 2. Clean up all listeners after a single_connection X11 forward, not just | ||
16 | the one that made the single connection | ||
17 | 3. Destroy X11 listeners when the session owning them goes away | ||
18 | testing and ok dtucker@ | ||
11 | 19 | ||
12 | 20050716 | 20 | 20050716 |
13 | - (dtucker) [auth-pam.c] Ensure that only one side of the authentication | 21 | - (dtucker) [auth-pam.c] Ensure that only one side of the authentication |
@@ -2841,4 +2849,4 @@ | |||
2841 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2849 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2842 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2850 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2843 | 2851 | ||
2844 | $Id: ChangeLog,v 1.3849 2005/07/17 07:18:49 djm Exp $ | 2852 | $Id: ChangeLog,v 1.3850 2005/07/17 07:19:24 djm Exp $ |
diff --git a/channels.c b/channels.c index b7ff85007..8da399b69 100644 --- a/channels.c +++ b/channels.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: channels.c,v 1.221 2005/07/16 01:35:24 djm Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.222 2005/07/17 06:49:04 djm Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -2659,7 +2659,7 @@ channel_send_window_changes(void) | |||
2659 | */ | 2659 | */ |
2660 | int | 2660 | int |
2661 | x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | 2661 | x11_create_display_inet(int x11_display_offset, int x11_use_localhost, |
2662 | int single_connection, u_int *display_numberp) | 2662 | int single_connection, u_int *display_numberp, int **chanids) |
2663 | { | 2663 | { |
2664 | Channel *nc = NULL; | 2664 | Channel *nc = NULL; |
2665 | int display_number, sock; | 2665 | int display_number, sock; |
@@ -2749,6 +2749,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | |||
2749 | } | 2749 | } |
2750 | 2750 | ||
2751 | /* Allocate a channel for each socket. */ | 2751 | /* Allocate a channel for each socket. */ |
2752 | if (chanids != NULL) | ||
2753 | *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); | ||
2752 | for (n = 0; n < num_socks; n++) { | 2754 | for (n = 0; n < num_socks; n++) { |
2753 | sock = socks[n]; | 2755 | sock = socks[n]; |
2754 | nc = channel_new("x11 listener", | 2756 | nc = channel_new("x11 listener", |
@@ -2756,7 +2758,11 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | |||
2756 | CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, | 2758 | CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, |
2757 | 0, "X11 inet listener", 1); | 2759 | 0, "X11 inet listener", 1); |
2758 | nc->single_connection = single_connection; | 2760 | nc->single_connection = single_connection; |
2761 | if (*chanids != NULL) | ||
2762 | (*chanids)[n] = nc->self; | ||
2759 | } | 2763 | } |
2764 | if (*chanids != NULL) | ||
2765 | (*chanids)[n] = -1; | ||
2760 | 2766 | ||
2761 | /* Return the display number for the DISPLAY environment variable. */ | 2767 | /* Return the display number for the DISPLAY environment variable. */ |
2762 | *display_numberp = display_number; | 2768 | *display_numberp = display_number; |
diff --git a/channels.h b/channels.h index b89b7c95d..1cb2c3a34 100644 --- a/channels.h +++ b/channels.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.h,v 1.78 2005/07/08 09:41:33 markus Exp $ */ | 1 | /* $OpenBSD: channels.h,v 1.79 2005/07/17 06:49:04 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -214,7 +214,7 @@ int channel_cancel_rport_listener(const char *, u_short); | |||
214 | /* x11 forwarding */ | 214 | /* x11 forwarding */ |
215 | 215 | ||
216 | int x11_connect_display(void); | 216 | int x11_connect_display(void); |
217 | int x11_create_display_inet(int, int, int, u_int *); | 217 | int x11_create_display_inet(int, int, int, u_int *, int **); |
218 | void x11_input_open(int, u_int32_t, void *); | 218 | void x11_input_open(int, u_int32_t, void *); |
219 | void x11_request_forwarding_with_spoofing(int, const char *, const char *, | 219 | void x11_request_forwarding_with_spoofing(int, const char *, const char *, |
220 | const char *); | 220 | const char *); |
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.183 2005/07/16 01:35:24 djm Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.184 2005/07/17 06:49:04 djm Exp $"); |
37 | 37 | ||
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | #include "ssh1.h" | 39 | #include "ssh1.h" |
@@ -1634,6 +1634,7 @@ session_new(void) | |||
1634 | s->ttyfd = -1; | 1634 | s->ttyfd = -1; |
1635 | s->used = 1; | 1635 | s->used = 1; |
1636 | s->self = i; | 1636 | s->self = i; |
1637 | s->x11_chanids = NULL; | ||
1637 | debug("session_new: session %d", i); | 1638 | debug("session_new: session %d", i); |
1638 | return s; | 1639 | return s; |
1639 | } | 1640 | } |
@@ -1707,6 +1708,29 @@ session_by_channel(int id) | |||
1707 | } | 1708 | } |
1708 | 1709 | ||
1709 | static Session * | 1710 | static Session * |
1711 | session_by_x11_channel(int id) | ||
1712 | { | ||
1713 | int i, j; | ||
1714 | |||
1715 | for (i = 0; i < MAX_SESSIONS; i++) { | ||
1716 | Session *s = &sessions[i]; | ||
1717 | |||
1718 | if (s->x11_chanids == NULL || !s->used) | ||
1719 | continue; | ||
1720 | for (j = 0; s->x11_chanids[j] != -1; j++) { | ||
1721 | if (s->x11_chanids[j] == id) { | ||
1722 | debug("session_by_x11_channel: session %d " | ||
1723 | "channel %d", s->self, id); | ||
1724 | return s; | ||
1725 | } | ||
1726 | } | ||
1727 | } | ||
1728 | debug("session_by_x11_channel: unknown channel %d", id); | ||
1729 | session_dump(); | ||
1730 | return NULL; | ||
1731 | } | ||
1732 | |||
1733 | static Session * | ||
1710 | session_by_pid(pid_t pid) | 1734 | session_by_pid(pid_t pid) |
1711 | { | 1735 | { |
1712 | int i; | 1736 | int i; |
@@ -1835,6 +1859,11 @@ session_x11_req(Session *s) | |||
1835 | { | 1859 | { |
1836 | int success; | 1860 | int success; |
1837 | 1861 | ||
1862 | if (s->auth_proto != NULL || s->auth_data != NULL) { | ||
1863 | error("session_x11_req: session %d: " | ||
1864 | "x11 fowarding already active", s->self); | ||
1865 | return 0; | ||
1866 | } | ||
1838 | s->single_connection = packet_get_char(); | 1867 | s->single_connection = packet_get_char(); |
1839 | s->auth_proto = packet_get_string(NULL); | 1868 | s->auth_proto = packet_get_string(NULL); |
1840 | s->auth_data = packet_get_string(NULL); | 1869 | s->auth_data = packet_get_string(NULL); |
@@ -2060,9 +2089,66 @@ sig2name(int sig) | |||
2060 | } | 2089 | } |
2061 | 2090 | ||
2062 | static void | 2091 | static void |
2092 | session_close_x11(int id) | ||
2093 | { | ||
2094 | Channel *c; | ||
2095 | |||
2096 | if ((c = channel_lookup(id)) == NULL) { | ||
2097 | debug("session_close_x11: x11 channel %d missing", id); | ||
2098 | } else { | ||
2099 | /* Detach X11 listener */ | ||
2100 | debug("session_close_x11: detach x11 channel %d", id); | ||
2101 | channel_cancel_cleanup(id); | ||
2102 | if (c->ostate != CHAN_OUTPUT_CLOSED) | ||
2103 | chan_mark_dead(c); | ||
2104 | } | ||
2105 | } | ||
2106 | |||
2107 | static void | ||
2108 | session_close_single_x11(int id, void *arg) | ||
2109 | { | ||
2110 | Session *s; | ||
2111 | u_int i; | ||
2112 | |||
2113 | debug3("session_close_single_x11: channel %d", id); | ||
2114 | channel_cancel_cleanup(id); | ||
2115 | if ((s = session_by_x11_channel(id)) == NULL) | ||
2116 | fatal("session_close_single_x11: no x11 channel %d", id); | ||
2117 | for (i = 0; s->x11_chanids[i] != -1; i++) { | ||
2118 | debug("session_close_single_x11: session %d: " | ||
2119 | "closing channel %d", s->self, s->x11_chanids[i]); | ||
2120 | /* | ||
2121 | * The channel "id" is already closing, but make sure we | ||
2122 | * close all of its siblings. | ||
2123 | */ | ||
2124 | if (s->x11_chanids[i] != id) | ||
2125 | session_close_x11(s->x11_chanids[i]); | ||
2126 | } | ||
2127 | xfree(s->x11_chanids); | ||
2128 | s->x11_chanids = NULL; | ||
2129 | if (s->display) { | ||
2130 | xfree(s->display); | ||
2131 | s->display = NULL; | ||
2132 | } | ||
2133 | if (s->auth_proto) { | ||
2134 | xfree(s->auth_proto); | ||
2135 | s->auth_proto = NULL; | ||
2136 | } | ||
2137 | if (s->auth_data) { | ||
2138 | xfree(s->auth_data); | ||
2139 | s->auth_data = NULL; | ||
2140 | } | ||
2141 | if (s->auth_display) { | ||
2142 | xfree(s->auth_display); | ||
2143 | s->auth_display = NULL; | ||
2144 | } | ||
2145 | } | ||
2146 | |||
2147 | static void | ||
2063 | session_exit_message(Session *s, int status) | 2148 | session_exit_message(Session *s, int status) |
2064 | { | 2149 | { |
2065 | Channel *c; | 2150 | Channel *c; |
2151 | u_int i; | ||
2066 | 2152 | ||
2067 | if ((c = channel_lookup(s->chanid)) == NULL) | 2153 | if ((c = channel_lookup(s->chanid)) == NULL) |
2068 | fatal("session_exit_message: session %d: no channel %d", | 2154 | fatal("session_exit_message: session %d: no channel %d", |
@@ -2102,6 +2188,14 @@ session_exit_message(Session *s, int status) | |||
2102 | if (c->ostate != CHAN_OUTPUT_CLOSED) | 2188 | if (c->ostate != CHAN_OUTPUT_CLOSED) |
2103 | chan_write_failed(c); | 2189 | chan_write_failed(c); |
2104 | s->chanid = -1; | 2190 | s->chanid = -1; |
2191 | |||
2192 | /* Close any X11 listeners associated with this session */ | ||
2193 | if (s->x11_chanids != NULL) { | ||
2194 | for (i = 0; s->x11_chanids[i] != -1; i++) { | ||
2195 | session_close_x11(s->x11_chanids[i]); | ||
2196 | s->x11_chanids[i] = -1; | ||
2197 | } | ||
2198 | } | ||
2105 | } | 2199 | } |
2106 | 2200 | ||
2107 | void | 2201 | void |
@@ -2116,6 +2210,8 @@ session_close(Session *s) | |||
2116 | xfree(s->term); | 2210 | xfree(s->term); |
2117 | if (s->display) | 2211 | if (s->display) |
2118 | xfree(s->display); | 2212 | xfree(s->display); |
2213 | if (s->x11_chanids) | ||
2214 | xfree(s->x11_chanids); | ||
2119 | if (s->auth_display) | 2215 | if (s->auth_display) |
2120 | xfree(s->auth_display); | 2216 | xfree(s->auth_display); |
2121 | if (s->auth_data) | 2217 | if (s->auth_data) |
@@ -2154,6 +2250,7 @@ void | |||
2154 | session_close_by_channel(int id, void *arg) | 2250 | session_close_by_channel(int id, void *arg) |
2155 | { | 2251 | { |
2156 | Session *s = session_by_channel(id); | 2252 | Session *s = session_by_channel(id); |
2253 | |||
2157 | if (s == NULL) { | 2254 | if (s == NULL) { |
2158 | debug("session_close_by_channel: no session for id %d", id); | 2255 | debug("session_close_by_channel: no session for id %d", id); |
2159 | return; | 2256 | return; |
@@ -2234,6 +2331,7 @@ session_setup_x11fwd(Session *s) | |||
2234 | struct stat st; | 2331 | struct stat st; |
2235 | char display[512], auth_display[512]; | 2332 | char display[512], auth_display[512]; |
2236 | char hostname[MAXHOSTNAMELEN]; | 2333 | char hostname[MAXHOSTNAMELEN]; |
2334 | u_int i; | ||
2237 | 2335 | ||
2238 | if (no_x11_forwarding_flag) { | 2336 | if (no_x11_forwarding_flag) { |
2239 | packet_send_debug("X11 forwarding disabled in user configuration file."); | 2337 | packet_send_debug("X11 forwarding disabled in user configuration file."); |
@@ -2259,10 +2357,14 @@ session_setup_x11fwd(Session *s) | |||
2259 | } | 2357 | } |
2260 | if (x11_create_display_inet(options.x11_display_offset, | 2358 | if (x11_create_display_inet(options.x11_display_offset, |
2261 | options.x11_use_localhost, s->single_connection, | 2359 | options.x11_use_localhost, s->single_connection, |
2262 | &s->display_number) == -1) { | 2360 | &s->display_number, &s->x11_chanids) == -1) { |
2263 | debug("x11_create_display_inet failed."); | 2361 | debug("x11_create_display_inet failed."); |
2264 | return 0; | 2362 | return 0; |
2265 | } | 2363 | } |
2364 | for (i = 0; s->x11_chanids[i] != -1; i++) { | ||
2365 | channel_register_cleanup(s->x11_chanids[i], | ||
2366 | session_close_single_x11); | ||
2367 | } | ||
2266 | 2368 | ||
2267 | /* Set up a suitable value for the DISPLAY variable. */ | 2369 | /* Set up a suitable value for the DISPLAY variable. */ |
2268 | if (gethostname(hostname, sizeof(hostname)) < 0) | 2370 | if (gethostname(hostname, sizeof(hostname)) < 0) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.h,v 1.24 2005/06/17 02:44:33 djm Exp $ */ | 1 | /* $OpenBSD: session.h,v 1.25 2005/07/17 06:49:04 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -49,6 +49,7 @@ struct Session { | |||
49 | int single_connection; | 49 | int single_connection; |
50 | /* proto 2 */ | 50 | /* proto 2 */ |
51 | int chanid; | 51 | int chanid; |
52 | int *x11_chanids; | ||
52 | int is_subsystem; | 53 | int is_subsystem; |
53 | u_int num_env; | 54 | u_int num_env; |
54 | struct { | 55 | struct { |