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

Collapse All | Expand All

(-)Makefile.in (-1 / +1 lines)
Lines 85-91 SSHDOBJS=sshd.o auth-rhosts.o auth-passw Link Here
85
	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
85
	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
86
	auth-krb5.o \
86
	auth-krb5.o \
87
	auth2-gss.o gss-serv.o gss-serv-krb5.o \
87
	auth2-gss.o gss-serv.o gss-serv-krb5.o \
88
	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o
88
	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o audit.o
89
89
90
MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
90
MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
91
MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
91
MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
(-)audit.c (+176 lines)
Added Link Here
1
/* $Id$ */
2
3
/*
4
 * Copyright (c) 2004, 2005 Darren Tucker.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "includes.h"
28
29
#ifdef AUDIT_EVENTS
30
31
#include "audit.h"
32
#include "log.h"
33
#include "auth.h"
34
35
/*
36
 * Care must be taken when using this since it will not be initialized when
37
 * connection_from is called.  Test it for NULL before using.
38
 */
39
extern Authctxt *the_authctxt;
40
41
/* Maybe add the audit class to struct Authmethod? */
42
ssh_audit_event_t
43
audit_classify_auth(const char *method)
44
{
45
	if (strcmp(method, "none") == 0)
46
		return AUTH_FAIL_NONE;
47
	else if (strcmp(method, "password") == 0)
48
		return AUTH_FAIL_PASSWD;
49
	else if (strcmp(method, "publickey") == 0 ||
50
	    strcmp(method, "rsa") == 0)
51
		return AUTH_FAIL_PUBKEY;
52
	else if (strncmp(method, "keyboard-interactive", 20) == 0 ||
53
	    strcmp(method, "challenge-response") == 0)
54
		return AUTH_FAIL_KBDINT;
55
	else if (strcmp(method, "hostbased") == 0 ||
56
	    strcmp(method, "rhosts-rsa") == 0)
57
		return AUTH_FAIL_HOSTBASED;
58
	else if (strcmp(method, "gssapi-with-mic") == 0)
59
		return AUTH_FAIL_GSSAPI;
60
	else
61
		return AUDIT_UNKNOWN;
62
}
63
64
# ifndef CUSTOM_AUDIT_EVENTS
65
66
/*
67
 * Null implementations of audit functions.
68
 * These get used if AUDIT_EVENTS is enabled but no audit module is defined.
69
 */
70
71
/* helper to return supplied username */
72
static const char *
73
audit_username(void)
74
{
75
	static const char unknownuser[] = "(unknown user)";
76
77
	if (the_authctxt == NULL || the_authctxt->user == NULL)
78
		return (unknownuser);
79
	return (the_authctxt->user);
80
}
81
82
/*
83
 * Called after a connection has been accepted but before any authentication
84
 * has been attempted.
85
 */
86
void
87
audit_connection_from(const char *host, int port)
88
{
89
	debug("%s: euid %d connection from %s port %d", __func__, geteuid(),
90
	    host, port);
91
}
92
93
/*
94
 * Called when various events occur (see audit.h for a list of possible
95
 * events).
96
 */
97
void
98
audit_event(ssh_audit_event_t event)
99
{
100
	char *eventstr[] = {
101
		"LOGIN_EXCEED_MAXTRIES",
102
		"LOGIN_ROOT_DENIED",
103
		"AUTH_SUCCESS",
104
		"AUTH_FAIL_NONE",
105
		"AUTH_FAIL_PASSWD",
106
		"AUTH_FAIL_KBDINT",
107
		"AUTH_FAIL_PUBKEY",
108
		"AUTH_FAIL_HOSTBASED",
109
		"AUTH_FAIL_GSSAPI",
110
		"INVALID_USER",
111
		"NOLOGIN",
112
		"CONNECTION_CLOSE",
113
		"AUDIT_UNKNOWN"
114
	};
115
116
	if (event >= sizeof(eventstr) / sizeof(*eventstr))
117
		fatal("event %d outside valid range", event);
118
	debug("%s: euid %d user %s event %d (%s)", __func__, geteuid(),
119
	    audit_username(), event, eventstr[event]);
120
}
121
122
/*
123
 * Called when a user session is started.  Argument is the tty allocated to
124
 * the session, or NULL if no tty was allocated.
125
 *
126
 * Note that this may be called multiple times if multiple sessions are used
127
 * within a single connection.
128
 */
