X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/780d885cf6a749455f48b6c9ad71d9bd24a3fb4e..c023a130651f79edf9205ef4a067d4158026a651:/monitor.c diff --git a/monitor.c b/monitor.c index 04534d75..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,14 +26,21 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.61 2004/07/17 05:31:41 dtucker 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" @@ -143,7 +151,7 @@ int mm_answer_gss_userok(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *); #endif -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS int mm_answer_audit_event(int, Buffer *); int mm_answer_audit_command(int, Buffer *); #endif @@ -171,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) @@ -191,12 +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 AUDIT_EVENTS - {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event}, +#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}, @@ -219,7 +228,7 @@ 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 AUDIT_EVENTS +#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 @@ -231,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}, @@ -251,8 +260,8 @@ struct mon_table mon_dispatch_proto15[] = { {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 AUDIT_EVENTS - {MONITOR_REQ_AUDIT_EVENT, 0, mm_answer_audit_event}, +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, #endif {0, 0, NULL} }; @@ -261,9 +270,9 @@ 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 AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, - {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, + {MONITOR_REQ_AUDIT_COMMAND, MON_ONCE, mm_answer_audit_command}, #endif {0, 0, NULL} }; @@ -310,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; @@ -324,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)) @@ -346,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) @@ -356,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); @@ -535,7 +549,11 @@ mm_answer_sign(int sock, 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 */ @@ -628,8 +646,8 @@ mm_answer_pwnamallow(int sock, Buffer *m) if (options.use_pam) monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif -#ifdef AUDIT_EVENTS - monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_EVENT, 1); +#ifdef SSH_AUDIT_EVENTS + monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_COMMAND, 1); #endif return (0); @@ -832,9 +850,7 @@ mm_answer_pam_account(int sock, Buffer *m) ret = do_pam_account(); buffer_put_int(m, ret); - buffer_append(&loginmsg, "\0", 1); - buffer_put_cstring(m, buffer_ptr(&loginmsg)); - buffer_clear(&loginmsg); + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); @@ -867,8 +883,8 @@ int 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; @@ -901,8 +917,8 @@ int 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; @@ -976,21 +992,24 @@ mm_answer_keyallowed(int sock, 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); @@ -1010,6 +1029,12 @@ mm_answer_keyallowed(int sock, 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", @@ -1211,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); } @@ -1322,7 +1347,7 @@ mm_answer_sesskey(int sock, Buffer *m) 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__); @@ -1374,6 +1399,7 @@ mm_answer_rsa_keyallowed(int sock, 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__); @@ -1513,7 +1539,7 @@ mm_answer_term(int sock, Buffer *req) exit(res); } -#ifdef AUDIT_EVENTS +#ifdef SSH_AUDIT_EVENTS /* Report that an audit event occurred */ int mm_answer_audit_event(int socket, Buffer *m) @@ -1523,15 +1549,14 @@ mm_answer_audit_event(int socket, Buffer *m) debug3("%s entering", __func__); event = buffer_get_int(m); - buffer_free(m); switch(event) { - case AUTH_FAIL_PUBKEY: - case AUTH_FAIL_HOSTBASED: - case AUTH_FAIL_GSSAPI: - case LOGIN_EXCEED_MAXTRIES: - case LOGIN_ROOT_DENIED: - case CONNECTION_CLOSE: - case INVALID_USER: + 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: @@ -1552,10 +1577,9 @@ mm_answer_audit_command(int socket, Buffer *m) /* sanity check command, if so how? */ audit_run_command(cmd); xfree(cmd); - buffer_free(m); return (0); } -#endif /* AUDIT_EVENTS */ +#endif /* SSH_AUDIT_EVENTS */ void monitor_apply_keystate(struct monitor *pmonitor) @@ -1612,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) || @@ -1623,6 +1646,7 @@ mm_get_kex(Buffer *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); @@ -1782,9 +1806,8 @@ monitor_init(void) struct monitor *mon; int pair[2]; - mon = xmalloc(sizeof(*mon)); + mon = xcalloc(1, sizeof(*mon)); - mon->m_pid = 0; monitor_socketpair(pair); mon->m_recvfd = pair[0]; @@ -1831,7 +1854,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) buffer_clear(m); buffer_put_int(m, major); - mm_request_send(sock,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); @@ -1844,7 +1867,7 @@ 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; @@ -1861,7 +1884,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *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); @@ -1910,7 +1933,7 @@ mm_answer_gss_userok(int sock, Buffer *m) debug3("%s: sending result %d", __func__, authenticated); 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);