]> andersk Git - gssapi-openssh.git/blobdiff - openssh/gss-genr.c
merged Simon's openssh-3.4p1-gssapi-20020627.diff patch to the trunk:
[gssapi-openssh.git] / openssh / gss-genr.c
index afd02821856e2f7805a7931ef2061367413dc090..511a1830c3405cfaa673f0be5d83f7469a566d92 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 Simon Wilkinson. All rights reserved. *
+ * Copyright (c) 2001,2002 Simon Wilkinson. All rights reserved. *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -37,6 +37,7 @@
 #include "kex.h"
 #include "log.h"
 #include "compat.h"
+#include "monitor_wrap.h"
 
 #include <netdb.h>
 
@@ -49,6 +50,8 @@ gss_buffer_desc gssapi_client_name = {0,NULL}; /* Name of our client */
 gss_cred_id_t   gssapi_client_creds = GSS_C_NO_CREDENTIAL; /* Their credentials */
 enum ssh_gss_id gssapi_client_type = GSS_LAST_ENTRY;
 
+unsigned char ssh1_key_digest[16]; /* used for ssh1 gssapi */
+
 /* The mechanism name used in the list below is defined in the internet
  * draft as the Base 64 encoding of the MD5 hash of the ASN.1 DER encoding 
  * of the underlying GSSAPI mechanism's OID.
@@ -101,8 +104,7 @@ ssh_gssapi_mechanisms(int server,char *host) {
        int             i = 0;
        int             present;
        char *          mechs;
-       Gssctxt         ctx;    
-       gss_buffer_desc token;          
+       Gssctxt *       ctx = NULL;     
 
        if (datafellows & SSH_OLD_GSSAPI) return NULL;
        
@@ -118,33 +120,21 @@ ssh_gssapi_mechanisms(int server,char *host) {
                        present=0;
                }
                if (present) {
-                       ssh_gssapi_build_ctx(&ctx);
-                       ssh_gssapi_set_oid(&ctx,&supported_mechs[i].oid);
-                       if (server) {
-                               if (ssh_gssapi_acquire_cred(&ctx)) {
-                                       ssh_gssapi_delete_ctx(&ctx);
-                                       continue;
-                               }
-                       }
-                       else { /* client */
-                               if (ssh_gssapi_import_name(&ctx,host))
-                                       continue;
-                               maj_status=ssh_gssapi_init_ctx(&ctx, 0, 
-                                                              GSS_C_NO_BUFFER,
-                                                              &token,
-                                                              NULL);
-                               ssh_gssapi_delete_ctx(&ctx);
-                               if (GSS_ERROR(maj_status)) {
-                                       continue;
-                               }
-                       }                                
-                               
-                       /* Append gss_group1_sha1_x to our list */
-                       buffer_append(&buf, gssprefix,
-                                     strlen(gssprefix));
-                       buffer_append(&buf, supported_mechs[i].enc_name,
-                                     strlen(supported_mechs[i].enc_name));
-               }
+                       if ((server && 
+                            !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx,
+                                                           &supported_mechs[i].oid)))) 
+                           || (!server &&
+                               !GSS_ERROR(ssh_gssapi_client_ctx(&ctx,
+                                                      &supported_mechs[i].oid,
+                                                      host)))) {
+                               /* Append gss_group1_sha1_x to our list */
+                               buffer_append(&buf, gssprefix,
+                                             strlen(gssprefix));
+                               buffer_append(&buf, 
+                                             supported_mechs[i].enc_name,
+                                             strlen(supported_mechs[i].enc_name));
+                      }
+               }
        } while (supported_mechs[++i].name != NULL);
        
        buffer_put_char(&buf,'\0');
