[28272] in Kerberos

home help back first fref pref prev next nref lref last post

Re: [modauthkerb] Saving credential with KrbSaveCredentials

daemon@ATHENA.MIT.EDU (Mikkel Kruse Johnsen)
Wed Aug 15 20:28:26 2007

From: Mikkel Kruse Johnsen <mikkel@linet.dk>
To: achim@grolmsnet.de
In-Reply-To: <200708141930.49168.achim@grolmsnet.de>
Content-Type: multipart/mixed; boundary="=-RsY6BcWm50qepaHQRESa"
Date: Wed, 15 Aug 2007 09:02:16 +0200
Message-Id: <1187161336.3009.7.camel@tux.lib.cbs.dk>
Mime-Version: 1.0
Cc: modauthkerb-help@lists.sourceforge.net, kerberos <kerberos@mit.edu>
Reply-To: mikkel@linet.dk
Errors-To: kerberos-bounces@mit.edu


--=-RsY6BcWm50qepaHQRESa
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Hi All

I got it to work. It seems there is an error in the SPNEGO code on MIT
Kerberos. When compiling mod_auth_kerb to use it's internal SPNEGO code
everything works fine.

The error as I see it, is that autheticate works but saving the
credential fails.

...
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1553): [client
130.226.36.170] kerb_authenticate_user entered with user (NULL) and
auth_type Kerberos
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1553): [client
130.226.36.170] kerb_authenticate_user entered with user (NULL) and
auth_type Kerberos
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1206): [client
130.226.36.170] Acquiring creds for HTTP/sugi.cbs.dk@CBS.DK
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1364): [client
130.226.36.170] Verifying client data using KRB5 GSS-API
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1380): [client
130.226.36.170] Verification returned code 0 lifetime 79137
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1398): [client
130.226.36.170] GSS-API token of length 22 bytes will be sent back
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1447): [client
130.226.36.170] set cached name mkj.lib@CBS.DK for connection
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1456): [client
130.226.36.170] krb_save_credentials activated, GSS_C_DELEG_FLAG
available
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1105): [client
130.226.36.170] Lifetime of delegated credential is expired
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1120): [client
130.226.36.170] Display name (mkj.lib@CBS.DK)
[Tue Aug 14 15:21:32 2007] [debug] src/mod_auth_kerb.c(1132): [client
130.226.36.170] Cred Usage GSS_C_BOTH
[Tue Aug 14 15:21:32 2007] [error] [client 130.226.36.170] Cannot store
delegated credential (gss_krb5_copy_ccache: Invalid credential was
supplied (No error))
....

As you can see the credential is expired when using the SPNEGO in MIT
kerberos.


...
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1553): [client
130.226.36.170] kerb_authenticate_user entered with user (NULL) and
auth_type Kerberos
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1553): [client
130.226.36.170] kerb_authenticate_user entered with user (NULL) and
auth_type Kerberos
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1206): [client
130.226.36.170] Acquiring creds for HTTP/sugi.cbs.dk@CBS.DK
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1364): [client
130.226.36.170] Verifying client data using SPNEGO GSS-API
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1380): [client
130.226.36.170] Verification returned code 0 lifetime 27495
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1398): [client
130.226.36.170] GSS-API token of length 22 bytes will be sent back
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1447): [client
130.226.36.170] set cached name mkj.lib@CBS.DK for connection
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1456): [client
130.226.36.170] krb_save_credentials activated, GSS_C_DELEG_FLAG
available
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1108): [client
130.226.36.170] Lifetime of delegated credential is 27495
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1120): [client
130.226.36.170] Display name (mkj.lib@CBS.DK)
[Wed Aug 15 08:41:46 2007] [debug] src/mod_auth_kerb.c(1125): [client
130.226.36.170] Cred Usage GSS_C_INITIATE
....

But using the SPNEGO in mod_auth_kerb it is not.


So is this an error in MIT kerberos or is mod_auth_kerb using the SPNEGO
wrong ?

/Mikkel




On Tue, 2007-08-14 at 19:30 +0200, Achim Grolms wrote:

