=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/monitor.c,v retrieving revision 1.34.2.2 retrieving revision 1.35 diff -u -r1.34.2.2 -r1.35 --- src/usr.bin/ssh/monitor.c 2004/03/04 18:18:15 1.34.2.2 +++ src/usr.bin/ssh/monitor.c 2003/04/01 10:10:23 1.35 @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.34.2.2 2004/03/04 18:18:15 brad Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.35 2003/04/01 10:10:23 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,12 +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 *); -int mm_answer_gss_checkmic(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 */ @@ -138,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; @@ -173,12 +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}, - {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, -#endif {0, 0, NULL} }; @@ -208,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} }; @@ -249,17 +243,14 @@ } } -void -monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) +Authctxt * +monitor_child_preauth(struct monitor *pmonitor) { struct mon_table *ent; int authenticated = 0; debug3("preauth child monitor started"); - authctxt = _authctxt; - memset(authctxt, 0, sizeof(*authctxt)); - if (compat20) { mon_dispatch = mon_dispatch_proto20; @@ -272,6 +263,8 @@ monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); } + authctxt = authctxt_new(); + /* The first few requests do not require asynchronous access */ while (!authenticated) { authenticated = monitor_read(pmonitor, mon_dispatch, &ent); @@ -299,27 +292,13 @@ __func__, authctxt->user); mm_get_keystate(pmonitor); -} -static void -monitor_set_child_handler(pid_t pid) -{ - monitor_child_pid = pid; + return (authctxt); } -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; @@ -327,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); @@ -530,7 +510,6 @@ if (pwent == NULL) { buffer_put_char(m, 0); - authctxt->pw = fakepw(); goto out; } @@ -608,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); @@ -771,7 +750,7 @@ debug3("%s: key_from_blob: %p", __func__, key); - if (key != NULL && authctxt->valid) { + if (key != NULL && authctxt->pw != NULL) { switch(type) { case MM_USERKEY: allowed = options.pubkey_authentication && @@ -856,7 +835,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++; } @@ -904,7 +883,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++; } @@ -1009,21 +988,22 @@ if (getpeername(packet_get_connection_in(), (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); - cleanup_exit(255); + fatal_cleanup(); } } /* 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); session_pty_cleanup2(s); } s->used = 0; @@ -1048,6 +1028,7 @@ res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; + fatal_add_cleanup(session_pty_cleanup2, (void *)s); pty_setowner(authctxt->pw, s->tty); buffer_put_int(m, 1); @@ -1283,7 +1264,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; @@ -1525,7 +1589,6 @@ mon = xmalloc(sizeof(*mon)); - mon->m_pid = 0; monitor_socketpair(pair); mon->m_recvfd = pair[0]; @@ -1553,107 +1616,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); - - 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); - } - return (0); -} - -int -mm_answer_gss_checkmic(int socket, 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); - - if (!GSS_ERROR(ret)) - 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-with-mic"; - - /* Monitor loop will terminate if authenticated */ - return (authenticated); -} -#endif /* GSSAPI */