]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2003/11/17 11:06:07
authordjm <djm>
Mon, 17 Nov 2003 11:18:21 +0000 (11:18 +0000)
committerdjm <djm>
Mon, 17 Nov 2003 11:18:21 +0000 (11:18 +0000)
     [auth2-gss.c gss-genr.c gss-serv.c monitor.c monitor.h monitor_wrap.c]
     [monitor_wrap.h sshconnect2.c ssh-gss.h]
     replace "gssapi" with "gssapi-with-mic"; from Simon Wilkinson;
     test + ok jakob.

ChangeLog
auth2-gss.c
gss-genr.c
gss-serv.c
monitor.c
monitor.h
monitor_wrap.c
monitor_wrap.h
ssh-gss.h
sshconnect2.c

index ba08383f1e2f1ef326e80f547cd3ca7d535a45c2..aa5dc838501e514c01cbfdf4799e5bf6265c7e43 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - djm@cvs.openbsd.org 2003/11/17 09:45:39
      [msg.c msg.h sshconnect2.c ssh-keysign.c]
      return error on msg send/receive failure (rather than fatal); ok markus@
+   - markus@cvs.openbsd.org 2003/11/17 11:06:07
+     [auth2-gss.c gss-genr.c gss-serv.c monitor.c monitor.h monitor_wrap.c]
+     [monitor_wrap.h sshconnect2.c ssh-gss.h]
+     replace "gssapi" with "gssapi-with-mic"; from Simon Wilkinson; 
+     test + ok jakob.
  - (djm) Bug #632: Don't call pam_end indirectly from within kbd-int
    conversation function
  - (djm) Export environment variables from authentication subprocess to 
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
 };
index bda12d6f1b5d12cb1eeb81f243fa77a049bc6fe6..6b7caad0e7b3bdd3614a18f5a7c5819dfc1253ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $     */
+/*     $OpenBSD: gss-genr.c,v 1.2 2003/11/17 11:06:07 markus Exp $     */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 #include "compat.h"
 #include "log.h"
 #include "monitor_wrap.h"
+#include "ssh2.h"
 
 #include "ssh-gss.h"
 
+extern u_char *session_id2;
+extern u_int session_id2_len;
 
 /* Check that the OID in a data stream matches that in the context */
 int
@@ -244,6 +247,28 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
        return (ctx->major);
 }
 
+OM_uint32
+ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
+{
+       if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
+           GSS_C_QOP_DEFAULT, buffer, hash)))
+               ssh_gssapi_error(ctx);
+       
+       return (ctx->major);
+}
+
+void
+ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, 
+    const char *context) 
+{      
+       buffer_init(b);
+       buffer_put_string(b, session_id2, session_id2_len);
+       buffer_put_char(b, SSH2_MSG_USERAUTH_REQUEST);
+       buffer_put_cstring(b, user);
+       buffer_put_cstring(b, service);
+       buffer_put_cstring(b, context);
+}
+
 OM_uint32
 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
        if (*ctx)
index 6574f9750b4af0b22fdf59e3104bd1647643bc37..de32a3f2ea03c5fb9bd3ddb889058669c8803a3b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-serv.c,v 1.4 2003/09/23 20:17:11 markus Exp $     */
+/*     $OpenBSD: gss-serv.c,v 1.5 2003/11/17 11:06:07 markus Exp $     */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -287,4 +287,14 @@ ssh_gssapi_userok(char *user)
        return (0);
 }
 
+/* Priviledged */
+OM_uint32
+ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
+{
+       ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
+           gssbuf, gssmic, NULL);
+
+       return (ctx->major);
+}
+
 #endif
index e83fb45a7c27ad2d1f0f7f543a47ecd6ddd22fc6..97f1ee9f4c16c920e8727a5232ce951b269a0420 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.51 2003/11/04 08:54:09 djm Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.52 2003/11/17 11:06:07 markus Exp $");
 
 #include <openssl/dh.h>
 
@@ -134,6 +134,7 @@ int mm_answer_pam_free_ctx(int, Buffer *);
 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 *);
 #endif
 
 static Authctxt *authctxt;
@@ -193,6 +194,7 @@ struct mon_table mon_dispatch_proto20[] = {
     {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}
 };
