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

Collapse All | Expand All

(-)a/Makefile.in (-1 / +1 lines)
Lines 92-98 LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ Link Here
92
	kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
92
	kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
93
	kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
93
	kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
94
	kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
94
	kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
95
	platform-pledge.o
95
	platform-pledge.o auditstub.o
96
96
97
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
97
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
98
	sshconnect.o sshconnect1.o sshconnect2.o mux.o
98
	sshconnect.o sshconnect1.o sshconnect2.o mux.o
(-)a/audit-bsm.c (-1 / +56 lines)
Lines 375-384 audit_connection_from(const char *host, int port) Link Here
375
#endif
375
#endif
376
}
376
}
377
377
378
void
378
int
379
audit_run_command(const char *command)
379
audit_run_command(const char *command)
380
{
380
{
381
	/* not implemented */
381
	/* not implemented */
382
	return 0;
383
}
384
385
void
386
audit_end_command(int handle, const char *command)
387
{
388
	/* not implemented */
389
}
390
391
void
392
audit_count_session_open(void)
393
{
394
	/* not necessary */
382
}
395
}
383
396
384
void
397
void
Lines 393-398 audit_session_close(struct logininfo *li) Link Here
393
	/* not implemented */
406
	/* not implemented */
394
}
407
}
395
408
409
int
410
audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
411
{
412
	/* not implemented */
413
}
414
396
void
415
void
397
audit_event(ssh_audit_event_t event)
416
audit_event(ssh_audit_event_t event)
398
{
417
{
Lines 454-457 audit_event(ssh_audit_event_t event) Link Here
454
		debug("%s: unhandled event %d", __func__, event);
473
		debug("%s: unhandled event %d", __func__, event);
455
	}
474
	}
456
}
475
}
476
477
void
478
audit_unsupported_body(int what)
479
{
480
	/* not implemented */
481
}
482
483
void
484
audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid)
485
{
486
	/* not implemented */
487
}
488
489
void
490
audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
491
{
492
	/* not implemented */
493
}
494
495
void
496
audit_destroy_sensitive_data(const char *fp)
497
{
498
	/* not implemented */
499
}
500
501
void
502
audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
503
{
504
	/* not implemented */
505
}
506
507
void
508
audit_generate_ephemeral_server_key(const char *fp)
509
{
510
	/* not implemented */
511
}
457
#endif /* BSM */
512
#endif /* BSM */
(-)a/audit-linux.c (-18 / +302 lines)
Lines 35-47 Link Here
35
35
36
#include "log.h"
36
#include "log.h"
37
#include "audit.h"
37
#include "audit.h"
38
#include "key.h"
39
#include "hostfile.h"
40
#include "auth.h"
41
#include "misc.h"      /* servconf.h needs misc.h for struct ForwardOptions */
42
#include "servconf.h"
38
#include "canohost.h"
43
#include "canohost.h"
44
#include "packet.h"
45
#include "cipher.h"
39
46
47
#define AUDIT_LOG_SIZE 256
48
49
extern ServerOptions options;
50
extern Authctxt *the_authctxt;
51
extern u_int utmp_len;
40
const char* audit_username(void);
52
const char* audit_username(void);
41
53
42
int
54
static void
43
linux_audit_record_event(int uid, const char *username,
55
linux_audit_user_logxxx(int uid, const char *username,
44
    const char *hostname, const char *ip, const char *ttyn, int success)
56
    const char *hostname, const char *ip, const char *ttyn, int success, int event)
45
{
57
{
46
	int audit_fd, rc, saved_errno;
58
	int audit_fd, rc, saved_errno;
47
59
Lines 49-59 linux_audit_record_event(int uid, const char *username, Link Here
49
	if (audit_fd < 0) {
61
	if (audit_fd < 0) {
50
		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
62
		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
51
		    errno == EAFNOSUPPORT)
63
		    errno == EAFNOSUPPORT)
52
			return 1; /* No audit support in kernel */
64
			return; /* No audit support in kernel */
53
		else
65
		else
54
			return 0; /* Must prevent login */
66
			goto fatal_report; /* Must prevent login */
55
	}
67
	}
56
	rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
68
	rc = audit_log_acct_message(audit_fd, event,
57
	    NULL, "login", username ? username : "(unknown)",
69
	    NULL, "login", username ? username : "(unknown)",
58
	    username == NULL ? uid : -1, hostname, ip, ttyn, success);
70
	    username == NULL ? uid : -1, hostname, ip, ttyn, success);
59
	saved_errno = errno;
71
	saved_errno = errno;
Lines 65-99 linux_audit_record_event(int uid, const char *username, Link Here
65
	if ((rc == -EPERM) && (geteuid() != 0))
77
	if ((rc == -EPERM) && (geteuid() != 0))
66
		rc = 0;
78
		rc = 0;
67
	errno = saved_errno;
79
	errno = saved_errno;
68
	return (rc >= 0);
80
	if (rc < 0) {
81
fatal_report:
82
		fatal("linux_audit_write_entry failed: %s", strerror(errno));
83
	}
84
}
85
86
static void
87
linux_audit_user_auth(int uid, const char *username,
88
    const char *hostname, const char *ip, const char *ttyn, int success, int event)
89
{
90
	int audit_fd, rc, saved_errno;
91
	static const char *event_name[] = {
92
		"maxtries exceeded",
93
		"root denied",
94
		"success",
95
		"none",
96
		"password",
97
		"challenge-response",
98
		"pubkey",
99
		"hostbased",
100
		"gssapi",
101
		"invalid user",
102
		"nologin",
103
		"connection closed",
104
		"connection abandoned",
105
		"unknown"
106
	};
107
108
	audit_fd = audit_open();
109
	if (audit_fd < 0) {
110
		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
111
		    errno == EAFNOSUPPORT)
112
			return; /* No audit support in kernel */
113
		else
114
			goto fatal_report; /* Must prevent login */
115
	}
116
117
	if ((event < 0) || (event > SSH_AUDIT_UNKNOWN))
118
		event = SSH_AUDIT_UNKNOWN;
119
120
	rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH,
121
	    NULL, event_name[event], username ? username : "(unknown)",
122
	    username == NULL ? uid : -1, hostname, ip, ttyn, success);
123
	saved_errno = errno;
124
	close(audit_fd);
125
	/*
126
	 * Do not report error if the error is EPERM and sshd is run as non
127
	 * root user.
128
	 */
129
	if ((rc == -EPERM) && (geteuid() != 0))
130
		rc = 0;
131
	errno = saved_errno;
132
	if (rc < 0) {
133
fatal_report:
134
		fatal("linux_audit_write_entry failed: %s", strerror(errno));
135
	}
136
}
137
138
int
139
audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
140
{
141
	char buf[AUDIT_LOG_SIZE];
142
	int audit_fd, rc, saved_errno;
143
144
	audit_fd = audit_open();
145
	if (audit_fd < 0) {
146
		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
147
					 errno == EAFNOSUPPORT)
148
			return 1; /* No audit support in kernel */
149
		else
150
			return 0; /* Must prevent login */
151
	}
152
	snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port());
153
	rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
154
		buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
155
	if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
156
		goto out;
157
	/* is the fingerprint_prefix() still needed?
158
	snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d",
159
			type, bits, sshkey_fingerprint_prefix(), fp, get_remote_port());
160
	*/
161
	snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s rport=%d",
162
			type, bits, fp, get_remote_port());
163
	rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
164
		buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
165
out:
166
	saved_errno = errno;
167
	audit_close(audit_fd);
168
	errno = saved_errno;
169
	/* do not report error if the error is EPERM and sshd is run as non root user */
170
	return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0));
69
}
171
}
70
172
173
static int user_login_count = 0;
174
71
/* Below is the sshd audit API code */
175
/* Below is the sshd audit API code */
72
176
73
void
177
void
74
audit_connection_from(const char *host, int port)
178
audit_connection_from(const char *host, int port)
75
{
179
{
76
}
77
	/* not implemented */
180
	/* not implemented */
181
}
78
182
79
void
183
int
80
audit_run_command(const char *command)
184
audit_run_command(const char *command)
81
{
185
{
82
	/* not implemented */
186
	if (!user_login_count++)
187
		linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
188
		    NULL, "ssh", 1, AUDIT_USER_LOGIN);
189
	linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
190
	    NULL, "ssh", 1, AUDIT_USER_START);
191
	return 0;
192
}
193
194
void
195
audit_end_command(int handle, const char *command)
196
{
197
	linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
198
	    NULL, "ssh", 1, AUDIT_USER_END);
199
	if (user_login_count && !--user_login_count)
200
		linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
201
		    NULL, "ssh", 1, AUDIT_USER_LOGOUT);
202
}
203
204
void
205
audit_count_session_open(void)
206
{
207
	user_login_count++;
83
}
208
}
84
209
85
void
210
void
86
audit_session_open(struct logininfo *li)
211
audit_session_open(struct logininfo *li)
87
{
212
{
88
	if (linux_audit_record_event(li->uid, NULL, li->hostname,
213
	if (!user_login_count++)
89
	    NULL, li->line, 1) == 0)
214
		linux_audit_user_logxxx(li->uid, NULL, li->hostname,
90
		fatal("linux_audit_write_entry failed: %s", strerror(errno));
215
		    NULL, li->line, 1, AUDIT_USER_LOGIN);
216
	linux_audit_user_logxxx(li->uid, NULL, li->hostname,
217
	    NULL, li->line, 1, AUDIT_USER_START);
91
}
218
}
92
219
93
void
220
void
94
audit_session_close(struct logininfo *li)
221
audit_session_close(struct logininfo *li)
95
{
222
{
96
	/* not implemented */
223
	linux_audit_user_logxxx(li->uid, NULL, li->hostname,
224
	    NULL, li->line, 1, AUDIT_USER_END);
225
	if (user_login_count && !--user_login_count)
226
		linux_audit_user_logxxx(li->uid, NULL, li->hostname,
227
		    NULL, li->line, 1, AUDIT_USER_LOGOUT);
97
}
228
}
98
229
99
void
230
void
Lines 101-121 audit_event(ssh_audit_event_t event) Link Here
101
{
232
{
102
	switch(event) {
233
	switch(event) {
103
	case SSH_AUTH_SUCCESS:
234
	case SSH_AUTH_SUCCESS:
104
	case SSH_CONNECTION_CLOSE:
235
		linux_audit_user_auth(-1, audit_username(), NULL,
236
			get_remote_ipaddr(), "ssh", 1, event);
237
		break;
238
105
	case SSH_NOLOGIN:
239
	case SSH_NOLOGIN:
106
	case SSH_LOGIN_EXCEED_MAXTRIES:
107
	case SSH_LOGIN_ROOT_DENIED:
240
	case SSH_LOGIN_ROOT_DENIED:
241
		linux_audit_user_auth(-1, audit_username(), NULL,
242
			get_remote_ipaddr(), "ssh", 0, event);
243
		linux_audit_user_logxxx(-1, audit_username(), NULL,
244
			get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
108
		break;
245
		break;
109
246
247
	case SSH_LOGIN_EXCEED_MAXTRIES:
110
	case SSH_AUTH_FAIL_NONE:
248
	case SSH_AUTH_FAIL_NONE:
111
	case SSH_AUTH_FAIL_PASSWD:
249
	case SSH_AUTH_FAIL_PASSWD:
112
	case SSH_AUTH_FAIL_KBDINT:
250
	case SSH_AUTH_FAIL_KBDINT:
113
	case SSH_AUTH_FAIL_PUBKEY:
251
	case SSH_AUTH_FAIL_PUBKEY:
114
	case SSH_AUTH_FAIL_HOSTBASED:
252
	case SSH_AUTH_FAIL_HOSTBASED:
115
	case SSH_AUTH_FAIL_GSSAPI:
253
	case SSH_AUTH_FAIL_GSSAPI:
254
		linux_audit_user_auth(-1, audit_username(), NULL,
255
			get_remote_ipaddr(), "ssh", 0, event);
256
		break;
257
258
	case SSH_CONNECTION_CLOSE:
259
		if (user_login_count) {
260
			while (user_login_count--)
261
				linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
262
				    NULL, "ssh", 1, AUDIT_USER_END);
263
			linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
264
			    NULL, "ssh", 1, AUDIT_USER_LOGOUT);
265
		}
266
		break;
267
268
	case SSH_CONNECTION_ABANDON:
116
	case SSH_INVALID_USER:
269
	case SSH_INVALID_USER:
117
		linux_audit_record_event(-1, audit_username(), NULL,
270
		linux_audit_user_logxxx(-1, audit_username(), NULL,
118
			get_remote_ipaddr(), "sshd", 0);
271
			get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
119
		break;
272
		break;
120
273
121
	default:
274
	default:
Lines 123-126 audit_event(ssh_audit_event_t event) Link Here
123
	}
276
	}
124
}
277
}
125
278
279
void
280
audit_unsupported_body(int what)
281
{
282
#ifdef AUDIT_CRYPTO_SESSION
283
	char buf[AUDIT_LOG_SIZE];
284
	const static char *name[] = { "cipher", "mac", "comp" };
285
	char *s;
286
	int audit_fd;
287
288
	snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ",
289
		name[what], get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())),
