]> andersk Git - gssapi-openssh.git/blobdiff - openssh/gss-genr.c
pass in mechanism OID to gss_display_status() so mechglue can route the
[gssapi-openssh.git] / openssh / gss-genr.c
index 511a1830c3405cfaa673f0be5d83f7469a566d92..ccd6d7e8558817f5eb5c9afe7acb3e317a249fd0 100644 (file)
@@ -38,6 +38,7 @@
 #include "log.h"
 #include "compat.h"
 #include "monitor_wrap.h"
+#include "canohost.h"
 
 #include <netdb.h>
 
@@ -103,6 +104,7 @@ ssh_gssapi_mechanisms(int server,char *host) {
        Buffer          buf;
        int             i = 0;
        int             present;
+       int             mech_count=0;
        char *          mechs;
        Gssctxt *       ctx = NULL;     
 
@@ -128,13 +130,25 @@ ssh_gssapi_mechanisms(int server,char *host) {
                                                       &supported_mechs[i].oid,
                                                       host)))) {
                                /* Append gss_group1_sha1_x to our list */
+                               if (++mech_count > 1) {
+                                   buffer_append(&buf, ",", 1);
+                               }
                                buffer_append(&buf, gssprefix,
                                              strlen(gssprefix));
                                buffer_append(&buf, 
                                              supported_mechs[i].enc_name,
                                              strlen(supported_mechs[i].enc_name));
-                      }
-               }
+                               debug("GSSAPI mechanism %s (%s%s) supported",
+                                     supported_mechs[i].name, gssprefix,
+                                     supported_mechs[i].enc_name);
+                       } else {
+                           debug("no credentials for GSSAPI mechanism %s",
+                                 supported_mechs[i].name);
+                       }
+               } else {
+                   debug("GSSAPI mechanism %s not supported",
+                         supported_mechs[i].name);
+               }
        } while (supported_mechs[++i].name != NULL);
        
        buffer_put_char(&buf,'\0');
