View | Details | Raw Unified | Return to bug 1086 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile.inc (-1 / +1 lines)
Lines 3-9 Link Here
3
CFLAGS+=	-I${.CURDIR}/..
3
CFLAGS+=	-I${.CURDIR}/..
4
4
5
CDIAGFLAGS=	-Wall
5
CDIAGFLAGS=	-Wall
6
#CDIAGFLAGS+=	-Werror
6
CDIAGFLAGS+=	-Werror
7
CDIAGFLAGS+=	-Wpointer-arith
7
CDIAGFLAGS+=	-Wpointer-arith
8
CDIAGFLAGS+=	-Wno-uninitialized
8
CDIAGFLAGS+=	-Wno-uninitialized
9
CDIAGFLAGS+=	-Wstrict-prototypes
9
CDIAGFLAGS+=	-Wstrict-prototypes
(-)channels.c (-2 / +5 lines)
Lines 268-273 channel_new(char *ctype, int type, int r Link Here
268
	c->force_drain = 0;
268
	c->force_drain = 0;
269
	c->single_connection = 0;
269
	c->single_connection = 0;
270
	c->detach_user = NULL;
270
	c->detach_user = NULL;
271
	c->detach_close = NULL;
271
	c->confirm = NULL;
272
	c->confirm = NULL;
272
	c->confirm_ctx = NULL;
273
	c->confirm_ctx = NULL;
273
	c->input_filter = NULL;
274
	c->input_filter = NULL;
Lines 627-633 channel_register_confirm(int id, channel Link Here
627
	c->confirm_ctx = ctx;
628
	c->confirm_ctx = ctx;
628
}
629
}
629
void
630
void
630
channel_register_cleanup(int id, channel_callback_fn *fn)
631
channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
631
{
632
{
632
	Channel *c = channel_lookup(id);
633
	Channel *c = channel_lookup(id);
633
634
Lines 636-641 channel_register_cleanup(int id, channel Link Here
636
		return;
637
		return;
637
	}
638
	}
638
	c->detach_user = fn;
639
	c->detach_user = fn;
640
	c->detach_close = do_close;
639
}
641
}
640
void
642
void
641
channel_cancel_cleanup(int id)
643
channel_cancel_cleanup(int id)
Lines 647-652 channel_cancel_cleanup(int id) Link Here
647
		return;
649
		return;
648
	}
650
	}
649
	c->detach_user = NULL;
651
	c->detach_user = NULL;
652
	c->detach_close = 0;
650
}
653
}
651
void
654
void
652
channel_register_filter(int id, channel_filter_fn *fn)
655
channel_register_filter(int id, channel_filter_fn *fn)
Lines 1660-1666 channel_garbage_collect(Channel *c) Link Here
1660
	if (c == NULL)
1663
	if (c == NULL)
1661
		return;
1664
		return;
1662
	if (c->detach_user != NULL) {
1665
	if (c->detach_user != NULL) {
1663
		if (!chan_is_dead(c, 0))
1666
		if (!chan_is_dead(c, c->detach_close))
1664
			return;
1667
			return;
1665
		debug2("channel %d: gc: notify user", c->self);
1668
		debug2("channel %d: gc: notify user", c->self);
1666
		c->detach_user(c->self, NULL);
1669
		c->detach_user(c->self, NULL);
(-)channels.h (-2 / +3 lines)
Lines 105-112 struct Channel { Link Here
105
105
106
	/* callback */
106
	/* callback */
107
	channel_callback_fn	*confirm;
107
	channel_callback_fn	*confirm;
108
	channel_callback_fn	*detach_user;
109
	void			*confirm_ctx;
108
	void			*confirm_ctx;
109
	channel_callback_fn	*detach_user;
110
	int			detach_close;
110
111
111
	/* filter */
112
	/* filter */
112
	channel_filter_fn	*input_filter;
113
	channel_filter_fn	*input_filter;
Lines 162-168 void channel_stop_listening(void); Link Here
162
163
163
void	 channel_send_open(int);
164
void	 channel_send_open(int);
164
void	 channel_request_start(int, char *, int);
165
void	 channel_request_start(int, char *, int);
165
void	 channel_register_cleanup(int, channel_callback_fn *);
166
void	 channel_register_cleanup(int, channel_callback_fn *, int);
166
void	 channel_register_confirm(int, channel_callback_fn *, void *);
167
void	 channel_register_confirm(int, channel_callback_fn *, void *);
167
void	 channel_register_filter(int, channel_filter_fn *);
168
void	 channel_register_filter(int, channel_filter_fn *);
168
void	 channel_cancel_cleanup(int);
169
void	 channel_cancel_cleanup(int);
(-)clientloop.c (-1 / +1 lines)
Lines 1379-1385 client_loop(int have_pty, int escape_cha Link Here
1379
			    simple_escape_filter);
1379
			    simple_escape_filter);
1380
		if (session_ident != -1)
1380
		if (session_ident != -1)
1381
			channel_register_cleanup(session_ident,
1381
			channel_register_cleanup(session_ident,
1382
			    client_channel_closed);
1382
			    client_channel_closed, 0);
1383
	} else {
1383
	} else {
1384
		/* Check if we should immediately send eof on stdin. */
1384
		/* Check if we should immediately send eof on stdin. */
1385
		client_check_initial_eof_on_stdin();
1385
		client_check_initial_eof_on_stdin();
(-)serverloop.c (-1 / +1 lines)
Lines 898-904 server_request_session(void) Link Here
898
		channel_free(c);
898
		channel_free(c);
899
		return NULL;
899
		return NULL;
900
	}
900
	}
