diff --git a/audit.c b/audit.c new file mode 100644 index 000000000..13852a05e --- /dev/null +++ b/audit.c @@ -0,0 +1,181 @@ +/* $Id: audit.c,v 1.1 2005/02/02 13:37:14 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef AUDIT_EVENTS + +#include "audit.h" +#include "log.h" +#include "auth.h" + +/* + * Care must be taken when using this since it WILL NOT be initialized when + * audit_connection_from() is called and MAY NOT be initialized when + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ +extern Authctxt *the_authctxt; + +/* Maybe add the audit class to struct Authmethod? */ +ssh_audit_event_t +audit_classify_auth(const char *method) +{ + if (strcmp(method, "none") == 0) + return AUTH_FAIL_NONE; + else if (strcmp(method, "password") == 0) + return AUTH_FAIL_PASSWD; + else if (strcmp(method, "publickey") == 0 || + strcmp(method, "rsa") == 0) + return AUTH_FAIL_PUBKEY; + else if (strncmp(method, "keyboard-interactive", 20) == 0 || + strcmp(method, "challenge-response") == 0) + return AUTH_FAIL_KBDINT; + else if (strcmp(method, "hostbased") == 0 || + strcmp(method, "rhosts-rsa") == 0) + return AUTH_FAIL_HOSTBASED; + else if (strcmp(method, "gssapi-with-mic") == 0) + return AUTH_FAIL_GSSAPI; + else + return AUDIT_UNKNOWN; +} + +/* helper to return supplied username */ +const char * +audit_username(void) +{ + static const char unknownuser[] = "(unknown user)"; + static const char invaliduser[] = "(invalid user)"; + + if (the_authctxt == NULL || the_authctxt->user == NULL) + return (unknownuser); + if (!the_authctxt->valid) + return (invaliduser); + return (the_authctxt->user); +} + +const char * +audit_event_lookup(ssh_audit_event_t ev) +{ + int i; + static struct event_lookup_struct { + ssh_audit_event_t event; + const char *name; + } event_lookup[] = { + {LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"}, + {LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"}, + {AUTH_SUCCESS, "AUTH_SUCCESS"}, + {AUTH_FAIL_NONE, "AUTH_FAIL_NONE"}, + {AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"}, + {AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"}, + {AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"}, + {AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"}, + {AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"}, + {INVALID_USER, "INVALID_USER"}, + {NOLOGIN, "NOLOGIN"}, + {CONNECTION_CLOSE, "CONNECTION_CLOSE"}, + {CONNECTION_ABANDON, "CONNECTION_ABANDON"}, + {AUDIT_UNKNOWN, "AUDIT_UNKNOWN"} + }; + + for (i = 0; event_lookup[i].event != AUDIT_UNKNOWN; i++) + if (event_lookup[i].event == ev) + break; + return(event_lookup[i].name); +} + +# ifndef CUSTOM_AUDIT_EVENTS +/* + * Null implementations of audit functions. + * These get used if AUDIT_EVENTS is defined but no audit module is enabled. + */ + +/* + * Called after a connection has been accepted but before any authentication + * has been attempted. + */ +void +audit_connection_from(const char *host, int port) +{ + debug("audit connection from %s port %d euid %d", host, port, + (int)geteuid()); +} + +/* + * Called when various events occur (see audit.h for a list of possible + * events and what they mean). + */ +void +audit_event(ssh_audit_event_t event) +{ + debug("audit event euid %d user %s event %d (%s)", geteuid(), + audit_username(), event, audit_event_lookup(event)); +} + +/* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +void +audit_session_open(const char *ttyn) +{ + const char *t = ttyn ? ttyn : "(no tty)"; + + debug("audit session open euid %d user %s tty name %s", geteuid(), + audit_username(), t); +} + +/* + * Called when a user session is closed. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +void +audit_session_close(const char *ttyn) +{ + const char *t = ttyn ? ttyn : "(no tty)"; + + debug("audit session close euid %d user %s tty name %s", geteuid(), + audit_username(), t); +} + +/* + * This will be called when a user runs a non-interactive command. Note that + * it may be called multiple times for a single connection since SSH2 allows + * multiple sessions within a single connection. + */ +void +audit_run_command(const char *command) +{ + debug("audit run command euid %d user %s command '%.200s'", geteuid(), + audit_username(), command); +} +# endif /* !defined CUSTOM_AUDIT_EVENTS */ +#endif /* AUDIT_EVENTS */ diff --git a/audit.h b/audit.h new file mode 100644 index 000000000..2c1437391 --- /dev/null +++ b/audit.h @@ -0,0 +1,56 @@ +/* $Id: audit.h,v 1.1 2005/02/02 13:37:14 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "auth.h" + +#ifndef _SSH_AUDIT_H +# define _SSH_AUDIT_H +enum ssh_audit_event_type { + LOGIN_EXCEED_MAXTRIES, + LOGIN_ROOT_DENIED, + AUTH_SUCCESS, + AUTH_FAIL_NONE, + AUTH_FAIL_PASSWD, + AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */ + AUTH_FAIL_PUBKEY, /* ssh2 pubkey or ssh1 rsa */ + AUTH_FAIL_HOSTBASED, /* ssh2 hostbased or ssh1 rhostsrsa */ + AUTH_FAIL_GSSAPI, + INVALID_USER, + NOLOGIN, /* denied by /etc/nologin, not implemented */ + CONNECTION_CLOSE, /* closed after attempting auth or session */ + CONNECTION_ABANDON, /* closed without completing auth */ + AUDIT_UNKNOWN +}; +typedef enum ssh_audit_event_type ssh_audit_event_t; + +void audit_connection_from(const char *, int); +void audit_event(ssh_audit_event_t); +void audit_session_open(const char *); +void audit_session_close(const char *); +void audit_run_command(const char *); +ssh_audit_event_t audit_classify_auth(const char *); + +#endif /* _SSH_AUDIT_H */