290
		get_local_port());
291
	free(s);
292
	audit_fd = audit_open();
293
	if (audit_fd < 0)
294
		/* no problem, the next instruction will be fatal() */
295
		return;
296
	audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
297
			buf, NULL, get_remote_ipaddr(), NULL, 0);
298
	audit_close(audit_fd);
299
#endif
300
}
301
302
const static char *direction[] = { "from-server", "from-client", "both" };
303
304
void
305
audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid,
306
	       uid_t uid)
307
{
308
#ifdef AUDIT_CRYPTO_SESSION
309
	char buf[AUDIT_LOG_SIZE];
310
	int audit_fd, audit_ok;
311
	const struct sshcipher *cipher = cipher_by_name(enc);
312
	char *s;
313
314
	snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s pfs=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
315
		direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs,
316
		(intmax_t)pid, (intmax_t)uid,
317
		get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port());
318
	free(s);
319
	audit_fd = audit_open();
320
	if (audit_fd < 0) {
321
		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
322
					 errno == EAFNOSUPPORT)
323
			return; /* No audit support in kernel */
324
		else
325
			fatal("cannot open audit"); /* Must prevent login */
326
	}
327
	audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
328
			buf, NULL, get_remote_ipaddr(), NULL, 1);
329
	audit_close(audit_fd);
330
	/* do not abort if the error is EPERM and sshd is run as non root user */
331
	if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
332
		fatal("cannot write into audit"); /* Must prevent login */
333
#endif
334
}
335
336
void
337
audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
338
{
339
	char buf[AUDIT_LOG_SIZE];
340
	int audit_fd, audit_ok;
341
	char *s;
342
343
	snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
344
		 direction[ctos], (intmax_t)pid, (intmax_t)uid,
345
		 get_remote_port(),
346
		 (s = get_local_ipaddr(packet_get_connection_in())),
347
		 get_local_port());
348
	free(s);
349
	audit_fd = audit_open();
350
	if (audit_fd < 0) {
351
		if (errno != EINVAL && errno != EPROTONOSUPPORT &&
352
					 errno != EAFNOSUPPORT)
353
			error("cannot open audit");
354
		return;
355
	}
356
	audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
357
			buf, NULL, get_remote_ipaddr(), NULL, 1);
358
	audit_close(audit_fd);
359
	/* do not abort if the error is EPERM and sshd is run as non root user */
360
	if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
361
		error("cannot write into audit");
362
}
363
364
void
365
audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
366
{
367
	char buf[AUDIT_LOG_SIZE];
368
	int audit_fd, audit_ok;
369
370
	snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ",
371
		fp, (intmax_t)pid, (intmax_t)uid);
372
	audit_fd = audit_open();
373
	if (audit_fd < 0) {
374
		if (errno != EINVAL && errno != EPROTONOSUPPORT &&
375
					 errno != EAFNOSUPPORT)
376
			error("cannot open audit");
377
		return;
378
	}
379
	audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
380
			buf, NULL,
381
			listening_for_clients() ? NULL : get_remote_ipaddr(),
382
			NULL, 1);
383
	audit_close(audit_fd);
384
	/* do not abort if the error is EPERM and sshd is run as non root user */
385
	if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
386
		error("cannot write into audit");
387
}
388
389
void
390
audit_generate_ephemeral_server_key(const char *fp)
391
{
392
	char buf[AUDIT_LOG_SIZE];
393
	int audit_fd, audit_ok;
394
395
	snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp);
396
	audit_fd = audit_open();
397
	if (audit_fd < 0) {
398
		if (errno != EINVAL && errno != EPROTONOSUPPORT &&
399
					 errno != EAFNOSUPPORT)
400
			error("cannot open audit");
401
		return;
402
	}
403
	audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER,
404
			buf, NULL, 0, NULL, 1);
405
	audit_close(audit_fd);
406
	/* do not abort if the error is EPERM and sshd is run as non root user */
407
	if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0)))
408
		error("cannot write into audit");
409
}
126
#endif /* USE_LINUX_AUDIT */
410
#endif /* USE_LINUX_AUDIT */
(-)a/audit.c (-7 / +134 lines)
Lines 28-33 Link Here
28
28
29
#include <stdarg.h>
29
#include <stdarg.h>
30
#include <string.h>
30
#include <string.h>
31
#include <unistd.h>
31
32
32
#ifdef SSH_AUDIT_EVENTS
33
#ifdef SSH_AUDIT_EVENTS
33
34
Lines 36-41 Link Here
36
#include "key.h"
37
#include "key.h"
37
#include "hostfile.h"
38
#include "hostfile.h"
38
#include "auth.h"
39
#include "auth.h"
40
#include "ssh-gss.h"
41
#include "monitor_wrap.h"
42
#include "xmalloc.h"
43
#include "misc.h"
44
#include "servconf.h"
39
45
40
/*
46
/*
41
 * Care must be taken when using this since it WILL NOT be initialized when
47
 * Care must be taken when using this since it WILL NOT be initialized when
Lines 43-48 Link Here
43
 * audit_event(CONNECTION_ABANDON) is called.  Test for NULL before using.
49
 * audit_event(CONNECTION_ABANDON) is called.  Test for NULL before using.
44
 */
50
 */
45
extern Authctxt *the_authctxt;
51
extern Authctxt *the_authctxt;
52
extern ServerOptions options;
46
53
47
/* Maybe add the audit class to struct Authmethod? */
54
/* Maybe add the audit class to struct Authmethod? */
48
ssh_audit_event_t
55
ssh_audit_event_t
Lines 71-83 audit_classify_auth(const char *method) Link Here
71
const char *
78
const char *
72
audit_username(void)
79
audit_username(void)
73
{
80
{
74
	static const char unknownuser[] = "(unknown user)";
81
	static const char unknownuser[] = "(unknown)";
75
	static const char invaliduser[] = "(invalid user)";
76
82
77
	if (the_authctxt == NULL || the_authctxt->user == NULL)
83
	if (the_authctxt == NULL || the_authctxt->user == NULL || !the_authctxt->valid)
78
		return (unknownuser);
84
		return (unknownuser);
79
	if (!the_authctxt->valid)
80
		return (invaliduser);
81
	return (the_authctxt->user);
85
	return (the_authctxt->user);
82
}
86
}
83
87
Lines 111-116 audit_event_lookup(ssh_audit_event_t ev) Link Here
111
	return(event_lookup[i].name);
115
	return(event_lookup[i].name);
112
}
116
}
113
117
118
void
119
audit_key(int host_user, int *rv, const Key *key)
120
{
121
	char *fp;
122
	const char *crypto_name;
123
124
	fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
125
	if (key->type == KEY_RSA1)
126
		crypto_name = "ssh-rsa1";
127
	else
128
		crypto_name = key_ssh_name(key);
129
	if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
130
		*rv = 0;
131
	free(fp);
132
}
133
134
void
135
audit_unsupported(int what)
136
{
137
	PRIVSEP(audit_unsupported_body(what));
138
}
139
140
void
141
audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs)
142
{
143
	PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid()));
144
}
145
146
void
147
audit_session_key_free(int ctos)
148
{
149
	PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid()));
150
}
151
114
# ifndef CUSTOM_SSH_AUDIT_EVENTS
152
# ifndef CUSTOM_SSH_AUDIT_EVENTS
115
/*
153
/*
116
 * Null implementations of audit functions.
154
 * Null implementations of audit functions.
Lines 140-145 audit_event(ssh_audit_event_t event) Link Here
140
}
178
}
141
179
142
/*
180
/*
181
 * Called when a child process has called, or will soon call,
182
 * audit_session_open.
183
 */
184
void
185
audit_count_session_open(void)
186
{
187
	debug("audit count session open euid %d user %s", geteuid(),
188
	      audit_username());
189
}
190
191
/*
143
 * Called when a user session is started.  Argument is the tty allocated to
192
 * Called when a user session is started.  Argument is the tty allocated to
144
 * the session, or NULL if no tty was allocated.
193
 * the session, or NULL if no tty was allocated.
145
 *
194
 *
Lines 174-186 audit_session_close(struct logininfo *li) Link Here
174
/*
223
/*
175
 * This will be called when a user runs a non-interactive command.  Note that
224
 * This will be called when a user runs a non-interactive command.  Note that
176
 * it may be called multiple times for a single connection since SSH2 allows
225
 * it may be called multiple times for a single connection since SSH2 allows
177
 * multiple sessions within a single connection.
226
 * multiple sessions within a single connection.  Returns a "handle" for
227
 * audit_end_command.
178
 */
228
 */
179
void
229
int
180
audit_run_command(const char *command)
230
audit_run_command(const char *command)
181
{
231
{
182
	debug("audit run command euid %d user %s command '%.200s'", geteuid(),
232
	debug("audit run command euid %d user %s command '%.200s'", geteuid(),
183
	    audit_username(), command);
233
	    audit_username(), command);
234
	return 0;
235
}
236
237
/*
238
 * This will be called when the non-interactive command finishes.  Note that
239
 * it may be called multiple times for a single connection since SSH2 allows
240
 * multiple sessions within a single connection.  "handle" should come from
241
 * the corresponding audit_run_command.
242
 */
243
void
244
audit_end_command(int handle, const char *command)
245
{
246
	debug("audit end nopty exec  euid %d user %s command '%.200s'", geteuid(),
247
	    audit_username(), command);
248
}
249
250
/*
251
 * This will be called when user is successfully autherized by the RSA1/RSA/DSA key.
252
 *
253
 * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key.
254
 */
255
int
256
audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
257
{
258
	debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d",
259
		host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
260
		sshkey_fingerprint_prefix(), fp, rv);
261
}
262
263
/*
264
 * This will be called when the protocol negotiation fails.
265
 */
266
void
267
audit_unsupported_body(int what)
268
{
269
	debug("audit unsupported protocol euid %d type %d", geteuid(), what);
270
}
271
272
/*
273
 * This will be called on succesfull protocol negotiation.
274
 */
275
void
276
audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid,
277
	       uid_t uid)
278
{
279
	debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u",
280
		(unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid,
281
	        (unsigned)uid);
282
}
283
284
/*
285
 * This will be called on succesfull session key discard
286
 */
