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 (+168 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
 * audit_connection_from() is called and MAY NOT be initialized when
38
 * audit_event(CONNECTION_ABANDON) is called.  Test for NULL before using.
39
 */
40
extern Authctxt *the_authctxt;
41
42
/* Maybe add the audit class to struct Authmethod? */
43
ssh_audit_event_t
44
audit_classify_auth(const char *method)
45
{
46
	if (strcmp(method, "none") == 0)
47
		return AUTH_FAIL_NONE;
48
	else if (strcmp(method, "password") == 0)
49
		return AUTH_FAIL_PASSWD;
50
	else if (strcmp(method, "publickey") == 0 ||
51
	    strcmp(method, "rsa") == 0)
52
		return AUTH_FAIL_PUBKEY;
53
	else if (strncmp(method, "keyboard-interactive", 20) == 0 ||
54
	    strcmp(method, "challenge-response") == 0)
55
		return AUTH_FAIL_KBDINT;
56
	else if (strcmp(method, "hostbased") == 0 ||
57
	    strcmp(method, "rhosts-rsa") == 0)
58
		return AUTH_FAIL_HOSTBASED;
59
	else if (strcmp(method, "gssapi-with-mic") == 0)
60
		return AUTH_FAIL_GSSAPI;
61
	else
62
		return AUDIT_UNKNOWN;
63
}
64
65
# ifndef CUSTOM_AUDIT_EVENTS
66
67
/*
68
 * Null implementations of audit functions.
69
 * These get used if AUDIT_EVENTS is defined but no audit module is enabled.
70
 */
71
72
/* helper to return supplied username */
73
static const char *
74
audit_username(void)
75
{
76
	static const char unknownuser[] = "(unknown user)";
77
78
	if (the_authctxt == NULL || the_authctxt->user == NULL)
79
		return (unknownuser);
80
	return (the_authctxt->user);
81
}
82
83
/*
84
 * Called after a connection has been accepted but before any authentication
85
 * has been attempted.
86
 */
87
void
88
audit_connection_from(const char *host, int port)
89
{
90
	debug("%s: euid %d connection from %s port %d", __func__, geteuid(),
91
	    host, port);
92
}
93
94
/*
95
 * Called when various events occur (see audit.h for a list of possible
96
 * events and what they mean).
97
 */
98
void
99
audit_event(ssh_audit_event_t event)
100
{
101
	char *eventstr[] = {
102
		"LOGIN_EXCEED_MAXTRIES",
103
		"LOGIN_ROOT_DENIED",
104
		"AUTH_SUCCESS",
105
		"AUTH_FAIL_NONE",
106
		"AUTH_FAIL_PASSWD",
107
		"AUTH_FAIL_KBDINT",
108
		"AUTH_FAIL_PUBKEY",
109
		"AUTH_FAIL_HOSTBASED",
110
		"AUTH_FAIL_GSSAPI",
111
		"INVALID_USER",
112
		"NOLOGIN",
113
		"CONNECTION_CLOSE",
114
		"CONNECTION_ABANDON",
115
		"AUDIT_UNKNOWN"
116
	};
117
118
	if (event >= sizeof(eventstr) / sizeof(*eventstr))
119
		fatal("event %d outside valid range", event);
120
	debug("%s: euid %d user %s event %d (%s)", __func__, geteuid(),
121
	    audit_username(), event, eventstr[event]);
122
}
123
124
/*
125
 * Called when a user session is started.  Argument is the tty allocated to
126
 * the session, or NULL if no tty was allocated.
127
 *
128
 * Note that this may be called multiple times if multiple sessions are used
129
 * within a single connection.
130
 */
131
void
132
audit_session_open(const char *ttyn)
133
{
134
	const char *t = ttyn ? ttyn : "(no tty)";
135
136
	debug("%s: euid %d user %s tty name %s", __func__, geteuid(),
137
	     audit_username(), t);
138
}
139
140
/*
141
 * Called when a user session is closed.  Argument is the tty allocated to
142
 * the session, or NULL if no tty was allocated.
143
 *
144
 * Note that this may be called multiple times if multiple sessions are used
145
 * within a single connection.
146
 */
147
void
148
audit_session_close(const char *ttyn)
149
{
150
	const char *t = ttyn ? ttyn : "(no tty)";
151
152
	debug("%s: euid %d user %s tty name %s", __func__, geteuid(),
153
	     audit_username(), t);
154
}
155
156
/*
157
 * This will be called when a user runs a non-interactive command.  Note that
158
 * it may be called multiple times for a single connection since SSH2 allows
159
 * multiple sessions within a single connection.
160
 */
161
void
162
audit_run_command(const char *command)
163
{
164
	debug("%s: euid %d user %s command '%s'", __func__, geteuid(),
165
	    audit_username(), command);
166
}
167
# endif  /* !defined CUSTOM_AUDIT_EVENTS */
168
#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 rhostsrsa */
40
	AUTH_FAIL_GSSAPI,
41
	INVALID_USER,
42
	NOLOGIN,		/* denied by /etc/nologin, not implemented */
43
	CONNECTION_CLOSE,	/* closed after attempting auth or session */
44
	CONNECTION_ABANDON,	/* closed without completing auth */
45
	AUDIT_UNKNOWN
46
};
47
typedef enum ssh_audit_event_type ssh_audit_event_t;
48
49
void	audit_connection_from(const char *, int);
50
void	audit_event(ssh_audit_event_t);
51
void	audit_session_open(const char *);
52
void	audit_session_close(const char *);
53
void	audit_run_command(const char *);
54
ssh_audit_event_t audit_classify_auth(const char *);
55
56
#endif /* _SSH_AUDIT_H */
(-)auth.c (+42 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.
260
		 */
261
		event = audit_classify_auth(method);
262
		switch(event) {
263
		case AUTH_FAIL_NONE:
264
		case AUTH_FAIL_PASSWD:
265
		case AUTH_FAIL_KBDINT:
266
			if (geteuid() == 0)
267
				audit_event(event);
268
			break;
269
		case AUTH_FAIL_PUBKEY:
270
		case AUTH_FAIL_HOSTBASED:
271
		case AUTH_FAIL_GSSAPI:
272
			/*
273
			 * This is required to handle the case where privsep
274
			 * is enabled but it's root logging in, since
275
			 * use_privsep won't be cleared until after a
276
			 * successful login.
277
			 */
278
			if (geteuid() == 0)
279
				audit_event(event);
280
			else
281
				PRIVSEP(audit_event(event));
282
			break;
283
		default:
284
			error("unknown authentication audit event %d", event);
285
		}
286
	}
