2010-09-20 02:41:01 +00:00
|
|
|
diff -up openssh-5.6p1/audit-bsm.c.audit2 openssh-5.6p1/audit-bsm.c
|
2010-11-02 20:10:16 +00:00
|
|
|
--- openssh-5.6p1/audit-bsm.c.audit2 2010-11-02 21:04:27.000000000 +0100
|
|
|
|
+++ openssh-5.6p1/audit-bsm.c 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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
|
2010-11-02 20:10:16 +00:00
|
|
|
--- openssh-5.6p1/audit.c.audit2 2010-11-02 21:04:27.000000000 +0100
|
|
|
|
+++ openssh-5.6p1/audit.c 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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
|
2010-11-02 20:10:16 +00:00
|
|
|
--- openssh-5.6p1/audit.h.audit2 2010-11-02 21:04:27.000000000 +0100
|
|
|
|
+++ openssh-5.6p1/audit.h 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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
|
2010-11-02 20:10:16 +00:00
|
|
|
--- openssh-5.6p1/audit-linux.c.audit2 2010-11-02 21:04:27.000000000 +0100
|
|
|
|
+++ openssh-5.6p1/audit-linux.c 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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
|
2010-11-02 20:10:16 +00:00
|
|
|
+++ openssh-5.6p1/auth2-pubkey.c 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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)
|
|
|
|
{
|
2010-11-02 20:10:16 +00:00
|
|
|
diff -up openssh-5.6p1/auth.h.audit2 openssh-5.6p1/auth.h
|
|
|
|
--- openssh-5.6p1/auth.h.audit2 2010-11-02 21:06:05.000000000 +0100
|
|
|
|
+++ openssh-5.6p1/auth.h 2010-11-02 21:07:32.000000000 +0100
|
|
|
|
@@ -170,6 +170,7 @@ void abandon_challenge_response(Authctxt
|
|
|
|
char *authorized_keys_file(struct passwd *);
|
|
|
|
char *authorized_keys_file2(struct passwd *);
|
|
|
|
char *authorized_principals_file(struct passwd *);
|
|
|
|
+int pubkey_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
|
|
|
|
|
|
|
FILE *auth_openkeyfile(const char *, struct passwd *, int);
|
|
|
|
FILE *auth_openprincipals(const char *, struct passwd *, int);
|
2010-09-20 02:41:01 +00:00
|
|
|
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
|
2010-11-02 20:10:16 +00:00
|
|
|
+++ openssh-5.6p1/auth-rsa.c 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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
|
2010-11-02 20:10:16 +00:00
|
|
|
+++ openssh-5.6p1/monitor.c 2010-11-02 21:04:28.000000000 +0100
|
2010-09-20 02:41:01 +00:00
|
|
|
@@ -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");
|
|
|
|
|