287
void
288
audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
289
{
290
	debug("audit session key discard euid %u direction %d from pid %ld uid %u",
291
		(unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
292
}
293
294
/*
295
 * This will be called on destroy private part of the server key
296
 */
297
void
298
audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
299
{
300
	debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
301
		geteuid(), fp, (long)pid, (unsigned)uid);
302
}
303
304
/*
305
 * This will be called on generation of the ephemeral server key
306
 */
307
void
308
audit_generate_ephemeral_server_key(const char *)
309
{
310
	debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
184
}
311
}
185
# endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
312
# endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
186
#endif /* SSH_AUDIT_EVENTS */
313
#endif /* SSH_AUDIT_EVENTS */
(-)a/audit.h (-1 / +22 lines)
Lines 28-33 Link Here
28
# define _SSH_AUDIT_H
28
# define _SSH_AUDIT_H
29
29
30
#include "loginrec.h"
30
#include "loginrec.h"
31
#include "key.h"
31
32
32
enum ssh_audit_event_type {
33
enum ssh_audit_event_type {
33
	SSH_LOGIN_EXCEED_MAXTRIES,
34
	SSH_LOGIN_EXCEED_MAXTRIES,
Lines 45-57 enum ssh_audit_event_type { Link Here
45
	SSH_CONNECTION_ABANDON,	/* closed without completing auth */
46
	SSH_CONNECTION_ABANDON,	/* closed without completing auth */
46
	SSH_AUDIT_UNKNOWN
47
	SSH_AUDIT_UNKNOWN
47
};
48
};
49
50
enum ssh_audit_kex {
51
	SSH_AUDIT_UNSUPPORTED_CIPHER,
52
	SSH_AUDIT_UNSUPPORTED_MAC,
53
	SSH_AUDIT_UNSUPPORTED_COMPRESSION
54
};
48
typedef enum ssh_audit_event_type ssh_audit_event_t;
55
typedef enum ssh_audit_event_type ssh_audit_event_t;
49
56
57
int	listening_for_clients(void);
58
50
void	audit_connection_from(const char *, int);
59
void	audit_connection_from(const char *, int);
51
void	audit_event(ssh_audit_event_t);
60
void	audit_event(ssh_audit_event_t);
61
void	audit_count_session_open(void);
52
void	audit_session_open(struct logininfo *);
62
void	audit_session_open(struct logininfo *);
53
void	audit_session_close(struct logininfo *);
63
void	audit_session_close(struct logininfo *);
54
void	audit_run_command(const char *);
64
int	audit_run_command(const char *);
65
void 	audit_end_command(int, const char *);
55
ssh_audit_event_t audit_classify_auth(const char *);
66
ssh_audit_event_t audit_classify_auth(const char *);
67
int	audit_keyusage(int, const char *, unsigned, char *, int);
68
void	audit_key(int, int *, const Key *);
69
void	audit_unsupported(int);
70
void	audit_kex(int, char *, char *, char *, char *);
71
void	audit_unsupported_body(int);
72
void	audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
73
void	audit_session_key_free(int ctos);
74
void	audit_session_key_free_body(int ctos, pid_t, uid_t);
75
void	audit_destroy_sensitive_data(const char *, pid_t, uid_t);
76
void	audit_generate_ephemeral_server_key(const char *);
56
77
57
#endif /* _SSH_AUDIT_H */
78
#endif /* _SSH_AUDIT_H */
(-)a/auditstub.c (+50 lines)
Line 0 Link Here
1
/* $Id: auditstub.c,v 1.1 jfch Exp $ */
2
3
/*
4
 * Copyright 2010 Red Hat, Inc.  All rights reserved.
5
 * Use is subject to license terms.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 *
27
 * Red Hat author: Jan F. Chadima <jchadima@redhat.com>
28
 */
29
30
#include <sys/types.h>
31
32
void
33
audit_unsupported(int n)
34
{
35
}
36
37
void
38
audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs)
39
{
40
}
41
42
void
43
audit_session_key_free(int ctos)
44
{
45
}
46
47
void
48
audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
49
{
50
}
(-)a/auth-rsa.c (-6 / +15 lines)
Lines 95-101 auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) Link Here
95
{
95
{
96
	u_char buf[32], mdbuf[16];
96
	u_char buf[32], mdbuf[16];
97
	struct ssh_digest_ctx *md;
97
	struct ssh_digest_ctx *md;
98
	int len;
98
	int len, rv;
99
#ifdef SSH_AUDIT_EVENTS
100
	char *fp;
101
#endif
99
102
100
	/* don't allow short keys */
103
	/* don't allow short keys */
101
	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
104
	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
Lines 119-130 auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) Link Here
119
	ssh_digest_free(md);
122
	ssh_digest_free(md);
120
123
121
	/* Verify that the response is the original challenge. */
124
	/* Verify that the response is the original challenge. */
122
	if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
125
	rv = timingsafe_bcmp(response, mdbuf, 16) == 0;
123
		/* Wrong answer. */
126
124
		return (0);
127
#ifdef SSH_AUDIT_EVENTS
128
	fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
129
	if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) {
130
		debug("unsuccessful audit");
131
		rv = 0;
125
	}
132
	}
126
	/* Correct answer. */
133
	free(fp);
127
	return (1);
134
#endif
135
136
	return rv;
128
}
137
}
129
138
130
/*
139
/*
(-)a/auth.c (-3 lines)
Lines 645-653 getpwnamallow(const char *user) Link Here
645
		record_failed_login(user,
645
		record_failed_login(user,
646
		    get_canonical_hostname(options.use_dns), "ssh");
646
		    get_canonical_hostname(options.use_dns), "ssh");
647
#endif
647
#endif
648
#ifdef SSH_AUDIT_EVENTS
649
		audit_event(SSH_INVALID_USER);
650
#endif /* SSH_AUDIT_EVENTS */
651
		return (NULL);
648
		return (NULL);
652
	}
649
	}
653
	if (!allowed_user(pw))
650
	if (!allowed_user(pw))
(-)a/auth.h (+2 lines)
Lines 192-197 void abandon_challenge_response(Authctxt *); Link Here
192
192
193
char	*expand_authorized_keys(const char *, struct passwd *pw);
193
char	*expand_authorized_keys(const char *, struct passwd *pw);
194
char	*authorized_principals_file(struct passwd *);
194
char	*authorized_principals_file(struct passwd *);
195
int	 user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
195
196
196
FILE	*auth_openkeyfile(const char *, struct passwd *, int);
197
FILE	*auth_openkeyfile(const char *, struct passwd *, int);
197
FILE	*auth_openprincipals(const char *, struct passwd *, int);
198
FILE	*auth_openprincipals(const char *, struct passwd *, int);
Lines 210-215 int get_hostkey_index(Key *, int, struct ssh *); Link Here
210
int	 ssh1_session_key(BIGNUM *);
211
int	 ssh1_session_key(BIGNUM *);
211
int	 sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
212
int	 sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
212
	     const u_char *, size_t, const char *, u_int);
213
	     const u_char *, size_t, const char *, u_int);
214
int	 hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
213
215
214
/* debug messages during authentication */
216
/* debug messages during authentication */
215
void	 auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
217
void	 auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
(-)a/auth2-hostbased.c (-1 / +13 lines)
Lines 138-144 userauth_hostbased(Authctxt *authctxt) Link Here
138
	/* test for allowed key and correct signature */
138
	/* test for allowed key and correct signature */
139
	authenticated = 0;
139
	authenticated = 0;
140
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
140
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
141
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
141
	    PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b),
142
			buffer_len(&b))) == 1)
142
			buffer_len(&b))) == 1)
143
		authenticated = 1;
143
		authenticated = 1;
144
144
Lines 155-160 done: Link Here
155
	return authenticated;
155
	return authenticated;
156
}
156
}
157
157
158
int
159
hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
160
{
161
	int rv;
162
163
	rv = key_verify(key, sig, slen, data, datalen);
164
#ifdef SSH_AUDIT_EVENTS
165
	audit_key(0, &rv, key);
166
#endif
167
	return rv;
168
}
169
158
/* return 1 if given hostkey is allowed */
170
/* return 1 if given hostkey is allowed */
159
int
171
int
160
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
172
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
(-)a/auth2-pubkey.c (-1 / +13 lines)
Lines 176-182 userauth_pubkey(Authctxt *authctxt) Link Here
176
		/* test for correct signature */
176
		/* test for correct signature */
177
		authenticated = 0;
177
		authenticated = 0;
178
		if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
178
		if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
179
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
179
		    PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b),
180
		    buffer_len(&b))) == 1) {
180
		    buffer_len(&b))) == 1) {
181
			authenticated = 1;
181
			authenticated = 1;
182
			/* Record the successful key to prevent reuse */
182
			/* Record the successful key to prevent reuse */
Lines 256-261 pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) Link Here
256
	free(extra);
256
	free(extra);
257
}
257
}
258
258
259
int
260
user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
261
{
262
	int rv;
263
264
	rv = key_verify(key, sig, slen, data, datalen);
265
#ifdef SSH_AUDIT_EVENTS
266
	audit_key(1, &rv, key);
267
#endif
268
	return rv;
269
}
270
259
/*
271
/*
260
 * Splits 's' into an argument vector. Handles quoted string and basic
272
 * Splits 's' into an argument vector. Handles quoted string and basic
261
 * escape characters (\\, \", \'). Caller must free the argument vector
273
 * escape characters (\\, \", \'). Caller must free the argument vector
(-)a/auth2.c (-3 lines)
Lines 239-247 input_userauth_request(int type, u_int32_t seq, void *ctxt) Link Here
239
		} else {
239
		} else {
240
			logit("input_userauth_request: invalid user %s", user);
240
			logit("input_userauth_request: invalid user %s", user);
241
			authctxt->pw = fakepw();
241
			authctxt->pw = fakepw();
242
#ifdef SSH_AUDIT_EVENTS
243
			PRIVSEP(audit_event(SSH_INVALID_USER));
244
#endif
245
		}
242
		}
246
#ifdef USE_PAM
243
#ifdef USE_PAM
247
		if (options.use_pam)
244
		if (options.use_pam)
(-)a/cipher.c (-20 lines)
Lines 57-82 extern const EVP_CIPHER *evp_ssh1_3des(void); Link Here
57
extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
57
extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
58
#endif
58
#endif
59
59
60
struct sshcipher {
61
	char	*name;
62
	int	number;		/* for ssh1 only */
63
	u_int	block_size;
64
	u_int	key_len;
65
	u_int	iv_len;		/* defaults to block_size */
66
	u_int	auth_len;
67
	u_int	discard_len;
68
	u_int	flags;
69
#define CFLAG_CBC		(1<<0)
70
#define CFLAG_CHACHAPOLY	(1<<1)
71
#define CFLAG_AESCTR		(1<<2)
72
#define CFLAG_NONE		(1<<3)
73
#ifdef WITH_OPENSSL
74
	const EVP_CIPHER	*(*evptype)(void);
75
#else
76
	void	*ignored;
