/*1* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6* 1. Redistributions of source code must retain the above copyright7* notice, this list of conditions and the following disclaimer.8* 2. Redistributions in binary form must reproduce the above copyright9* notice, this list of conditions and the following disclaimer in the10* documentation and/or other materials provided with the distribution.11*12* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR13* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES14* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.15* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,16* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT17* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,18* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY19* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT20* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF21* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.22*/2324#include "includes.h"2526#include <stdarg.h>27#include <string.h>28#include <unistd.h>2930#ifdef SSH_AUDIT_EVENTS3132#include "audit.h"33#include "log.h"34#include "hostfile.h"35#include "auth.h"3637/*38* Care must be taken when using this since it WILL NOT be initialized when39* audit_connection_from() is called and MAY NOT be initialized when40* audit_event(CONNECTION_ABANDON) is called. Test for NULL before using.41*/42extern Authctxt *the_authctxt;4344/* Maybe add the audit class to struct Authmethod? */45ssh_audit_event_t46audit_classify_auth(const char *method)47{48if (strcmp(method, "none") == 0)49return SSH_AUTH_FAIL_NONE;50else if (strcmp(method, "password") == 0)51return SSH_AUTH_FAIL_PASSWD;52else if (strcmp(method, "publickey") == 0 ||53strcmp(method, "rsa") == 0)54return SSH_AUTH_FAIL_PUBKEY;55else if (strncmp(method, "keyboard-interactive", 20) == 0 ||56strcmp(method, "challenge-response") == 0)57return SSH_AUTH_FAIL_KBDINT;58else if (strcmp(method, "hostbased") == 0 ||59strcmp(method, "rhosts-rsa") == 0)60return SSH_AUTH_FAIL_HOSTBASED;61else if (strcmp(method, "gssapi-with-mic") == 0)62return SSH_AUTH_FAIL_GSSAPI;63else64return SSH_AUDIT_UNKNOWN;65}6667/* helper to return supplied username */68const char *69audit_username(void)70{71static const char unknownuser[] = "(unknown user)";72static const char invaliduser[] = "(invalid user)";7374if (the_authctxt == NULL || the_authctxt->user == NULL)75return (unknownuser);76if (!the_authctxt->valid)77return (invaliduser);78return (the_authctxt->user);79}8081const char *82audit_event_lookup(ssh_audit_event_t ev)83{84int i;85static struct event_lookup_struct {86ssh_audit_event_t event;87const char *name;88} event_lookup[] = {89{SSH_LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"},90{SSH_LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"},91{SSH_AUTH_SUCCESS, "AUTH_SUCCESS"},92{SSH_AUTH_FAIL_NONE, "AUTH_FAIL_NONE"},93{SSH_AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"},94{SSH_AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"},95{SSH_AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"},96{SSH_AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"},97{SSH_AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"},98{SSH_INVALID_USER, "INVALID_USER"},99{SSH_NOLOGIN, "NOLOGIN"},100{SSH_CONNECTION_CLOSE, "CONNECTION_CLOSE"},101{SSH_CONNECTION_ABANDON, "CONNECTION_ABANDON"},102{SSH_AUDIT_UNKNOWN, "AUDIT_UNKNOWN"}103};104105for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++)106if (event_lookup[i].event == ev)107break;108return(event_lookup[i].name);109}110111# ifndef CUSTOM_SSH_AUDIT_EVENTS112/*113* Null implementations of audit functions.114* These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.115*/116117/*118* Called after a connection has been accepted but before any authentication119* has been attempted.120*/121void122audit_connection_from(const char *host, int port)123{124debug("audit connection from %s port %d euid %d", host, port,125(int)geteuid());126}127128/*129* Called when various events occur (see audit.h for a list of possible130* events and what they mean).131*/132void133audit_event(struct ssh *ssh, ssh_audit_event_t event)134{135debug("audit event euid %d user %s event %d (%s)", geteuid(),136audit_username(), event, audit_event_lookup(event));137}138139/*140* Called when a user session is started. Argument is the tty allocated to141* the session, or NULL if no tty was allocated.142*143* Note that this may be called multiple times if multiple sessions are used144* within a single connection.145*/146void147audit_session_open(struct logininfo *li)148{149const char *t = li->line ? li->line : "(no tty)";150151debug("audit session open euid %d user %s tty name %s", geteuid(),152audit_username(), t);153}154155/*156* Called when a user session is closed. Argument is the tty allocated to157* the session, or NULL if no tty was allocated.158*159* Note that this may be called multiple times if multiple sessions are used160* within a single connection.161*/162void163audit_session_close(struct logininfo *li)164{165const char *t = li->line ? li->line : "(no tty)";166167debug("audit session close euid %d user %s tty name %s", geteuid(),168audit_username(), t);169}170171/*172* This will be called when a user runs a non-interactive command. Note that173* it may be called multiple times for a single connection since SSH2 allows174* multiple sessions within a single connection.175*/176void177audit_run_command(const char *command)178{179debug("audit run command euid %d user %s command '%.200s'", geteuid(),180audit_username(), command);181}182# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */183#endif /* SSH_AUDIT_EVENTS */184185186