]> andersk Git - openssh.git/blobdiff - auth2-gss.c
- markus@cvs.openbsd.org 2003/11/17 11:06:07
[openssh.git] / auth2-gss.c
index 84fb384f95456bb9bae08f419282d457e688ba82..220862dc8f03c784359fc4d238761f1c35c9aec4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth2-gss.c,v 1.5 2003/11/02 11:01:03 markus Exp $    */
+/*     $OpenBSD: auth2-gss.c,v 1.6 2003/11/17 11:06:07 markus Exp $    */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -43,6 +43,7 @@
 extern ServerOptions options;
 
 static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
+static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
 static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
 static void input_gssapi_errtok(int, u_int32_t, void *);
 
@@ -129,7 +130,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        Gssctxt *gssctxt;
        gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
        gss_buffer_desc recv_tok;
-       OM_uint32 maj_status, min_status;
+       OM_uint32 maj_status, min_status, flags;
        u_int len;
 
        if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
@@ -142,7 +143,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        packet_check_eom();
 
        maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
-           &send_tok, NULL));
+           &send_tok, &flags));
 
        xfree(recv_tok.value);
 
@@ -154,7 +155,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
                }
                authctxt->postponed = 0;
                dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-               userauth_finish(authctxt, 0, "gssapi");
+               userauth_finish(authctxt, 0, "gssapi-with-mic");
        } else {
                if (send_tok.length != 0) {
                        packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -163,8 +164,13 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
                }
                if (maj_status == GSS_S_COMPLETE) {
                        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-                       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
-                                    &input_gssapi_exchange_complete);
+                       if (flags & GSS_C_INTEG_FLAG)
+                               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
+                                   &input_gssapi_mic);
+                       else
+                               dispatch_set(
+                                   SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+                                   &input_gssapi_exchange_complete);
                }
        }
 
@@ -224,9 +230,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
        gssctxt = authctxt->methoddata;
 
        /*
-        * We don't need to check the status, because the stored credentials
-        * which userok uses are only populated once the context init step
-        * has returned complete.
+        * We don't need to check the status, because we're only enabled in
+        * the dispatcher once the exchange is complete
         */
 
        packet_check_eom();
@@ -236,12 +241,53 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
        authctxt->postponed = 0;
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+}
+
+static void
+input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       int authenticated = 0;
+       Buffer b;
+       gss_buffer_desc mic, gssbuf;
+       u_int len;
+       
+       if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+               fatal("No authentication or GSSAPI context");
+       
+       gssctxt = authctxt->methoddata;
+       
+       mic.value = packet_get_string(&len);
+       mic.length = len;
+       
+       ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
+           "gssapi-with-mic");
+       
+       gssbuf.value = buffer_ptr(&b);
+       gssbuf.length = buffer_len(&b);
+       
+       if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
+               authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+       else
+               logit("GSSAPI MIC check failed");
+
+       buffer_free(&b);
+       xfree(mic.value);
+       
+       authctxt->postponed = 0;
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
-       userauth_finish(authctxt, authenticated, "gssapi");
+       userauth_finish(authctxt, authenticated, "gssapi-with-mic");
 }
 
 Authmethod method_gssapi = {
-       "gssapi",
+       "gssapi-with-mic",
        userauth_gssapi,
        &options.gss_authentication
 };
This page took 0.039537 seconds and 4 git commands to generate.