> On Friday 10 August 2007 21:02, Henry B. Hotz wrote:
> 
> > > Is there anyone who has this working, saving the ticket from either
> > > Firefox/linux, Firefox/WinXP, IE7/WinXP ?
> >
> > Yes, I've had no problems with the two WinXP cases.  Have done
> > Firefox both with native Windows SSPI and with KfW GSSAPI. 
> 
> That means your requests use the SPNEGO mechtype in every case?
> 
> On your mod_auth_kerb side - what code does the SPNEGO processing,
> mod_auth_kerb itself or a SPNEGO-supporting Kerberosimplementation?
> 
> 
> Background of this question:
> I have asked Mikkel to run HTTP-Requests on the Firefoxmachine
> using Perl and LWP::Authen::Negotiate (from CPAN)
> because LWP::Authen::Negotiate can be easily modified.
> 
> The strange thing is:
> 
> If using GSSAPI-mechtype Kerberos5 everything works fine.
> If using GSSAPI-mechtype SPNEGO Mikkel gets the same results
> as if he uses his Firefox.
> 
> Any ideas?
> 
> Achim
> Received-SPF: pass (0: SPF record at ispgateway.de designates 80.67.18.14 as permitted sender)
> 
> !DSPAM:46c1e6cb107062091219428!
> 

Mikkel Kruse
Johnsen
Adm.Dir.

Linet
Ørholmgade 6 st tv
Copenhagen N 2200
Denmark

Work: +45 21287793
Mobile: +45
21287793
Email:
mikkel@linet.dk
IM:
mikkel@linet.dk
(MSN)
 Professional
Profile
Healthcare 


Network
Consultant 

--=-RsY6BcWm50qepaHQRESa
Content-Disposition: attachment; filename=mod_auth_kerb-5.3-deleg.patch
Content-Type: text/x-patch; name=mod_auth_kerb-5.3-deleg.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit

diff -r -u mod_auth_kerb-5.3.orig/src/mod_auth_kerb.c mod_auth_kerb-5.3/src/mod_auth_kerb.c
--- mod_auth_kerb-5.3.orig/src/mod_auth_kerb.c	2007-07-25 11:38:20.000000000 +0200
+++ mod_auth_kerb-5.3/src/mod_auth_kerb.c	2007-08-15 08:41:11.000000000 +0200
@@ -1060,6 +1060,13 @@
    krb5_context context;
    int ret = HTTP_INTERNAL_SERVER_ERROR;
 
+   gss_name_t name;
+   OM_uint32 lifetime;
+   gss_cred_usage_t cred_usage;
+   gss_OID_set mechanisms;
+
+   gss_buffer_desc output_name_buffer;
+
    problem = krb5_init_context(&context);
    if (problem) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Cannot initialize krb5 context");
@@ -1080,6 +1087,57 @@
       goto end;
    }
 
+   // Start Credential Check
+   //
+   maj_stat = gss_inquire_cred (&min_stat, delegated_cred, &name, &lifetime, &cred_usage, &mechanisms);
+   if (maj_stat != GSS_S_COMPLETE) {
+      log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Inquire delegated credential (%s)",
+         get_gss_error(r->pool, maj_stat, min_stat, "gss_inquire_cred"));
+      goto end;
+   }
+
+   if (lifetime == GSS_C_INDEFINITE) {
+      log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Lifetime of delegated credential never expires");
+   } else {
+     if (lifetime == 0) {
+       log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Lifetime of delegated credential is expired");
+     } else {
+       log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Lifetime of delegated credential is %d", lifetime);
+     }
+   }
+
+   maj_stat = gss_display_name (&min_stat, name, &output_name_buffer, NULL);
+   if (maj_stat != GSS_S_COMPLETE) {
+      log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Display name (%s)",
+         get_gss_error(r->pool, maj_stat, min_stat, "gss_display_name"));
+      goto end;
+   } else {
+      log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Display name (%s)", (char *)output_name_buffer.value);
+   }
+
+   if (cred_usage == GSS_C_INITIATE) {
+      log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Cred Usage GSS_C_INITIATE");
+   } else {
+     if (cred_usage == GSS_C_ACCEPT) {
+       log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Cred Usage GSS_C_ACCEPT");
+     } else {
+       log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+         "Cred Usage GSS_C_BOTH");
+     }
+   }
+
+   gss_release_oid_set(&min_stat, &mechanisms);
+   //
+   // End Credential Check
+
    maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, ccache);
    if (GSS_ERROR(maj_stat)) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
@@ -1125,7 +1183,7 @@
    token.length = strlen(buf) + 1;
 
    major_status = gss_import_name(&minor_status, &token,
-	 			  (have_server_princ) ? GSS_KRB5_NT_PRINCIPAL_NAME : GSS_C_NT_HOSTBASED_SERVICE,
+	 			  (have_server_princ) ? /*GSS_KRB5_NT_PRINCIPAL_NAME*/ (gss_OID)gss_nt_krb5_name : /*GSS_C_NT_HOSTBASED_SERVICE*/ (gss_OID)gss_nt_service_name,
 				  &server_name);
    memset(&token, 0, sizeof(token));
    if (GSS_ERROR(major_status)) {
@@ -1163,6 +1221,7 @@
    return 0;
 }
 
