=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/monitor.c,v retrieving revision 1.29.2.3 retrieving revision 1.30 diff -u -r1.29.2.3 -r1.30 --- src/usr.bin/ssh/monitor.c 2003/09/16 21:20:26 1.29.2.3 +++ src/usr.bin/ssh/monitor.c 2002/11/05 19:45:20 1.30 @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.29.2.3 2003/09/16 21:20:26 brad Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.30 2002/11/05 19:45:20 markus Exp $"); #include @@ -59,11 +59,6 @@ #include "ssh2.h" #include "mpaux.h" -#ifdef GSSAPI -#include "ssh-gss.h" -static Gssctxt *gsscontext = NULL; -#endif - /* Imports */ extern ServerOptions options; extern u_int utmp_len; @@ -98,7 +93,7 @@ u_int olen; } child_state; -/* Functions on the monitor that answer unprivileged requests */ +/* Functions on the montior that answer unprivileged requests */ int mm_answer_moduli(int, Buffer *); int mm_answer_sign(int, Buffer *); @@ -121,11 +116,12 @@ int mm_answer_sesskey(int, Buffer *); int mm_answer_sessid(int, Buffer *); -#ifdef GSSAPI -int mm_answer_gss_setup_ctx(int, Buffer *); -int mm_answer_gss_accept_ctx(int, Buffer *); -int mm_answer_gss_userok(int, Buffer *); +#ifdef KRB4 +int mm_answer_krb4(int, Buffer *); #endif +#ifdef KRB5 +int mm_answer_krb5(int, Buffer *); +#endif static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -137,9 +133,8 @@ static char *hostbased_cuser = NULL; static char *hostbased_chost = NULL; static char *auth_method = "unknown"; -static u_int session_id2_len = 0; +static int session_id2_len = 0; static u_char *session_id2 = NULL; -static pid_t monitor_child_pid; struct mon_table { enum monitor_reqtype type; @@ -172,11 +167,6 @@ #endif {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, -#ifdef GSSAPI - {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, - {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, - {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, -#endif {0, 0, NULL} }; @@ -206,6 +196,12 @@ {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, #endif +#ifdef KRB4 + {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4}, +#endif +#ifdef KRB5 + {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, +#endif {0, 0, NULL} }; @@ -300,25 +296,9 @@ return (authctxt); } -static void -monitor_set_child_handler(pid_t pid) -{ - monitor_child_pid = pid; -} - -static void -monitor_child_handler(int signal) -{ - kill(monitor_child_pid, signal); -} - void monitor_child_postauth(struct monitor *pmonitor) { - monitor_set_child_handler(pmonitor->m_pid); - signal(SIGHUP, &monitor_child_handler); - signal(SIGTERM, &monitor_child_handler); - if (compat20) { mon_dispatch = mon_dispatch_postauth20; @@ -326,6 +306,7 @@ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); + } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -606,7 +587,7 @@ passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && - auth_password(authctxt, passwd); + authctxt->valid && auth_password(authctxt, passwd); memset(passwd, 0, strlen(passwd)); xfree(passwd); @@ -634,20 +615,20 @@ u_int numprompts; u_int *echo_on; char **prompts; - u_int success; + int res; - success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, - &prompts, &echo_on) < 0 ? 0 : 1; + res = bsdauth_query(authctxt, &name, &infotxt, &numprompts, + &prompts, &echo_on); buffer_clear(m); - buffer_put_int(m, success); - if (success) + buffer_put_int(m, res); + if (res != -1) buffer_put_cstring(m, prompts[0]); - debug3("%s: sending challenge success: %u", __func__, success); + debug3("%s: sending challenge res: %d", __func__, res); mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m); - if (success) { + if (res != -1) { xfree(name); xfree(infotxt); xfree(prompts); @@ -691,16 +672,16 @@ { struct skey skey; char challenge[1024]; - u_int success; + int res; - success = skeychallenge(&skey, authctxt->user, challenge) < 0 ? 0 : 1; + res = skeychallenge(&skey, authctxt->user, challenge); buffer_clear(m); - buffer_put_int(m, success); - if (success) + buffer_put_int(m, res); + if (res != -1) buffer_put_cstring(m, challenge); - debug3("%s: sending challenge success: %u", __func__, success); + debug3("%s: sending challenge res: %d", __func__, res); mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); return (0); @@ -790,9 +771,8 @@ fatal("%s: unknown key type %d", __func__, type); break; } - } - if (key != NULL) key_free(key); + } /* clear temporarily storage (used by verify) */ monitor_reset_key_state(); @@ -811,7 +791,6 @@ buffer_clear(m); buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); mm_append_debug(m); @@ -854,7 +833,7 @@ fail++; p = buffer_get_string(&b, NULL); if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", + log("wrong user name passed to monitor: expected %s != %.100s", authctxt->user, p); fail++; } @@ -902,7 +881,7 @@ fail++; p = buffer_get_string(&b, NULL); if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", + log("wrong user name passed to monitor: expected %s != %.100s", authctxt->user, p); fail++; } @@ -1012,14 +991,14 @@ } /* Record that there was a login on that tty from the remote host. */ record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, - get_remote_name_or_ip(utmp_len, options.use_dns), + get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), (struct sockaddr *)&from, fromlen); } static void mm_session_close(Session *s) { - debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); + debug3("%s: session %d pid %d", __func__, s->self, s->pid); if (s->ttyfd != -1) { debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); fatal_remove_cleanup(session_pty_cleanup2, (void *)s); @@ -1174,7 +1153,6 @@ } buffer_clear(m); buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); /* clear temporarily storage (used by generate challenge) */ monitor_reset_key_state(); @@ -1189,9 +1167,8 @@ key_blob = blob; key_bloblen = blen; key_blobtype = MM_RSAUSERKEY; - } - if (key != NULL) key_free(key); + } mm_append_debug(m); @@ -1232,9 +1209,6 @@ mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); - - xfree(blob); - key_free(key); return (0); } @@ -1265,7 +1239,6 @@ fatal("%s: received bad response to challenge", __func__); success = auth_rsa_verify_response(key, ssh1_challenge, response); - xfree(blob); key_free(key); xfree(response); @@ -1283,7 +1256,90 @@ return (success); } +#ifdef KRB4 int +mm_answer_krb4(int socket, Buffer *m) +{ + KTEXT_ST auth, reply; + char *client, *p; + int success; + u_int alen; + + reply.length = auth.length = 0; + + p = buffer_get_string(m, &alen); + if (alen >= MAX_KTXT_LEN) + fatal("%s: auth too large", __func__); + memcpy(auth.dat, p, alen); + auth.length = alen; + memset(p, 0, alen); + xfree(p); + + success = options.kerberos_authentication && + authctxt->valid && + auth_krb4(authctxt, &auth, &client, &reply); + + memset(auth.dat, 0, alen); + buffer_clear(m); + buffer_put_int(m, success); + + if (success) { + buffer_put_cstring(m, client); + buffer_put_string(m, reply.dat, reply.length); + if (client) + xfree(client); + if (reply.length) + memset(reply.dat, 0, reply.length); + } + + debug3("%s: sending result %d", __func__, success); + mm_request_send(socket, MONITOR_ANS_KRB4, m); + + auth_method = "kerberos"; + + /* Causes monitor loop to terminate if authenticated */ + return (success); +} +#endif + +#ifdef KRB5 +int +mm_answer_krb5(int socket, Buffer *m) +{ + krb5_data tkt, reply; + char *client_user; + u_int len; + int success; + + /* use temporary var to avoid size issues on 64bit arch */ + tkt.data = buffer_get_string(m, &len); + tkt.length = len; + + success = options.kerberos_authentication && + authctxt->valid && + auth_krb5(authctxt, &tkt, &client_user, &reply); + + if (tkt.length) + xfree(tkt.data); + + buffer_clear(m); + buffer_put_int(m, success); + + if (success) { + buffer_put_cstring(m, client_user); + buffer_put_string(m, reply.data, reply.length); + if (client_user) + xfree(client_user); + if (reply.length) + xfree(reply.data); + } + mm_request_send(socket, MONITOR_ANS_KRB5, m); + + return success; +} +#endif + +int mm_answer_term(int socket, Buffer *req) { extern struct monitor *pmonitor; @@ -1367,8 +1423,6 @@ (memcmp(kex->session_id, session_id2, session_id2_len) != 0)) 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_GEX_SHA1] = kexgex_server; kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); @@ -1398,8 +1452,6 @@ Buffer m; u_char *blob, *p; u_int bloblen, plen; - u_int32_t seqnr, packets; - u_int64_t blocks; debug3("%s: Waiting for new keys", __func__); @@ -1429,14 +1481,8 @@ xfree(blob); /* Now get sequence numbers for the packets */ - seqnr = buffer_get_int(&m); - blocks = buffer_get_int64(&m); - packets = buffer_get_int(&m); - packet_set_state(MODE_OUT, seqnr, blocks, packets); - seqnr = buffer_get_int(&m); - blocks = buffer_get_int64(&m); - packets = buffer_get_int(&m); - packet_set_state(MODE_IN, seqnr, blocks, packets); + packet_set_seqnr(MODE_OUT, buffer_get_int(&m)); + packet_set_seqnr(MODE_IN, buffer_get_int(&m)); skip: /* Get the key context */ @@ -1552,79 +1598,3 @@ mon->m_recvfd = pair[0]; mon->m_sendfd = pair[1]; } - -#ifdef GSSAPI -int -mm_answer_gss_setup_ctx(int socket, Buffer *m) -{ - gss_OID_desc oid; - OM_uint32 major; - u_int len; - - oid.elements = buffer_get_string(m, &len); - oid.length = len; - - major = ssh_gssapi_server_ctx(&gsscontext, &oid); - - xfree(oid.elements); - - buffer_clear(m); - buffer_put_int(m, major); - - mm_request_send(socket,MONITOR_ANS_GSSSETUP, m); - - /* Now we have a context, enable the step */ - monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); - - return (0); -} - -int -mm_answer_gss_accept_ctx(int socket, Buffer *m) -{ - gss_buffer_desc in; - gss_buffer_desc out = GSS_C_EMPTY_BUFFER; - OM_uint32 major,minor; - OM_uint32 flags = 0; /* GSI needs this */ - u_int len; - - in.value = buffer_get_string(m, &len); - in.length = len; - major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); - xfree(in.value); - - buffer_clear(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); - - gss_release_buffer(&minor, &out); - - /* Complete - now we can do signing */ - if (major==GSS_S_COMPLETE) { - monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); - monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); - } - return (0); -} - -int -mm_answer_gss_userok(int socket, Buffer *m) -{ - int authenticated; - - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); - - buffer_clear(m); - buffer_put_int(m, authenticated); - - debug3("%s: sending result %d", __func__, authenticated); - mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); - - auth_method="gssapi"; - - /* Monitor loop will terminate if authenticated */ - return (authenticated); -} -#endif /* GSSAPI */