heimdal/gssapi: Allow a NULL authenticator
authorAndrew Bartlett <abartlet@samba.org>
Fri, 26 Jun 2015 07:14:56 +0000 (19:14 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 5 Aug 2015 04:39:19 +0000 (06:39 +0200)
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.

This was seen in the wild, with a Huawei Unified Storage System S5500 V3 against the AD DC

Original patch by Andrew Bartlett, restructured by Douglas Bagnall

Cherry-picked from upstream GIT 0a5de96d72cdea9e465412d7dba1e5d13e53dc09
which is the merge of https://github.com/heimdal/heimdal/pull/134

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11425
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source4/heimdal/lib/gssapi/krb5/accept_sec_context.c

index 5a00e124c2cf5d606ca9ce05a3ea7882bbb16a46..cfe27ace875e0f20e5e206cce52fed3047b1864a 100644 (file)
@@ -510,13 +510,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,
@@ -528,44 +523,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) {