77
#endif
78
};
79
80
static const struct sshcipher ciphers[] = {
60
static const struct sshcipher ciphers[] = {
81
#ifdef WITH_SSH1
61
#ifdef WITH_SSH1
82
	{ "des",	SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
62
	{ "des",	SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
(-)a/cipher.h (-1 / +20 lines)
Lines 62-68 Link Here
62
#define CIPHER_ENCRYPT		1
62
#define CIPHER_ENCRYPT		1
63
#define CIPHER_DECRYPT		0
63
#define CIPHER_DECRYPT		0
64
64
65
struct sshcipher;
65
struct sshcipher {
66
	char	*name;
67
	int	number;		/* for ssh1 only */
68
	u_int	block_size;
69
	u_int	key_len;
70
	u_int	iv_len;		/* defaults to block_size */
71
	u_int	auth_len;
72
	u_int	discard_len;
73
	u_int	flags;
74
#define CFLAG_CBC		(1<<0)
75
#define CFLAG_CHACHAPOLY	(1<<1)
76
#define CFLAG_AESCTR		(1<<2)
77
#define CFLAG_NONE		(1<<3)
78
#ifdef WITH_OPENSSL
79
	const EVP_CIPHER	*(*evptype)(void);
80
#else
81
	void	*ignored;
82
#endif
83
};
84
66
struct sshcipher_ctx {
85
struct sshcipher_ctx {
67
	int	plaintext;
86
	int	plaintext;
68
	int	encrypt;
87
	int	encrypt;
(-)a/kex.c (-3 / +50 lines)
Lines 53-58 Link Here
53
#include "ssherr.h"
53
#include "ssherr.h"
54
#include "sshbuf.h"
54
#include "sshbuf.h"
55
#include "digest.h"
55
#include "digest.h"
56
#include "audit.h"
56
57
57
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
58
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
58
# if defined(HAVE_EVP_SHA256)
59
# if defined(HAVE_EVP_SHA256)
Lines 630-637 choose_enc(struct sshenc *enc, char *client, char *server) Link Here
630
{
631
{
631
	char *name = match_list(client, server, NULL);
632
	char *name = match_list(client, server, NULL);
632
633
633
	if (name == NULL)
634
	if (name == NULL) {
635
#ifdef SSH_AUDIT_EVENTS
636
		audit_unsupported(SSH_AUDIT_UNSUPPORTED_CIPHER);
637
#endif
634
		return SSH_ERR_NO_CIPHER_ALG_MATCH;
638
		return SSH_ERR_NO_CIPHER_ALG_MATCH;
639
	}
635
	if ((enc->cipher = cipher_by_name(name)) == NULL)
640
	if ((enc->cipher = cipher_by_name(name)) == NULL)
636
		return SSH_ERR_INTERNAL_ERROR;
641
		return SSH_ERR_INTERNAL_ERROR;
637
	enc->name = name;
642
	enc->name = name;
Lines 649-656 choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) Link Here
649
{
654
{
650
	char *name = match_list(client, server, NULL);
655
	char *name = match_list(client, server, NULL);
651
656
652
	if (name == NULL)
657
	if (name == NULL) {
658
#ifdef SSH_AUDIT_EVENTS
659
		audit_unsupported(SSH_AUDIT_UNSUPPORTED_MAC);
660
#endif
653
		return SSH_ERR_NO_MAC_ALG_MATCH;
661
		return SSH_ERR_NO_MAC_ALG_MATCH;
662
	}
654
	if (mac_setup(mac, name) < 0)
663
	if (mac_setup(mac, name) < 0)
655
		return SSH_ERR_INTERNAL_ERROR;
664
		return SSH_ERR_INTERNAL_ERROR;
656
	/* truncate the key */
665
	/* truncate the key */
Lines 667-674 choose_comp(struct sshcomp *comp, char *client, char *server) Link Here
667
{
676
{
668
	char *name = match_list(client, server, NULL);
677
	char *name = match_list(client, server, NULL);
669
678
670
	if (name == NULL)
679
	if (name == NULL) {
680
#ifdef SSH_AUDIT_EVENTS
681
		audit_unsupported(SSH_AUDIT_UNSUPPORTED_COMPRESSION);
682
#endif
671
		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
683
		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
684
	}
672
	if (strcmp(name, "zlib@openssh.com") == 0) {
685
	if (strcmp(name, "zlib@openssh.com") == 0) {
673
		comp->type = COMP_DELAYED;
686
		comp->type = COMP_DELAYED;
674
	} else if (strcmp(name, "zlib") == 0) {
687
	} else if (strcmp(name, "zlib") == 0) {
Lines 839-844 kex_choose_conf(struct ssh *ssh) Link Here
839
		dh_need = MAX(dh_need, newkeys->enc.block_size);
852
		dh_need = MAX(dh_need, newkeys->enc.block_size);
840
		dh_need = MAX(dh_need, newkeys->enc.iv_len);
853
		dh_need = MAX(dh_need, newkeys->enc.iv_len);
841
		dh_need = MAX(dh_need, newkeys->mac.key_len);
854
		dh_need = MAX(dh_need, newkeys->mac.key_len);
855
		debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need);
856
#ifdef SSH_AUDIT_EVENTS
857
		audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name);
858
#endif
842
	}
859
	}
843
	/* XXX need runden? */
860
	/* XXX need runden? */
844
	kex->we_need = need;
861
	kex->we_need = need;
Lines 1013-1015 dump_digest(char *msg, u_char *digest, int len) Link Here
1013
	sshbuf_dump_data(digest, len, stderr);
1030
	sshbuf_dump_data(digest, len, stderr);
1014
}
1031
}
1015
#endif
1032
#endif
1033
1034
static void
1035
enc_destroy(struct sshenc *enc)
1036
{
1037
	if (enc == NULL)
1038
		return;
1039
1040
	if (enc->key) {
1041
		memset(enc->key, 0, enc->key_len);
1042
		free(enc->key);
1043
	}
1044
1045
	if (enc->iv) {
1046
		memset(enc->iv,  0, enc->iv_len);
1047
		free(enc->iv);
1048
	}
1049
1050
	memset(enc, 0, sizeof(*enc));
1051
}
1052
1053
void
1054
newkeys_destroy(struct newkeys *newkeys)
1055
{
1056
	if (newkeys == NULL)
1057
		return;
1058
1059
	enc_destroy(&newkeys->enc);
1060
	mac_destroy(&newkeys->mac);
1061
	memset(&newkeys->comp, 0, sizeof(newkeys->comp));
1062
}
(-)a/kex.h (+2 lines)
Lines 190-195 int kexecdh_server(struct ssh *); Link Here
190
int	 kexc25519_client(struct ssh *);
190
int	 kexc25519_client(struct ssh *);
191
int	 kexc25519_server(struct ssh *);
191
int	 kexc25519_server(struct ssh *);
192
192
193
void	newkeys_destroy(struct newkeys *newkeys);
194
193
int	 kex_dh_hash(const char *, const char *,
195
int	 kex_dh_hash(const char *, const char *,
194
    const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
196
    const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
195
    const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);
197
    const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);
(-)a/key.h (+1 lines)
Lines 50-55 typedef struct sshkey Key; Link Here
50
#define key_ecdsa_bits_to_nid	sshkey_ecdsa_bits_to_nid
50
#define key_ecdsa_bits_to_nid	sshkey_ecdsa_bits_to_nid
51
#define key_ecdsa_key_to_nid	sshkey_ecdsa_key_to_nid
51
#define key_ecdsa_key_to_nid	sshkey_ecdsa_key_to_nid
52
#define key_is_cert		sshkey_is_cert
52
#define key_is_cert		sshkey_is_cert
53
#define key_is_private		sshkey_is_private
53
#define key_type_plain		sshkey_type_plain
54
#define key_type_plain		sshkey_type_plain
54
#define key_curve_name_to_nid	sshkey_curve_name_to_nid
55
#define key_curve_name_to_nid	sshkey_curve_name_to_nid
55
#define key_curve_nid_to_bits	sshkey_curve_nid_to_bits
56
#define key_curve_nid_to_bits	sshkey_curve_nid_to_bits
(-)a/mac.c (+14 lines)
Lines 226-231 mac_clear(struct sshmac *mac) Link Here
226
	mac->umac_ctx = NULL;
226
	mac->umac_ctx = NULL;
227
}
227
}
228
228
229
void
230
mac_destroy(struct sshmac *mac)
231
{
232
	if (mac == NULL)
233
		return;
234
235
	if (mac->key) {
236
		memset(mac->key, 0, mac->key_len);
237
		free(mac->key);
238
	}
239
240
	memset(mac, 0, sizeof(*mac));
241
}
242
229
/* XXX copied from ciphers_valid */
243
/* XXX copied from ciphers_valid */
230
#define	MAC_SEP	","
244
#define	MAC_SEP	","
231
int
245
int
(-)a/mac.h (+1 lines)
Lines 47-51 int mac_init(struct sshmac *); Link Here
47
int	 mac_compute(struct sshmac *, u_int32_t, const u_char *, int,
47
int	 mac_compute(struct sshmac *, u_int32_t, const u_char *, int,
48
    u_char *, size_t);
48
    u_char *, size_t);
49
void	 mac_clear(struct sshmac *);
49
void	 mac_clear(struct sshmac *);
50
void	 mac_destroy(struct sshmac *);
50
51
51
#endif /* SSHMAC_H */
52
#endif /* SSHMAC_H */
(-)a/monitor.c (-2 / +181 lines)
Lines 101-106 Link Here
101
#include "compat.h"
101
#include "compat.h"
102
#include "ssh2.h"
102
#include "ssh2.h"
103
#include "authfd.h"
103
#include "authfd.h"
104
#include "audit.h"
104
#include "match.h"
105
#include "match.h"
105
#include "ssherr.h"
106
#include "ssherr.h"
106
107
Lines 116-121 extern Buffer auth_debug; Link Here
116
extern int auth_debug_init;
117
extern int auth_debug_init;
117
extern Buffer loginmsg;
118
extern Buffer loginmsg;
118
119
120
extern void destroy_sensitive_data(int);
121
119
/* State exported from the child */
122
/* State exported from the child */
120
static struct sshbuf *child_state;
123
static struct sshbuf *child_state;
121
124
Lines 161-166 int mm_answer_gss_checkmic(int, Buffer *); Link Here
161
#ifdef SSH_AUDIT_EVENTS
164
#ifdef SSH_AUDIT_EVENTS
162
int mm_answer_audit_event(int, Buffer *);
165
int mm_answer_audit_event(int, Buffer *);
163
int mm_answer_audit_command(int, Buffer *);
166
int mm_answer_audit_command(int, Buffer *);
167
int mm_answer_audit_end_command(int, Buffer *);
168
int mm_answer_audit_unsupported_body(int, Buffer *);
169
int mm_answer_audit_kex_body(int, Buffer *);
170
int mm_answer_audit_session_key_free_body(int, Buffer *);
171
int mm_answer_audit_server_key_free(int, Buffer *);
164
#endif
172
#endif
165
173
166
static int monitor_read_log(struct monitor *);
174
static int monitor_read_log(struct monitor *);
Lines 217-222 struct mon_table mon_dispatch_proto20[] = { Link Here
217
#endif
225
#endif
218
#ifdef SSH_AUDIT_EVENTS
226
#ifdef SSH_AUDIT_EVENTS
219
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
227
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
228
    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
229
    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
230
    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
231
    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
220
#endif
232
#endif
221
#ifdef BSD_AUTH
233
#ifdef BSD_AUTH
222
    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
234
    {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
Lines 248-253 struct mon_table mon_dispatch_postauth20[] = { Link Here
248
#ifdef SSH_AUDIT_EVENTS
260
#ifdef SSH_AUDIT_EVENTS
249
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
261
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
250
    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
262
    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
263
    {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
264
    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
265
    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
266
    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
267
    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
251
#endif
268
#endif
252
    {0, 0, NULL}
269
    {0, 0, NULL}
253
};
270
};
Lines 280-285 struct mon_table mon_dispatch_proto15[] = { Link Here
280
#endif
297
#endif
281
#ifdef SSH_AUDIT_EVENTS
298
#ifdef SSH_AUDIT_EVENTS
282
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
299
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
300
    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
301
    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
302
    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
303
    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
283
#endif
304
#endif
284
#endif /* WITH_SSH1 */
305
#endif /* WITH_SSH1 */
285
    {0, 0, NULL}
306
    {0, 0, NULL}
Lines 293-298 struct mon_table mon_dispatch_postauth15[] = { Link Here
293
#ifdef SSH_AUDIT_EVENTS
314
#ifdef SSH_AUDIT_EVENTS
294
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
315
    {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
295
    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
316
    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
317
    {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
318
    {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body},
319
    {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body},
320
    {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body},
321
    {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
296
#endif
322
#endif
297
#endif /* WITH_SSH1 */
323
#endif /* WITH_SSH1 */
298
    {0, 0, NULL}
324
    {0, 0, NULL}
Lines 1411-1419 mm_answer_keyverify(int sock, Buffer *m) Link Here
1411
	Key *key;
1437
	Key *key;
1412
	u_char *signature, *data, *blob;
1438
	u_char *signature, *data, *blob;
1413
	u_int signaturelen, datalen, bloblen;
1439
	u_int signaturelen, datalen, bloblen;
1440
	int type = 0;
1414
	int verified = 0;
1441
	int verified = 0;
1415
	int valid_data = 0;
1442
	int valid_data = 0;
1416
1443
1444
	type = buffer_get_int(m);
1417
	blob = buffer_get_string(m, &bloblen);
1445
	blob = buffer_get_string(m, &bloblen);
1418
	signature = buffer_get_string(m, &signaturelen);
1446
	signature = buffer_get_string(m, &signaturelen);
1419
	data = buffer_get_string(m, &datalen);
1447
	data = buffer_get_string(m, &datalen);
Lines 1421-1426 mm_answer_keyverify(int sock, Buffer *m) Link Here
1421
	if (hostbased_cuser == NULL || hostbased_chost == NULL ||
1449
	if (hostbased_cuser == NULL || hostbased_chost == NULL ||
1422
	  !monitor_allowed_key(blob, bloblen))
1450
	  !monitor_allowed_key(blob, bloblen))
1423
		fatal("%s: bad key, not previously allowed", __func__);
1451
		fatal("%s: bad key, not previously allowed", __func__);
1452
	if (type != key_blobtype)
1453
		fatal("%s: bad key type", __func__);
1424
1454
1425
	key = key_from_blob(blob, bloblen);
1455
	key = key_from_blob(blob, bloblen);
1426
	if (key == NULL)
1456
	if (key == NULL)
Lines 1441-1447 mm_answer_keyverify(int sock, Buffer *m) Link Here
1441
	if (!valid_data)
1471
	if (!valid_data)
1442
		fatal("%s: bad signature data blob", __func__);
1472
		fatal("%s: bad signature data blob", __func__);
1443
1473
1444
	verified = key_verify(key, signature, signaturelen, data, datalen);
1474
	switch (key_blobtype) {
1475
	case MM_USERKEY:
1476
		verified = user_key_verify(key, signature, signaturelen, data, datalen);
1477
		break;
1478
	case MM_HOSTKEY:
1479
		verified = hostbased_key_verify(key, signature, signaturelen, data, datalen);
1480
		break;
1481
	default:
1482
		verified = 0;
1483
		break;
1484
	}
1445
	debug3("%s: key %p signature %s",
1485
	debug3("%s: key %p signature %s",
1446
	    __func__, key, (verified == 1) ? "verified" : "unverified");
1486
	    __func__, key, (verified == 1) ? "verified" : "unverified");
1447
1487
Lines 1502-1507 mm_session_close(Session *s) Link Here
1502
		debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
1542
		debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
1503
		session_pty_cleanup2(s);
1543
		session_pty_cleanup2(s);
1504
	}
1544
	}
1545
#ifdef SSH_AUDIT_EVENTS
1546
	if (s->command != NULL) {
1547
		debug3("%s: command %d", __func__, s->command_handle);
1548
		session_end_command2(s);
1549
	}
1550
#endif
1505
	session_unused(s->self);
1551
	session_unused(s->self);
1506
}
1552
}
1507
1553
Lines 1784-1789 mm_answer_term(int sock, Buffer *req) Link Here
1784
		sshpam_cleanup();
1830
		sshpam_cleanup();
1785
#endif
1831
#endif
1786
1832
1833
	destroy_sensitive_data(0);
1834
1787
	while (waitpid(pmonitor->m_pid, &status, 0) == -1)
1835
	while (waitpid(pmonitor->m_pid, &status, 0) == -1)
1788
		if (errno != EINTR)
1836
		if (errno != EINTR)
1789
			exit(1);
1837
			exit(1);
Lines 1826-1836 mm_answer_audit_command(int socket, Buffer *m) Link Here
1826
{
1874
{
1827
	u_int len;
1875
	u_int len;
1828
	char *cmd;
1876
	char *cmd;
1877
	Session *s;
1829
1878
1830
	debug3("%s entering", __func__);
1879
	debug3("%s entering", __func__);
1831
	cmd = buffer_get_string(m, &len);
1880
	cmd = buffer_get_string(m, &len);
1881
1832
	/* sanity check command, if so how? */
1882
	/* sanity check command, if so how? */
1833
	audit_run_command(cmd);
1883
	s = session_new();
1884
	if (s == NULL)
1885
		fatal("%s: error allocating a session", __func__);
1886
	s->command = cmd;
1887
	s->command_handle = audit_run_command(cmd);
1888
1889
	buffer_clear(m);
1890
	buffer_put_int(m, s->self);
1891
1892
	mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m);
1893
1894
	return (0);
1895
}
1896
1897
int
1898
mm_answer_audit_end_command(int socket, Buffer *m)
1899
{
1900
	int handle;
1901
	u_int len;
1902
	char *cmd;
1903
	Session *s;
1904
1905
	debug3("%s entering", __func__);
1906
	handle = buffer_get_int(m);
1907
	cmd = buffer_get_string(m, &len);
1908
1909
	s = session_by_id(handle);
1910
	if (s == NULL || s->ttyfd != -1 || s->command == NULL ||
1911
	    strcmp(s->command, cmd) != 0)
1912
		fatal("%s: invalid handle", __func__);
1913
	mm_session_close(s);
1834
	free(cmd);
1914
	free(cmd);
1835
	return (0);
1915
	return (0);
1836
}
1916
}
Lines 1880-1885 monitor_apply_keystate(struct monitor *pmonitor) Link Here
1880
void
1960
void
1881
mm_get_keystate(struct monitor *pmonitor)
1961
mm_get_keystate(struct monitor *pmonitor)
1882
{
1962
{
1963
	Buffer m;
1883
	debug3("%s: Waiting for new keys", __func__);
1964
	debug3("%s: Waiting for new keys", __func__);
1884
1965
1885
	if ((child_state = sshbuf_new()) == NULL)
1966
	if ((child_state = sshbuf_new()) == NULL)
Lines 1887-1892 mm_get_keystate(struct monitor *pmonitor) Link Here
1887
	mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
1968
	mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
1888
	    child_state);
1969
	    child_state);
1889
	debug3("%s: GOT new keys", __func__);
1970
	debug3("%s: GOT new keys", __func__);
1971
1972
#ifdef SSH_AUDIT_EVENTS
1973
	if (compat20) {
1974
		buffer_init(&m);
1975
		mm_request_receive_expect(pmonitor->m_sendfd,
1976
					  MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
1977
		mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m);
1978
		buffer_free(&m);
1979
	}
1980
#endif
1981
1982
	/* Drain any buffered messages from the child */
1983
	while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
1984
		;
1985
1890
}
1986
}
1891
1987
1892
1988
Lines 2056-2058 mm_answer_gss_userok(int sock, Buffer *m) Link Here
2056
}
2152
}
2057
#endif /* GSSAPI */
2153
#endif /* GSSAPI */
2058
2154
2155
#ifdef SSH_AUDIT_EVENTS
2156
int
2157
mm_answer_audit_unsupported_body(int sock, Buffer *m)
2158
{
2159
	int what;
2160
2161
	what = buffer_get_int(m);
2162
2163
	audit_unsupported_body(what);
2164
2165
	buffer_clear(m);
2166
2167
	mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m);
2168
	return 0;
2169
}
2170
2171
int
2172
mm_answer_audit_kex_body(int sock, Buffer *m)
2173
{
2174
	int ctos, len;
2175
	char *cipher, *mac, *compress, *pfs;
2176
	pid_t pid;
2177
	uid_t uid;
2178
2179
	ctos = buffer_get_int(m);
2180
	cipher = buffer_get_string(m, &len);
2181
	mac = buffer_get_string(m, &len);
2182
	compress = buffer_get_string(m, &len);
2183
	pfs = buffer_get_string(m, &len);
2184
	pid = buffer_get_int64(m);
2185
	uid = buffer_get_int64(m);
2186
2187
	audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid);
2188
2189
	free(cipher);
2190
	free(mac);
2191
	free(compress);
2192
	free(pfs);
2193
	buffer_clear(m);
2194
2195
	mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m);
2196
	return 0;
2197
}
2198
2199
int
2200
mm_answer_audit_session_key_free_body(int sock, Buffer *m)
2201
{
2202
	int ctos;
2203
	pid_t pid;
2204
	uid_t uid;
2205
2206
	ctos = buffer_get_int(m);
2207
	pid = buffer_get_int64(m);
2208
	uid = buffer_get_int64(m);
2209
2210
	audit_session_key_free_body(ctos, pid, uid);
2211
2212
	buffer_clear(m);
2213
2214
	mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
2215
	return 0;
2216
}
2217
2218
int
2219
mm_answer_audit_server_key_free(int sock, Buffer *m)
2220
{
2221
	int len;
2222
	char *fp;
2223
	pid_t pid;
2224
	uid_t uid;
2225
2226
	fp = buffer_get_string(m, &len);
2227
	pid = buffer_get_int64(m);
2228
	uid = buffer_get_int64(m);
2229
2230
	audit_destroy_sensitive_data(fp, pid, uid);
2231
2232
	free(fp);
2233
	buffer_clear(m);
2234
2235
	return 0;
2236
}
2237
#endif /* SSH_AUDIT_EVENTS */
(-)a/monitor.h (-1 / +7 lines)
Lines 63-69 enum monitor_reqtype { Link Here
63
	MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
63
	MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107,
64
	MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
64
	MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109,
65
	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
65
	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
66
	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
66
	MONITOR_REQ_AUDIT_EVENT = 112,
67
	MONITOR_REQ_AUDIT_COMMAND = 114, MONITOR_ANS_AUDIT_COMMAND = 115,
68
	MONITOR_REQ_AUDIT_END_COMMAND = 116,
69
	MONITOR_REQ_AUDIT_UNSUPPORTED = 118, MONITOR_ANS_AUDIT_UNSUPPORTED = 119,
70
	MONITOR_REQ_AUDIT_KEX = 120, MONITOR_ANS_AUDIT_KEX = 121,
71
	MONITOR_REQ_AUDIT_SESSION_KEY_FREE = 122, MONITOR_ANS_AUDIT_SESSION_KEY_FREE = 123,
72
	MONITOR_REQ_AUDIT_SERVER_KEY_FREE = 124
67
73
68
};
74
};
69
75
(-)a/monitor_wrap.c (-2 / +147 lines)
Lines 443-449 mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key, Link Here
443
 */