901
	channel_register_cleanup(c->self, session_close_by_channel);
901
	channel_register_cleanup(c->self, session_close_by_channel, 0);
902
	return c;
902
	return c;
903
}
903
}
904
904
(-)session.c (-61 / +158 lines)
Lines 100-105 extern Buffer loginmsg; Link Here
100
/* original command from peer. */
100
/* original command from peer. */
101
const char *original_command = NULL;
101
const char *original_command = NULL;
102
102
103
/*
104
 * This list tracks X11 channels, which must have a lifetime dependent on a 
105
 * session's _channel_, which may outlive the session itself.
106
 */
107
struct x11_channels {
108
	TAILQ_ENTRY(x11_channels) next;
109
	Session	*session;
110
	int	channel_owner;
111
	int	*x11_chanids;
112
};
113
TAILQ_HEAD(x11_chans, x11_channels);
114
static struct x11_chans x11_chans = TAILQ_HEAD_INITIALIZER(x11_chans);
115
103
/* data */
116
/* data */
104
#define MAX_SESSIONS 10
117
#define MAX_SESSIONS 10
105
Session	sessions[MAX_SESSIONS];
118
Session	sessions[MAX_SESSIONS];
Lines 1271-1284 session_new(void) Link Here
1271
	}
1284
	}
