]> andersk Git - gssapi-openssh.git/commitdiff
revision: solve the compilation problem when both GSI and Kerberos are supported... OPENSSH_GSSAPI_MULTI-branch
authorbhe <bhe>
Mon, 8 Jul 2002 17:37:35 +0000 (17:37 +0000)
committerbhe <bhe>
Mon, 8 Jul 2002 17:37:35 +0000 (17:37 +0000)
gss-serv.c and ssh-gss.h are modified
gssapi_krb.h and globus_gss_assist_gsi.h are added
gssapi_krb.h is the merged gssapi.h files of GSI library and Kerberos library
globus_gss_assist_gsi.h is same as the original header file globus_gss_assist.h except it includes the new gssapi_krb.h.
gss-serv.c includes new header file and reorganize the order of GSSAPI authentication order in ssh_gssapi_storecreds
ssh-gss.h includes new header file and reorganize the order of GSSAPI authentication order in ssh_gss_id

openssh/gss-serv.c
openssh/ssh-gss.h

index b29df32fa64ef9581631f43abf5b107cbc690a3a..ceef7dc7054cdff1c958b1bf9d93db444441c07c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001,2002 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001 Simon Wilkinson. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,6 @@
 #include "servconf.h"
 #include "compat.h"
 #include "misc.h"
-#include "monitor_wrap.h"
 
 #include "ssh-gss.h"
 
@@ -53,6 +52,9 @@ extern ServerOptions options;
 extern u_char *session_id2;
 extern int session_id2_len;
 