443
 */
444
444
445
int
445
int
446
mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
446
mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
447
{
447
{
448
	Buffer m;
448
	Buffer m;
449
	u_char *blob;
449
	u_char *blob;
Lines 457-462 mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) Link Here
457
		return (0);
457
		return (0);
458
458
459
	buffer_init(&m);
459
	buffer_init(&m);
460
	buffer_put_int(&m, type);
460
	buffer_put_string(&m, blob, len);
461
	buffer_put_string(&m, blob, len);
461
	buffer_put_string(&m, sig, siglen);
462
	buffer_put_string(&m, sig, siglen);
462
	buffer_put_string(&m, data, datalen);
463
	buffer_put_string(&m, data, datalen);
Lines 474-479 mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) Link Here
474
	return (verified);
475
	return (verified);
475
}
476
}
476
477
478
int
479
mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
480
{
481
	return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen);
482
}
483
484
int
485
mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
486
{
487
	return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen);
488
}
489
477
void
490
void
478
mm_send_keystate(struct monitor *monitor)
491
mm_send_keystate(struct monitor *monitor)
479
{
492
{
Lines 986-995 mm_audit_event(ssh_audit_event_t event) Link Here
986
	buffer_free(&m);
999
	buffer_free(&m);
987
}
1000
}
988
1001
989
void
1002
int
990
mm_audit_run_command(const char *command)
1003
mm_audit_run_command(const char *command)
991
{
1004
{
992
	Buffer m;
1005
	Buffer m;
1006
	int handle;
993
1007
994
	debug3("%s entering command %s", __func__, command);
1008
	debug3("%s entering command %s", __func__, command);
995
1009
Lines 997-1002 mm_audit_run_command(const char *command) Link Here
997
	buffer_put_cstring(&m, command);
1011
	buffer_put_cstring(&m, command);
998
1012
999
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
1013
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
1014
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m);
1015
1016
	handle = buffer_get_int(&m);
1017
	buffer_free(&m);
1018
1019
	return (handle);
1020
}
1021
1022
void
1023
mm_audit_end_command(int handle, const char *command)
1024
{
1025
	Buffer m;
1026
1027
	debug3("%s entering command %s", __func__, command);
1028
1029
	buffer_init(&m);
1030
	buffer_put_int(&m, handle);
1031
	buffer_put_cstring(&m, command);
1032
1033
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m);
1000
	buffer_free(&m);
1034
	buffer_free(&m);
1001
}
1035
}
1002
#endif /* SSH_AUDIT_EVENTS */
1036
#endif /* SSH_AUDIT_EVENTS */
Lines 1087-1089 mm_ssh_gssapi_userok(char *user) Link Here
1087
}
1121
}
1088
#endif /* GSSAPI */
1122
#endif /* GSSAPI */
1089
1123
1124
#ifdef SSH_AUDIT_EVENTS
1125
void
1126
mm_audit_unsupported_body(int what)
1127
{
1128
	Buffer m;
1129
1130
	buffer_init(&m);
1131
	buffer_put_int(&m, what);
1132
1133
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m);
1134
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED,
1135
				  &m);
1136
1137
	buffer_free(&m);
1138
}
1139
1140
void
1141
mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid,
1142
		  uid_t uid)
1143
{
1144
	Buffer m;
1145
1146
	buffer_init(&m);
1147
	buffer_put_int(&m, ctos);
1148
	buffer_put_cstring(&m, cipher);
1149
	buffer_put_cstring(&m, (mac ? mac : "<implicit>"));
1150
	buffer_put_cstring(&m, compress);
1151
	buffer_put_cstring(&m, fps);
1152
	buffer_put_int64(&m, pid);
1153
	buffer_put_int64(&m, uid);
1154
1155
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m);
1156
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX,
1157
				  &m);
1158
1159
	buffer_free(&m);
