gssapi: Allow a NULL authenticator
authorAndrew Bartlett <abartlet@samba.org>
Tue, 7 Jul 2015 01:52:10 +0000 (13:52 +1200)
committerDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 29 Jul 2015 22:52:54 +0000 (10:52 +1200)
Some non-GSSAPI implementations that instead try to create compatible packets by wrapping krb5_mk_req()
can trigger a NULL authenticator here.  Assume this to be equvilent to specifying an all-zero
channel bindings and some reasonable (fixed) flags.

Original patch by Andrew Bartlett, restructured by Douglas Bagnall

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
lib/gssapi/krb5/accept_sec_context.c

index c55e87e1dce83ab95401900f3caef74e61da49b7..ada03f5a57702acb88be0183b71738802cfae1e0 100644 (file)
@@ -511,13 +511,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
            return ret;
        }
 
-       if (authenticator->cksum == NULL) {
-           krb5_free_authenticator(context, &authenticator);
-           *minor_status = 0;
-           return GSS_S_BAD_BINDINGS;
-       }
-
-        if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
+        if (authenticator->cksum != NULL
+           && authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
             ret = _gsskrb5_verify_8003_checksum(minor_status,
                                                input_chan_bindings,
                                                authenticator->cksum,
@@ -529,44 +524,48 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
                return ret;
            }
         } else {
-           krb5_crypto crypto;
-
-           kret = krb5_crypto_init(context,
-                                   ctx->auth_context->keyblock,
-                                   0, &crypto);
-           if(kret) {
+           if (authenticator->cksum != NULL) {
+               krb5_crypto crypto;
+
+               kret = krb5_crypto_init(context,
+                                       ctx->auth_context->keyblock,
+                                       0, &crypto);
+               if(kret) {
+                   krb5_free_authenticator(context, &authenticator);
+
+                   ret = GSS_S_FAILURE;
+                   *minor_status = kret;
+                   return ret;
+               }
+
+               /*
+                * Windows accepts Samba3's use of a kerberos, rather than
+                * GSSAPI checksum here
+                */
+
+               kret = krb5_verify_checksum(context,
+                                           crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
+                                           authenticator->cksum);
                krb5_free_authenticator(context, &authenticator);
+               krb5_crypto_destroy(context, crypto);
 
-               ret = GSS_S_FAILURE;
-               *minor_status = kret;
-               return ret;
+               if(kret) {
+                   ret = GSS_S_BAD_SIG;
+                   *minor_status = kret;
+                   return ret;
+               }
            }
 
            /*
-            * Windows accepts Samba3's use of a kerberos, rather than
-            * GSSAPI checksum here
+            * If there is no checksum or a kerberos checksum (which Windows
+            * and Samba accept), we use the ap_options to guess the mutual
+            * flag.
             */
 
-           kret = krb5_verify_checksum(context,
-                                       crypto, KRB5_KU_AP_REQ_AUTH_CKSUM, NULL, 0,
-                                       authenticator->cksum);
-           krb5_free_authenticator(context, &authenticator);
-           krb5_crypto_destroy(context, crypto);
-
-           if(kret) {
-               ret = GSS_S_BAD_SIG;
-               *minor_status = kret;
-               return ret;
-           }
-
-           /*
-            * Samba style get some flags (but not DCE-STYLE), use
-            * ap_options to guess the mutual flag.
-            */
-           ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+           ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
            if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
                ctx->flags |= GSS_C_MUTUAL_FLAG;
-        }
+       }
     }
 
     if(ctx->flags & GSS_C_MUTUAL_FLAG) {