From b7b582b70e6204ee84a732c5d7375b956a80f784 Mon Sep 17 00:00:00 2001 From: "Jan F. Chadima" Date: Mon, 20 Sep 2010 04:41:01 +0200 Subject: [PATCH] - add auditing the key ussage --- openssh-5.6p1-audit2.patch | 203 +++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 openssh-5.6p1-audit2.patch diff --git a/openssh-5.6p1-audit2.patch b/openssh-5.6p1-audit2.patch new file mode 100644 index 0000000..3f7e695 --- /dev/null +++ b/openssh-5.6p1-audit2.patch @@ -0,0 +1,203 @@ +diff -up openssh-5.6p1/audit-bsm.c.audit2 openssh-5.6p1/audit-bsm.c +--- openssh-5.6p1/audit-bsm.c.audit2 2010-11-02 11:38:30.000000000 +0100 ++++ openssh-5.6p1/audit-bsm.c 2010-11-02 11:38:30.000000000 +0100 +@@ -316,6 +316,12 @@ audit_session_close(struct logininfo *li + /* not implemented */ + } + ++int ++audit_keyusage(const char *type, unsigned len, char *fp, int rv) ++{ ++ /* not implemented */ ++} ++ + void + audit_event(ssh_audit_event_t event) + { +diff -up openssh-5.6p1/audit.c.audit2 openssh-5.6p1/audit.c +--- openssh-5.6p1/audit.c.audit2 2010-11-02 11:38:30.000000000 +0100 ++++ openssh-5.6p1/audit.c 2010-11-02 11:38:30.000000000 +0100 +@@ -182,5 +182,17 @@ audit_run_command(const char *command) + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); + } ++ ++/* ++ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key. ++ * ++ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key. ++ */ ++int ++audit_keyusage(const char *type, unsigned len, char *fp, int rv) ++{ ++ debug("audit key usage euid %d user %s key type %s key length %d fingerprint %s, result %d", geteuid(), ++ audit_username(), type, len, fp, rv); ++} + # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ + #endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-5.6p1/audit.h.audit2 openssh-5.6p1/audit.h +--- openssh-5.6p1/audit.h.audit2 2010-11-02 11:38:30.000000000 +0100 ++++ openssh-5.6p1/audit.h 2010-11-02 11:38:30.000000000 +0100 +@@ -53,5 +53,6 @@ void audit_session_open(struct logininfo + void audit_session_close(struct logininfo *); + void audit_run_command(const char *); + ssh_audit_event_t audit_classify_auth(const char *); ++int audit_keyusage(const char *, unsigned, char *, int); + + #endif /* _SSH_AUDIT_H */ +diff -up openssh-5.6p1/audit-linux.c.audit2 openssh-5.6p1/audit-linux.c +--- openssh-5.6p1/audit-linux.c.audit2 2010-11-02 11:38:30.000000000 +0100 ++++ openssh-5.6p1/audit-linux.c 2010-11-02 11:43:56.000000000 +0100 +@@ -37,6 +37,8 @@ + #include "audit.h" + #include "canohost.h" + ++#define AUDIT_LOG_SIZE 128 ++ + const char* audit_username(void); + + int +@@ -62,6 +64,36 @@ linux_audit_record_event(int uid, const + return (rc >= 0); + } + ++int ++audit_keyusage(const char *type, unsigned len, char *fp, int rv) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, rc, saved_errno; ++ ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return 1; /* No audit support in kernel */ ++ else ++ return 0; /* Must prevent login */ ++ } ++ snprintf(buf, sizeof(buf), "pubkey_auth rport=%d", get_remote_port()); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); ++ if (rc < 0) ++ goto out; ++ snprintf(buf, sizeof(buf), "pubkey_auth algo=%s size=%d fp=%s rport=%d", ++ type, 8 * len, fp, get_remote_port()); ++ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL, ++ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv); ++out: ++ saved_errno = errno; ++ audit_close(audit_fd); ++ errno = saved_errno; ++ return (rc >= 0); ++} ++ + /* Below is the sshd audit API code */ + + void +diff -up openssh-5.6p1/auth2-pubkey.c.audit2 openssh-5.6p1/auth2-pubkey.c +--- openssh-5.6p1/auth2-pubkey.c.audit2 2010-07-02 05:35:19.000000000 +0200 ++++ openssh-5.6p1/auth2-pubkey.c 2010-11-02 11:38:30.000000000 +0100 +@@ -177,6 +177,40 @@ done: + return authenticated; + } + ++int ++pubkey_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen) ++{ ++ int rv; ++#ifdef SSH_AUDIT_EVENTS ++ char *fp; ++ unsigned size = 0; ++ const char *crypto_name[] = { ++ "ssh-rsa1", ++ "ssh-rsa", ++ "ssh-dsa", ++ "unknown" }; ++#endif ++ ++ rv = key_verify(key, sig, slen, data, datalen); ++#ifdef SSH_AUDIT_EVENTS ++ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); ++ switch(key->type) { ++ case KEY_RSA1: ++ case KEY_RSA: ++ size = RSA_size(key->rsa); ++ break; ++ case KEY_DSA: ++ size = DSA_size(key->dsa); ++ break; ++ } ++ ++ if (audit_keyusage(crypto_name[key->type], size, fp, rv) == 0) ++ rv = 0; ++ xfree(fp); ++#endif ++ return rv; ++} ++ + static int + match_principals_option(const char *principal_list, struct KeyCert *cert) + { +diff -up openssh-5.6p1/auth-rsa.c.audit2 openssh-5.6p1/auth-rsa.c +--- openssh-5.6p1/auth-rsa.c.audit2 2010-07-16 05:58:37.000000000 +0200 ++++ openssh-5.6p1/auth-rsa.c 2010-11-02 11:38:30.000000000 +0100 +@@ -92,7 +92,10 @@ auth_rsa_verify_response(Key *key, BIGNU + { + u_char buf[32], mdbuf[16]; + MD5_CTX md; +- int len; ++ int len, rv; ++#ifdef SSH_AUDIT_EVENTS ++ char *fp; ++#endif + + if (auth_key_is_revoked(key)) + return 0; +@@ -116,12 +119,18 @@ auth_rsa_verify_response(Key *key, BIGNU + MD5_Final(mdbuf, &md); + + /* Verify that the response is the original challenge. */ +- if (timingsafe_bcmp(response, mdbuf, 16) != 0) { +- /* Wrong answer. */ +- return (0); ++ rv = timingsafe_bcmp(response, mdbuf, 16) == 0; ++ ++#ifdef SSH_AUDIT_EVENTS ++ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); ++ if (audit_keyusage("ssh-rsa1", RSA_size(key->rsa), fp, rv) == 0) { ++ debug("unsuccessful audit"); ++ rv = 0; + } +- /* Correct answer. */ +- return (1); ++ xfree(fp); ++#endif ++ ++ return rv; + } + + /* +diff -up openssh-5.6p1/monitor.c.audit2 openssh-5.6p1/monitor.c +--- openssh-5.6p1/monitor.c.audit2 2010-08-03 07:50:16.000000000 +0200 ++++ openssh-5.6p1/monitor.c 2010-11-02 11:38:30.000000000 +0100 +@@ -1235,7 +1235,19 @@ mm_answer_keyverify(int sock, Buffer *m) + if (!valid_data) + fatal("%s: bad signature data blob", __func__); + +- verified = key_verify(key, signature, signaturelen, data, datalen); ++ switch (key_blobtype) { ++ case MM_USERKEY: ++ verified = pubkey_key_verify(key, signature, signaturelen, data, datalen); ++ break; ++ case MM_HOSTKEY: ++ verified = key_verify(key, signature, signaturelen, data, datalen); ++ valid_data = monitor_valid_hostbasedblob(data, datalen, ++ hostbased_cuser, hostbased_chost); ++ break; ++ default: ++ verified = 0; ++ break; ++ } + debug3("%s: key %p signature %s", + __func__, key, (verified == 1) ? "verified" : "unverified"); +