1160
}
1161
1162
void
1163
mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid)
1164
{
1165
	Buffer m;
1166
1167
	buffer_init(&m);
1168
	buffer_put_int(&m, ctos);
1169
	buffer_put_int64(&m, pid);
1170
	buffer_put_int64(&m, uid);
1171
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m);
1172
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE,
1173
				  &m);
1174
	buffer_free(&m);
1175
}
1176
1177
void
1178
mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
1179
{
1180
	Buffer m;
1181
1182
	buffer_init(&m);
1183
	buffer_put_cstring(&m, fp);
1184
	buffer_put_int64(&m, pid);
1185
	buffer_put_int64(&m, uid);
1186
1187
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m);
1188
	buffer_free(&m);
1189
}
1190
1191
int mm_forward_audit_messages(int fdin)
1192
{
1193
	u_char buf[4];
1194
	u_int blen, msg_len;
1195
	Buffer m;
1196
	int ret = 0;
1197
1198
	debug3("%s: entering", __func__);
1199
	buffer_init(&m);
1200
	do {
1201
		blen = atomicio(read, fdin, buf, sizeof(buf));
1202
		if (blen == 0) /* closed pipe */
1203
			break;
1204
		if (blen != sizeof(buf)) {
1205
			error("%s: Failed to read the buffer from child", __func__);
1206
			ret = -1;
1207
			break;
1208
		}
1209
1210
		msg_len = get_u32(buf);
1211
		if (msg_len > 256 * 1024)
1212
			fatal("%s: read: bad msg_len %d", __func__, msg_len);
1213
		buffer_clear(&m);
1214
		buffer_append_space(&m, msg_len);
1215
		if (atomicio(read, fdin, buffer_ptr(&m), msg_len) != msg_len) {
1216
			error("%s: Failed to read the the buffer conent from the child", __func__);
1217
			ret = -1;
1218
			break;
1219
		}
1220
		if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || 
1221
		    atomicio(vwrite, pmonitor->m_recvfd, buffer_ptr(&m), msg_len) != msg_len) {
1222
			error("%s: Failed to write the messag to the monitor", __func__);
1223
			ret = -1;
1224
			break;
1225
		}
1226
	} while (1);
1227
	buffer_free(&m);
1228
	return ret;
1229
}
1230
void mm_set_monitor_pipe(int fd)
1231
{
1232
	pmonitor->m_recvfd = fd;
1233
}
1234
#endif /* SSH_AUDIT_EVENTS */
(-)a/monitor_wrap.h (-2 / +10 lines)
Lines 49-55 int mm_key_allowed(enum mm_keytype, char *, char *, Key *, int); Link Here
49
int mm_user_key_allowed(struct passwd *, Key *, int);
49
int mm_user_key_allowed(struct passwd *, Key *, int);
50
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
50
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
51
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
51
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
52
int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
52
int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int);
53
int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int);
53
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
54
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
54
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
55
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
55
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
56
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
Lines 74-80 void mm_sshpam_free_ctx(void *); Link Here
74
#ifdef SSH_AUDIT_EVENTS
75
#ifdef SSH_AUDIT_EVENTS
75
#include "audit.h"
76
#include "audit.h"
76
void mm_audit_event(ssh_audit_event_t);
77
void mm_audit_event(ssh_audit_event_t);
77
void mm_audit_run_command(const char *);
78
int mm_audit_run_command(const char *);
79
void mm_audit_end_command(int, const char *);
80
void mm_audit_unsupported_body(int);
81
void mm_audit_kex_body(int, char *, char *, char *, char *, pid_t, uid_t);
82
void mm_audit_session_key_free_body(int, pid_t, uid_t);
83
void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
84
int mm_forward_audit_messages(int);
85
void mm_set_monitor_pipe(int);
78
#endif
86
#endif
79
87
80
struct Session;
88
struct Session;
(-)a/packet.c (-11 / +89 lines)
Lines 67-72 Link Here
67
#include "key.h"	/* typedefs XXX */
67
#include "key.h"	/* typedefs XXX */
68
68
69
#include "xmalloc.h"
69
#include "xmalloc.h"
70
#include "audit.h"
70
#include "crc32.h"
71
#include "crc32.h"
71
#include "deattack.h"
72
#include "deattack.h"
72
#include "compat.h"
73
#include "compat.h"
Lines 454-459 ssh_packet_get_connection_out(struct ssh *ssh) Link Here
454
	return ssh->state->connection_out;
455
	return ssh->state->connection_out;
455
}
456
}
456
457
458
static int
459
packet_state_has_keys (const struct session_state *state)
460
{
461
	return state != NULL &&
462
		(state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL);
463
}
464
457
/*
465
/*
458
 * Returns the IP-address of the remote host as a string.  The returned
466
 * Returns the IP-address of the remote host as a string.  The returned
459
 * string must not be freed.
467
 * string must not be freed.
Lines 498-510 ssh_packet_close(struct ssh *ssh) Link Here
498
	if (!state->initialized)
506
	if (!state->initialized)
499
		return;
507
		return;
500
	state->initialized = 0;
508
	state->initialized = 0;
501
	if (state->connection_in == state->connection_out) {
502
		shutdown(state->connection_out, SHUT_RDWR);
503
		close(state->connection_out);
504
	} else {
505
		close(state->connection_in);
506
		close(state->connection_out);
507
	}
508
	sshbuf_free(state->input);
509
	sshbuf_free(state->input);
509
	sshbuf_free(state->output);
510
	sshbuf_free(state->output);
510
	sshbuf_free(state->outgoing_packet);
511
	sshbuf_free(state->outgoing_packet);
Lines 536-547 ssh_packet_close(struct ssh *ssh) Link Here
536
				inflateEnd(stream);
537
				inflateEnd(stream);
537
		}
538
		}
538
	}
539
	}
539
	if ((r = cipher_cleanup(&state->send_context)) != 0)
540
	if (packet_state_has_keys(state)) {
540
		error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
541
		if ((r = cipher_cleanup(&state->send_context)) != 0)
541
	if ((r = cipher_cleanup(&state->receive_context)) != 0)
542
			error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
542
		error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
543
		if ((r = cipher_cleanup(&state->receive_context)) != 0)
544
			error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
545
		audit_session_key_free(MODE_OUT);
546
	}
543
	free(ssh->remote_ipaddr);
547
	free(ssh->remote_ipaddr);
544
	ssh->remote_ipaddr = NULL;
548
	ssh->remote_ipaddr = NULL;
549
	if (state->connection_in == state->connection_out) {
550
		shutdown(state->connection_out, SHUT_RDWR);
551
		close(state->connection_out);
552
	} else {
553
		close(state->connection_in);
554
		close(state->connection_out);
555
	}
545
	free(ssh->state);
556
	free(ssh->state);
546
	ssh->state = NULL;
557
	ssh->state = NULL;
547
}
558
}
Lines 966-971 ssh_set_newkeys(struct ssh *ssh, int mode) Link Here
966
		   (unsigned long long)state->p_read.blocks,
977
		   (unsigned long long)state->p_read.blocks,
967
		   (unsigned long long)state->p_send.bytes,
978
		   (unsigned long long)state->p_send.bytes,
968
		   (unsigned long long)state->p_send.blocks);
979
		   (unsigned long long)state->p_send.blocks);
980
		audit_session_key_free(mode);
969
		if ((r = cipher_cleanup(cc)) != 0)
981
		if ((r = cipher_cleanup(cc)) != 0)
970
			return r;
982
			return r;
971
		enc  = &state->newkeys[mode]->enc;
983
		enc  = &state->newkeys[mode]->enc;
Lines 2406-2411 ssh_packet_get_output(struct ssh *ssh) Link Here
2406
	return (void *)ssh->state->output;
2418
	return (void *)ssh->state->output;
2407
}
2419
}
2408
2420
2421
static void
2422
newkeys_destroy_and_free(struct newkeys *newkeys)
2423
{
2424
	if (newkeys == NULL)
2425
		return;
2426
2427
	free(newkeys->enc.name);
2428
2429
	if (newkeys->mac.enabled) {
2430
		mac_clear(&newkeys->mac);
2431
		free(newkeys->mac.name);
2432
	}
2433
2434
	free(newkeys->comp.name);
2435
2436
	newkeys_destroy(newkeys);
2437
	free(newkeys);
2438
}
2439
2440
static void
2441
packet_destroy_state(struct session_state *state)
2442
{
2443
	if (state == NULL)
2444
		return;
2445
2446
	cipher_cleanup(&state->receive_context);
2447
	cipher_cleanup(&state->send_context);
2448
2449
	buffer_free(state->input);
2450
	state->input = NULL;
2451
	buffer_free(state->output);
2452
	state->output = NULL;
2453
	buffer_free(state->outgoing_packet);
2454
	state->outgoing_packet = NULL;
2455
	buffer_free(state->incoming_packet);
2456
	state->incoming_packet = NULL;
2457
	if( state->compression_buffer ) {
2458
		buffer_free(state->compression_buffer);
2459
		state->compression_buffer = NULL;
2460
	}
2461
	newkeys_destroy_and_free(state->newkeys[MODE_IN]);
2462
	state->newkeys[MODE_IN] = NULL;
2463
	newkeys_destroy_and_free(state->newkeys[MODE_OUT]);
2464
	state->newkeys[MODE_OUT] = NULL;
2465
	mac_destroy(state->packet_discard_mac);
2466
//	TAILQ_HEAD(, packet) outgoing;
2467
//	memset(state, 0, sizeof(state));
2468
}
2469
2470
void
2471
packet_destroy_all(int audit_it, int privsep)
2472
{
2473
	if (audit_it)
2474
		audit_it = (active_state != NULL && packet_state_has_keys(active_state->state));
2475
	if (active_state != NULL)
2476
		packet_destroy_state(active_state->state);
2477
	if (audit_it) {
2478
#ifdef SSH_AUDIT_EVENTS
2479
		if (privsep)
2480
			audit_session_key_free(MODE_OUT);
2481
		else
2482
			audit_session_key_free_body(MODE_OUT, getpid(), getuid());
2483
#endif
2484
	}
2485
}
2486
2409
/* Reset after_authentication and reset compression in post-auth privsep */
2487
/* Reset after_authentication and reset compression in post-auth privsep */
2410
static int
2488
static int
2411
ssh_packet_set_postauth(struct ssh *ssh)
2489
ssh_packet_set_postauth(struct ssh *ssh)
(-)a/packet.h (+1 lines)
Lines 200-203 extern struct ssh *active_state; Link Here
200
# undef EC_POINT
200
# undef EC_POINT
201
#endif
201
#endif
202
202
203
void	 packet_destroy_all(int, int);
203
#endif				/* PACKET_H */
204
#endif				/* PACKET_H */
(-)a/sandbox-seccomp-filter.c (+6 lines)
Lines 153-158 static const struct sock_filter preauth_insns[] = { Link Here
153
#ifdef __NR_gettimeofday
153
#ifdef __NR_gettimeofday
154
	SC_ALLOW(gettimeofday),
154
	SC_ALLOW(gettimeofday),
155
#endif
155
#endif
156
#ifdef SSH_AUDIT_EVENTS
157
	SC_ALLOW(getuid),
158
#ifdef __NR_getuid32 /* not defined on x86_64 */
159
	SC_ALLOW(getuid32),
160
#endif
161
#endif
156
#ifdef __NR_madvise
162
#ifdef __NR_madvise
157
	SC_ALLOW(madvise),
163
	SC_ALLOW(madvise),
158
#endif
164
#endif
(-)a/session.c (-5 / +111 lines)
Lines 139-145 extern int log_stderr; Link Here
139
extern int debug_flag;
139
extern int debug_flag;
140
extern u_int utmp_len;
140
extern u_int utmp_len;
141
extern int startup_pipe;
141
extern int startup_pipe;
142
extern void destroy_sensitive_data(void);
142
extern void destroy_sensitive_data(int);
143
extern Buffer loginmsg;
143
extern Buffer loginmsg;
144
144
145
/* original command from peer. */
145
/* original command from peer. */
Lines 159-164 static Session *sessions = NULL; Link Here
159
login_cap_t *lc;
159
login_cap_t *lc;
160
#endif
160
#endif
161
161
162
#ifdef SSH_AUDIT_EVENTS
163
int paudit[2];
164
#endif
165
162
static int is_child = 0;
166
static int is_child = 0;
163
static int in_chroot = 0;
167
static int in_chroot = 0;
164
168
Lines 730-735 do_exec_pty(Session *s, const char *command) Link Here
730
	/* Parent.  Close the slave side of the pseudo tty. */
734
	/* Parent.  Close the slave side of the pseudo tty. */
731
	close(ttyfd);
735
	close(ttyfd);
732
736
737
#if !defined(HAVE_OSF_SIA) && defined(SSH_AUDIT_EVENTS)
738
	/* do_login in the child did not affect state in this process,
739
	   compensate.  From an architectural standpoint, this is extremely
740
	   ugly. */
741
	if (!(options.use_login && command == NULL))
742
		audit_count_session_open();
743
#endif
744
733
	/* Enter interactive session. */
745
	/* Enter interactive session. */
734
	s->ptymaster = ptymaster;
746
	s->ptymaster = ptymaster;
735
	packet_set_interactive(1, 
747
	packet_set_interactive(1, 
Lines 825-839 do_exec(Session *s, const char *command) Link Here
825
	    s->self);
837
	    s->self);
826
838
827
#ifdef SSH_AUDIT_EVENTS
839
#ifdef SSH_AUDIT_EVENTS
840
	if (s->command != NULL || s->command_handle != -1)
841
		fatal("do_exec: command already set");
828
	if (command != NULL)
842
	if (command != NULL)
829
		PRIVSEP(audit_run_command(command));
843
		s->command = xstrdup(command);
830
	else if (s->ttyfd == -1) {
844
	else if (s->ttyfd == -1) {
831
		char *shell = s->pw->pw_shell;
845
		char *shell = s->pw->pw_shell;
832
846
833
		if (shell[0] == '\0')	/* empty shell means /bin/sh */
847
		if (shell[0] == '\0')	/* empty shell means /bin/sh */
834
			shell =_PATH_BSHELL;
848
			shell =_PATH_BSHELL;
835
		PRIVSEP(audit_run_command(shell));
849
		s->command = xstrdup(shell);
836
	}
850
	}
851
	if (s->command != NULL && s->ptyfd == -1)
852
		s->command_handle = PRIVSEP(audit_run_command(s->command));
853
	if (pipe(paudit) < 0)
854
		fatal("pipe: %s", strerror(errno));
837
#endif
855
#endif
838
	if (s->ttyfd != -1)
856
	if (s->ttyfd != -1)
839
		ret = do_exec_pty(s, command);
857
		ret = do_exec_pty(s, command);
Lines 849-854 do_exec(Session *s, const char *command) Link Here
849
	 */
867
	 */
850
	buffer_clear(&loginmsg);
868
	buffer_clear(&loginmsg);
851
869
870
#ifdef SSH_AUDIT_EVENTS
871
	close(paudit[1]);
872
	if (use_privsep && ret == 0) {
873
		/*
874
		 * Read the audit messages from forked child and send them
875
		 * back to monitor. We don't want to communicate directly,
876
		 * because the messages might get mixed up.
877
		 * Continue after the pipe gets closed (all messages sent).
878
		 */
879
		ret = mm_forward_audit_messages(paudit[0]);
880
	}
881
	close(paudit[0]);
882
#endif /* SSH_AUDIT_EVENTS */
883
852
	return ret;
884
	return ret;
853
}
885
}
854
886
Lines 1669-1676 do_child(Session *s, const char *command) Link Here
1669
	struct passwd *pw = s->pw;