1272
	for (i = 0; i < MAX_SESSIONS; i++) {
1285
	for (i = 0; i < MAX_SESSIONS; i++) {
1273
		Session *s = &sessions[i];
1286
		Session *s = &sessions[i];
1274
		if (! s->used) {
1287
		if (!s->used) {
1275
			memset(s, 0, sizeof(*s));
1288
			memset(s, 0, sizeof(*s));
1276
			s->chanid = -1;
1289
			s->chanid = -1;
1277
			s->ptyfd = -1;
1290
			s->ptyfd = -1;
1278
			s->ttyfd = -1;
1291
			s->ttyfd = -1;
1279
			s->used = 1;
1292
			s->used = 1;
1280
			s->self = i;
1293
			s->self = i;
1281
			s->x11_chanids = NULL;
1294
			s->x11 = NULL;
1282
			debug("session_new: session %d", i);
1295
			debug("session_new: session %d", i);
1283
			return s;
1296
			return s;
1284
		}
1297
		}
Lines 1290-1295 static void Link Here
1290
session_dump(void)
1303
session_dump(void)
1291
{
1304
{
1292
	int i;
1305
	int i;
1306
	struct x11_channels *x11c;
1307
1293
	for (i = 0; i < MAX_SESSIONS; i++) {
1308
	for (i = 0; i < MAX_SESSIONS; i++) {
1294
		Session *s = &sessions[i];
1309
		Session *s = &sessions[i];
1295
		debug("dump: used %d session %d %p channel %d pid %ld",
1310
		debug("dump: used %d session %d %p channel %d pid %ld",
Lines 1299-1304 session_dump(void) Link Here
1299
		    s->chanid,
1314
		    s->chanid,
1300
		    (long)s->pid);
1315
		    (long)s->pid);
1301
	}
1316
	}
1317
	TAILQ_FOREACH(x11c, &x11_chans, next) {
1318
		debug("x11 dump: channel owner %d session %d",
1319
		    x11c->channel_owner, 
1320
		    x11c->session == NULL ? -1 : x11c->session->self);
1321
	}
1302
}
1322
}
1303
1323
1304
int
1324
int
Lines 1352-1380 session_by_channel(int id) Link Here
1352
}
1372
}
1353
1373
1354
static Session *
1374
static Session *
1355
session_by_x11_channel(int id)
1356
{
1357
	int i, j;
1358
1359
	for (i = 0; i < MAX_SESSIONS; i++) {
1360
		Session *s = &sessions[i];
1361
1362
		if (s->x11_chanids == NULL || !s->used)
1363
			continue;
1364
		for (j = 0; s->x11_chanids[j] != -1; j++) {
1365
			if (s->x11_chanids[j] == id) {
1366
				debug("session_by_x11_channel: session %d "
1367
				    "channel %d", s->self, id);
1368
				return s;
1369
			}
1370
		}
1371
	}
1372
	debug("session_by_x11_channel: unknown channel %d", id);
1373
	session_dump();
1374
	return NULL;
1375
}
1376
1377
static Session *
1378
session_by_pid(pid_t pid)
1375
session_by_pid(pid_t pid)
1379
{
1376
{
1380
	int i;
1377
	int i;
Lines 1389-1394 session_by_pid(pid_t pid) Link Here
1389
	return NULL;
1386
	return NULL;
1390
}
1387
}
1391
1388
1389
/* Allocate a X11 channel tracking entry and attach it to a session */
1390
static void
1391
session_x11_chantrack_attach(Session *s, int *x11_channels)
1392
{
1393
	struct x11_channels *x11c;
1394
1395
	if (s == NULL || s->chanid == -1 || x11_channels == NULL)
1396
		return;
1397
1398
	x11c = xmalloc(sizeof(*x11c));
1399
	x11c->session = s;
1400
	x11c->channel_owner = s->chanid;
1401
	x11c->x11_chanids = x11_channels;
1402
	
1403
	TAILQ_INSERT_TAIL(&x11_chans, x11c, next);
1404
	s->x11 = x11c;
1405
}
1406
1407
/* Deallocate a channel tracker */
1408
static void
1409
session_x11_chantrack_free(struct x11_channels *x11c)
1410
{
1411
	debug("session_x11_chantrack_free: channel_owner %d",
1412
	    x11c->channel_owner);
1413
	TAILQ_REMOVE(&x11_chans, x11c, next);
1414
	xfree(x11c->x11_chanids);
1415
	xfree(x11c);
1416
}
1417
1418
/* Look up an X11 channel tracker by its channel owner */
1419
static struct x11_channels *
1420
session_x11_chantrack_by_cid(int id)
1421
{
1422
	struct x11_channels *x11c;
1423
1424
	TAILQ_FOREACH(x11c, &x11_chans, next) {
1425
		if (x11c->channel_owner == id) {
1426
			debug("session_x11_chantrack_by_cid: channel %d", id);
1427
			return (x11c);
1428
		}
1429
	}
1430
1431
	debug("session_x11_chantrack_by_cid: unknown channel %d", id);
1432
	session_dump();
1433
	return (NULL);
1434
}
1435
1436
/* Look up an X11 channel tracker by one of its X11 channels */
1437
static struct x11_channels *
1438
session_x11_chantrack_by_xcid(int id)
1439
{
1440
	struct x11_channels *x11c;
1441
	u_int i;
1442
1443
	TAILQ_FOREACH(x11c, &x11_chans, next) {
1444
		for (i = 0; x11c->x11_chanids[i] != -1; i++) {
1445
			if (x11c->x11_chanids[i] == id) {
1446
				debug("session_x11_chantrack_by_xcid: "
1447
				    "channel %d", id);
1448
				return (x11c);
1449
			}
1450
		}
1451
	}
1452
1453
	debug("session_x11_chantrack_by_xcid: unknown channel %d", id);
1454
	session_dump();
1455
	return (NULL);
1456
}
1457
1392
static int
1458
static int
1393
session_window_change_req(Session *s)
1459
session_window_change_req(Session *s)
1394
{
1460
{
Lines 1748-1798 session_close_x11(int id) Link Here
1748
	}
1814
	}
