diff options
author | Colin Watson <cjwatson@debian.org> | 2005-01-04 13:07:27 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2005-01-04 13:07:27 +0000 |
commit | fd0f611b70a83d80fe8793af785542ee5541b7cd (patch) | |
tree | bededd22bb7eeec52e20083237ab7e4113445a16 /session.c | |
parent | c44fe9a5b9d3db96a7249b04d915f17e4a3a3b04 (diff) | |
parent | ebd2ce335af5861020c79fddb1ae35c03bf036cf (diff) |
Merge 3.9p1 to the trunk.
Diffstat (limited to 'session.c')
-rw-r--r-- | session.c | 118 |
1 files changed, 82 insertions, 36 deletions
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.180 2004/07/28 09:40:29 markus Exp $"); |
37 | 37 | ||
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | #include "ssh1.h" | 39 | #include "ssh1.h" |
@@ -42,7 +42,7 @@ RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $"); | |||
42 | #include "sshpty.h" | 42 | #include "sshpty.h" |
43 | #include "packet.h" | 43 | #include "packet.h" |
44 | #include "buffer.h" | 44 | #include "buffer.h" |
45 | #include "mpaux.h" | 45 | #include "match.h" |
46 | #include "uidswap.h" | 46 | #include "uidswap.h" |
47 | #include "compat.h" | 47 | #include "compat.h" |
48 | #include "channels.h" | 48 | #include "channels.h" |
@@ -196,12 +196,11 @@ auth_input_request_forwarding(struct passwd * pw) | |||
196 | static void | 196 | static void |
197 | display_loginmsg(void) | 197 | display_loginmsg(void) |
198 | { | 198 | { |
199 | if (buffer_len(&loginmsg) > 0) { | 199 | if (buffer_len(&loginmsg) > 0) { |
200 | buffer_append(&loginmsg, "\0", 1); | 200 | buffer_append(&loginmsg, "\0", 1); |
201 | printf("%s\n", (char *)buffer_ptr(&loginmsg)); | 201 | printf("%s", (char *)buffer_ptr(&loginmsg)); |
202 | buffer_clear(&loginmsg); | 202 | buffer_clear(&loginmsg); |
203 | } | 203 | } |
204 | fflush(stdout); | ||
205 | } | 204 | } |
206 | 205 | ||
207 | void | 206 | void |
@@ -265,7 +264,7 @@ do_authenticated1(Authctxt *authctxt) | |||
265 | compression_level = packet_get_int(); | 264 | compression_level = packet_get_int(); |
266 | packet_check_eom(); | 265 | packet_check_eom(); |
267 | if (compression_level < 1 || compression_level > 9) { | 266 | if (compression_level < 1 || compression_level > 9) { |
268 | packet_send_debug("Received illegal compression level %d.", | 267 | packet_send_debug("Received invalid compression level %d.", |
269 | compression_level); | 268 | compression_level); |
270 | break; | 269 | break; |
271 | } | 270 | } |
@@ -481,7 +480,11 @@ do_exec_no_pty(Session *s, const char *command) | |||
481 | close(perr[1]); | 480 | close(perr[1]); |
482 | 481 | ||
483 | if (compat20) { | 482 | if (compat20) { |
484 | session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]); | 483 | if (s->is_subsystem) { |
484 | close(perr[0]); | ||
485 | perr[0] = -1; | ||
486 | } | ||
487 | session_set_fds(s, pin[1], pout[0], perr[0]); | ||
485 | } else { | 488 | } else { |
486 | /* Enter the interactive session. */ | 489 | /* Enter the interactive session. */ |
487 | server_loop(pid, pin[1], pout[0], perr[0]); | 490 | server_loop(pid, pin[1], pout[0], perr[0]); |
@@ -672,14 +675,19 @@ do_exec(Session *s, const char *command) | |||
672 | do_exec_no_pty(s, command); | 675 | do_exec_no_pty(s, command); |
673 | 676 | ||
674 | original_command = NULL; | 677 | original_command = NULL; |
675 | } | ||
676 | 678 | ||
679 | /* | ||
680 | * Clear loginmsg: it's the child's responsibility to display | ||
681 | * it to the user, otherwise multiple sessions may accumulate | ||
682 | * multiple copies of the login messages. | ||
683 | */ | ||
684 | buffer_clear(&loginmsg); | ||
685 | } | ||
677 | 686 | ||
678 | /* administrative, login(1)-like work */ | 687 | /* administrative, login(1)-like work */ |
679 | void | 688 | void |
680 | do_login(Session *s, const char *command) | 689 | do_login(Session *s, const char *command) |
681 | { | 690 | { |
682 | char *time_string; | ||
683 | socklen_t fromlen; | 691 | socklen_t fromlen; |
684 | struct sockaddr_storage from; | 692 | struct sockaddr_storage from; |
685 | struct passwd * pw = s->pw; | 693 | struct passwd * pw = s->pw; |
@@ -724,19 +732,6 @@ do_login(Session *s, const char *command) | |||
724 | 732 | ||
725 | display_loginmsg(); | 733 | display_loginmsg(); |
726 | 734 | ||
727 | #ifndef NO_SSH_LASTLOG | ||
728 | if (options.print_lastlog && s->last_login_time != 0) { | ||
729 | time_string = ctime(&s->last_login_time); | ||
730 | if (strchr(time_string, '\n')) | ||
731 | *strchr(time_string, '\n') = 0; | ||
732 | if (strcmp(s->hostname, "") == 0) | ||
733 | printf("Last login: %s\r\n", time_string); | ||
734 | else | ||
735 | printf("Last login: %s from %s\r\n", time_string, | ||
736 | s->hostname); | ||
737 | } | ||
738 | #endif /* NO_SSH_LASTLOG */ | ||
739 | |||
740 | do_motd(); | 735 | do_motd(); |
741 | } | 736 | } |
742 | 737 | ||
@@ -996,6 +991,10 @@ do_setup_env(Session *s, const char *shell) | |||
996 | 991 | ||
997 | if (!options.use_login) { | 992 | if (!options.use_login) { |
998 | /* Set basic environment. */ | 993 | /* Set basic environment. */ |
994 | for (i = 0; i < s->num_env; i++) | ||
995 | child_set_env(&env, &envsize, s->env[i].name, | ||
996 | s->env[i].val); | ||
997 | |||
999 | child_set_env(&env, &envsize, "USER", pw->pw_name); | 998 | child_set_env(&env, &envsize, "USER", pw->pw_name); |
1000 | child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); | 999 | child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); |
1001 | #ifdef _AIX | 1000 | #ifdef _AIX |
@@ -1310,9 +1309,10 @@ do_setusercontext(struct passwd *pw) | |||
1310 | static void | 1309 | static void |
1311 | do_pwchange(Session *s) | 1310 | do_pwchange(Session *s) |
1312 | { | 1311 | { |
1312 | fflush(NULL); | ||
1313 | fprintf(stderr, "WARNING: Your password has expired.\n"); | 1313 | fprintf(stderr, "WARNING: Your password has expired.\n"); |
1314 | if (s->ttyfd != -1) { | 1314 | if (s->ttyfd != -1) { |
1315 | fprintf(stderr, | 1315 | fprintf(stderr, |
1316 | "You must change your password now and login again!\n"); | 1316 | "You must change your password now and login again!\n"); |
1317 | execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL); | 1317 | execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL); |
1318 | perror("passwd"); | 1318 | perror("passwd"); |
@@ -1423,6 +1423,13 @@ do_child(Session *s, const char *command) | |||
1423 | #else /* HAVE_OSF_SIA */ | 1423 | #else /* HAVE_OSF_SIA */ |
1424 | do_nologin(pw); | 1424 | do_nologin(pw); |
1425 | do_setusercontext(pw); | 1425 | do_setusercontext(pw); |
1426 | /* | ||
1427 | * PAM session modules in do_setusercontext may have | ||
1428 | * generated messages, so if this in an interactive | ||
1429 | * login then display them too. | ||
1430 | */ | ||
1431 | if (command == NULL) | ||
1432 | display_loginmsg(); | ||
1426 | #endif /* HAVE_OSF_SIA */ | 1433 | #endif /* HAVE_OSF_SIA */ |
1427 | } | 1434 | } |
1428 | 1435 | ||
@@ -1688,12 +1695,6 @@ session_pty_req(Session *s) | |||
1688 | packet_disconnect("Protocol error: you already have a pty."); | 1695 | packet_disconnect("Protocol error: you already have a pty."); |
1689 | return 0; | 1696 | return 0; |
1690 | } | 1697 | } |
1691 | /* Get the time and hostname when the user last logged in. */ | ||
1692 | if (options.print_lastlog) { | ||
1693 | s->hostname[0] = '\0'; | ||
1694 | s->last_login_time = get_last_login_time(s->pw->pw_uid, | ||
1695 | s->pw->pw_name, s->hostname, sizeof(s->hostname)); | ||
1696 | } | ||
1697 | 1698 | ||
1698 | s->term = packet_get_string(&len); | 1699 | s->term = packet_get_string(&len); |
1699 | 1700 | ||
@@ -1820,9 +1821,8 @@ session_exec_req(Session *s) | |||
1820 | static int | 1821 | static int |
1821 | session_break_req(Session *s) | 1822 | session_break_req(Session *s) |
1822 | { | 1823 | { |
1823 | u_int break_length; | ||
1824 | 1824 | ||
1825 | break_length = packet_get_int(); /* ignored */ | 1825 | packet_get_int(); /* ignored */ |
1826 | packet_check_eom(); | 1826 | packet_check_eom(); |
1827 | 1827 | ||
1828 | if (s->ttyfd == -1 || | 1828 | if (s->ttyfd == -1 || |
@@ -1832,6 +1832,41 @@ session_break_req(Session *s) | |||
1832 | } | 1832 | } |
1833 | 1833 | ||
1834 | static int | 1834 | static int |
1835 | session_env_req(Session *s) | ||
1836 | { | ||
1837 | char *name, *val; | ||
1838 | u_int name_len, val_len, i; | ||
1839 | |||
1840 | name = packet_get_string(&name_len); | ||
1841 | val = packet_get_string(&val_len); | ||
1842 | packet_check_eom(); | ||
1843 | |||
1844 | /* Don't set too many environment variables */ | ||
1845 | if (s->num_env > 128) { | ||
1846 | debug2("Ignoring env request %s: too many env vars", name); | ||
1847 | goto fail; | ||
1848 | } | ||
1849 | |||
1850 | for (i = 0; i < options.num_accept_env; i++) { | ||
1851 | if (match_pattern(name, options.accept_env[i])) { | ||
1852 | debug2("Setting env %d: %s=%s", s->num_env, name, val); | ||
1853 | s->env = xrealloc(s->env, sizeof(*s->env) * | ||
1854 | (s->num_env + 1)); | ||
1855 | s->env[s->num_env].name = name; | ||
1856 | s->env[s->num_env].val = val; | ||
1857 | s->num_env++; | ||
1858 | return (1); | ||
1859 | } | ||
1860 | } | ||
1861 | debug2("Ignoring env request %s: disallowed name", name); | ||
1862 | |||
1863 | fail: | ||
1864 | xfree(name); | ||
1865 | xfree(val); | ||
1866 | return (0); | ||
1867 | } | ||
1868 | |||
1869 | static int | ||
1835 | session_auth_agent_req(Session *s) | 1870 | session_auth_agent_req(Session *s) |
1836 | { | 1871 | { |
1837 | static int called = 0; | 1872 | static int called = 0; |
@@ -1878,13 +1913,16 @@ session_input_channel_req(Channel *c, const char *rtype) | |||
1878 | success = session_auth_agent_req(s); | 1913 | success = session_auth_agent_req(s); |
1879 | } else if (strcmp(rtype, "subsystem") == 0) { | 1914 | } else if (strcmp(rtype, "subsystem") == 0) { |
1880 | success = session_subsystem_req(s); | 1915 | success = session_subsystem_req(s); |
1881 | } else if (strcmp(rtype, "break") == 0) { | 1916 | } else if (strcmp(rtype, "env") == 0) { |
1882 | success = session_break_req(s); | 1917 | success = session_env_req(s); |
1883 | } | 1918 | } |
1884 | } | 1919 | } |
1885 | if (strcmp(rtype, "window-change") == 0) { | 1920 | if (strcmp(rtype, "window-change") == 0) { |
1886 | success = session_window_change_req(s); | 1921 | success = session_window_change_req(s); |
1922 | } else if (strcmp(rtype, "break") == 0) { | ||
1923 | success = session_break_req(s); | ||
1887 | } | 1924 | } |
1925 | |||
1888 | return success; | 1926 | return success; |
1889 | } | 1927 | } |
1890 | 1928 | ||
@@ -2017,6 +2055,8 @@ session_exit_message(Session *s, int status) | |||
2017 | void | 2055 | void |
2018 | session_close(Session *s) | 2056 | session_close(Session *s) |
2019 | { | 2057 | { |
2058 | int i; | ||
2059 | |||
2020 | debug("session_close: session %d pid %ld", s->self, (long)s->pid); | 2060 | debug("session_close: session %d pid %ld", s->self, (long)s->pid); |
2021 | if (s->ttyfd != -1) | 2061 | if (s->ttyfd != -1) |
2022 | session_pty_cleanup(s); | 2062 | session_pty_cleanup(s); |
@@ -2031,6 +2071,12 @@ session_close(Session *s) | |||
2031 | if (s->auth_proto) | 2071 | if (s->auth_proto) |
2032 | xfree(s->auth_proto); | 2072 | xfree(s->auth_proto); |
2033 | s->used = 0; | 2073 | s->used = 0; |
2074 | for (i = 0; i < s->num_env; i++) { | ||
2075 | xfree(s->env[i].name); | ||
2076 | xfree(s->env[i].val); | ||
2077 | } | ||
2078 | if (s->env != NULL) | ||
2079 | xfree(s->env); | ||
2034 | session_proctitle(s); | 2080 | session_proctitle(s); |
2035 | } | 2081 | } |
2036 | 2082 | ||