1701
	struct passwd *pw = s->pw;
1670
	int r = 0;
1702
	int r = 0;
1671
1703
1704
#ifdef SSH_AUDIT_EVENTS
1705
	int pparent = paudit[1];
1706
	close(paudit[0]);
1707
	/* Hack the monitor pipe to avoid race condition with parent */
1708
	if (use_privsep)
1709
		mm_set_monitor_pipe(pparent);
1710
#endif
1711
1672
	/* remove hostkey from the child's memory */
1712
	/* remove hostkey from the child's memory */
1673
	destroy_sensitive_data();
1713
	destroy_sensitive_data(use_privsep);
1714
	/*
1715
	 * We can audit this, because wer hacked the pipe to direct the
1716
	 * messages over postauth child. But this message requires answer
1717
	 * which we can't do using one-way pipe.
1718
	 */
1719
	packet_destroy_all(0, 1);
1720
1721
#ifdef SSH_AUDIT_EVENTS
1722
	/* Notify parent that we are done */
1723
	close(pparent);
1724
#endif
1674
1725
1675
	/* Force a password change */
1726
	/* Force a password change */
1676
	if (s->authctxt->force_pwchange) {
1727
	if (s->authctxt->force_pwchange) {
Lines 1897-1902 session_unused(int id) Link Here
1897
	sessions[id].ttyfd = -1;
1948
	sessions[id].ttyfd = -1;
1898
	sessions[id].ptymaster = -1;
1949
	sessions[id].ptymaster = -1;
1899
	sessions[id].x11_chanids = NULL;
1950
	sessions[id].x11_chanids = NULL;
1951
#ifdef SSH_AUDIT_EVENTS
1952
	sessions[id].command_handle = -1;
1953
#endif
1900
	sessions[id].next_unused = sessions_first_unused;
1954
	sessions[id].next_unused = sessions_first_unused;
1901
	sessions_first_unused = id;
1955
	sessions_first_unused = id;
1902
}
1956
}
Lines 1979-1984 session_open(Authctxt *authctxt, int chanid) Link Here
1979
}
2033
}
1980
2034
1981
Session *
2035
Session *
2036
session_by_id(int id)
2037
{
2038
	if (id >= 0 && id < sessions_nalloc) {
2039
		Session *s = &sessions[id];
2040
		if (s->used)
2041
			return s;
2042
	}
2043
	debug("%s: unknown id %d", __func__, id);
2044
	session_dump();
2045
	return NULL;
2046
}
2047
2048
Session *
1982
session_by_tty(char *tty)
2049
session_by_tty(char *tty)
1983
{
2050
{
1984
	int i;
2051
	int i;
Lines 2495-2500 session_exit_message(Session *s, int status) Link Here
2495
		chan_write_failed(c);
2562
		chan_write_failed(c);
2496
}
2563
}
2497
2564
2565
#ifdef SSH_AUDIT_EVENTS
2566
void
2567
session_end_command2(Session *s)
2568
{
2569
	if (s->command != NULL) {
2570
		if (s->command_handle != -1)
2571
			audit_end_command(s->command_handle, s->command);
2572
		free(s->command);
2573
		s->command = NULL;
2574
		s->command_handle = -1;
2575
	}
2576
}
2577
2578
static void
2579
session_end_command(Session *s)
2580
{
2581
	if (s->command != NULL) {
2582
		if (s->command_handle != -1)
2583
			PRIVSEP(audit_end_command(s->command_handle, s->command));
2584
		free(s->command);
2585
		s->command = NULL;
2586
		s->command_handle = -1;
2587
	}
2588
}
2589
#endif
2590
2498
void
2591
void
2499
session_close(Session *s)
2592
session_close(Session *s)
2500
{
2593
{
Lines 2508-2513 session_close(Session *s) Link Here
2508
2601
2509
	if (s->ttyfd != -1)
2602
	if (s->ttyfd != -1)
2510
		session_pty_cleanup(s);
2603
		session_pty_cleanup(s);
2604
#ifdef SSH_AUDIT_EVENTS
2605
	if (s->command)
2606
		session_end_command(s);
2607
#endif
2511
	free(s->term);
2608
	free(s->term);
2512
	free(s->display);
2609
	free(s->display);
2513
	free(s->x11_chanids);
2610
	free(s->x11_chanids);
Lines 2722-2727 do_authenticated2(Authctxt *authctxt) Link Here
2722
	server_loop2(authctxt);
2819
	server_loop2(authctxt);
2723
}
2820
}
2724
2821
2822
static void
2823
do_cleanup_one_session(Session *s)
2824
{
2825
	session_pty_cleanup2(s);
2826
#ifdef SSH_AUDIT_EVENTS
2827
	session_end_command2(s);
2828
#endif
2829
}
2830
2725
void
2831
void
2726
do_cleanup(Authctxt *authctxt)
2832
do_cleanup(Authctxt *authctxt)
2727
{
2833
{
Lines 2770-2774 do_cleanup(Authctxt *authctxt) Link Here
2770
	 * or if running in monitor.
2876
	 * or if running in monitor.
2771
	 */
2877
	 */
2772
	if (!use_privsep || mm_is_monitor())
2878
	if (!use_privsep || mm_is_monitor())
2773
		session_destroy_all(session_pty_cleanup2);
2879
		session_destroy_all(do_cleanup_one_session);
2774
}
2880
}
(-)a/session.h (+8 lines)
Lines 61-66 struct Session { Link Here
61
		char	*name;
61
		char	*name;
62
		char	*val;
62
		char	*val;
63
	} *env;
63
	} *env;
64
65
	/* exec */
66
#ifdef SSH_AUDIT_EVENTS
67
	int	command_handle;
68
	char	*command;
69
#endif
64
};
70
};
65
71
66
void	 do_authenticated(Authctxt *);
72
void	 do_authenticated(Authctxt *);
Lines 73-80 void session_close_by_pid(pid_t, int); Link Here
73
void	 session_close_by_channel(int, void *);
79
void	 session_close_by_channel(int, void *);
74
void	 session_destroy_all(void (*)(Session *));
80
void	 session_destroy_all(void (*)(Session *));
75
void	 session_pty_cleanup2(Session *);
81
void	 session_pty_cleanup2(Session *);
82
void	 session_end_command2(Session *);
76
83
77
Session	*session_new(void);
84
Session	*session_new(void);
85
Session *session_by_id(int);
78
Session	*session_by_tty(char *);
86
Session	*session_by_tty(char *);
79
void	 session_close(Session *);
87
void	 session_close(Session *);
80
void	 do_setusercontext(struct passwd *);
88
void	 do_setusercontext(struct passwd *);
(-)a/sshd.c (-7 / +92 lines)
Lines 121-126 Link Here
121
#include "ssh-gss.h"
121
#include "ssh-gss.h"
122
#endif
122
#endif
123
#include "monitor_wrap.h"
123
#include "monitor_wrap.h"
124
#include "audit.h"
124
#include "ssh-sandbox.h"
125
#include "ssh-sandbox.h"
125
#include "version.h"
126
#include "version.h"
126
#include "ssherr.h"
127
#include "ssherr.h"
Lines 253-259 Buffer loginmsg; Link Here
253
struct passwd *privsep_pw = NULL;
254
struct passwd *privsep_pw = NULL;
254
255
255
/* Prototypes for various functions defined later in this file. */
256
/* Prototypes for various functions defined later in this file. */
256
void destroy_sensitive_data(void);
257
void destroy_sensitive_data(int);
257
void demote_sensitive_data(void);
258
void demote_sensitive_data(void);
258
259
259
#ifdef WITH_SSH1
260
#ifdef WITH_SSH1
Lines 274-279 close_listen_socks(void) Link Here
274
	num_listen_socks = -1;
275
	num_listen_socks = -1;
275
}
276
}
276
277
278
/*
279
 * Is this process listening for clients (i.e. not specific to any specific
280
 * client connection?)
281
 */
282
int listening_for_clients(void)
283
{
284
	return num_listen_socks > 0;
285
}
286
277
static void
287
static void
278
close_startup_pipes(void)
288
close_startup_pipes(void)
279
{
289
{
Lines 553-574 sshd_exchange_identification(int sock_in, int sock_out) Link Here
553
	}
563
	}
554
}
564
}
555
565
556
/* Destroy the host and server keys.  They will no longer be needed. */
566
/*
567
 * Destroy the host and server keys.  They will no longer be needed.  Careful,
568
 * this can be called from cleanup_exit() - i.e. from just about anywhere.
569
 */