1749
}
1815
}
1750
1816
1817
/* Channel cleanup callback to destroy X11 listener siblings when one closes */
1751
static void
1818
static void
1752
session_close_single_x11(int id, void *arg)
1819
session_close_single_x11(int id, void *arg)
1753
{
1820
{
1754
	Session *s;
1821
	struct x11_channels *x11c;
1755
	u_int i;
1822
	u_int i;
1756
1823
1757
	debug3("session_close_single_x11: channel %d", id);
1824
	debug3("session_close_single_x11: channel %d", id);
1758
	channel_cancel_cleanup(id);
1825
	channel_cancel_cleanup(id);
1759
	if ((s  = session_by_x11_channel(id)) == NULL)
1826
	if ((x11c  = session_x11_chantrack_by_xcid(id)) == NULL)
1760
		fatal("session_close_single_x11: no x11 channel %d", id);
1827
		fatal("session_close_single_x11: no x11 channel %d", id);
1761
	for (i = 0; s->x11_chanids[i] != -1; i++) {
1828
	for (i = 0; x11c->x11_chanids[i] != -1; i++) {
1762
		debug("session_close_single_x11: session %d: "
1829
		debug("session_close_single_x11: session %d: "
1763
		    "closing channel %d", s->self, s->x11_chanids[i]);
1830
		    "closing channel %d", x11c->session->self,
1831
		    x11c->x11_chanids[i]);
1764
		/*
1832
		/*
1765
		 * The channel "id" is already closing, but make sure we
1833
		 * The channel "id" is already closing, but make sure we
1766
		 * close all of its siblings.
1834
		 * close all of its siblings.
1767
		 */
1835
		 */
1768
		if (s->x11_chanids[i] != id)
1836
		if (x11c->x11_chanids[i] != id)
1769
			session_close_x11(s->x11_chanids[i]);
1837
			session_close_x11(x11c->x11_chanids[i]);
1770
	}
1771
	xfree(s->x11_chanids);
1772
	s->x11_chanids = NULL;
1773
	if (s->display) {
1774
		xfree(s->display);
1775
		s->display = NULL;
1776
	}
1838
	}
1777
	if (s->auth_proto) {
1839
	if (x11c->session != NULL) {
1778
		xfree(s->auth_proto);
1840
		if (x11c->session->display != NULL) {
1779
		s->auth_proto = NULL;
1841
			xfree(x11c->session->display);
1842
			x11c->session->display = NULL;
1843
		}
1844
		if (x11c->session->auth_proto != NULL) {
1845
			xfree(x11c->session->auth_proto);
1846
			x11c->session->auth_proto = NULL;
1847
		}
1848
		if (x11c->session->auth_data != NULL) {
1849
			xfree(x11c->session->auth_data);
1850
			x11c->session->auth_data = NULL;
1851
		}
1852
		if (x11c->session->auth_display != NULL) {
1853
			xfree(x11c->session->auth_display);
1854
			x11c->session->auth_display = NULL;
1855
		}
1856
		x11c->session->x11 = NULL;
1780
	}
1857
	}
1781
	if (s->auth_data) {
1858
	session_x11_chantrack_free(x11c);
1782
		xfree(s->auth_data);
1859
}
1783
		s->auth_data = NULL;
1860
1861
/* Channel callback to destroy dependant X11 listeners when owner channel closes */
1862
static void
1863
session_cleanup_x11_listeners(int id, void *arg)
1864
{
1865
	struct x11_channels *x11c;
1866
	u_int i;
1867
1868
	debug3("session_cleanup_x11_listeners: channel %d", id);
1869
	channel_cancel_cleanup(id);
1870
	if ((x11c  = session_x11_chantrack_by_cid(id)) == NULL) {
1871
		error("session_close_single_x11: no x11 channel %d", id);
1872
		return;
1784
	}
1873
	}
1785
	if (s->auth_display) {
1874
1786
		xfree(s->auth_display);
1875
	for (i = 0; x11c->x11_chanids[i] != -1; i++) {
1787
		s->auth_display = NULL;
1876
		debug("session_cleanup_x11_listeners: session channel %d: "
1877
		    "closing associated X11 channel %d", id,
1878
		    x11c->x11_chanids[i]);
1879
		session_close_x11(x11c->x11_chanids[i]);
1788
	}
1880
	}
1881
	session_x11_chantrack_free(x11c);
1789
}
1882
}
1790
1883
1791
static void
1884
static void
1792
session_exit_message(Session *s, int status)
1885
session_exit_message(Session *s, int status)
1793
{
1886
{
1794
	Channel *c;
1887
	Channel *c;
1795
	u_int i;
1796
1888
1797
	if ((c = channel_lookup(s->chanid)) == NULL)
1889
	if ((c = channel_lookup(s->chanid)) == NULL)
1798
		fatal("session_exit_message: session %d: no channel %d",
1890
		fatal("session_exit_message: session %d: no channel %d",
Lines 1827-1841 session_exit_message(Session *s, int sta Link Here
1827
	 */
1919
	 */
1828
	if (c->ostate != CHAN_OUTPUT_CLOSED)
1920
	if (c->ostate != CHAN_OUTPUT_CLOSED)
1829
		chan_write_failed(c);
1921
		chan_write_failed(c);
1830
	s->chanid = -1;
1831
1922
1832
	/* Close any X11 listeners associated with this session */
1923
	/*
1833
	if (s->x11_chanids != NULL) {
1924
	 * Attach a new cleanup function to the closing channel, so it
1834
		for (i = 0; s->x11_chanids[i] != -1; i++) {
1925
	 * can take its associated X11 listeners with it when it finally 
1835
			session_close_x11(s->x11_chanids[i]);
1926
	 * goes away.
1836
			s->x11_chanids[i] = -1;
1927
	 */
1837
		}
1928
	channel_register_cleanup(s->chanid, session_cleanup_x11_listeners, 1);
1838
	}
1929
1930
	s->chanid = -1;
1839
}
1931
}
1840
1932
1841
void
1933
void
Lines 1848-1857 session_close(Session *s) Link Here
1848
		session_pty_cleanup(s);
1940
		session_pty_cleanup(s);
1849
	if (s->term)
1941
	if (s->term)
1850
		xfree(s->term);
1942
		xfree(s->term);
1943
	if (s->x11)
1944
		s->x11->session = NULL; /* detach */
1851
	if (s->display)
1945
	if (s->display)
1852
		xfree(s->display);
1946
		xfree(s->display);
1853
	if (s->x11_chanids)
1854
		xfree(s->x11_chanids);
1855
	if (s->auth_display)
1947
	if (s->auth_display)
1856
		xfree(s->auth_display);
1948
		xfree(s->auth_display);
1857
	if (s->auth_data)
1949
	if (s->auth_data)
Lines 1880-1885 session_close_by_pid(pid_t pid, int stat Link Here
1880
	if (s->chanid != -1)
1972
	if (s->chanid != -1)
1881
		session_exit_message(s, status);
1973
		session_exit_message(s, status);
1882
	session_close(s);
1974
	session_close(s);
1975
	session_dump();
1883
}
1976
}
1884
1977
1885
/*
1978
/*
Lines 1963-1968 session_setup_x11fwd(Session *s) Link Here
1963
	char display[512], auth_display[512];
2056
	char display[512], auth_display[512];
1964
	char hostname[MAXHOSTNAMELEN];
2057
	char hostname[MAXHOSTNAMELEN];
1965
	u_int i;
2058
	u_int i;
2059
	int *x11_channels;
1966
2060
1967
	if (no_x11_forwarding_flag) {
2061
	if (no_x11_forwarding_flag) {
1968
		packet_send_debug("X11 forwarding disabled in user configuration file.");
2062
		packet_send_debug("X11 forwarding disabled in user configuration file.");
Lines 1988-2000 session_setup_x11fwd(Session *s) Link Here
1988
	}
2082
	}
1989
	if (x11_create_display_inet(options.x11_display_offset,
2083
	if (x11_create_display_inet(options.x11_display_offset,
1990
	    options.x11_use_localhost, s->single_connection,
2084
	    options.x11_use_localhost, s->single_connection,
1991
	    &s->display_number, &s->x11_chanids) == -1) {
2085
	    &s->display_number, &x11_channels) == -1) {
1992
		debug("x11_create_display_inet failed.");
2086
		debug("x11_create_display_inet failed.");
1993
		return 0;
2087
		return 0;
1994
	}
2088
	}
1995
	for (i = 0; s->x11_chanids[i] != -1; i++) {
2089
1996
		channel_register_cleanup(s->x11_chanids[i],
2090
	session_x11_chantrack_attach(s, x11_channels);
1997
		    session_close_single_x11);
2091
2092
	for (i = 0; x11_channels[i] != -1; i++) {
2093
		channel_register_cleanup(x11_channels[i],
2094
		    session_close_single_x11, 0);
1998
	}
2095
	}
1999
2096
2000
	/* Set up a suitable value for the DISPLAY variable. */
2097
	/* Set up a suitable value for the DISPLAY variable. */
(-)session.h (-1 / +1 lines)
Lines 49-55 struct Session { Link Here
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
	struct x11_channels *x11;
53
	int	is_subsystem;
53
	int	is_subsystem;
54
	u_int	num_env;
54
	u_int	num_env;
55
	struct {
55
	struct {

Return to bug 1086