diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | monitor.c | 16 | ||||
-rw-r--r-- | monitor_wrap.c | 9 | ||||
-rw-r--r-- | session.c | 42 | ||||
-rw-r--r-- | session.h | 5 | ||||
-rw-r--r-- | sshd.c | 8 | ||||
-rw-r--r-- | sshlogin.c | 43 |
7 files changed, 89 insertions, 42 deletions
@@ -15,6 +15,12 @@ | |||
15 | Fix incorrect macro, .I -> .Em | 15 | Fix incorrect macro, .I -> .Em |
16 | From: Eric S. Raymond <esr at thyrsus dot com> | 16 | From: Eric S. Raymond <esr at thyrsus dot com> |
17 | ok jmc@ | 17 | ok jmc@ |
18 | - dtucker@cvs.openbsd.org 2004/07/17 05:31:41 | ||
19 | [monitor.c monitor_wrap.c session.c session.h sshd.c sshlogin.c] | ||
20 | Move "Last logged in at.." message generation to the monitor, right | ||
21 | before recording the new login. Fixes missing lastlog message when | ||
22 | /var/log/lastlog is not world-readable and incorrect datestamp when | ||
23 | multiple sessions are used (bz #463); much assistance & ok markus@ | ||
18 | 24 | ||
19 | 20040711 | 25 | 20040711 |
20 | - (dtucker) [auth-pam.c] Check for zero from waitpid() too, which allows | 26 | - (dtucker) [auth-pam.c] Check for zero from waitpid() too, which allows |
@@ -1521,4 +1527,4 @@ | |||
1521 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 1527 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
1522 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 1528 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
1523 | 1529 | ||
1524 | $Id: ChangeLog,v 1.3476 2004/07/17 06:13:15 dtucker Exp $ | 1530 | $Id: ChangeLog,v 1.3477 2004/07/17 07:05:14 dtucker Exp $ |
@@ -25,7 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "includes.h" | 27 | #include "includes.h" |
28 | RCSID("$OpenBSD: monitor.c,v 1.60 2004/06/22 05:05:45 dtucker Exp $"); | 28 | RCSID("$OpenBSD: monitor.c,v 1.61 2004/07/17 05:31:41 dtucker Exp $"); |
29 | 29 | ||
30 | #include <openssl/dh.h> | 30 | #include <openssl/dh.h> |
31 | 31 | ||
@@ -79,6 +79,7 @@ extern u_char session_id[]; | |||
79 | extern Buffer input, output; | 79 | extern Buffer input, output; |
80 | extern Buffer auth_debug; | 80 | extern Buffer auth_debug; |
81 | extern int auth_debug_init; | 81 | extern int auth_debug_init; |
82 | extern Buffer loginmsg; | ||
82 | 83 | ||
83 | /* State exported from the child */ | 84 | /* State exported from the child */ |
84 | 85 | ||
@@ -1230,10 +1231,6 @@ mm_answer_pty(int sock, Buffer *m) | |||
1230 | 1231 | ||
1231 | buffer_put_int(m, 1); | 1232 | buffer_put_int(m, 1); |
1232 | buffer_put_cstring(m, s->tty); | 1233 | buffer_put_cstring(m, s->tty); |
1233 | mm_request_send(sock, MONITOR_ANS_PTY, m); | ||
1234 | |||
1235 | mm_send_fd(sock, s->ptyfd); | ||
1236 | mm_send_fd(sock, s->ttyfd); | ||
1237 | 1234 | ||
1238 | /* We need to trick ttyslot */ | 1235 | /* We need to trick ttyslot */ |
1239 | if (dup2(s->ttyfd, 0) == -1) | 1236 | if (dup2(s->ttyfd, 0) == -1) |
@@ -1244,6 +1241,15 @@ mm_answer_pty(int sock, Buffer *m) | |||
1244 | /* Now we can close the file descriptor again */ | 1241 | /* Now we can close the file descriptor again */ |
1245 | close(0); | 1242 | close(0); |
1246 | 1243 | ||
1244 | /* send messages generated by record_login */ | ||
1245 | buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); | ||
1246 | buffer_clear(&loginmsg); | ||
1247 | |||
1248 | mm_request_send(sock, MONITOR_ANS_PTY, m); | ||
1249 | |||
1250 | mm_send_fd(sock, s->ptyfd); | ||
1251 | mm_send_fd(sock, s->ttyfd); | ||
1252 | |||
1247 | /* make sure nothing uses fd 0 */ | 1253 | /* make sure nothing uses fd 0 */ |
1248 | if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) | 1254 | if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) |
1249 | fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); | 1255 | fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); |
diff --git a/monitor_wrap.c b/monitor_wrap.c index f6bc34ec8..0d7a0e3bd 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -25,7 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "includes.h" | 27 | #include "includes.h" |
28 | RCSID("$OpenBSD: monitor_wrap.c,v 1.38 2004/07/03 11:02:25 dtucker Exp $"); | 28 | RCSID("$OpenBSD: monitor_wrap.c,v 1.39 2004/07/17 05:31:41 dtucker Exp $"); |
29 | 29 | ||
30 | #include <openssl/bn.h> | 30 | #include <openssl/bn.h> |
31 | #include <openssl/dh.h> | 31 | #include <openssl/dh.h> |
@@ -70,6 +70,7 @@ extern z_stream incoming_stream; | |||
70 | extern z_stream outgoing_stream; | 70 | extern z_stream outgoing_stream; |
71 | extern struct monitor *pmonitor; | 71 | extern struct monitor *pmonitor; |
72 | extern Buffer input, output; | 72 | extern Buffer input, output; |
73 | extern Buffer loginmsg; | ||
73 | extern ServerOptions options; | 74 | extern ServerOptions options; |
74 | 75 | ||
75 | int | 76 | int |
@@ -642,7 +643,7 @@ int | |||
642 | mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) | 643 | mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) |
643 | { | 644 | { |
644 | Buffer m; | 645 | Buffer m; |
645 | char *p; | 646 | char *p, *msg; |
646 | int success = 0; | 647 | int success = 0; |
647 | 648 | ||
648 | buffer_init(&m); | 649 | buffer_init(&m); |
@@ -658,11 +659,15 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) | |||
658 | return (0); | 659 | return (0); |
659 | } | 660 | } |
660 | p = buffer_get_string(&m, NULL); | 661 | p = buffer_get_string(&m, NULL); |
662 | msg = buffer_get_string(&m, NULL); | ||
661 | buffer_free(&m); | 663 | buffer_free(&m); |
662 | 664 | ||
663 | strlcpy(namebuf, p, namebuflen); /* Possible truncation */ | 665 | strlcpy(namebuf, p, namebuflen); /* Possible truncation */ |
664 | xfree(p); | 666 | xfree(p); |
665 | 667 | ||
668 | buffer_append(&loginmsg, msg, strlen(msg)); | ||
669 | xfree(msg); | ||
670 | |||
666 | *ptyfd = mm_receive_fd(pmonitor->m_recvfd); | 671 | *ptyfd = mm_receive_fd(pmonitor->m_recvfd); |
667 | *ttyfd = mm_receive_fd(pmonitor->m_recvfd); | 672 | *ttyfd = mm_receive_fd(pmonitor->m_recvfd); |
668 | 673 | ||
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.178 2004/07/11 17:48:47 deraadt Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.179 2004/07/17 05:31:41 dtucker Exp $"); |
37 | 37 | ||
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | #include "ssh1.h" | 39 | #include "ssh1.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 |
@@ -676,14 +675,19 @@ do_exec(Session *s, const char *command) | |||
676 | do_exec_no_pty(s, command); | 675 | do_exec_no_pty(s, command); |
677 | 676 | ||
678 | original_command = NULL; | 677 | original_command = NULL; |
679 | } | ||
680 | 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 | } | ||
681 | 686 | ||
682 | /* administrative, login(1)-like work */ | 687 | /* administrative, login(1)-like work */ |
683 | void | 688 | void |
684 | do_login(Session *s, const char *command) | 689 | do_login(Session *s, const char *command) |
685 | { | 690 | { |
686 | char *time_string; | ||
687 | socklen_t fromlen; | 691 | socklen_t fromlen; |
688 | struct sockaddr_storage from; | 692 | struct sockaddr_storage from; |
689 | struct passwd * pw = s->pw; | 693 | struct passwd * pw = s->pw; |
@@ -728,19 +732,6 @@ do_login(Session *s, const char *command) | |||
728 | 732 | ||
729 | display_loginmsg(); | 733 | display_loginmsg(); |
730 | 734 | ||
731 | #ifndef NO_SSH_LASTLOG | ||
732 | if (options.print_lastlog && s->last_login_time != 0) { | ||
733 | time_string = ctime(&s->last_login_time); | ||
734 | if (strchr(time_string, '\n')) | ||
735 | *strchr(time_string, '\n') = 0; | ||
736 | if (strcmp(s->hostname, "") == 0) | ||
737 | printf("Last login: %s\r\n", time_string); | ||
738 | else | ||
739 | printf("Last login: %s from %s\r\n", time_string, | ||
740 | s->hostname); | ||
741 | } | ||
742 | #endif /* NO_SSH_LASTLOG */ | ||
743 | |||
744 | do_motd(); | 735 | do_motd(); |
745 | } | 736 | } |
746 | 737 | ||
@@ -1318,6 +1309,7 @@ do_setusercontext(struct passwd *pw) | |||
1318 | static void | 1309 | static void |
1319 | do_pwchange(Session *s) | 1310 | do_pwchange(Session *s) |
1320 | { | 1311 | { |
1312 | fflush(NULL); | ||
1321 | fprintf(stderr, "WARNING: Your password has expired.\n"); | 1313 | fprintf(stderr, "WARNING: Your password has expired.\n"); |
1322 | if (s->ttyfd != -1) { | 1314 | if (s->ttyfd != -1) { |
1323 | fprintf(stderr, | 1315 | fprintf(stderr, |
@@ -1703,12 +1695,6 @@ session_pty_req(Session *s) | |||
1703 | packet_disconnect("Protocol error: you already have a pty."); | 1695 | packet_disconnect("Protocol error: you already have a pty."); |
1704 | return 0; | 1696 | return 0; |
1705 | } | 1697 | } |
1706 | /* Get the time and hostname when the user last logged in. */ | ||
1707 | if (options.print_lastlog) { | ||
1708 | s->hostname[0] = '\0'; | ||
1709 | s->last_login_time = get_last_login_time(s->pw->pw_uid, | ||
1710 | s->pw->pw_name, s->hostname, sizeof(s->hostname)); | ||
1711 | } | ||
1712 | 1698 | ||
1713 | s->term = packet_get_string(&len); | 1699 | s->term = packet_get_string(&len); |
1714 | 1700 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.h,v 1.22 2004/04/27 09:46:37 djm Exp $ */ | 1 | /* $OpenBSD: session.h,v 1.23 2004/07/17 05:31:41 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -39,9 +39,6 @@ struct Session { | |||
39 | int ptyfd, ttyfd, ptymaster; | 39 | int ptyfd, ttyfd, ptymaster; |
40 | u_int row, col, xpixel, ypixel; | 40 | u_int row, col, xpixel, ypixel; |
41 | char tty[TTYSZ]; | 41 | char tty[TTYSZ]; |
42 | /* last login */ | ||
43 | char hostname[MAXHOSTNAMELEN]; | ||
44 | time_t last_login_time; | ||
45 | /* X11 */ | 42 | /* X11 */ |
46 | u_int display_number; | 43 | u_int display_number; |
47 | char *display; | 44 | char *display; |
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "includes.h" | 44 | #include "includes.h" |
45 | RCSID("$OpenBSD: sshd.c,v 1.298 2004/07/11 17:48:47 deraadt Exp $"); | 45 | RCSID("$OpenBSD: sshd.c,v 1.299 2004/07/17 05:31:41 dtucker Exp $"); |
46 | 46 | ||
47 | #include <openssl/dh.h> | 47 | #include <openssl/dh.h> |
48 | #include <openssl/bn.h> | 48 | #include <openssl/bn.h> |
@@ -216,6 +216,9 @@ Buffer loginmsg; | |||
216 | /* global authentication context */ | 216 | /* global authentication context */ |
217 | Authctxt *the_authctxt = NULL; | 217 | Authctxt *the_authctxt = NULL; |
218 | 218 | ||
219 | /* message to be displayed after login */ | ||
220 | Buffer loginmsg; | ||
221 | |||
219 | /* Prototypes for various functions defined later in this file. */ | 222 | /* Prototypes for various functions defined later in this file. */ |
220 | void destroy_sensitive_data(void); | 223 | void destroy_sensitive_data(void); |
221 | void demote_sensitive_data(void); | 224 | void demote_sensitive_data(void); |
@@ -1680,6 +1683,9 @@ main(int ac, char **av) | |||
1680 | if (privsep_preauth(authctxt) == 1) | 1683 | if (privsep_preauth(authctxt) == 1) |
1681 | goto authenticated; | 1684 | goto authenticated; |
1682 | 1685 | ||
1686 | /* prepare buffer to collect messages to display to user after login */ | ||
1687 | buffer_init(&loginmsg); | ||
1688 | |||
1683 | /* perform the key exchange */ | 1689 | /* perform the key exchange */ |
1684 | /* authenticate user and start session */ | 1690 | /* authenticate user and start session */ |
1685 | if (compat20) { | 1691 | if (compat20) { |
diff --git a/sshlogin.c b/sshlogin.c index 75446f9eb..41817ec96 100644 --- a/sshlogin.c +++ b/sshlogin.c | |||
@@ -39,9 +39,15 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: sshlogin.c,v 1.9 2004/07/03 05:11:33 dtucker Exp $"); | 42 | RCSID("$OpenBSD: sshlogin.c,v 1.10 2004/07/17 05:31:41 dtucker Exp $"); |
43 | 43 | ||
44 | #include "loginrec.h" | 44 | #include "loginrec.h" |
45 | #include "log.h" | ||
46 | #include "buffer.h" | ||
47 | #include "servconf.h" | ||
48 | |||
49 | extern Buffer loginmsg; | ||
50 | extern ServerOptions options; | ||
45 | 51 | ||
46 | /* | 52 | /* |
47 | * Returns the time when the user last logged in. Returns 0 if the | 53 | * Returns the time when the user last logged in. Returns 0 if the |
@@ -60,6 +66,38 @@ get_last_login_time(uid_t uid, const char *logname, | |||
60 | } | 66 | } |
61 | 67 | ||
62 | /* | 68 | /* |
69 | * Generate and store last login message. This must be done before | ||
70 | * login_login() is called and lastlog is updated. | ||
71 | */ | ||
72 | void | ||
73 | store_lastlog_message(const char *user, uid_t uid) | ||
74 | { | ||
75 | char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; | ||
76 | time_t last_login_time; | ||
77 | |||
78 | #ifndef NO_SSH_LASTLOG | ||
79 | if (!options.print_lastlog) | ||
80 | return; | ||
81 | |||
82 | last_login_time = get_last_login_time(uid, user, hostname, | ||
83 | sizeof(hostname)); | ||
84 | |||
85 | if (last_login_time != 0) { | ||
86 | time_string = ctime(&last_login_time); | ||
87 | if (strchr(time_string, '\n')) | ||
88 | *strchr(time_string, '\n') = '\0'; | ||
89 | if (strcmp(hostname, "") == 0) | ||
90 | snprintf(buf, sizeof(buf), "Last login: %s\r\n", | ||
91 | time_string); | ||
92 | else | ||
93 | snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n", | ||
94 | time_string, hostname); | ||
95 | buffer_append(&loginmsg, buf, strlen(buf)); | ||
96 | } | ||
97 | #endif /* NO_SSH_LASTLOG */ | ||
98 | } | ||
99 | |||
100 | /* | ||
63 | * Records that the user has logged in. I wish these parts of operating | 101 | * Records that the user has logged in. I wish these parts of operating |
64 | * systems were more standardized. | 102 | * systems were more standardized. |
65 | */ | 103 | */ |
@@ -69,6 +107,9 @@ record_login(pid_t pid, const char *tty, const char *user, uid_t uid, | |||
69 | { | 107 | { |
70 | struct logininfo *li; | 108 | struct logininfo *li; |
71 | 109 | ||
110 | /* save previous login details before writing new */ | ||
111 | store_lastlog_message(user, uid); | ||
112 | |||
72 | li = login_alloc_entry(pid, user, host, tty); | 113 | li = login_alloc_entry(pid, user, host, tty); |
73 | login_set_addr(li, addr, addrlen); | 114 | login_set_addr(li, addr, addrlen); |
74 | login_login(li); | 115 | login_login(li); |