129
void
130
audit_session_open(const char *ttyn)
131
{
132
	const char *t = ttyn ? ttyn : "(no tty)";
133
134
	debug("%s: euid %d user %s tty name %s", __func__, geteuid(),
135
	     audit_username(), t);
136
}
137
138
/*
139
 * Called when a user session is closed.  Argument is the tty allocated to
140
 * the session, or NULL if no tty was allocated.
141
 *
142
 * Note that this may be called multiple times if multiple sessions are used
143
 * within a single connection.
144
 */
145
void
146
audit_session_close(const char *ttyn)
147
{
148
	const char *t = ttyn ? ttyn : "(no tty)";
149
150
	debug("%s: euid %d user %s tty name %s", __func__, geteuid(),
151
	     audit_username(), t);
152
}
153
154
/*
155
 * This will be called when a user runs a non-interactive command.  Note that
156
 * it may be called multiple times for a single connection since SSH2 allows
157
 * multiple sessions within a single connection.
158
 */
159
void
160
audit_run_command(const char *command)
161
{
162
	debug("%s: euid %d user %s command '%s'", __func__, geteuid(),
163
	    audit_username(), command);
164
}
165
166
/*
167
 * Called for connections that terminate without authenticating successfully
168
 * and on fatal errors.
169
 */
170
void
171
audit_cleanup(void)
172
{
173
	debug("%s called for user %s", __func__, audit_username());
174
}
175
# endif  /* !defined CUSTOM_AUDIT_EVENTS */
176
#endif /* AUDIT_EVENTS */
(-)audit.h (+56 lines)
Added Link Here
1
/* $Id$ */
2
3
/*
4
 * Copyright (c) 2004, 2005 Darren Tucker.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "auth.h"
28
29
#ifndef _SSH_AUDIT_H
30
# define _SSH_AUDIT_H
31
enum ssh_audit_event_type {
32
	LOGIN_EXCEED_MAXTRIES,
33
	LOGIN_ROOT_DENIED,
34
	AUTH_SUCCESS,
35
	AUTH_FAIL_NONE,
36
	AUTH_FAIL_PASSWD,
37
	AUTH_FAIL_KBDINT,	/* keyboard-interactive or challenge-response */
38
	AUTH_FAIL_PUBKEY,	/* ssh2 pubkey or ssh1 rsa */
39
	AUTH_FAIL_HOSTBASED,	/* ssh2 hostbased or ssh1 rsarhsots */
40
	AUTH_FAIL_GSSAPI,
41
	INVALID_USER,
42
	NOLOGIN,		/* not implemented */
43
	CONNECTION_CLOSE,	/* not implemented */
44
	AUDIT_UNKNOWN