@@ -217,11 +207,11 @@ enum ssh_gss_id ssh_gssapi_get_ctype(Gssctxt *ctxt) {
 
 /* Set the GSS context's OID to the oid indicated by the given key exchange
  * name. */
-int ssh_gssapi_id_kex(Gssctxt *ctx, char *name) {
+gss_OID ssh_gssapi_id_kex(Gssctxt *ctx, char *name) {
   enum ssh_gss_id i=0;
   
   if (strncmp(name, gssprefix, strlen(gssprefix)-1) !=0) {
-     return(1);
+     return(NULL);
   }
   
   name+=strlen(gssprefix); /* Move to the start of the MIME string */
@@ -232,11 +222,11 @@ int ssh_gssapi_id_kex(Gssctxt *ctx, char *name) {
   }
 
   if (supported_mechs[i].name==NULL)
-     return (1);
+     return (NULL);
 
-  ssh_gssapi_set_oid(ctx,&supported_mechs[i].oid);
+  if (ctx) ssh_gssapi_set_oid(ctx,&supported_mechs[i].oid);
 
-  return 0;
+  return &supported_mechs[i].oid;
 }
 
 
@@ -295,37 +285,45 @@ ssh_gssapi_send_error(OM_uint32 major_status,OM_uint32 minor_status) {
  * stuff life is a little easier
  */
 void
-ssh_gssapi_build_ctx(Gssctxt *ctx)
+ssh_gssapi_build_ctx(Gssctxt **ctx)
 {
-       ctx->context=GSS_C_NO_CONTEXT;
-       ctx->name=GSS_C_NO_NAME;
-       ctx->oid=GSS_C_NO_OID;
-       ctx->creds=GSS_C_NO_CREDENTIAL;
-       ctx->client=GSS_C_NO_NAME;
-       ctx->client_creds=GSS_C_NO_CREDENTIAL;
+       *ctx=xmalloc(sizeof (Gssctxt));
+       (*ctx)->context=GSS_C_NO_CONTEXT;
+       (*ctx)->name=GSS_C_NO_NAME;
+       (*ctx)->oid=GSS_C_NO_OID;
+       (*ctx)->creds=GSS_C_NO_CREDENTIAL;
+       (*ctx)->client=GSS_C_NO_NAME;
+       (*ctx)->client_creds=GSS_C_NO_CREDENTIAL;
 }
 
 /* Delete our context, providing it has been built correctly */
 void
-ssh_gssapi_delete_ctx(Gssctxt *ctx)
+ssh_gssapi_delete_ctx(Gssctxt **ctx)
 {
        OM_uint32 ms;
        
-       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)
-               gss_release_name(&ms,&ctx->name);
-       if (ctx->oid != GSS_C_NO_OID) {
-               xfree(ctx->oid->elements);
-               xfree(ctx->oid);
-               ctx->oid = GSS_C_NO_OID;
+       /* Return if there's no context */
+       if ((*ctx)==NULL)
+               return;
+               
+       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)
+               gss_release_name(&ms,&(*ctx)->name);
+       if ((*ctx)->oid != GSS_C_NO_OID) {
+               xfree((*ctx)->oid->elements);
+               xfree((*ctx)->oid);
+               (*ctx)->oid = GSS_C_NO_OID;
        }
-       if (ctx->creds != GSS_C_NO_CREDENTIAL)
-               gss_release_cred(&ms,&ctx->creds);
-       if (ctx->client != GSS_C_NO_NAME)
-               gss_release_name(&ms,&ctx->client);     
-       if (ctx->client_creds != GSS_C_NO_CREDENTIAL)
-               gss_release_cred(&ms,&ctx->client_creds); 
+       if ((*ctx)->creds != GSS_C_NO_CREDENTIAL)
+               gss_release_cred(&ms,&(*ctx)->creds);
+       if ((*ctx)->client != GSS_C_NO_NAME)
+               gss_release_name(&ms,&(*ctx)->client);  
+       if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL)
+               gss_release_cred(&ms,&(*ctx)->client_creds);
+       
+       xfree(*ctx);
+       *ctx=NULL; 
 }
 
 /* Wrapper to init_sec_context 
@@ -399,11 +397,24 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
                debug("Got no client credentials");
        }
 
-       /* FIXME: We should check that the mechanism thats being used is
+       /* FIXME: We should check that the me
         * the one that we asked for (in ctx->oid) */
 
        ctx->status=maj_status;
        
+       /* Now, if we're complete and we have the right flags, then
+        * we flag the user as also having been authenticated
+        */
+       
+       if (((flags==NULL) || ((*flags & GSS_C_MUTUAL_FLAG) && 
+                              (*flags & GSS_C_INTEG_FLAG))) &&
+           (maj_status == GSS_S_COMPLETE)) {
+               if (ssh_gssapi_getclient(ctx,&gssapi_client_type,
+                                        &gssapi_client_name,
+                                        &gssapi_client_creds))
+                       fatal("Couldn't convert client name");
+       }
+
        return(maj_status);
 }
 
@@ -453,7 +464,9 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
 
 /* Acquire credentials for a server running on the current host.
  * Requires that the context structure contains a valid OID
- */      
+ */
+/* Returns a GSSAPI error code */
 OM_uint32
 ssh_gssapi_acquire_cred(Gssctxt *ctx) {
        OM_uint32 maj_status, min_status;
@@ -507,5 +520,52 @@ ssh_gssapi_getclient(Gssctxt *ctx, enum ssh_gss_id *type,
        ctx->client_creds=GSS_C_NO_CREDENTIAL;
        return(maj_status);
 }
+
+OM_uint32
+ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) {
+       OM_uint32 maj_status,min_status;
        
+       /* ssh1 needs to exchange the hash of the keys */
+       /* will us this hash to return it */
+       if (!compat20) {
+               if ((maj_status=gss_wrap(&min_status,ctx->context,
+                                       0,
+                                       GSS_C_QOP_DEFAULT,
+                                       buffer,
+                                       NULL,
+                                       hash)))
+                       ssh_gssapi_error(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);
+       }
+       
+       return(maj_status);
+}
+
+OM_uint32
+ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid) {
+       if (*ctx) ssh_gssapi_delete_ctx(ctx);
+       ssh_gssapi_build_ctx(ctx);
+       ssh_gssapi_set_oid(*ctx,oid);
+       return(ssh_gssapi_acquire_cred(*ctx));
+}
+
+OM_uint32 
+ssh_gssapi_client_ctx(Gssctxt **ctx,gss_OID oid, char *host) {
+       gss_buffer_desc token;
+       OM_uint32 major,minor;
+       
+       if (*ctx) ssh_gssapi_delete_ctx(ctx);
+       ssh_gssapi_build_ctx(ctx);
+       ssh_gssapi_set_oid(*ctx,oid);
+       ssh_gssapi_import_name(*ctx,host);
+       major=ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, NULL);
+       gss_release_buffer(&minor,&token);
+       return(major);
+}
+                                                                                        
 #endif /* GSSAPI */
This page took 0.046123 seconds and 4 git commands to generate.