+#ifndef GSSAPI_SUPPORTS_SPNEGO
 static int
 cmp_gss_type(gss_buffer_t token, gss_OID oid)
 {
@@ -1189,6 +1248,7 @@
 
    return memcmp(p, oid->elements, oid->length);
 }
+#endif
 
 #define NAMEKEY "mod_auth_kerb:client_name"
 
@@ -1198,7 +1258,13 @@
 authenticate_user_gss(request_rec *r, kerb_auth_config *conf,
 		      const char *auth_line, char **negotiate_ret_value)
 {
-  OM_uint32 major_status, minor_status, minor_status2;
+  krb5_context ctx;
+  krb5_keytab keytab;
+  krb5_kt_cursor cursor;
+  krb5_keytab_entry entry;
+  int k5_errno;
+  char *principal = NULL;
+  OM_uint32 major_status, minor_status, minor_status2, major_status_accept;
   gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
   const char *auth_param = NULL;
@@ -1215,6 +1281,9 @@
   spnego_oid.length = 6;
   spnego_oid.elements = (void *)"\x2b\x06\x01\x05\x05\x02";
 
+  OM_uint32 acc_ret_flags;
+  OM_uint32 time_rec;
+
   if (conf->krb_5_keytab) {
      char *ktname;
      /* we don't use the ap_* calls here, since the string passed to putenv()
@@ -1234,9 +1303,11 @@
 #endif
   }
 
+/*
   ret = get_gss_creds(r, conf, &server_creds);
   if (ret)
      goto end;
+*/
 
   /* ap_getword() shifts parameter */
   auth_param = ap_getword_white(r->pool, &auth_line);
@@ -1264,54 +1335,81 @@
      			gss_accept_sec_context_spnego : gss_accept_sec_context;
 #endif
 
-  log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Verifying client data using %s",
+  /* We're going to try accepting the context with every different principal
+     available in our keytab if we can.  Otherwise, we're going to fall back
+     on just doing this once with the specified principal name.  If k5_errno
+     is zero, we're walking through the keytab; otherwise, we're not. */
+  k5_errno = krb5_init_context(&ctx);
+  if (k5_errno == 0 && conf->krb_5_keytab)
+      k5_errno = krb5_kt_resolve(ctx, conf->krb_5_keytab, &keytab);
+  else
+      k5_errno = krb5_kt_default(ctx, &keytab);
+  if (k5_errno == 0)
+      k5_errno = krb5_kt_start_seq_get(ctx, keytab, &cursor);
+
+  /* Here's the big loop in which we try to do the authentication. */
+  do {
+    if (k5_errno == 0)
+      k5_errno = krb5_kt_next_entry(ctx, keytab, &entry, &cursor);
+    if (k5_errno == 0)
+      k5_errno = krb5_unparse_name(ctx, entry.principal, &principal);
+    if (k5_errno == 0)
+      conf->krb_service_name = principal;
+  
+    ret = get_gss_creds(r, conf, &server_creds);
+    if (ret)
+      goto end;
+
+    /* pridat: Read client Negotiate data of length XXX, prefix YYY */
+    log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Verifying client data using %s",
 	     (accept_sec_token == gss_accept_sec_context)
 	       ? "KRB5 GSS-API"
 	       : "SPNEGO GSS-API");
 
-  major_status = accept_sec_token(&minor_status,
-				  &context,
-				  server_creds,
-				  &input_token,
-				  GSS_C_NO_CHANNEL_BINDINGS,
-				  &client_name,
-				  NULL,
-				  &output_token,
-				  NULL,
-				  NULL,
-				  &delegated_cred);
-  log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-	     "Verification returned code %d", major_status);
-  if (output_token.length) {
-     char *token = NULL;
-     size_t len;
+    major_status_accept = accept_sec_token(&minor_status,
+  					 &context,
+					 server_creds,
+				 	 &input_token,
+				  	 GSS_C_NO_CHANNEL_BINDINGS,
+				 	 &client_name,
+				 	 NULL,
+				 	 &output_token,
+				 	 &acc_ret_flags,
+				 	 &time_rec,
+				  	 &delegated_cred);
+    log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+  	     "Verification returned code %d lifetime %d", major_status_accept, time_rec);
+    if (output_token.length) {
+       char *token = NULL;
+       size_t len;
      
-     len = apr_base64_encode_len(output_token.length) + 1;
-     token = apr_pcalloc(r->connection->pool, len + 1);
-     if (token == NULL) {
-	log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+       len = apr_base64_encode_len(output_token.length) + 1;
+       token = apr_pcalloc(r->connection->pool, len + 1);
+       if (token == NULL) {
+	  log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 	           "ap_pcalloc() failed (not enough memory)");
-        ret = HTTP_INTERNAL_SERVER_ERROR;
-	gss_release_buffer(&minor_status2, &output_token);
-	goto end;
-     }
-     apr_base64_encode(token, output_token.value, output_token.length);
-     token[len] = '\0';
-     *negotiate_ret_value = token;
-     log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-	        "GSS-API token of length %d bytes will be sent back",
-		output_token.length);
-     gss_release_buffer(&minor_status2, &output_token);
-     set_kerb_auth_headers(r, conf, 0, 0, *negotiate_ret_value);
-  }
+          ret = HTTP_INTERNAL_SERVER_ERROR;
+    	  gss_release_buffer(&minor_status2, &output_token);
+  	  goto end;
+       }
+       apr_base64_encode(token, output_token.value, output_token.length);
+       token[len] = '\0';
+       *negotiate_ret_value = token;
+       log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+  	        "GSS-API token of length %d bytes will be sent back",
+  		output_token.length);
+       gss_release_buffer(&minor_status2, &output_token);
+       set_kerb_auth_headers(r, conf, 0, 0, *negotiate_ret_value);
+    }
+  } while (k5_errno == 0 && GSS_ERROR(major_status_accept));
 
