Bugzilla – Attachment 2090 Details for
Bug 1402
Support auditing through Linux Audit subsystem
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
05 audit server key destruction suitable for 5.9p1
openssh-5.9p1-audit5.patch (text/plain), 15.63 KB, created by
jchadima
on 2011-09-18 12:49:50 AEST
(
hide
)
Description:
05 audit server key destruction suitable for 5.9p1
Filename:
MIME Type:
Creator:
jchadima
Created:
2011-09-18 12:49:50 AEST
Size:
15.63 KB
patch
obsolete
>diff -up openssh-5.9p1/audit-bsm.c.audit5 openssh-5.9p1/audit-bsm.c >--- openssh-5.9p1/audit-bsm.c.audit5 2011-09-13 22:07:31.262575526 +0200 >+++ openssh-5.9p1/audit-bsm.c 2011-09-13 22:07:33.268491813 +0200 >@@ -414,4 +414,22 @@ audit_session_key_free_body(int ctos, pi > { > /* not implemented */ > } >+ >+void >+audit_destroy_sensitive_data(const char *fp) >+{ >+ /* not implemented */ >+} >+ >+void >+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) >+{ >+ /* not implemented */ >+} >+ >+void >+audit_generate_ephemeral_server_key(const char *fp) >+{ >+ /* not implemented */ >+} > #endif /* BSM */ >diff -up openssh-5.9p1/audit-linux.c.audit5 openssh-5.9p1/audit-linux.c >--- openssh-5.9p1/audit-linux.c.audit5 2011-09-13 22:07:31.400584308 +0200 >+++ openssh-5.9p1/audit-linux.c 2011-09-13 22:07:33.357460348 +0200 >@@ -350,4 +350,50 @@ audit_session_key_free_body(int ctos, pi > error("cannot write into audit"); > } > >+void >+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) >+{ >+ char buf[AUDIT_LOG_SIZE]; >+ int audit_fd, audit_ok; >+ >+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ", >+ fp, (intmax_t)pid, (intmax_t)uid); >+ audit_fd = audit_open(); >+ if (audit_fd < 0) { >+ if (errno != EINVAL && errno != EPROTONOSUPPORT && >+ errno != EAFNOSUPPORT) >+ error("cannot open audit"); >+ return; >+ } >+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, >+ buf, NULL, >+ listening_for_clients() ? NULL : get_remote_ipaddr(), >+ NULL, 1); >+ audit_close(audit_fd); >+ /* do not abort if the error is EPERM and sshd is run as non root user */ >+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) >+ error("cannot write into audit"); >+} >+ >+void >+audit_generate_ephemeral_server_key(const char *fp) >+{ >+ char buf[AUDIT_LOG_SIZE]; >+ int audit_fd, audit_ok; >+ >+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp); >+ audit_fd = audit_open(); >+ if (audit_fd < 0) { >+ if (errno != EINVAL && errno != EPROTONOSUPPORT && >+ errno != EAFNOSUPPORT) >+ error("cannot open audit"); >+ return; >+ } >+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, >+ buf, NULL, 0, NULL, 1); >+ audit_close(audit_fd); >+ /* do not abort if the error is EPERM and sshd is run as non root user */ >+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) >+ error("cannot write into audit"); >+} > #endif /* USE_LINUX_AUDIT */ >diff -up openssh-5.9p1/audit.c.audit5 openssh-5.9p1/audit.c >--- openssh-5.9p1/audit.c.audit5 2011-09-13 22:07:31.495458797 +0200 >+++ openssh-5.9p1/audit.c 2011-09-13 22:07:33.478458341 +0200 >@@ -290,5 +290,24 @@ audit_session_key_free_body(int ctos, pi > debug("audit session key discard euid %u direction %d from pid %ld uid %u", > (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); > } >+ >+/* >+ * This will be called on destroy private part of the server key >+ */ >+void >+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) >+{ >+ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u", >+ geteuid(), fp, (long)pid, (unsigned)uid); >+} >+ >+/* >+ * This will be called on generation of the ephemeral server key >+ */ >+void >+audit_generate_ephemeral_server_key(const char *) >+{ >+ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp); >+} > # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ > #endif /* SSH_AUDIT_EVENTS */ >diff -up openssh-5.9p1/audit.h.audit5 openssh-5.9p1/audit.h >--- openssh-5.9p1/audit.h.audit5 2011-09-13 22:07:31.616459125 +0200 >+++ openssh-5.9p1/audit.h 2011-09-13 22:07:33.612458074 +0200 >@@ -48,6 +48,8 @@ enum ssh_audit_event_type { > }; > typedef enum ssh_audit_event_type ssh_audit_event_t; > >+int listening_for_clients(void); >+ > void audit_connection_from(const char *, int); > void audit_event(ssh_audit_event_t); > void audit_count_session_open(void); >@@ -64,5 +66,7 @@ void audit_unsupported_body(int); > void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); > void audit_session_key_free(int ctos); > void audit_session_key_free_body(int ctos, pid_t, uid_t); >+void audit_destroy_sensitive_data(const char *, pid_t, uid_t); >+void audit_generate_ephemeral_server_key(const char *); > > #endif /* _SSH_AUDIT_H */ >diff -up openssh-5.9p1/key.c.audit5 openssh-5.9p1/key.c >--- openssh-5.9p1/key.c.audit5 2011-09-13 22:07:23.054490740 +0200 >+++ openssh-5.9p1/key.c 2011-09-13 22:07:33.721583661 +0200 >@@ -1799,6 +1799,30 @@ key_demote(const Key *k) > } > > int >+key_is_private(const Key *k) >+{ >+ switch (k->type) { >+ case KEY_RSA_CERT_V00: >+ case KEY_RSA_CERT: >+ case KEY_RSA1: >+ case KEY_RSA: >+ return k->rsa->d != NULL; >+ case KEY_DSA_CERT_V00: >+ case KEY_DSA_CERT: >+ case KEY_DSA: >+ return k->dsa->priv_key != NULL; >+#ifdef OPENSSL_HAS_ECC >+ case KEY_ECDSA_CERT: >+ case KEY_ECDSA: >+ return EC_KEY_get0_private_key(k->ecdsa) != NULL; >+#endif >+ default: >+ fatal("key_is_private: bad key type %d", k->type); >+ return 1; >+ } >+} >+ >+int > key_is_cert(const Key *k) > { > if (k == NULL) >diff -up openssh-5.9p1/key.h.audit5 openssh-5.9p1/key.h >--- openssh-5.9p1/key.h.audit5 2011-09-13 22:07:23.160459285 +0200 >+++ openssh-5.9p1/key.h 2011-09-13 22:07:33.847459341 +0200 >@@ -109,6 +109,7 @@ Key *key_generate(int, u_int); > Key *key_from_private(const Key *); > int key_type_from_name(char *); > int key_is_cert(const Key *); >+int key_is_private(const Key *k); > int key_type_plain(int); > int key_to_certified(Key *, int); > int key_drop_cert(Key *); >diff -up openssh-5.9p1/monitor.c.audit5 openssh-5.9p1/monitor.c >--- openssh-5.9p1/monitor.c.audit5 2011-09-13 22:07:32.285495537 +0200 >+++ openssh-5.9p1/monitor.c 2011-09-13 22:10:04.148554239 +0200 >@@ -114,6 +114,8 @@ extern Buffer auth_debug; > extern int auth_debug_init; > extern Buffer loginmsg; > >+extern void destroy_sensitive_data(int); >+ > /* State exported from the child */ > > struct { >@@ -191,6 +193,7 @@ int mm_answer_audit_end_command(int, Buf > int mm_answer_audit_unsupported_body(int, Buffer *); > int mm_answer_audit_kex_body(int, Buffer *); > int mm_answer_audit_session_key_free_body(int, Buffer *); >+int mm_answer_audit_server_key_free(int, Buffer *); > #endif > > static int monitor_read_log(struct monitor *); >@@ -244,6 +247,7 @@ struct mon_table mon_dispatch_proto20[] > {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, > {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, >+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, > #endif > #ifdef BSD_AUTH > {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, >@@ -285,6 +289,7 @@ struct mon_table mon_dispatch_postauth20 > {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, > {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, >+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, > #endif > {0, 0, NULL} > }; >@@ -319,6 +324,7 @@ struct mon_table mon_dispatch_proto15[] > {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, > {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, >+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, > #endif > {0, 0, NULL} > }; >@@ -334,6 +340,7 @@ struct mon_table mon_dispatch_postauth15 > {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, > {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, > {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, >+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free}, > #endif > {0, 0, NULL} > }; >@@ -1716,6 +1723,8 @@ mm_answer_term(int sock, Buffer *req) > sshpam_cleanup(); > #endif > >+ destroy_sensitive_data(0); >+ > while (waitpid(pmonitor->m_pid, &status, 0) == -1) > if (errno != EINTR) > exit(1); >@@ -2470,4 +2479,25 @@ mm_answer_audit_session_key_free_body(in > mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); > return 0; > } >+ >+int >+mm_answer_audit_server_key_free(int sock, Buffer *m) >+{ >+ int len; >+ char *fp; >+ pid_t pid; >+ uid_t uid; >+ >+ fp = buffer_get_string(m, &len); >+ pid = buffer_get_int64(m); >+ uid = buffer_get_int64(m); >+ >+ audit_destroy_sensitive_data(fp, pid, uid); >+ >+ xfree(fp); >+ buffer_clear(m); >+ >+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m); >+ return 0; >+} > #endif /* SSH_AUDIT_EVENTS */ >diff -up openssh-5.9p1/monitor.h.audit5 openssh-5.9p1/monitor.h >--- openssh-5.9p1/monitor.h.audit5 2011-09-13 22:07:32.385522626 +0200 >+++ openssh-5.9p1/monitor.h 2011-09-13 22:07:34.098459356 +0200 >@@ -64,6 +64,7 @@ enum monitor_reqtype { > MONITOR_REQ_AUDIT_UNSUPPORTED, MONITOR_ANS_AUDIT_UNSUPPORTED, > MONITOR_REQ_AUDIT_KEX, MONITOR_ANS_AUDIT_KEX, > MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, >+ MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, > MONITOR_REQ_TERM, > MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1, > MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA, >diff -up openssh-5.9p1/monitor_wrap.c.audit5 openssh-5.9p1/monitor_wrap.c >--- openssh-5.9p1/monitor_wrap.c.audit5 2011-09-13 22:07:32.510521163 +0200 >+++ openssh-5.9p1/monitor_wrap.c 2011-09-13 22:07:34.610458275 +0200 >@@ -1559,4 +1559,20 @@ mm_audit_session_key_free_body(int ctos, > &m); > buffer_free(&m); > } >+ >+void >+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid) >+{ >+ Buffer m; >+ >+ buffer_init(&m); >+ buffer_put_cstring(&m, fp); >+ buffer_put_int64(&m, pid); >+ buffer_put_int64(&m, uid); >+ >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m); >+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, >+ &m); >+ buffer_free(&m); >+} > #endif /* SSH_AUDIT_EVENTS */ >diff -up openssh-5.9p1/monitor_wrap.h.audit5 openssh-5.9p1/monitor_wrap.h >--- openssh-5.9p1/monitor_wrap.h.audit5 2011-09-13 22:07:32.607520810 +0200 >+++ openssh-5.9p1/monitor_wrap.h 2011-09-13 22:07:34.716458214 +0200 >@@ -81,6 +81,7 @@ void mm_audit_end_command(int, const cha > void mm_audit_unsupported_body(int); > void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); > void mm_audit_session_key_free_body(int, pid_t, uid_t); >+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t); > #endif > > struct Session; >diff -up openssh-5.9p1/session.c.audit5 openssh-5.9p1/session.c >--- openssh-5.9p1/session.c.audit5 2011-09-13 22:07:32.973544819 +0200 >+++ openssh-5.9p1/session.c 2011-09-13 22:07:34.849585578 +0200 >@@ -136,7 +136,7 @@ extern int log_stderr; > extern int debug_flag; > extern u_int utmp_len; > extern int startup_pipe; >-extern void destroy_sensitive_data(void); >+extern void destroy_sensitive_data(int); > extern Buffer loginmsg; > > /* original command from peer. */ >@@ -1633,7 +1633,7 @@ do_child(Session *s, const char *command > int r = 0; > > /* remove hostkey from the child's memory */ >- destroy_sensitive_data(); >+ destroy_sensitive_data(1); > /* Don't audit this - both us and the parent would be talking to the > monitor over a single socket, with no synchronization. */ > packet_destroy_all(0, 1); >diff -up openssh-5.9p1/sshd.c.audit5 openssh-5.9p1/sshd.c >--- openssh-5.9p1/sshd.c.audit5 2011-09-13 22:07:33.106516378 +0200 >+++ openssh-5.9p1/sshd.c 2011-09-13 22:07:34.989470331 +0200 >@@ -254,7 +254,7 @@ Buffer loginmsg; > struct passwd *privsep_pw = NULL; > > /* Prototypes for various functions defined later in this file. */ >-void destroy_sensitive_data(void); >+void destroy_sensitive_data(int); > void demote_sensitive_data(void); > > static void do_ssh1_kex(void); >@@ -273,6 +273,15 @@ close_listen_socks(void) > num_listen_socks = -1; > } > >+/* >+ * Is this process listening for clients (i.e. not specific to any specific >+ * client connection?) >+ */ >+int listening_for_clients(void) >+{ >+ return num_listen_socks > 0; >+} >+ > static void > close_startup_pipes(void) > { >@@ -533,22 +542,47 @@ sshd_exchange_identification(int sock_in > } > } > >-/* Destroy the host and server keys. They will no longer be needed. */ >+/* >+ * Destroy the host and server keys. They will no longer be needed. Careful, >+ * this can be called from cleanup_exit() - i.e. from just about anywhere. >+ */ > void >-destroy_sensitive_data(void) >+destroy_sensitive_data(int privsep) > { > int i; >+ pid_t pid; >+ uid_t uid; > > if (sensitive_data.server_key) { > key_free(sensitive_data.server_key); > sensitive_data.server_key = NULL; > } >+ pid = getpid(); >+ uid = getuid(); > for (i = 0; i < options.num_host_key_files; i++) { > if (sensitive_data.host_keys[i]) { >+ char *fp; >+ >+ if (key_is_private(sensitive_data.host_keys[i])) >+ fp = key_fingerprint(sensitive_data.host_keys[i], >+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, >+ SSH_FP_HEX); >+ else >+ fp = NULL; > key_free(sensitive_data.host_keys[i]); > sensitive_data.host_keys[i] = NULL; >+ if (fp != NULL) { >+ if (privsep) >+ PRIVSEP(audit_destroy_sensitive_data(fp, >+ pid, uid)); >+ else >+ audit_destroy_sensitive_data(fp, >+ pid, uid); >+ xfree(fp); >+ } > } >- if (sensitive_data.host_certificates[i]) { >+ if (sensitive_data.host_certificates >+ && sensitive_data.host_certificates[i]) { > key_free(sensitive_data.host_certificates[i]); > sensitive_data.host_certificates[i] = NULL; > } >@@ -562,6 +596,8 @@ void > demote_sensitive_data(void) > { > Key *tmp; >+ pid_t pid; >+ uid_t uid; > int i; > > if (sensitive_data.server_key) { >@@ -570,13 +606,27 @@ demote_sensitive_data(void) > sensitive_data.server_key = tmp; > } > >+ pid = getpid(); >+ uid = getuid(); > for (i = 0; i < options.num_host_key_files; i++) { > if (sensitive_data.host_keys[i]) { >+ char *fp; >+ >+ if (key_is_private(sensitive_data.host_keys[i])) >+ fp = key_fingerprint(sensitive_data.host_keys[i], >+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, >+ SSH_FP_HEX); >+ else >+ fp = NULL; > tmp = key_demote(sensitive_data.host_keys[i]); > key_free(sensitive_data.host_keys[i]); > sensitive_data.host_keys[i] = tmp; > if (tmp->type == KEY_RSA1) > sensitive_data.ssh1_host_key = tmp; >+ if (fp != NULL) { >+ audit_destroy_sensitive_data(fp, pid, uid); >+ xfree(fp); >+ } > } > /* Certs do not need demotion */ > } >@@ -1145,6 +1195,7 @@ server_accept_loop(int *sock_in, int *so > if (received_sigterm) { > logit("Received signal %d; terminating.", > (int) received_sigterm); >+ destroy_sensitive_data(0); > close_listen_socks(); > unlink(options.pid_file); > exit(received_sigterm == SIGTERM ? 0 : 255); >@@ -2050,7 +2101,7 @@ main(int ac, char **av) > privsep_postauth(authctxt); > /* the monitor process [priv] will not return */ > if (!compat20) >- destroy_sensitive_data(); >+ destroy_sensitive_data(0); > } > > packet_set_timeout(options.client_alive_interval, >@@ -2061,6 +2112,7 @@ main(int ac, char **av) > > /* The connection has been terminated. */ > packet_destroy_all(1, 1); >+ destroy_sensitive_data(1); > > packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); > packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); >@@ -2289,7 +2341,7 @@ do_ssh1_kex(void) > session_id[i] = session_key[i] ^ session_key[i + 16]; > } > /* Destroy the private and public keys. No longer. */ >- destroy_sensitive_data(); >+ destroy_sensitive_data(0); > > if (use_privsep) > mm_ssh1_session_id(session_id); >@@ -2392,6 +2444,8 @@ cleanup_exit(int i) > if (the_authctxt) > do_cleanup(the_authctxt); > is_privsep_child = use_privsep && pmonitor != NULL && !mm_is_monitor(); >+ if (sensitive_data.host_keys != NULL) >+ destroy_sensitive_data(is_privsep_child); > packet_destroy_all(1, is_privsep_child); > #ifdef SSH_AUDIT_EVENTS > /* done after do_cleanup so it can cancel the PAM auth 'thread' */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1402
:
1396
|
1930
|
1931
|
1934
|
1939
|
1940
|
1942
|
1943
|
1945
|
1950
|
1951
|
1952
|
1954
|
1974
|
1975
|
1976
|
1981
|
2010
|
2011
|
2012
|
2013
|
2014
|
2015
|
2085
|
2086
|
2087
|
2088
|
2089
|
2090
|
2795