]> andersk Git - gssapi-openssh.git/commitdiff
o Merge in OPENSSH_3_4P1_GSI_20021008. OPENSSH_3_4P1_GSI_20021008_GPT-merged
authorcphillip <cphillip>
Tue, 8 Oct 2002 20:07:11 +0000 (20:07 +0000)
committercphillip <cphillip>
Tue, 8 Oct 2002 20:07:11 +0000 (20:07 +0000)
openssh/auth2-gss.c
openssh/gss-genr.c
openssh/kexgss.c
openssh/monitor.c
openssh/monitor.h
openssh/monitor_wrap.c
openssh/monitor_wrap.h
openssh/readconf.c
openssh/readconf.h
openssh/ssh_config.5
openssh/sshconnect2.c

index ddaf953eba9540ad5f8adf55651119e14478e0cd..c20796123a2516bb28fd8084528aa985cb64a176 100644 (file)
@@ -142,15 +142,6 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
                                                 &send_tok, NULL));
         packet_check_eom();
         
-        if (GSS_ERROR(maj_status)) {
-                /* Failure <sniff> */
-               ssh_gssapi_send_error(gssctxt->oid,maj_status,min_status);
-                authctxt->postponed = 0;
-               dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
-                dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-                userauth_finish(authctxt, 0, "gssapi");
-        }
-                        
         if (send_tok.length != 0) {
                 /* Send a packet back to the client */
                if (!compat20)
@@ -163,6 +154,19 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
                 gss_release_buffer(&min_status, &send_tok);        
         }
         
