diff options
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 117 |
1 files changed, 62 insertions, 55 deletions
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.129 2002/03/18 03:41:08 provos Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.130 2002/03/18 17:50:31 provos 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.129 2002/03/18 03:41:08 provos 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 "monitor_wrap.h" | ||
59 | 60 | ||
60 | #ifdef HAVE_CYGWIN | 61 | #ifdef HAVE_CYGWIN |
61 | #include <windows.h> | 62 | #include <windows.h> |
@@ -63,39 +64,11 @@ RCSID("$OpenBSD: session.c,v 1.129 2002/03/18 03:41:08 provos Exp $"); | |||
63 | #define is_winnt (GetVersion() < 0x80000000) | 64 | #define is_winnt (GetVersion() < 0x80000000) |
64 | #endif | 65 | #endif |
65 | 66 | ||
66 | /* types */ | ||
67 | |||
68 | #define TTYSZ 64 | ||
69 | typedef struct Session Session; | ||
70 | struct Session { | ||
71 | int used; | ||
72 | int self; | ||
73 | struct passwd *pw; | ||
74 | Authctxt *authctxt; | ||
75 | pid_t pid; | ||
76 | /* tty */ | ||
77 | char *term; | ||
78 | int ptyfd, ttyfd, ptymaster; | ||
79 | int row, col, xpixel, ypixel; | ||
80 | char tty[TTYSZ]; | ||
81 | /* X11 */ | ||
82 | int display_number; | ||
83 | char *display; | ||
84 | int screen; | ||
85 | char *auth_display; | ||
86 | char *auth_proto; | ||
87 | char *auth_data; | ||
88 | int single_connection; | ||
89 | /* proto 2 */ | ||
90 | int chanid; | ||
91 | int is_subsystem; | ||
92 | }; | ||
93 | |||
94 | /* func */ | 67 | /* func */ |
95 | 68 | ||
96 | Session *session_new(void); | 69 | Session *session_new(void); |
97 | void session_set_fds(Session *, int, int, int); | 70 | void session_set_fds(Session *, int, int, int); |
98 | static void session_pty_cleanup(void *); | 71 | void session_pty_cleanup(void *); |
99 | void session_proctitle(Session *); | 72 | void session_proctitle(Session *); |
100 | int session_setup_x11fwd(Session *); | 73 | int session_setup_x11fwd(Session *); |
101 | void do_exec_pty(Session *, const char *); | 74 | void do_exec_pty(Session *, const char *); |
@@ -112,7 +85,6 @@ int check_quietlogin(Session *, const char *); | |||
112 | static void do_authenticated1(Authctxt *); | 85 | static void do_authenticated1(Authctxt *); |
113 | static void do_authenticated2(Authctxt *); | 86 | static void do_authenticated2(Authctxt *); |
114 | 87 | ||
115 | static void session_close(Session *); | ||
116 | static int session_pty_req(Session *); | 88 | static int session_pty_req(Session *); |
117 | 89 | ||
118 | /* import */ | 90 | /* import */ |
@@ -1087,7 +1059,7 @@ do_nologin(struct passwd *pw) | |||
1087 | } | 1059 | } |
1088 | 1060 | ||
1089 | /* Set login name, uid, gid, and groups. */ | 1061 | /* Set login name, uid, gid, and groups. */ |
1090 | static void | 1062 | void |
1091 | do_setusercontext(struct passwd *pw) | 1063 | do_setusercontext(struct passwd *pw) |
1092 | { | 1064 | { |
1093 | #ifdef HAVE_CYGWIN | 1065 | #ifdef HAVE_CYGWIN |
@@ -1142,6 +1114,23 @@ do_setusercontext(struct passwd *pw) | |||
1142 | fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); | 1114 | fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); |
1143 | } | 1115 | } |
1144 | 1116 | ||
1117 | void | ||
1118 | launch_login(struct passwd *pw, const char *hostname) | ||
1119 | { | ||
1120 | /* Launch login(1). */ | ||
1121 | |||
1122 | execl("/usr/bin/login", "login", "-h", hostname, | ||
1123 | #ifdef LOGIN_NEEDS_TERM | ||
1124 | (s->term ? s->term : "unknown"), | ||
1125 | #endif /* LOGIN_NEEDS_TERM */ | ||
1126 | "-p", "-f", "--", pw->pw_name, (char *)NULL); | ||
1127 | |||
1128 | /* Login couldn't be executed, die. */ | ||
1129 | |||
1130 | perror("login"); | ||
1131 | exit(1); | ||
1132 | } | ||
1133 | |||
1145 | /* | 1134 | /* |
1146 | * Performs common processing for the child, such as setting up the | 1135 | * Performs common processing for the child, such as setting up the |
1147 | * environment, closing extra file descriptors, setting the user and group | 1136 | * environment, closing extra file descriptors, setting the user and group |
@@ -1267,18 +1256,8 @@ do_child(Session *s, const char *command) | |||
1267 | signal(SIGPIPE, SIG_DFL); | 1256 | signal(SIGPIPE, SIG_DFL); |
1268 | 1257 | ||
1269 | if (options.use_login) { | 1258 | if (options.use_login) { |
1270 | /* Launch login(1). */ | 1259 | launch_login(pw, hostname); |
1271 | 1260 | /* NEVERREACHED */ | |
1272 | execl(LOGIN_PROGRAM, "login", "-h", hostname, | ||
1273 | #ifdef LOGIN_NEEDS_TERM | ||
1274 | (s->term ? s->term : "unknown"), | ||
1275 | #endif /* LOGIN_NEEDS_TERM */ | ||
1276 | "-p", "-f", "--", pw->pw_name, (char *)NULL); | ||
1277 | |||
1278 | /* Login couldn't be executed, die. */ | ||
1279 | |||
1280 | perror("login"); | ||
1281 | exit(1); | ||
1282 | } | 1261 | } |
1283 | 1262 | ||
1284 | /* Get the last component of the shell name. */ | 1263 | /* Get the last component of the shell name. */ |
@@ -1388,6 +1367,22 @@ session_open(Authctxt *authctxt, int chanid) | |||
1388 | return 1; | 1367 | return 1; |
1389 | } | 1368 | } |
1390 | 1369 | ||
1370 | Session * | ||
1371 | session_by_tty(char *tty) | ||
1372 | { | ||
1373 | int i; | ||
1374 | for (i = 0; i < MAX_SESSIONS; i++) { | ||
1375 | Session *s = &sessions[i]; | ||
1376 | if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { | ||
1377 | debug("session_by_tty: session %d tty %s", i, tty); | ||
1378 | return s; | ||
1379 | } | ||
1380 | } | ||
1381 | debug("session_by_tty: unknown tty %.100s", tty); | ||
1382 | session_dump(); | ||
1383 | return NULL; | ||
1384 | } | ||
1385 | |||
1391 | static Session * | 1386 | static Session * |
1392 | session_by_channel(int id) | 1387 | session_by_channel(int id) |
1393 | { | 1388 | { |
@@ -1436,7 +1431,7 @@ session_pty_req(Session *s) | |||
1436 | { | 1431 | { |
1437 | u_int len; | 1432 | u_int len; |
1438 | int n_bytes; | 1433 | int n_bytes; |
1439 | 1434 | ||
1440 | if (no_pty_flag) { | 1435 | if (no_pty_flag) { |
1441 | debug("Allocating a pty not permitted for this authentication."); | 1436 | debug("Allocating a pty not permitted for this authentication."); |
1442 | return 0; | 1437 | return 0; |
@@ -1465,7 +1460,7 @@ session_pty_req(Session *s) | |||
1465 | 1460 | ||
1466 | /* Allocate a pty and open it. */ | 1461 | /* Allocate a pty and open it. */ |
1467 | debug("Allocating pty."); | 1462 | debug("Allocating pty."); |
1468 | if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { | 1463 | if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { |
1469 | if (s->term) | 1464 | if (s->term) |
1470 | xfree(s->term); | 1465 | xfree(s->term); |
1471 | s->term = NULL; | 1466 | s->term = NULL; |
@@ -1486,7 +1481,8 @@ session_pty_req(Session *s) | |||
1486 | * time in case we call fatal() (e.g., the connection gets closed). | 1481 | * time in case we call fatal() (e.g., the connection gets closed). |
1487 | */ | 1482 | */ |
1488 | fatal_add_cleanup(session_pty_cleanup, (void *)s); | 1483 | fatal_add_cleanup(session_pty_cleanup, (void *)s); |
1489 | pty_setowner(s->pw, s->tty); | 1484 | if (!use_privsep) |
1485 | pty_setowner(s->pw, s->tty); | ||
1490 | 1486 | ||
1491 | /* Set window size from the packet. */ | 1487 | /* Set window size from the packet. */ |
1492 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); | 1488 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
@@ -1649,8 +1645,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr) | |||
1649 | * Function to perform pty cleanup. Also called if we get aborted abnormally | 1645 | * Function to perform pty cleanup. Also called if we get aborted abnormally |
1650 | * (e.g., due to a dropped connection). | 1646 | * (e.g., due to a dropped connection). |
1651 | */ | 1647 | */ |
1652 | static void | 1648 | void |
1653 | session_pty_cleanup(void *session) | 1649 | session_pty_cleanup2(void *session) |
1654 | { | 1650 | { |
1655 | Session *s = session; | 1651 | Session *s = session; |
1656 | 1652 | ||
@@ -1668,7 +1664,8 @@ session_pty_cleanup(void *session) | |||
1668 | record_logout(s->pid, s->tty, s->pw->pw_name); | 1664 | record_logout(s->pid, s->tty, s->pw->pw_name); |
1669 | 1665 | ||
1670 | /* Release the pseudo-tty. */ | 1666 | /* Release the pseudo-tty. */ |
1671 | pty_release(s->tty); | 1667 | if (getuid() == 0) |
1668 | pty_release(s->tty); | ||
1672 | 1669 | ||
1673 | /* | 1670 | /* |
1674 | * Close the server side of the socket pairs. We must do this after | 1671 | * Close the server side of the socket pairs. We must do this after |
@@ -1676,12 +1673,18 @@ session_pty_cleanup(void *session) | |||
1676 | * while we're still cleaning up. | 1673 | * while we're still cleaning up. |
1677 | */ | 1674 | */ |
1678 | if (close(s->ptymaster) < 0) | 1675 | if (close(s->ptymaster) < 0) |
1679 | error("close(s->ptymaster): %s", strerror(errno)); | 1676 | error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); |
1680 | 1677 | ||
1681 | /* unlink pty from session */ | 1678 | /* unlink pty from session */ |
1682 | s->ttyfd = -1; | 1679 | s->ttyfd = -1; |
1683 | } | 1680 | } |
1684 | 1681 | ||
1682 | void | ||
1683 | session_pty_cleanup(void *session) | ||
1684 | { | ||
1685 | PRIVSEP(session_pty_cleanup2(session)); | ||
1686 | } | ||
1687 | |||
1685 | static void | 1688 | static void |
1686 | session_exit_message(Session *s, int status) | 1689 | session_exit_message(Session *s, int status) |
1687 | { | 1690 | { |
@@ -1727,7 +1730,7 @@ session_exit_message(Session *s, int status) | |||
1727 | s->chanid = -1; | 1730 | s->chanid = -1; |
1728 | } | 1731 | } |
1729 | 1732 | ||
1730 | static void | 1733 | void |
1731 | session_close(Session *s) | 1734 | session_close(Session *s) |
1732 | { | 1735 | { |
1733 | debug("session_close: session %d pid %d", s->self, s->pid); | 1736 | debug("session_close: session %d pid %d", s->self, s->pid); |
@@ -1794,13 +1797,17 @@ session_close_by_channel(int id, void *arg) | |||
1794 | } | 1797 | } |
1795 | 1798 | ||
1796 | void | 1799 | void |
1797 | session_destroy_all(void) | 1800 | session_destroy_all(void (*closefunc)(Session *)) |
1798 | { | 1801 | { |
1799 | int i; | 1802 | int i; |
1800 | for (i = 0; i < MAX_SESSIONS; i++) { | 1803 | for (i = 0; i < MAX_SESSIONS; i++) { |
1801 | Session *s = &sessions[i]; | 1804 | Session *s = &sessions[i]; |
1802 | if (s->used) | 1805 | if (s->used) { |
1803 | session_close(s); | 1806 | if (closefunc != NULL) |
1807 | closefunc(s); | ||
1808 | else | ||
1809 | session_close(s); | ||
1810 | } | ||
1804 | } | 1811 | } |
1805 | } | 1812 | } |
1806 | 1813 | ||