@@ -1781,14 +1783,42 @@ mm_answer_gss_accept_ctx(int socket, Buffer *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);
+               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)
 {
@@ -1802,7 +1832,7 @@ mm_answer_gss_userok(int socket, Buffer *m)
        debug3("%s: sending result %d", __func__, authenticated);
        mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
 
-       auth_method="gssapi";
+       auth_method="gssapi-with-mic";
 
        /* Monitor loop will terminate if authenticated */
        return (authenticated);
index a153f416879548e5a61f3d5e3b72611f843edcd0..621a4ad1816240319c3809258b3b91dc75784095 100644 (file)
--- a/monitor.h
+++ b/monitor.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor.h,v 1.12 2003/09/23 20:17:11 markus Exp $     */
+/*     $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $     */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -52,6 +52,7 @@ enum monitor_reqtype {
        MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
        MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
        MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
+       MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
        MONITOR_REQ_PAM_START,
        MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
        MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
index fe14604226b90d489f083aa7337850343b07c62d..c685535d3adc4915450da9f156b2ceea9ebdbb5c 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_wrap.c,v 1.34 2003/10/15 09:48:45 markus Exp $");
+RCSID("$OpenBSD: monitor_wrap.c,v 1.35 2003/11/17 11:06:07 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
@@ -1134,6 +1134,25 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
        return (major);
 }
 
+OM_uint32
+mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
+{
+       Buffer m;
+       OM_uint32 major;
+
+       buffer_init(&m);
+       buffer_put_string(&m, gssbuf->value, gssbuf->length);
+       buffer_put_string(&m, gssmic->value, gssmic->length);
+
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
+       mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
+           &m);
+
+       major = buffer_get_int(&m);
+       buffer_free(&m);
+       return(major);
+}
+
 int
 mm_ssh_gssapi_userok(char *user)
 {
index 76c02f13aed662b2fb445f57a23ccdd90586fe19..55be10b195149c04516b1cf1ecfeec4e5548de26 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor_wrap.h,v 1.12 2003/09/23 20:17:11 markus Exp $        */
+/*     $OpenBSD: monitor_wrap.h,v 1.13 2003/11/17 11:06:07 markus Exp $        */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -62,6 +62,7 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt,
    gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags);
 int mm_ssh_gssapi_userok(char *user);
+OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
 #endif
 
 #ifdef USE_PAM
index c76648ee0b5433f5d194a2469ddd709cce75a3b7..2b6fe21306202c28c674e6515bf9d833ba95a61b 100644 (file)
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh-gss.h,v 1.3 2003/10/02 08:26:53 markus Exp $      */
+/*     $OpenBSD: ssh-gss.h,v 1.4 2003/11/17 11:06:07 markus Exp $      */
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
@@ -50,6 +50,7 @@
 #define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE     63
 #define SSH2_MSG_USERAUTH_GSSAPI_ERROR                 64
 #define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK                        65
+#define SSH2_MSG_USERAUTH_GSSAPI_MIC                   66
 
 #define SSH_GSS_OIDTYPE 0x06
 
@@ -108,11 +109,13 @@ void ssh_gssapi_error(Gssctxt *ctx);
 char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
 void ssh_gssapi_build_ctx(Gssctxt **ctx);
 void ssh_gssapi_delete_ctx(Gssctxt **ctx);
+OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid);
+void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
 
 /* In the server */
 int ssh_gssapi_userok(char *name);
-
+OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
 void ssh_gssapi_do_child(char ***envp, u_int *envsizep);
 void ssh_gssapi_cleanup_creds(void);
 void ssh_gssapi_storecreds(void);
index 388a25741d7b976c44270ea80888bf3fe9e969f0..f6368aadd31189961d26f9c854048aef9958df77 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.131 2003/11/17 09:45:39 djm Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.132 2003/11/17 11:06:07 markus Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -222,7 +222,7 @@ static char *authmethods_get(void);
 
 Authmethod authmethods[] = {
 #ifdef GSSAPI
-       {"gssapi",
+       {"gssapi-with-mic",
                userauth_gssapi,
                &options.gss_authentication,
                NULL},
@@ -543,10 +543,12 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
        Authctxt *authctxt = ctxt;
        Gssctxt *gssctxt = authctxt->methoddata;
        gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
-       OM_uint32 status, ms;
+       gss_buffer_desc gssbuf, mic;
+       OM_uint32 status, ms, flags;
+       Buffer b;
        
        status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
-           recv_tok, &send_tok, NULL);
+           recv_tok, &send_tok, &flags);
 
        if (send_tok.length > 0) {
                if (GSS_ERROR(status))
@@ -560,9 +562,29 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
        }
        
        if (status == GSS_S_COMPLETE) {
-               /* If that succeeded, send a exchange complete message */
-               packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
-               packet_send();
+               /* send either complete or MIC, depending on mechanism */
+               if (!(flags & GSS_C_INTEG_FLAG)) {
+                       packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
+                       packet_send();
+               } else {
+                       ssh_gssapi_buildmic(&b, authctxt->server_user,
+                           authctxt->service, "gssapi-with-mic");
+
+                       gssbuf.value = buffer_ptr(&b);
+                       gssbuf.length = buffer_len(&b);
+                       
+                       status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
+                       
+                       if (!GSS_ERROR(status)) {
+                               packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
+                               packet_put_string(mic.value, mic.length);
+                               
+                               packet_send();
+                       }
+                               
+                       buffer_free(&b);
+                       gss_release_buffer(&ms, &mic);
+               }          
        }
        
        return status;
This page took 0.615128 seconds and 5 git commands to generate.