+void    userauth_reply(Authctxt *authctxt, int authenticated);
+static void gssapi_unsetenv(const char *var);
+
 typedef struct ssh_gssapi_cred_cache {
        char *filename;
        char *envvar;
@@ -61,6 +63,7 @@ typedef struct ssh_gssapi_cred_cache {
 } ssh_gssapi_cred_cache;
 
 static struct ssh_gssapi_cred_cache gssapi_cred_store = {NULL,NULL,NULL};
+unsigned char ssh1_key_digest[16]; /* used for ssh1 gssapi */
 
 /*
  * Environment variables pointing to delegated credentials
@@ -71,8 +74,6 @@ static char *delegation_env[] = {
   NULL
 };
 
-static void gssapi_unsetenv(const char *var);
-
 #ifdef KRB5
 
 #ifdef HEIMDAL
@@ -133,23 +134,6 @@ ssh_gssapi_krb5_userok(char *name) {
        krb5_free_principal(krb_context, princ);
        return retval;
 }
-
-int
-ssh_gssapi_krb5_localname(char **user)
-{
-    krb5_principal princ;
-
-    if (krb5_parse_name(krb_context, gssapi_client_name.value, &princ)) {
-       return(0);
-    }
-    *user = (char *)xmalloc(256);
-    if (krb5_aname_to_localname(krb_context, princ, 256, *user)) {
-       xfree(*user);
-       *user = NULL;
-       return(0);
-    }
-    return(1);
-}
        
 /* Make sure that this is called _after_ we've setuid to the user */
 
@@ -265,7 +249,7 @@ ssh_gssapi_krb5_storecreds() {
 #endif /* KRB5 */
 
 #ifdef GSI
-#include <globus_gss_assist.h>
+#include "globus_gss_assist_gsi.h"
 
 /*
  * Check if this user is OK to login under GSI. User has been authenticated
@@ -289,15 +273,6 @@ ssh_gssapi_gsi_userok(char *name)
     return authorized;
 }
 
-/*
- * Return the local username associated with the GSI credentials.
- */
-int
-ssh_gssapi_gsi_localname(char **user)
-{
-    return(globus_gss_assist_gridmap(gssapi_client_name.value, user) == 0);
-}
-
 /*
  * Handle setting up child environment for GSI.
  *
@@ -388,16 +363,16 @@ void
 ssh_gssapi_storecreds()
 {
        switch (gssapi_client_type) {
-#ifdef KRB5
-       case GSS_KERBEROS:
-               ssh_gssapi_krb5_storecreds();
-               break;
-#endif
 #ifdef GSI
        case GSS_GSI:
                ssh_gssapi_gsi_storecreds();
                break;
 #endif /* GSI */
+#ifdef KRB5
+       case GSS_KERBEROS:
+               ssh_gssapi_krb5_storecreds();
+               break;
+#endif
        case GSS_LAST_ENTRY:
                /* GSSAPI not used in this authentication */
                debug("No GSSAPI credentials stored");
@@ -476,32 +451,225 @@ ssh_gssapi_userok(char *user)
 }
 
 int
-ssh_gssapi_localname(char **user)
+userauth_external(Authctxt *authctxt)
 {
-       *user = NULL;
-       if (gssapi_client_name.length==0 || 
-           gssapi_client_name.value==NULL) {
-               debug("No suitable client data");
-               return(0);;
+       packet_check_eom();
+
+       return(ssh_gssapi_userok(authctxt->user));
+}
+
+void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
+void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
+
+/* We only support those mechanisms that we know about (ie ones that we know
+ * how to check local user kuserok and the like
+ */
+int
+userauth_gssapi(Authctxt *authctxt)
+{
+       gss_OID_desc    oid= {0,NULL};
+       Gssctxt         *ctxt;
+       int             mechs;
+       gss_OID_set     supported;
+       int             present;
+       OM_uint32       ms;
+       u_int           len;
+       
+       if (!authctxt->valid || authctxt->user == NULL)
+               return 0;
+               
+       if (datafellows & SSH_OLD_GSSAPI) {
+               debug("Early drafts of GSSAPI userauth not supported");
+               return 0;
        }
-       switch (gssapi_client_type) {
-#ifdef KRB5
-       case GSS_KERBEROS:
-               return(ssh_gssapi_krb5_localname(user));
-               break; /* Not reached */
-#endif
-#ifdef GSI
-       case GSS_GSI:
-               return(ssh_gssapi_gsi_localname(user));
-               break; /* Not reached */
-#endif /* GSI */
-       case GSS_LAST_ENTRY:
-               debug("Client not GSSAPI");
-               break;
-       default:
-               debug("Unknown client authentication type");
+       
+       mechs=packet_get_int();
+       if (mechs==0) {
+               debug("Mechanism negotiation is not supported");
+               return 0;
        }
-       return(0);
+
+       ssh_gssapi_supported_oids(&supported);
+       do {
+               if (oid.elements)
+                       xfree(oid.elements);
+               oid.elements = packet_get_string(&len);
+               oid.length = len;
+               gss_test_oid_set_member(&ms, &oid, supported, &present);
+               mechs--;
+       } while (mechs>0 && !present);
+       
+       if (!present) {
+               xfree(oid.elements);
+               return(0);
+       }
+       
+       ctxt=xmalloc(sizeof(Gssctxt));
+       authctxt->methoddata=(void *)ctxt;
+       
+       ssh_gssapi_build_ctx(ctxt);
+       ssh_gssapi_set_oid(ctxt,&oid);
+
+       if (ssh_gssapi_acquire_cred(ctxt))
+               return 0;
+
+       /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */
+
+       if (!compat20)
+       packet_start(SSH_SMSG_AUTH_GSSAPI_RESPONSE);
+       else
+       packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
+       packet_put_string(oid.elements,oid.length);
+       packet_send();
+       packet_write_wait();
+       xfree(oid.elements);
+               
+       if (!compat20)
+       dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN,
+                               &input_gssapi_token);
+       else
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, 
+                    &input_gssapi_token);
+       authctxt->postponed = 1;
+       
+       return 0;
+}
+
+void
+input_gssapi_token(int type, u_int32_t plen, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       gss_buffer_desc send_tok,recv_tok;
+       OM_uint32 maj_status, min_status;
+       
+       if (authctxt == NULL || authctxt->methoddata == NULL)
+               fatal("No authentication or GSSAPI context");
+               
+       gssctxt=authctxt->methoddata;
+
+       recv_tok.value=packet_get_string(&recv_tok.length);
+       
+       maj_status=ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok, NULL);
+       packet_check_eom();
+       
+       if (GSS_ERROR(maj_status)) {
+               /* Failure <sniff> */
+               ssh_gssapi_send_error(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)
+               packet_start(SSH_MSG_AUTH_GSSAPI_TOKEN);
+               else
+               packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
+                packet_put_string(send_tok.value,send_tok.length);
+                packet_send();
+                packet_write_wait();
+                gss_release_buffer(&min_status, &send_tok);
+       }
+       
+       if (maj_status == GSS_S_COMPLETE) {
+               dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
+               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
+               /* ssh1 does not have an extra message here */
+               if (!compat20)
+               input_gssapi_exchange_complete(0, 0, ctxt);
+               else
+               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+                            &input_gssapi_exchange_complete);
+       }
+}
+
+/* This is called when the client thinks we've completed authentication.
+ * It should only be enabled in the dispatch handler by the function above,
+ * which only enables it once the GSSAPI exchange is complete.
+ */
+void
+input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       int authenticated;
+
+       if(strcmp(authctxt->user,"") == 0) {
+               char *user;
+               char *gridmapped_name = NULL;
+               struct passwd *pw = NULL;
+               if(globus_gss_assist_gridmap(gssapi_client_name.value,
+                           &gridmapped_name) == 0) {
+                               user = gridmapped_name;
+                               debug("I gridmapped and got %s", user);
+                               pw = getpwnam(user);
+                               if (pw && allowed_user(pw)) {
+                               authctxt->user = user;
+                               authctxt->pw = pwcopy(pw);
+                               authctxt->valid = 1;
+                               }
+               }
+       }
+
+       
+       if (authctxt == NULL || authctxt->methoddata == NULL)
+               fatal("No authentication or GSSAPI context");
+               
+       gssctxt=authctxt->methoddata;
+
+       /* This should never happen, but better safe than sorry. */
+       if (gssctxt->status != GSS_S_COMPLETE) {
+               packet_disconnect("Context negotiation is not complete");
+       }
+
+       if (ssh_gssapi_getclient(gssctxt,&gssapi_client_type,
+                                &gssapi_client_name,
+                                &gssapi_client_creds)) {
+               fatal("Couldn't convert client name");
+       }
+                                               
+        authenticated = ssh_gssapi_userok(authctxt->user);
+
+       /* ssh1 needs to exchange the hash of the keys */
+       if (!compat20) {
+               if (authenticated) {
+
+                       OM_uint32 maj_status, min_status;
+                       gss_buffer_desc gssbuf,msg_tok;
+
+                       /* ssh1 uses wrap */
+                       gssbuf.value=ssh1_key_digest;
+                       gssbuf.length=sizeof(ssh1_key_digest);
+                       if ((maj_status=gss_wrap(&min_status,
+                                       gssctxt->context,
+                                       0,
+                                       GSS_C_QOP_DEFAULT,
+                                       &gssbuf,
+                                       NULL,
+                                       &msg_tok))) {
+                               ssh_gssapi_error(maj_status,min_status);
+                               fatal("Couldn't wrap keys");
+                       }
+                       packet_start(SSH_SMSG_AUTH_GSSAPI_HASH);
+                       packet_put_string((char *)msg_tok.value,msg_tok.length);
+                       packet_send();
+                       packet_write_wait();
+                       gss_release_buffer(&min_status,&msg_tok);
+               } else {
+                   packet_start(SSH_MSG_AUTH_GSSAPI_ABORT);
+                   packet_send();
+                   packet_write_wait();
+               }
+       }
+
+       authctxt->postponed = 0;
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(authctxt, authenticated, "gssapi");
 }
 
 /*
index fdf9567ff9819a54bb05c91470fd09109ee65bbf..95434470d26119279d3419e5f6a7bb285d39a2a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001,2002 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001 Simon Wilkinson. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _SSH_GSS_H
-#define _SSH_GSS_H
-
 #ifdef GSSAPI
 
 #include "kex.h"
 #include "buffer.h"
 
-#include <gssapi.h>
+#include "gssapi_krb.h"
 
 #ifdef KRB5
 #ifndef HEIMDAL
-#include <gssapi_generic.h>
 
 /* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */
 
 #endif /* !HEIMDAL */
 #endif /* KRB5 */
 