45
};
46
typedef enum ssh_audit_event_type ssh_audit_event_t;
47
48
void	audit_connection_from(const char *, int);
49
void	audit_event(ssh_audit_event_t);
50
void	audit_session_open(const char *);
51
void	audit_session_close(const char *);
52
void	audit_run_command(const char *);
53
void	audit_cleanup(void);
54
ssh_audit_event_t audit_classify_auth(const char *);
55
56
#endif /* _SSH_AUDIT_H */
(-)auth.c (+37 lines)
Lines 50-55 RCSID("$OpenBSD: auth.c,v 1.57 2005/01/2 Link Here
50
#include "misc.h"
50
#include "misc.h"
51
#include "bufaux.h"
51
#include "bufaux.h"
52
#include "packet.h"
52
#include "packet.h"
53
#include "monitor_wrap.h"
53
54
54
/* import */
55
/* import */
55
extern ServerOptions options;
56
extern ServerOptions options;
Lines 246-251 auth_log(Authctxt *authctxt, int authent Link Here
246
	if (authenticated == 0 && strcmp(method, "password") == 0)
247
	if (authenticated == 0 && strcmp(method, "password") == 0)
247
		record_failed_login(authctxt->user, "ssh");
248
		record_failed_login(authctxt->user, "ssh");
248
#endif
249
#endif
250
#ifdef AUDIT_EVENTS
251
	if (authenticated == 0 && !authctxt->postponed) {
252
		ssh_audit_event_t event;
253
254
		debug3("%s: audit failed auth attempt, method %s euid %d",
255
		    __func__, method, geteuid());
256
		/*
257
		 * Because the auth loop is used in both monitor and slave,
258
		 * we must be careful to send each event only once and with
259
		 * enough privs to write the event.  Also need to handle the
260
		 * case where privsep=yes but root has logged on.
261
		 */
262
		event = audit_classify_auth(method);
263
		switch(event) {
264
		case AUTH_FAIL_NONE:
265
		case AUTH_FAIL_PASSWD:
266
		case AUTH_FAIL_KBDINT:
267
			if (geteuid() == 0)
268
				audit_event(event);
269
			break;
270
		case AUTH_FAIL_PUBKEY:
271
		case AUTH_FAIL_HOSTBASED:
272
		case AUTH_FAIL_GSSAPI:
273
			if (geteuid() == 0)
274
				audit_event(event);
275
			else
276
				PRIVSEP(audit_event(event));
277
			break;
278
		default:
279
			error("unknown authentication audit event %d", event);
280
		}
281
	}
282
#endif
249
}
283
}
250
284
251
/*
285
/*
Lines 470-475 getpwnamallow(const char *user) Link Here
470
#ifdef CUSTOM_FAILED_LOGIN
504
#ifdef CUSTOM_FAILED_LOGIN
471
		record_failed_login(user, "ssh");
505
		record_failed_login(user, "ssh");
472
#endif
506
#endif
507
#ifdef AUDIT_EVENTS
508
		audit_event(INVALID_USER);
509
#endif /* AUDIT_EVENTS */
473
		return (NULL);
510
		return (NULL);
474
	}
511
	}
475
	if (!allowed_user(pw))
512
	if (!allowed_user(pw))
(-)auth.h (+1 lines)
Lines 130-135 int auth_shadow_pwexpired(Authctxt *); Link Here
130
#endif
130
#endif
131
131
132
#include "auth-pam.h"
132
#include "auth-pam.h"
133
#include "audit.h"
133
void remove_kbdint_device(const char *);
134
void remove_kbdint_device(const char *);
134
135
135
void disable_forwarding(void);
136
void disable_forwarding(void);
(-)auth1.c (-2 / +11 lines)
Lines 247-254 do_authloop(Authctxt *authctxt) Link Here
247
#else
247
#else
248
		/* Special handling for root */
248
		/* Special handling for root */
249
		if (authenticated && authctxt->pw->pw_uid == 0 &&
249
		if (authenticated && authctxt->pw->pw_uid == 0 &&
250
		    !auth_root_allowed(get_authname(type)))
250
		    !auth_root_allowed(get_authname(type))) {
251
			authenticated = 0;
251
			authenticated = 0;
252
# ifdef AUDIT_EVENTS
253
			PRIVSEP(audit_event(LOGIN_ROOT_DENIED));
254
# endif
255
		}
252
#endif
256
#endif
253
257
254
#ifdef USE_PAM
258
#ifdef USE_PAM
Lines 283-290 do_authloop(Authctxt *authctxt) Link Here
283
		if (authenticated)
287
		if (authenticated)
284
			return;
288
			return;
285
289
286
		if (authctxt->failures++ > options.max_authtries)
290
		if (authctxt->failures++ > options.max_authtries) {
291
#ifdef AUDIT_EVENTS
292
			if (use_privsep)
293
				PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES));
294
#endif
287
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
295
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
296
		}
288
297
289
		packet_start(SSH_SMSG_FAILURE);
298
		packet_start(SSH_SMSG_FAILURE);
290
		packet_send();
299
		packet_send();
(-)auth2.c (-2 / +14 lines)
Lines 167-172 input_userauth_request(int type, u_int32 Link Here
167
			if (options.use_pam)
167
			if (options.use_pam)
168
				PRIVSEP(start_pam(authctxt));
168
				PRIVSEP(start_pam(authctxt));
169
#endif
169
#endif
170
#ifdef AUDIT_EVENTS
171
			PRIVSEP(audit_event(INVALID_USER));
172
#endif
170
		}
173
		}