+        if (GSS_ERROR(maj_status)) {
+                /* Failure <sniff> */
+               if (gssctxt) {  /* may be NULL under privsep */
+                   ssh_gssapi_send_error(gssctxt->oid,maj_status,min_status);
+               } else {
+                   ssh_gssapi_send_error(GSS_C_NO_OID,maj_status,min_status);
+               }
+                authctxt->postponed = 0;
+               dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
+                dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+                userauth_finish(authctxt, 0, "gssapi");
+        }
+                        
         if (maj_status == GSS_S_COMPLETE) {
                dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
                 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
index ccd6d7e8558817f5eb5c9afe7acb3e317a249fd0..334536e0ab19ad4bf69808908507debd929c8fae 100644 (file)
@@ -110,7 +110,7 @@ ssh_gssapi_mechanisms(int server,char *host) {
 
        if (datafellows & SSH_OLD_GSSAPI) return NULL;
        
-       gss_indicate_mechs(&min_status, &supported);
+       PRIVSEP(gss_indicate_mechs(&min_status, &supported));
        
        buffer_init(&buf);      
 
@@ -169,7 +169,7 @@ void ssh_gssapi_supported_oids(gss_OID_set *oidset) {
        gss_OID_set supported;
        
        gss_create_empty_oid_set(&min_status,oidset);
-       gss_indicate_mechs(&min_status, &supported);
+       PRIVSEP(gss_indicate_mechs(&min_status, &supported));
 
        while (supported_mechs[i].name!=NULL) {
                if ((maj_status=gss_test_oid_set_member(&min_status,
@@ -260,10 +260,10 @@ ssh_gssapi_error_ex(gss_OID mech, OM_uint32 major_status,
         ctx = 0;
        /* The GSSAPI error */
         do {
-               lmaj = gss_display_status(&lmin, major_status,
-                                         GSS_C_GSS_CODE,
-                                         mech,
-                                         &ctx, &msg);
+               lmaj = PRIVSEP(gss_display_status(&lmin, major_status,
+                                                 GSS_C_GSS_CODE,
+                                                 mech,
+                                                 &ctx, &msg));
                if (lmaj == GSS_S_COMPLETE) {
                        debug((char *)msg.value);
                        if (send_packet) packet_send_debug((char *)msg.value);
@@ -273,10 +273,10 @@ ssh_gssapi_error_ex(gss_OID mech, OM_uint32 major_status,
 
         /* The mechanism specific error */
         do {
-               lmaj = gss_display_status(&lmin, minor_status,
-                                         GSS_C_MECH_CODE,
-                                         mech,
-                                         &ctx, &msg);
+               lmaj = PRIVSEP(gss_display_status(&lmin, minor_status,
+                                                 GSS_C_MECH_CODE,
+                                                 mech,
+                                                 &ctx, &msg));
                if (lmaj == GSS_S_COMPLETE) {
                        debug((char *)msg.value);
                        if (send_packet) packet_send_debug((char *)msg.value);
@@ -320,7 +320,9 @@ ssh_gssapi_build_ctx(Gssctxt **ctx)
 void
 ssh_gssapi_delete_ctx(Gssctxt **ctx)
 {
+#if !defined(MECHGLUE)
        OM_uint32 ms;
+#endif
        
        /* Return if there's no context */
        if ((*ctx)==NULL)
@@ -396,6 +398,7 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
                                gss_buffer_desc *send_tok, OM_uint32 *flags) 
 {
        OM_uint32 maj_status, min_status;
+       gss_OID mech;
        
        maj_status=gss_accept_sec_context(&min_status,
                                          &ctx->context,
@@ -403,7 +406,7 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
                                          recv_tok,
                                          GSS_C_NO_CHANNEL_BINDINGS,
                                          &ctx->client,
-                                         &ctx->oid,
+                                         &mech, /* read-only pointer */
                                          send_tok,
                                          flags,
                                          NULL,
@@ -507,7 +510,7 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) {
                                    &ctx->creds,
                                    NULL,
                                    NULL))) {
-               ssh_gssapi_error(GSS_C_NO_OID,maj_status,min_status);
+           ssh_gssapi_error(ctx->oid,maj_status,min_status);
        }
                                
        gss_release_oid_set(&min_status, &oidset);
@@ -525,7 +528,7 @@ ssh_gssapi_getclient(Gssctxt *ctx, enum ssh_gss_id *type,
        
        *type=ssh_gssapi_get_ctype(ctx);
        if ((maj_status=gss_display_name(&min_status,ctx->client,name,NULL))) {
-               ssh_gssapi_error(GSS_C_NO_OID,maj_status,min_status);
+               ssh_gssapi_error(ctx->oid,maj_status,min_status);
        }
        
        /* This is icky. There appears to be no way to copy this structure,
index 7d18b1a28bbf4b5c2987edb461ad84ab9b901154..d202a8766d39b8e1c631779e8e0785ecf89a8dd0 100644 (file)
@@ -371,18 +371,18 @@ kexgss_server(Kex *kex)
        } while (maj_status & GSS_S_CONTINUE_NEEDED);
 
        if (GSS_ERROR(maj_status)) {
-               ssh_gssapi_send_error(ctxt->oid,maj_status,min_status);
+               ssh_gssapi_send_error(oid,maj_status,min_status);
                packet_disconnect("gssapi key exchange handshake failed");
        }
 
        debug("gss_complete");
        if (!(ret_flags & GSS_C_MUTUAL_FLAG)) {
-               ssh_gssapi_send_error(ctxt->oid,maj_status,min_status);
+               ssh_gssapi_send_error(oid,maj_status,min_status);
                packet_disconnect("gssapi mutual authentication failed");
        }
                
        if (!(ret_flags & GSS_C_INTEG_FLAG)) {
-               ssh_gssapi_send_error(ctxt->oid,maj_status,min_status);
+               ssh_gssapi_send_error(oid,maj_status,min_status);
                packet_disconnect("gssapi channel integrity not established");
        }               
        
@@ -423,7 +423,11 @@ kexgss_server(Kex *kex)
        gssbuf.length = 20; /* Hashlen appears to always be 20 */
        
        if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) {
-               ssh_gssapi_send_error(ctxt->oid,maj_status,min_status);
+               if (ctxt) { /* may be NULL under privsep */
+                   ssh_gssapi_send_error(ctxt->oid,maj_status,min_status);
+               } else {
+                   ssh_gssapi_send_error(GSS_C_NO_OID,maj_status,min_status);
+               }
                packet_disconnect("Couldn't get MIC");
        }
        
index 582f0ca86026334706a1e264ebee8ca29e64ff05..38ee51befe35054d84e35976f6fd4e351f2bb6a0 100644 (file)
@@ -131,6 +131,8 @@ int mm_answer_gss_accept_ctx(int, Buffer *);
 int mm_answer_gss_userok(int, Buffer *);
 int mm_answer_gss_localname(int, Buffer *);
 int mm_answer_gss_sign(int, Buffer *);
+int mm_answer_gss_indicate_mechs(int, Buffer *);
+int mm_answer_gss_display_status(int, Buffer *);
 #endif
 
 #ifdef GSI
@@ -186,6 +188,8 @@ 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_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
+    {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
+    {MONITOR_REQ_GSSSTAT, MON_ISAUTH, mm_answer_gss_display_status},
     {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
     {MONITOR_REQ_GSSLOCALNAME, MON_AUTH, mm_answer_gss_localname},
 #endif
@@ -199,6 +203,8 @@ struct mon_table mon_dispatch_postauth20[] = {
     {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
     {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
     {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
+    {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs},
+    {MONITOR_REQ_GSSSTAT, 0, mm_answer_gss_display_status},
 #endif
     {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
     {MONITOR_REQ_SIGN, 0, mm_answer_sign},
@@ -230,6 +236,8 @@ struct mon_table mon_dispatch_proto15[] = {
     {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
     {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
     {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
+    {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
+    {MONITOR_REQ_GSSSTAT, MON_ISAUTH, mm_answer_gss_display_status},
 #endif
 #ifdef GSI
     {MONITOR_REQ_GSIGRIDMAP, MON_PERMIT, mm_answer_gsi_gridmap},
@@ -245,6 +253,8 @@ struct mon_table mon_dispatch_postauth15[] = {
     {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
     {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
     {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
+    {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs},
+    {MONITOR_REQ_GSSSTAT, 0, mm_answer_gss_display_status},
 #endif
     {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
     {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
@@ -302,6 +312,8 @@ monitor_child_preauth(struct monitor *pmonitor)
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1);
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTAT, 1);
 #endif
        } else {
                mon_dispatch = mon_dispatch_proto15;
@@ -309,6 +321,8 @@ monitor_child_preauth(struct monitor *pmonitor)
                monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
 #ifdef GSSAPI          
                monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1);
+               monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTAT, 1);
 #endif
 #ifdef GSI
                monitor_permit(mon_dispatch, MONITOR_REQ_GSIGRIDMAP, 1);
@@ -367,6 +381,9 @@ monitor_child_postauth(struct monitor *pmonitor)
                mon_dispatch = mon_dispatch_postauth15;
                monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
        }
+#ifdef GSSAPI          
+       monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTAT, 1);
+#endif
        if (!no_pty_flag) {
                monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
                monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
@@ -1710,6 +1727,65 @@ mm_answer_gss_sign(int socket, Buffer *m) {
         return(0);
 }
 
+int
+mm_answer_gss_indicate_mechs(int socket, Buffer *m) {
+        OM_uint32 major,minor;
+       gss_OID_set mech_set;
+       int i;
+
+       major=gss_indicate_mechs(&minor, &mech_set);
+
+       buffer_clear(m);
+       buffer_put_int(m, major);
+       buffer_put_int(m, mech_set->count);
+       for (i=0; i < mech_set->count; i++) {
+           buffer_put_string(m, mech_set->elements[i].elements,
+                             mech_set->elements[i].length);
+       }
+
+       mm_request_send(socket,MONITOR_ANS_GSSMECHS,m);
+
+       return(0);
+}
+
+int
+mm_answer_gss_display_status(int socket, Buffer *m) {
+        OM_uint32 major,minor,status_value,message_context;
+       int status_type;
+       gss_OID_desc mech_type_desc;
+       gss_OID mech_type;
+       gss_buffer_desc status_string;
+       u_int length;
+
+       status_value = buffer_get_int(m);
+       status_type = buffer_get_int(m);
+       mech_type_desc.elements = buffer_get_string(m, &length);
+       mech_type_desc.length = length;
+       if (length != 0) {
+           mech_type = &mech_type_desc;
+       } else if (gsscontext) {
+           mech_type = gsscontext->oid;
+       } else {
+           mech_type = GSS_C_NO_OID;
+       }
+       message_context = buffer_get_int(m);
+
+       major=gss_display_status(&minor, status_value, status_type, mech_type,
+                                &message_context, &status_string);
+
+       buffer_clear(m);
+       buffer_put_int(m, message_context);
+       buffer_put_string(m, status_string.value, status_string.length);
+
+       mm_request_send(socket,MONITOR_ANS_GSSSTAT,m);
+
+       if (mech_type_desc.elements) {
+           xfree(mech_type_desc.elements);
+       }
+
+       return 0;
+}
+
 #endif /* GSSAPI */
 
 #ifdef GSI
index c23eea4743d50cd9b2a4621a142008015c7f56c5..83e49864be88e760d350fdb871c3ed154933ff1a 100644 (file)
@@ -42,6 +42,8 @@ enum monitor_reqtype {
        MONITOR_REQ_GSSSETUP,MONITOR_ANS_GSSSETUP,
        MONITOR_REQ_GSSSTEP,MONITOR_ANS_GSSSTEP,
        MONITOR_REQ_GSSSIGN,MONITOR_ANS_GSSSIGN,
+       MONITOR_REQ_GSSMECHS,MONITOR_ANS_GSSMECHS,
+       MONITOR_REQ_GSSSTAT,MONITOR_ANS_GSSSTAT,
        MONITOR_REQ_GSSUSEROK,MONITOR_ANS_GSSUSEROK,
        MONITOR_REQ_GSSLOCALNAME,MONITOR_ANS_GSSLOCALNAME,
        MONITOR_REQ_GSIGRIDMAP,MONITOR_ANS_GSIGRIDMAP,
index 2f07edc4caf2b313b3b03ae910a40330af14f751..099a627f8cbbed6af25f5d9b6ed528b0bc799e37 100644 (file)
@@ -1043,6 +1043,72 @@ mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) {
 
         return(major);
 }
+
+OM_uint32
+mm_gss_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set)
+{
+        Buffer m;
+       OM_uint32 major;
+       int i=0;
+
+       buffer_init(&m);
+
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, &m);
+
+        debug3("%s: waiting for MONITOR_ANS_GSSMECHS",__func__);
+        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS,
+                                 &m);
+        major=buffer_get_int(&m);
+       *mech_set = xmalloc(sizeof(gss_OID_set_desc));
+        (*mech_set)->count=buffer_get_int(&m);
+       (*mech_set)->elements=xmalloc(sizeof(gss_OID_desc)*(*mech_set)->count);
+       for (i=0; i < (*mech_set)->count; i++) {
+           u_int length;
+           (*mech_set)->elements[i].elements=buffer_get_string(&m, &length);
+           (*mech_set)->elements[i].length = length;
+       }
+
+        return(major);
+}
+
+OM_uint32
+mm_gss_display_status(OM_uint32 *minor_status, OM_uint32 status_value,
+                     int status_type, const gss_OID mech_type,
+                     OM_uint32 *message_context, gss_buffer_t status_string)
+{
+        Buffer m;
+       OM_uint32 major;
+
+       buffer_init(&m);
+
+       buffer_put_int(&m, status_value);
+       buffer_put_int(&m, status_type);
+       if (mech_type) {
+           buffer_put_string(&m, mech_type->elements, mech_type->length);
+       } else {
+           buffer_put_string(&m, "", 0);
+       }
+       if (message_context) {
+           buffer_put_int(&m, *message_context);
+       } else {
+           buffer_put_int(&m, 0);
+       }
+
+       mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTAT, &m);
+
+        debug3("%s: waiting for MONITOR_ANS_GSSMECHS",__func__);
+        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTAT,
+                                 &m);
+       
+       if (message_context) {
+           *message_context = buffer_get_int(&m);
+       } else {
+           buffer_get_int(&m);
+       }
+       status_string->value = buffer_get_string(&m, &status_string->length);
+
+       return major;
+}
 #endif /* GSSAPI */
 
 #ifdef GSI
index cd8a042c45553718b76adefe861410a534010243..04491b459d58ff7f1f17b3f7aff654df1c538433 100644 (file)
@@ -68,6 +68,13 @@ OM_uint32 mm_ssh_gssapi_sign(Gssctxt *ctxt, gss_buffer_desc *buffer,
                             gss_buffer_desc *hash);
 int mm_ssh_gssapi_userok(char *user);
 int mm_ssh_gssapi_localname(char **user);
+OM_uint32 mm_gss_indicate_mechs(OM_uint32 *minor_status,
+                               gss_OID_set *mech_set);
+OM_uint32 mm_gss_display_status(OM_uint32 *minor_status,
+                               OM_uint32 status_value,
+                               int status_type, const gss_OID mech_type,
+                               OM_uint32 *message_context,
+                               gss_buffer_t status_string);
 #endif
 
 #ifdef GSI
index 30d4332d3864a24a413cd5961600f9dfa6181c4c..211075d6f94b17637726ad09fde75d4268a703af 100644 (file)
@@ -98,7 +98,7 @@ typedef enum {
        oKerberosAuthentication,
 #endif
 #ifdef GSSAPI
-       oGssAuthentication, oGssDelegateCreds,
+       oGssAuthentication, oGssKeyEx, oGssDelegateCreds,
 #ifdef GSI
        oGssGlobusDelegateLimitedCreds,
 #endif /* GSI */
@@ -151,6 +151,7 @@ static struct {
 #endif
 #ifdef GSSAPI
        { "gssapiauthentication", oGssAuthentication },
+       { "gssapikeyexchange", oGssKeyEx },
        { "gssapidelegatecredentials", oGssDelegateCreds },
 #ifdef GSI
        /* For backwards compatability with old 1.2.27 client code */
@@ -382,6 +383,10 @@ parse_flag:
                intptr = &options->gss_authentication;
                goto parse_flag;
       
+       case oGssKeyEx:
+               intptr = &options->gss_keyex;
+               goto parse_flag;
+
        case oGssDelegateCreds:
                intptr = &options->gss_deleg_creds;
                goto parse_flag;
@@ -781,6 +786,7 @@ initialize_options(Options * options)
        options->challenge_response_authentication = -1;
 #ifdef GSSAPI
         options->gss_authentication = -1;
+       options->gss_keyex = -1;
         options->gss_deleg_creds = -1;
 #ifdef GSI
         options->gss_globus_deleg_limited_proxy = -1;
@@ -866,6 +872,8 @@ fill_default_options(Options * options)
 #ifdef GSSAPI
        if (options->gss_authentication == -1)
                options->gss_authentication = 1;
+       if (options->gss_keyex == -1)
+               options->gss_keyex = 1;
        if (options->gss_deleg_creds == -1)
                options->gss_deleg_creds = 1;
 #ifdef GSI
index f370adfdac16cc67b68390031016fafcff829b61..74ae2fdb4404c3f390ba3de09b7792225f7f786c 100644 (file)
@@ -50,6 +50,7 @@ typedef struct {
 
 #ifdef GSSAPI
        int     gss_authentication;
+       int     gss_keyex;
        int     gss_deleg_creds;
 #ifdef GSI
        int     gss_globus_deleg_limited_proxy;
index c1796eb1c6288c388fa946a977f9b050eb0b56f4..aecc799535348abd6e334b81b723be2fe65d40f1 100644 (file)
@@ -311,6 +311,11 @@ the result of a successful key exchange, or using GSSAPI user
 authentication.
 The default is 
 .Dq yes .
+.It Cm GssapiKeyExchange
+Specifies whether key exchange based on GSSAPI may be used. When using
+GSSAPI key exchange the server need not have a host key.
+The default is
+.Dq yes .
 .It Cm GssapiDelegateCredentials
 Specifies whether GSSAPI credentials will be delegated (forwarded) to
 the server.
index 38cef29cfc391a5ea7caf648f31301bd5d80a86d..d525f64ac08d33030ce674dbfd4e2481471776e5 100644 (file)
@@ -90,6 +90,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        xxx_hostaddr = hostaddr;
 
 #ifdef GSSAPI
+       if (options.gss_keyex) {
        /* Add the GSSAPI mechanisms currently supported on this client to
         * the key exchange algorithm proposal */
        orig = myproposal[PROPOSAL_KEX_ALGS];
@@ -99,6 +100,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
           myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len);
           snprintf(myproposal[PROPOSAL_KEX_ALGS],len,"%s,%s",gss,orig);
        }
+       }
 #endif
 
        if (options.ciphers == (char *)-1) {
@@ -131,7 +133,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 #ifdef GSSAPI
         /* If we've got GSSAPI algorithms, then we also support the
          * 'null' hostkey, as a last resort */
-       if (gss) {
+       if (options.gss_keyex && gss) {
                orig=myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
                len = strlen(orig)+sizeof(",null");
                myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]=xmalloc(len);
@@ -496,17 +498,16 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
 int 
 userauth_gssapi(Authctxt *authctxt)
 {
-       int i;
        Gssctxt *gssctxt;
-       static int tries=0;
-
-       /* For now, we only make one attempt at this. We could try offering
-        * the server different GSSAPI OIDs until we get bored, I suppose.
-        */     
-       if (tries++>0) return 0;
+       static int mech=0;
 
        if (datafellows & SSH_OLD_GSSAPI) return 0;
        
+       /* Try each mechanism in turn.  Give up if we've tried all
+          supported mechanisms.
+        */
+       if (mech==GSS_LAST_ENTRY) return 0;
+       
        /* Initialise as much of our context as we can, so failures can be
         * trapped before sending any packets.
         */
@@ -536,17 +537,19 @@ userauth_gssapi(Authctxt *authctxt)
         * This may not be the case - we should use something along
         * the lines of the code in gss_genr to remove the ones that
         * aren't supported */
-       packet_put_int(GSS_LAST_ENTRY);
-       for (i=0;i<GSS_LAST_ENTRY;i++) {
-               packet_put_string(supported_mechs[i].oid.elements,
-                                 supported_mechs[i].oid.length);
-       }
+
+       /* Try one GSSAPI mechanism at a time. */
+       packet_put_int(1);
+       packet_put_string(supported_mechs[mech].oid.elements,
+                         supported_mechs[mech].oid.length);
         packet_send();
         packet_write_wait();
 
         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,&input_gssapi_response);
         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
        
+       mech++;                 /* Move to next mechanism for next time. */
+
         return 1;
 }
 
@@ -598,7 +601,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        u_int slen;
        
        if (authctxt == NULL)
-               fatal("input_gssapi_response: no authentication context");
+               fatal("input_gssapi_token: no authentication context");
        gssctxt = authctxt->methoddata;
        
        recv_tok.value=packet_get_string(&slen);
This page took 0.285352 seconds and 5 git commands to generate.