-/* draft-ietf-secsh-gsskeyex-03 */
-#define SSH2_MSG_KEXGSS_INIT                           30
-#define SSH2_MSG_KEXGSS_CONTINUE                       31
-#define SSH2_MSG_KEXGSS_COMPLETE                       32
-#define SSH2_MSG_KEXGSS_HOSTKEY                                33
-#define SSH2_MSG_KEXGSS_ERROR                          34
-#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE              60
-#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN                 61
+/* draft-ietf-secsh-gsskeyex-01 */
+#define SSH2_MSG_KEXGSS_INIT           30
+#define SSH2_MSG_KEXGSS_CONTINUE       31
+#define SSH2_MSG_KEXGSS_COMPLETE       32
+#define SSH2_MSG_KEXGSS_HOSTKEY                33
+#define KEX_GSS_SHA1                   "gss-group1-sha1-"
+
+/* draft-galb-secsh-gssapi-01 */
+#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE     60
+#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN        61
+#define SSH2_MSG_USERAUTH_GSSAPI_HASH         62
 #define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE     63    
-#define SSH2_MSG_USERAUTH_GSSAPI_ERROR                 64  
-
-#define KEX_GSS_SHA1                                   "gss-group1-sha1-"
 
 enum ssh_gss_id {
-#ifdef KRB5
-       GSS_KERBEROS,
-#endif
 #ifdef GSI
        GSS_GSI,
 #endif /* GSI */
+#ifdef KRB5
+       GSS_KERBEROS,
+#endif
        GSS_LAST_ENTRY
 };
 