@@ -196,13 +210,14 @@ void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) {
 enum ssh_gss_id ssh_gssapi_get_ctype(Gssctxt *ctxt) {
        enum ssh_gss_id i=0;
        
-       while(supported_mechs[i].name!=NULL &&
-               supported_mechs[i].oid.length != ctxt->oid->length &&
-               (memcmp(supported_mechs[i].oid.elements,
-                      ctxt->oid->elements,ctxt->oid->length) !=0)) {
+       while(supported_mechs[i].name!=NULL) {
+          if (supported_mechs[i].oid.length == ctxt->oid->length &&
+              (memcmp(supported_mechs[i].oid.elements,
+                      ctxt->oid->elements,ctxt->oid->length) == 0))
+              return i;
           i++;
        }
-       return(i);
+       return(GSS_LAST_ENTRY);
 }
 
 /* Set the GSS context's OID to the oid indicated by the given key exchange
@@ -226,16 +241,20 @@ gss_OID ssh_gssapi_id_kex(Gssctxt *ctx, char *name) {
 
   if (ctx) ssh_gssapi_set_oid(ctx,&supported_mechs[i].oid);
 
+  debug("using GSSAPI mechanism %s (%s%s)", supported_mechs[i].name,
+       gssprefix, supported_mechs[i].enc_name);
+
   return &supported_mechs[i].oid;
 }
 
 
 /* All this effort to report an error ... */
 static void
-ssh_gssapi_error_ex(OM_uint32 major_status,OM_uint32 minor_status,
+ssh_gssapi_error_ex(gss_OID mech, OM_uint32 major_status,
+                   OM_uint32 minor_status,
                    int send_packet) {
        OM_uint32 lmaj, lmin;
-        gss_buffer_desc msg;
+        gss_buffer_desc msg = {0,NULL};
         OM_uint32 ctx;
         
         ctx = 0;
@@ -243,7 +262,7 @@ ssh_gssapi_error_ex(OM_uint32 major_status,OM_uint32 minor_status,
         do {
                lmaj = gss_display_status(&lmin, major_status,
                                          GSS_C_GSS_CODE,
-                                         GSS_C_NULL_OID,
+                                         mech,
                                          &ctx, &msg);
                if (lmaj == GSS_S_COMPLETE) {
                        debug((char *)msg.value);
@@ -256,7 +275,7 @@ ssh_gssapi_error_ex(OM_uint32 major_status,OM_uint32 minor_status,
         do {
                lmaj = gss_display_status(&lmin, minor_status,
                                          GSS_C_MECH_CODE,
-                                         GSS_C_NULL_OID,
+                                         mech,
                                          &ctx, &msg);
                if (lmaj == GSS_S_COMPLETE) {
                        debug((char *)msg.value);
@@ -267,13 +286,14 @@ ssh_gssapi_error_ex(OM_uint32 major_status,OM_uint32 minor_status,
 }
 
 void
-ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status) {
-    ssh_gssapi_error_ex(major_status, minor_status, 0);
+ssh_gssapi_error(gss_OID mech,OM_uint32 major_status,OM_uint32 minor_status) {
+    ssh_gssapi_error_ex(mech, major_status, minor_status, 0);
 }
 
 void
-ssh_gssapi_send_error(OM_uint32 major_status,OM_uint32 minor_status) {
-    ssh_gssapi_error_ex(major_status, minor_status, 1);
+ssh_gssapi_send_error(gss_OID mech,
+                     OM_uint32 major_status,OM_uint32 minor_status) {
+    ssh_gssapi_error_ex(mech, major_status, minor_status, 1);
 }
 
 
@@ -306,6 +326,7 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx)
        if ((*ctx)==NULL)
                return;
                
+#if !defined(MECHGLUE) /* mechglue has some memory management issues */
        if ((*ctx)->context != GSS_C_NO_CONTEXT) 
                gss_delete_sec_context(&ms,&(*ctx)->context,GSS_C_NO_BUFFER);
        if ((*ctx)->name != GSS_C_NO_NAME)
@@ -321,6 +342,7 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx)
                gss_release_name(&ms,&(*ctx)->client);  
        if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL)
                gss_release_cred(&ms,&(*ctx)->client_creds);
+#endif
        
        xfree(*ctx);
        *ctx=NULL; 
@@ -360,7 +382,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok,
                                        NULL);
        ctx->status=maj_status;
        if (GSS_ERROR(maj_status)) {
-               ssh_gssapi_error(maj_status,min_status);
+               ssh_gssapi_error(ctx->oid,maj_status,min_status);
        }
        return(maj_status);
 }
@@ -374,7 +396,6 @@ 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,
@@ -382,13 +403,13 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
                                          recv_tok,
                                          GSS_C_NO_CHANNEL_BINDINGS,
                                          &ctx->client,
-                                         &mech,
+                                         &ctx->oid,
                                          send_tok,
                                          flags,
                                          NULL,
                                          &ctx->client_creds);
        if (GSS_ERROR(maj_status)) {
-               ssh_gssapi_send_error(maj_status,min_status);
+               ssh_gssapi_send_error(ctx->oid,maj_status,min_status);
        }
        
        if (ctx->client_creds) {
@@ -421,27 +442,22 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
 /* Create a service name for the given host */
 OM_uint32
 ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
-       gss_buffer_desc gssbuf;
+       gss_buffer_desc gssbuf = {0,NULL};
        OM_uint32 maj_status, min_status;
-       struct hostent *hostinfo = NULL;
        char *xhost;
        
        /* Make a copy of the host name, in case it was returned by a
         * previous call to gethostbyname(). */ 
        xhost = xstrdup(host);
 
-       /* Make sure we have the FQDN. Some GSSAPI implementations don't do
+       /* If xhost is the loopback interface, switch it to our
+          true local hostname. */
+       resolve_localhost(&xhost);
+
+       /* Make sure we have the FQHN. Some GSSAPI implementations don't do
         * this for us themselves */
-       
-       hostinfo = gethostbyname(xhost);
-       
-       if ((hostinfo == NULL) || (hostinfo->h_name == NULL)) {
-               debug("Unable to get FQDN for \"%s\"", xhost);
-       } else {
-               xfree(xhost);
-               xhost = xstrdup(hostinfo->h_name);
-       }
-               
+       make_fqhn(&xhost);
+
         gssbuf.length = sizeof("host@")+strlen(xhost);
 
         gssbuf.value = xmalloc(gssbuf.length);
@@ -454,7 +470,7 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
                                        &gssbuf,
                                         GSS_C_NT_HOSTBASED_SERVICE,
                                         &ctx->name))) {
-               ssh_gssapi_error(maj_status,min_status);
+               ssh_gssapi_error(ctx->oid, maj_status,min_status);
        }
        
        xfree(xhost);
@@ -491,7 +507,7 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) {
                                    &ctx->creds,
                                    NULL,
                                    NULL))) {
-               ssh_gssapi_error(maj_status,min_status);
+               ssh_gssapi_error(GSS_C_NO_OID,maj_status,min_status);
        }
                                
        gss_release_oid_set(&min_status, &oidset);
@@ -509,7 +525,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(maj_status,min_status);
+               ssh_gssapi_error(GSS_C_NO_OID,maj_status,min_status);
        }
        
        /* This is icky. There appears to be no way to copy this structure,
@@ -534,13 +550,13 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) {
                                        buffer,
                                        NULL,
                                        hash)))
-                       ssh_gssapi_error(maj_status,min_status);
+                       ssh_gssapi_error(ctx->oid,maj_status,min_status);
        }
        else
 
        if ((maj_status=gss_get_mic(&min_status,ctx->context,
                                    GSS_C_QOP_DEFAULT, buffer, hash))) {
-               ssh_gssapi_error(maj_status,min_status);
+               ssh_gssapi_error(ctx->oid,maj_status,min_status);
        }
        
        return(maj_status);
@@ -556,7 +572,7 @@ ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid) {
 
 OM_uint32 
 ssh_gssapi_client_ctx(Gssctxt **ctx,gss_OID oid, char *host) {
-       gss_buffer_desc token;
+       gss_buffer_desc token = {0,NULL};
        OM_uint32 major,minor;
        
        if (*ctx) ssh_gssapi_delete_ctx(ctx);
This page took 0.12112 seconds and 4 git commands to generate.