diff --git a/audit-bsm.c b/audit-bsm.c index 5160869..c7a1b47 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -481,7 +481,7 @@ audit_unsupported_body(int what) } void -audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid) +audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) { /* not implemented */ } diff --git a/audit-linux.c b/audit-linux.c index 6954fc1..6686f6a 100644 --- a/audit-linux.c +++ b/audit-linux.c @@ -297,7 +297,7 @@ audit_unsupported_body(int what) const static char *direction[] = { "from-server", "from-client", "both" }; void -audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, +audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) { #ifdef AUDIT_CRYPTO_SESSION @@ -306,8 +306,8 @@ audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, Cipher *cipher = cipher_by_name(enc); char *s; - snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d mac=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", - direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, + 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 ", + direction[ctos], enc, cipher ? 8 * cipher->key_len : 0, mac, pfs, (intmax_t)pid, (intmax_t)uid, get_remote_port(), (s = get_local_ipaddr(packet_get_connection_in())), get_local_port()); free(s); diff --git a/audit.c b/audit.c index 13c6849..5b49434 100644 --- a/audit.c +++ b/audit.c @@ -135,9 +135,9 @@ audit_unsupported(int what) } void -audit_kex(int ctos, char *enc, char *mac, char *comp) +audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) { - PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); + PRIVSEP(audit_kex_body(ctos, enc, mac, comp, pfs, getpid(), getuid())); } void @@ -270,11 +270,11 @@ audit_unsupported_body(int what) * This will be called on succesfull protocol negotiation. */ void -audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, +audit_kex_body(int ctos, char *enc, char *mac, char *compress, char *pfs, pid_t pid, uid_t uid) { - debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u", - (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid, + debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s pfs %s from pid %ld uid %u", + (unsigned)geteuid(), ctos, enc, mac, compress, pfs, (long)pid, (unsigned)uid); } diff --git a/audit.h b/audit.h index a2dc3ff..903df66 100644 --- a/audit.h +++ b/audit.h @@ -61,9 +61,9 @@ ssh_audit_event_t audit_classify_auth(const char *); int audit_keyusage(int, const char *, unsigned, char *, int); void audit_key(int, int *, const Key *); void audit_unsupported(int); -void audit_kex(int, char *, char *, char *); +void audit_kex(int, char *, char *, char *, char *); void audit_unsupported_body(int); -void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); +void audit_kex_body(int, char *, 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); diff --git a/auditstub.c b/auditstub.c index 45817e0..116f460 100644 --- a/auditstub.c +++ b/auditstub.c @@ -35,7 +35,7 @@ audit_unsupported(int n) } void -audit_kex(int ctos, char *enc, char *mac, char *comp) +audit_kex(int ctos, char *enc, char *mac, char *comp, char *pfs) { } diff --git a/kex.c b/kex.c index ede7b67..eb5f333 100644 --- a/kex.c +++ b/kex.c @@ -553,13 +553,12 @@ kex_choose_conf(Kex *kex) newkeys->enc.name, authlen == 0 ? newkeys->mac.name : "", newkeys->comp.name); -#ifdef SSH_AUDIT_EVENTS - audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name); -#endif } + choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; @@ -571,11 +570,16 @@ kex_choose_conf(Kex *kex) dh_need = MAX(dh_need, newkeys->enc.block_size); dh_need = MAX(dh_need, newkeys->enc.iv_len); dh_need = MAX(dh_need, newkeys->mac.key_len); + debug("kex: %s need=%d dh_need=%d", kex->name, need, dh_need); +#ifdef SSH_AUDIT_EVENTS + audit_kex(mode, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name, kex->name); +#endif } /* XXX need runden? */ kex->we_need = need; kex->dh_need = dh_need; + /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && !(datafellows & SSH_BUG_FIRSTKEX)) { diff --git a/monitor.c b/monitor.c index 70b9b4c..81bc9c1 100644 --- a/monitor.c +++ b/monitor.c @@ -2396,7 +2396,7 @@ int mm_answer_audit_kex_body(int sock, Buffer *m) { int ctos, len; - char *cipher, *mac, *compress; + char *cipher, *mac, *compress, *pfs; pid_t pid; uid_t uid; @@ -2404,14 +2404,16 @@ mm_answer_audit_kex_body(int sock, Buffer *m) cipher = buffer_get_string(m, &len); mac = buffer_get_string(m, &len); compress = buffer_get_string(m, &len); + pfs = buffer_get_string(m, &len); pid = buffer_get_int64(m); uid = buffer_get_int64(m); - audit_kex_body(ctos, cipher, mac, compress, pid, uid); + audit_kex_body(ctos, cipher, mac, compress, pfs, pid, uid); free(cipher); free(mac); free(compress); + free(pfs); buffer_clear(m); mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m); diff --git a/monitor_wrap.c b/monitor_wrap.c index 93f6535..69b29d8 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1408,7 +1408,7 @@ mm_audit_unsupported_body(int what) } void -mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, +mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, char *fps, pid_t pid, uid_t uid) { Buffer m; @@ -1418,6 +1418,7 @@ mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid, buffer_put_cstring(&m, cipher); buffer_put_cstring(&m, (mac ? mac : "")); buffer_put_cstring(&m, compress); + buffer_put_cstring(&m, fps); buffer_put_int64(&m, pid); buffer_put_int64(&m, uid); diff --git a/monitor_wrap.h b/monitor_wrap.h index 4cf0c78..e43109f 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -83,7 +83,7 @@ void mm_audit_event(ssh_audit_event_t); int mm_audit_run_command(const char *); void mm_audit_end_command(int, const char *); void mm_audit_unsupported_body(int); -void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); +void mm_audit_kex_body(int, char *, 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 diff --git a/sshd.c b/sshd.c index ee94825..41a94a7 100644 --- a/sshd.c +++ b/sshd.c @@ -2430,7 +2430,7 @@ do_ssh1_kex(void) packet_disconnect("IP Spoofing check bytes do not match."); #ifdef SSH_AUDIT_EVENTS - audit_kex(2, cipher_name(cipher_type), "crc", "none"); + audit_kex(2, cipher_name(cipher_type), "crc", "none", "none"); #endif debug("Encryption type: %.200s", cipher_name(cipher_type));