557
void
570
void
558
destroy_sensitive_data(void)
571
destroy_sensitive_data(int privsep)
559
{
572
{
560
	int i;
573
	int i;
574
#ifdef SSH_AUDIT_EVENTS
575
	pid_t pid;
576
	uid_t uid;
561
577
578
	pid = getpid();
579
	uid = getuid();
580
#endif
562
	if (sensitive_data.server_key) {
581
	if (sensitive_data.server_key) {
563
		key_free(sensitive_data.server_key);
582
		key_free(sensitive_data.server_key);
564
		sensitive_data.server_key = NULL;
583
		sensitive_data.server_key = NULL;
565
	}
584
	}
566
	for (i = 0; i < options.num_host_key_files; i++) {
585
	for (i = 0; i < options.num_host_key_files; i++) {
567
		if (sensitive_data.host_keys[i]) {
586
		if (sensitive_data.host_keys[i]) {
587
			char *fp;
588
589
			if (key_is_private(sensitive_data.host_keys[i]))
590
				fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX);
591
			else
592
				fp = NULL;
568
			key_free(sensitive_data.host_keys[i]);
593
			key_free(sensitive_data.host_keys[i]);
569
			sensitive_data.host_keys[i] = NULL;
594
			sensitive_data.host_keys[i] = NULL;
595
			if (fp != NULL) {
596
#ifdef SSH_AUDIT_EVENTS
597
				if (privsep)
598
					PRIVSEP(audit_destroy_sensitive_data(fp,
599
						pid, uid));
600
				else
601
					audit_destroy_sensitive_data(fp,
602
						pid, uid);
603
#endif
604
				free(fp);
605
			}
570
		}
606
		}
571
		if (sensitive_data.host_certificates[i]) {
607
		if (sensitive_data.host_certificates
608
		    && sensitive_data.host_certificates[i]) {
572
			key_free(sensitive_data.host_certificates[i]);
609
			key_free(sensitive_data.host_certificates[i]);
573
			sensitive_data.host_certificates[i] = NULL;
610
			sensitive_data.host_certificates[i] = NULL;
574
		}
611
		}
Lines 583-589 demote_sensitive_data(void) Link Here
583
{
620
{
584
	Key *tmp;
621
	Key *tmp;
585
	int i;
622
	int i;
623
#ifdef SSH_AUDIT_EVENTS
624
	pid_t pid;
625
	uid_t uid;
586
626
627
	pid = getpid();
628
	uid = getuid();
629
#endif
587
	if (sensitive_data.server_key) {
630
	if (sensitive_data.server_key) {
588
		tmp = key_demote(sensitive_data.server_key);
631
		tmp = key_demote(sensitive_data.server_key);
589
		key_free(sensitive_data.server_key);
632
		key_free(sensitive_data.server_key);
Lines 592-602 demote_sensitive_data(void) Link Here
592
635
593
	for (i = 0; i < options.num_host_key_files; i++) {
636
	for (i = 0; i < options.num_host_key_files; i++) {
594
		if (sensitive_data.host_keys[i]) {
637
		if (sensitive_data.host_keys[i]) {
638
			char *fp;
639
640
			if (key_is_private(sensitive_data.host_keys[i]))
641
				fp = sshkey_fingerprint(sensitive_data.host_keys[i], options.fingerprint_hash, SSH_FP_HEX);
642
			else
643
				fp = NULL;
595
			tmp = key_demote(sensitive_data.host_keys[i]);
644
			tmp = key_demote(sensitive_data.host_keys[i]);
596
			key_free(sensitive_data.host_keys[i]);
645
			key_free(sensitive_data.host_keys[i]);
597
			sensitive_data.host_keys[i] = tmp;
646
			sensitive_data.host_keys[i] = tmp;
598
			if (tmp->type == KEY_RSA1)
647
			if (tmp->type == KEY_RSA1)
599
				sensitive_data.ssh1_host_key = tmp;
648
				sensitive_data.ssh1_host_key = tmp;
649
			if (fp != NULL) {
650
#ifdef SSH_AUDIT_EVENTS
651
				audit_destroy_sensitive_data(fp, pid, uid);
652
#endif
653
				free(fp);
654
			}
600
		}
655
		}
601
		/* Certs do not need demotion */
656
		/* Certs do not need demotion */
602
	}
657
	}
Lines 746-751 privsep_postauth(Authctxt *authctxt) Link Here
746
	else if (pmonitor->m_pid != 0) {
801
	else if (pmonitor->m_pid != 0) {
747
		verbose("User child is on pid %ld", (long)pmonitor->m_pid);
802
		verbose("User child is on pid %ld", (long)pmonitor->m_pid);
748
		buffer_clear(&loginmsg);
803
		buffer_clear(&loginmsg);
804
		if (*pmonitor->m_pkex != NULL ){
805
			newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_OUT]);
806
			newkeys_destroy((*pmonitor->m_pkex)->newkeys[MODE_IN]);
807
			audit_session_key_free_body(2, getpid(), getuid());
808
			packet_destroy_all(0, 0);
809
		}
749
		monitor_child_postauth(pmonitor);
810
		monitor_child_postauth(pmonitor);
750
811
751
		/* NEVERREACHED */
812
		/* NEVERREACHED */
Lines 1273-1278 server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) Link Here
1273
		if (received_sigterm) {
1334
		if (received_sigterm) {
1274
			logit("Received signal %d; terminating.",
1335
			logit("Received signal %d; terminating.",
1275
			    (int) received_sigterm);
1336
			    (int) received_sigterm);
1337
			destroy_sensitive_data(0);
1276
			close_listen_socks();
1338
			close_listen_socks();
1277
			if (options.pid_file != NULL)
1339
			if (options.pid_file != NULL)
1278
				unlink(options.pid_file);
1340
				unlink(options.pid_file);
Lines 2212-2217 main(int ac, char **av) Link Here
2212
	 */
2274
	 */
2213
	if (use_privsep) {
2275
	if (use_privsep) {
2214
		mm_send_keystate(pmonitor);
2276
		mm_send_keystate(pmonitor);
2277
		packet_destroy_all(1, 1);
2215
		exit(0);
2278
		exit(0);
2216
	}
2279
	}
2217
2280
Lines 2254-2260 main(int ac, char **av) Link Here
2254
		privsep_postauth(authctxt);
2317
		privsep_postauth(authctxt);
2255
		/* the monitor process [priv] will not return */
2318
		/* the monitor process [priv] will not return */
2256
		if (!compat20)
2319
		if (!compat20)
2257
			destroy_sensitive_data();
2320
			destroy_sensitive_data(0);
2258
	}
2321
	}
2259
2322
2260
	packet_set_timeout(options.client_alive_interval,
2323
	packet_set_timeout(options.client_alive_interval,
Lines 2268-2273 main(int ac, char **av) Link Here
2268
	do_authenticated(authctxt);
2331
	do_authenticated(authctxt);
2269
2332
2270
	/* The connection has been terminated. */
2333
	/* The connection has been terminated. */
2334
	packet_destroy_all(1, 1);
2335
	destroy_sensitive_data(1);
2336
2271
	packet_get_bytes(&ibytes, &obytes);
2337
	packet_get_bytes(&ibytes, &obytes);
2272
	verbose("Transferred: sent %llu, received %llu bytes",
2338
	verbose("Transferred: sent %llu, received %llu bytes",
2273
	    (unsigned long long)obytes, (unsigned long long)ibytes);
2339
	    (unsigned long long)obytes, (unsigned long long)ibytes);
Lines 2428-2433 do_ssh1_kex(void) Link Here
2428
		if (cookie[i] != packet_get_char())
2494
		if (cookie[i] != packet_get_char())
2429
			packet_disconnect("IP Spoofing check bytes do not match.");
2495
			packet_disconnect("IP Spoofing check bytes do not match.");
2430
2496
2497
#ifdef SSH_AUDIT_EVENTS
2498
	audit_kex(MODE_OUT, cipher_name(cipher_type), "crc", "none", "none");
2499
#endif
2500
2431
	debug("Encryption type: %.200s", cipher_name(cipher_type));
2501
	debug("Encryption type: %.200s", cipher_name(cipher_type));
2432
2502
2433
	/* Get the encrypted integer. */
2503
	/* Get the encrypted integer. */
Lines 2487-2493 do_ssh1_kex(void) Link Here
2487
	}
2557
	}
2488
2558
2489
	/* Destroy the private and public keys. No longer. */
2559
	/* Destroy the private and public keys. No longer. */
2490
	destroy_sensitive_data();
2560
	destroy_sensitive_data(1);
2491
2561
2492
	if (use_privsep)
2562
	if (use_privsep)
2493
		mm_ssh1_session_id(session_id);
2563
		mm_ssh1_session_id(session_id);
Lines 2612-2617 do_ssh2_kex(void) Link Here
2612
void
2682
void
2613
cleanup_exit(int i)
2683
cleanup_exit(int i)
2614
{
2684
{
2685
	static int in_cleanup = 0;
2686
	int is_privsep_child;
2687
2688
	/* cleanup_exit can be called at the very least from the privsep
2689
	   wrappers used for auditing.  Make sure we don't recurse
2690
	   indefinitely. */
2691
	if (in_cleanup)
2692
		_exit(i);
2693
	in_cleanup = 1;
2694
2615
	if (the_authctxt) {
2695
	if (the_authctxt) {
2616
		do_cleanup(the_authctxt);
2696
		do_cleanup(the_authctxt);
2617
		if (use_privsep && privsep_is_preauth &&
2697
		if (use_privsep && privsep_is_preauth &&
Lines 2623-2631 cleanup_exit(int i) Link Here
2623
				    pmonitor->m_pid, strerror(errno));
2703
				    pmonitor->m_pid, strerror(errno));
2624
		}
2704
		}
2625
	}
2705
	}
2706
	is_privsep_child = use_privsep && pmonitor != NULL && pmonitor->m_pid == 0;
2707
	if (sensitive_data.host_keys != NULL)
2708
		destroy_sensitive_data(is_privsep_child);
2709
	packet_destroy_all(1, is_privsep_child);
2626
#ifdef SSH_AUDIT_EVENTS
2710
#ifdef SSH_AUDIT_EVENTS
2627
	/* done after do_cleanup so it can cancel the PAM auth 'thread' */
2711
	/* done after do_cleanup so it can cancel the PAM auth 'thread' */
2628
	if (!use_privsep || mm_is_monitor())
2712
	if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
2713
	    (!use_privsep || mm_is_monitor()))
2629
		audit_event(SSH_CONNECTION_ABANDON);
2714
		audit_event(SSH_CONNECTION_ABANDON);
2630
#endif
2715
#endif
2631
	_exit(i);
2716
	_exit(i);
(-)a/sshkey.c (+27 lines)
Lines 302-307 sshkey_type_is_valid_ca(int type) Link Here
302
}
302
}
303
303
304
int
304
int
305
sshkey_is_private(const struct sshkey *k)
306
{
307
      switch (k->type) {
308
#ifdef WITH_OPENSSL
309
      case KEY_RSA_CERT:
310
      case KEY_RSA1:
311
      case KEY_RSA:
312
              return k->rsa->d != NULL;
313
      case KEY_DSA_CERT:
314
      case KEY_DSA:
315
              return k->dsa->priv_key != NULL;
316
#ifdef OPENSSL_HAS_ECC
317
      case KEY_ECDSA_CERT:
318
      case KEY_ECDSA:
319
              return EC_KEY_get0_private_key(k->ecdsa) != NULL;
320
#endif /* OPENSSL_HAS_ECC */
321
#endif /* WITH_OPENSSL */
322
      case KEY_ED25519_CERT:
323
      case KEY_ED25519:
324
              return (k->ed25519_pk != NULL);
325
      default:
326
              /* fatal("key_is_private: bad key type %d", k->type); */
327
              return 0;
328
      }
329
}
330
331
int
305
sshkey_is_cert(const struct sshkey *k)
332
sshkey_is_cert(const struct sshkey *k)
306
{
333
{
307
	if (k == NULL)
334
	if (k == NULL)
(-)a/sshkey.h (-1 / +1 lines)
Lines 132-137 u_int sshkey_size(const struct sshkey *); Link Here
132
int		 sshkey_generate(int type, u_int bits, struct sshkey **keyp);
132
int		 sshkey_generate(int type, u_int bits, struct sshkey **keyp);
133
int		 sshkey_from_private(const struct sshkey *, struct sshkey **);
133
int		 sshkey_from_private(const struct sshkey *, struct sshkey **);
134
int	 sshkey_type_from_name(const char *);
134
int	 sshkey_type_from_name(const char *);
135
int	 sshkey_is_private(const struct sshkey *);
135
int	 sshkey_is_cert(const struct sshkey *);
136
int	 sshkey_is_cert(const struct sshkey *);
136
int	 sshkey_type_is_cert(int);
137
int	 sshkey_type_is_cert(int);
137
int	 sshkey_type_plain(int);
138
int	 sshkey_type_plain(int);
138
- 

Return to bug 1402