summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-07-17 17:19:24 +1000
committerDamien Miller <djm@mindrot.org>2005-07-17 17:19:24 +1000
commit2b9b045d930b8d724f768fafdd9a46fa453b9a3e (patch)
treef127eb67a0f4818cbb429b7faa76330e7659a6c5
parent37294fb6307202e6f52d7046b3ddb56a4786d27f (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--ChangeLog10
-rw-r--r--channels.c10
-rw-r--r--channels.h4
-rw-r--r--session.c106
-rw-r--r--session.h3
5 files changed, 125 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 647ad0160..84b82cccc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
1220050716 2020050716
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"
42RCSID("$OpenBSD: channels.c,v 1.221 2005/07/16 01:35:24 djm Exp $"); 42RCSID("$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 */
2660int 2660int
2661x11_create_display_inet(int x11_display_offset, int x11_use_localhost, 2661x11_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
216int x11_connect_display(void); 216int x11_connect_display(void);
217int x11_create_display_inet(int, int, int, u_int *); 217int x11_create_display_inet(int, int, int, u_int *, int **);
218void x11_input_open(int, u_int32_t, void *); 218void x11_input_open(int, u_int32_t, void *);
219void x11_request_forwarding_with_spoofing(int, const char *, const char *, 219void x11_request_forwarding_with_spoofing(int, const char *, const char *,
220 const char *); 220 const char *);
diff --git a/session.c b/session.c
index 13c3b001f..81d7d53e8 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.183 2005/07/16 01:35:24 djm Exp $"); 36RCSID("$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
1709static Session * 1710static Session *
1711session_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
1733static Session *
1710session_by_pid(pid_t pid) 1734session_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
2062static void 2091static void
2092session_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
2107static void
2108session_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
2147static void
2063session_exit_message(Session *s, int status) 2148session_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
2107void 2201void
@@ -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
2154session_close_by_channel(int id, void *arg) 2250session_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)
diff --git a/session.h b/session.h
index 92bd16573..a2598a99c 100644
--- a/session.h
+++ b/session.h
@@ -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 {