[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