]> andersk Git - gssapi-openssh.git/blobdiff - openssh/kexgsss.c
merge of OPENSSH_3_6_1P1_SIMON_20030411
[gssapi-openssh.git] / openssh / kexgsss.c
index ea17b2d15fbb93cb43cb8a7013d474fe69399eb8..7cb068da008721aedc1c2c5b70cd1be003c39395 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001,2002 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "ssh2.h"
 #include "ssh-gss.h"
 #include "monitor_wrap.h"
-#include "canohost.h"
+
+static void kex_gss_send_error(Gssctxt *ctxt);
 
 void
 kexgss_server(Kex *kex)
 {
-
        OM_uint32 maj_status, min_status;
        
        /* Some GSSAPI implementations use the input value of ret_flags (an
-        * output variable) as a means of triggering mechanism specific 
-        * features. Initializing it to zero avoids inadvertently 
-        * activating this non-standard behaviour.*/
+       * output variable) as a means of triggering mechanism specific 
+       * features. Initializing it to zero avoids inadvertently 
+       * activating this non-standard behaviour.*/
 
        OM_uint32 ret_flags = 0;
        gss_buffer_desc gssbuf,send_tok,recv_tok,msg_tok;
@@ -62,8 +62,8 @@ kexgss_server(Kex *kex)
         BIGNUM *shared_secret = NULL;
         BIGNUM *dh_client_pub = NULL;
        int type =0;
-       gss_OID oid;
        u_int slen;
+       gss_OID oid;
        
        /* Initialise GSSAPI */
 
@@ -75,9 +75,11 @@ kexgss_server(Kex *kex)
        
        debug2("%s: Acquiring credentials",__func__);
        
-       if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,oid))))
-          packet_disconnect("Unable to acquire credentials for the server");
-
+       if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt,oid)))) {
+               kex_gss_send_error(ctxt);
+               packet_disconnect("Unable to acquire credentials for the server");
+        }
+                                                                                                                                
        do {
                debug("Wait SSH2_MSG_GSSAPI_INIT");
                type = packet_read();
@@ -91,7 +93,7 @@ kexgss_server(Kex *kex)
                        dh_client_pub = BN_new();
                        
                        if (dh_client_pub == NULL)
-                               fatal("dh_client_pub == NULL");
+                               packet_disconnect("dh_client_pub == NULL");
                        packet_get_bignum2(dh_client_pub);
                        
                        /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
@@ -108,17 +110,18 @@ kexgss_server(Kex *kex)
                }
                
                maj_status=PRIVSEP(ssh_gssapi_accept_ctx(ctxt,&recv_tok, 
-                                                        &send_tok, &ret_flags));
+                                                       &send_tok, &ret_flags));
 
                gss_release_buffer(&min_status,&recv_tok);
-
+               
 #ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
                 if (ret_flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG) {
                         packet_disconnect("Limited proxy is not allowed in gssapi key exchange.");
                 }
 #endif
-               
-               if (maj_status & GSS_S_CONTINUE_NEEDED) {
+
+               if ((maj_status & GSS_S_CONTINUE_NEEDED) ||
+                   (GSS_ERROR(maj_status) && send_tok.length>0)) {
                        debug("Sending GSSAPI_CONTINUE");
                        packet_start(SSH2_MSG_KEXGSS_CONTINUE);
                        packet_put_string(send_tok.value,send_tok.length);
@@ -129,21 +132,17 @@ kexgss_server(Kex *kex)
        } while (maj_status & GSS_S_CONTINUE_NEEDED);
 
        if (GSS_ERROR(maj_status)) {
-               ssh_gssapi_send_error(oid,maj_status,min_status);
+               kex_gss_send_error(ctxt);
                packet_disconnect("gssapi key exchange handshake failed");
        }
-
+       
        debug("gss_complete");
-       if (!(ret_flags & GSS_C_MUTUAL_FLAG)) {
-               ssh_gssapi_send_error(oid,maj_status,min_status);
-               packet_disconnect("gssapi mutual authentication failed");
-       }
+       if (!(ret_flags & GSS_C_MUTUAL_FLAG))
+               packet_disconnect("gssapi_mutual authentication failed");
                
-       if (!(ret_flags & GSS_C_INTEG_FLAG)) {
-               ssh_gssapi_send_error(oid,maj_status,min_status);
+       if (!(ret_flags & GSS_C_INTEG_FLAG))
                packet_disconnect("gssapi channel integrity not established");
-       }               
-       
+                       
        dh = dh_new_group1();
        dh_gen_key(dh, kex->we_need * 8);
        
@@ -159,7 +158,8 @@ kexgss_server(Kex *kex)
        memset(kbuf, 0, klen);
        xfree(kbuf);
        
-        hash = kex_gssapi_hash(
+       /* The GSSAPI hash is identical to the Diffie Helman one */
+        hash = kex_dh_hash(
             kex->client_version_string,
             kex->server_version_string,
             buffer_ptr(&kex->peer), buffer_len(&kex->peer),
@@ -181,12 +181,8 @@ kexgss_server(Kex *kex)
        gssbuf.length = 20; /* Hashlen appears to always be 20 */
        
        if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) {
-               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");
+               kex_gss_send_error(ctxt);
+               fatal("Couldn't get MIC");
        }
        
        packet_start(SSH2_MSG_KEXGSS_COMPLETE);
@@ -210,7 +206,7 @@ kexgss_server(Kex *kex)
        gss_release_buffer(&min_status, &send_tok);     
 
        /* If we've got a context, delete it. It may be NULL if we've been
-        * using privsep */
+       * using privsep */
        ssh_gssapi_delete_ctx(&ctxt);
        
        DH_free(dh);
@@ -220,4 +216,22 @@ kexgss_server(Kex *kex)
        kex_finish(kex);
 }
 
+static void 
+kex_gss_send_error(Gssctxt *ctxt) {
+       char *errstr;
+       OM_uint32 maj,min;
+               
+       errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min));
+       if (errstr) {
+               packet_start(SSH2_MSG_KEXGSS_ERROR);
+               packet_put_int(maj);
+               packet_put_int(min);
+               packet_put_cstring(errstr);
+               packet_put_cstring("");
+               packet_send();
+               packet_write_wait();
+               /* XXX - We should probably log the error locally here */
+               xfree(errstr);
+       }
+}
 #endif /* GSSAPI */
This page took 0.072486 seconds and 4 git commands to generate.