summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'session.c')
-rw-r--r--session.c118
1 files changed, 82 insertions, 36 deletions
diff --git a/session.c b/session.c
index 55db2ffd2..ee4008acf 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.172 2004/01/30 09:48:57 markus Exp $"); 36RCSID("$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)
196static void 196static void
197display_loginmsg(void) 197display_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
207void 206void
@@ -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 */
679void 688void
680do_login(Session *s, const char *command) 689do_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)
1310static void 1309static void
1311do_pwchange(Session *s) 1310do_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)
1820static int 1821static int
1821session_break_req(Session *s) 1822session_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
1834static int 1834static int
1835session_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
1869static int
1835session_auth_agent_req(Session *s) 1870session_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)
2017void 2055void
2018session_close(Session *s) 2056session_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