View | Details | Raw Unified | Return to bug 463 | Differences between
and this patch

Collapse All | Expand All

(-)monitor.c (+20 lines)
Lines 110-115 Link Here
110
int mm_answer_pty(int, Buffer *);
110
int mm_answer_pty(int, Buffer *);
111
int mm_answer_pty_cleanup(int, Buffer *);
111
int mm_answer_pty_cleanup(int, Buffer *);
112
int mm_answer_term(int, Buffer *);
112
int mm_answer_term(int, Buffer *);
113
int mm_answer_getloginmsg(int, Buffer *);
113
int mm_answer_rsa_keyallowed(int, Buffer *);
114
int mm_answer_rsa_keyallowed(int, Buffer *);
114
int mm_answer_rsa_challenge(int, Buffer *);
115
int mm_answer_rsa_challenge(int, Buffer *);
115
int mm_answer_rsa_response(int, Buffer *);
116
int mm_answer_rsa_response(int, Buffer *);
Lines 176-181 Link Here
176
    {MONITOR_REQ_PTY, 0, mm_answer_pty},
177
    {MONITOR_REQ_PTY, 0, mm_answer_pty},
177
    {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
178
    {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
178
    {MONITOR_REQ_TERM, 0, mm_answer_term},
179
    {MONITOR_REQ_TERM, 0, mm_answer_term},
180
    {MONITOR_REQ_LOGINMSG, 0, mm_answer_getloginmsg},
179
    {0, 0, NULL}
181
    {0, 0, NULL}
180
};
182
};
181
183
Lines 209-214 Link Here
209
    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
211
    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
210
    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
212
    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
211
    {MONITOR_REQ_TERM, 0, mm_answer_term},
213
    {MONITOR_REQ_TERM, 0, mm_answer_term},
214
    {MONITOR_REQ_LOGINMSG, 0, mm_answer_getloginmsg},
212
    {0, 0, NULL}
215
    {0, 0, NULL}
213
};
216
};
214
217
Lines 314-319 Link Here
314
	if (!no_pty_flag) {
317
	if (!no_pty_flag) {
315
		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
318
		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
316
		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
319
		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
320
		monitor_permit(mon_dispatch, MONITOR_REQ_LOGINMSG, 1);
317
	}
321
	}
318
322
319
	for (;;)
323
	for (;;)
Lines 1068-1073 Link Here
1068
		mm_session_close(s);
1072
		mm_session_close(s);
1069
	buffer_put_int(m, 0);
1073
	buffer_put_int(m, 0);
1070
	mm_request_send(socket, MONITOR_ANS_PTY, m);
1074
	mm_request_send(socket, MONITOR_ANS_PTY, m);
1075
	return (0);
1076
}
1077
1078
int
1079
mm_answer_getloginmsg(int socket, Buffer *m)
1080
{
1081
	char *msg;
1082
1083
	debug3("%s entering", __func__);
1084
1085
	/* retrieve stored login message */
1086
	msg = get_loginmsg();
1087
1088
	buffer_clear(m);
1089
	buffer_put_string(m, msg, strlen(msg));
1090
	mm_request_send(socket, MONITOR_ANS_LOGINMSG, m);
1071
	return (0);
1091
	return (0);
1072
}
1092
}
1073
1093
(-)monitor.h (+1 lines)
Lines 44-49 Link Here
44
	MONITOR_REQ_KEYEXPORT,
44
	MONITOR_REQ_KEYEXPORT,
45
	MONITOR_REQ_PTY, MONITOR_ANS_PTY,
45
	MONITOR_REQ_PTY, MONITOR_ANS_PTY,
46
	MONITOR_REQ_PTYCLEANUP,
46
	MONITOR_REQ_PTYCLEANUP,
47
	MONITOR_REQ_LOGINMSG, MONITOR_ANS_LOGINMSG,
47
	MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY,
48
	MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY,
48
	MONITOR_REQ_SESSID,
49
	MONITOR_REQ_SESSID,
49
	MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
50
	MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
(-)monitor_wrap.c (+19 lines)
Lines 660-665 Link Here
660
	s->ttyfd = -1;
660
	s->ttyfd = -1;
661
}
661
}
662
662
663
char *
664
mm_get_loginmsg(void)
665
{
666
	Buffer m;
667
	char *msg;
668
669
	debug3("%s entering", __func__);
670
671
	buffer_init(&m);
672
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_LOGINMSG, &m);
673
674
	debug3("%s waiting for MONITOR_ANS_LOGINMSG", __func__);
