X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/aff51935734441207923b8e59fbc3644fc4e7d2c..c023a130651f79edf9205ef4a067d4158026a651:/monitor.c diff --git a/monitor.c b/monitor.c index 449397e3..894523da 100644 --- a/monitor.c +++ b/monitor.c @@ -1,3 +1,4 @@ +/* $OpenBSD: monitor.c,v 1.77 2006/03/30 11:40:21 dtucker Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -25,19 +26,32 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.54 2003/11/21 11:57:03 djm Exp $"); -#include +#include +#include + +#ifdef HAVE_PATHS_H +#include +#endif +#include #ifdef SKEY #include #endif +#include + #include "ssh.h" #include "auth.h" #include "kex.h" #include "dh.h" +#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ +#undef TARGET_OS_MAC +#include "zlib.h" +#define TARGET_OS_MAC 1 +#else #include "zlib.h" +#endif #include "packet.h" #include "auth-options.h" #include "sshpty.h" @@ -57,7 +71,6 @@ RCSID("$OpenBSD: monitor.c,v 1.54 2003/11/21 11:57:03 djm Exp $"); #include "bufaux.h" #include "compat.h" #include "ssh2.h" -#include "mpaux.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -74,6 +87,7 @@ extern u_char session_id[]; extern Buffer input, output; extern Buffer auth_debug; extern int auth_debug_init; +extern Buffer loginmsg; /* State exported from the child */ @@ -137,6 +151,11 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); #endif +#ifdef SSH_AUDIT_EVENTS +int mm_answer_audit_event(int, Buffer *); +int mm_answer_audit_command(int, Buffer *); +#endif + static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -160,6 +179,7 @@ struct mon_table { #define MON_ISAUTH 0x0004 /* Required for Authentication */ #define MON_AUTHDECIDE 0x0008 /* Decides Authentication */ #define MON_ONCE 0x0010 /* Disable after calling */ +#define MON_ALOG 0x0020 /* Log auth attempt without authenticating */ #define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE) @@ -180,9 +200,12 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, +#endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, - {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, + {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, #endif #ifdef SKEY {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, @@ -205,6 +228,10 @@ struct mon_table mon_dispatch_postauth20[] = { {MONITOR_REQ_PTY, 0, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, +#endif {0, 0, NULL} }; @@ -213,13 +240,13 @@ struct mon_table mon_dispatch_proto15[] = { {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey}, {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, - {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed}, - {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, + {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed}, + {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed}, {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge}, {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response}, #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, - {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, + {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, #endif #ifdef SKEY {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, @@ -232,6 +259,9 @@ struct mon_table mon_dispatch_proto15[] = { {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, +#endif +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, #endif {0, 0, NULL} }; @@ -240,6 +270,10 @@ struct mon_table mon_dispatch_postauth15[] = { {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, {MONITOR_REQ_TERM, 0, mm_answer_term}, +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_ONCE, mm_answer_audit_command}, +#endif {0, 0, NULL} }; @@ -285,6 +319,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) authctxt = _authctxt; memset(authctxt, 0, sizeof(*authctxt)); + authctxt->loginmsg = &loginmsg; + if (compat20) { mon_dispatch = mon_dispatch_proto20; @@ -299,6 +335,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) /* The first few requests do not require asynchronous access */ while (!authenticated) { + auth_method = "unknown"; authenticated = monitor_read(pmonitor, mon_dispatch, &ent); if (authenticated) { if (!(ent->flags & MON_AUTHDECIDE)) @@ -321,7 +358,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) #endif } - if (ent->flags & MON_AUTHDECIDE) { + if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { auth_log(authctxt, authenticated, auth_method, compat20 ? " ssh2" : ""); if (!authenticated) @@ -331,6 +368,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) if (!authctxt->valid) fatal("%s: authenticated invalid user", __func__); + if (strcmp(auth_method, "unknown") == 0) + fatal("%s: authentication method name unknown", __func__); debug("%s: %s has been authenticated by privileged process", __func__, authctxt->user); @@ -345,9 +384,9 @@ monitor_set_child_handler(pid_t pid) } static void -monitor_child_handler(int signal) +monitor_child_handler(int sig) { - kill(monitor_child_pid, signal); + kill(monitor_child_pid, sig); } void @@ -462,7 +501,7 @@ monitor_reset_key_state(void) } int -mm_answer_moduli(int socket, Buffer *m) +mm_answer_moduli(int sock, Buffer *m) { DH *dh; int min, want, max; @@ -492,12 +531,12 @@ mm_answer_moduli(int socket, Buffer *m) DH_free(dh); } - mm_request_send(socket, MONITOR_ANS_MODULI, m); + mm_request_send(sock, MONITOR_ANS_MODULI, m); return (0); } int -mm_answer_sign(int socket, Buffer *m) +mm_answer_sign(int sock, Buffer *m) { Key *key; u_char *p; @@ -510,7 +549,11 @@ mm_answer_sign(int socket, Buffer *m) keyid = buffer_get_int(m); p = buffer_get_string(m, &datlen); - if (datlen != 20) + /* + * Supported KEX types will only return SHA1 (20 byte) or + * SHA256 (32 byte) hashes + */ + if (datlen != 20 && datlen != 32) fatal("%s: data length incorrect: %u", __func__, datlen); /* save session id, it will be passed on the first call */ @@ -533,7 +576,7 @@ mm_answer_sign(int socket, Buffer *m) xfree(p); xfree(signature); - mm_request_send(socket, MONITOR_ANS_SIGN, m); + mm_request_send(sock, MONITOR_ANS_SIGN, m); /* Turn on permissions for getpwnam */ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); @@ -544,9 +587,9 @@ mm_answer_sign(int socket, Buffer *m) /* Retrieves the password entry and also checks if the user is permitted */ int -mm_answer_pwnamallow(int socket, Buffer *m) +mm_answer_pwnamallow(int sock, Buffer *m) { - char *login; + char *username; struct passwd *pwent; int allowed = 0; @@ -555,13 +598,13 @@ mm_answer_pwnamallow(int socket, Buffer *m) if (authctxt->attempt++ != 0) fatal("%s: multiple attempts for getpwnam", __func__); - login = buffer_get_string(m, NULL); + username = buffer_get_string(m, NULL); - pwent = getpwnamallow(login); + pwent = getpwnamallow(username); - authctxt->user = xstrdup(login); - setproctitle("%s [priv]", pwent ? login : "unknown"); - xfree(login); + authctxt->user = xstrdup(username); + setproctitle("%s [priv]", pwent ? username : "unknown"); + xfree(username); buffer_clear(m); @@ -588,7 +631,7 @@ mm_answer_pwnamallow(int socket, Buffer *m) out: debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); - mm_request_send(socket, MONITOR_ANS_PWNAM, m); + mm_request_send(sock, MONITOR_ANS_PWNAM, m); /* For SSHv1 allow authentication now */ if (!compat20) @@ -603,18 +646,21 @@ mm_answer_pwnamallow(int socket, Buffer *m) if (options.use_pam) monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif +#ifdef SSH_AUDIT_EVENTS + monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_COMMAND, 1); +#endif return (0); } -int mm_answer_auth2_read_banner(int socket, Buffer *m) +int mm_answer_auth2_read_banner(int sock, Buffer *m) { char *banner; buffer_clear(m); banner = auth2_read_banner(); buffer_put_cstring(m, banner != NULL ? banner : ""); - mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); + mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); if (banner != NULL) xfree(banner); @@ -623,7 +669,7 @@ int mm_answer_auth2_read_banner(int socket, Buffer *m) } int -mm_answer_authserv(int socket, Buffer *m) +mm_answer_authserv(int sock, Buffer *m) { monitor_permit_authentications(1); @@ -641,7 +687,7 @@ mm_answer_authserv(int socket, Buffer *m) } int -mm_answer_authpassword(int socket, Buffer *m) +mm_answer_authpassword(int sock, Buffer *m) { static int call_count; char *passwd; @@ -659,7 +705,7 @@ mm_answer_authpassword(int socket, Buffer *m) buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m); + mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); call_count++; if (plen == 0 && call_count == 1) @@ -673,7 +719,7 @@ mm_answer_authpassword(int socket, Buffer *m) #ifdef BSD_AUTH int -mm_answer_bsdauthquery(int socket, Buffer *m) +mm_answer_bsdauthquery(int sock, Buffer *m) { char *name, *infotxt; u_int numprompts; @@ -690,7 +736,7 @@ mm_answer_bsdauthquery(int socket, Buffer *m) buffer_put_cstring(m, prompts[0]); debug3("%s: sending challenge success: %u", __func__, success); - mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m); + mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); if (success) { xfree(name); @@ -703,7 +749,7 @@ mm_answer_bsdauthquery(int socket, Buffer *m) } int -mm_answer_bsdauthrespond(int socket, Buffer *m) +mm_answer_bsdauthrespond(int sock, Buffer *m) { char *response; int authok; @@ -722,7 +768,7 @@ mm_answer_bsdauthrespond(int socket, Buffer *m) buffer_put_int(m, authok); debug3("%s: sending authenticated: %d", __func__, authok); - mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m); + mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); auth_method = "bsdauth"; @@ -732,13 +778,14 @@ mm_answer_bsdauthrespond(int socket, Buffer *m) #ifdef SKEY int -mm_answer_skeyquery(int socket, Buffer *m) +mm_answer_skeyquery(int sock, Buffer *m) { struct skey skey; char challenge[1024]; u_int success; - success = skeychallenge(&skey, authctxt->user, challenge) < 0 ? 0 : 1; + success = _compat_skeychallenge(&skey, authctxt->user, challenge, + sizeof(challenge)) < 0 ? 0 : 1; buffer_clear(m); buffer_put_int(m, success); @@ -746,13 +793,13 @@ mm_answer_skeyquery(int socket, Buffer *m) buffer_put_cstring(m, challenge); debug3("%s: sending challenge success: %u", __func__, success); - mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); + mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); return (0); } int -mm_answer_skeyrespond(int socket, Buffer *m) +mm_answer_skeyrespond(int sock, Buffer *m) { char *response; int authok; @@ -770,7 +817,7 @@ mm_answer_skeyrespond(int socket, Buffer *m) buffer_put_int(m, authok); debug3("%s: sending authenticated: %d", __func__, authok); - mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m); + mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); auth_method = "skey"; @@ -780,18 +827,12 @@ mm_answer_skeyrespond(int socket, Buffer *m) #ifdef USE_PAM int -mm_answer_pam_start(int socket, Buffer *m) +mm_answer_pam_start(int sock, Buffer *m) { - char *user; - if (!options.use_pam) fatal("UsePAM not set, but ended up in %s anyway", __func__); - user = buffer_get_string(m, NULL); - - start_pam(user); - - xfree(user); + start_pam(authctxt); monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); @@ -799,18 +840,19 @@ mm_answer_pam_start(int socket, Buffer *m) } int -mm_answer_pam_account(int socket, Buffer *m) +mm_answer_pam_account(int sock, Buffer *m) { u_int ret; - + if (!options.use_pam) fatal("UsePAM not set, but ended up in %s anyway", __func__); ret = do_pam_account(); buffer_put_int(m, ret); + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); - mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); + mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); return (ret); } @@ -819,7 +861,7 @@ static void *sshpam_ctxt, *sshpam_authok; extern KbdintDevice sshpam_device; int -mm_answer_pam_init_ctx(int socket, Buffer *m) +mm_answer_pam_init_ctx(int sock, Buffer *m) { debug3("%s", __func__); @@ -833,16 +875,16 @@ mm_answer_pam_init_ctx(int socket, Buffer *m) } else { buffer_put_int(m, 0); } - mm_request_send(socket, MONITOR_ANS_PAM_INIT_CTX, m); + mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); } int -mm_answer_pam_query(int socket, Buffer *m) +mm_answer_pam_query(int sock, Buffer *m) { char *name, *info, **prompts; - u_int num, *echo_on; - int i, ret; + u_int i, num, *echo_on; + int ret; debug3("%s", __func__); sshpam_authok = NULL; @@ -867,16 +909,16 @@ mm_answer_pam_query(int socket, Buffer *m) xfree(prompts); if (echo_on != NULL) xfree(echo_on); - mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m); + mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); return (0); } int -mm_answer_pam_respond(int socket, Buffer *m) +mm_answer_pam_respond(int sock, Buffer *m) { char **resp; - u_int num; - int i, ret; + u_int i, num; + int ret; debug3("%s", __func__); sshpam_authok = NULL; @@ -894,7 +936,7 @@ mm_answer_pam_respond(int socket, Buffer *m) } buffer_clear(m); buffer_put_int(m, ret); - mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m); + mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); auth_method = "keyboard-interactive/pam"; if (ret == 0) sshpam_authok = sshpam_ctxt; @@ -902,13 +944,13 @@ mm_answer_pam_respond(int socket, Buffer *m) } int -mm_answer_pam_free_ctx(int socket, Buffer *m) +mm_answer_pam_free_ctx(int sock, Buffer *m) { debug3("%s", __func__); (sshpam_device.free_ctx)(sshpam_ctxt); buffer_clear(m); - mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m); + mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); return (sshpam_authok == sshpam_ctxt); } #endif @@ -925,7 +967,7 @@ mm_append_debug(Buffer *m) } int -mm_answer_keyallowed(int socket, Buffer *m) +mm_answer_keyallowed(int sock, Buffer *m) { Key *key; char *cuser, *chost; @@ -950,21 +992,24 @@ mm_answer_keyallowed(int socket, Buffer *m) debug3("%s: key_from_blob: %p", __func__, key); if (key != NULL && authctxt->valid) { - switch(type) { + switch (type) { case MM_USERKEY: allowed = options.pubkey_authentication && user_key_allowed(authctxt->pw, key); + auth_method = "publickey"; break; case MM_HOSTKEY: allowed = options.hostbased_authentication && hostbased_key_allowed(authctxt->pw, cuser, chost, key); + auth_method = "hostbased"; break; case MM_RSAHOSTKEY: key->type = KEY_RSA1; /* XXX */ allowed = options.rhosts_rsa_authentication && auth_rhosts_rsa_key_allowed(authctxt->pw, cuser, chost, key); + auth_method = "rsa"; break; default: fatal("%s: unknown key type %d", __func__, type); @@ -984,6 +1029,12 @@ mm_answer_keyallowed(int socket, Buffer *m) key_blobtype = type; hostbased_cuser = cuser; hostbased_chost = chost; + } else { + /* Log failed attempt */ + auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : ""); + xfree(blob); + xfree(cuser); + xfree(chost); } debug3("%s: key %p is %s", @@ -995,7 +1046,7 @@ mm_answer_keyallowed(int socket, Buffer *m) mm_append_debug(m); - mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m); + mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); if (type == MM_RSAHOSTKEY) monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); @@ -1116,7 +1167,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, } int -mm_answer_keyverify(int socket, Buffer *m) +mm_answer_keyverify(int sock, Buffer *m) { Key *key; u_char *signature, *data, *blob; @@ -1166,7 +1217,7 @@ mm_answer_keyverify(int socket, Buffer *m) buffer_clear(m); buffer_put_int(m, verified); - mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m); + mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); return (verified); } @@ -1185,7 +1236,7 @@ mm_record_login(Session *s, struct passwd *pw) fromlen = sizeof(from); if (packet_connection_is_on_socket()) { if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & from, &fromlen) < 0) { + (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); cleanup_exit(255); } @@ -1208,7 +1259,7 @@ mm_session_close(Session *s) } int -mm_answer_pty(int socket, Buffer *m) +mm_answer_pty(int sock, Buffer *m) { extern struct monitor *pmonitor; Session *s; @@ -1230,10 +1281,6 @@ mm_answer_pty(int socket, Buffer *m) buffer_put_int(m, 1); buffer_put_cstring(m, s->tty); - mm_request_send(socket, MONITOR_ANS_PTY, m); - - mm_send_fd(socket, s->ptyfd); - mm_send_fd(socket, s->ttyfd); /* We need to trick ttyslot */ if (dup2(s->ttyfd, 0) == -1) @@ -1244,6 +1291,15 @@ mm_answer_pty(int socket, Buffer *m) /* Now we can close the file descriptor again */ close(0); + /* send messages generated by record_login */ + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); + buffer_clear(&loginmsg); + + mm_request_send(sock, MONITOR_ANS_PTY, m); + + mm_send_fd(sock, s->ptyfd); + mm_send_fd(sock, s->ttyfd); + /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); @@ -1264,12 +1320,12 @@ mm_answer_pty(int socket, Buffer *m) if (s != NULL) mm_session_close(s); buffer_put_int(m, 0); - mm_request_send(socket, MONITOR_ANS_PTY, m); + mm_request_send(sock, MONITOR_ANS_PTY, m); return (0); } int -mm_answer_pty_cleanup(int socket, Buffer *m) +mm_answer_pty_cleanup(int sock, Buffer *m) { Session *s; char *tty; @@ -1285,13 +1341,13 @@ mm_answer_pty_cleanup(int socket, Buffer *m) } int -mm_answer_sesskey(int socket, Buffer *m) +mm_answer_sesskey(int sock, Buffer *m) { BIGNUM *p; int rsafail; /* Turn off permissions */ - monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0); if ((p = BN_new()) == NULL) fatal("%s: BN_new", __func__); @@ -1306,7 +1362,7 @@ mm_answer_sesskey(int socket, Buffer *m) BN_clear_free(p); - mm_request_send(socket, MONITOR_ANS_SESSKEY, m); + mm_request_send(sock, MONITOR_ANS_SESSKEY, m); /* Turn on permissions for sessid passing */ monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); @@ -1315,7 +1371,7 @@ mm_answer_sesskey(int socket, Buffer *m) } int -mm_answer_sessid(int socket, Buffer *m) +mm_answer_sessid(int sock, Buffer *m) { int i; @@ -1333,7 +1389,7 @@ mm_answer_sessid(int socket, Buffer *m) } int -mm_answer_rsa_keyallowed(int socket, Buffer *m) +mm_answer_rsa_keyallowed(int sock, Buffer *m) { BIGNUM *client_n; Key *key = NULL; @@ -1343,6 +1399,7 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m) debug3("%s entering", __func__); + auth_method = "rsa"; if (options.rsa_authentication && authctxt->valid) { if ((client_n = BN_new()) == NULL) fatal("%s: BN_new", __func__); @@ -1373,7 +1430,7 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m) mm_append_debug(m); - mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m); + mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); @@ -1381,7 +1438,7 @@ mm_answer_rsa_keyallowed(int socket, Buffer *m) } int -mm_answer_rsa_challenge(int socket, Buffer *m) +mm_answer_rsa_challenge(int sock, Buffer *m) { Key *key = NULL; u_char *blob; @@ -1407,7 +1464,7 @@ mm_answer_rsa_challenge(int socket, Buffer *m) buffer_put_bignum2(m, ssh1_challenge); debug3("%s sending reply", __func__); - mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m); + mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); @@ -1417,7 +1474,7 @@ mm_answer_rsa_challenge(int socket, Buffer *m) } int -mm_answer_rsa_response(int socket, Buffer *m) +mm_answer_rsa_response(int sock, Buffer *m) { Key *key = NULL; u_char *blob, *response; @@ -1456,13 +1513,13 @@ mm_answer_rsa_response(int socket, Buffer *m) buffer_clear(m); buffer_put_int(m, success); - mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m); + mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); return (success); } int -mm_answer_term(int socket, Buffer *req) +mm_answer_term(int sock, Buffer *req) { extern struct monitor *pmonitor; int res, status; @@ -1479,8 +1536,50 @@ mm_answer_term(int socket, Buffer *req) res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; /* Terminate process */ - exit (res); + exit(res); +} + +#ifdef SSH_AUDIT_EVENTS +/* Report that an audit event occurred */ +int +mm_answer_audit_event(int socket, Buffer *m) +{ + ssh_audit_event_t event; + + debug3("%s entering", __func__); + + event = buffer_get_int(m); + switch(event) { + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: + case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_LOGIN_ROOT_DENIED: + case SSH_CONNECTION_CLOSE: + case SSH_INVALID_USER: + audit_event(event); + break; + default: + fatal("Audit event type %d not permitted", event); + } + + return (0); +} + +int +mm_answer_audit_command(int socket, Buffer *m) +{ + u_int len; + char *cmd; + + debug3("%s entering", __func__); + cmd = buffer_get_string(m, &len); + /* sanity check command, if so how? */ + audit_run_command(cmd); + xfree(cmd); + return (0); } +#endif /* SSH_AUDIT_EVENTS */ void monitor_apply_keystate(struct monitor *pmonitor) @@ -1537,8 +1636,7 @@ mm_get_kex(Buffer *m) void *blob; u_int bloblen; - kex = xmalloc(sizeof(*kex)); - memset(kex, 0, sizeof(*kex)); + kex = xcalloc(1, sizeof(*kex)); kex->session_id = buffer_get_string(m, &kex->session_id_len); if ((session_id2 == NULL) || (kex->session_id_len != session_id2_len) || @@ -1546,7 +1644,9 @@ mm_get_kex(Buffer *m) fatal("mm_get_get: internal error: bad session id"); kex->we_need = buffer_get_int(m); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); @@ -1706,7 +1806,7 @@ monitor_init(void) struct monitor *mon; int pair[2]; - mon = xmalloc(sizeof(*mon)); + mon = xcalloc(1, sizeof(*mon)); monitor_socketpair(pair); @@ -1738,23 +1838,23 @@ monitor_reinit(struct monitor *mon) #ifdef GSSAPI int -mm_answer_gss_setup_ctx(int socket, Buffer *m) +mm_answer_gss_setup_ctx(int sock, Buffer *m) { - gss_OID_desc oid; + gss_OID_desc goid; OM_uint32 major; u_int len; - oid.elements = buffer_get_string(m, &len); - oid.length = len; + goid.elements = buffer_get_string(m, &len); + goid.length = len; - major = ssh_gssapi_server_ctx(&gsscontext, &oid); + major = ssh_gssapi_server_ctx(&gsscontext, &goid); - xfree(oid.elements); + xfree(goid.elements); buffer_clear(m); buffer_put_int(m, major); - mm_request_send(socket,MONITOR_ANS_GSSSETUP, m); + mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); /* Now we have a context, enable the step */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); @@ -1763,11 +1863,11 @@ mm_answer_gss_setup_ctx(int socket, Buffer *m) } int -mm_answer_gss_accept_ctx(int socket, Buffer *m) +mm_answer_gss_accept_ctx(int sock, Buffer *m) { gss_buffer_desc in; gss_buffer_desc out = GSS_C_EMPTY_BUFFER; - OM_uint32 major,minor; + OM_uint32 major, minor; OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1780,11 +1880,11 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m) buffer_put_int(m, major); buffer_put_string(m, out.value, out.length); buffer_put_int(m, flags); - mm_request_send(socket, MONITOR_ANS_GSSSTEP, m); + mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); gss_release_buffer(&minor, &out); - if (major==GSS_S_COMPLETE) { + if (major == GSS_S_COMPLETE) { monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -1793,35 +1893,35 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m) } int -mm_answer_gss_checkmic(int socket, Buffer *m) +mm_answer_gss_checkmic(int sock, Buffer *m) { gss_buffer_desc gssbuf, mic; OM_uint32 ret; u_int len; - + gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); mic.length = len; - + ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); - + xfree(gssbuf.value); xfree(mic.value); - + buffer_clear(m); buffer_put_int(m, ret); - - mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m); - + + mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); + if (!GSS_ERROR(ret)) monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); - + return (0); } int -mm_answer_gss_userok(int socket, Buffer *m) +mm_answer_gss_userok(int sock, Buffer *m) { int authenticated; @@ -1831,9 +1931,9 @@ mm_answer_gss_userok(int socket, Buffer *m) buffer_put_int(m, authenticated); debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); + mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); - auth_method="gssapi-with-mic"; + auth_method = "gssapi-with-mic"; /* Monitor loop will terminate if authenticated */ return (authenticated);