171
		setproctitle("%s%s", authctxt->valid ? user : "unknown",
174
		setproctitle("%s%s", authctxt->valid ? user : "unknown",
172
		    use_privsep ? " [net]" : "");
175
		    use_privsep ? " [net]" : "");
Lines 214-221 userauth_finish(Authctxt *authctxt, int Link Here
214
217
215
	/* Special handling for root */
218
	/* Special handling for root */
216
	if (authenticated && authctxt->pw->pw_uid == 0 &&
219
	if (authenticated && authctxt->pw->pw_uid == 0 &&
217
	    !auth_root_allowed(method))
220
	    !auth_root_allowed(method)) {
218
		authenticated = 0;
221
		authenticated = 0;
222
#ifdef AUDIT_EVENTS
223
		PRIVSEP(audit_event(LOGIN_ROOT_DENIED));
224
#endif
225
	}
219
226
220
#ifdef USE_PAM
227
#ifdef USE_PAM
221
	if (options.use_pam && authenticated) {
228
	if (options.use_pam && authenticated) {
Lines 255-262 userauth_finish(Authctxt *authctxt, int Link Here
255
		/* now we can break out */
262
		/* now we can break out */
256
		authctxt->success = 1;
263
		authctxt->success = 1;
257
	} else {
264
	} else {
258
		if (authctxt->failures++ > options.max_authtries)
265
		if (authctxt->failures++ > options.max_authtries) {
266
#ifdef AUDIT_EVENTS
267
			if (use_privsep)
268
				PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES));
269
#endif
259
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
270
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
271
		}
260
		methods = authmethods_get();
272
		methods = authmethods_get();
261
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
273
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
262
		packet_put_cstring(methods);
274
		packet_put_cstring(methods);
(-)loginrec.c (+7 lines)
Lines 131-136 Link Here
131
#include "loginrec.h"
131
#include "loginrec.h"
132
#include "log.h"
132
#include "log.h"
133
#include "atomicio.h"
133
#include "atomicio.h"
134
#include "auth.h"
134
135
135
#ifdef HAVE_UTIL_H
136
#ifdef HAVE_UTIL_H
136
# include <util.h>
137
# include <util.h>
Lines 419-424 login_write(struct logininfo *li) Link Here
419
	if (li->type == LTYPE_LOGIN && 
420
	if (li->type == LTYPE_LOGIN && 
420
	   !sys_auth_record_login(li->username,li->hostname,li->line))
421
	   !sys_auth_record_login(li->username,li->hostname,li->line))
421
		logit("Writing login record failed for %s", li->username);
422
		logit("Writing login record failed for %s", li->username);
423
#endif
424
#ifdef AUDIT_EVENTS
425
	if (li->type == LTYPE_LOGIN)
426
		audit_session_open(li->line);
427
	else if (li->type == LTYPE_LOGOUT)
428
		audit_session_close(li->line);
422
#endif
429
#endif
423
	return (0);
430
	return (0);
424
}
431
}
(-)monitor.c (+64 lines)
Lines 143-148 int mm_answer_gss_userok(int, Buffer *); Link Here
143
int mm_answer_gss_checkmic(int, Buffer *);
143
int mm_answer_gss_checkmic(int, Buffer *);
144
#endif
144
#endif
145
145
146
#ifdef AUDIT_EVENTS
147
int mm_answer_audit_event(int, Buffer *);
148
int mm_answer_audit_command(int, Buffer *);
149
#endif
150
146
static Authctxt *authctxt;
151
static Authctxt *authctxt;
147
static BIGNUM *ssh1_challenge = NULL;	/* used for ssh1 rsa auth */
152
static BIGNUM *ssh1_challenge = NULL;	/* used for ssh1 rsa auth */
148
153
Lines 186-191 struct mon_table mon_dispatch_proto20[] Link Here
186
    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
191
    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
187
    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
192
    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
188
#endif
193
#endif
194
#ifdef AUDIT_EVENTS
195
    {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event},
196
#endif
189
#ifdef BSD_AUTH
197
#ifdef BSD_AUTH
190
    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
198
    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
191
    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
199
    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
Lines 211-216 struct mon_table mon_dispatch_postauth20 Link Here
211
    {MONITOR_REQ_PTY, 0, mm_answer_pty},