675
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_LOGINMSG, &m);
676
	msg = buffer_get_string(&m, NULL);
677
	buffer_free(&m);
678
679
	return(msg);
680
}
681
663
/* Request process termination */
682
/* Request process termination */
664
683
665
void
684
void
(-)monitor_wrap.h (+1 lines)
Lines 58-63 Link Here
58
void mm_terminate(void);
58
void mm_terminate(void);
59
int mm_pty_allocate(int *, int *, char *, int);
59
int mm_pty_allocate(int *, int *, char *, int);
60
void mm_session_pty_cleanup2(void *);
60
void mm_session_pty_cleanup2(void *);
61
char *mm_get_loginmsg(void);
61
62
62
/* SSHv1 interfaces */
63
/* SSHv1 interfaces */
63
void mm_ssh1_session_id(u_char *);
64
void mm_ssh1_session_id(u_char *);
(-)session.c (-17 / +12 lines)
Lines 86-91 Link Here
86
extern u_int utmp_len;
86
extern u_int utmp_len;
87
extern int startup_pipe;
87
extern int startup_pipe;
88
extern void destroy_sensitive_data(void);
88
extern void destroy_sensitive_data(void);
89
extern Buffer loginmsg;
89
90
90
/* original command from peer. */
91
/* original command from peer. */
91
const char *original_command = NULL;
92
const char *original_command = NULL;
Lines 638-644 Link Here
638
void
639
void
639
do_login(Session *s, const char *command)
640
do_login(Session *s, const char *command)
640
{
641
{
641
	char *time_string;
642
	socklen_t fromlen;
642
	socklen_t fromlen;
643
	struct sockaddr_storage from;
643
	struct sockaddr_storage from;
644
	struct passwd * pw = s->pw;
644
	struct passwd * pw = s->pw;
Lines 668-683 Link Here
668
	if (check_quietlogin(s, command))
668
	if (check_quietlogin(s, command))
669
		return;
669
		return;
670
670
671
	if (options.print_lastlog && s->last_login_time != 0) {
671
	/* print login messages */
672
		time_string = ctime(&s->last_login_time);
672
	printf("%s", get_loginmsg());
673
		if (strchr(time_string, '\n'))
674
			*strchr(time_string, '\n') = 0;
675
		if (strcmp(s->hostname, "") == 0)
676
			printf("Last login: %s\r\n", time_string);
677
		else
678
			printf("Last login: %s from %s\r\n", time_string,
679
			    s->hostname);
680
	}
681
673
682
	do_motd();
674
	do_motd();
683
}
675
}
Lines 1370-1381 Link Here
1370
		packet_disconnect("Protocol error: you already have a pty.");
1362
		packet_disconnect("Protocol error: you already have a pty.");
1371
		return 0;
1363
		return 0;
1372
	}
1364
	}
1373
	/* Get the time and hostname when the user last logged in. */
1374
	if (options.print_lastlog) {
1375
		s->hostname[0] = '\0';
1376
		s->last_login_time = get_last_login_time(s->pw->pw_uid,
1377
		    s->pw->pw_name, s->hostname, sizeof(s->hostname));
1378
	}
1379
1365
1380
	s->term = packet_get_string(&len);
1366
	s->term = packet_get_string(&len);
1381
1367
Lines 1406-1411 Link Here
1406
		return 0;
1392
		return 0;
1407
	}
1393
	}
1408
	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1394
	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1395
1396
	/* copy loginmsg from monitor to display after fork */
1397
	if (use_privsep) {
1398
		char *msg;
1399
1400
		msg = PRIVSEP(get_loginmsg());
1401
		buffer_clear(&loginmsg);
1402
		buffer_append(&loginmsg, msg, strlen(msg));
1403
	}
1409
1404
1410
	/* for SSH1 the tty modes length is not given */
1405
	/* for SSH1 the tty modes length is not given */
1411
	if (!compat20)
1406
	if (!compat20)
