[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Jul 5 08:53:03 UTC 2016


The branch, master has been updated
       via  978bc86 kerberos: Return enc data on PREAUTH_FAILED
      from  965361a password_hash: Make an error message clearer

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 978bc8681e74ffa17f96fd5d4355094c4a26691c
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Mon May 9 16:14:51 2016 +1200

    kerberos: Return enc data on PREAUTH_FAILED
    
    Without the enc data, Windows clients will perform two AS-REQ causing the password
    lockout count to increase by two instead of one.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11539
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Tue Jul  5 10:52:32 CEST 2016 on sn-devel-144

-----------------------------------------------------------------------

Summary of changes:
 source4/heimdal/kdc/kerberos5.c    | 178 +++++++++++++++++++++----------------
 source4/torture/krb5/kdc-heimdal.c |  18 ++++
 2 files changed, 117 insertions(+), 79 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 3762abe..b8bb5fa 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -976,7 +976,7 @@ _kdc_as_rep(krb5_context context,
     krb5_error_code ret = 0;
     const char *e_text = NULL;
     krb5_crypto crypto;
-    Key *ckey, *skey;
+    Key *skey;
     EncryptionKey *reply_key = NULL, session_key;
     int flags = HDB_F_FOR_AS_REQ;
 #ifdef PKINIT
@@ -1373,6 +1373,9 @@ _kdc_as_rep(krb5_context context,
            was some problem with it, other than too large skew */
 	if(found_pa && et.flags.pre_authent == 0){
 	    kdc_log(context, config, 0, "%s -- %s", e_text, client_name);
+	    if (!prepare_enc_data(context, config, &e_data, b, client)) {
+	        goto out;
+	    }
 	    e_text = NULL;
 	    goto out;
 	}
@@ -1380,88 +1383,11 @@ _kdc_as_rep(krb5_context context,
 	      || b->kdc_options.request_anonymous /* hack to force anon */
 	      || client->entry.flags.require_preauth
 	      || server->entry.flags.require_preauth) {
-	METHOD_DATA method_data;
-	PA_DATA *pa;
-	unsigned char *buf;
-	size_t len;
-
     use_pa:
-	method_data.len = 0;
-	method_data.val = NULL;
-
-	ret = realloc_method_data(&method_data);
-	if (ret) {
-	    free_METHOD_DATA(&method_data);
-	    goto out;
-	}
-	pa = &method_data.val[method_data.len-1];
-	pa->padata_type		= KRB5_PADATA_ENC_TIMESTAMP;
-	pa->padata_value.length	= 0;
-	pa->padata_value.data	= NULL;
-
-#ifdef PKINIT
-	ret = realloc_method_data(&method_data);
-	if (ret) {
-	    free_METHOD_DATA(&method_data);
-	    goto out;
-	}
-	pa = &method_data.val[method_data.len-1];
-	pa->padata_type		= KRB5_PADATA_PK_AS_REQ;
-	pa->padata_value.length	= 0;
-	pa->padata_value.data	= NULL;
-
-	ret = realloc_method_data(&method_data);
-	if (ret) {
-	    free_METHOD_DATA(&method_data);
-	    goto out;
-	}
-	pa = &method_data.val[method_data.len-1];
-	pa->padata_type		= KRB5_PADATA_PK_AS_REQ_WIN;
-	pa->padata_value.length	= 0;
-	pa->padata_value.data	= NULL;
-#endif
-
-	/*
-	 * If there is a client key, send ETYPE_INFO{,2}
-	 */
-	ret = _kdc_find_etype(context,
-			      config->preauth_use_strongest_session_key, TRUE,
-			      client, b->etype.val, b->etype.len, NULL, &ckey);
-	if (ret == 0) {
-
-	    /*
-	     * RFC4120 requires:
-	     * - If the client only knows about old enctypes, then send
-	     *   both info replies (we send 'info' first in the list).
-	     * - If the client is 'modern', because it knows about 'new'
-	     *   enctype types, then only send the 'info2' reply.
-	     *
-	     * Before we send the full list of etype-info data, we pick
-	     * the client key we would have used anyway below, just pick
-	     * that instead.
-	     */
-
-	    if (older_enctype(ckey->key.keytype)) {
-		ret = get_pa_etype_info(context, config,
-					&method_data, ckey);
-		if (ret) {
-		    free_METHOD_DATA(&method_data);
-		    goto out;
-		}
-	    }
-	    ret = get_pa_etype_info2(context, config,
-				     &method_data, ckey);
-	    if (ret) {
-		free_METHOD_DATA(&method_data);
+	if (!prepare_enc_data(context, config, &e_data, b, client)) {
 		goto out;
-	    }
 	}
 
-	ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
-	free_METHOD_DATA(&method_data);
-
-	e_data.data   = buf;
-	e_data.length = len;
 	e_text ="Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
 
 	ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
@@ -1834,6 +1760,100 @@ out:
     return ret;
 }
 
+krb5_boolean
+prepare_enc_data(krb5_context context,
+		 krb5_kdc_configuration *config,
+		 krb5_data *e_data,
+		 KDC_REQ_BODY *b,
+		 hdb_entry_ex *client)
+{
+	METHOD_DATA method_data;
+	PA_DATA *pa;
+	unsigned char *buf;
+	size_t len;
+	Key *ckey;
+	krb5_error_code ret;
+
+	method_data.len = 0;
+	method_data.val = NULL;
+
+	ret = realloc_method_data(&method_data);
+	if (ret) {
+	    free_METHOD_DATA(&method_data);
+	    return FALSE;
+	}
+	pa = &method_data.val[method_data.len-1];
+	pa->padata_type		= KRB5_PADATA_ENC_TIMESTAMP;
+	pa->padata_value.length	= 0;
+	pa->padata_value.data	= NULL;
+
+#ifdef PKINIT
+	ret = realloc_method_data(&method_data);
+	if (ret) {
+	    free_METHOD_DATA(&method_data);
+	    return FALSE;
+	}
+	pa = &method_data.val[method_data.len-1];
+	pa->padata_type		= KRB5_PADATA_PK_AS_REQ;
+	pa->padata_value.length	= 0;
+	pa->padata_value.data	= NULL;
+
+	ret = realloc_method_data(&method_data);
+	if (ret) {
+	    free_METHOD_DATA(&method_data);
+	    return FALSE;
+	}
+	pa = &method_data.val[method_data.len-1];
+	pa->padata_type		= KRB5_PADATA_PK_AS_REQ_WIN;
+	pa->padata_value.length	= 0;
+	pa->padata_value.data	= NULL;
+#endif
+
+	/*
+	 * If there is a client key, send ETYPE_INFO{,2}
+	 */
+	ret = _kdc_find_etype(context,
+			      config->preauth_use_strongest_session_key, TRUE,
+			      client, b->etype.val, b->etype.len, NULL, &ckey);
+	if (ret == 0) {
+
+	    /*
+	     * RFC4120 requires:
+	     * - If the client only knows about old enctypes, then send
+	     *   both info replies (we send 'info' first in the list).
+	     * - If the client is 'modern', because it knows about 'new'
+	     *   enctype types, then only send the 'info2' reply.
+	     *
+	     * Before we send the full list of etype-info data, we pick
+	     * the client key we would have used anyway below, just pick
+	     * that instead.
+	     */
+
+	    if (older_enctype(ckey->key.keytype)) {
+		ret = get_pa_etype_info(context, config,
+					&method_data, ckey);
+		if (ret) {
+		    free_METHOD_DATA(&method_data);
+		    return FALSE;
+		}
+	    }
+	    ret = get_pa_etype_info2(context, config,
+				     &method_data, ckey);
+	    if (ret) {
+		free_METHOD_DATA(&method_data);
+		return FALSE;
+	    }
+	}
+
+	ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
+	free_METHOD_DATA(&method_data);
+
+	e_data->data   = buf;
+	e_data->length = len;
+
+	return TRUE;
+}
+
 /*
  * Add the AuthorizationData `data´ of `type´ to the last element in
  * the sequence of authorization_data in `tkt´ wrapped in an IF_RELEVANT
diff --git a/source4/torture/krb5/kdc-heimdal.c b/source4/torture/krb5/kdc-heimdal.c
index fffe773..52014f7 100644
--- a/source4/torture/krb5/kdc-heimdal.c
+++ b/source4/torture/krb5/kdc-heimdal.c
@@ -189,6 +189,10 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
 						 "Got wrong error.error_code");
 			free_KRB_ERROR(&error);
 		} else if (test_context->packet_count == 1) {
+			METHOD_DATA m;
+			size_t len;
+			int i, ret = 0;
+			bool found = false;
 			torture_assert_int_equal(test_context->tctx,
 						 decode_KRB_ERROR(recv_buf->data, recv_buf->length, &error, &used), 0,
 						 "decode_AS_REP failed");
@@ -196,6 +200,20 @@ static bool torture_krb5_post_recv_test(struct torture_krb5_context *test_contex
 			torture_assert_int_equal(test_context->tctx, error.pvno, 5, "Got wrong error.pvno");
 			torture_assert_int_equal(test_context->tctx, error.error_code, KRB5KDC_ERR_PREAUTH_FAILED - KRB5KDC_ERR_NONE,
 						 "Got wrong error.error_code");
+			torture_assert(test_context->tctx, error.e_data != NULL, "No e-data returned");
+			ret = decode_METHOD_DATA(error.e_data->data, error.e_data->length, &m, &len);
+			torture_assert_int_equal(test_context->tctx, ret, 0,
+						 "Got invalid method data");
+
+			torture_assert(test_context->tctx, m.len > 0, "No PA_DATA given");
+			for (i = 0; i < m.len; i++) {
+				if (m.val[i].padata_type == KRB5_PADATA_ENC_TIMESTAMP) {
+					found = true;
+					break;
+				}
+			}
+			torture_assert(test_context->tctx, found, "Encrypted timestamp not found");
+
 			free_KRB_ERROR(&error);
 		}
 		torture_assert(test_context->tctx, test_context->packet_count < 2, "too many packets");


-- 
Samba Shared Repository



More information about the samba-cvs mailing list