219
    {MONITOR_REQ_PTY, 0, mm_answer_pty},
212
    {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
220
    {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
213
    {MONITOR_REQ_TERM, 0, mm_answer_term},
221
    {MONITOR_REQ_TERM, 0, mm_answer_term},
222
#ifdef AUDIT_EVENTS
223
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
224
    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
225
#endif
214
    {0, 0, NULL}
226
    {0, 0, NULL}
215
};
227
};
216
228
Lines 239-244 struct mon_table mon_dispatch_proto15[] Link Here
239
    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
251
    {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
240
    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
252
    {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
241
#endif
253
#endif
254
#ifdef AUDIT_EVENTS
255
    {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event},
256
#endif
242
    {0, 0, NULL}
257
    {0, 0, NULL}
243
};
258
};
244
259
Lines 246-251 struct mon_table mon_dispatch_postauth15 Link Here
246
    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
261
    {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
247
    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
262
    {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
248
    {MONITOR_REQ_TERM, 0, mm_answer_term},
263
    {MONITOR_REQ_TERM, 0, mm_answer_term},
264
#ifdef AUDIT_EVENTS
265
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
266
    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
267
#endif
249
    {0, 0, NULL}
268
    {0, 0, NULL}
250
};
269
};
251
270
Lines 609-614 mm_answer_pwnamallow(int sock, Buffer *m Link Here
609
	if (options.use_pam)
628
	if (options.use_pam)
610
		monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
629
		monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
611
#endif
630
#endif
631
#ifdef AUDIT_EVENTS
632
	monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_EVENT, 1);
633
#endif
612
634
613
	return (0);
635
	return (0);
614
}
636
}
Lines 1490-1495 mm_answer_term(int sock, Buffer *req) Link Here
1490
	/* Terminate process */
1512
	/* Terminate process */
1491
	exit(res);
1513
	exit(res);
1492
}
1514
}
1515
1516
#ifdef AUDIT_EVENTS
1517
/* Report that an audit event occurred */
1518
int
1519
mm_answer_audit_event(int socket, Buffer *m)
1520
{
1521
	ssh_audit_event_t event;
1522
1523
	debug3("%s entering", __func__);
1524
1525
	event = buffer_get_int(m);
1526
	buffer_free(m);
1527
	switch(event) {
1528
	case AUTH_FAIL_PUBKEY:
1529
	case AUTH_FAIL_HOSTBASED:
1530
	case AUTH_FAIL_GSSAPI:
1531
	case LOGIN_EXCEED_MAXTRIES:
1532
	case LOGIN_ROOT_DENIED:
1533
		audit_event(event);
1534
		break;
1535
	default:
1536
		fatal("Audit event type %d not permitted", event);
1537
	}
1538
1539
	return (0);
1540
}
1541
1542
int
1543
mm_answer_audit_command(int socket, Buffer *m)
1544
{
1545
	u_int len;
1546
	char *cmd;
1547
1548
	debug3("%s entering", __func__);
1549
	cmd = buffer_get_string(m, &len);
1550
	/* sanity check command, if so how? */
1551
	audit_run_command(cmd);
1552
	xfree(cmd);
1553
	buffer_free(m);
1554
	return (0);
1555
}
1556
#endif /* AUDIT_EVENTS */
1493
1557
1494
void
1558
void
1495
monitor_apply_keystate(struct monitor *pmonitor)
1559
monitor_apply_keystate(struct monitor *pmonitor)
(-)monitor.h (+1 lines)
Lines 59-64 enum monitor_reqtype { Link Here
59
	MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
59
	MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
60
	MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
60
	MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
61
	MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
61
	MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
62
	MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
62
	MONITOR_REQ_TERM
63
	MONITOR_REQ_TERM
63
};
64
};
64
65
(-)monitor_wrap.c (+30 lines)
Lines 1103-1108 mm_auth_rsa_verify_response(Key *key, BI Link Here
1103
	return (success);
1103
	return (success);
1104
}
1104
}
1105
1105
1106
#ifdef AUDIT_EVENTS
1107
void
1108
mm_audit_event(ssh_audit_event_t event)
1109
{
1110
	Buffer m;
1111
1112
	debug3("%s entering", __func__);
1113
1114
	buffer_init(&m);
1115
	buffer_put_int(&m, event);
1116
1117
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
1118
	buffer_free(&m);
1119
}
1120
1121
void
1122
mm_audit_run_command(const char *command)
1123
{
1124
	Buffer m;
1125
1126
	debug3("%s entering command %s", __func__, command);
1127
1128
	buffer_init(&m);
1129
	buffer_put_cstring(&m, command);
1130
1131
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
1132
	buffer_free(&m);
1133
}
1134
#endif /* AUDIT_EVENTS */
1135
1106
#ifdef GSSAPI
1136
#ifdef GSSAPI
1107
OM_uint32
1137
OM_uint32
1108
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
1138
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
(-)monitor_wrap.h (+6 lines)
Lines 74-79 int mm_sshpam_respond(void *, u_int, cha Link Here
74
void mm_sshpam_free_ctx(void *);
74
void mm_sshpam_free_ctx(void *);
75
#endif
75
#endif
76
76
77
#ifdef AUDIT_EVENTS
78
#include "audit.h"
79
void mm_audit_event(ssh_audit_event_t);
80
void mm_audit_run_command(const char *);
81
#endif
82
77
struct Session;
83
struct Session;
78
void mm_terminate(void);
84
void mm_terminate(void);
79
int mm_pty_allocate(int *, int *, char *, int);
85
int mm_pty_allocate(int *, int *, char *, int);
(-)session.c (+17 lines)
Lines 665-670 do_exec(Session *s, const char *command) Link Here
665
		debug("Forced command '%.900s'", command);
665
		debug("Forced command '%.900s'", command);
666
	}