-  if (GSS_ERROR(major_status)) {
+  if (GSS_ERROR(major_status_accept)) {
      if (input_token.length > 7 && memcmp(input_token.value, "NTLMSSP", 7) == 0)
 	log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
 	          "Warning: received token seems to be NTLM, which isn't supported by the Kerberos module. Check your IE configuration.");
 
      log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-	        "%s", get_gss_error(r->pool, major_status, minor_status,
+	        "%s", get_gss_error(r->pool, major_status_accept, minor_status,
 		                    "gss_accept_sec_context() failed"));
      /* Don't offer the Negotiate method again if call to GSS layer failed */
      *negotiate_ret_value = NULL;
@@ -1323,7 +1421,7 @@
   /* This is a _Kerberos_ module so multiple authentication rounds aren't
    * supported. If we wanted a generic GSS authentication we would have to do
    * some magic with exporting context etc. */
-  if (major_status & GSS_S_CONTINUE_NEEDED) {
+  if (major_status_accept & GSS_S_CONTINUE_NEEDED) {
      ret = HTTP_UNAUTHORIZED;
      goto end;
   }
@@ -1351,8 +1449,30 @@
   }
 #endif
 
-  if (conf->krb_save_credentials && delegated_cred != GSS_C_NO_CREDENTIAL)
-     store_gss_creds(r, conf, (char *)output_token.value, delegated_cred);
+  if (major_status_accept == GSS_S_COMPLETE ) {
+    if (conf->krb_save_credentials) {
+      if (delegated_cred != GSS_C_NO_CREDENTIAL) {
+        if (acc_ret_flags & GSS_C_DELEG_FLAG) {
+          log_rerror( APLOG_MARK, APLOG_DEBUG, 0, r,
+       	    "krb_save_credentials activated, GSS_C_DELEG_FLAG available");
+ 
+          store_gss_creds(r, conf, (char *)output_token.value, delegated_cred);
+        } 
+        else {
+          log_rerror( APLOG_MARK, APLOG_DEBUG, 0, r,
+            "krb_save_credentials activated, no GSS_C_DELEG_FLAG");
+        }
+      } 
+      else {
+        log_rerror( APLOG_MARK, APLOG_DEBUG, 0, r,
+          "krb_save_credentials activated, no GSS_C_NO_CREDENTIAL");
+      }
+    }
+  }
+  else {
+    log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
+      "krb_save_credentials not activated, no GSS_S_COMPLETE");
+  }	 
 
   gss_release_buffer(&minor_status, &output_token);
 

--=-RsY6BcWm50qepaHQRESa
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

________________________________________________
Kerberos mailing list           Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos

--=-RsY6BcWm50qepaHQRESa--


home help back first fref pref prev next nref lref last post