diff options
author | Darren Tucker <dtucker@zip.com.au> | 2005-02-03 00:20:53 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2005-02-03 00:20:53 +1100 |
commit | 269a1ea1c80a855d1eb74fccba6dd5c75947c5d2 (patch) | |
tree | 2c3ece8547de7552c4c78337607a1a387decd797 | |
parent | 2fba993080eba14e339d6a6666ee79580ee20f97 (diff) |
- (dtucker) [Makefile.in auth.c auth.h auth1.c auth2.c loginrec.c monitor.c
monitor.h monitor_wrap.c monitor_wrap.h session.c sshd.c] Bug #125:
(first stage) Add audit instrumentation to sshd, currently disabled by
default. with suggestions from and djm@
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | auth.c | 42 | ||||
-rw-r--r-- | auth.h | 1 | ||||
-rw-r--r-- | auth1.c | 12 | ||||
-rw-r--r-- | auth2.c | 15 | ||||
-rw-r--r-- | loginrec.c | 9 | ||||
-rw-r--r-- | monitor.c | 65 | ||||
-rw-r--r-- | monitor.h | 1 | ||||
-rw-r--r-- | monitor_wrap.c | 30 | ||||
-rw-r--r-- | monitor_wrap.h | 6 | ||||
-rw-r--r-- | session.c | 16 | ||||
-rw-r--r-- | sshd.c | 12 |
13 files changed, 211 insertions, 8 deletions
@@ -14,6 +14,10 @@ | |||
14 | attempts (currently only for password, kbdint and C/R, only on Linux and | 14 | attempts (currently only for password, kbdint and C/R, only on Linux and |
15 | HP-UX), based on code from login.c from util-linux. With ashok_kovai at | 15 | HP-UX), based on code from login.c from util-linux. With ashok_kovai at |
16 | hotmail.com, ok djm@ | 16 | hotmail.com, ok djm@ |
17 | - (dtucker) [Makefile.in auth.c auth.h auth1.c auth2.c loginrec.c monitor.c | ||
18 | monitor.h monitor_wrap.c monitor_wrap.h session.c sshd.c] Bug #125: | ||
19 | (first stage) Add audit instrumentation to sshd, currently disabled by | ||
20 | default. with suggestions from and djm@ | ||
17 | 21 | ||
18 | 20050201 | 22 | 20050201 |
19 | - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some | 23 | - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some |
@@ -2068,4 +2072,4 @@ | |||
2068 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2072 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2069 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2073 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2070 | 2074 | ||
2071 | $Id: ChangeLog,v 1.3632 2005/02/02 12:30:24 dtucker Exp $ | 2075 | $Id: ChangeLog,v 1.3633 2005/02/02 13:20:53 dtucker Exp $ |
diff --git a/Makefile.in b/Makefile.in index 8a1c9f7c0..c6cfef11a 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.267 2005/01/18 01:05:18 dtucker Exp $ | 1 | # $Id: Makefile.in,v 1.268 2005/02/02 13:20:53 dtucker Exp $ |
2 | 2 | ||
3 | # uncomment if you run a non bourne compatable shell. Ie. csh | 3 | # uncomment if you run a non bourne compatable shell. Ie. csh |
4 | #SHELL = @SH@ | 4 | #SHELL = @SH@ |
@@ -85,7 +85,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ | |||
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 |
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: auth.c,v 1.57 2005/01/22 08:17:59 dtucker Exp $"); | |||
51 | #include "bufaux.h" | 51 | #include "bufaux.h" |
52 | #include "packet.h" | 52 | #include "packet.h" |
53 | #include "loginrec.h" | 53 | #include "loginrec.h" |
54 | #include "monitor_wrap.h" | ||
54 | 55 | ||
55 | /* import */ | 56 | /* import */ |
56 | extern ServerOptions options; | 57 | extern ServerOptions options; |
@@ -251,6 +252,44 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) | |||
251 | record_failed_login(authctxt->user, | 252 | record_failed_login(authctxt->user, |
252 | get_canonical_hostname(options.use_dns), "ssh"); | 253 | get_canonical_hostname(options.use_dns), "ssh"); |
253 | #endif | 254 | #endif |
255 | #ifdef AUDIT_EVENTS | ||
256 | if (authenticated == 0 && !authctxt->postponed) { | ||
257 | ssh_audit_event_t event; | ||
258 | |||
259 | debug3("audit failed auth attempt, method %s euid %d", | ||
260 | method, (int)geteuid()); | ||
261 | /* | ||
262 | * Because the auth loop is used in both monitor and slave, | ||
263 | * we must be careful to send each event only once and with | ||
264 | * enough privs to write the event. | ||
265 | */ | ||
266 | event = audit_classify_auth(method); | ||
267 | switch(event) { | ||
268 | case AUTH_FAIL_NONE: | ||
269 | case AUTH_FAIL_PASSWD: | ||
270 | case AUTH_FAIL_KBDINT: | ||
271 | if (geteuid() == 0) | ||
272 | audit_event(event); | ||
273 | break; | ||
274 | case AUTH_FAIL_PUBKEY: | ||
275 | case AUTH_FAIL_HOSTBASED: | ||
276 | case AUTH_FAIL_GSSAPI: | ||
277 | /* | ||
278 | * This is required to handle the case where privsep | ||
279 | * is enabled but it's root logging in, since | ||
280 | * use_privsep won't be cleared until after a | ||
281 | * successful login. | ||
282 | */ | ||
283 | if (geteuid() == 0) | ||
284 | audit_event(event); | ||
285 | else | ||
286 | PRIVSEP(audit_event(event)); | ||
287 | break; | ||
288 | default: | ||
289 | error("unknown authentication audit event %d", event); | ||
290 | } | ||
291 | } | ||
292 | #endif | ||
254 | } | 293 | } |
255 | 294 | ||
256 | /* | 295 | /* |
@@ -476,6 +515,9 @@ getpwnamallow(const char *user) | |||
476 | record_failed_login(user, | 515 | record_failed_login(user, |
477 | get_canonical_hostname(options.use_dns), "ssh"); | 516 | get_canonical_hostname(options.use_dns), "ssh"); |
478 | #endif | 517 | #endif |
518 | #ifdef AUDIT_EVENTS | ||
519 | audit_event(INVALID_USER); | ||
520 | #endif /* AUDIT_EVENTS */ | ||
479 | return (NULL); | 521 | return (NULL); |
480 | } | 522 | } |
481 | if (!allowed_user(pw)) | 523 | if (!allowed_user(pw)) |
@@ -130,6 +130,7 @@ int auth_shadow_pwexpired(Authctxt *); | |||
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); |
@@ -247,8 +247,12 @@ do_authloop(Authctxt *authctxt) | |||
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 |
@@ -283,8 +287,12 @@ do_authloop(Authctxt *authctxt) | |||
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(); |
@@ -167,6 +167,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) | |||
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]" : ""); |
@@ -214,8 +217,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) | |||
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) { |
@@ -255,8 +262,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) | |||
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); |
diff --git a/loginrec.c b/loginrec.c index e77318ba3..0fa9bdea7 100644 --- a/loginrec.c +++ b/loginrec.c | |||
@@ -154,6 +154,7 @@ | |||
154 | #include "atomicio.h" | 154 | #include "atomicio.h" |
155 | #include "packet.h" | 155 | #include "packet.h" |
156 | #include "canohost.h" | 156 | #include "canohost.h" |
157 | #include "auth.h" | ||
157 | 158 | ||
158 | #ifdef HAVE_UTIL_H | 159 | #ifdef HAVE_UTIL_H |
159 | # include <util.h> | 160 | # include <util.h> |
@@ -163,7 +164,7 @@ | |||
163 | # include <libutil.h> | 164 | # include <libutil.h> |
164 | #endif | 165 | #endif |
165 | 166 | ||
166 | RCSID("$Id: loginrec.c,v 1.63 2005/02/02 12:30:25 dtucker Exp $"); | 167 | RCSID("$Id: loginrec.c,v 1.64 2005/02/02 13:20:53 dtucker Exp $"); |
167 | 168 | ||
168 | /** | 169 | /** |
169 | ** prototypes for helper functions in this file | 170 | ** prototypes for helper functions in this file |
@@ -443,6 +444,12 @@ login_write(struct logininfo *li) | |||
443 | !sys_auth_record_login(li->username,li->hostname,li->line)) | 444 | !sys_auth_record_login(li->username,li->hostname,li->line)) |
444 | logit("Writing login record failed for %s", li->username); | 445 | logit("Writing login record failed for %s", li->username); |
445 | #endif | 446 | #endif |
447 | #ifdef AUDIT_EVENTS | ||
448 | if (li->type == LTYPE_LOGIN) | ||
449 | audit_session_open(li->line); | ||
450 | else if (li->type == LTYPE_LOGOUT) | ||
451 | audit_session_close(li->line); | ||
452 | #endif | ||
446 | return (0); | 453 | return (0); |
447 | } | 454 | } |
448 | 455 | ||
@@ -143,6 +143,11 @@ int mm_answer_gss_userok(int, Buffer *); | |||
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 | ||
@@ -186,6 +191,9 @@ struct mon_table mon_dispatch_proto20[] = { | |||
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}, |
@@ -211,6 +219,10 @@ struct mon_table mon_dispatch_postauth20[] = { | |||
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 | ||
@@ -239,6 +251,9 @@ struct mon_table mon_dispatch_proto15[] = { | |||
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 | ||
@@ -246,6 +261,10 @@ struct mon_table mon_dispatch_postauth15[] = { | |||
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 | ||
@@ -609,6 +628,9 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
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 | } |
@@ -1491,6 +1513,49 @@ mm_answer_term(int sock, Buffer *req) | |||
1491 | exit(res); | 1513 | exit(res); |
1492 | } | 1514 | } |
1493 | 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 */ | ||
1558 | |||
1494 | void | 1559 | void |
1495 | monitor_apply_keystate(struct monitor *pmonitor) | 1560 | monitor_apply_keystate(struct monitor *pmonitor) |
1496 | { | 1561 | { |
@@ -59,6 +59,7 @@ enum monitor_reqtype { | |||
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 | ||
diff --git a/monitor_wrap.c b/monitor_wrap.c index 23857639b..983b24072 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1103,6 +1103,36 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) | |||
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) |
diff --git a/monitor_wrap.h b/monitor_wrap.h index e5cf5718c..7ed241aa8 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -74,6 +74,12 @@ int mm_sshpam_respond(void *, u_int, char **); | |||
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); |
@@ -665,6 +665,18 @@ do_exec(Session *s, const char *command) | |||
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); |
@@ -2321,6 +2333,10 @@ do_cleanup(Authctxt *authctxt) | |||
2321 | } | 2333 | } |
2322 | #endif | 2334 | #endif |
2323 | 2335 | ||
2336 | #ifdef AUDIT_EVENTS | ||
2337 | PRIVSEP(audit_event(CONNECTION_CLOSE)); | ||
2338 | #endif | ||
2339 | |||
2324 | /* remove agent socket */ | 2340 | /* remove agent socket */ |
2325 | auth_sock_cleanup_proc(authctxt->pw); | 2341 | auth_sock_cleanup_proc(authctxt->pw); |
2326 | 2342 | ||
@@ -1628,6 +1628,9 @@ main(int ac, char **av) | |||
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()) { |
@@ -1697,6 +1700,10 @@ main(int ac, char **av) | |||
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. |
@@ -2010,5 +2017,10 @@ cleanup_exit(int i) | |||
2010 | { | 2017 | { |
2011 | if (the_authctxt) | 2018 | if (the_authctxt) |
2012 | do_cleanup(the_authctxt); | 2019 | do_cleanup(the_authctxt); |
2020 | #ifdef AUDIT_EVENTS | ||
2021 | /* done after do_cleanup so it can cancel the PAM auth 'thread' */ | ||
2022 | if (!use_privsep || mm_is_monitor()) | ||
2023 | audit_event(CONNECTION_ABANDON); | ||
2024 | #endif | ||
2013 | _exit(i); | 2025 | _exit(i); |
2014 | } | 2026 | } |