287
#endif
249
}
288
}
250
289
251
/*
290
/*
Lines 470-475 getpwnamallow(const char *user) Link Here
470
#ifdef CUSTOM_FAILED_LOGIN
509
#ifdef CUSTOM_FAILED_LOGIN
471
		record_failed_login(user, "ssh");
510
		record_failed_login(user, "ssh");
472
#endif
511
#endif
512
#ifdef AUDIT_EVENTS
513
		audit_event(INVALID_USER);
514
#endif /* AUDIT_EVENTS */
473
		return (NULL);
515
		return (NULL);
474
	}
516
	}
475
	if (!allowed_user(pw))
517
	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 / +10 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
			PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES));
293
#endif
287
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
294
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
295
		}
288
296
289
		packet_start(SSH_SMSG_FAILURE);
297
		packet_start(SSH_SMSG_FAILURE);
290
		packet_send();
298
		packet_send();
(-)auth2.c (-2 / +13 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
			PRIVSEP(audit_event(LOGIN_EXCEED_MAXTRIES));
268
#endif
259
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
269
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
270
		}
260
		methods = authmethods_get();
271
		methods = authmethods_get();
261
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
272
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
262
		packet_put_cstring(methods);
273
		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 (+65 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|MON_ONCE, 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
	case CONNECTION_CLOSE:
1534
		audit_event(event);
1535
		break;
1536
	default:
1537
		fatal("Audit event type %d not permitted", event);
1538
	}
1539
1540
	return (0);
1541
}
1542
1543
int
1544
mm_answer_audit_command(int socket, Buffer *m)
1545
{
1546
	u_int len;
1547
	char *cmd;
1548
1549
	debug3("%s entering", __func__);
1550
	cmd = buffer_get_string(m, &len);
1551
	/* sanity check command, if so how? */
1552
	audit_run_command(cmd);
1553
	xfree(cmd);
1554
	buffer_free(m);
1555
	return (0);
1556
}
1557
#endif /* AUDIT_EVENTS */
1493
1558
1494
void
1559
void
1495
monitor_apply_keystate(struct monitor *pmonitor)
1560
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 (+16 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
	PRIVSEP(audit_event(CONNECTION_CLOSE));
2312
#endif
2328
#endif
2313
2329
2314
	/* remove agent socket */
2330
	/* remove agent socket */
(-)sshd.c (+10 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.
Lines 2008-2013 do_ssh2_kex(void) Link Here
2008
void
2015
void
2009
cleanup_exit(int i)
2016
cleanup_exit(int i)
2010
{
2017
{
2018
#ifdef AUDIT_EVENTS
2019
	audit_event(CONNECTION_ABANDON);
2020
#endif
2011
	if (the_authctxt)
2021
	if (the_authctxt)
2012
		do_cleanup(the_authctxt);
2022
		do_cleanup(the_authctxt);
2013
	_exit(i);
2023
	_exit(i);

Return to bug 125