|
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. */ |