666
	}
667
667
668
#ifdef AUDIT_EVENTS
669
	if (command != NULL)
670
		PRIVSEP(audit_run_command(command));
671
	else if (s->ttyfd == -1) {
672
		char *shell = s->pw->pw_shell;
673
674
		if (shell[0] == '\0')	/* empty shell means /bin/sh */
675
			shell =_PATH_BSHELL;
676
		PRIVSEP(audit_run_command(shell));
677
	}
678
#endif
679
668
#ifdef GSSAPI
680
#ifdef GSSAPI
669
	if (options.gss_authentication) {
681
	if (options.gss_authentication) {
670
		temporarily_use_uid(s->pw);
682
		temporarily_use_uid(s->pw);
Lines 2309-2314 do_cleanup(Authctxt *authctxt) Link Here
2309
		sshpam_cleanup();
2321
		sshpam_cleanup();
2310
		sshpam_thread_cleanup();
2322
		sshpam_thread_cleanup();
2311
	}
2323
	}
2324
#endif
2325
2326
#ifdef AUDIT_EVENTS
2327
	if (!use_privsep || mm_is_monitor())
2328
		audit_cleanup();
2312
#endif
2329
#endif
2313
2330
2314
	/* remove agent socket */
2331
	/* remove agent socket */
(-)sshd.c (+7 lines)
Lines 1628-1633 main(int ac, char **av) Link Here
1628
	remote_port = get_remote_port();
1628
	remote_port = get_remote_port();
1629
	remote_ip = get_remote_ipaddr();
1629
	remote_ip = get_remote_ipaddr();
1630
1630
1631
#ifdef AUDIT_EVENTS
1632
	audit_connection_from(remote_ip, remote_port);
1633
#endif
1631
#ifdef LIBWRAP
1634
#ifdef LIBWRAP
1632
	/* Check whether logins are denied from this host. */
1635
	/* Check whether logins are denied from this host. */
1633
	if (packet_connection_is_on_socket()) {
1636
	if (packet_connection_is_on_socket()) {
Lines 1697-1702 main(int ac, char **av) Link Here
1697
	}
1700
	}
1698
1701
1699
 authenticated:
1702
 authenticated:
1703
#ifdef AUDIT_EVENTS
1704
	audit_event(AUTH_SUCCESS);
1705
#endif
1706
1700
	/*
1707
	/*
1701
	 * In privilege separation, we fork another child and prepare
1708
	 * In privilege separation, we fork another child and prepare
1702
	 * file descriptor passing.
1709
	 * file descriptor passing.

Return to bug 125