@@ -89,7 +85,7 @@ extern gss_cred_id_t   gssapi_client_creds;
 extern enum ssh_gss_id gssapi_client_type;
 
 char *ssh_gssapi_mechanisms(int server, char *host);
-gss_OID ssh_gssapi_id_kex(Gssctxt *ctx, char *name);
+int ssh_gssapi_id_kex(Gssctxt *ctx, char *name);
 void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len);
 void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid);
 void ssh_gssapi_supported_oids(gss_OID_set *oidset);
@@ -110,32 +106,18 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx,
                                gss_cred_id_t *creds);
 void ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status);
 void ssh_gssapi_send_error(OM_uint32 major_status,OM_uint32 minor_status);
-void ssh_gssapi_build_ctx(Gssctxt **ctx);
-void ssh_gssapi_delete_ctx(Gssctxt **ctx);
-OM_uint32 ssh_gssapi_client_ctx(Gssctxt **ctx,gss_OID oid,char *host);
-OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid);
+void ssh_gssapi_build_ctx(Gssctxt *ctx);
+void ssh_gssapi_delete_ctx(Gssctxt *ctx);
 
 /* In the client */
 void ssh_gssapi_client(Kex *kex, char *host, struct sockaddr *hostaddr,
                        Buffer *client_kexinit, Buffer *server_kexinit);
 
 /* In the server */
-int ssh_gssapi_userok(char *name);
-int ssh_gssapi_localname(char **lname);
 void ssh_gssapi_server(Kex *kex, Buffer *client_kexinit, 
                       Buffer *server_kexinit);
-
-OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *buffer, 
-                                       gss_buffer_desc *hash);
-
 void ssh_gssapi_do_child(char ***envp, u_int *envsizep);                 
 void ssh_gssapi_cleanup_creds(void *ignored);
 void ssh_gssapi_storecreds();
 void ssh_gssapi_clean_env();
-
-#ifdef GSI
-int gsi_gridmap(char *subject_name, char **mapped_name);
-#endif
 #endif /* GSSAPI */
-
-#endif /* _SSH_GSS_H */
This page took 1.687521 seconds and 5 git commands to generate.