(-)session.h (-3 lines)
Lines 39-47 Link Here
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;
(-)sshd.c (+6 lines)
Lines 192-197 Link Here
192
int use_privsep;
192
int use_privsep;
193
struct monitor *pmonitor;
193
struct monitor *pmonitor;
194
194
195
/* message to be displayed after login */
196
Buffer loginmsg;
197
195
/* Prototypes for various functions defined later in this file. */
198
/* Prototypes for various functions defined later in this file. */
196
void destroy_sensitive_data(void);
199
void destroy_sensitive_data(void);
197
void demote_sensitive_data(void);
200
void demote_sensitive_data(void);
Lines 1439-1444 Link Here
1439
	if (use_privsep)
1442
	if (use_privsep)
1440
		if ((authctxt = privsep_preauth()) != NULL)
1443
		if ((authctxt = privsep_preauth()) != NULL)
1441
			goto authenticated;
1444
			goto authenticated;
1445
1446
	/* prepare buffer to collect authentication messages */
1447
	buffer_init(&loginmsg);
1442
1448
1443
	/* perform the key exchange */
1449
	/* perform the key exchange */
1444
	/* authenticate user and start session */
1450
	/* authenticate user and start session */
(-)sshlogin.c (-2 / +48 lines)
Lines 45-51 Link Here
45
#include <utmp.h>
45
#include <utmp.h>
46
#include "sshlogin.h"
46
#include "sshlogin.h"
47
#include "log.h"
47
#include "log.h"
48
#include "buffer.h"
49
#include "servconf.h"
48
50
51
extern Buffer loginmsg;
52
extern ServerOptions options;
53
49
/*
54
/*
50
 * Returns the time when the user last logged in.  Returns 0 if the
55
 * Returns the time when the user last logged in.  Returns 0 if the
51
 * information is not available.  This must be called before record_login.
56
 * information is not available.  This must be called before record_login.
Lines 78-86 Link Here
78
	return ll.ll_time;
83
	return ll.ll_time;
79
}
84
}
80
85
86
/*
87
 * Retrieves loginmsg.  Returns empty string if no message exists.
88
 */
89
char *
90
get_loginmsg(void)
91
{
92
	buffer_append(&loginmsg, "", 1);   /* null terminate string */
93
	return(buffer_ptr(&loginmsg));
94
}
95
96
/*
97
 * Generate and store last login message.  This must be done before
98
 * login_login() is called and lastlog is updated.
99
 */
100
void
101
store_lastlog_message(const char *user, uid_t uid)
102
{
103
	char *time_string, hostname[MAXHOSTNAMELEN], buf[512];
104
	time_t last_login_time;
105
106
	hostname[0] = '\0';
107
	last_login_time = get_last_login_time(uid, user, hostname,
108
	    sizeof(hostname));
109
110
	if (options.print_lastlog && last_login_time != 0) {
111
		time_string = ctime(&last_login_time);
112
		if (strchr(time_string, '\n'))
113
                        *strchr(time_string, '\n') = 0;
114
                if (strcmp(hostname, "") == 0)
115
			snprintf(buf, sizeof(buf), "Last login: %s\r\n",
116
			    time_string);
117
                else
118
			snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n",
119
			    time_string, hostname);
120
		buffer_append(&loginmsg, buf, strlen(buf));
121
	}
122
}
123
81
/*
124
/*
82
 * Records that the user has logged in.  I these parts of operating systems
125
 * Records that the user has logged in.  I wish these parts of operating
83
 * were more standardized.
126
 * systems were more standardized.
84
 */
127
 */
85
void
128
void
86
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
129
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
Lines 90-95 Link Here
90
	struct lastlog ll;
133
	struct lastlog ll;
91
	char *lastlog;
134
	char *lastlog;
92
	struct utmp u;
135
	struct utmp u;
136
137
	/* save previous login details before writing new */
138
	store_lastlog_message(user, uid);
93
139
94
	/* Construct an utmp/wtmp entry. */
140
	/* Construct an utmp/wtmp entry. */
95
	memset(&u, 0, sizeof(u));
141
	memset(&u, 0, sizeof(u));
(-)sshlogin.h (+1 lines)
Lines 19-23 Link Here
19
    const char *, struct sockaddr *, socklen_t);
19
    const char *, struct sockaddr *, socklen_t);
20
void	 record_logout(pid_t, const char *);
20
void	 record_logout(pid_t, const char *);
21
u_long	 get_last_login_time(uid_t, const char *, char *, u_int);
21
u_long	 get_last_login_time(uid_t, const char *, char *, u_int);
22
char	*get_loginmsg(void);
22
23
23
#endif
24
#endif

Return to bug 463