Compare commits
104 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2ce5811ff | ||
|
|
fe6911cd3d | ||
|
|
53c3b9de3c | ||
|
|
fb94528750 | ||
|
|
a0a34794e3 | ||
|
|
5c0a004494 | ||
|
|
f2bc777d63 | ||
|
|
099df268ce | ||
|
|
9e0ac6c616 | ||
|
|
4c1f565dfa | ||
|
|
9767c1c24e | ||
|
|
d71494ca6c | ||
|
|
b45374269b | ||
|
|
5cc4a0d8bc | ||
|
|
87d784ddd7 | ||
|
|
1ed0e3a2d8 | ||
|
|
0fe5c327ec | ||
|
|
f5676fd233 | ||
|
|
ae2cf9bef3 | ||
|
|
a2c04215f0 | ||
|
|
0b340d0ef3 | ||
|
|
7058594eab | ||
|
|
ec957f5711 | ||
|
|
dca288bae2 | ||
|
|
4a4fd39d5e | ||
|
|
4eee9bbb50 | ||
|
|
f0b4f85e9e | ||
|
|
f29ff7186e | ||
|
|
ba968605e7 | ||
|
|
f003c0755c | ||
|
|
a206938c15 | ||
|
|
95288a2fb9 | ||
|
|
3668746b8f | ||
|
|
603ad7099e | ||
|
|
56cee506e7 | ||
|
|
c13bf943d8 | ||
|
|
0c2f5dcbe5 | ||
|
|
f5aa40a4a2 | ||
|
|
440331a1e4 | ||
|
|
3907ec760c | ||
|
|
e138eb8125 | ||
|
|
601b89387b | ||
|
|
e9188f0caa | ||
|
|
c25a51c969 | ||
|
|
04513849e3 | ||
|
|
fc958d4773 | ||
|
|
29a69aee06 | ||
|
|
0ceb166d96 | ||
|
|
2ef37ab30d | ||
|
|
970430cbff | ||
|
|
f858c7e550 | ||
|
|
b998554176 | ||
|
|
75355e197a | ||
|
|
ad88d4fd50 | ||
|
|
70255ea5b0 | ||
|
|
91c904e5df | ||
|
|
ca196a9d6b | ||
|
|
03e8c69837 | ||
|
|
c4016b4e4c | ||
|
|
2484569caa | ||
|
|
6a2eeb9666 | ||
|
|
af96dc0c6c | ||
|
|
c5044b0741 | ||
|
|
91bbbda93f | ||
|
|
4df0096f20 | ||
|
|
65a1e5607c | ||
|
|
72e80d67ef | ||
|
|
c4150c67d1 | ||
|
|
904d264a41 | ||
|
|
69e05d5e39 | ||
|
|
e9fb111a11 | ||
|
|
1c2362203e | ||
|
|
c183c8de7d | ||
|
|
7ef4909316 | ||
|
|
14c7d0b635 | ||
|
|
002bf4053e | ||
|
|
d67d35a3c6 | ||
|
|
cf3e70c97c | ||
|
|
1c03da79de | ||
|
|
d20ec5d3bc | ||
|
|
ab3f34f0e7 | ||
|
|
3faaf11da7 | ||
|
|
00a0ac8abc | ||
|
|
d3ac4cf9b0 | ||
|
|
35a4aa7b99 | ||
|
|
90bc2e25b3 | ||
|
|
d5839d0511 | ||
|
|
105082cb42 | ||
|
|
0dd40e4ff0 | ||
|
|
042ca4af99 | ||
|
|
54bf131a4a | ||
|
|
ef09340be0 | ||
|
|
327ebd0b26 | ||
|
|
b23f8f6215 | ||
|
|
9fb5239517 | ||
|
|
0da55d6175 | ||
|
|
58924baeb4 | ||
|
|
ed80b08062 | ||
|
|
b783a5421c | ||
|
|
ab7a2a35c2 | ||
|
|
dc8775d11d | ||
|
|
5facc9df4d | ||
|
|
015255764a | ||
|
|
ec1ab43ca2 |
109 changed files with 25559 additions and 9070 deletions
1
.fmf/version
Normal file
1
.fmf/version
Normal file
|
|
@ -0,0 +1 @@
|
|||
1
|
||||
113
.gitignore
vendored
113
.gitignore
vendored
|
|
@ -1,49 +1,50 @@
|
|||
krb5-1.3.4.tar.gz
|
||||
krb5-1.3.5.tar.gz
|
||||
krb5-1.3.5.tar.gz.asc
|
||||
krb5-1.3.6.tar.gz
|
||||
krb5-1.3.6.tar.gz.asc
|
||||
krb5-1.4.tar.gz
|
||||
krb5-1.4.tar.gz.asc
|
||||
krb5-1.4.1.tar.gz
|
||||
krb5-1.4.1.tar.gz.asc
|
||||
krb5-1.4.2.tar.gz
|
||||
krb5-1.4.2.tar.gz.asc
|
||||
krb5-1.4.3.tar.gz
|
||||
krb5-1.4.3.tar.gz.asc
|
||||
krb5-1.5.tar.gz
|
||||
krb5-1.5.tar.gz.asc
|
||||
krb5-1.6.tar.gz
|
||||
krb5-1.6.tar.gz.asc
|
||||
krb5-1.6-pdf.tar.gz
|
||||
krb5-1.6.1.tar.gz
|
||||
krb5-1.6.1.tar.gz.asc
|
||||
krb5-1.6.1-pdf.tar.gz
|
||||
krb5-1.6.2.tar.gz
|
||||
krb5-1.6.2.tar.gz.asc
|
||||
krb5-1.6.2-pdf.tar.gz
|
||||
krb5-1.6.3.tar.gz
|
||||
krb5-1.6.3.tar.gz.asc
|
||||
krb5-1.6.3-pdf.tar.gz
|
||||
krb5-1.7.tar.gz
|
||||
krb5-1.7.tar.gz.asc
|
||||
krb5-1.7-pdf.tar.gz
|
||||
krb5-1.7.1.tar.gz
|
||||
krb5-1.7.1.tar.gz.asc
|
||||
krb5-1.7.1-pdf.tar.gz
|
||||
krb5-1.8.tar.gz
|
||||
krb5-1.8.tar.gz.asc
|
||||
krb5-appl-1.0.tar.gz
|
||||
krb5-appl-1.0.tar.gz.asc
|
||||
krb5-1.8-pdf.tar.gz
|
||||
krb5-1.8.1.tar.gz
|
||||
krb5-1.8.1.tar.gz.asc
|
||||
krb5-1.8.1-pdf.tar.gz
|
||||
krb5-1.8.2.tar.gz.asc
|
||||
krb5-1.8.2-pdf.tar.gz
|
||||
krb5-1.8.3.tar.gz
|
||||
krb5-1.8.3.tar.gz.asc
|
||||
krb5-1.8.3-pdf.tar.gz
|
||||
/results_krb5
|
||||
/krb5-1.3.4.tar.gz
|
||||
/krb5-1.3.5.tar.gz
|
||||
/krb5-1.3.5.tar.gz.asc
|
||||
/krb5-1.3.6.tar.gz
|
||||
/krb5-1.3.6.tar.gz.asc
|
||||
/krb5-1.4.tar.gz
|
||||
/krb5-1.4.tar.gz.asc
|
||||
/krb5-1.4.1.tar.gz
|
||||
/krb5-1.4.1.tar.gz.asc
|
||||
/krb5-1.4.2.tar.gz
|
||||
/krb5-1.4.2.tar.gz.asc
|
||||
/krb5-1.4.3.tar.gz
|
||||
/krb5-1.4.3.tar.gz.asc
|
||||
/krb5-1.5.tar.gz
|
||||
/krb5-1.5.tar.gz.asc
|
||||
/krb5-1.6.tar.gz
|
||||
/krb5-1.6.tar.gz.asc
|
||||
/krb5-1.6-pdf.tar.gz
|
||||
/krb5-1.6.1.tar.gz
|
||||
/krb5-1.6.1.tar.gz.asc
|
||||
/krb5-1.6.1-pdf.tar.gz
|
||||
/krb5-1.6.2.tar.gz
|
||||
/krb5-1.6.2.tar.gz.asc
|
||||
/krb5-1.6.2-pdf.tar.gz
|
||||
/krb5-1.6.3.tar.gz
|
||||
/krb5-1.6.3.tar.gz.asc
|
||||
/krb5-1.6.3-pdf.tar.gz
|
||||
/krb5-1.7.tar.gz
|
||||
/krb5-1.7.tar.gz.asc
|
||||
/krb5-1.7-pdf.tar.gz
|
||||
/krb5-1.7.1.tar.gz
|
||||
/krb5-1.7.1.tar.gz.asc
|
||||
/krb5-1.7.1-pdf.tar.gz
|
||||
/krb5-1.8.tar.gz
|
||||
/krb5-1.8.tar.gz.asc
|
||||
/krb5-appl-1.0.tar.gz
|
||||
/krb5-appl-1.0.tar.gz.asc
|
||||
/krb5-1.8-pdf.tar.gz
|
||||
/krb5-1.8.1.tar.gz
|
||||
/krb5-1.8.1.tar.gz.asc
|
||||
/krb5-1.8.1-pdf.tar.gz
|
||||
/krb5-1.8.2.tar.gz.asc
|
||||
/krb5-1.8.2-pdf.tar.gz
|
||||
/krb5-1.8.3.tar.gz
|
||||
/krb5-1.8.3.tar.gz.asc
|
||||
/krb5-1.8.3-pdf.tar.gz
|
||||
/krb5-1.9-beta2.tar.gz
|
||||
/krb5-1.9-beta2.tar.gz.asc
|
||||
/krb5-1.9-beta2-pdf.tar.bz2
|
||||
|
|
@ -187,3 +188,23 @@ krb5-1.8.3-pdf.tar.gz
|
|||
/krb5-1.18.1.tar.gz.asc
|
||||
/krb5-1.18.2.tar.gz
|
||||
/krb5-1.18.2.tar.gz.asc
|
||||
/krb5-1.18.3.tar.gz
|
||||
/krb5-1.18.3.tar.gz.asc
|
||||
/krb5-1.19-beta1.tar.gz
|
||||
/krb5-1.19-beta1.tar.gz.asc
|
||||
/krb5-1.19-beta2.tar.gz
|
||||
/krb5-1.19-beta2.tar.gz.asc
|
||||
/krb5-1.19.tar.gz
|
||||
/krb5-1.19.tar.gz.asc
|
||||
/krb5-1.19.1.tar.gz
|
||||
/krb5-1.19.1.tar.gz.asc
|
||||
/krb5-1.19.2.tar.gz
|
||||
/krb5-1.19.2.tar.gz.asc
|
||||
/krb5-1.20.1.tar.gz
|
||||
/krb5-1.20.1.tar.gz.asc
|
||||
/krb5-1.21.tar.gz
|
||||
/krb5-1.21.tar.gz.asc
|
||||
/krb5-1.21.2.tar.gz
|
||||
/krb5-1.21.2.tar.gz.asc
|
||||
/krb5-1.21.3.tar.gz
|
||||
/krb5-1.21.3.tar.gz.asc
|
||||
|
|
|
|||
310
0001-downstream-Revert-Don-t-issue-session-keys-with-depr.patch
Normal file
310
0001-downstream-Revert-Don-t-issue-session-keys-with-depr.patch
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
From 6f7fd964539dfe4a885068f43a91db9738661870 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Tue, 9 Jul 2024 11:15:33 +0200
|
||||
Subject: [PATCH] [downstream] Revert "Don't issue session keys with
|
||||
deprecated enctypes"
|
||||
|
||||
This reverts commit 1b57a4d134bbd0e7c52d5885a92eccc815726463.
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 12 ------------
|
||||
doc/admin/enctypes.rst | 23 +++-------------------
|
||||
src/include/k5-int.h | 4 ----
|
||||
src/kdc/kdc_util.c | 10 ----------
|
||||
src/lib/krb5/krb/get_in_tkt.c | 31 +++++++++++-------------------
|
||||
src/lib/krb5/krb/init_ctx.c | 10 ----------
|
||||
src/tests/gssapi/t_enctypes.py | 3 +--
|
||||
src/tests/t_etype_info.py | 2 +-
|
||||
src/tests/t_sesskeynego.py | 28 ++-------------------------
|
||||
src/util/k5test.py | 4 ++--
|
||||
10 files changed, 20 insertions(+), 107 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index ecdf917501..f22d5db11b 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -95,18 +95,6 @@ Additionally, krb5.conf may include any of the relations described in
|
||||
|
||||
The libdefaults section may contain any of the following relations:
|
||||
|
||||
-**allow_des3**
|
||||
- Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
|
||||
- In future releases, this flag will allow des3-cbc-sha1 to be used
|
||||
- at all. The default value for this tag is false. (Added in
|
||||
- release 1.21.)
|
||||
-
|
||||
-**allow_rc4**
|
||||
- Permit the KDC to issue tickets with arcfour-hmac session keys.
|
||||
- In future releases, this flag will allow arcfour-hmac to be used
|
||||
- at all. The default value for this tag is false. (Added in
|
||||
- release 1.21.)
|
||||
-
|
||||
**allow_weak_crypto**
|
||||
If this flag is set to false, then weak encryption types (as noted
|
||||
in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered
|
||||
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
|
||||
index dce19ad43e..694922c0d9 100644
|
||||
--- a/doc/admin/enctypes.rst
|
||||
+++ b/doc/admin/enctypes.rst
|
||||
@@ -48,15 +48,12 @@ Session key selection
|
||||
The KDC chooses the session key enctype by taking the intersection of
|
||||
its **permitted_enctypes** list, the list of long-term keys for the
|
||||
most recent kvno of the service, and the client's requested list of
|
||||
-enctypes. Starting in krb5-1.21, all services are assumed to support
|
||||
-aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
|
||||
-keys will not be issued by default.
|
||||
+enctypes.
|
||||
|
||||
Starting in krb5-1.11, it is possible to set a string attribute on a
|
||||
service principal to control what session key enctypes the KDC may
|
||||
-issue for service tickets for that principal, overriding the service's
|
||||
-long-term keys and the assumption of aes256-cts-hmac-sha1-96 support.
|
||||
-See :ref:`set_string` in :ref:`kadmin(1)` for details.
|
||||
+issue for service tickets for that principal. See :ref:`set_string`
|
||||
+in :ref:`kadmin(1)` for details.
|
||||
|
||||
|
||||
Choosing enctypes for a service
|
||||
@@ -90,20 +87,6 @@ affect how enctypes are chosen.
|
||||
acceptable risk for your environment and the weak enctypes are
|
||||
required for backward compatibility.
|
||||
|
||||
-**allow_des3**
|
||||
- was added in release 1.21 and defaults to *false*. Unless this
|
||||
- flag is set to *true*, the KDC will not issue tickets with
|
||||
- des3-cbc-sha1 session keys. In a future release, this flag will
|
||||
- control whether des3-cbc-sha1 is permitted in similar fashion to
|
||||
- weak enctypes.
|
||||
-
|
||||
-**allow_rc4**
|
||||
- was added in release 1.21 and defaults to *false*. Unless this
|
||||
- flag is set to *true*, the KDC will not issue tickets with
|
||||
- arcfour-hmac session keys. In a future release, this flag will
|
||||
- control whether arcfour-hmac is permitted in similar fashion to
|
||||
- weak enctypes.
|
||||
-
|
||||
**permitted_enctypes**
|
||||
controls the set of enctypes that a service will permit for
|
||||
session keys and for ticket and authenticator encryption. The KDC
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index 2f7791b775..1d1c8293f4 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -180,8 +180,6 @@ typedef unsigned char u_char;
|
||||
* matches the variable name. Keep these alphabetized. */
|
||||
#define KRB5_CONF_ACL_FILE "acl_file"
|
||||
#define KRB5_CONF_ADMIN_SERVER "admin_server"
|
||||
-#define KRB5_CONF_ALLOW_DES3 "allow_des3"
|
||||
-#define KRB5_CONF_ALLOW_RC4 "allow_rc4"
|
||||
#define KRB5_CONF_ALLOW_WEAK_CRYPTO "allow_weak_crypto"
|
||||
#define KRB5_CONF_AUTH_TO_LOCAL "auth_to_local"
|
||||
#define KRB5_CONF_AUTH_TO_LOCAL_NAMES "auth_to_local_names"
|
||||
@@ -1240,8 +1238,6 @@ struct _krb5_context {
|
||||
struct _kdb_log_context *kdblog_context;
|
||||
|
||||
krb5_boolean allow_weak_crypto;
|
||||
- krb5_boolean allow_des3;
|
||||
- krb5_boolean allow_rc4;
|
||||
krb5_boolean ignore_acceptor_hostname;
|
||||
krb5_boolean enforce_ok_as_delegate;
|
||||
enum dns_canonhost dns_canonicalize_hostname;
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index e54cc751f9..75e04b73db 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -1088,16 +1088,6 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
|
||||
if (!krb5_is_permitted_enctype(context, ktype[i]))
|
||||
continue;
|
||||
|
||||
- /*
|
||||
- * Prevent these deprecated enctypes from being used as session keys
|
||||
- * unless they are explicitly allowed. In the future they will be more
|
||||
- * comprehensively disabled and eventually removed.
|
||||
- */
|
||||
- if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
|
||||
- continue;
|
||||
- if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
|
||||
- continue;
|
||||
-
|
||||
if (dbentry_supports_enctype(context, server, ktype[i]))
|
||||
return ktype[i];
|
||||
}
|
||||
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
||||
index ea089f0fcc..1b420a3ac2 100644
|
||||
--- a/src/lib/krb5/krb/get_in_tkt.c
|
||||
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
||||
@@ -1582,31 +1582,22 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||
(*prompter)(context, data, 0, banner, 0, 0);
|
||||
}
|
||||
|
||||
-/* Display a warning via the prompter if a deprecated enctype was used for
|
||||
- * either the reply key or the session key. */
|
||||
+/* Display a warning via the prompter if des3-cbc-sha1 was used for either the
|
||||
+ * reply key or the session key. */
|
||||
static void
|
||||
-warn_deprecated(krb5_context context, krb5_init_creds_context ctx,
|
||||
- krb5_enctype as_key_enctype)
|
||||
+warn_des3(krb5_context context, krb5_init_creds_context ctx,
|
||||
+ krb5_enctype as_key_enctype)
|
||||
{
|
||||
- krb5_enctype etype;
|
||||
- char encbuf[128], banner[256];
|
||||
+ const char *banner;
|
||||
|
||||
- if (ctx->prompter == NULL)
|
||||
- return;
|
||||
-
|
||||
- if (krb5int_c_deprecated_enctype(as_key_enctype))
|
||||
- etype = as_key_enctype;
|
||||
- else if (krb5int_c_deprecated_enctype(ctx->cred.keyblock.enctype))
|
||||
- etype = ctx->cred.keyblock.enctype;
|
||||
- else
|
||||
+ if (as_key_enctype != ENCTYPE_DES3_CBC_SHA1 &&
|
||||
+ ctx->cred.keyblock.enctype != ENCTYPE_DES3_CBC_SHA1)
|
||||
return;
|
||||
-
|
||||
- if (krb5_enctype_to_name(etype, FALSE, encbuf, sizeof(encbuf)) != 0)
|
||||
+ if (ctx->prompter == NULL)
|
||||
return;
|
||||
- snprintf(banner, sizeof(banner),
|
||||
- _("Warning: encryption type %s used for authentication is "
|
||||
- "deprecated and will be disabled"), encbuf);
|
||||
|
||||
+ banner = _("Warning: encryption type des3-cbc-sha1 used for "
|
||||
+ "authentication is weak and will be disabled");
|
||||
/* PROMPTER_INVOCATION */
|
||||
(*ctx->prompter)(context, ctx->prompter_data, NULL, banner, 0, NULL);
|
||||
}
|
||||
@@ -1857,7 +1848,7 @@ init_creds_step_reply(krb5_context context,
|
||||
ctx->complete = TRUE;
|
||||
warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
|
||||
ctx->in_tkt_service, ctx->reply);
|
||||
- warn_deprecated(context, ctx, encrypting_key.enctype);
|
||||
+ warn_des3(context, ctx, encrypting_key.enctype);
|
||||
|
||||
cleanup:
|
||||
krb5_free_pa_data(context, kdc_padata);
|
||||
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
|
||||
index a6c2bbeb54..87b486c53f 100644
|
||||
--- a/src/lib/krb5/krb/init_ctx.c
|
||||
+++ b/src/lib/krb5/krb/init_ctx.c
|
||||
@@ -221,16 +221,6 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
goto cleanup;
|
||||
ctx->allow_weak_crypto = tmp;
|
||||
|
||||
- retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
|
||||
- if (retval)
|
||||
- goto cleanup;
|
||||
- ctx->allow_des3 = tmp;
|
||||
-
|
||||
- retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
|
||||
- if (retval)
|
||||
- goto cleanup;
|
||||
- ctx->allow_rc4 = tmp;
|
||||
-
|
||||
retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
|
||||
index f5f11842e2..7494d7fcdb 100755
|
||||
--- a/src/tests/gssapi/t_enctypes.py
|
||||
+++ b/src/tests/gssapi/t_enctypes.py
|
||||
@@ -18,8 +18,7 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
|
||||
# These tests make assumptions about the default enctype lists, so set
|
||||
# them explicitly rather than relying on the library defaults.
|
||||
supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
|
||||
-conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
|
||||
- 'allow_des3': 'true', 'allow_rc4': 'true'},
|
||||
+conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4'},
|
||||
'realms': {'$realm': {'supported_enctypes': supp}}}
|
||||
realm = K5Realm(krb5_conf=conf)
|
||||
shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
|
||||
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
|
||||
index 38cf96ca8f..c982508d8b 100644
|
||||
--- a/src/tests/t_etype_info.py
|
||||
+++ b/src/tests/t_etype_info.py
|
||||
@@ -1,7 +1,7 @@
|
||||
from k5test import *
|
||||
|
||||
supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
|
||||
-conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
|
||||
+conf = {'libdefaults': {'allow_weak_crypto': 'true'},
|
||||
'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
|
||||
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
|
||||
|
||||
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
|
||||
index 5a213617b5..9024aee838 100755
|
||||
--- a/src/tests/t_sesskeynego.py
|
||||
+++ b/src/tests/t_sesskeynego.py
|
||||
@@ -25,8 +25,6 @@ conf3 = {'libdefaults': {
|
||||
'default_tkt_enctypes': 'aes128-cts',
|
||||
'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
|
||||
conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
|
||||
-conf5 = {'libdefaults': {'allow_rc4': 'true'}}
|
||||
-conf6 = {'libdefaults': {'allow_des3': 'true'}}
|
||||
# Test with client request and session_enctypes preferring aes128, but
|
||||
# aes256 long-term key.
|
||||
realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
|
||||
@@ -56,12 +54,10 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
|
||||
'aes128-cts,aes256-cts'])
|
||||
test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
|
||||
|
||||
-# 3b: Skip RC4 (as the KDC does not allow it for session keys by
|
||||
-# default) and negotiate aes128-cts session key, with only an aes256
|
||||
-# long-term service key.
|
||||
+# 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
|
||||
realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
|
||||
'rc4-hmac,aes128-cts,aes256-cts'])
|
||||
-test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
|
||||
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
|
||||
realm.stop()
|
||||
|
||||
# 4: Check that permitted_enctypes is a default for session key enctypes.
|
||||
@@ -71,24 +67,4 @@ realm.run([kvno, 'user'],
|
||||
expected_trace=('etypes requested in TGS request: aes256-cts',))
|
||||
realm.stop()
|
||||
|
||||
-# 5: allow_rc4 permits negotiation of rc4-hmac session key.
|
||||
-realm = K5Realm(krb5_conf=conf5, create_host=False, get_creds=False)
|
||||
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
|
||||
-realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
|
||||
-test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
|
||||
-realm.stop()
|
||||
-
|
||||
-# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
|
||||
-realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
|
||||
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
|
||||
-realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
|
||||
-test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
|
||||
-realm.stop()
|
||||
-
|
||||
-# 7: default config negotiates aes256-sha1 session key for RC4-only service.
|
||||
-realm = K5Realm(create_host=False, get_creds=False)
|
||||
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
|
||||
-test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'DEPRECATED:arcfour-hmac')
|
||||
-realm.stop()
|
||||
-
|
||||
success('sesskeynego')
|
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
||||
index 8e5f5ba8e9..2a86c5cdfc 100644
|
||||
--- a/src/util/k5test.py
|
||||
+++ b/src/util/k5test.py
|
||||
@@ -1340,14 +1340,14 @@ _passes = [
|
||||
|
||||
# Exercise the DES3 enctype.
|
||||
('des3', None,
|
||||
- {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
|
||||
+ {'libdefaults': {'permitted_enctypes': 'des3'}},
|
||||
{'realms': {'$realm': {
|
||||
'supported_enctypes': 'des3-cbc-sha1:normal',
|
||||
'master_key_type': 'des3-cbc-sha1'}}}),
|
||||
|
||||
# Exercise the arcfour enctype.
|
||||
('arcfour', None,
|
||||
- {'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
|
||||
+ {'libdefaults': {'permitted_enctypes': 'rc4'}},
|
||||
{'realms': {'$realm': {
|
||||
'supported_enctypes': 'arcfour-hmac:normal',
|
||||
'master_key_type': 'arcfour-hmac'}}}),
|
||||
--
|
||||
2.45.1
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From 9feb7298b90d3e6a34821fce7315757c0bf81c9e Mon Sep 17 00:00:00 2001
|
||||
From de4205c45e310ceaaa7cd7958af7293322fa43a6 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 23 Aug 2016 16:29:58 -0400
|
||||
Subject: [PATCH] [downstream] ksu pam integration
|
||||
|
|
@ -30,10 +30,10 @@ Last-updated: krb5-1.18-beta1
|
|||
create mode 100644 src/clients/ksu/pam.h
|
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
||||
index 2394f7e33..830203683 100644
|
||||
index 3d66a876b3..ce3c5a9bac 100644
|
||||
--- a/src/aclocal.m4
|
||||
+++ b/src/aclocal.m4
|
||||
@@ -1675,3 +1675,72 @@ if test "$with_ldap" = yes; then
|
||||
@@ -1458,3 +1458,72 @@ if test "$with_ldap" = yes; then
|
||||
OPENLDAP_PLUGIN=yes
|
||||
fi
|
||||
])dnl
|
||||
|
|
@ -107,7 +107,7 @@ index 2394f7e33..830203683 100644
|
|||
+])dnl
|
||||
+
|
||||
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
|
||||
index 8b4edce4d..9d58f29b5 100644
|
||||
index 8b4edce4d8..9d58f29b5d 100644
|
||||
--- a/src/clients/ksu/Makefile.in
|
||||
+++ b/src/clients/ksu/Makefile.in
|
||||
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
|
||||
|
|
@ -145,11 +145,11 @@ index 8b4edce4d..9d58f29b5 100644
|
|||
clean:
|
||||
$(RM) ksu
|
||||
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
|
||||
index 57c349200..508242e0e 100644
|
||||
index af12861729..931f054041 100644
|
||||
--- a/src/clients/ksu/main.c
|
||||
+++ b/src/clients/ksu/main.c
|
||||
@@ -26,6 +26,7 @@
|
||||
* KSU was writen by: Ari Medvinsky, ari@isi.edu
|
||||
* KSU was written by: Ari Medvinsky, ari@isi.edu
|
||||
*/
|
||||
|
||||
+#include "autoconf.h"
|
||||
|
|
@ -303,7 +303,7 @@ index 57c349200..508242e0e 100644
|
|||
}
|
||||
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
|
||||
new file mode 100644
|
||||
index 000000000..cbfe48704
|
||||
index 0000000000..cbfe487047
|
||||
--- /dev/null
|
||||
+++ b/src/clients/ksu/pam.c
|
||||
@@ -0,0 +1,389 @@
|
||||
|
|
@ -698,7 +698,7 @@ index 000000000..cbfe48704
|
|||
+#endif
|
||||
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
|
||||
new file mode 100644
|
||||
index 000000000..0ab76569c
|
||||
index 0000000000..0ab76569cb
|
||||
--- /dev/null
|
||||
+++ b/src/clients/ksu/pam.h
|
||||
@@ -0,0 +1,57 @@
|
||||
|
|
@ -760,10 +760,10 @@ index 000000000..0ab76569c
|
|||
+void appl_pam_cleanup(void);
|
||||
+#endif
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 234f4281c..d1f576124 100644
|
||||
index 77be7a2025..587221936e 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1390,6 +1390,8 @@ AC_SUBST([VERTO_VERSION])
|
||||
@@ -1399,6 +1399,8 @@ AC_SUBST([VERTO_VERSION])
|
||||
|
||||
AC_PATH_PROG(GROFF, groff)
|
||||
|
||||
|
|
@ -772,3 +772,6 @@ index 234f4281c..d1f576124 100644
|
|||
# Make localedir work in autoconf 2.5x.
|
||||
if test "${localedir+set}" != set; then
|
||||
localedir='$(datadir)/locale'
|
||||
--
|
||||
2.45.1
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From f8c70f6190a0573e2aca0b40964cf3b1a73ca8bb Mon Sep 17 00:00:00 2001
|
||||
From 30ff501e4b519396f5aea25e24919be817863e7c Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 23 Aug 2016 16:30:53 -0400
|
||||
Subject: [PATCH] [downstream] SELinux integration
|
||||
|
|
@ -36,7 +36,9 @@ The selabel APIs for looking up the context should be thread-safe (per
|
|||
Red Hat #273081), so switching to using them instead of matchpathcon(),
|
||||
which we used earlier, is some improvement.
|
||||
|
||||
Last-updated: krb5-1.18-beta1
|
||||
Last-updated: krb5-1.20.1
|
||||
[jrische@redhat.com: Replace deprecated security_context_t by char *:
|
||||
- src/util/support/selinux.c]
|
||||
---
|
||||
src/aclocal.m4 | 48 +++
|
||||
src/build-tools/krb5-config.in | 3 +-
|
||||
|
|
@ -61,16 +63,16 @@ Last-updated: krb5-1.18-beta1
|
|||
.../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +-
|
||||
src/util/profile/prof_file.c | 3 +-
|
||||
src/util/support/Makefile.in | 3 +-
|
||||
src/util/support/selinux.c | 406 ++++++++++++++++++
|
||||
24 files changed, 573 insertions(+), 21 deletions(-)
|
||||
src/util/support/selinux.c | 405 ++++++++++++++++++
|
||||
24 files changed, 572 insertions(+), 21 deletions(-)
|
||||
create mode 100644 src/include/k5-label.h
|
||||
create mode 100644 src/util/support/selinux.c
|
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
||||
index 830203683..6796fec53 100644
|
||||
index ce3c5a9bac..3331970930 100644
|
||||
--- a/src/aclocal.m4
|
||||
+++ b/src/aclocal.m4
|
||||
@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag)
|
||||
@@ -85,6 +85,7 @@ AC_SUBST_FILE(libnodeps_frag)
|
||||
dnl
|
||||
KRB5_AC_PRAGMA_WEAK_REF
|
||||
WITH_LDAP
|
||||
|
|
@ -78,7 +80,7 @@ index 830203683..6796fec53 100644
|
|||
KRB5_LIB_PARAMS
|
||||
KRB5_AC_INITFINI
|
||||
KRB5_AC_ENABLE_THREADS
|
||||
@@ -1743,4 +1744,51 @@ AC_SUBST(PAM_LIBS)
|
||||
@@ -1526,4 +1527,51 @@ AC_SUBST(PAM_LIBS)
|
||||
AC_SUBST(PAM_MAN)
|
||||
AC_SUBST(NON_PAM_MAN)
|
||||
])dnl
|
||||
|
|
@ -131,10 +133,10 @@ index 830203683..6796fec53 100644
|
|||
+AC_SUBST(SELINUX_LIBS)
|
||||
+])dnl
|
||||
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
|
||||
index f6184da3f..c17cb5eb5 100755
|
||||
index 8e6eb86601..7677f37359 100755
|
||||
--- a/src/build-tools/krb5-config.in
|
||||
+++ b/src/build-tools/krb5-config.in
|
||||
@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@'
|
||||
@@ -40,6 +40,7 @@ DL_LIB='@DL_LIB@'
|
||||
DEFCCNAME='@DEFCCNAME@'
|
||||
DEFKTNAME='@DEFKTNAME@'
|
||||
DEFCKTNAME='@DEFCKTNAME@'
|
||||
|
|
@ -142,7 +144,7 @@ index f6184da3f..c17cb5eb5 100755
|
|||
|
||||
LIBS='@LIBS@'
|
||||
GEN_LIB=@GEN_LIB@
|
||||
@@ -255,7 +256,7 @@ if test -n "$do_libs"; then
|
||||
@@ -253,7 +254,7 @@ if test -n "$do_libs"; then
|
||||
fi
|
||||
|
||||
# If we ever support a flag to generate output suitable for static
|
||||
|
|
@ -152,7 +154,7 @@ index f6184da3f..c17cb5eb5 100755
|
|||
|
||||
echo $lib_flags
|
||||
diff --git a/src/config/pre.in b/src/config/pre.in
|
||||
index ce87e21ca..917357df9 100644
|
||||
index a0c60c70b3..7eaa2f351c 100644
|
||||
--- a/src/config/pre.in
|
||||
+++ b/src/config/pre.in
|
||||
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
|
||||
|
|
@ -163,7 +165,7 @@ index ce87e21ca..917357df9 100644
|
|||
|
||||
INSTALL=@INSTALL@
|
||||
INSTALL_STRIP=
|
||||
@@ -402,7 +403,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
|
||||
@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
|
||||
# HESIOD_LIBS is -lhesiod...
|
||||
HESIOD_LIBS = @HESIOD_LIBS@
|
||||
|
||||
|
|
@ -173,10 +175,10 @@ index ce87e21ca..917357df9 100644
|
|||
GSS_LIBS = $(GSS_KRB5_LIB)
|
||||
# needs fixing if ever used on macOS!
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index d1f576124..440a22bd9 100644
|
||||
index 587221936e..69be9030f8 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1392,6 +1392,8 @@ AC_PATH_PROG(GROFF, groff)
|
||||
@@ -1401,6 +1401,8 @@ AC_PATH_PROG(GROFF, groff)
|
||||
|
||||
KRB5_WITH_PAM
|
||||
|
||||
|
|
@ -186,7 +188,7 @@ index d1f576124..440a22bd9 100644
|
|||
if test "${localedir+set}" != set; then
|
||||
localedir='$(datadir)/locale'
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index 9616b24bf..0d9af3d95 100644
|
||||
index 1d1c8293f4..768110e5ef 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
|
||||
|
|
@ -199,7 +201,7 @@ index 9616b24bf..0d9af3d95 100644
|
|||
#define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */
|
||||
diff --git a/src/include/k5-label.h b/src/include/k5-label.h
|
||||
new file mode 100644
|
||||
index 000000000..dfaaa847c
|
||||
index 0000000000..dfaaa847cb
|
||||
--- /dev/null
|
||||
+++ b/src/include/k5-label.h
|
||||
@@ -0,0 +1,32 @@
|
||||
|
|
@ -236,10 +238,10 @@ index 000000000..dfaaa847c
|
|||
+#endif
|
||||
+#endif
|
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||
index 79761f6d2..e9435c693 100644
|
||||
index 4e09ed345d..09f800be52 100644
|
||||
--- a/src/include/krb5/krb5.hin
|
||||
+++ b/src/include/krb5/krb5.hin
|
||||
@@ -87,6 +87,12 @@
|
||||
@@ -83,6 +83,12 @@
|
||||
#define THREEPARAMOPEN(x,y,z) open(x,y,z)
|
||||
#endif
|
||||
|
||||
|
|
@ -253,7 +255,7 @@ index 79761f6d2..e9435c693 100644
|
|||
|
||||
#include <stdlib.h>
|
||||
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
|
||||
index 301e3476d..19f2cc230 100644
|
||||
index a89b5144f6..4d6cc0bdf9 100644
|
||||
--- a/src/kadmin/dbutil/dump.c
|
||||
+++ b/src/kadmin/dbutil/dump.c
|
||||
@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname)
|
||||
|
|
@ -288,10 +290,10 @@ index 301e3476d..19f2cc230 100644
|
|||
com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
|
||||
goto cleanup;
|
||||
diff --git a/src/kdc/main.c b/src/kdc/main.c
|
||||
index fdcd694d7..1ede4bf2f 100644
|
||||
index bfdfef5c48..b43fe9a082 100644
|
||||
--- a/src/kdc/main.c
|
||||
+++ b/src/kdc/main.c
|
||||
@@ -872,7 +872,7 @@ write_pid_file(const char *path)
|
||||
@@ -844,7 +844,7 @@ write_pid_file(const char *path)
|
||||
FILE *file;
|
||||
unsigned long pid;
|
||||
|
||||
|
|
@ -301,10 +303,10 @@ index fdcd694d7..1ede4bf2f 100644
|
|||
return errno;
|
||||
pid = (unsigned long) getpid();
|
||||
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
|
||||
index 5622d56e1..356e3e0e6 100644
|
||||
index aa3c81ea30..cb9785aaeb 100644
|
||||
--- a/src/kprop/kpropd.c
|
||||
+++ b/src/kprop/kpropd.c
|
||||
@@ -487,6 +487,9 @@ doit(int fd)
|
||||
@@ -488,6 +488,9 @@ doit(int fd)
|
||||
krb5_enctype etype;
|
||||
int database_fd;
|
||||
char host[INET6_ADDRSTRLEN + 1];
|
||||
|
|
@ -314,7 +316,7 @@ index 5622d56e1..356e3e0e6 100644
|
|||
|
||||
signal_wrapper(SIGALRM, alarm_handler);
|
||||
alarm(params.iprop_resync_timeout);
|
||||
@@ -542,9 +545,15 @@ doit(int fd)
|
||||
@@ -543,9 +546,15 @@ doit(int fd)
|
||||
free(name);
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -331,10 +333,10 @@ index 5622d56e1..356e3e0e6 100644
|
|||
KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
|
||||
if (retval) {
|
||||
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
|
||||
index c6885edf2..9aec3c05e 100644
|
||||
index e14da53790..b879a4049b 100644
|
||||
--- a/src/lib/kadm5/logger.c
|
||||
+++ b/src/lib/kadm5/logger.c
|
||||
@@ -309,7 +309,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
|
||||
@@ -310,7 +310,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
|
||||
*/
|
||||
append = (cp[4] == ':') ? O_APPEND : 0;
|
||||
if (append || cp[4] == '=') {
|
||||
|
|
@ -343,7 +345,7 @@ index c6885edf2..9aec3c05e 100644
|
|||
S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
if (fd != -1)
|
||||
f = fdopen(fd, append ? "a" : "w");
|
||||
@@ -776,7 +776,7 @@ krb5_klog_reopen(krb5_context kcontext)
|
||||
@@ -777,7 +777,7 @@ krb5_klog_reopen(krb5_context kcontext)
|
||||
* In case the old logfile did not get moved out of the
|
||||
* way, open for append to prevent squashing the old logs.
|
||||
*/
|
||||
|
|
@ -353,7 +355,7 @@ index c6885edf2..9aec3c05e 100644
|
|||
set_cloexec_file(f);
|
||||
log_control.log_entries[lindex].lfu_filep = f;
|
||||
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
|
||||
index 2659a2501..e9b95fce5 100644
|
||||
index 2659a25018..e9b95fce59 100644
|
||||
--- a/src/lib/kdb/kdb_log.c
|
||||
+++ b/src/lib/kdb/kdb_log.c
|
||||
@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
|
||||
|
|
@ -366,7 +368,7 @@ index 2659a2501..e9b95fce5 100644
|
|||
retval = errno;
|
||||
goto cleanup;
|
||||
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
|
||||
index 7b100a0ec..5683a0433 100644
|
||||
index 1da40b51d0..f3ab7340a6 100644
|
||||
--- a/src/lib/krb5/ccache/cc_dir.c
|
||||
+++ b/src/lib/krb5/ccache/cc_dir.c
|
||||
@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents)
|
||||
|
|
@ -416,7 +418,7 @@ index 7b100a0ec..5683a0433 100644
|
|||
_("Credential cache directory %s does not exist"),
|
||||
dirname);
|
||||
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
|
||||
index 021c94398..aaf573439 100644
|
||||
index e510211fc5..f3ea28c8ec 100644
|
||||
--- a/src/lib/krb5/keytab/kt_file.c
|
||||
+++ b/src/lib/krb5/keytab/kt_file.c
|
||||
@@ -735,14 +735,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
|
||||
|
|
@ -437,10 +439,10 @@ index 021c94398..aaf573439 100644
|
|||
goto report_errno;
|
||||
writevno = 1;
|
||||
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
|
||||
index 7073459f0..e9b99f4ca 100644
|
||||
index 4cbbbb270a..c4058ddc96 100644
|
||||
--- a/src/lib/krb5/os/trace.c
|
||||
+++ b/src/lib/krb5/os/trace.c
|
||||
@@ -458,7 +458,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
|
||||
@@ -460,7 +460,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
|
||||
fd = malloc(sizeof(*fd));
|
||||
if (fd == NULL)
|
||||
return ENOMEM;
|
||||
|
|
@ -450,7 +452,7 @@ index 7073459f0..e9b99f4ca 100644
|
|||
free(fd);
|
||||
return errno;
|
||||
diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c
|
||||
index 7db30a33b..2b9d01921 100644
|
||||
index 9a506e9d44..f92ab47143 100644
|
||||
--- a/src/plugins/kdb/db2/adb_openclose.c
|
||||
+++ b/src/plugins/kdb/db2/adb_openclose.c
|
||||
@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename,
|
||||
|
|
@ -463,7 +465,7 @@ index 7db30a33b..2b9d01921 100644
|
|||
* maybe someone took away write permission so we could only
|
||||
* get shared locks?
|
||||
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
|
||||
index 5106a5c99..e481e8121 100644
|
||||
index 2c163d91cc..9a344a603e 100644
|
||||
--- a/src/plugins/kdb/db2/kdb_db2.c
|
||||
+++ b/src/plugins/kdb/db2/kdb_db2.c
|
||||
@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
|
||||
|
|
@ -478,7 +480,7 @@ index 5106a5c99..e481e8121 100644
|
|||
retval = errno;
|
||||
goto cleanup;
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
index 2977b17f3..d5809a5a9 100644
|
||||
index 2977b17f3a..d5809a5a93 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.11 (Berkeley) 11/2/95";
|
||||
|
|
@ -499,7 +501,7 @@ index 2977b17f3..d5809a5a9 100644
|
|||
|
||||
} else {
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c
|
||||
index 862dbb164..686a960c9 100644
|
||||
index 862dbb1640..686a960c96 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/hash/hash.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/hash/hash.c
|
||||
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95";
|
||||
|
|
@ -520,7 +522,7 @@ index 862dbb164..686a960c9 100644
|
|||
(void)fcntl(hashp->fp, F_SETFD, 1);
|
||||
}
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
||||
index d8b26e701..b0daa7c02 100644
|
||||
index d8b26e7011..b0daa7c021 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
||||
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c 8.12 (Berkeley) 11/18/94";
|
||||
|
|
@ -542,7 +544,7 @@ index d8b26e701..b0daa7c02 100644
|
|||
|
||||
if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
|
||||
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
|
||||
index b92cb58c7..0a95101ad 100644
|
||||
index e87688d666..30f7c00ab5 100644
|
||||
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
|
||||
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
|
||||
@@ -190,7 +190,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
|
||||
|
|
@ -579,7 +581,7 @@ index b92cb58c7..0a95101ad 100644
|
|||
if (newfile == NULL) {
|
||||
com_err(me, errno, _("Error creating file %s"), tmp_file);
|
||||
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
|
||||
index aa951df05..79f9500f6 100644
|
||||
index aa951df05f..79f9500f69 100644
|
||||
--- a/src/util/profile/prof_file.c
|
||||
+++ b/src/util/profile/prof_file.c
|
||||
@@ -33,6 +33,7 @@
|
||||
|
|
@ -600,7 +602,7 @@ index aa951df05..79f9500f6 100644
|
|||
retval = errno;
|
||||
if (retval == 0)
|
||||
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
|
||||
index 86d5a950a..1052d53a1 100644
|
||||
index 86d5a950a6..1052d53a1e 100644
|
||||
--- a/src/util/support/Makefile.in
|
||||
+++ b/src/util/support/Makefile.in
|
||||
@@ -74,6 +74,7 @@ IPC_SYMS= \
|
||||
|
|
@ -622,10 +624,10 @@ index 86d5a950a..1052d53a1 100644
|
|||
|
||||
diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c
|
||||
new file mode 100644
|
||||
index 000000000..6d41f3244
|
||||
index 0000000000..807d039da3
|
||||
--- /dev/null
|
||||
+++ b/src/util/support/selinux.c
|
||||
@@ -0,0 +1,406 @@
|
||||
@@ -0,0 +1,405 @@
|
||||
+/*
|
||||
+ * Copyright 2007,2008,2009,2011,2012,2013,2016 Red Hat, Inc. All Rights Reserved.
|
||||
+ *
|
||||
|
|
@ -724,17 +726,16 @@ index 000000000..6d41f3244
|
|||
+ }
|
||||
+}
|
||||
+
|
||||
+static security_context_t
|
||||
+static char *
|
||||
+push_fscreatecon(const char *pathname, mode_t mode)
|
||||
+{
|
||||
+ security_context_t previous, configuredsc, currentsc, derivedsc;
|
||||
+ char *previous, *configuredsc, *currentsc, *genpath;
|
||||
+ const char *derivedsc, *fullpath, *currentuser;
|
||||
+ context_t current, derived;
|
||||
+ const char *fullpath, *currentuser;
|
||||
+ char *genpath;
|
||||
+
|
||||
+ previous = configuredsc = currentsc = derivedsc = NULL;
|
||||
+ previous = configuredsc = currentsc = genpath = NULL;
|
||||
+ derivedsc = NULL;
|
||||
+ current = derived = NULL;
|
||||
+ genpath = NULL;
|
||||
+
|
||||
+ fullpath = pathname;
|
||||
+
|
||||
|
|
@ -862,7 +863,7 @@ index 000000000..6d41f3244
|
|||
+}
|
||||
+
|
||||
+static void
|
||||
+pop_fscreatecon(security_context_t previous)
|
||||
+pop_fscreatecon(char *previous)
|
||||
+{
|
||||
+ if (!is_selinux_enabled()) {
|
||||
+ return;
|
||||
|
|
@ -916,7 +917,7 @@ index 000000000..6d41f3244
|
|||
+{
|
||||
+ FILE *fp;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ if ((strcmp(mode, "r") == 0) ||
|
||||
+ (strcmp(mode, "rb") == 0)) {
|
||||
|
|
@ -942,7 +943,7 @@ index 000000000..6d41f3244
|
|||
+{
|
||||
+ int fd;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ k5_once(&labeled_once, label_mutex_init);
|
||||
+ k5_mutex_lock(&labeled_mutex);
|
||||
|
|
@ -963,7 +964,7 @@ index 000000000..6d41f3244
|
|||
+{
|
||||
+ int ret;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ k5_once(&labeled_once, label_mutex_init);
|
||||
+ k5_mutex_lock(&labeled_mutex);
|
||||
|
|
@ -984,7 +985,7 @@ index 000000000..6d41f3244
|
|||
+{
|
||||
+ int ret;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ k5_once(&labeled_once, label_mutex_init);
|
||||
+ k5_mutex_lock(&labeled_mutex);
|
||||
|
|
@ -1005,7 +1006,7 @@ index 000000000..6d41f3244
|
|||
+{
|
||||
+ int fd;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+ mode_t mode;
|
||||
+ va_list ap;
|
||||
+
|
||||
|
|
@ -1032,3 +1033,6 @@ index 000000000..6d41f3244
|
|||
+}
|
||||
+
|
||||
+#endif /* USE_SELINUX */
|
||||
--
|
||||
2.45.1
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From c6e103db0eb02c31a13b8cbcbae296c473074991 Mon Sep 17 00:00:00 2001
|
||||
From 393830d96000ed692aa9a99ef87187d6f2863931 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 23 Aug 2016 16:49:25 -0400
|
||||
Subject: [PATCH] [downstream] fix debuginfo with y.tab.c
|
||||
|
|
@ -14,7 +14,7 @@ Last-updated: krb5-1.9
|
|||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in
|
||||
index adfea6e2b..d1327e400 100644
|
||||
index adfea6e2b5..d1327e400b 100644
|
||||
--- a/src/kadmin/cli/Makefile.in
|
||||
+++ b/src/kadmin/cli/Makefile.in
|
||||
@@ -37,3 +37,8 @@ clean-unix::
|
||||
|
|
@ -27,7 +27,7 @@ index adfea6e2b..d1327e400 100644
|
|||
+ $(YACC.y) $<
|
||||
+ $(CP) y.tab.c $@
|
||||
diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||
index 8669c2436..a22f23c02 100644
|
||||
index 8669c2436c..a22f23c02c 100644
|
||||
--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||
+++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE)
|
||||
|
|
@ -39,3 +39,6 @@ index 8669c2436..a22f23c02 100644
|
|||
|
||||
install:
|
||||
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
|
||||
--
|
||||
2.45.1
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
From bf8521bfaa4a4d54f6eb94f785c68942f4afa055 Mon Sep 17 00:00:00 2001
|
||||
From 7b6453903c248a761d3ceb538dfacebbf3d3a9ff Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Fri, 9 Nov 2018 15:12:21 -0500
|
||||
Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4
|
||||
|
|
@ -19,10 +19,12 @@ post6 restores MD4 (and therefore keygen-only RC4).
|
|||
|
||||
post7 restores MD5 and adds radius_md5_fips_override.
|
||||
|
||||
Last-updated: krb5-1.17
|
||||
post8 silences a static analyzer warning.
|
||||
|
||||
Last-updated: krb5-1.20
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 6 +++
|
||||
src/lib/crypto/krb/prng.c | 11 ++++-
|
||||
src/lib/crypto/krb/prng.c | 15 +++++-
|
||||
.../crypto/openssl/enc_provider/camellia.c | 6 +++
|
||||
src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++++-
|
||||
.../crypto/openssl/hash_provider/hash_evp.c | 12 +++++
|
||||
|
|
@ -36,13 +38,13 @@ Last-updated: krb5-1.17
|
|||
src/lib/krad/t_attrset.c | 4 +-
|
||||
src/plugins/preauth/spake/spake_client.c | 6 +++
|
||||
src/plugins/preauth/spake/spake_kdc.c | 6 +++
|
||||
15 files changed, 151 insertions(+), 33 deletions(-)
|
||||
15 files changed, 155 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index 1d2aa7f68..3a8b9cf47 100644
|
||||
index f22d5db11b..a33711d918 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -331,6 +331,12 @@ The libdefaults section may contain any of the following relations:
|
||||
@@ -330,6 +330,12 @@ The libdefaults section may contain any of the following relations:
|
||||
qualification of shortnames, set this relation to the empty string
|
||||
with ``qualify_shortname = ""``. (New in release 1.18.)
|
||||
|
||||
|
|
@ -56,22 +58,26 @@ index 1d2aa7f68..3a8b9cf47 100644
|
|||
If this flag is true, reverse name lookup will be used in addition
|
||||
to forward name lookup to canonicalizing hostnames for use in
|
||||
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
|
||||
index cb9ca9b98..f0e9984ca 100644
|
||||
index d6b79e2dea..9e80a03d21 100644
|
||||
--- a/src/lib/crypto/krb/prng.c
|
||||
+++ b/src/lib/crypto/krb/prng.c
|
||||
@@ -26,6 +26,8 @@
|
||||
@@ -26,6 +26,12 @@
|
||||
|
||||
#include "crypto_int.h"
|
||||
|
||||
+#include <openssl/rand.h>
|
||||
+
|
||||
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
+#include <openssl/crypto.h>
|
||||
+#endif
|
||||
+
|
||||
krb5_error_code KRB5_CALLCONV
|
||||
krb5_c_random_seed(krb5_context context, krb5_data *data)
|
||||
{
|
||||
@@ -99,9 +101,16 @@ krb5_boolean
|
||||
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
|
||||
@@ -96,9 +102,16 @@ cleanup:
|
||||
static krb5_boolean
|
||||
get_os_entropy(unsigned char *buf, size_t len)
|
||||
{
|
||||
const char *device;
|
||||
-#if defined(__linux__) && defined(SYS_getrandom)
|
||||
int r;
|
||||
|
||||
|
|
@ -87,10 +93,10 @@ index cb9ca9b98..f0e9984ca 100644
|
|||
/*
|
||||
* Pull from the /dev/urandom pool, but require it to have been seeded.
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
index 2da691329..f79679a0b 100644
|
||||
index 01920e6ce1..d9f327add6 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
|
||||
@@ -387,6 +387,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
|
||||
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
|
||||
struct iov_cursor cursor;
|
||||
|
||||
|
|
@ -100,7 +106,7 @@ index 2da691329..f79679a0b 100644
|
|||
if (output->length < CAMELLIA_BLOCK_SIZE)
|
||||
return KRB5_BAD_MSIZE;
|
||||
|
||||
@@ -331,6 +334,9 @@ static krb5_error_code
|
||||
@@ -418,6 +421,9 @@ static krb5_error_code
|
||||
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
|
||||
krb5_data *state)
|
||||
{
|
||||
|
|
@ -111,10 +117,10 @@ index 2da691329..f79679a0b 100644
|
|||
state->data = (void *) malloc(16);
|
||||
if (state->data == NULL)
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
index a65d57b7a..6ccaca94a 100644
|
||||
index 448d563348..ce63cb5f1b 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
@@ -69,6 +69,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
struct arcfour_state *arcstate;
|
||||
|
||||
|
|
@ -124,7 +130,7 @@ index a65d57b7a..6ccaca94a 100644
|
|||
arcstate = (state != NULL) ? (void *)state->data : NULL;
|
||||
if (arcstate != NULL) {
|
||||
ctx = arcstate->ctx;
|
||||
@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
@@ -116,7 +119,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
static void
|
||||
k5_arcfour_free_state(krb5_data *state)
|
||||
{
|
||||
|
|
@ -138,7 +144,7 @@ index a65d57b7a..6ccaca94a 100644
|
|||
|
||||
EVP_CIPHER_CTX_free(arcstate->ctx);
|
||||
free(arcstate);
|
||||
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
|
||||
@@ -128,6 +136,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
|
||||
{
|
||||
struct arcfour_state *arcstate;
|
||||
|
||||
|
|
@ -149,10 +155,10 @@ index a65d57b7a..6ccaca94a 100644
|
|||
* The cipher state here is a saved pointer to a struct arcfour_state
|
||||
* object, rather than a flat byte array as in most enc providers. The
|
||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
index 1e0fb8fc3..2eb5139c0 100644
|
||||
index f2fbffdb29..11659908bb 100644
|
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
@@ -49,6 +49,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
@@ -60,6 +60,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
|
|
@ -164,7 +170,7 @@ index 1e0fb8fc3..2eb5139c0 100644
|
|||
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||
for (i = 0; i < num_data; i++) {
|
||||
if (!SIGN_IOV(&data[i]))
|
||||
@@ -64,12 +69,19 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
@@ -78,6 +83,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
static krb5_error_code
|
||||
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||
{
|
||||
|
|
@ -176,6 +182,7 @@ index 1e0fb8fc3..2eb5139c0 100644
|
|||
return hash_evp(EVP_md4(), data, num_data, output);
|
||||
}
|
||||
|
||||
@@ -90,6 +100,8 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||
static krb5_error_code
|
||||
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||
{
|
||||
|
|
@ -185,24 +192,24 @@ index 1e0fb8fc3..2eb5139c0 100644
|
|||
}
|
||||
|
||||
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
|
||||
index 7dc59dcc0..769a50c00 100644
|
||||
index bf12b8d6a0..f21e268f7f 100644
|
||||
--- a/src/lib/crypto/openssl/hmac.c
|
||||
+++ b/src/lib/crypto/openssl/hmac.c
|
||||
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
|
||||
@@ -111,7 +111,11 @@ map_digest(const struct krb5_hash_provider *hash)
|
||||
return EVP_sha256();
|
||||
else if (!strncmp(hash->hash_name, "SHA-384",7))
|
||||
else if (hash == &krb5int_hash_sha384)
|
||||
return EVP_sha384();
|
||||
- else if (!strncmp(hash->hash_name, "MD5", 3))
|
||||
- else if (hash == &krb5int_hash_md5)
|
||||
+
|
||||
+ if (FIPS_mode())
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!strncmp(hash->hash_name, "MD5", 3))
|
||||
+ if (hash == &krb5int_hash_md5)
|
||||
return EVP_md5();
|
||||
else if (!strncmp(hash->hash_name, "MD4", 3))
|
||||
else if (hash == &krb5int_hash_md4)
|
||||
return EVP_md4();
|
||||
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
|
||||
index 9c13d9d75..42d354a3b 100644
|
||||
index 9c13d9d755..42d354a3b5 100644
|
||||
--- a/src/lib/krad/attr.c
|
||||
+++ b/src/lib/krad/attr.c
|
||||
@@ -38,7 +38,8 @@
|
||||
|
|
@ -326,7 +333,7 @@ index 9c13d9d75..42d354a3b 100644
|
|||
|
||||
krad_attr
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||
index 03c613716..d89982a13 100644
|
||||
index f309f1581c..6ec031e320 100644
|
||||
--- a/src/lib/krad/attrset.c
|
||||
+++ b/src/lib/krad/attrset.c
|
||||
@@ -167,7 +167,8 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
|
||||
|
|
@ -349,7 +356,7 @@ index 03c613716..d89982a13 100644
|
|||
return retval;
|
||||
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index 996a89372..312dc8258 100644
|
||||
index 7619563fc5..e123763954 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -39,6 +39,8 @@
|
||||
|
|
@ -395,7 +402,7 @@ index 996a89372..312dc8258 100644
|
|||
|
||||
/* Decode attributes from a buffer. */
|
||||
krb5_error_code
|
||||
@@ -152,4 +163,17 @@ gai_error_code(int err)
|
||||
@@ -156,4 +167,17 @@ gai_error_code(int err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -407,14 +414,14 @@ index 996a89372..312dc8258 100644
|
|||
+ if (!FIPS_mode())
|
||||
+ return 0;
|
||||
+
|
||||
+ profile_get_boolean(ctx->profile, "libdefaults",
|
||||
+ "radius_md5_fips_override", NULL, 0, &val);
|
||||
+ (void)profile_get_boolean(ctx->profile, "libdefaults",
|
||||
+ "radius_md5_fips_override", NULL, 0, &val);
|
||||
+ return !val;
|
||||
+}
|
||||
+
|
||||
#endif /* INTERNAL_H_ */
|
||||
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||
index c597174b6..fc2d24800 100644
|
||||
index c597174b65..fc2d248001 100644
|
||||
--- a/src/lib/krad/packet.c
|
||||
+++ b/src/lib/krad/packet.c
|
||||
@@ -53,12 +53,6 @@ typedef unsigned char uchar;
|
||||
|
|
@ -475,7 +482,7 @@ index c597174b6..fc2d24800 100644
|
|||
}
|
||||
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||
index 437f7e91a..0f90443ce 100644
|
||||
index 06ae751bc8..929f1cef67 100644
|
||||
--- a/src/lib/krad/remote.c
|
||||
+++ b/src/lib/krad/remote.c
|
||||
@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr)
|
||||
|
|
@ -496,7 +503,7 @@ index 437f7e91a..0f90443ce 100644
|
|||
request_finish(r, 0, rsp);
|
||||
break;
|
||||
}
|
||||
@@ -455,6 +455,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
@@ -460,6 +460,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
(krad_packet_iter_cb)iterator, &r, &tmp);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
|
@ -510,7 +517,7 @@ index 437f7e91a..0f90443ce 100644
|
|||
K5_TAILQ_FOREACH(r, &rr->list, list) {
|
||||
if (r->request == tmp) {
|
||||
diff --git a/src/lib/krad/t_attr.c b/src/lib/krad/t_attr.c
|
||||
index eb2a780c8..4d285ad9d 100644
|
||||
index eb2a780c89..4d285ad9de 100644
|
||||
--- a/src/lib/krad/t_attr.c
|
||||
+++ b/src/lib/krad/t_attr.c
|
||||
@@ -50,6 +50,7 @@ main()
|
||||
|
|
@ -531,7 +538,7 @@ index eb2a780c8..4d285ad9d 100644
|
|||
insist(len == sizeof(encoded));
|
||||
insist(memcmp(outbuf, encoded, len) == 0);
|
||||
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
|
||||
index 7928335ca..0f9576253 100644
|
||||
index 7928335ca4..0f95762534 100644
|
||||
--- a/src/lib/krad/t_attrset.c
|
||||
+++ b/src/lib/krad/t_attrset.c
|
||||
@@ -49,6 +49,7 @@ main()
|
||||
|
|
@ -553,7 +560,7 @@ index 7928335ca..0f9576253 100644
|
|||
|
||||
/* Manually encode User-Name. */
|
||||
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
|
||||
index 00734a13b..a3ce22b70 100644
|
||||
index 00734a13b5..a3ce22b70f 100644
|
||||
--- a/src/plugins/preauth/spake/spake_client.c
|
||||
+++ b/src/plugins/preauth/spake/spake_client.c
|
||||
@@ -38,6 +38,8 @@
|
||||
|
|
@ -577,7 +584,7 @@ index 00734a13b..a3ce22b70 100644
|
|||
vt->name = "spake";
|
||||
vt->pa_type_list = pa_types;
|
||||
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
|
||||
index 88c964ce1..c7df0392f 100644
|
||||
index 1a772d450f..232e78bc05 100644
|
||||
--- a/src/plugins/preauth/spake/spake_kdc.c
|
||||
+++ b/src/plugins/preauth/spake/spake_kdc.c
|
||||
@@ -41,6 +41,8 @@
|
||||
|
|
@ -589,7 +596,7 @@ index 88c964ce1..c7df0392f 100644
|
|||
/*
|
||||
* The SPAKE kdcpreauth module uses a secure cookie containing the following
|
||||
* concatenated fields (all integer fields are big-endian):
|
||||
@@ -571,6 +573,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
|
||||
@@ -551,6 +553,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
|
||||
|
||||
if (maj_ver != 1)
|
||||
return KRB5_PLUGIN_VER_NOTSUPP;
|
||||
|
|
@ -600,3 +607,6 @@ index 88c964ce1..c7df0392f 100644
|
|||
vt = (krb5_kdcpreauth_vtable)vtable;
|
||||
vt->name = "spake";
|
||||
vt->pa_type_list = pa_types;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
From 707fa7bd2be6327343dc8fc5c20dc77645524518 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 5 May 2022 17:15:12 +0200
|
||||
Subject: [PATCH] [downstream] Allow krad UDP/TCP localhost connection
|
||||
with FIPS
|
||||
|
||||
libkrad allows to establish connections only to UNIX socket in FIPS
|
||||
mode, because MD5 digest is not considered safe enough to be used for
|
||||
network communication. However, FreeRadius requires connection on TCP or
|
||||
UDP ports.
|
||||
|
||||
This commit allows TCP or UDP connections in FIPS mode if destination is
|
||||
localhost.
|
||||
|
||||
Resolves: rhbz#2082189
|
||||
---
|
||||
src/lib/krad/remote.c | 35 +++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 33 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||
index 929f1cef67..063f17a613 100644
|
||||
--- a/src/lib/krad/remote.c
|
||||
+++ b/src/lib/krad/remote.c
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
+#include <stdbool.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
|
||||
@@ -74,6 +75,35 @@ on_io(verto_ctx *ctx, verto_ev *ev);
|
||||
static void
|
||||
on_timeout(verto_ctx *ctx, verto_ev *ev);
|
||||
|
||||
+static in_addr_t get_in_addr(struct addrinfo *info)
|
||||
+{ return ((struct sockaddr_in *)(info->ai_addr))->sin_addr.s_addr; }
|
||||
+
|
||||
+static struct in6_addr *get_in6_addr(struct addrinfo *info)
|
||||
+{ return &(((struct sockaddr_in6 *)(info->ai_addr))->sin6_addr); }
|
||||
+
|
||||
+static bool is_inet_localhost(struct addrinfo *info)
|
||||
+{
|
||||
+ struct addrinfo *p;
|
||||
+
|
||||
+ for (p = info; p; p = p->ai_next) {
|
||||
+ switch (p->ai_family) {
|
||||
+ case AF_INET:
|
||||
+ if (IN_LOOPBACKNET != (get_in_addr(p) & IN_CLASSA_NET
|
||||
+ >> IN_CLASSA_NSHIFT))
|
||||
+ return false;
|
||||
+ break;
|
||||
+ case AF_INET6:
|
||||
+ if (!IN6_IS_ADDR_LOOPBACK(get_in6_addr(p)))
|
||||
+ return false;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/* Iterate over the set of outstanding packets. */
|
||||
static const krad_packet *
|
||||
iterator(request **out)
|
||||
@@ -460,8 +490,9 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
(krad_packet_iter_cb)iterator, &r, &tmp);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
- else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL &&
|
||||
- rr->info->ai_family != AF_UNIX) {
|
||||
+ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL
|
||||
+ && rr->info->ai_family != AF_UNIX
|
||||
+ && !is_inet_localhost(rr->info)) {
|
||||
/* This would expose cleartext passwords, so abort. */
|
||||
retval = ESOCKTNOSUPPORT;
|
||||
goto error;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
From 1da88bea558348be2974470774aa688f8be634c0 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 7 Dec 2022 13:22:42 +0100
|
||||
Subject: [PATCH] [downstream] Make tests compatible with
|
||||
sssd_krb5_locator_plugin.so
|
||||
|
||||
The sssd_krb5_locator_plugin.so plugin provided by sssd-client conflicts
|
||||
with the upstream test t_discover_uri.py. The test has to be modified in
|
||||
order to avoid false positive.
|
||||
---
|
||||
src/lib/krb5/os/t_discover_uri.py | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/krb5/os/t_discover_uri.py b/src/lib/krb5/os/t_discover_uri.py
|
||||
index 87bac17929..26bc95a8dc 100644
|
||||
--- a/src/lib/krb5/os/t_discover_uri.py
|
||||
+++ b/src/lib/krb5/os/t_discover_uri.py
|
||||
@@ -1,3 +1,4 @@
|
||||
+from os.path import exists
|
||||
from k5test import *
|
||||
|
||||
entries = ('URI _kerberos.TEST krb5srv::kkdcp:https://kdc1 1 1\n',
|
||||
@@ -37,8 +38,14 @@ realm.env['RESOLV_WRAPPER_HOSTS'] = hosts_filename
|
||||
out = realm.run(['./t_locate_kdc', 'TEST'], env=realm.env)
|
||||
l = out.splitlines()
|
||||
|
||||
+if (exists('/usr/lib/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')
|
||||
+ or exists('/usr/lib64/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')):
|
||||
+ line_range = range(6, 14)
|
||||
+else:
|
||||
+ line_range = range(4, 12)
|
||||
+
|
||||
j = 0
|
||||
-for i in range(4, 12):
|
||||
+for i in line_range:
|
||||
if l[i].strip() != expected[j]:
|
||||
fail('URI answers do not match')
|
||||
j += 1
|
||||
--
|
||||
2.45.1
|
||||
|
||||
120
0009-downstream-Include-missing-OpenSSL-FIPS-header.patch
Normal file
120
0009-downstream-Include-missing-OpenSSL-FIPS-header.patch
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
From 775ed8588cc21385fb16a4cec4a861f0d578ce04 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 5 Jan 2023 20:06:47 +0100
|
||||
Subject: [PATCH] [downstream] Include missing OpenSSL FIPS header
|
||||
|
||||
The inclusion of openssl/fips.h, which provides the declaration of
|
||||
FIPS_mode(), was removed from openssl/crypto.h. As a consequence, this
|
||||
header file has to be included explicitly in krb5 code.
|
||||
---
|
||||
src/lib/crypto/krb/prng.c | 4 +++-
|
||||
src/lib/crypto/openssl/enc_provider/camellia.c | 1 +
|
||||
src/lib/crypto/openssl/enc_provider/rc4.c | 4 ++++
|
||||
src/lib/crypto/openssl/hmac.c | 1 +
|
||||
src/lib/krad/internal.h | 4 ++++
|
||||
src/plugins/preauth/spake/spake_client.c | 4 ++++
|
||||
src/plugins/preauth/spake/spake_kdc.c | 4 ++++
|
||||
7 files changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
|
||||
index 9e80a03d21..ae37c77518 100644
|
||||
--- a/src/lib/crypto/krb/prng.c
|
||||
+++ b/src/lib/crypto/krb/prng.c
|
||||
@@ -28,7 +28,9 @@
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
-#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+#include <openssl/fips.h>
|
||||
+#else
|
||||
#include <openssl/crypto.h>
|
||||
#endif
|
||||
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
index d9f327add6..3dd3b0624f 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <openssl/camellia.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/core_names.h>
|
||||
+#include <openssl/fips.h>
|
||||
#else
|
||||
#include <openssl/modes.h>
|
||||
#endif
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
index ce63cb5f1b..6a83f10d27 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+#include <openssl/fips.h>
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* The loopback field is a pointer to the structure. If the application copies
|
||||
* the state (not a valid operation, but one which happens to works with some
|
||||
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
|
||||
index f21e268f7f..25a419d73a 100644
|
||||
--- a/src/lib/crypto/openssl/hmac.c
|
||||
+++ b/src/lib/crypto/openssl/hmac.c
|
||||
@@ -59,6 +59,7 @@
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_names.h>
|
||||
+#include <openssl/fips.h>
|
||||
#else
|
||||
#include <openssl/hmac.h>
|
||||
#endif
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index e123763954..a17b6f39b1 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -41,6 +41,10 @@
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+#include <openssl/fips.h>
|
||||
+#endif
|
||||
+
|
||||
#ifndef UCHAR_MAX
|
||||
#define UCHAR_MAX 255
|
||||
#endif
|
||||
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
|
||||
index a3ce22b70f..13c699071f 100644
|
||||
--- a/src/plugins/preauth/spake/spake_client.c
|
||||
+++ b/src/plugins/preauth/spake/spake_client.c
|
||||
@@ -40,6 +40,10 @@
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+#include <openssl/fips.h>
|
||||
+#endif
|
||||
+
|
||||
typedef struct reqstate_st {
|
||||
krb5_pa_spake *msg; /* set in prep_questions, used in process */
|
||||
krb5_keyblock *initial_key;
|
||||
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
|
||||
index 232e78bc05..3394f8a58e 100644
|
||||
--- a/src/plugins/preauth/spake/spake_kdc.c
|
||||
+++ b/src/plugins/preauth/spake/spake_kdc.c
|
||||
@@ -43,6 +43,10 @@
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+#include <openssl/fips.h>
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* The SPAKE kdcpreauth module uses a secure cookie containing the following
|
||||
* concatenated fields (all integer fields are big-endian):
|
||||
--
|
||||
2.45.1
|
||||
|
||||
31
0010-downstream-Do-not-set-root-as-ksu-file-owner.patch
Normal file
31
0010-downstream-Do-not-set-root-as-ksu-file-owner.patch
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
From 4fd20741afcf76085ea62eb015cd589bb9392a7b Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Mon, 9 Jan 2023 22:39:52 +0100
|
||||
Subject: [PATCH] [downstream] Do not set root as ksu file owner
|
||||
|
||||
Upstream Makefile uses the install command to set root as owner of the
|
||||
ksu executable file. However, this is no longer supported on latest
|
||||
versions of the Mock build environment.
|
||||
|
||||
In case of ksu, the owner, group, and mode are already set using %attr()
|
||||
in the specfile.
|
||||
---
|
||||
src/config/pre.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/config/pre.in b/src/config/pre.in
|
||||
index 7eaa2f351c..e9ae71471e 100644
|
||||
--- a/src/config/pre.in
|
||||
+++ b/src/config/pre.in
|
||||
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
|
||||
INSTALL_SCRIPT=@INSTALL_PROGRAM@
|
||||
INSTALL_DATA=@INSTALL_DATA@
|
||||
INSTALL_SHLIB=@INSTALL_SHLIB@
|
||||
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
|
||||
+INSTALL_SETUID=$(INSTALL)
|
||||
## This is needed because autoconf will sometimes define @exec_prefix@ to be
|
||||
## ${prefix}.
|
||||
prefix=@prefix@
|
||||
--
|
||||
2.45.1
|
||||
|
||||
165
0011-downstream-Allow-KRB5KDF-MD5-and-MD4-in-FIPS-mode.patch
Normal file
165
0011-downstream-Allow-KRB5KDF-MD5-and-MD4-in-FIPS-mode.patch
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
From 16f90c007036789d8d9343e8a0cbabfd21853b5a Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 19 Jan 2023 19:22:27 +0100
|
||||
Subject: [PATCH] [downstream] Allow KRB5KDF, MD5, and MD4 in FIPS mode
|
||||
|
||||
OpenSSL's restrictions to use KRB5KDF, MD5, and MD4 in FIPS mode are
|
||||
bypassed in case AES SHA-1 HMAC or RC4 encryption types are allowed by
|
||||
the crypto policy.
|
||||
---
|
||||
.../crypto/openssl/hash_provider/hash_evp.c | 97 +++++++++++++++++--
|
||||
src/lib/crypto/openssl/kdf.c | 2 +-
|
||||
2 files changed, 89 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
index 11659908bb..eb2e693e9f 100644
|
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
@@ -44,6 +44,49 @@
|
||||
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#endif
|
||||
|
||||
+#include <openssl/provider.h>
|
||||
+#include <openssl/fips.h>
|
||||
+#include <threads.h>
|
||||
+
|
||||
+typedef struct ossl_lib_md_context {
|
||||
+ OSSL_LIB_CTX *libctx;
|
||||
+ OSSL_PROVIDER *default_provider;
|
||||
+ OSSL_PROVIDER *legacy_provider;
|
||||
+} ossl_md_context_t;
|
||||
+
|
||||
+static thread_local ossl_md_context_t *ossl_md_ctx = NULL;
|
||||
+
|
||||
+static krb5_error_code
|
||||
+init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo)
|
||||
+{
|
||||
+ ctx->libctx = OSSL_LIB_CTX_new();
|
||||
+ if (!ctx->libctx)
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ /* Load both legacy and default provider as both may be needed. */
|
||||
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||
+
|
||||
+ if (!(ctx->default_provider && ctx->legacy_provider))
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+deinit_ossl_ctx(ossl_md_context_t *ctx)
|
||||
+{
|
||||
+ if (ctx->legacy_provider)
|
||||
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||
+
|
||||
+ if (ctx->default_provider)
|
||||
+ OSSL_PROVIDER_unload(ctx->default_provider);
|
||||
+
|
||||
+ if (ctx->libctx)
|
||||
+ OSSL_LIB_CTX_free(ctx->libctx);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static krb5_error_code
|
||||
hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
krb5_data *output)
|
||||
@@ -60,11 +103,6 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
- if (type == EVP_md4() || type == EVP_md5()) {
|
||||
- /* See comments below in hash_md4() and hash_md5(). */
|
||||
- EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||
- }
|
||||
-
|
||||
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||
for (i = 0; i < num_data; i++) {
|
||||
if (!SIGN_IOV(&data[i]))
|
||||
@@ -77,6 +115,43 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
return ok ? 0 : KRB5_CRYPTO_INTERNAL;
|
||||
}
|
||||
|
||||
+static krb5_error_code
|
||||
+hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output)
|
||||
+{
|
||||
+ krb5_error_code err;
|
||||
+ EVP_MD *md = NULL;
|
||||
+
|
||||
+ if (!ossl_md_ctx) {
|
||||
+ ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
|
||||
+ if (!ossl_md_ctx) {
|
||||
+ err = ENOMEM;
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ err = init_ossl_md_ctx(ossl_md_ctx, algo);
|
||||
+ if (err) {
|
||||
+ deinit_ossl_ctx(ossl_md_ctx);
|
||||
+ free(ossl_md_ctx);
|
||||
+ ossl_md_ctx = NULL;
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
|
||||
+ if (!md) {
|
||||
+ err = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ err = hash_evp(md, data, num_data, output);
|
||||
+
|
||||
+end:
|
||||
+ if (md)
|
||||
+ EVP_MD_free(md);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
#endif
|
||||
|
||||
#ifdef K5_OPENSSL_MD4
|
||||
@@ -88,7 +163,8 @@ hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||
* by IPA. These keys are only used along a (separately) secured channel
|
||||
* for legacy reasons when performing trusts to Active Directory.
|
||||
*/
|
||||
- return hash_evp(EVP_md4(), data, num_data, output);
|
||||
+ return FIPS_mode() ? hash_legacy_evp("MD4", data, num_data, output)
|
||||
+ : hash_evp(EVP_md4(), data, num_data, output);
|
||||
}
|
||||
|
||||
const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||
@@ -100,9 +176,12 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||
static krb5_error_code
|
||||
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||
{
|
||||
- /* MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||
- * is gated in libkrad by libdefaults->radius_md5_fips_override. */
|
||||
- return hash_evp(EVP_md5(), data, num_data, output);
|
||||
+ /*
|
||||
+ * MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||
+ * is gated in libkrad by libdefaults->radius_md5_fips_override.
|
||||
+ */
|
||||
+ return FIPS_mode() ? hash_legacy_evp("MD5", data, num_data, output)
|
||||
+ : hash_evp(EVP_md5(), data, num_data, output);
|
||||
}
|
||||
|
||||
const struct krb5_hash_provider krb5int_hash_md5 = {
|
||||
diff --git a/src/lib/crypto/openssl/kdf.c b/src/lib/crypto/openssl/kdf.c
|
||||
index 5a43c3d9eb..8528ddc4a9 100644
|
||||
--- a/src/lib/crypto/openssl/kdf.c
|
||||
+++ b/src/lib/crypto/openssl/kdf.c
|
||||
@@ -198,7 +198,7 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL);
|
||||
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips");
|
||||
if (kdf == NULL) {
|
||||
ret = KRB5_CRYPTO_INTERNAL;
|
||||
goto done;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
280
0012-downstream-Allow-to-set-PAC-ticket-signature-as-opti.patch
Normal file
280
0012-downstream-Allow-to-set-PAC-ticket-signature-as-opti.patch
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
From 23b58199db429603802e338db530677b61561335 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 15 Mar 2023 15:56:34 +0100
|
||||
Subject: [PATCH] [downstream] Allow to set PAC ticket signature as
|
||||
optional
|
||||
|
||||
MS-PAC states that "The ticket signature SHOULD be included in tickets
|
||||
that are not encrypted to the krbtgt account". However, the
|
||||
implementation of krb5_kdc_verify_ticket() will require the ticket
|
||||
signature to be present in case the target of the request is a service
|
||||
principal.
|
||||
|
||||
In gradual upgrade environments, it results in S4U2Proxy requests
|
||||
against a 1.20 KDC using a service ticket generated by an older version
|
||||
KDC to fail.
|
||||
|
||||
This commit adds a krb5_kdc_verify_ticket_ext() function with an extra
|
||||
switch parameter to tolerate the absence of ticket signature in this
|
||||
scenario. If the ticket signature is present, it has to be valid,
|
||||
regardless of this parameter.
|
||||
|
||||
This parameter is set based on the "optional_pac_tkt_chksum" string
|
||||
attribute of the TGT KDB entry.
|
||||
---
|
||||
doc/admin/admin_commands/kadmin_local.rst | 6 ++++
|
||||
doc/appdev/refs/api/index.rst | 1 +
|
||||
src/include/kdb.h | 1 +
|
||||
src/include/krb5/krb5.hin | 40 +++++++++++++++++++++++
|
||||
src/kdc/kdc_util.c | 32 ++++++++++++++----
|
||||
src/lib/krb5/krb/pac.c | 31 +++++++++++++++---
|
||||
src/lib/krb5/libkrb5.exports | 1 +
|
||||
src/man/kadmin.man | 6 ++++
|
||||
8 files changed, 108 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/admin_commands/kadmin_local.rst b/doc/admin/admin_commands/kadmin_local.rst
|
||||
index 2435b3c361..58ac79549f 100644
|
||||
--- a/doc/admin/admin_commands/kadmin_local.rst
|
||||
+++ b/doc/admin/admin_commands/kadmin_local.rst
|
||||
@@ -658,6 +658,12 @@ KDC:
|
||||
Directory realm when using aes-sha2 keys on the local krbtgt
|
||||
entry.
|
||||
|
||||
+**optional_pac_tkt_chksum**
|
||||
+ Boolean value defining the behavior of the KDC in case an expected
|
||||
+ ticket checksum signed with one of this principal keys is not
|
||||
+ present in the PAC. This is typically the case for TGS or
|
||||
+ cross-realm TGS principals when processing S4U2Proxy requests.
|
||||
+
|
||||
This command requires the **modify** privilege.
|
||||
|
||||
Alias: **setstr**
|
||||
diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst
|
||||
index d12be47c3c..9b95ebd0f9 100644
|
||||
--- a/doc/appdev/refs/api/index.rst
|
||||
+++ b/doc/appdev/refs/api/index.rst
|
||||
@@ -225,6 +225,7 @@ Rarely used public interfaces
|
||||
krb5_is_referral_realm.rst
|
||||
krb5_kdc_sign_ticket.rst
|
||||
krb5_kdc_verify_ticket.rst
|
||||
+ krb5_kdc_verify_ticket_ext.rst
|
||||
krb5_kt_add_entry.rst
|
||||
krb5_kt_end_seq_get.rst
|
||||
krb5_kt_get_entry.rst
|
||||
diff --git a/src/include/kdb.h b/src/include/kdb.h
|
||||
index 745b24f351..6075349e5e 100644
|
||||
--- a/src/include/kdb.h
|
||||
+++ b/src/include/kdb.h
|
||||
@@ -136,6 +136,7 @@
|
||||
#define KRB5_KDB_SK_PAC_PRIVSVR_ENCTYPE "pac_privsvr_enctype"
|
||||
#define KRB5_KDB_SK_SESSION_ENCTYPES "session_enctypes"
|
||||
#define KRB5_KDB_SK_REQUIRE_AUTH "require_auth"
|
||||
+#define KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM "optional_pac_tkt_chksum"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||
index c5a625db8f..2d9b64dc85 100644
|
||||
--- a/src/include/krb5/krb5.hin
|
||||
+++ b/src/include/krb5/krb5.hin
|
||||
@@ -8329,6 +8329,46 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
const krb5_keyblock *server,
|
||||
const krb5_keyblock *privsvr, krb5_pac *pac_out);
|
||||
|
||||
+/**
|
||||
+ * Verify a PAC, possibly including ticket signature
|
||||
+ *
|
||||
+ * @param [in] context Library context
|
||||
+ * @param [in] enc_tkt Ticket enc-part, possibly containing a PAC
|
||||
+ * @param [in] server_princ Canonicalized name of ticket server
|
||||
+ * @param [in] server Key to validate server checksum (or NULL)
|
||||
+ * @param [in] privsvr Key to validate KDC checksum (or NULL)
|
||||
+ * @paran [in] optional_tkt_chksum Whether to require a ticket checksum
|
||||
+ * @param [out] pac_out Verified PAC (NULL if no PAC included)
|
||||
+ *
|
||||
+ * This function is an extension of krb5_kdc_verify_ticket(), adding the @a
|
||||
+ * optional_tkt_chksum parameter allowing to tolerate the absence of the PAC
|
||||
+ * ticket signature.
|
||||
+ *
|
||||
+ * If a PAC is present in @a enc_tkt, verify its signatures. If @a privsvr is
|
||||
+ * not NULL and @a server_princ is not a krbtgt or kadmin/changepw service and
|
||||
+ * @a optional_tkt_chksum is FALSE, require a ticket signature over @a enc_tkt
|
||||
+ * in addition to the KDC signature. Place the verified PAC in @a pac_out. If
|
||||
+ * an invalid PAC signature is found, return an error matching the Windows KDC
|
||||
+ * protocol code for that condition as closely as possible.
|
||||
+ *
|
||||
+ * If no PAC is present in @a enc_tkt, set @a pac_out to NULL and return
|
||||
+ * successfully.
|
||||
+ *
|
||||
+ * @note This function does not validate the PAC_CLIENT_INFO buffer. If a
|
||||
+ * specific value is expected, the caller can make a separate call to
|
||||
+ * krb5_pac_verify_ext() with a principal but no keys.
|
||||
+ *
|
||||
+ * @retval 0 Success; otherwise - Kerberos error codes
|
||||
+ */
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_kdc_verify_ticket_ext(krb5_context context,
|
||||
+ const krb5_enc_tkt_part *enc_tkt,
|
||||
+ krb5_const_principal server_princ,
|
||||
+ const krb5_keyblock *server,
|
||||
+ const krb5_keyblock *privsvr,
|
||||
+ krb5_boolean optional_tkt_chksum,
|
||||
+ krb5_pac *pac_out);
|
||||
+
|
||||
/** @deprecated Use krb5_kdc_sign_ticket() instead. */
|
||||
krb5_error_code KRB5_CALLCONV
|
||||
krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index fe4e48209a..93415ba862 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -560,16 +560,36 @@ cleanup:
|
||||
static krb5_error_code
|
||||
try_verify_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
krb5_db_entry *server, krb5_keyblock *server_key,
|
||||
- const krb5_keyblock *tgt_key, krb5_pac *pac_out)
|
||||
+ krb5_db_entry *tgt, const krb5_keyblock *tgt_key,
|
||||
+ krb5_pac *pac_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
+ krb5_boolean optional_tkt_chksum;
|
||||
+ char *str = NULL;
|
||||
krb5_keyblock *privsvr_key;
|
||||
|
||||
ret = pac_privsvr_key(context, server, tgt_key, &privsvr_key);
|
||||
if (ret)
|
||||
return ret;
|
||||
- ret = krb5_kdc_verify_ticket(context, enc_tkt, server->princ, server_key,
|
||||
- privsvr_key, pac_out);
|
||||
+
|
||||
+ /* Check if the absence of ticket signature is tolerated for this realm */
|
||||
+ ret = krb5_dbe_get_string(context, tgt,
|
||||
+ KRB5_KDB_SK_OPTIONAL_PAC_TKT_CHKSUM, &str);
|
||||
+ /* TODO: should be using _krb5_conf_boolean(), but os-proto.h is not
|
||||
+ * available here.
|
||||
+ */
|
||||
+ optional_tkt_chksum = !ret && str && (strncasecmp(str, "true", 4) == 0
|
||||
+ || strncasecmp(str, "t", 1) == 0
|
||||
+ || strncasecmp(str, "yes", 3) == 0
|
||||
+ || strncasecmp(str, "y", 1) == 0
|
||||
+ || strncasecmp(str, "1", 1) == 0
|
||||
+ || strncasecmp(str, "on", 2) == 0);
|
||||
+
|
||||
+ krb5_dbe_free_string(context, str);
|
||||
+
|
||||
+ ret = krb5_kdc_verify_ticket_ext(context, enc_tkt, server->princ,
|
||||
+ server_key, privsvr_key,
|
||||
+ optional_tkt_chksum, pac_out);
|
||||
krb5_free_keyblock(context, privsvr_key);
|
||||
return ret;
|
||||
}
|
||||
@@ -599,7 +619,7 @@ get_verified_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
server_key, NULL, pac_out);
|
||||
}
|
||||
|
||||
- ret = try_verify_pac(context, enc_tkt, server, server_key, tgt_key,
|
||||
+ ret = try_verify_pac(context, enc_tkt, server, server_key, tgt, tgt_key,
|
||||
pac_out);
|
||||
if (ret != KRB5KRB_AP_ERR_MODIFIED && ret != KRB5_BAD_ENCTYPE)
|
||||
return ret;
|
||||
@@ -613,8 +633,8 @@ get_verified_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
ret = krb5_dbe_decrypt_key_data(context, NULL, kd, &old_key, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
- ret = try_verify_pac(context, enc_tkt, server, server_key, &old_key,
|
||||
- pac_out);
|
||||
+ ret = try_verify_pac(context, enc_tkt, server, server_key, tgt,
|
||||
+ &old_key, pac_out);
|
||||
krb5_free_keyblock_contents(context, &old_key);
|
||||
if (!ret)
|
||||
return 0;
|
||||
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
|
||||
index 5d1fdf1ba0..0c0e2ada68 100644
|
||||
--- a/src/lib/krb5/krb/pac.c
|
||||
+++ b/src/lib/krb5/krb/pac.c
|
||||
@@ -594,6 +594,19 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
krb5_const_principal server_princ,
|
||||
const krb5_keyblock *server,
|
||||
const krb5_keyblock *privsvr, krb5_pac *pac_out)
|
||||
+{
|
||||
+ return krb5_kdc_verify_ticket_ext(context, enc_tkt, server_princ, server,
|
||||
+ privsvr, FALSE, pac_out);
|
||||
+}
|
||||
+
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_kdc_verify_ticket_ext(krb5_context context,
|
||||
+ const krb5_enc_tkt_part *enc_tkt,
|
||||
+ krb5_const_principal server_princ,
|
||||
+ const krb5_keyblock *server,
|
||||
+ const krb5_keyblock *privsvr,
|
||||
+ krb5_boolean optional_tkt_chksum,
|
||||
+ krb5_pac *pac_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_pac pac = NULL;
|
||||
@@ -602,7 +615,7 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
krb5_authdata *orig, **ifrel = NULL, **recoded_ifrel = NULL;
|
||||
uint8_t z = 0;
|
||||
krb5_authdata zpac = { KV5M_AUTHDATA, KRB5_AUTHDATA_WIN2K_PAC, 1, &z };
|
||||
- krb5_boolean is_service_tkt;
|
||||
+ krb5_boolean is_service_tkt, has_tkt_chksum = FALSE;
|
||||
size_t i, j;
|
||||
|
||||
*pac_out = NULL;
|
||||
@@ -667,11 +680,21 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||
|
||||
ret = verify_checksum(context, pac, KRB5_PAC_TICKET_CHECKSUM, privsvr,
|
||||
KRB5_KEYUSAGE_APP_DATA_CKSUM, recoded_tkt);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
+ if (ret) {
|
||||
+ if (!optional_tkt_chksum)
|
||||
+ goto cleanup;
|
||||
+ else if (ret != ENOENT)
|
||||
+ goto cleanup;
|
||||
+ /* Otherwise ticket signature is absent but optional. Proceed... */
|
||||
+ } else {
|
||||
+ has_tkt_chksum = TRUE;
|
||||
+ }
|
||||
}
|
||||
+ /* Else, we make the assumption the ticket signature is absent in case this
|
||||
+ * is not a service ticket.
|
||||
+ */
|
||||
|
||||
- ret = verify_pac_checksums(context, pac, is_service_tkt, server, privsvr);
|
||||
+ ret = verify_pac_checksums(context, pac, has_tkt_chksum, server, privsvr);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
|
||||
index 4c50e935a2..d4b0455c8c 100644
|
||||
--- a/src/lib/krb5/libkrb5.exports
|
||||
+++ b/src/lib/krb5/libkrb5.exports
|
||||
@@ -463,6 +463,7 @@ krb5_is_thread_safe
|
||||
krb5_kdc_rep_decrypt_proc
|
||||
krb5_kdc_sign_ticket
|
||||
krb5_kdc_verify_ticket
|
||||
+krb5_kdc_verify_ticket_ext
|
||||
krb5_kt_add_entry
|
||||
krb5_kt_client_default
|
||||
krb5_kt_close
|
||||
diff --git a/src/man/kadmin.man b/src/man/kadmin.man
|
||||
index 8413e70ccd..f68eb0569d 100644
|
||||
--- a/src/man/kadmin.man
|
||||
+++ b/src/man/kadmin.man
|
||||
@@ -724,6 +724,12 @@ encryption type. It may be necessary to set this value to
|
||||
"aes256\-sha1" on the cross\-realm krbtgt entry for an Active
|
||||
Directory realm when using aes\-sha2 keys on the local krbtgt
|
||||
entry.
|
||||
+.TP
|
||||
+\fBoptional_pac_tkt_chksum\fP
|
||||
+Boolean value defining the behavior of the KDC in case an expected ticket
|
||||
+checksum signed with one of this principal keys is not present in the PAC. This
|
||||
+is typically the case for TGS or cross-realm TGS principals when processing
|
||||
+S4U2Proxy requests.
|
||||
.UNINDENT
|
||||
.sp
|
||||
This command requires the \fBmodify\fP privilege.
|
||||
--
|
||||
2.45.1
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
From 31b9debcf2cbd558f8f315fefb69fc8206b115b4 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Tue, 23 May 2023 12:19:54 +0200
|
||||
Subject: [PATCH] [downstream] Make PKINIT CMS SHA-1 signature
|
||||
verification available in FIPS mode
|
||||
|
||||
We recommend using the SHA1 crypto-module in order to allow the
|
||||
verification of SHA-1 signature for CMS messages. However, this module
|
||||
does not work in FIPS mode, because the SHA-1 algorithm is absent from
|
||||
the OpenSSL FIPS provider.
|
||||
|
||||
This commit enables the signature verification process to fetch the
|
||||
algorithm from a non-FIPS OpenSSL provider.
|
||||
|
||||
Support for SHA-1 CMS signature is still required, especially in order
|
||||
to interoperate with Active Directory. At least it is until elliptic
|
||||
curve cryptography is implemented for PKINIT in MIT krb5.
|
||||
---
|
||||
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index cb9c79626c..17dd18e37d 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -1844,8 +1844,17 @@ cms_signeddata_verify(krb5_context context,
|
||||
if (oid == NULL)
|
||||
goto cleanup;
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+ /* Do not use FIPS provider (even in FIPS mode) because it keeps from
|
||||
+ * allowing SHA-1 signature verification using the SHA1 crypto-module
|
||||
+ */
|
||||
+ cms = CMS_ContentInfo_new_ex(NULL, "-fips");
|
||||
+ if (!cms)
|
||||
+ goto cleanup;
|
||||
+#endif
|
||||
+
|
||||
/* decode received CMS message */
|
||||
- if ((cms = d2i_CMS_ContentInfo(NULL, &p, (int)signed_data_len)) == NULL) {
|
||||
+ if (!d2i_CMS_ContentInfo(&cms, &p, (int)signed_data_len)) {
|
||||
retval = oerr(context, 0, _("Failed to decode CMS message"));
|
||||
goto cleanup;
|
||||
}
|
||||
--
|
||||
2.45.1
|
||||
|
||||
218
0014-Enable-PKINIT-if-at-least-one-group-is-available.patch
Normal file
218
0014-Enable-PKINIT-if-at-least-one-group-is-available.patch
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
From c24c9faf859ddc04910a6bc591d8ddb2ada93e80 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 30 May 2023 01:21:48 -0400
|
||||
Subject: [PATCH] Enable PKINIT if at least one group is available
|
||||
|
||||
OpenSSL may no longer allow decoding of non-well-known Diffie-Hellman
|
||||
group parameters as EVP_PKEY objects in FIPS mode. However, OpenSSL
|
||||
does not know about MODP group 2 (1024-bit), which is considered as a
|
||||
custom group. As a consequence, the PKINIT kdcpreauth module fails to
|
||||
load in FIPS mode.
|
||||
|
||||
Allow initialization of PKINIT plugin if at least one of the MODP
|
||||
well-known group parameters successfully decodes.
|
||||
|
||||
[ghudson@mit.edu: minor commit message and code edits]
|
||||
|
||||
ticket: 9096 (new)
|
||||
(cherry picked from commit 509d8db922e9ad6f108883838473b6178f89874a)
|
||||
---
|
||||
src/plugins/preauth/pkinit/pkinit_clnt.c | 2 +-
|
||||
src/plugins/preauth/pkinit/pkinit_crypto.h | 3 +-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 76 +++++++++++--------
|
||||
src/plugins/preauth/pkinit/pkinit_srv.c | 2 +-
|
||||
src/plugins/preauth/pkinit/pkinit_trace.h | 3 +
|
||||
5 files changed, 51 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
index 725d5bc438..ea9ba454df 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
@@ -1378,7 +1378,7 @@ pkinit_client_plugin_init(krb5_context context,
|
||||
if (retval)
|
||||
goto errout;
|
||||
|
||||
- retval = pkinit_init_plg_crypto(&ctx->cryptoctx);
|
||||
+ retval = pkinit_init_plg_crypto(context, &ctx->cryptoctx);
|
||||
if (retval)
|
||||
goto errout;
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
index 9fa315d7a0..8bdbea8e95 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
@@ -103,7 +103,8 @@ typedef struct _pkinit_cert_matching_data {
|
||||
/*
|
||||
* Functions to initialize and cleanup crypto contexts
|
||||
*/
|
||||
-krb5_error_code pkinit_init_plg_crypto(pkinit_plg_crypto_context *);
|
||||
+krb5_error_code pkinit_init_plg_crypto(krb5_context,
|
||||
+ pkinit_plg_crypto_context *);
|
||||
void pkinit_fini_plg_crypto(pkinit_plg_crypto_context);
|
||||
|
||||
krb5_error_code pkinit_init_req_crypto(pkinit_req_crypto_context *);
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 17dd18e37d..8cdc40bfb4 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -47,7 +47,8 @@
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
-static krb5_error_code pkinit_init_dh_params(pkinit_plg_crypto_context );
|
||||
+static krb5_error_code pkinit_init_dh_params(krb5_context,
|
||||
+ pkinit_plg_crypto_context);
|
||||
static void pkinit_fini_dh_params(pkinit_plg_crypto_context );
|
||||
|
||||
static krb5_error_code pkinit_init_certs(pkinit_identity_crypto_context ctx);
|
||||
@@ -951,7 +952,8 @@ oerr_cert(krb5_context context, krb5_error_code code, X509_STORE_CTX *certctx,
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
-pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx)
|
||||
+pkinit_init_plg_crypto(krb5_context context,
|
||||
+ pkinit_plg_crypto_context *cryptoctx)
|
||||
{
|
||||
krb5_error_code retval = ENOMEM;
|
||||
pkinit_plg_crypto_context ctx = NULL;
|
||||
@@ -969,7 +971,7 @@ pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx)
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
- retval = pkinit_init_dh_params(ctx);
|
||||
+ retval = pkinit_init_dh_params(context, ctx);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
@@ -1278,30 +1280,36 @@ pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ctx)
|
||||
ASN1_OBJECT_free(ctx->id_kp_serverAuth);
|
||||
}
|
||||
|
||||
-static krb5_error_code
|
||||
-pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
|
||||
+static int
|
||||
+try_import_group(krb5_context context, const krb5_data *params,
|
||||
+ const char *name, EVP_PKEY **pkey_out)
|
||||
{
|
||||
- krb5_error_code retval = ENOMEM;
|
||||
-
|
||||
- plgctx->dh_1024 = decode_dh_params(&oakley_1024);
|
||||
- if (plgctx->dh_1024 == NULL)
|
||||
- goto cleanup;
|
||||
-
|
||||
- plgctx->dh_2048 = decode_dh_params(&oakley_2048);
|
||||
- if (plgctx->dh_2048 == NULL)
|
||||
- goto cleanup;
|
||||
+ *pkey_out = decode_dh_params(params);
|
||||
+ if (*pkey_out == NULL)
|
||||
+ TRACE_PKINIT_DH_GROUP_UNAVAILABLE(context, name);
|
||||
+ return (*pkey_out != NULL) ? 1 : 0;
|
||||
+}
|
||||
|
||||
- plgctx->dh_4096 = decode_dh_params(&oakley_4096);
|
||||
- if (plgctx->dh_4096 == NULL)
|
||||
- goto cleanup;
|
||||
+static krb5_error_code
|
||||
+pkinit_init_dh_params(krb5_context context, pkinit_plg_crypto_context plgctx)
|
||||
+{
|
||||
+ int n = 0;
|
||||
|
||||
- retval = 0;
|
||||
+ n += try_import_group(context, &oakley_1024, "MODP 2 (1024-bit)",
|
||||
+ &plgctx->dh_1024);
|
||||
+ n += try_import_group(context, &oakley_2048, "MODP 14 (2048-bit)",
|
||||
+ &plgctx->dh_2048);
|
||||
+ n += try_import_group(context, &oakley_4096, "MODP 16 (4096-bit)",
|
||||
+ &plgctx->dh_4096);
|
||||
|
||||
-cleanup:
|
||||
- if (retval)
|
||||
+ if (n == 0) {
|
||||
pkinit_fini_dh_params(plgctx);
|
||||
+ k5_setmsg(context, ENOMEM,
|
||||
+ _("PKINIT cannot initialize any key exchange groups"));
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
|
||||
- return retval;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2912,11 +2920,11 @@ client_create_dh(krb5_context context,
|
||||
|
||||
if (cryptoctx->received_params != NULL)
|
||||
params = cryptoctx->received_params;
|
||||
- else if (dh_size == 1024)
|
||||
+ else if (plg_cryptoctx->dh_1024 != NULL && dh_size == 1024)
|
||||
params = plg_cryptoctx->dh_1024;
|
||||
- else if (dh_size == 2048)
|
||||
+ else if (plg_cryptoctx->dh_2048 != NULL && dh_size == 2048)
|
||||
params = plg_cryptoctx->dh_2048;
|
||||
- else if (dh_size == 4096)
|
||||
+ else if (plg_cryptoctx->dh_4096 != NULL && dh_size == 4096)
|
||||
params = plg_cryptoctx->dh_4096;
|
||||
else
|
||||
goto cleanup;
|
||||
@@ -3212,19 +3220,23 @@ pkinit_create_td_dh_parameters(krb5_context context,
|
||||
krb5_algorithm_identifier alg_4096 = { dh_oid, oakley_4096 };
|
||||
krb5_algorithm_identifier *alglist[4];
|
||||
|
||||
- if (opts->dh_min_bits > 4096) {
|
||||
- ret = KRB5KRB_ERR_GENERIC;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
i = 0;
|
||||
- if (opts->dh_min_bits <= 2048)
|
||||
+ if (plg_cryptoctx->dh_2048 != NULL && opts->dh_min_bits <= 2048)
|
||||
alglist[i++] = &alg_2048;
|
||||
- alglist[i++] = &alg_4096;
|
||||
- if (opts->dh_min_bits <= 1024)
|
||||
+ if (plg_cryptoctx->dh_4096 != NULL && opts->dh_min_bits <= 4096)
|
||||
+ alglist[i++] = &alg_4096;
|
||||
+ if (plg_cryptoctx->dh_1024 != NULL && opts->dh_min_bits <= 1024)
|
||||
alglist[i++] = &alg_1024;
|
||||
alglist[i] = NULL;
|
||||
|
||||
+ if (i == 0) {
|
||||
+ ret = KRB5KRB_ERR_GENERIC;
|
||||
+ k5_setmsg(context, ret,
|
||||
+ _("OpenSSL has no supported key exchange groups for "
|
||||
+ "pkinit_dh_min_bits=%d"), opts->dh_min_bits);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
ret = k5int_encode_krb5_td_dh_parameters(alglist, &der_alglist);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
index 1b3bf6d4d0..768a4e559f 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
@@ -1222,7 +1222,7 @@ pkinit_server_plugin_init_realm(krb5_context context, const char *realmname,
|
||||
goto errout;
|
||||
plgctx->realmname_len = strlen(plgctx->realmname);
|
||||
|
||||
- retval = pkinit_init_plg_crypto(&plgctx->cryptoctx);
|
||||
+ retval = pkinit_init_plg_crypto(context, &plgctx->cryptoctx);
|
||||
if (retval)
|
||||
goto errout;
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
index 259e95c6c2..5ee39c085c 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
@@ -90,6 +90,9 @@
|
||||
#define TRACE_PKINIT_CLIENT_TRYAGAIN(c) \
|
||||
TRACE(c, "PKINIT client trying again with KDC-provided parameters")
|
||||
|
||||
+#define TRACE_PKINIT_DH_GROUP_UNAVAILABLE(c, name) \
|
||||
+ TRACE(c, "PKINIT key exchange group {str} unsupported", name)
|
||||
+
|
||||
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
|
||||
TRACE(c, "PKINIT OpenSSL error: {str}", msg)
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
64
0015-Replace-ssl.wrap_socket-for-tests.patch
Normal file
64
0015-Replace-ssl.wrap_socket-for-tests.patch
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
From e92365b510a2407eaceaec90836f5c713403d75f Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 19 Jul 2023 13:43:17 +0200
|
||||
Subject: [PATCH] Replace ssl.wrap_socket() for tests
|
||||
|
||||
The ssl.wrap_socket() function was deprecated in Python 3.7 and is
|
||||
removed in Python 3.12. The ssl.SSLContext.wrap_socket() method
|
||||
replaces it.
|
||||
|
||||
Bump the required Python version for tests to 3.4 for
|
||||
ssl.create_default_context().
|
||||
|
||||
[ghudson@mit.edu: changed minimum Python version]
|
||||
|
||||
(cherry picked from commit 0ceab6c363e65fb21d3312a663f2b9b569ecc415)
|
||||
---
|
||||
src/configure.ac | 9 ++++-----
|
||||
src/util/wsgiref-kdcproxy.py | 4 +++-
|
||||
2 files changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 2561e917a2..487f393146 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1157,10 +1157,9 @@ AC_SUBST(PKINIT)
|
||||
# for lib/apputils
|
||||
AC_REPLACE_FUNCS(daemon)
|
||||
|
||||
-# For Python tests. Python version 3.2.4 is required as prior
|
||||
-# versions do not accept string input to subprocess.Popen.communicate
|
||||
-# when universal_newlines is set.
|
||||
-PYTHON_MINVERSION=3.2.4
|
||||
+# For Python tests. Python version 3.4 is required for
|
||||
+# ssl.create_default_context().
|
||||
+PYTHON_MINVERSION=3.4
|
||||
AC_SUBST(PYTHON_MINVERSION)
|
||||
AC_CHECK_PROG(PYTHON,python3,python3)
|
||||
if test x"$PYTHON" = x; then
|
||||
@@ -1168,7 +1167,7 @@ if test x"$PYTHON" = x; then
|
||||
fi
|
||||
HAVE_PYTHON=no
|
||||
if test x"$PYTHON" != x; then
|
||||
- wantver="(sys.hexversion >= 0x30204F0)"
|
||||
+ wantver="(sys.hexversion >= 0x30400F0)"
|
||||
if "$PYTHON" -c "import sys; sys.exit(not $wantver and 1 or 0)"; then
|
||||
HAVE_PYTHON=yes
|
||||
fi
|
||||
diff --git a/src/util/wsgiref-kdcproxy.py b/src/util/wsgiref-kdcproxy.py
|
||||
index 58759696b6..d1d10d733c 100755
|
||||
--- a/src/util/wsgiref-kdcproxy.py
|
||||
+++ b/src/util/wsgiref-kdcproxy.py
|
||||
@@ -14,6 +14,8 @@ else:
|
||||
pem = '*'
|
||||
|
||||
server = make_server('localhost', port, kdcproxy.Application())
|
||||
-server.socket = ssl.wrap_socket(server.socket, certfile=pem, server_side=True)
|
||||
+sslctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
||||
+sslctx.load_cert_chain(certfile=pem)
|
||||
+server.socket = sslctx.wrap_socket(server.socket, server_side=True)
|
||||
os.write(sys.stdout.fileno(), b'proxy server ready\n')
|
||||
server.serve_forever()
|
||||
--
|
||||
2.45.1
|
||||
|
||||
10685
0016-Eliminate-old-style-function-declarations.patch
Normal file
10685
0016-Eliminate-old-style-function-declarations.patch
Normal file
File diff suppressed because it is too large
Load diff
206
0017-Fix-two-unlikely-memory-leaks.patch
Normal file
206
0017-Fix-two-unlikely-memory-leaks.patch
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
From ee66c1feedb57ce06ce51aaa823f9a61f564c58e Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 5 Mar 2024 19:53:07 -0500
|
||||
Subject: [PATCH] Fix two unlikely memory leaks
|
||||
|
||||
In gss_krb5int_make_seal_token_v3(), one of the bounds checks (which
|
||||
could probably never be triggered) leaks plain.data. Fix this leak
|
||||
and use current practices for cleanup throughout the function.
|
||||
|
||||
In xmt_rmtcallres() (unused within the tree and likely elsewhere),
|
||||
store port_ptr into crp->port_ptr as soon as it is allocated;
|
||||
otherwise it could leak if the subsequent xdr_u_int32() operation
|
||||
fails.
|
||||
|
||||
(cherry picked from commit c5f9c816107f70139de11b38aa02db2f1774ee0d)
|
||||
---
|
||||
src/lib/gssapi/krb5/k5sealv3.c | 56 +++++++++++++++-------------------
|
||||
src/lib/rpc/pmap_rmt.c | 10 +++---
|
||||
2 files changed, 29 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
|
||||
index 1fcbdfbb87..d3210c1107 100644
|
||||
--- a/src/lib/gssapi/krb5/k5sealv3.c
|
||||
+++ b/src/lib/gssapi/krb5/k5sealv3.c
|
||||
@@ -65,7 +65,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
int conf_req_flag, int toktype)
|
||||
{
|
||||
size_t bufsize = 16;
|
||||
- unsigned char *outbuf = 0;
|
||||
+ unsigned char *outbuf = NULL;
|
||||
krb5_error_code err;
|
||||
int key_usage;
|
||||
unsigned char acceptor_flag;
|
||||
@@ -75,9 +75,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
#endif
|
||||
size_t ec;
|
||||
unsigned short tok_id;
|
||||
- krb5_checksum sum;
|
||||
+ krb5_checksum sum = { 0 };
|
||||
krb5_key key;
|
||||
krb5_cksumtype cksumtype;
|
||||
+ krb5_data plain = empty_data();
|
||||
+
|
||||
+ token->value = NULL;
|
||||
+ token->length = 0;
|
||||
|
||||
acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR;
|
||||
key_usage = (toktype == KG_TOK_WRAP_MSG
|
||||
@@ -107,14 +111,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
#endif
|
||||
|
||||
if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) {
|
||||
- krb5_data plain;
|
||||
krb5_enc_data cipher;
|
||||
size_t ec_max;
|
||||
size_t encrypt_size;
|
||||
|
||||
/* 300: Adds some slop. */
|
||||
- if (SIZE_MAX - 300 < message->length)
|
||||
- return ENOMEM;
|
||||
+ if (SIZE_MAX - 300 < message->length) {
|
||||
+ err = ENOMEM;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
ec_max = SIZE_MAX - message->length - 300;
|
||||
if (ec_max > 0xffff)
|
||||
ec_max = 0xffff;
|
||||
@@ -126,20 +131,20 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
#endif
|
||||
err = alloc_data(&plain, message->length + 16 + ec);
|
||||
if (err)
|
||||
- return err;
|
||||
+ goto cleanup;
|
||||
|
||||
/* Get size of ciphertext. */
|
||||
encrypt_size = krb5_encrypt_size(plain.length, key->keyblock.enctype);
|
||||
if (encrypt_size > SIZE_MAX / 2) {
|
||||
err = ENOMEM;
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
bufsize = 16 + encrypt_size;
|
||||
/* Allocate space for header plus encrypted data. */
|
||||
outbuf = gssalloc_malloc(bufsize);
|
||||
if (outbuf == NULL) {
|
||||
- free(plain.data);
|
||||
- return ENOMEM;
|
||||
+ err = ENOMEM;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* TOK_ID */
|
||||
@@ -164,11 +169,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
cipher.ciphertext.length = bufsize - 16;
|
||||
cipher.enctype = key->keyblock.enctype;
|
||||
err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher);
|
||||
- zap(plain.data, plain.length);
|
||||
- free(plain.data);
|
||||
- plain.data = 0;
|
||||
if (err)
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
|
||||
/* Now that we know we're returning a valid token.... */
|
||||
ctx->seq_send++;
|
||||
@@ -181,7 +183,6 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
/* If the rotate fails, don't worry about it. */
|
||||
#endif
|
||||
} else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) {
|
||||
- krb5_data plain;
|
||||
size_t cksumsize;
|
||||
|
||||
/* Here, message is the application-supplied data; message2 is
|
||||
@@ -193,21 +194,19 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
wrap_with_checksum:
|
||||
err = alloc_data(&plain, message->length + 16);
|
||||
if (err)
|
||||
- return err;
|
||||
+ goto cleanup;
|
||||
|
||||
err = krb5_c_checksum_length(context, cksumtype, &cksumsize);
|
||||
if (err)
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
|
||||
assert(cksumsize <= 0xffff);
|
||||
|
||||
bufsize = 16 + message2->length + cksumsize;
|
||||
outbuf = gssalloc_malloc(bufsize);
|
||||
if (outbuf == NULL) {
|
||||
- free(plain.data);
|
||||
- plain.data = 0;
|
||||
err = ENOMEM;
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* TOK_ID */
|
||||
@@ -239,23 +238,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
if (message2->length)
|
||||
memcpy(outbuf + 16, message2->value, message2->length);
|
||||
|
||||
- sum.contents = outbuf + 16 + message2->length;
|
||||
- sum.length = cksumsize;
|
||||
-
|
||||
err = krb5_k_make_checksum(context, cksumtype, key,
|
||||
key_usage, &plain, &sum);
|
||||
- zap(plain.data, plain.length);
|
||||
- free(plain.data);
|
||||
- plain.data = 0;
|
||||
if (err) {
|
||||
zap(outbuf,bufsize);
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
if (sum.length != cksumsize)
|
||||
abort();
|
||||
memcpy(outbuf + 16 + message2->length, sum.contents, cksumsize);
|
||||
- krb5_free_checksum_contents(context, &sum);
|
||||
- sum.contents = 0;
|
||||
/* Now that we know we're actually generating the token... */
|
||||
ctx->seq_send++;
|
||||
|
||||
@@ -285,12 +276,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context,
|
||||
|
||||
token->value = outbuf;
|
||||
token->length = bufsize;
|
||||
- return 0;
|
||||
+ outbuf = NULL;
|
||||
+ err = 0;
|
||||
|
||||
-error:
|
||||
+cleanup:
|
||||
+ krb5_free_checksum_contents(context, &sum);
|
||||
+ zapfree(plain.data, plain.length);
|
||||
gssalloc_free(outbuf);
|
||||
- token->value = NULL;
|
||||
- token->length = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c
|
||||
index 434e4eea65..f55ca46c60 100644
|
||||
--- a/src/lib/rpc/pmap_rmt.c
|
||||
+++ b/src/lib/rpc/pmap_rmt.c
|
||||
@@ -161,12 +161,12 @@ xdr_rmtcallres(
|
||||
caddr_t port_ptr;
|
||||
|
||||
port_ptr = (caddr_t)(void *)crp->port_ptr;
|
||||
- if (xdr_reference(xdrs, &port_ptr, sizeof (uint32_t),
|
||||
- (xdrproc_t)xdr_u_int32) &&
|
||||
- xdr_u_int32(xdrs, &crp->resultslen)) {
|
||||
- crp->port_ptr = (uint32_t *)(void *)port_ptr;
|
||||
+ if (!xdr_reference(xdrs, &port_ptr, sizeof (uint32_t),
|
||||
+ (xdrproc_t)xdr_u_int32))
|
||||
+ return (FALSE);
|
||||
+ crp->port_ptr = (uint32_t *)(void *)port_ptr;
|
||||
+ if (xdr_u_int32(xdrs, &crp->resultslen))
|
||||
return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
|
||||
- }
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
--
|
||||
2.45.1
|
||||
|
||||
2316
0018-Fix-unimportant-memory-leaks.patch
Normal file
2316
0018-Fix-unimportant-memory-leaks.patch
Normal file
File diff suppressed because it is too large
Load diff
71
0019-Remove-klist-s-defname-global-variable.patch
Normal file
71
0019-Remove-klist-s-defname-global-variable.patch
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
From 05bb6d9c729a3c6a4ba35270368bc0f6e1875ad0 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Mon, 8 Jan 2024 16:52:27 +0100
|
||||
Subject: [PATCH] Remove klist's defname global variable
|
||||
|
||||
Addition of a "cleanup" section in kinit's show_ccache() function as
|
||||
part of commit 6c5471176f5266564fbc8a7e02f03b4b042202f8 introduced a
|
||||
double-free bug, because defname is a global variable. After the
|
||||
first call, successive calls may take place with a dangling pointer in
|
||||
defname, which will be freed if krb5_cc_get_principal() fails.
|
||||
|
||||
Convert "defname" to a local variable initialized at the beginning of
|
||||
show_ccache().
|
||||
|
||||
[ghudson@mit.edu: edited commit message]
|
||||
|
||||
(cherry picked from commit 5b00197227231943bd2305328c8260dd0b0dbcf0)
|
||||
---
|
||||
src/clients/klist/klist.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
|
||||
index b5ae96a843..b5808e5c93 100644
|
||||
--- a/src/clients/klist/klist.c
|
||||
+++ b/src/clients/klist/klist.c
|
||||
@@ -53,7 +53,6 @@ int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
|
||||
int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0;
|
||||
int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
|
||||
int show_config = 0;
|
||||
-char *defname;
|
||||
char *progname;
|
||||
krb5_timestamp now;
|
||||
unsigned int timestamp_width;
|
||||
@@ -62,7 +61,7 @@ krb5_context context;
|
||||
|
||||
static krb5_boolean is_local_tgt(krb5_principal princ, krb5_data *realm);
|
||||
static char *etype_string(krb5_enctype );
|
||||
-static void show_credential(krb5_creds *);
|
||||
+static void show_credential(krb5_creds *, const char *);
|
||||
|
||||
static void list_all_ccaches(void);
|
||||
static int list_ccache(krb5_ccache);
|
||||
@@ -473,6 +472,7 @@ show_ccache(krb5_ccache cache)
|
||||
krb5_creds creds;
|
||||
krb5_principal princ = NULL;
|
||||
krb5_error_code ret;
|
||||
+ char *defname = NULL;
|
||||
int status = 1;
|
||||
|
||||
ret = krb5_cc_get_principal(context, cache, &princ);
|
||||
@@ -503,7 +503,7 @@ show_ccache(krb5_ccache cache)
|
||||
}
|
||||
while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) {
|
||||
if (show_config || !krb5_is_config_principal(context, creds.server))
|
||||
- show_credential(&creds);
|
||||
+ show_credential(&creds, defname);
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
}
|
||||
if (ret == KRB5_CC_END) {
|
||||
@@ -676,7 +676,7 @@ print_config_data(int col, krb5_data *data)
|
||||
}
|
||||
|
||||
static void
|
||||
-show_credential(krb5_creds *cred)
|
||||
+show_credential(krb5_creds *cred, const char *defname)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ticket *tkt = NULL;
|
||||
--
|
||||
2.45.1
|
||||
|
||||
34
0020-End-connection-on-KDC_ERR_SVC_UNAVAILABLE.patch
Normal file
34
0020-End-connection-on-KDC_ERR_SVC_UNAVAILABLE.patch
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
From d7bcca2a215de880f4419afc450a96a747d48560 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 27 Oct 2023 00:44:53 -0400
|
||||
Subject: [PATCH] End connection on KDC_ERR_SVC_UNAVAILABLE
|
||||
|
||||
In sendto_kdc.c:service_fds(), if a message handler indicates that a
|
||||
message should be discarded, kill the connection so we don't continue
|
||||
waiting on it for more data.
|
||||
|
||||
ticket: 7899
|
||||
(cherry picked from commit ca80f64c786341d5871ae1de18142e62af64f7b9)
|
||||
---
|
||||
src/lib/krb5/os/sendto_kdc.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
|
||||
index 0f4bf23a95..262edf09b4 100644
|
||||
--- a/src/lib/krb5/os/sendto_kdc.c
|
||||
+++ b/src/lib/krb5/os/sendto_kdc.c
|
||||
@@ -1440,7 +1440,10 @@ service_fds(krb5_context context, struct select_state *selstate,
|
||||
if (msg_handler != NULL) {
|
||||
krb5_data reply = make_data(state->in.buf, state->in.pos);
|
||||
|
||||
- stop = (msg_handler(context, &reply, msg_handler_data) != 0);
|
||||
+ if (!msg_handler(context, &reply, msg_handler_data)) {
|
||||
+ kill_conn(context, state, selstate);
|
||||
+ stop = 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (stop) {
|
||||
--
|
||||
2.46.0
|
||||
|
||||
226
0021-Add-request_timeout-configuration-parameter.patch
Normal file
226
0021-Add-request_timeout-configuration-parameter.patch
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
From a07b3ae29fd972c40e30b95f6bcc8fb3ed4d9991 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Thu, 26 Oct 2023 14:20:34 -0400
|
||||
Subject: [PATCH] Add request_timeout configuration parameter
|
||||
|
||||
Add a parameter to limit the total amount of time taken for a KDC or
|
||||
password change request.
|
||||
|
||||
ticket: 9106 (new)
|
||||
(cherry picked from commit 802318cda963456b3ed7856c836e89da891483be)
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 9 ++++++
|
||||
src/include/k5-int.h | 2 ++
|
||||
src/lib/krb5/krb/init_ctx.c | 14 +++++++-
|
||||
src/lib/krb5/os/sendto_kdc.c | 51 ++++++++++++++++++++----------
|
||||
4 files changed, 58 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index a33711d918..65fb592d98 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -356,6 +356,15 @@ The libdefaults section may contain any of the following relations:
|
||||
(:ref:`duration` string.) Sets the default renewable lifetime
|
||||
for initial ticket requests. The default value is 0.
|
||||
|
||||
+**request_timeout**
|
||||
+ (:ref:`duration` string.) Sets the maximum total time for KDC or
|
||||
+ password change requests. This timeout does not affect the
|
||||
+ intervals between requests, so setting a low timeout may result in
|
||||
+ fewer requests being attempted and/or some servers not being
|
||||
+ contacted. A value of 0 indicates no specific maximum, in which
|
||||
+ case requests will time out if no server responds after several
|
||||
+ tries. The default value is 0. (New in release 1.22.)
|
||||
+
|
||||
**spake_preauth_groups**
|
||||
A whitespace or comma-separated list of words which specifies the
|
||||
groups allowed for SPAKE preauthentication. The possible values
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index b3e07945c1..69d6a6f569 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -296,6 +296,7 @@ typedef unsigned char u_char;
|
||||
#define KRB5_CONF_SPAKE_PREAUTH_INDICATOR "spake_preauth_indicator"
|
||||
#define KRB5_CONF_SPAKE_PREAUTH_KDC_CHALLENGE "spake_preauth_kdc_challenge"
|
||||
#define KRB5_CONF_SPAKE_PREAUTH_GROUPS "spake_preauth_groups"
|
||||
+#define KRB5_CONF_REQUEST_TIMEOUT "request_timeout"
|
||||
#define KRB5_CONF_TICKET_LIFETIME "ticket_lifetime"
|
||||
#define KRB5_CONF_UDP_PREFERENCE_LIMIT "udp_preference_limit"
|
||||
#define KRB5_CONF_UNLOCKITER "unlockiter"
|
||||
@@ -1200,6 +1201,7 @@ struct _krb5_context {
|
||||
kdb5_dal_handle *dal_handle;
|
||||
/* allowable clock skew */
|
||||
krb5_deltat clockskew;
|
||||
+ krb5_deltat req_timeout;
|
||||
krb5_flags kdc_default_options;
|
||||
krb5_flags library_options;
|
||||
krb5_boolean profile_secure;
|
||||
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
|
||||
index 2b5abcd817..582a2945ff 100644
|
||||
--- a/src/lib/krb5/krb/init_ctx.c
|
||||
+++ b/src/lib/krb5/krb/init_ctx.c
|
||||
@@ -157,7 +157,7 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
krb5_context ctx = 0;
|
||||
krb5_error_code retval;
|
||||
int tmp;
|
||||
- char *plugin_dir = NULL;
|
||||
+ char *plugin_dir = NULL, *timeout_str = NULL;
|
||||
|
||||
/* Verify some assumptions. If the assumptions hold and the
|
||||
compiler is optimizing, this should result in no code being
|
||||
@@ -240,6 +240,17 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
get_integer(ctx, KRB5_CONF_CLOCKSKEW, DEFAULT_CLOCKSKEW, &tmp);
|
||||
ctx->clockskew = tmp;
|
||||
|
||||
+ retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
|
||||
+ KRB5_CONF_REQUEST_TIMEOUT, NULL, NULL,
|
||||
+ &timeout_str);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+ if (timeout_str != NULL) {
|
||||
+ retval = krb5_string_to_deltat(timeout_str, &ctx->req_timeout);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
get_integer(ctx, KRB5_CONF_KDC_DEFAULT_OPTIONS, KDC_OPT_RENEWABLE_OK,
|
||||
&tmp);
|
||||
ctx->kdc_default_options = tmp;
|
||||
@@ -281,6 +292,7 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
|
||||
cleanup:
|
||||
profile_release_string(plugin_dir);
|
||||
+ profile_release_string(timeout_str);
|
||||
krb5_free_context(ctx);
|
||||
return retval;
|
||||
}
|
||||
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
|
||||
index 262edf09b4..98247a1089 100644
|
||||
--- a/src/lib/krb5/os/sendto_kdc.c
|
||||
+++ b/src/lib/krb5/os/sendto_kdc.c
|
||||
@@ -1395,34 +1395,41 @@ get_endtime(time_ms endtime, struct conn_state *conns)
|
||||
|
||||
static krb5_boolean
|
||||
service_fds(krb5_context context, struct select_state *selstate,
|
||||
- time_ms interval, struct conn_state *conns,
|
||||
+ time_ms interval, time_ms timeout, struct conn_state *conns,
|
||||
struct select_state *seltemp, const krb5_data *realm,
|
||||
int (*msg_handler)(krb5_context, const krb5_data *, void *),
|
||||
void *msg_handler_data, struct conn_state **winner_out)
|
||||
{
|
||||
int e, selret = 0;
|
||||
- time_ms endtime;
|
||||
+ time_ms curtime, interval_end, endtime;
|
||||
struct conn_state *state;
|
||||
|
||||
*winner_out = NULL;
|
||||
|
||||
- e = get_curtime_ms(&endtime);
|
||||
+ e = get_curtime_ms(&curtime);
|
||||
if (e)
|
||||
return TRUE;
|
||||
- endtime += interval;
|
||||
+ interval_end = curtime + interval;
|
||||
|
||||
e = 0;
|
||||
while (selstate->nfds > 0) {
|
||||
- e = cm_select_or_poll(selstate, get_endtime(endtime, conns),
|
||||
- seltemp, &selret);
|
||||
+ endtime = get_endtime(interval_end, conns);
|
||||
+ /* Don't wait longer than the whole request should last. */
|
||||
+ if (timeout && endtime > timeout)
|
||||
+ endtime = timeout;
|
||||
+ e = cm_select_or_poll(selstate, endtime, seltemp, &selret);
|
||||
if (e == EINTR)
|
||||
continue;
|
||||
if (e != 0)
|
||||
break;
|
||||
|
||||
- if (selret == 0)
|
||||
- /* Timeout, return to caller. */
|
||||
+ if (selret == 0) {
|
||||
+ /* We timed out. Stop if we hit the overall request timeout. */
|
||||
+ if (timeout && (get_curtime_ms(&curtime) || curtime >= timeout))
|
||||
+ return TRUE;
|
||||
+ /* Otherwise return to the caller to send the next request. */
|
||||
return FALSE;
|
||||
+ }
|
||||
|
||||
/* Got something on a socket, process it. */
|
||||
for (state = conns; state != NULL; state = state->next) {
|
||||
@@ -1495,7 +1502,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
||||
void *msg_handler_data)
|
||||
{
|
||||
int pass;
|
||||
- time_ms delay;
|
||||
+ time_ms delay, timeout = 0;
|
||||
krb5_error_code retval;
|
||||
struct conn_state *conns = NULL, *state, **tailptr, *next, *winner;
|
||||
size_t s;
|
||||
@@ -1505,6 +1512,13 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
||||
|
||||
*reply = empty_data();
|
||||
|
||||
+ if (context->req_timeout) {
|
||||
+ retval = get_curtime_ms(&timeout);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+ timeout += 1000 * context->req_timeout;
|
||||
+ }
|
||||
+
|
||||
/* One for use here, listing all our fds in use, and one for
|
||||
* temporary use in service_fds, for the fds of interest. */
|
||||
sel_state = malloc(2 * sizeof(*sel_state));
|
||||
@@ -1532,8 +1546,9 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
||||
if (maybe_send(context, state, message, sel_state, realm,
|
||||
callback_info))
|
||||
continue;
|
||||
- done = service_fds(context, sel_state, 1000, conns, seltemp,
|
||||
- realm, msg_handler, msg_handler_data, &winner);
|
||||
+ done = service_fds(context, sel_state, 1000, timeout, conns,
|
||||
+ seltemp, realm, msg_handler, msg_handler_data,
|
||||
+ &winner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1545,13 +1560,13 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
||||
if (maybe_send(context, state, message, sel_state, realm,
|
||||
callback_info))
|
||||
continue;
|
||||
- done = service_fds(context, sel_state, 1000, conns, seltemp,
|
||||
+ done = service_fds(context, sel_state, 1000, timeout, conns, seltemp,
|
||||
realm, msg_handler, msg_handler_data, &winner);
|
||||
}
|
||||
|
||||
/* Wait for two seconds at the end of the first pass. */
|
||||
if (!done) {
|
||||
- done = service_fds(context, sel_state, 2000, conns, seltemp,
|
||||
+ done = service_fds(context, sel_state, 2000, timeout, conns, seltemp,
|
||||
realm, msg_handler, msg_handler_data, &winner);
|
||||
}
|
||||
|
||||
@@ -1562,15 +1577,17 @@ k5_sendto(krb5_context context, const krb5_data *message,
|
||||
if (maybe_send(context, state, message, sel_state, realm,
|
||||
callback_info))
|
||||
continue;
|
||||
- done = service_fds(context, sel_state, 1000, conns, seltemp,
|
||||
- realm, msg_handler, msg_handler_data, &winner);
|
||||
+ done = service_fds(context, sel_state, 1000, timeout, conns,
|
||||
+ seltemp, realm, msg_handler, msg_handler_data,
|
||||
+ &winner);
|
||||
if (sel_state->nfds == 0)
|
||||
break;
|
||||
}
|
||||
/* Wait for the delay backoff at the end of this pass. */
|
||||
if (!done) {
|
||||
- done = service_fds(context, sel_state, delay, conns, seltemp,
|
||||
- realm, msg_handler, msg_handler_data, &winner);
|
||||
+ done = service_fds(context, sel_state, delay, timeout, conns,
|
||||
+ seltemp, realm, msg_handler, msg_handler_data,
|
||||
+ &winner);
|
||||
}
|
||||
if (sel_state->nfds == 0)
|
||||
break;
|
||||
--
|
||||
2.46.0
|
||||
|
||||
138
0022-Wait-indefinitely-on-KDC-TCP-connections.patch
Normal file
138
0022-Wait-indefinitely-on-KDC-TCP-connections.patch
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
From 1da153d97d7fb30a44fca35f9b71b8f4ed5385b9 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Thu, 26 Oct 2023 16:26:42 -0400
|
||||
Subject: [PATCH] Wait indefinitely on KDC TCP connections
|
||||
|
||||
When making a KDC or password change request, wait indefinitely
|
||||
(limited only by request_timeout if set) once a KDC has accepted a TCP
|
||||
connection.
|
||||
|
||||
ticket: 9105 (new)
|
||||
(cherry picked from commit 6436a3808061da787a43c6810f5f0370cdfb6e36)
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 2 +-
|
||||
src/lib/krb5/os/sendto_kdc.c | 50 ++++++++++++++++--------------
|
||||
2 files changed, 27 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index 65fb592d98..b7284c47df 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -357,7 +357,7 @@ The libdefaults section may contain any of the following relations:
|
||||
for initial ticket requests. The default value is 0.
|
||||
|
||||
**request_timeout**
|
||||
- (:ref:`duration` string.) Sets the maximum total time for KDC or
|
||||
+ (:ref:`duration` string.) Sets the maximum total time for KDC and
|
||||
password change requests. This timeout does not affect the
|
||||
intervals between requests, so setting a low timeout may result in
|
||||
fewer requests being attempted and/or some servers not being
|
||||
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
|
||||
index 98247a1089..924f5b2d26 100644
|
||||
--- a/src/lib/krb5/os/sendto_kdc.c
|
||||
+++ b/src/lib/krb5/os/sendto_kdc.c
|
||||
@@ -134,7 +134,6 @@ struct conn_state {
|
||||
krb5_data callback_buffer;
|
||||
size_t server_index;
|
||||
struct conn_state *next;
|
||||
- time_ms endtime;
|
||||
krb5_boolean defer;
|
||||
struct {
|
||||
const char *uri_path;
|
||||
@@ -344,15 +343,19 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime,
|
||||
struct select_state *out, int *sret)
|
||||
{
|
||||
#ifndef USE_POLL
|
||||
- struct timeval tv;
|
||||
+ struct timeval tv, *tvp;
|
||||
#endif
|
||||
krb5_error_code retval;
|
||||
time_ms curtime, interval;
|
||||
|
||||
- retval = get_curtime_ms(&curtime);
|
||||
- if (retval != 0)
|
||||
- return retval;
|
||||
- interval = (curtime < endtime) ? endtime - curtime : 0;
|
||||
+ if (endtime != 0) {
|
||||
+ retval = get_curtime_ms(&curtime);
|
||||
+ if (retval != 0)
|
||||
+ return retval;
|
||||
+ interval = (curtime < endtime) ? endtime - curtime : 0;
|
||||
+ } else {
|
||||
+ interval = -1;
|
||||
+ }
|
||||
|
||||
/* We don't need a separate copy of the selstate for poll, but use one for
|
||||
* consistency with how we use select. */
|
||||
@@ -361,9 +364,14 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime,
|
||||
#ifdef USE_POLL
|
||||
*sret = poll(out->fds, out->nfds, interval);
|
||||
#else
|
||||
- tv.tv_sec = interval / 1000;
|
||||
- tv.tv_usec = interval % 1000 * 1000;
|
||||
- *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, &tv);
|
||||
+ if (interval != -1) {
|
||||
+ tv.tv_sec = interval / 1000;
|
||||
+ tv.tv_usec = interval % 1000 * 1000;
|
||||
+ tvp = &tv;
|
||||
+ } else {
|
||||
+ tvp = NULL;
|
||||
+ }
|
||||
+ *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, tvp);
|
||||
#endif
|
||||
|
||||
return (*sret < 0) ? SOCKET_ERRNO : 0;
|
||||
@@ -1099,11 +1107,6 @@ service_tcp_connect(krb5_context context, const krb5_data *realm,
|
||||
}
|
||||
|
||||
conn->state = WRITING;
|
||||
-
|
||||
- /* Record this connection's timeout for service_fds. */
|
||||
- if (get_curtime_ms(&conn->endtime) == 0)
|
||||
- conn->endtime += 10000;
|
||||
-
|
||||
return conn->service_write(context, realm, conn, selstate);
|
||||
}
|
||||
|
||||
@@ -1378,19 +1381,18 @@ kill_conn:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-/* Return the maximum of endtime and the endtime fields of all currently active
|
||||
- * TCP connections. */
|
||||
-static time_ms
|
||||
-get_endtime(time_ms endtime, struct conn_state *conns)
|
||||
+/* Return true if conns contains any states with connected TCP sockets. */
|
||||
+static krb5_boolean
|
||||
+any_tcp_connections(struct conn_state *conns)
|
||||
{
|
||||
struct conn_state *state;
|
||||
|
||||
for (state = conns; state != NULL; state = state->next) {
|
||||
- if ((state->state == READING || state->state == WRITING) &&
|
||||
- state->endtime > endtime)
|
||||
- endtime = state->endtime;
|
||||
+ if (state->addr.transport != UDP &&
|
||||
+ (state->state == READING || state->state == WRITING))
|
||||
+ return TRUE;
|
||||
}
|
||||
- return endtime;
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
static krb5_boolean
|
||||
@@ -1413,9 +1415,9 @@ service_fds(krb5_context context, struct select_state *selstate,
|
||||
|
||||
e = 0;
|
||||
while (selstate->nfds > 0) {
|
||||
- endtime = get_endtime(interval_end, conns);
|
||||
+ endtime = any_tcp_connections(conns) ? 0 : interval_end;
|
||||
/* Don't wait longer than the whole request should last. */
|
||||
- if (timeout && endtime > timeout)
|
||||
+ if (timeout && (!endtime || endtime > timeout))
|
||||
endtime = timeout;
|
||||
e = cm_select_or_poll(selstate, endtime, seltemp, &selret);
|
||||
if (e == EINTR)
|
||||
--
|
||||
2.46.0
|
||||
|
||||
1297
0023-Remove-PKINIT-RSA-support.patch
Normal file
1297
0023-Remove-PKINIT-RSA-support.patch
Normal file
File diff suppressed because it is too large
Load diff
265
0024-Fix-various-issues-detected-by-static-analysis.patch
Normal file
265
0024-Fix-various-issues-detected-by-static-analysis.patch
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
From 3999883b9745bfd7065d41ff05b19e56bcb2e791 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 6 Sep 2024 17:18:11 +0200
|
||||
Subject: [PATCH] Fix various issues detected by static analysis
|
||||
|
||||
In klists's show_credential(), ensure that the column counter doesn't
|
||||
decrease if printf() fails.
|
||||
|
||||
In process_k5beta7_princ(), bounds-check the e_length field.
|
||||
|
||||
In ndr_enc_delegation_info(), initialize b so it is always valid for
|
||||
the cleanup handler.
|
||||
|
||||
In krb5_dbe_def_decrypt_key_data(), change the flow control so ret is
|
||||
always set by the end of the function. Return KRB5_KDB_INVALIDKEYSIZE
|
||||
if there isn't enough data in the first key_data_contents field or if
|
||||
the serialized key length is invalid.
|
||||
|
||||
In svcauth_gss_validate(), expand rpchdr to accomodate the header plus
|
||||
MAX_AUTH_BYTES.
|
||||
|
||||
In svcudp_reply(), change slen to unsigned to match the return type of
|
||||
XDR_GETPOS() and eliminate an unnecessary check for slen >= 0.
|
||||
|
||||
In krb5int_pthread_loaded()(), remove pthread_equal() from the weak
|
||||
symbol checks. It is implemented as an inline function in some glibc
|
||||
versions, which makes the comparison "&pthread_equal == 0" always
|
||||
false.
|
||||
|
||||
[ghudson@mit.edu: further modified krb5_dbe_def_decrypt_key_data() for
|
||||
clarity; added detail to commit message]
|
||||
|
||||
(cherry picked from commit a96541981ee34c8642ddeb6101b98e883e41c6e5)
|
||||
---
|
||||
src/clients/klist/klist.c | 12 ++++-----
|
||||
src/kadmin/dbutil/dump.c | 5 ++++
|
||||
src/kdc/ndr.c | 2 +-
|
||||
src/lib/kdb/decrypt_key.c | 54 ++++++++++++++++++++------------------
|
||||
src/lib/rpc/svc_auth_gss.c | 5 +++-
|
||||
src/lib/rpc/svc_udp.c | 13 ++++-----
|
||||
src/util/support/threads.c | 2 --
|
||||
7 files changed, 51 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
|
||||
index b5808e5c93..ba9539fd23 100644
|
||||
--- a/src/clients/klist/klist.c
|
||||
+++ b/src/clients/klist/klist.c
|
||||
@@ -681,7 +681,7 @@ show_credential(krb5_creds *cred, const char *defname)
|
||||
krb5_error_code ret;
|
||||
krb5_ticket *tkt = NULL;
|
||||
char *name = NULL, *sname = NULL, *tktsname, *flags;
|
||||
- int extra_field = 0, ccol = 0, i;
|
||||
+ int extra_field = 0, ccol = 0, i, r;
|
||||
krb5_boolean is_config = krb5_is_config_principal(context, cred->server);
|
||||
|
||||
ret = krb5_unparse_name(context, cred->client, &name);
|
||||
@@ -711,11 +711,11 @@ show_credential(krb5_creds *cred, const char *defname)
|
||||
fputs("config: ", stdout);
|
||||
ccol = 8;
|
||||
for (i = 1; i < cred->server->length; i++) {
|
||||
- ccol += printf("%s%.*s%s",
|
||||
- i > 1 ? "(" : "",
|
||||
- (int)cred->server->data[i].length,
|
||||
- cred->server->data[i].data,
|
||||
- i > 1 ? ")" : "");
|
||||
+ r = printf("%s%.*s%s", i > 1 ? "(" : "",
|
||||
+ (int)cred->server->data[i].length,
|
||||
+ cred->server->data[i].data, i > 1 ? ")" : "");
|
||||
+ if (r >= 0)
|
||||
+ ccol += r;
|
||||
}
|
||||
fputs(" = ", stdout);
|
||||
ccol += 3;
|
||||
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
|
||||
index 4d6cc0bdf9..feb053d834 100644
|
||||
--- a/src/kadmin/dbutil/dump.c
|
||||
+++ b/src/kadmin/dbutil/dump.c
|
||||
@@ -704,6 +704,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
|
||||
|
||||
dbentry->len = u1;
|
||||
dbentry->n_key_data = u4;
|
||||
+
|
||||
+ if (u5 > UINT16_MAX) {
|
||||
+ load_err(fname, *linenop, _("invalid principal extra data size"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
dbentry->e_length = u5;
|
||||
|
||||
if (kp != NULL) {
|
||||
diff --git a/src/kdc/ndr.c b/src/kdc/ndr.c
|
||||
index d438408ee2..38be9fe42a 100644
|
||||
--- a/src/kdc/ndr.c
|
||||
+++ b/src/kdc/ndr.c
|
||||
@@ -242,7 +242,7 @@ ndr_enc_delegation_info(struct pac_s4u_delegation_info *in, krb5_data *out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
size_t i;
|
||||
- struct k5buf b;
|
||||
+ struct k5buf b = EMPTY_K5BUF;
|
||||
struct encoded_wchars pt_encoded = { 0 }, *tss_encoded = NULL;
|
||||
uint32_t pointer = 0;
|
||||
|
||||
diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c
|
||||
index 82bbed6312..21aa3742b1 100644
|
||||
--- a/src/lib/kdb/decrypt_key.c
|
||||
+++ b/src/lib/kdb/decrypt_key.c
|
||||
@@ -60,7 +60,7 @@ krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
|
||||
krb5_keyblock *dbkey_out,
|
||||
krb5_keysalt *keysalt_out)
|
||||
{
|
||||
- krb5_error_code ret;
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
int16_t keylen;
|
||||
krb5_enc_data cipher;
|
||||
krb5_data plain = empty_data();
|
||||
@@ -74,36 +74,38 @@ krb5_dbe_def_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
|
||||
if (mkey == NULL)
|
||||
return KRB5_KDB_BADSTORED_MKEY;
|
||||
|
||||
- if (kd->key_data_contents[0] != NULL && kd->key_data_length[0] >= 2) {
|
||||
- keylen = load_16_le(kd->key_data_contents[0]);
|
||||
- if (keylen < 0)
|
||||
- return EINVAL;
|
||||
- cipher.enctype = ENCTYPE_UNKNOWN;
|
||||
- cipher.ciphertext = make_data(kd->key_data_contents[0] + 2,
|
||||
- kd->key_data_length[0] - 2);
|
||||
- ret = alloc_data(&plain, kd->key_data_length[0] - 2);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
+ if (kd->key_data_contents[0] == NULL || kd->key_data_length[0] < 2)
|
||||
+ return KRB5_KDB_INVALIDKEYSIZE;
|
||||
|
||||
- ret = krb5_c_decrypt(context, mkey, 0, 0, &cipher, &plain);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
+ keylen = load_16_le(kd->key_data_contents[0]);
|
||||
+ if (keylen < 0)
|
||||
+ return KRB5_KDB_INVALIDKEYSIZE;
|
||||
|
||||
- /* Make sure the plaintext has at least as many bytes as the true ke
|
||||
- * length (it may have more due to padding). */
|
||||
- if ((unsigned int)keylen > plain.length) {
|
||||
- ret = KRB5_CRYPTO_INTERNAL;
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ cipher.enctype = ENCTYPE_UNKNOWN;
|
||||
+ cipher.ciphertext = make_data(kd->key_data_contents[0] + 2,
|
||||
+ kd->key_data_length[0] - 2);
|
||||
+ ret = alloc_data(&plain, kd->key_data_length[0] - 2);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
- kb.magic = KV5M_KEYBLOCK;
|
||||
- kb.enctype = kd->key_data_type[0];
|
||||
- kb.length = keylen;
|
||||
- kb.contents = (uint8_t *)plain.data;
|
||||
- plain = empty_data();
|
||||
+ ret = krb5_c_decrypt(context, mkey, 0, 0, &cipher, &plain);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Make sure the plaintext has at least as many bytes as the true key
|
||||
+ * length (it may have more due to padding). */
|
||||
+ if ((unsigned int)keylen > plain.length) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
+ kb.magic = KV5M_KEYBLOCK;
|
||||
+ kb.enctype = kd->key_data_type[0];
|
||||
+ kb.length = keylen;
|
||||
+ kb.contents = (uint8_t *)plain.data;
|
||||
+ plain = empty_data();
|
||||
+
|
||||
/* Decode salt data. */
|
||||
if (keysalt_out != NULL) {
|
||||
if (kd->key_data_ver == 2) {
|
||||
diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
|
||||
index 98d601c8ab..4f1d2911b0 100644
|
||||
--- a/src/lib/rpc/svc_auth_gss.c
|
||||
+++ b/src/lib/rpc/svc_auth_gss.c
|
||||
@@ -297,7 +297,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
struct opaque_auth *oa;
|
||||
gss_buffer_desc rpcbuf, checksum;
|
||||
OM_uint32 maj_stat, min_stat, qop_state;
|
||||
- u_char rpchdr[128];
|
||||
+ u_char rpchdr[32 + MAX_AUTH_BYTES];
|
||||
int32_t *buf;
|
||||
|
||||
log_debug("in svcauth_gss_validate()");
|
||||
@@ -315,6 +315,8 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
return (FALSE);
|
||||
|
||||
buf = (int32_t *)(void *)rpchdr;
|
||||
+
|
||||
+ /* Write the 32 first bytes of the header. */
|
||||
IXDR_PUT_LONG(buf, msg->rm_xid);
|
||||
IXDR_PUT_ENUM(buf, msg->rm_direction);
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
|
||||
@@ -323,6 +325,7 @@ svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct r
|
||||
IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
+
|
||||
if (oa->oa_length) {
|
||||
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
|
||||
buf += RNDUP(oa->oa_length) / sizeof(int32_t);
|
||||
diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c
|
||||
index 8ecbdf2b33..3aff277eb7 100644
|
||||
--- a/src/lib/rpc/svc_udp.c
|
||||
+++ b/src/lib/rpc/svc_udp.c
|
||||
@@ -248,8 +248,9 @@ static bool_t svcudp_reply(
|
||||
{
|
||||
struct svcudp_data *su = su_data(xprt);
|
||||
XDR *xdrs = &su->su_xdrs;
|
||||
- int slen;
|
||||
+ u_int slen;
|
||||
bool_t stat = FALSE;
|
||||
+ ssize_t r;
|
||||
|
||||
xdrproc_t xdr_results = NULL;
|
||||
caddr_t xdr_location = 0;
|
||||
@@ -272,12 +273,12 @@ static bool_t svcudp_reply(
|
||||
if (xdr_replymsg(xdrs, msg) &&
|
||||
(!has_args ||
|
||||
(SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
|
||||
- slen = (int)XDR_GETPOS(xdrs);
|
||||
- if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
|
||||
- (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
|
||||
- == slen) {
|
||||
+ slen = XDR_GETPOS(xdrs);
|
||||
+ r = sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
|
||||
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen);
|
||||
+ if (r >= 0 && (u_int)r == slen) {
|
||||
stat = TRUE;
|
||||
- if (su->su_cache && slen >= 0) {
|
||||
+ if (su->su_cache) {
|
||||
cache_set(xprt, (uint32_t) slen);
|
||||
}
|
||||
}
|
||||
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
|
||||
index be7e4c2e3f..4ded805b79 100644
|
||||
--- a/src/util/support/threads.c
|
||||
+++ b/src/util/support/threads.c
|
||||
@@ -118,7 +118,6 @@ struct tsd_block {
|
||||
# pragma weak pthread_mutex_destroy
|
||||
# pragma weak pthread_mutex_init
|
||||
# pragma weak pthread_self
|
||||
-# pragma weak pthread_equal
|
||||
# pragma weak pthread_getspecific
|
||||
# pragma weak pthread_setspecific
|
||||
# pragma weak pthread_key_create
|
||||
@@ -151,7 +150,6 @@ int krb5int_pthread_loaded (void)
|
||||
|| &pthread_mutex_destroy == 0
|
||||
|| &pthread_mutex_init == 0
|
||||
|| &pthread_self == 0
|
||||
- || &pthread_equal == 0
|
||||
/* Any program that's really multithreaded will have to be
|
||||
able to create threads. */
|
||||
|| &pthread_create == 0
|
||||
--
|
||||
2.46.0
|
||||
|
||||
629
0025-Generate-and-verify-message-MACs-in-libkrad.patch
Normal file
629
0025-Generate-and-verify-message-MACs-in-libkrad.patch
Normal file
|
|
@ -0,0 +1,629 @@
|
|||
From ea02fd7bb79861b8e36517c7c95af821a16657c4 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 22 Aug 2024 17:15:50 +0200
|
||||
Subject: [PATCH] Generate and verify message MACs in libkrad
|
||||
|
||||
Implement some of the measures specified in
|
||||
draft-ietf-radext-deprecating-radius-03 for mitigating the BlastRADIUS
|
||||
attack (CVE-2024-3596):
|
||||
|
||||
* Include a Message-Authenticator MAC as the first attribute when
|
||||
generating a packet of type Access-Request, Access-Reject,
|
||||
Access-Accept, or Access-Challenge (sections 5.2.1 and 5.2.4), if
|
||||
the secret is non-empty. (An empty secret indicates the use of Unix
|
||||
domain socket transport.)
|
||||
|
||||
* Validate the Message-Authenticator MAC in received packets, if
|
||||
present.
|
||||
|
||||
FreeRADIUS enforces Message-Authenticator as of versions 3.2.5 and
|
||||
3.0.27. libkrad must generate Message-Authenticator attributes in
|
||||
order to remain compatible with these implementations.
|
||||
|
||||
[ghudson@mit.edu: adjusted style and naming; simplified some
|
||||
functions; edited commit message]
|
||||
|
||||
ticket: 9142 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 871125fea8ce0370a972bf65f7d1de63f619b06c)
|
||||
---
|
||||
src/include/k5-int.h | 5 +
|
||||
src/lib/crypto/krb/checksum_hmac_md5.c | 28 ++++
|
||||
src/lib/crypto/libk5crypto.exports | 1 +
|
||||
src/lib/krad/attr.c | 17 ++
|
||||
src/lib/krad/attrset.c | 59 +++++--
|
||||
src/lib/krad/internal.h | 7 +-
|
||||
src/lib/krad/packet.c | 206 +++++++++++++++++++++++--
|
||||
src/lib/krad/t_attrset.c | 2 +-
|
||||
src/lib/krad/t_daemon.py | 3 +-
|
||||
src/lib/krad/t_packet.c | 11 ++
|
||||
src/tests/t_otp.py | 3 +
|
||||
11 files changed, 311 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index 69d6a6f569..b7789a2dd8 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -2403,4 +2403,9 @@ krb5_boolean
|
||||
k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
||||
krb5_const_principal princ);
|
||||
|
||||
+/* Generate an HMAC-MD5 keyed checksum as specified by RFC 2104. */
|
||||
+krb5_error_code
|
||||
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output);
|
||||
+
|
||||
#endif /* _KRB5_INT_H */
|
||||
diff --git a/src/lib/crypto/krb/checksum_hmac_md5.c b/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
index ec024f3966..a809388549 100644
|
||||
--- a/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
+++ b/src/lib/crypto/krb/checksum_hmac_md5.c
|
||||
@@ -92,3 +92,31 @@ cleanup:
|
||||
free(hash_iov);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+krb5_error_code
|
||||
+k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data,
|
||||
+ krb5_data *output)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ const struct krb5_hash_provider *hash = &krb5int_hash_md5;
|
||||
+ krb5_keyblock keyblock = { 0 };
|
||||
+ krb5_data hashed_key;
|
||||
+ uint8_t hkeybuf[16];
|
||||
+ krb5_crypto_iov iov;
|
||||
+
|
||||
+ /* Hash the key if it is longer than the block size. */
|
||||
+ if (key->length > hash->blocksize) {
|
||||
+ hashed_key = make_data(hkeybuf, sizeof(hkeybuf));
|
||||
+ iov.flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov.data = *key;
|
||||
+ ret = hash->hash(&iov, 1, &hashed_key);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ key = &hashed_key;
|
||||
+ }
|
||||
+
|
||||
+ keyblock.magic = KV5M_KEYBLOCK;
|
||||
+ keyblock.length = key->length;
|
||||
+ keyblock.contents = (uint8_t *)key->data;
|
||||
+ return krb5int_hmac_keyblock(hash, &keyblock, data, num_data, output);
|
||||
+}
|
||||
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
|
||||
index d8ffa63304..00e0ce1812 100644
|
||||
--- a/src/lib/crypto/libk5crypto.exports
|
||||
+++ b/src/lib/crypto/libk5crypto.exports
|
||||
@@ -102,3 +102,4 @@ krb5_c_prfplus
|
||||
krb5_c_derive_prfplus
|
||||
k5_enctype_to_ssf
|
||||
krb5int_c_deprecated_enctype
|
||||
+k5_hmac_md5
|
||||
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
|
||||
index 42d354a3b5..65ed1d35e7 100644
|
||||
--- a/src/lib/krad/attr.c
|
||||
+++ b/src/lib/krad/attr.c
|
||||
@@ -125,6 +125,23 @@ static const attribute_record attributes[UCHAR_MAX] = {
|
||||
{"NAS-Port-Type", 4, 4, NULL, NULL},
|
||||
{"Port-Limit", 4, 4, NULL, NULL},
|
||||
{"Login-LAT-Port", 1, MAX_ATTRSIZE, NULL, NULL},
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for tunnelling */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Reserved for Apple Remote Access Protocol */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Password-Retry */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Prompt */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Connect-Info */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* Configuration-Token */
|
||||
+ {NULL, 0, 0, NULL, NULL}, /* EAP-Message */
|
||||
+ {"Message-Authenticator", MD5_DIGEST_SIZE, MD5_DIGEST_SIZE, NULL, NULL},
|
||||
};
|
||||
|
||||
/* Encode User-Password attribute. */
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||
index 6ec031e320..e5457ebfd7 100644
|
||||
--- a/src/lib/krad/attrset.c
|
||||
+++ b/src/lib/krad/attrset.c
|
||||
@@ -164,15 +164,44 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Place an encoded attributes into outbuf at position *i. Increment *i by the
|
||||
+ * length of the encoding. */
|
||||
+static krb5_error_code
|
||||
+append_attr(krb5_context ctx, const char *secret,
|
||||
+ const uint8_t *auth, krad_attr type, const krb5_data *data,
|
||||
+ uint8_t outbuf[MAX_ATTRSETSIZE], size_t *i, krb5_boolean *is_fips)
|
||||
+{
|
||||
+ uint8_t buffer[MAX_ATTRSIZE];
|
||||
+ size_t attrlen;
|
||||
+ krb5_error_code retval;
|
||||
+
|
||||
+ retval = kr_attr_encode(ctx, secret, auth, type, data, buffer, &attrlen,
|
||||
+ is_fips);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ if (attrlen > MAX_ATTRSETSIZE - *i - 2)
|
||||
+ return EMSGSIZE;
|
||||
+
|
||||
+ outbuf[(*i)++] = type;
|
||||
+ outbuf[(*i)++] = attrlen + 2;
|
||||
+ memcpy(outbuf + *i, buffer, attrlen);
|
||||
+ *i += attrlen;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
krb5_error_code
|
||||
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
- const unsigned char *auth,
|
||||
+ const uint8_t *auth, krb5_boolean add_msgauth,
|
||||
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||
krb5_boolean *is_fips)
|
||||
{
|
||||
- unsigned char buffer[MAX_ATTRSIZE];
|
||||
krb5_error_code retval;
|
||||
- size_t i = 0, attrlen;
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const uint8_t zeroes[MD5_DIGEST_SIZE] = { 0 };
|
||||
+ krb5_data zerodata;
|
||||
+ size_t i = 0;
|
||||
attr *a;
|
||||
|
||||
if (set == NULL) {
|
||||
@@ -180,19 +209,21 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||
- retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
|
||||
- buffer, &attrlen, is_fips);
|
||||
- if (retval != 0)
|
||||
+ if (add_msgauth) {
|
||||
+ /* Encode Message-Authenticator as the first attribute, per
|
||||
+ * draft-ietf-radext-deprecating-radius-03 section 5.2. */
|
||||
+ zerodata = make_data((uint8_t *)zeroes, MD5_DIGEST_SIZE);
|
||||
+ retval = append_attr(set->ctx, secret, auth, msgauth_type, &zerodata,
|
||||
+ outbuf, &i, is_fips);
|
||||
+ if (retval)
|
||||
return retval;
|
||||
+ }
|
||||
|
||||
- if (i + attrlen + 2 > MAX_ATTRSETSIZE)
|
||||
- return EMSGSIZE;
|
||||
-
|
||||
- outbuf[i++] = a->type;
|
||||
- outbuf[i++] = attrlen + 2;
|
||||
- memcpy(&outbuf[i], buffer, attrlen);
|
||||
- i += attrlen;
|
||||
+ K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||
+ retval = append_attr(set->ctx, secret, auth, a->type, &a->attr,
|
||||
+ outbuf, &i, is_fips);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
*outlen = i;
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index a17b6f39b1..ca66f3ec68 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -49,6 +49,8 @@
|
||||
#define UCHAR_MAX 255
|
||||
#endif
|
||||
|
||||
+#define MD5_DIGEST_SIZE 16
|
||||
+
|
||||
/* RFC 2865 */
|
||||
#define MAX_ATTRSIZE (UCHAR_MAX - 2)
|
||||
#define MAX_ATTRSETSIZE (KRAD_PACKET_SIZE_MAX - 20)
|
||||
@@ -79,10 +81,11 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||
krad_attr type, const krb5_data *in,
|
||||
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||
|
||||
-/* Encode the attributes into the buffer. */
|
||||
+/* Encode set into outbuf. If add_msgauth is true, include a zeroed
|
||||
+ * Message-Authenticator as the first attribute. */
|
||||
krb5_error_code
|
||||
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||
- const unsigned char *auth,
|
||||
+ const uint8_t *auth, krb5_boolean add_msgauth,
|
||||
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||
krb5_boolean *is_fips);
|
||||
|
||||
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||
index c5446b890c..3c1a4d507e 100644
|
||||
--- a/src/lib/krad/packet.c
|
||||
+++ b/src/lib/krad/packet.c
|
||||
@@ -36,6 +36,7 @@
|
||||
typedef unsigned char uchar;
|
||||
|
||||
/* RFC 2865 */
|
||||
+#define MSGAUTH_SIZE (2 + MD5_DIGEST_SIZE)
|
||||
#define OFFSET_CODE 0
|
||||
#define OFFSET_ID 1
|
||||
#define OFFSET_LENGTH 2
|
||||
@@ -222,6 +223,106 @@ packet_set_attrset(krb5_context ctx, const char *secret, krad_packet *pkt)
|
||||
return kr_attrset_decode(ctx, &tmp, secret, pkt_auth(pkt), &pkt->attrset);
|
||||
}
|
||||
|
||||
+/* Determine if a packet requires a Message-Authenticator attribute. */
|
||||
+static inline krb5_boolean
|
||||
+requires_msgauth(const char *secret, krad_code code)
|
||||
+{
|
||||
+ /* If no secret is provided, assume that the transport is a UNIX socket.
|
||||
+ * Message-Authenticator is required only on UDP and TCP connections. */
|
||||
+ if (*secret == '\0')
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /*
|
||||
+ * Per draft-ietf-radext-deprecating-radius-03 sections 5.2.1 and 5.2.4,
|
||||
+ * Message-Authenticator is required in Access-Request packets and all
|
||||
+ * potential responses when UDP or TCP transport is used.
|
||||
+ */
|
||||
+ return code == krad_code_name2num("Access-Request") ||
|
||||
+ code == krad_code_name2num("Access-Reject") ||
|
||||
+ code == krad_code_name2num("Access-Accept") ||
|
||||
+ code == krad_code_name2num("Access-Challenge");
|
||||
+}
|
||||
+
|
||||
+/* Check if the packet has a Message-Authenticator attribute. */
|
||||
+static inline krb5_boolean
|
||||
+has_pkt_msgauth(const krad_packet *pkt)
|
||||
+{
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+
|
||||
+ return krad_attrset_get(pkt->attrset, msgauth_type, 0) != NULL;
|
||||
+}
|
||||
+
|
||||
+/* Return the beginning of the Message-Authenticator attribute in pkt, or NULL
|
||||
+ * if no such attribute is present. */
|
||||
+static const uint8_t *
|
||||
+lookup_msgauth_addr(const krad_packet *pkt)
|
||||
+{
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ size_t i;
|
||||
+ uint8_t *p;
|
||||
+
|
||||
+ i = OFFSET_ATTR;
|
||||
+ while (i + 2 < pkt->pkt.length) {
|
||||
+ p = (uint8_t *)offset(&pkt->pkt, i);
|
||||
+ if (msgauth_type == *p)
|
||||
+ return p;
|
||||
+ i += p[1];
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Calculate the message authenticator MAC for pkt as specified in RFC 2869
|
||||
+ * section 5.14, placing the result in mac_out. Use the provided authenticator
|
||||
+ * auth, which may be from pkt or from a corresponding request.
|
||||
+ */
|
||||
+static krb5_error_code
|
||||
+calculate_mac(const char *secret, const krad_packet *pkt,
|
||||
+ const uint8_t auth[AUTH_FIELD_SIZE],
|
||||
+ uint8_t mac_out[MD5_DIGEST_SIZE])
|
||||
+{
|
||||
+ uint8_t zeroed_msgauth[MSGAUTH_SIZE];
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const uint8_t *msgauth_attr, *msgauth_end, *pkt_end;
|
||||
+ krb5_crypto_iov input[5];
|
||||
+ krb5_data ksecr, mac;
|
||||
+
|
||||
+ msgauth_attr = lookup_msgauth_addr(pkt);
|
||||
+ if (msgauth_attr == NULL)
|
||||
+ return EINVAL;
|
||||
+ msgauth_end = msgauth_attr + MSGAUTH_SIZE;
|
||||
+ pkt_end = (const uint8_t *)pkt->pkt.data + pkt->pkt.length;
|
||||
+
|
||||
+ /* Read code, id, and length from the packet. */
|
||||
+ input[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[0].data = make_data(pkt->pkt.data, OFFSET_AUTH);
|
||||
+
|
||||
+ /* Read the provided authenticator. */
|
||||
+ input[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[1].data = make_data((uint8_t *)auth, AUTH_FIELD_SIZE);
|
||||
+
|
||||
+ /* Read any attributes before Message-Authenticator. */
|
||||
+ input[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[2].data = make_data(pkt_attr(pkt), msgauth_attr - pkt_attr(pkt));
|
||||
+
|
||||
+ /* Read Message-Authenticator with the data bytes all set to zero, per RFC
|
||||
+ * 2869 section 5.14. */
|
||||
+ zeroed_msgauth[0] = msgauth_type;
|
||||
+ zeroed_msgauth[1] = MSGAUTH_SIZE;
|
||||
+ memset(zeroed_msgauth + 2, 0, MD5_DIGEST_SIZE);
|
||||
+ input[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[3].data = make_data(zeroed_msgauth, MSGAUTH_SIZE);
|
||||
+
|
||||
+ /* Read any attributes after Message-Authenticator. */
|
||||
+ input[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ input[4].data = make_data((uint8_t *)msgauth_end, pkt_end - msgauth_end);
|
||||
+
|
||||
+ mac = make_data(mac_out, MD5_DIGEST_SIZE);
|
||||
+ ksecr = string2data((char *)secret);
|
||||
+ return k5_hmac_md5(&ksecr, input, 5, &mac);
|
||||
+}
|
||||
+
|
||||
ssize_t
|
||||
krad_packet_bytes_needed(const krb5_data *buffer)
|
||||
{
|
||||
@@ -255,6 +356,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
krad_packet *pkt;
|
||||
uchar id;
|
||||
size_t attrset_len;
|
||||
+ krb5_boolean msgauth_required;
|
||||
|
||||
pkt = packet_new();
|
||||
if (pkt == NULL) {
|
||||
@@ -274,9 +376,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
+ /* Determine if Message-Authenticator is required. */
|
||||
+ msgauth_required = (*secret != '\0' &&
|
||||
+ code == krad_code_name2num("Access-Request"));
|
||||
+
|
||||
/* Encode the attributes. */
|
||||
- retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
|
||||
- &attrset_len, &pkt->is_fips);
|
||||
+ retval = kr_attrset_encode(set, secret, pkt_auth(pkt), msgauth_required,
|
||||
+ pkt_attr(pkt), &attrset_len, &pkt->is_fips);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
@@ -285,6 +391,13 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
pkt_code_set(pkt, code);
|
||||
pkt_len_set(pkt, pkt->pkt.length);
|
||||
|
||||
+ if (msgauth_required) {
|
||||
+ /* Calculate and set the Message-Authenticator MAC. */
|
||||
+ retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
|
||||
+ if (retval != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Copy the attrset for future use. */
|
||||
retval = packet_set_attrset(ctx, secret, pkt);
|
||||
if (retval != 0)
|
||||
@@ -307,14 +420,19 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
krb5_error_code retval;
|
||||
krad_packet *pkt;
|
||||
size_t attrset_len;
|
||||
+ krb5_boolean msgauth_required;
|
||||
|
||||
pkt = packet_new();
|
||||
if (pkt == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
+ /* Determine if Message-Authenticator is required. */
|
||||
+ msgauth_required = requires_msgauth(secret, code);
|
||||
+
|
||||
/* Encode the attributes. */
|
||||
- retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
|
||||
- &attrset_len, &pkt->is_fips);
|
||||
+ retval = kr_attrset_encode(set, secret, pkt_auth(request),
|
||||
+ msgauth_required, pkt_attr(pkt), &attrset_len,
|
||||
+ &pkt->is_fips);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
@@ -330,6 +448,18 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
|
||||
+ if (msgauth_required) {
|
||||
+ /*
|
||||
+ * Calculate and replace the Message-Authenticator MAC. Per RFC 2869
|
||||
+ * section 5.14, use the authenticator from the request, not from the
|
||||
+ * response.
|
||||
+ */
|
||||
+ retval = calculate_mac(secret, pkt, pkt_auth(request),
|
||||
+ pkt_attr(pkt) + 2);
|
||||
+ if (retval != 0)
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Copy the attrset for future use. */
|
||||
retval = packet_set_attrset(ctx, secret, pkt);
|
||||
if (retval != 0)
|
||||
@@ -343,6 +473,34 @@ error:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/* Verify the Message-Authenticator value in pkt, using the provided
|
||||
+ * authenticator (which may be from pkt or from a corresponding request). */
|
||||
+static krb5_error_code
|
||||
+verify_msgauth(const char *secret, const krad_packet *pkt,
|
||||
+ const uint8_t auth[AUTH_FIELD_SIZE])
|
||||
+{
|
||||
+ uint8_t mac[MD5_DIGEST_SIZE];
|
||||
+ krad_attr msgauth_type = krad_attr_name2num("Message-Authenticator");
|
||||
+ const krb5_data *msgauth;
|
||||
+ krb5_error_code retval;
|
||||
+
|
||||
+ msgauth = krad_packet_get_attr(pkt, msgauth_type, 0);
|
||||
+ if (msgauth == NULL)
|
||||
+ return ENODATA;
|
||||
+
|
||||
+ retval = calculate_mac(secret, pkt, auth, mac);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ if (msgauth->length != MD5_DIGEST_SIZE)
|
||||
+ return EMSGSIZE;
|
||||
+
|
||||
+ if (k5_bcmp(mac, msgauth->data, MD5_DIGEST_SIZE) != 0)
|
||||
+ return EBADMSG;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Decode a packet. */
|
||||
static krb5_error_code
|
||||
decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer,
|
||||
@@ -394,21 +552,35 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
|
||||
krad_packet **reqpkt)
|
||||
{
|
||||
const krad_packet *tmp = NULL;
|
||||
+ krad_packet *req;
|
||||
krb5_error_code retval;
|
||||
|
||||
- retval = decode_packet(ctx, secret, buffer, reqpkt);
|
||||
- if (cb != NULL && retval == 0) {
|
||||
+ retval = decode_packet(ctx, secret, buffer, &req);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ /* Verify Message-Authenticator if present. */
|
||||
+ if (has_pkt_msgauth(req)) {
|
||||
+ retval = verify_msgauth(secret, req, pkt_auth(req));
|
||||
+ if (retval) {
|
||||
+ krad_packet_free(req);
|
||||
+ return retval;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (cb != NULL) {
|
||||
for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) {
|
||||
if (pkt_id_get(*reqpkt) == pkt_id_get(tmp))
|
||||
break;
|
||||
}
|
||||
- }
|
||||
|
||||
- if (cb != NULL && (retval != 0 || tmp != NULL))
|
||||
- (*cb)(data, TRUE);
|
||||
+ if (tmp != NULL)
|
||||
+ (*cb)(data, TRUE);
|
||||
+ }
|
||||
|
||||
+ *reqpkt = req;
|
||||
*duppkt = tmp;
|
||||
- return retval;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -435,9 +607,17 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
|
||||
break;
|
||||
}
|
||||
|
||||
- /* If the authenticator matches, then the response is valid. */
|
||||
- if (memcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) == 0)
|
||||
- break;
|
||||
+ /* Verify the response authenticator. */
|
||||
+ if (k5_bcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Verify Message-Authenticator if present. */
|
||||
+ if (has_pkt_msgauth(*rsppkt)) {
|
||||
+ if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
|
||||
index 4cdb8b7d8e..f9c66509bd 100644
|
||||
--- a/src/lib/krad/t_attrset.c
|
||||
+++ b/src/lib/krad/t_attrset.c
|
||||
@@ -63,7 +63,7 @@ main(void)
|
||||
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
|
||||
|
||||
/* Encode attrset. */
|
||||
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
|
||||
+ noerror(kr_attrset_encode(set, "foo", auth, FALSE, buffer, &encode_len,
|
||||
&is_fips));
|
||||
krad_attrset_free(set);
|
||||
|
||||
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
|
||||
index 4a3de079c7..647d4894eb 100755
|
||||
--- a/src/lib/krad/t_daemon.py
|
||||
+++ b/src/lib/krad/t_daemon.py
|
||||
@@ -40,6 +40,7 @@ DICTIONARY = """
|
||||
ATTRIBUTE\tUser-Name\t1\tstring
|
||||
ATTRIBUTE\tUser-Password\t2\toctets
|
||||
ATTRIBUTE\tNAS-Identifier\t32\tstring
|
||||
+ATTRIBUTE\tMessage-Authenticator\t80\toctets
|
||||
"""
|
||||
|
||||
class TestServer(server.Server):
|
||||
@@ -52,7 +53,7 @@ class TestServer(server.Server):
|
||||
if key == "User-Password":
|
||||
passwd = [pkt.PwDecrypt(x) for x in pkt[key]]
|
||||
|
||||
- reply = self.CreateReplyPacket(pkt)
|
||||
+ reply = self.CreateReplyPacket(pkt, message_authenticator=True)
|
||||
if passwd == ['accept']:
|
||||
reply.code = packet.AccessAccept
|
||||
else:
|
||||
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
|
||||
index c22489144f..104b6507a2 100644
|
||||
--- a/src/lib/krad/t_packet.c
|
||||
+++ b/src/lib/krad/t_packet.c
|
||||
@@ -172,6 +172,9 @@ main(int argc, const char **argv)
|
||||
krb5_data username, password;
|
||||
krb5_boolean auth = FALSE;
|
||||
krb5_context ctx;
|
||||
+ const krad_packet *dupreq;
|
||||
+ const krb5_data *encpkt;
|
||||
+ krad_packet *decreq;
|
||||
|
||||
username = string2data("testUser");
|
||||
|
||||
@@ -184,9 +187,17 @@ main(int argc, const char **argv)
|
||||
|
||||
password = string2data("accept");
|
||||
noerror(make_packet(ctx, &username, &password, &packets[ACCEPT_PACKET]));
|
||||
+ encpkt = krad_packet_encode(packets[ACCEPT_PACKET]);
|
||||
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
|
||||
+ &dupreq, &decreq));
|
||||
+ krad_packet_free(decreq);
|
||||
|
||||
password = string2data("reject");
|
||||
noerror(make_packet(ctx, &username, &password, &packets[REJECT_PACKET]));
|
||||
+ encpkt = krad_packet_encode(packets[REJECT_PACKET]);
|
||||
+ noerror(krad_packet_decode_request(ctx, "foo", encpkt, NULL, NULL,
|
||||
+ &dupreq, &decreq));
|
||||
+ krad_packet_free(decreq);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
|
||||
index c3b820a411..dd5cdc5c26 100755
|
||||
--- a/src/tests/t_otp.py
|
||||
+++ b/src/tests/t_otp.py
|
||||
@@ -49,6 +49,7 @@ ATTRIBUTE User-Name 1 string
|
||||
ATTRIBUTE User-Password 2 octets
|
||||
ATTRIBUTE Service-Type 6 integer
|
||||
ATTRIBUTE NAS-Identifier 32 string
|
||||
+ATTRIBUTE Message-Authenticator 80 octets
|
||||
'''
|
||||
|
||||
class RadiusDaemon(Process):
|
||||
@@ -97,6 +98,8 @@ class RadiusDaemon(Process):
|
||||
reply.code = packet.AccessReject
|
||||
replyq['reply'] = False
|
||||
|
||||
+ reply.add_message_authenticator()
|
||||
+
|
||||
outq.put(replyq)
|
||||
if addr is None:
|
||||
sock.send(reply.ReplyPacket())
|
||||
--
|
||||
2.46.0
|
||||
|
||||
1027
0026-PKINIT-ECDH-support.patch
Normal file
1027
0026-PKINIT-ECDH-support.patch
Normal file
File diff suppressed because it is too large
Load diff
78
0027-Add-ecdsa-with-sha512-256-to-supportedCMSTypes.patch
Normal file
78
0027-Add-ecdsa-with-sha512-256-to-supportedCMSTypes.patch
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
From 43d10f1580c033fe706470e7588c720ac7854918 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 21 Jun 2023 18:27:11 +0200
|
||||
Subject: [PATCH] Add ecdsa-with-sha512/256 to supportedCMSTypes
|
||||
|
||||
Elliptic curve certificates are already supported for PKINIT
|
||||
pre-authentication, but their associated signature types aren't
|
||||
advertized. Add ecdsa-with-sha512 and ecdsa-with-sha256 OIDs to the
|
||||
supportedCMSTypes list sent by the client.
|
||||
|
||||
[ghudson@mit.edu: edited commit message]
|
||||
|
||||
ticket: 9100 (new)
|
||||
(cherry picked from commit 9913e5c92c4e5cb76d6ae58386f744766d2e6454)
|
||||
---
|
||||
src/plugins/preauth/pkinit/pkinit_constants.c | 38 +++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
index 10f8688ec2..905e90d29c 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
@@ -64,14 +64,52 @@ static char sha512WithRSAEncr_oid[9] = {
|
||||
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
|
||||
};
|
||||
|
||||
+/* RFC 3279 ecdsa-with-SHA1: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) 1 */
|
||||
+static char ecdsaWithSha1_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01
|
||||
+};
|
||||
+
|
||||
+/* RFC 5758 ecdsa-with-SHA256: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) ecdsa-with-SHA2(3) 2 */
|
||||
+static char ecdsaWithSha256_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02
|
||||
+};
|
||||
+
|
||||
+/* RFC 5758 ecdsa-with-SHA384: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) ecdsa-with-SHA2(3) 3 */
|
||||
+static char ecdsaWithSha384_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03
|
||||
+};
|
||||
+
|
||||
+/* RFC 5758 ecdsa-with-SHA512: iso(1) member-body(2) us(840) ansi-X9-62(10045)
|
||||
+ * signatures(4) ecdsa-with-SHA2(3) 4 */
|
||||
+static char ecdsaWithSha512_oid[] = {
|
||||
+ 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
|
||||
+};
|
||||
+
|
||||
const krb5_data sha256WithRSAEncr_id = {
|
||||
KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
|
||||
};
|
||||
const krb5_data sha512WithRSAEncr_id = {
|
||||
KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
|
||||
};
|
||||
+const krb5_data ecdsaWithSha1_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha1_oid), ecdsaWithSha1_oid
|
||||
+};
|
||||
+const krb5_data ecdsaWithSha256_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha256_oid), ecdsaWithSha256_oid
|
||||
+};
|
||||
+const krb5_data ecdsaWithSha384_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha384_oid), ecdsaWithSha384_oid
|
||||
+};
|
||||
+const krb5_data ecdsaWithSha512_id = {
|
||||
+ KV5M_DATA, sizeof(ecdsaWithSha512_oid), ecdsaWithSha512_oid
|
||||
+};
|
||||
|
||||
krb5_data const * const supported_cms_algs[] = {
|
||||
+ &ecdsaWithSha512_id,
|
||||
+ &ecdsaWithSha256_id,
|
||||
&sha512WithRSAEncr_id,
|
||||
&sha256WithRSAEncr_id,
|
||||
NULL
|
||||
--
|
||||
2.47.1
|
||||
|
||||
264
0028-Get-rid-of-pkinit_crypto_openssl.h.patch
Normal file
264
0028-Get-rid-of-pkinit_crypto_openssl.h.patch
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
From fba4cbf0bc50569b8ea6d1e1c3303eaab84935e1 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Sun, 30 Jul 2023 01:07:38 -0400
|
||||
Subject: [PATCH] Get rid of pkinit_crypto_openssl.h
|
||||
|
||||
Fold pkinit_crypto_openssl.h into the one source file where it was
|
||||
used. Also clean up the include of <arpa/inet.h>, as htonl() is no
|
||||
longer used after commit 1c87ce6c44a9de0824580a2d72a8a202237e01f4.
|
||||
|
||||
(cherry picked from commit b3352945fb8836f8b4095e0b8aad04b54aca3152)
|
||||
---
|
||||
src/plugins/preauth/pkinit/deps | 2 +-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 85 +++++++++++-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.h | 121 ------------------
|
||||
3 files changed, 83 insertions(+), 125 deletions(-)
|
||||
delete mode 100644 src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/deps b/src/plugins/preauth/pkinit/deps
|
||||
index 58320aa801..b6f4476fe8 100644
|
||||
--- a/src/plugins/preauth/pkinit/deps
|
||||
+++ b/src/plugins/preauth/pkinit/deps
|
||||
@@ -112,4 +112,4 @@ pkinit_crypto_openssl.so pkinit_crypto_openssl.po $(OUTPRE)pkinit_crypto_openssl
|
||||
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
|
||||
$(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
|
||||
pkcs11.h pkinit.h pkinit_accessor.h pkinit_crypto.h \
|
||||
- pkinit_crypto_openssl.c pkinit_crypto_openssl.h pkinit_trace.h
|
||||
+ pkinit_crypto_openssl.c pkinit_trace.h
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index f6d494bd11..ae8599d5a2 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -30,20 +30,99 @@
|
||||
*/
|
||||
|
||||
#include "k5-int.h"
|
||||
-#include "pkinit_crypto_openssl.h"
|
||||
#include "k5-buf.h"
|
||||
#include "k5-err.h"
|
||||
#include "k5-hex.h"
|
||||
-#include <unistd.h>
|
||||
+#include "pkinit.h"
|
||||
#include <dirent.h>
|
||||
-#include <arpa/inet.h>
|
||||
|
||||
+#include <openssl/bn.h>
|
||||
+#include <openssl/dh.h>
|
||||
+#include <openssl/x509.h>
|
||||
+#include <openssl/pkcs7.h>
|
||||
+#include <openssl/pkcs12.h>
|
||||
+#include <openssl/obj_mac.h>
|
||||
+#include <openssl/x509v3.h>
|
||||
+#include <openssl/err.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/sha.h>
|
||||
+#include <openssl/asn1.h>
|
||||
+#include <openssl/pem.h>
|
||||
+#include <openssl/asn1t.h>
|
||||
+#include <openssl/cms.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/kdf.h>
|
||||
+#include <openssl/decoder.h>
|
||||
#include <openssl/params.h>
|
||||
#endif
|
||||
|
||||
+#define DN_BUF_LEN 256
|
||||
+#define MAX_CREDS_ALLOWED 20
|
||||
+
|
||||
+struct _pkinit_cred_info {
|
||||
+ char *name;
|
||||
+ X509 *cert;
|
||||
+ EVP_PKEY *key;
|
||||
+#ifndef WITHOUT_PKCS11
|
||||
+ CK_BYTE_PTR cert_id;
|
||||
+ int cert_id_len;
|
||||
+#endif
|
||||
+};
|
||||
+typedef struct _pkinit_cred_info *pkinit_cred_info;
|
||||
+
|
||||
+struct _pkinit_identity_crypto_context {
|
||||
+ pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
|
||||
+ STACK_OF(X509) *my_certs; /* available user certs */
|
||||
+ char *identity; /* identity name for user cert */
|
||||
+ int cert_index; /* cert to use out of available certs*/
|
||||
+ EVP_PKEY *my_key; /* available user keys if in filesystem */
|
||||
+ STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
|
||||
+ STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
|
||||
+ STACK_OF(X509_CRL) *revoked; /* available crls */
|
||||
+ int pkcs11_method;
|
||||
+ krb5_prompter_fct prompter;
|
||||
+ void *prompter_data;
|
||||
+#ifndef WITHOUT_PKCS11
|
||||
+ char *p11_module_name;
|
||||
+ CK_SLOT_ID slotid;
|
||||
+ char *token_label;
|
||||
+ char *cert_label;
|
||||
+ /* These are crypto-specific. */
|
||||
+ struct plugin_file_handle *p11_module;
|
||||
+ CK_SESSION_HANDLE session;
|
||||
+ CK_FUNCTION_LIST_PTR p11;
|
||||
+ uint8_t *cert_id;
|
||||
+ size_t cert_id_len;
|
||||
+ CK_MECHANISM_TYPE mech;
|
||||
+#endif
|
||||
+ krb5_boolean defer_id_prompt;
|
||||
+ pkinit_deferred_id *deferred_ids;
|
||||
+};
|
||||
+
|
||||
+struct _pkinit_plg_crypto_context {
|
||||
+ EVP_PKEY *dh_1024;
|
||||
+ EVP_PKEY *dh_2048;
|
||||
+ EVP_PKEY *dh_4096;
|
||||
+ EVP_PKEY *ec_p256;
|
||||
+ EVP_PKEY *ec_p384;
|
||||
+ EVP_PKEY *ec_p521;
|
||||
+ ASN1_OBJECT *id_pkinit_authData;
|
||||
+ ASN1_OBJECT *id_pkinit_DHKeyData;
|
||||
+ ASN1_OBJECT *id_pkinit_rkeyData;
|
||||
+ ASN1_OBJECT *id_pkinit_san;
|
||||
+ ASN1_OBJECT *id_ms_san_upn;
|
||||
+ ASN1_OBJECT *id_pkinit_KPClientAuth;
|
||||
+ ASN1_OBJECT *id_pkinit_KPKdc;
|
||||
+ ASN1_OBJECT *id_ms_kp_sc_logon;
|
||||
+ ASN1_OBJECT *id_kp_serverAuth;
|
||||
+};
|
||||
+
|
||||
+struct _pkinit_req_crypto_context {
|
||||
+ X509 *received_cert;
|
||||
+ EVP_PKEY *client_pkey;
|
||||
+};
|
||||
+
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
|
||||
deleted file mode 100644
|
||||
index b7a3358800..0000000000
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
|
||||
+++ /dev/null
|
||||
@@ -1,121 +0,0 @@
|
||||
-/*
|
||||
- * COPYRIGHT (C) 2006,2007
|
||||
- * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
|
||||
- * ALL RIGHTS RESERVED
|
||||
- *
|
||||
- * Permission is granted to use, copy, create derivative works
|
||||
- * and redistribute this software and such derivative works
|
||||
- * for any purpose, so long as the name of The University of
|
||||
- * Michigan is not used in any advertising or publicity
|
||||
- * pertaining to the use of distribution of this software
|
||||
- * without specific, written prior authorization. If the
|
||||
- * above copyright notice or any other identification of the
|
||||
- * University of Michigan is included in any copy of any
|
||||
- * portion of this software, then the disclaimer below must
|
||||
- * also be included.
|
||||
- *
|
||||
- * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
|
||||
- * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
|
||||
- * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
|
||||
- * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
- * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
|
||||
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||
- * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
|
||||
- * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
|
||||
- * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
|
||||
- * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
|
||||
- * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
|
||||
- * SUCH DAMAGES.
|
||||
- */
|
||||
-
|
||||
-#ifndef _PKINIT_CRYPTO_OPENSSL_H
|
||||
-#define _PKINIT_CRYPTO_OPENSSL_H
|
||||
-
|
||||
-#include "pkinit.h"
|
||||
-
|
||||
-#include <openssl/bn.h>
|
||||
-#include <openssl/dh.h>
|
||||
-#include <openssl/x509.h>
|
||||
-#include <openssl/pkcs7.h>
|
||||
-#include <openssl/pkcs12.h>
|
||||
-#include <openssl/obj_mac.h>
|
||||
-#include <openssl/x509v3.h>
|
||||
-#include <openssl/err.h>
|
||||
-#include <openssl/evp.h>
|
||||
-#include <openssl/sha.h>
|
||||
-#include <openssl/asn1.h>
|
||||
-#include <openssl/pem.h>
|
||||
-#include <openssl/asn1t.h>
|
||||
-#include <openssl/cms.h>
|
||||
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
-#include <openssl/core_names.h>
|
||||
-#include <openssl/decoder.h>
|
||||
-#endif
|
||||
-
|
||||
-#define DN_BUF_LEN 256
|
||||
-#define MAX_CREDS_ALLOWED 20
|
||||
-
|
||||
-struct _pkinit_cred_info {
|
||||
- char *name;
|
||||
- X509 *cert;
|
||||
- EVP_PKEY *key;
|
||||
-#ifndef WITHOUT_PKCS11
|
||||
- CK_BYTE_PTR cert_id;
|
||||
- int cert_id_len;
|
||||
-#endif
|
||||
-};
|
||||
-typedef struct _pkinit_cred_info * pkinit_cred_info;
|
||||
-
|
||||
-struct _pkinit_identity_crypto_context {
|
||||
- pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
|
||||
- STACK_OF(X509) *my_certs; /* available user certs */
|
||||
- char *identity; /* identity name for user cert */
|
||||
- int cert_index; /* cert to use out of available certs*/
|
||||
- EVP_PKEY *my_key; /* available user keys if in filesystem */
|
||||
- STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
|
||||
- STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
|
||||
- STACK_OF(X509_CRL) *revoked; /* available crls */
|
||||
- int pkcs11_method;
|
||||
- krb5_prompter_fct prompter;
|
||||
- void *prompter_data;
|
||||
-#ifndef WITHOUT_PKCS11
|
||||
- char *p11_module_name;
|
||||
- CK_SLOT_ID slotid;
|
||||
- char *token_label;
|
||||
- char *cert_label;
|
||||
- /* These are crypto-specific */
|
||||
- struct plugin_file_handle *p11_module;
|
||||
- CK_SESSION_HANDLE session;
|
||||
- CK_FUNCTION_LIST_PTR p11;
|
||||
- uint8_t *cert_id;
|
||||
- size_t cert_id_len;
|
||||
- CK_MECHANISM_TYPE mech;
|
||||
-#endif
|
||||
- krb5_boolean defer_id_prompt;
|
||||
- pkinit_deferred_id *deferred_ids;
|
||||
-};
|
||||
-
|
||||
-struct _pkinit_plg_crypto_context {
|
||||
- EVP_PKEY *dh_1024;
|
||||
- EVP_PKEY *dh_2048;
|
||||
- EVP_PKEY *dh_4096;
|
||||
- EVP_PKEY *ec_p256;
|
||||
- EVP_PKEY *ec_p384;
|
||||
- EVP_PKEY *ec_p521;
|
||||
- ASN1_OBJECT *id_pkinit_authData;
|
||||
- ASN1_OBJECT *id_pkinit_DHKeyData;
|
||||
- ASN1_OBJECT *id_pkinit_rkeyData;
|
||||
- ASN1_OBJECT *id_pkinit_san;
|
||||
- ASN1_OBJECT *id_ms_san_upn;
|
||||
- ASN1_OBJECT *id_pkinit_KPClientAuth;
|
||||
- ASN1_OBJECT *id_pkinit_KPKdc;
|
||||
- ASN1_OBJECT *id_ms_kp_sc_logon;
|
||||
- ASN1_OBJECT *id_kp_serverAuth;
|
||||
-};
|
||||
-
|
||||
-struct _pkinit_req_crypto_context {
|
||||
- X509 *received_cert;
|
||||
- EVP_PKEY *client_pkey;
|
||||
-};
|
||||
-
|
||||
-#endif /* _PKINIT_CRYPTO_OPENSSL_H */
|
||||
--
|
||||
2.47.1
|
||||
|
||||
157
0029-Use-SoftHSMv2-for-PKCS11-PKINIT-tests.patch
Normal file
157
0029-Use-SoftHSMv2-for-PKCS11-PKINIT-tests.patch
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
From 1b01057df4c2223fbf92be44f1e764207208ef03 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 26 Feb 2024 19:03:38 -0500
|
||||
Subject: [PATCH] Use SoftHSMv2 for PKCS11 PKINIT tests
|
||||
|
||||
Instead of softpkcs11, use SoftHSMv2 to mock the PKCS11 token for
|
||||
PKINIT tests. Use pkcs11-tool from OpenSC to initialize the token and
|
||||
import a certificate and key. SoftHSM does not support PIN-less
|
||||
tokens (see https://github.com/opendnssec/SoftHSMv2/issues/480) so
|
||||
remove that test for now.
|
||||
|
||||
(cherry picked from commit 8ab61608236883fdc5c2d43f4bd1ff2094401d19)
|
||||
---
|
||||
.github/workflows/build.yml | 2 +-
|
||||
src/tests/t_pkinit.py | 82 ++++++++++++++++++++-----------------
|
||||
2 files changed, 45 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
|
||||
index 68a4788adb..d7ae86b150 100644
|
||||
--- a/.github/workflows/build.yml
|
||||
+++ b/.github/workflows/build.yml
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
- sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh
|
||||
+ sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh softhsm2 opensc
|
||||
pip3 install pyrad
|
||||
- name: Build
|
||||
env:
|
||||
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
|
||||
index f8f2debc1b..4435746429 100755
|
||||
--- a/src/tests/t_pkinit.py
|
||||
+++ b/src/tests/t_pkinit.py
|
||||
@@ -1,11 +1,10 @@
|
||||
from k5test import *
|
||||
+import re
|
||||
|
||||
# Skip this test if pkinit wasn't built.
|
||||
if not pkinit_enabled:
|
||||
skip_rest('PKINIT tests', 'PKINIT module not built')
|
||||
|
||||
-soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')
|
||||
-
|
||||
# Construct a krb5.conf fragment configuring pkinit.
|
||||
user_pem = os.path.join(pkinit_certs, 'user.pem')
|
||||
privkey_pem = os.path.join(pkinit_certs, 'privkey.pem')
|
||||
@@ -55,9 +54,6 @@ p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
|
||||
p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
|
||||
p12_generic_identity = 'PKCS12:%s' % generic_p12
|
||||
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
|
||||
-p11_identity = 'PKCS11:' + soft_pkcs11
|
||||
-p11_token_identity = ('PKCS11:module_name=' + soft_pkcs11 +
|
||||
- ':slotid=1:token=SoftToken (token)')
|
||||
|
||||
# Start a realm with the test kdb module for the following UPN SAN tests.
|
||||
realm = K5Realm(kdc_conf=alias_kdc_conf, create_kdb=False, pkinit=True)
|
||||
@@ -389,53 +385,63 @@ realm.klist(realm.user_princ)
|
||||
realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
|
||||
expected_code=1, expected_msg='Preauthentication failed while')
|
||||
|
||||
-softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
|
||||
-realm.env['SOFTPKCS11RC'] = softpkcs11rc
|
||||
+softhsm2 = '/usr/lib/softhsm/libsofthsm2.so'
|
||||
+if not os.path.exists(softhsm2):
|
||||
+ skip_rest('PKCS11 tests', 'SoftHSMv2 required')
|
||||
+pkcs11_tool = which('pkcs11-tool')
|
||||
+if not pkcs11_tool:
|
||||
+ skip_rest('PKCS11 tests', 'pkcs11-tool from OpenSC required')
|
||||
+tool_cmd = [pkcs11_tool, '--module', softhsm2]
|
||||
+
|
||||
+# Prepare a SoftHSM token.
|
||||
+softhsm2_conf = os.path.join(realm.testdir, 'softhsm2.conf')
|
||||
+softhsm2_tokens = os.path.join(realm.testdir, 'tokens')
|
||||
+os.mkdir(softhsm2_tokens)
|
||||
+realm.env['SOFTHSM2_CONF'] = softhsm2_conf
|
||||
+with open(softhsm2_conf, 'w') as f:
|
||||
+ f.write('directories.tokendir = %s\n' % softhsm2_tokens)
|
||||
+realm.run(tool_cmd + ['--init-token', '--label', 'user',
|
||||
+ '--so-pin', 'sopin', '--init-pin', '--pin', 'userpin'])
|
||||
+realm.run(tool_cmd + ['-w', user_pem, '-y', 'cert'])
|
||||
+realm.run(tool_cmd + ['-w', privkey_pem, '-y', 'privkey',
|
||||
+ '-l', '--pin', 'userpin'])
|
||||
+
|
||||
+# Extract the slot ID generated by SoftHSM.
|
||||
+out = realm.run(tool_cmd + ['-L'])
|
||||
+m = re.search(r'slot ID 0x([0-9a-f]+)\n', out)
|
||||
+if not m:
|
||||
+ fail('could not extract slot ID from SoftHSM token')
|
||||
+slot_id = int(m.group(1), 16)
|
||||
+
|
||||
+p11_attr = 'X509_user_identity=PKCS11:' + softhsm2
|
||||
+p11_token_identity = ('PKCS11:module_name=%s:slotid=%d:token=user' %
|
||||
+ (softhsm2, slot_id))
|
||||
|
||||
-# PKINIT with PKCS11: identity, with no need for a PIN.
|
||||
-mark('PKCS11 identity, no PIN')
|
||||
-conf = open(softpkcs11rc, 'w')
|
||||
-conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem))
|
||||
-conf.close()
|
||||
-# Expect to succeed without having to supply any more information.
|
||||
-realm.kinit(realm.user_princ,
|
||||
- flags=['-X', 'X509_user_identity=%s' % p11_identity])
|
||||
+mark('PKCS11 identity, with PIN (prompter)')
|
||||
+realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='userpin')
|
||||
realm.klist(realm.user_princ)
|
||||
realm.run([kvno, realm.host_princ])
|
||||
|
||||
-# PKINIT with PKCS11: identity, with a PIN supplied by the prompter.
|
||||
-mark('PKCS11 identity, with PIN (prompter)')
|
||||
-os.remove(softpkcs11rc)
|
||||
-conf = open(softpkcs11rc, 'w')
|
||||
-conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
|
||||
- privkey_enc_pem))
|
||||
-conf.close()
|
||||
-# Expect failure if the responder does nothing, and there's no prompter
|
||||
+mark('PKCS11 identity, unavailable PIN')
|
||||
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
|
||||
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ],
|
||||
- expected_code=2)
|
||||
-realm.kinit(realm.user_princ,
|
||||
- flags=['-X', 'X509_user_identity=%s' % p11_identity],
|
||||
- password='encrypted')
|
||||
-realm.klist(realm.user_princ)
|
||||
-realm.run([kvno, realm.host_princ])
|
||||
+ '-X', p11_attr, realm.user_princ], expected_code=2)
|
||||
|
||||
-# Supply the wrong PIN.
|
||||
mark('PKCS11 identity, wrong PIN')
|
||||
expected_trace = ('PKINIT client has no configured identity; giving up',)
|
||||
realm.kinit(realm.user_princ,
|
||||
- flags=['-X', 'X509_user_identity=%s' % p11_identity],
|
||||
+ flags=['-X', p11_attr],
|
||||
password='wrong', expected_code=1, expected_trace=expected_trace)
|
||||
|
||||
# PKINIT with PKCS11: identity, with a PIN supplied by the responder.
|
||||
-# Supply the response in raw form.
|
||||
+# Supply the response in raw form. Expect the PIN_COUNT_LOW flag (1)
|
||||
+# to be set due to the previous test.
|
||||
mark('PKCS11 identity, with PIN (responder)')
|
||||
-realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
|
||||
- '-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity,
|
||||
- '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ])
|
||||
+realm.run(['./responder', '-x', 'pkinit={"%s": 1}' % p11_token_identity,
|
||||
+ '-r', 'pkinit={"%s": "userpin"}' % p11_token_identity,
|
||||
+ '-X', p11_attr, realm.user_princ])
|
||||
# Supply the response through the convenience API.
|
||||
-realm.run(['./responder', '-X', 'X509_user_identity=%s' % p11_identity,
|
||||
- '-p', '%s=%s' % (p11_token_identity, 'encrypted'),
|
||||
+realm.run(['./responder', '-X', p11_attr,
|
||||
+ '-p', '%s=%s' % (p11_token_identity, 'userpin'),
|
||||
realm.user_princ])
|
||||
realm.klist(realm.user_princ)
|
||||
realm.run([kvno, realm.host_princ])
|
||||
--
|
||||
2.47.1
|
||||
|
||||
202
0030-Simplify-PKINIT-cert-representation.patch
Normal file
202
0030-Simplify-PKINIT-cert-representation.patch
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
From b0315d30f066c4241fcecc33dd9e4d1c7c28b9d8 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 9 Feb 2024 17:32:40 -0500
|
||||
Subject: [PATCH] Simplify PKINIT cert representation
|
||||
|
||||
In the _pkinit_identity_crypto_context structure, the my_certs field
|
||||
is a stack which only ever contains one cert and is only ever used to
|
||||
retrieve that one cert. The cert_index field is always 0. Replace
|
||||
these fields with a my_cert field pointing directly to the X509
|
||||
certificate.
|
||||
|
||||
Simplify crypto_cert_select_default() by making it call
|
||||
crypto_cert_select() with index 0 after verifying the certificate
|
||||
count.
|
||||
|
||||
(cherry picked from commit f95dfb7908456f9563cee66706216a21df8d791f)
|
||||
---
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 74 +++++--------------
|
||||
1 file changed, 20 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index ae8599d5a2..da59cb1e02 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -73,10 +73,9 @@ typedef struct _pkinit_cred_info *pkinit_cred_info;
|
||||
|
||||
struct _pkinit_identity_crypto_context {
|
||||
pkinit_cred_info creds[MAX_CREDS_ALLOWED+1];
|
||||
- STACK_OF(X509) *my_certs; /* available user certs */
|
||||
+ X509 *my_cert; /* selected user or KDC cert */
|
||||
char *identity; /* identity name for user cert */
|
||||
- int cert_index; /* cert to use out of available certs*/
|
||||
- EVP_PKEY *my_key; /* available user keys if in filesystem */
|
||||
+ EVP_PKEY *my_key; /* selected cert key if in filesystem */
|
||||
STACK_OF(X509) *trustedCAs; /* available trusted ca certs */
|
||||
STACK_OF(X509) *intermediateCAs; /* available intermediate ca certs */
|
||||
STACK_OF(X509_CRL) *revoked; /* available crls */
|
||||
@@ -1489,8 +1488,7 @@ pkinit_init_certs(pkinit_identity_crypto_context ctx)
|
||||
|
||||
for (i = 0; i < MAX_CREDS_ALLOWED; i++)
|
||||
ctx->creds[i] = NULL;
|
||||
- ctx->my_certs = NULL;
|
||||
- ctx->cert_index = 0;
|
||||
+ ctx->my_cert = NULL;
|
||||
ctx->my_key = NULL;
|
||||
ctx->trustedCAs = NULL;
|
||||
ctx->intermediateCAs = NULL;
|
||||
@@ -1506,8 +1504,8 @@ pkinit_fini_certs(pkinit_identity_crypto_context ctx)
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
- if (ctx->my_certs != NULL)
|
||||
- sk_X509_pop_free(ctx->my_certs, X509_free);
|
||||
+ if (ctx->my_cert != NULL)
|
||||
+ X509_free(ctx->my_cert);
|
||||
|
||||
if (ctx->my_key != NULL)
|
||||
EVP_PKEY_free(ctx->my_key);
|
||||
@@ -1696,7 +1694,6 @@ cms_signeddata_create(krb5_context context,
|
||||
ASN1_OCTET_STRING *digest = NULL;
|
||||
unsigned int alg_len = 0, digest_len = 0;
|
||||
unsigned char *y = NULL;
|
||||
- X509 *cert = NULL;
|
||||
ASN1_OBJECT *oid = NULL, *oid_copy;
|
||||
|
||||
/* Start creating PKCS7 data. */
|
||||
@@ -1715,7 +1712,7 @@ cms_signeddata_create(krb5_context context,
|
||||
if (oid == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- if (id_cryptoctx->my_certs != NULL) {
|
||||
+ if (id_cryptoctx->my_cert != NULL) {
|
||||
X509_STORE *certstore = NULL;
|
||||
X509_STORE_CTX *certctx;
|
||||
STACK_OF(X509) *certstack = NULL;
|
||||
@@ -1726,8 +1723,6 @@ cms_signeddata_create(krb5_context context,
|
||||
if ((cert_stack = sk_X509_new_null()) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
|
||||
-
|
||||
certstore = X509_STORE_new();
|
||||
if (certstore == NULL)
|
||||
goto cleanup;
|
||||
@@ -1736,7 +1731,7 @@ cms_signeddata_create(krb5_context context,
|
||||
certctx = X509_STORE_CTX_new();
|
||||
if (certctx == NULL)
|
||||
goto cleanup;
|
||||
- X509_STORE_CTX_init(certctx, certstore, cert,
|
||||
+ X509_STORE_CTX_init(certctx, certstore, id_cryptoctx->my_cert,
|
||||
id_cryptoctx->intermediateCAs);
|
||||
X509_STORE_CTX_trusted_stack(certctx, id_cryptoctx->trustedCAs);
|
||||
if (!X509_verify_cert(certctx)) {
|
||||
@@ -1764,13 +1759,13 @@ cms_signeddata_create(krb5_context context,
|
||||
if (!ASN1_INTEGER_set(p7si->version, 1))
|
||||
goto cleanup;
|
||||
if (!X509_NAME_set(&p7si->issuer_and_serial->issuer,
|
||||
- X509_get_issuer_name(cert)))
|
||||
+ X509_get_issuer_name(id_cryptoctx->my_cert)))
|
||||
goto cleanup;
|
||||
/* because ASN1_INTEGER_set is used to set a 'long' we will do
|
||||
* things the ugly way. */
|
||||
ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
|
||||
if (!(p7si->issuer_and_serial->serial =
|
||||
- ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
|
||||
+ ASN1_INTEGER_dup(X509_get_serialNumber(id_cryptoctx->my_cert))))
|
||||
goto cleanup;
|
||||
|
||||
/* will not fill-out EVP_PKEY because it's on the smartcard */
|
||||
@@ -3311,7 +3306,7 @@ pkinit_check_kdc_pkid(krb5_context context,
|
||||
PKCS7_ISSUER_AND_SERIAL *is = NULL;
|
||||
const unsigned char *p = pdid_buf;
|
||||
int status = 1;
|
||||
- X509 *kdc_cert = sk_X509_value(id_cryptoctx->my_certs, id_cryptoctx->cert_index);
|
||||
+ X509 *kdc_cert = id_cryptoctx->my_cert;
|
||||
|
||||
*valid_kdcPkId = 0;
|
||||
pkiDebug("found kdcPkId in AS REQ\n");
|
||||
@@ -4783,7 +4778,8 @@ cleanup:
|
||||
}
|
||||
|
||||
/*
|
||||
- * Set the certificate in idctx->creds[cred_index] as the selected certificate.
|
||||
+ * Set the certificate in idctx->creds[cred_index] as the selected certificate,
|
||||
+ * stealing pointers from it.
|
||||
*/
|
||||
krb5_error_code
|
||||
crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,
|
||||
@@ -4795,20 +4791,17 @@ crypto_cert_select(krb5_context context, pkinit_identity_crypto_context idctx,
|
||||
return ENOENT;
|
||||
|
||||
ci = idctx->creds[cred_index];
|
||||
- /* copy the selected cert into our id_cryptoctx */
|
||||
- if (idctx->my_certs != NULL)
|
||||
- sk_X509_pop_free(idctx->my_certs, X509_free);
|
||||
- idctx->my_certs = sk_X509_new_null();
|
||||
- sk_X509_push(idctx->my_certs, ci->cert);
|
||||
- free(idctx->identity);
|
||||
+
|
||||
+ idctx->my_cert = ci->cert;
|
||||
+ ci->cert = NULL;
|
||||
+
|
||||
/* hang on to the selected credential name */
|
||||
+ free(idctx->identity);
|
||||
if (ci->name != NULL)
|
||||
idctx->identity = strdup(ci->name);
|
||||
else
|
||||
idctx->identity = NULL;
|
||||
|
||||
- ci->cert = NULL; /* Don't free it twice */
|
||||
- idctx->cert_index = 0;
|
||||
if (idctx->pkcs11_method != 1) {
|
||||
idctx->my_key = ci->key;
|
||||
ci->key = NULL; /* Don't free it twice */
|
||||
@@ -4837,41 +4830,14 @@ crypto_cert_select_default(krb5_context context,
|
||||
|
||||
retval = crypto_cert_get_count(id_cryptoctx, &cert_count);
|
||||
if (retval)
|
||||
- goto errout;
|
||||
+ return retval;
|
||||
|
||||
if (cert_count != 1) {
|
||||
TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count);
|
||||
- retval = EINVAL;
|
||||
- goto errout;
|
||||
- }
|
||||
- /* copy the selected cert into our id_cryptoctx */
|
||||
- if (id_cryptoctx->my_certs != NULL) {
|
||||
- sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
|
||||
+ return EINVAL;
|
||||
}
|
||||
- id_cryptoctx->my_certs = sk_X509_new_null();
|
||||
- sk_X509_push(id_cryptoctx->my_certs, id_cryptoctx->creds[0]->cert);
|
||||
- id_cryptoctx->creds[0]->cert = NULL; /* Don't free it twice */
|
||||
- id_cryptoctx->cert_index = 0;
|
||||
- /* hang on to the selected credential name */
|
||||
- if (id_cryptoctx->creds[0]->name != NULL)
|
||||
- id_cryptoctx->identity = strdup(id_cryptoctx->creds[0]->name);
|
||||
- else
|
||||
- id_cryptoctx->identity = NULL;
|
||||
|
||||
- if (id_cryptoctx->pkcs11_method != 1) {
|
||||
- id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
|
||||
- id_cryptoctx->creds[0]->key = NULL; /* Don't free it twice */
|
||||
- }
|
||||
-#ifndef WITHOUT_PKCS11
|
||||
- else {
|
||||
- id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
|
||||
- id_cryptoctx->creds[0]->cert_id = NULL; /* Don't free it twice */
|
||||
- id_cryptoctx->cert_id_len = id_cryptoctx->creds[0]->cert_id_len;
|
||||
- }
|
||||
-#endif
|
||||
- retval = 0;
|
||||
-errout:
|
||||
- return retval;
|
||||
+ return crypto_cert_select(context, id_cryptoctx, 0);
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
||||
1768
0031-Support-PKCS11-EC-client-certs-in-PKINIT.patch
Normal file
1768
0031-Support-PKCS11-EC-client-certs-in-PKINIT.patch
Normal file
File diff suppressed because it is too large
Load diff
599
0032-Improve-PKCS11-error-reporting-in-PKINIT.patch
Normal file
599
0032-Improve-PKCS11-error-reporting-in-PKINIT.patch
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
From e43c05e7b0b93401dd68fc3ec3186c3a455b04ea Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 23 Feb 2024 13:51:26 -0500
|
||||
Subject: [PATCH] Improve PKCS11 error reporting in PKINIT
|
||||
|
||||
Create a helper p11err() to set extended error message for failed
|
||||
PKCS11 operations, and use it instead of pkiDebug() and pkcs11error().
|
||||
|
||||
ticket: 9113 (new)
|
||||
(cherry picked from commit 98afb314d13939cbee19c69885dcb655db8460da)
|
||||
---
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 262 ++++++++++--------
|
||||
src/plugins/preauth/pkinit/pkinit_trace.h | 9 -
|
||||
2 files changed, 142 insertions(+), 129 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 4accfc2664..402bf1b9b3 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -161,9 +161,11 @@ static krb5_error_code pkinit_create_sequence_of_principal_identifiers
|
||||
int type, krb5_pa_data ***e_data_out);
|
||||
|
||||
#ifndef WITHOUT_PKCS11
|
||||
-static krb5_error_code pkinit_find_private_key
|
||||
-(pkinit_identity_crypto_context, CK_ATTRIBUTE_TYPE usage,
|
||||
- CK_OBJECT_HANDLE *objp);
|
||||
+static krb5_error_code
|
||||
+pkinit_find_private_key(krb5_context context,
|
||||
+ pkinit_identity_crypto_context id_cryptoctx,
|
||||
+ CK_ATTRIBUTE_TYPE usage,
|
||||
+ CK_OBJECT_HANDLE *objp);
|
||||
static krb5_error_code pkinit_login
|
||||
(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
|
||||
CK_TOKEN_INFO *tip, const char *password);
|
||||
@@ -180,6 +182,8 @@ static krb5_error_code pkinit_sign_data_pkcs11
|
||||
(krb5_context context, pkinit_identity_crypto_context id_cryptoctx,
|
||||
unsigned char *data, unsigned int data_len,
|
||||
unsigned char **sig, unsigned int *sig_len);
|
||||
+
|
||||
+static krb5_error_code p11err(krb5_context context, CK_RV rv, const char *op);
|
||||
#endif /* WITHOUT_PKCS11 */
|
||||
|
||||
static krb5_error_code pkinit_sign_data_fs
|
||||
@@ -197,9 +201,6 @@ create_krb5_invalidCertificates(krb5_context context,
|
||||
static krb5_error_code
|
||||
create_identifiers_from_stack(STACK_OF(X509) *sk,
|
||||
krb5_external_principal_identifier *** ids);
|
||||
-static const char *
|
||||
-pkcs11err(int err);
|
||||
-
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
|
||||
@@ -944,8 +945,9 @@ cleanup:
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||
|
||||
+#ifndef WITHOUT_PKC11
|
||||
static struct pkcs11_errstrings {
|
||||
- short code;
|
||||
+ CK_RV code;
|
||||
char *text;
|
||||
} pkcs11_errstrings[] = {
|
||||
{ 0x0, "ok" },
|
||||
@@ -1035,6 +1037,7 @@ static struct pkcs11_errstrings {
|
||||
{ 0x200, "function rejected" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
+#endif
|
||||
|
||||
MAKE_INIT_FUNCTION(pkinit_openssl_init);
|
||||
|
||||
@@ -1563,6 +1566,8 @@ pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
|
||||
free(ctx->token_label);
|
||||
free(ctx->cert_id);
|
||||
free(ctx->cert_label);
|
||||
+ ctx->p11_module_name = ctx->token_label = ctx->cert_label = NULL;
|
||||
+ ctx->cert_id = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3344,48 +3349,53 @@ pkinit_pkcs7type2oid(pkinit_plg_crypto_context cryptoctx, int pkcs7_type)
|
||||
}
|
||||
|
||||
#ifndef WITHOUT_PKCS11
|
||||
-static struct plugin_file_handle *
|
||||
+static krb5_error_code
|
||||
load_pkcs11_module(krb5_context context, const char *modname,
|
||||
- CK_FUNCTION_LIST_PTR_PTR p11p)
|
||||
+ struct plugin_file_handle **handle_out,
|
||||
+ CK_FUNCTION_LIST_PTR_PTR p11_out)
|
||||
{
|
||||
struct plugin_file_handle *handle = NULL;
|
||||
- CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
|
||||
+ CK_RV rv, (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
|
||||
struct errinfo einfo = EMPTY_ERRINFO;
|
||||
- const char *errmsg = NULL;
|
||||
+ const char *errmsg = NULL, *failure;
|
||||
void (*sym)(void);
|
||||
long err;
|
||||
- CK_RV rv;
|
||||
|
||||
TRACE_PKINIT_PKCS11_OPEN(context, modname);
|
||||
err = krb5int_open_plugin(modname, &handle, &einfo);
|
||||
if (err) {
|
||||
- errmsg = k5_get_error(&einfo, err);
|
||||
- TRACE_PKINIT_PKCS11_OPEN_FAILED(context, errmsg);
|
||||
+ failure = _("Cannot load PKCS11 module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = krb5int_get_plugin_func(handle, "C_GetFunctionList", &sym, &einfo);
|
||||
if (err) {
|
||||
- errmsg = k5_get_error(&einfo, err);
|
||||
- TRACE_PKINIT_PKCS11_GETSYM_FAILED(context, errmsg);
|
||||
+ failure = _("Cannot find C_GetFunctionList in PKCS11 module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))sym;
|
||||
- rv = (*getflist)(p11p);
|
||||
+ rv = (*getflist)(p11_out);
|
||||
if (rv != CKR_OK) {
|
||||
- TRACE_PKINIT_PKCS11_GETFLIST_FAILED(context, pkcs11err(rv));
|
||||
+ failure = _("Cannot retrieve function list in PKCS11 module");
|
||||
goto error;
|
||||
}
|
||||
|
||||
- return handle;
|
||||
+ *handle_out = handle;
|
||||
+ return 0;
|
||||
|
||||
error:
|
||||
- k5_free_error(&einfo, errmsg);
|
||||
+ if (err) {
|
||||
+ errmsg = k5_get_error(&einfo, err);
|
||||
+ k5_setmsg(context, err, _("%s: %s"), failure, errmsg);
|
||||
+ } else {
|
||||
+ err = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ k5_setmsg(context, err, "%s", failure);
|
||||
+ }
|
||||
k5_clear_error(&einfo);
|
||||
if (handle != NULL)
|
||||
krb5int_close_plugin(handle);
|
||||
- return NULL;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
@@ -3393,12 +3403,13 @@ pkinit_login(krb5_context context,
|
||||
pkinit_identity_crypto_context id_cryptoctx,
|
||||
CK_TOKEN_INFO *tip, const char *password)
|
||||
{
|
||||
+ krb5_error_code ret = 0;
|
||||
+ CK_RV rv;
|
||||
krb5_data rdat;
|
||||
char *prompt;
|
||||
const char *warning;
|
||||
krb5_prompt kprompt;
|
||||
krb5_prompt_type prompt_type;
|
||||
- int r = 0;
|
||||
|
||||
if (tip->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
|
||||
rdat.data = NULL;
|
||||
@@ -3407,7 +3418,7 @@ pkinit_login(krb5_context context,
|
||||
rdat.data = strdup(password);
|
||||
rdat.length = strlen(password);
|
||||
} else if (id_cryptoctx->prompter == NULL) {
|
||||
- r = KRB5_LIBOS_CANTREADPWD;
|
||||
+ ret = KRB5_LIBOS_CANTREADPWD;
|
||||
rdat.data = NULL;
|
||||
} else {
|
||||
if (tip->flags & CKF_USER_PIN_LOCKED)
|
||||
@@ -3431,31 +3442,28 @@ pkinit_login(krb5_context context,
|
||||
|
||||
/* PROMPTER_INVOCATION */
|
||||
k5int_set_prompt_types(context, &prompt_type);
|
||||
- r = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
|
||||
- NULL, NULL, 1, &kprompt);
|
||||
+ ret = (*id_cryptoctx->prompter)(context, id_cryptoctx->prompter_data,
|
||||
+ NULL, NULL, 1, &kprompt);
|
||||
k5int_set_prompt_types(context, 0);
|
||||
free(prompt);
|
||||
}
|
||||
|
||||
- if (r == 0) {
|
||||
- r = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
|
||||
- (u_char *) rdat.data, rdat.length);
|
||||
-
|
||||
- if (r != CKR_OK) {
|
||||
- TRACE_PKINIT_PKCS11_LOGIN_FAILED(context, pkcs11err(r));
|
||||
- r = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
- }
|
||||
+ if (!ret) {
|
||||
+ rv = id_cryptoctx->p11->C_Login(id_cryptoctx->session, CKU_USER,
|
||||
+ (uint8_t *)rdat.data, rdat.length);
|
||||
+ if (rv != CKR_OK)
|
||||
+ ret = p11err(context, rv, "C_Login");
|
||||
}
|
||||
free(rdat.data);
|
||||
|
||||
- return r;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
pkinit_open_session(krb5_context context,
|
||||
pkinit_identity_crypto_context cctx)
|
||||
{
|
||||
- CK_ULONG i, pret;
|
||||
+ CK_ULONG i, rv;
|
||||
unsigned char *cp;
|
||||
size_t label_len;
|
||||
CK_ULONG count = 0;
|
||||
@@ -3469,30 +3477,35 @@ pkinit_open_session(krb5_context context,
|
||||
return 0; /* session already open */
|
||||
|
||||
/* Load module */
|
||||
- cctx->p11_module = load_pkcs11_module(context, cctx->p11_module_name,
|
||||
- &cctx->p11);
|
||||
- if (cctx->p11_module == NULL)
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ ret = load_pkcs11_module(context, cctx->p11_module_name, &cctx->p11_module,
|
||||
+ &cctx->p11);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
/* Init */
|
||||
- pret = cctx->p11->C_Initialize(NULL);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_Initialize: %s\n", pkcs11err(pret));
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_Initialize(NULL);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_Initialize");
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* Get the list of available slots */
|
||||
- if (cctx->p11->C_GetSlotList(TRUE, NULL, &count) != CKR_OK)
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_GetSlotList(TRUE, NULL, &count);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetSlotList");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (count == 0) {
|
||||
TRACE_PKINIT_PKCS11_NO_TOKEN(context);
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ goto cleanup;
|
||||
}
|
||||
- slotlist = calloc(count, sizeof(CK_SLOT_ID));
|
||||
+ slotlist = k5calloc(count, sizeof(CK_SLOT_ID), &ret);
|
||||
if (slotlist == NULL)
|
||||
- return ENOMEM;
|
||||
- if (cctx->p11->C_GetSlotList(TRUE, slotlist, &count) != CKR_OK) {
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ goto cleanup;
|
||||
+ rv = cctx->p11->C_GetSlotList(TRUE, slotlist, &count);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetSlotList");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3503,19 +3516,17 @@ pkinit_open_session(krb5_context context,
|
||||
continue;
|
||||
|
||||
/* Open session */
|
||||
- pret = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
|
||||
- NULL, NULL, &cctx->session);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_OpenSession: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_OpenSession(slotlist[i], CKF_SERIAL_SESSION,
|
||||
+ NULL, NULL, &cctx->session);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_OpenSession");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get token info */
|
||||
- pret = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_GetTokenInfo: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = cctx->p11->C_GetTokenInfo(slotlist[i], &tinfo);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetTokenInfo");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3577,6 +3588,10 @@ pkinit_open_session(krb5_context context,
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
+ /* On error, finalize the PKCS11 fields to ensure that we don't mistakenly
|
||||
+ * short-circuit with success on the next call. */
|
||||
+ if (ret)
|
||||
+ pkinit_fini_pkcs11(cctx);
|
||||
free(slotlist);
|
||||
free(p11name);
|
||||
return ret;
|
||||
@@ -3598,16 +3613,17 @@ cleanup:
|
||||
* If there are more than one, we just take the first one.
|
||||
*/
|
||||
|
||||
-krb5_error_code
|
||||
-pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
|
||||
+static krb5_error_code
|
||||
+pkinit_find_private_key(krb5_context context,
|
||||
+ pkinit_identity_crypto_context id_cryptoctx,
|
||||
CK_ATTRIBUTE_TYPE usage,
|
||||
CK_OBJECT_HANDLE *objp)
|
||||
{
|
||||
CK_OBJECT_CLASS cls;
|
||||
CK_ATTRIBUTE attrs[4];
|
||||
CK_ULONG count;
|
||||
+ CK_RV rv;
|
||||
unsigned int nattrs = 0;
|
||||
- int r;
|
||||
#ifdef PKINIT_USE_KEY_USAGE
|
||||
CK_BBOOL true_false;
|
||||
#endif
|
||||
@@ -3637,18 +3653,21 @@ pkinit_find_private_key(pkinit_identity_crypto_context id_cryptoctx,
|
||||
attrs[nattrs].ulValueLen = id_cryptoctx->cert_id_len;
|
||||
nattrs++;
|
||||
|
||||
- r = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs, nattrs);
|
||||
- if (r != CKR_OK) {
|
||||
- pkiDebug("krb5_pkinit_sign_data: C_FindObjectsInit: %s\n",
|
||||
- pkcs11err(r));
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
- }
|
||||
+ rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
|
||||
+ nattrs);
|
||||
+ if (rv != CKR_OK)
|
||||
+ return p11err(context, rv, _("C_FindObjectsInit"));
|
||||
|
||||
- r = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1, &count);
|
||||
+ rv = id_cryptoctx->p11->C_FindObjects(id_cryptoctx->session, objp, 1,
|
||||
+ &count);
|
||||
id_cryptoctx->p11->C_FindObjectsFinal(id_cryptoctx->session);
|
||||
- pkiDebug("found %d private keys (%s)\n", (int)count, pkcs11err(r));
|
||||
- if (r != CKR_OK || count < 1)
|
||||
+ if (rv != CKR_OK)
|
||||
+ return p11err(context, rv, _("C_FindObjects"));
|
||||
+ if (count < 1) {
|
||||
+ k5_setmsg(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
+ _("Found no private keys in PKCS11 token"));
|
||||
return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -3796,34 +3815,32 @@ pkinit_sign_data_pkcs11(krb5_context context,
|
||||
CK_FUNCTION_LIST_PTR p11;
|
||||
CK_ATTRIBUTE attr;
|
||||
CK_KEY_TYPE keytype;
|
||||
+ CK_RV rv;
|
||||
EVP_MD_CTX *ctx;
|
||||
const EVP_MD *md = EVP_sha256();
|
||||
unsigned int mdlen;
|
||||
uint8_t mdbuf[EVP_MAX_MD_SIZE], *dinfo = NULL, *sigbuf = NULL, *input;
|
||||
size_t dinfo_len, input_len;
|
||||
- int r;
|
||||
|
||||
*sig = NULL;
|
||||
*sig_len = 0;
|
||||
|
||||
- if (pkinit_open_session(context, id_cryptoctx)) {
|
||||
- pkiDebug("can't open pkcs11 session\n");
|
||||
- return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
- }
|
||||
+ ret = pkinit_open_session(context, id_cryptoctx);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
p11 = id_cryptoctx->p11;
|
||||
session = id_cryptoctx->session;
|
||||
|
||||
- ret = pkinit_find_private_key(id_cryptoctx, CKA_SIGN, &obj);
|
||||
+ ret = pkinit_find_private_key(context, id_cryptoctx, CKA_SIGN, &obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
attr.type = CKA_KEY_TYPE;
|
||||
attr.pValue = &keytype;
|
||||
attr.ulValueLen = sizeof(keytype);
|
||||
- r = p11->C_GetAttributeValue(session, obj, &attr, 1);
|
||||
- if (r) {
|
||||
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(r));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_GetAttributeValue(session, obj, &attr, 1);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetAttributeValue");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3865,10 +3882,9 @@ pkinit_sign_data_pkcs11(krb5_context context,
|
||||
mech.pParameter = NULL;
|
||||
mech.ulParameterLen = 0;
|
||||
|
||||
- r = p11->C_SignInit(session, &mech, obj);
|
||||
- if (r != CKR_OK) {
|
||||
- pkiDebug("C_SignInit: %s\n", pkcs11err(r));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_SignInit(session, &mech, obj);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_SignInit");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3881,18 +3897,17 @@ pkinit_sign_data_pkcs11(krb5_context context,
|
||||
if (sigbuf == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- r = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
- if (r == CKR_BUFFER_TOO_SMALL || (r == CKR_OK && len >= PK_SIGLEN_GUESS)) {
|
||||
+ rv = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
+ if (rv == CKR_BUFFER_TOO_SMALL ||
|
||||
+ (rv == CKR_OK && len >= PK_SIGLEN_GUESS)) {
|
||||
free(sigbuf);
|
||||
- pkiDebug("C_Sign realloc %d\n", (int) len);
|
||||
sigbuf = k5alloc(len, &ret);
|
||||
if (sigbuf == NULL)
|
||||
goto cleanup;
|
||||
- r = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
+ rv = p11->C_Sign(session, input, input_len, sigbuf, &len);
|
||||
}
|
||||
- if (r != CKR_OK) {
|
||||
- pkiDebug("C_Sign: %s\n", pkcs11err(r));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_Sign");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4348,13 +4363,14 @@ reassemble_pkcs11_name(pkinit_identity_opts *idopts)
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
-load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
- pkinit_identity_opts *idopts, pkinit_cred_info *cred_out)
|
||||
+load_one_cert(krb5_context context, CK_FUNCTION_LIST_PTR p11,
|
||||
+ CK_SESSION_HANDLE session, pkinit_identity_opts *idopts,
|
||||
+ pkinit_cred_info *cred_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
CK_ATTRIBUTE attrs[2];
|
||||
CK_BYTE_PTR cert = NULL, cert_id = NULL;
|
||||
- CK_RV pret;
|
||||
+ CK_RV rv;
|
||||
const unsigned char *cp;
|
||||
CK_OBJECT_HANDLE obj;
|
||||
CK_ULONG count;
|
||||
@@ -4364,8 +4380,8 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
*cred_out = NULL;
|
||||
|
||||
/* Look for X.509 cert. */
|
||||
- pret = p11->C_FindObjects(session, &obj, 1, &count);
|
||||
- if (pret != CKR_OK || count <= 0)
|
||||
+ rv = p11->C_FindObjects(session, &obj, 1, &count);
|
||||
+ if (rv != CKR_OK || count <= 0)
|
||||
return 0;
|
||||
|
||||
/* Get cert and id len. */
|
||||
@@ -4375,10 +4391,9 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
attrs[1].type = CKA_ID;
|
||||
attrs[1].pValue = NULL;
|
||||
attrs[1].ulValueLen = 0;
|
||||
- pret = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
- if (pret != CKR_OK && pret != CKR_BUFFER_TOO_SMALL) {
|
||||
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
+ if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL) {
|
||||
+ ret = p11err(context, rv, "C_GetAttributeValue");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4393,10 +4408,9 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
attrs[0].pValue = cert;
|
||||
attrs[1].type = CKA_ID;
|
||||
attrs[1].pValue = cert_id;
|
||||
- pret = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_GetAttributeValue: %s\n", pkcs11err(pret));
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ rv = p11->C_GetAttributeValue(session, obj, attrs, 2);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_GetAttributeValue");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4406,7 +4420,8 @@ load_one_cert(CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE session,
|
||||
cp = (unsigned char *)cert;
|
||||
x = d2i_X509(NULL, &cp, (int)attrs[0].ulValueLen);
|
||||
if (x == NULL) {
|
||||
- ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
+ ret = oerr(context, 0,
|
||||
+ _("Failed to decode X509 certificate from PKCS11 token"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -4444,7 +4459,7 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
||||
int i;
|
||||
unsigned int nattrs;
|
||||
krb5_error_code ret;
|
||||
- CK_RV pret;
|
||||
+ CK_RV rv;
|
||||
|
||||
/* Copy stuff from idopts -> id_cryptoctx */
|
||||
if (idopts->p11_module_name != NULL) {
|
||||
@@ -4516,16 +4531,16 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
||||
nattrs++;
|
||||
}
|
||||
|
||||
- pret = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
|
||||
- nattrs);
|
||||
- if (pret != CKR_OK) {
|
||||
- pkiDebug("C_FindObjectsInit: %s\n", pkcs11err(pret));
|
||||
+ rv = id_cryptoctx->p11->C_FindObjectsInit(id_cryptoctx->session, attrs,
|
||||
+ nattrs);
|
||||
+ if (rv != CKR_OK) {
|
||||
+ ret = p11err(context, rv, "C_FindObjectsInit");
|
||||
return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CREDS_ALLOWED; i++) {
|
||||
- ret = load_one_cert(id_cryptoctx->p11, id_cryptoctx->session, idopts,
|
||||
- &id_cryptoctx->creds[i]);
|
||||
+ ret = load_one_cert(context, id_cryptoctx->p11, id_cryptoctx->session,
|
||||
+ idopts, &id_cryptoctx->creds[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (id_cryptoctx->creds[i] == NULL)
|
||||
@@ -5510,19 +5525,26 @@ print_pubkey(BIGNUM * key, char *msg)
|
||||
}
|
||||
#endif
|
||||
|
||||
-static const char *
|
||||
-pkcs11err(int err)
|
||||
+#ifndef WITHOUT_PKCS11
|
||||
+static krb5_error_code
|
||||
+p11err(krb5_context context, CK_RV rv, const char *op)
|
||||
{
|
||||
+ krb5_error_code code = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
int i;
|
||||
+ const char *msg;
|
||||
|
||||
- for (i = 0; pkcs11_errstrings[i].text != NULL; i++)
|
||||
- if (pkcs11_errstrings[i].code == err)
|
||||
+ for (i = 0; pkcs11_errstrings[i].text != NULL; i++) {
|
||||
+ if (pkcs11_errstrings[i].code == rv)
|
||||
break;
|
||||
- if (pkcs11_errstrings[i].text != NULL)
|
||||
- return (pkcs11_errstrings[i].text);
|
||||
+ }
|
||||
+ msg = pkcs11_errstrings[i].text;
|
||||
+ if (msg == NULL)
|
||||
+ msg = "unknown PKCS11 error";
|
||||
|
||||
- return "unknown PKCS11 error";
|
||||
+ krb5_set_error_message(context, code, _("PKCS11 error (%s): %s"), op, msg);
|
||||
+ return code;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Add an item to the pkinit_identity_crypto_context's list of deferred
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
index 1c1ceb5a41..1faa6816d7 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
@@ -98,21 +98,12 @@
|
||||
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
|
||||
TRACE(c, "PKINIT OpenSSL error: {str}", msg)
|
||||
|
||||
-#define TRACE_PKINIT_PKCS11_GETFLIST_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT PKCS11 C_GetFunctionList failed: {str}", errstr)
|
||||
-#define TRACE_PKINIT_PKCS11_GETSYM_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT unable to find PKCS11 plugin symbol " \
|
||||
- "C_GetFunctionList: {str}", errstr)
|
||||
-#define TRACE_PKINIT_PKCS11_LOGIN_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT PKCS11 C_Login failed: {str}", errstr)
|
||||
#define TRACE_PKINIT_PKCS11_NO_MATCH_TOKEN(c) \
|
||||
TRACE(c, "PKINIT PKCS#11 module has no matching tokens")
|
||||
#define TRACE_PKINIT_PKCS11_NO_TOKEN(c) \
|
||||
TRACE(c, "PKINIT PKCS#11 module shows no slots with tokens")
|
||||
#define TRACE_PKINIT_PKCS11_OPEN(c, name) \
|
||||
TRACE(c, "PKINIT opening PKCS#11 module \"{str}\"", name)
|
||||
-#define TRACE_PKINIT_PKCS11_OPEN_FAILED(c, errstr) \
|
||||
- TRACE(c, "PKINIT PKCS#11 module open failed: {str}", errstr)
|
||||
#define TRACE_PKINIT_PKCS11_SLOT(c, slot, len, label) \
|
||||
TRACE(c, "PKINIT PKCS#11 slotid {int} token {lenstr}", \
|
||||
slot, len, label)
|
||||
--
|
||||
2.47.1
|
||||
|
||||
61
0033-Set-missing-mask-flags-for-kdb5_util-operations.patch
Normal file
61
0033-Set-missing-mask-flags-for-kdb5_util-operations.patch
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
From 946f7dba8cea3d2ed0e68c5e7594cbd7e1364609 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 1 Aug 2024 10:56:07 +0200
|
||||
Subject: [PATCH] Set missing mask flags for kdb5_util operations
|
||||
|
||||
Set KADM5_TL_DATA for the use_mkey and update_princ_encryption
|
||||
commands. (Commit c877f13c8985d820583b0d7ac1bb4c5dc36e677e did this
|
||||
for the add_new_mkey and purge_mkeys commands.) Set appropriate flags
|
||||
for the add_random_key command.
|
||||
|
||||
[ghudson@mit.edu: combined two commits; pruned out proposed mask flag
|
||||
additions for values represented within key data or tl-data (like
|
||||
KADM5_MKVNO), as those flags are currently only used in the kadm5
|
||||
protocol, not to communicate with the KDB module]
|
||||
|
||||
ticket: 9158 (new)
|
||||
(cherry picked from commit 4ed7da378940198cf4415f86d4eb013de6ac6455)
|
||||
---
|
||||
src/kadmin/dbutil/kdb5_mkey.c | 4 +++-
|
||||
src/kadmin/dbutil/kdb5_util.c | 3 +++
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c
|
||||
index aceb0a9b80..ac5c51d05e 100644
|
||||
--- a/src/kadmin/dbutil/kdb5_mkey.c
|
||||
+++ b/src/kadmin/dbutil/kdb5_mkey.c
|
||||
@@ -525,6 +525,8 @@ kdb5_use_mkey(int argc, char *argv[])
|
||||
goto cleanup_return;
|
||||
}
|
||||
|
||||
+ master_entry->mask |= KADM5_TL_DATA;
|
||||
+
|
||||
if ((retval = krb5_db_put_principal(util_context, master_entry))) {
|
||||
com_err(progname, retval,
|
||||
_("while adding master key entry to the database"));
|
||||
@@ -814,7 +816,7 @@ update_princ_encryption_1(void *cb, krb5_db_entry *ent)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- ent->mask |= KADM5_KEY_DATA;
|
||||
+ ent->mask |= KADM5_KEY_DATA | KADM5_TL_DATA;
|
||||
|
||||
if ((retval = krb5_db_put_principal(util_context, ent))) {
|
||||
com_err(progname, retval, _("while updating principal '%s' key data "
|
||||
diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c
|
||||
index 55d529fa4c..afc817891b 100644
|
||||
--- a/src/kadmin/dbutil/kdb5_util.c
|
||||
+++ b/src/kadmin/dbutil/kdb5_util.c
|
||||
@@ -600,6 +600,9 @@ add_random_key(int argc, char **argv)
|
||||
exit_status++;
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ dbent->mask |= KADM5_ATTRIBUTES | KADM5_KEY_DATA | KADM5_TL_DATA;
|
||||
+
|
||||
ret = krb5_db_put_principal(util_context, dbent);
|
||||
krb5_db_free_principal(util_context, dbent);
|
||||
if (ret) {
|
||||
--
|
||||
2.47.1
|
||||
|
||||
64
0034-Prevent-overflow-when-calculating-ulog-block-size.patch
Normal file
64
0034-Prevent-overflow-when-calculating-ulog-block-size.patch
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
From 9b669dd42b28e7900f5ccac2816204e7d04ea23c Mon Sep 17 00:00:00 2001
|
||||
From: Zoltan Borbely <Zoltan.Borbely@morganstanley.com>
|
||||
Date: Tue, 28 Jan 2025 16:39:25 -0500
|
||||
Subject: [PATCH] Prevent overflow when calculating ulog block size
|
||||
|
||||
In kdb_log.c:resize(), log an error and fail if the update size is
|
||||
larger than the largest possible block size (2^16-1).
|
||||
|
||||
CVE-2025-24528:
|
||||
|
||||
In MIT krb5 release 1.7 and later with incremental propagation
|
||||
enabled, an authenticated attacker can cause kadmind to write beyond
|
||||
the end of the mapped region for the iprop log file, likely causing a
|
||||
process crash.
|
||||
|
||||
[ghudson@mit.edu: edited commit message and added CVE description]
|
||||
|
||||
ticket: 9159 (new)
|
||||
tags: pullup
|
||||
target_version: 1.21-next
|
||||
|
||||
(cherry picked from commit 78ceba024b64d49612375be4a12d1c066b0bfbd0)
|
||||
---
|
||||
src/lib/kdb/kdb_log.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
|
||||
index e9b95fce59..c805ebd988 100644
|
||||
--- a/src/lib/kdb/kdb_log.c
|
||||
+++ b/src/lib/kdb/kdb_log.c
|
||||
@@ -183,7 +183,7 @@ extend_file_to(int fd, unsigned int new_size)
|
||||
*/
|
||||
static krb5_error_code
|
||||
resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
|
||||
- unsigned int recsize)
|
||||
+ unsigned int recsize, const kdb_incr_update_t *upd)
|
||||
{
|
||||
unsigned int new_block, new_size;
|
||||
|
||||
@@ -195,6 +195,12 @@ resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
|
||||
new_block *= ULOG_BLOCK;
|
||||
new_size += ulogentries * new_block;
|
||||
|
||||
+ if (new_block > UINT16_MAX) {
|
||||
+ syslog(LOG_ERR, _("ulog overflow caused by principal %.*s"),
|
||||
+ upd->kdb_princ_name.utf8str_t_len,
|
||||
+ upd->kdb_princ_name.utf8str_t_val);
|
||||
+ return KRB5_LOG_ERROR;
|
||||
+ }
|
||||
if (new_size > MAXLOGLEN)
|
||||
return KRB5_LOG_ERROR;
|
||||
|
||||
@@ -291,7 +297,7 @@ store_update(kdb_log_context *log_ctx, kdb_incr_update_t *upd)
|
||||
recsize = sizeof(kdb_ent_header_t) + upd_size;
|
||||
|
||||
if (recsize > ulog->kdb_block) {
|
||||
- retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize);
|
||||
+ retval = resize(ulog, ulogentries, log_ctx->ulogfd, recsize, upd);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
||||
327
0035-Don-t-issue-session-keys-with-deprecated-enctypes.patch
Normal file
327
0035-Don-t-issue-session-keys-with-deprecated-enctypes.patch
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
From c617915958a5cb05463713adcf03b6a0e0512ac3 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 16 Dec 2022 18:31:07 -0500
|
||||
Subject: [PATCH] Don't issue session keys with deprecated enctypes
|
||||
|
||||
A paper by Tom Tervoort noted that rc4-hmac pre-hashes the input for
|
||||
its checksum and GSS operations before applying HMAC, and is therefore
|
||||
potentially vulnerable to hash collision attacks if a protocol
|
||||
contains a restricted signing oracle.
|
||||
|
||||
In light of these potential attacks, begin the functional deprecation
|
||||
of DES3 and RC4 by disallowing their use as session key enctypes by
|
||||
default. Add the variables allow_des3 and allow_rc4 in case
|
||||
negotiability of these enctypes for session keys needs to be turned
|
||||
back on, with the expectation that in future releases the enctypes
|
||||
will be more comprehensively deprecated.
|
||||
|
||||
ticket: 9081
|
||||
(cherry picked from commit 1b57a4d134bbd0e7c52d5885a92eccc815726463)
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 12 ++++++++++++
|
||||
doc/admin/enctypes.rst | 23 +++++++++++++++++++---
|
||||
src/include/k5-int.h | 4 ++++
|
||||
src/kdc/kdc_util.c | 10 ++++++++++
|
||||
src/lib/krb5/krb/get_in_tkt.c | 31 +++++++++++++++++++-----------
|
||||
src/lib/krb5/krb/init_ctx.c | 10 ++++++++++
|
||||
src/tests/gssapi/t_enctypes.py | 5 +++--
|
||||
src/tests/t_etype_info.py | 5 +++--
|
||||
src/tests/t_sesskeynego.py | 28 +++++++++++++++++++++++++--
|
||||
src/util/k5test.py | 9 ++++++++-
|
||||
10 files changed, 116 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index dca52e1426..d51fd3ce7e 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -95,6 +95,18 @@ Additionally, krb5.conf may include any of the relations described in
|
||||
|
||||
The libdefaults section may contain any of the following relations:
|
||||
|
||||
+**allow_des3**
|
||||
+ Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
|
||||
+ In future releases, this flag will allow des3-cbc-sha1 to be used
|
||||
+ at all. The default value for this tag is false. (Added in
|
||||
+ release 1.21.)
|
||||
+
|
||||
+**allow_rc4**
|
||||
+ Permit the KDC to issue tickets with arcfour-hmac session keys.
|
||||
+ In future releases, this flag will allow arcfour-hmac to be used
|
||||
+ at all. The default value for this tag is false. (Added in
|
||||
+ release 1.21.)
|
||||
+
|
||||
**allow_weak_crypto**
|
||||
If this flag is set to false, then weak encryption types (as noted
|
||||
in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered
|
||||
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
|
||||
index c4d5499d3b..2b4ed7da0b 100644
|
||||
--- a/doc/admin/enctypes.rst
|
||||
+++ b/doc/admin/enctypes.rst
|
||||
@@ -48,12 +48,15 @@ Session key selection
|
||||
The KDC chooses the session key enctype by taking the intersection of
|
||||
its **permitted_enctypes** list, the list of long-term keys for the
|
||||
most recent kvno of the service, and the client's requested list of
|
||||
-enctypes.
|
||||
+enctypes. Starting in krb5-1.21, all services are assumed to support
|
||||
+aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
|
||||
+keys will not be issued by default.
|
||||
|
||||
Starting in krb5-1.11, it is possible to set a string attribute on a
|
||||
service principal to control what session key enctypes the KDC may
|
||||
-issue for service tickets for that principal. See :ref:`set_string`
|
||||
-in :ref:`kadmin(1)` for details.
|
||||
+issue for service tickets for that principal, overriding the service's
|
||||
+long-term keys and the assumption of aes256-cts-hmac-sha1-96 support.
|
||||
+See :ref:`set_string` in :ref:`kadmin(1)` for details.
|
||||
|
||||
|
||||
Choosing enctypes for a service
|
||||
@@ -87,6 +90,20 @@ affect how enctypes are chosen.
|
||||
acceptable risk for your environment and the weak enctypes are
|
||||
required for backward compatibility.
|
||||
|
||||
+**allow_des3**
|
||||
+ was added in release 1.21 and defaults to *false*. Unless this
|
||||
+ flag is set to *true*, the KDC will not issue tickets with
|
||||
+ des3-cbc-sha1 session keys. In a future release, this flag will
|
||||
+ control whether des3-cbc-sha1 is permitted in similar fashion to
|
||||
+ weak enctypes.
|
||||
+
|
||||
+**allow_rc4**
|
||||
+ was added in release 1.21 and defaults to *false*. Unless this
|
||||
+ flag is set to *true*, the KDC will not issue tickets with
|
||||
+ arcfour-hmac session keys. In a future release, this flag will
|
||||
+ control whether arcfour-hmac is permitted in similar fashion to
|
||||
+ weak enctypes.
|
||||
+
|
||||
**permitted_enctypes**
|
||||
controls the set of enctypes that a service will permit for
|
||||
session keys and for ticket and authenticator encryption. The KDC
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index b7789a2dd8..d0a263aa7d 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -181,6 +181,8 @@ typedef unsigned char u_char;
|
||||
* matches the variable name. Keep these alphabetized. */
|
||||
#define KRB5_CONF_ACL_FILE "acl_file"
|
||||
#define KRB5_CONF_ADMIN_SERVER "admin_server"
|
||||
+#define KRB5_CONF_ALLOW_DES3 "allow_des3"
|
||||
+#define KRB5_CONF_ALLOW_RC4 "allow_rc4"
|
||||
#define KRB5_CONF_ALLOW_WEAK_CRYPTO "allow_weak_crypto"
|
||||
#define KRB5_CONF_AUTH_TO_LOCAL "auth_to_local"
|
||||
#define KRB5_CONF_AUTH_TO_LOCAL_NAMES "auth_to_local_names"
|
||||
@@ -1241,6 +1243,8 @@ struct _krb5_context {
|
||||
struct _kdb_log_context *kdblog_context;
|
||||
|
||||
krb5_boolean allow_weak_crypto;
|
||||
+ krb5_boolean allow_des3;
|
||||
+ krb5_boolean allow_rc4;
|
||||
krb5_boolean ignore_acceptor_hostname;
|
||||
krb5_boolean enforce_ok_as_delegate;
|
||||
enum dns_canonhost dns_canonicalize_hostname;
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index 93415ba862..c7b6e4090d 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -1108,6 +1108,16 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
|
||||
if (!krb5_is_permitted_enctype(context, ktype[i]))
|
||||
continue;
|
||||
|
||||
+ /*
|
||||
+ * Prevent these deprecated enctypes from being used as session keys
|
||||
+ * unless they are explicitly allowed. In the future they will be more
|
||||
+ * comprehensively disabled and eventually removed.
|
||||
+ */
|
||||
+ if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
|
||||
+ continue;
|
||||
+ if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
|
||||
+ continue;
|
||||
+
|
||||
if (dbentry_supports_enctype(context, server, ktype[i]))
|
||||
return ktype[i];
|
||||
}
|
||||
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
||||
index 1b420a3ac2..ea089f0fcc 100644
|
||||
--- a/src/lib/krb5/krb/get_in_tkt.c
|
||||
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
||||
@@ -1582,22 +1582,31 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||
(*prompter)(context, data, 0, banner, 0, 0);
|
||||
}
|
||||
|
||||
-/* Display a warning via the prompter if des3-cbc-sha1 was used for either the
|
||||
- * reply key or the session key. */
|
||||
+/* Display a warning via the prompter if a deprecated enctype was used for
|
||||
+ * either the reply key or the session key. */
|
||||
static void
|
||||
-warn_des3(krb5_context context, krb5_init_creds_context ctx,
|
||||
- krb5_enctype as_key_enctype)
|
||||
+warn_deprecated(krb5_context context, krb5_init_creds_context ctx,
|
||||
+ krb5_enctype as_key_enctype)
|
||||
{
|
||||
- const char *banner;
|
||||
+ krb5_enctype etype;
|
||||
+ char encbuf[128], banner[256];
|
||||
|
||||
- if (as_key_enctype != ENCTYPE_DES3_CBC_SHA1 &&
|
||||
- ctx->cred.keyblock.enctype != ENCTYPE_DES3_CBC_SHA1)
|
||||
- return;
|
||||
if (ctx->prompter == NULL)
|
||||
return;
|
||||
|
||||
- banner = _("Warning: encryption type des3-cbc-sha1 used for "
|
||||
- "authentication is weak and will be disabled");
|
||||
+ if (krb5int_c_deprecated_enctype(as_key_enctype))
|
||||
+ etype = as_key_enctype;
|
||||
+ else if (krb5int_c_deprecated_enctype(ctx->cred.keyblock.enctype))
|
||||
+ etype = ctx->cred.keyblock.enctype;
|
||||
+ else
|
||||
+ return;
|
||||
+
|
||||
+ if (krb5_enctype_to_name(etype, FALSE, encbuf, sizeof(encbuf)) != 0)
|
||||
+ return;
|
||||
+ snprintf(banner, sizeof(banner),
|
||||
+ _("Warning: encryption type %s used for authentication is "
|
||||
+ "deprecated and will be disabled"), encbuf);
|
||||
+
|
||||
/* PROMPTER_INVOCATION */
|
||||
(*ctx->prompter)(context, ctx->prompter_data, NULL, banner, 0, NULL);
|
||||
}
|
||||
@@ -1848,7 +1857,7 @@ init_creds_step_reply(krb5_context context,
|
||||
ctx->complete = TRUE;
|
||||
warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
|
||||
ctx->in_tkt_service, ctx->reply);
|
||||
- warn_des3(context, ctx, encrypting_key.enctype);
|
||||
+ warn_deprecated(context, ctx, encrypting_key.enctype);
|
||||
|
||||
cleanup:
|
||||
krb5_free_pa_data(context, kdc_padata);
|
||||
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
|
||||
index 582a2945ff..a32f8dbf03 100644
|
||||
--- a/src/lib/krb5/krb/init_ctx.c
|
||||
+++ b/src/lib/krb5/krb/init_ctx.c
|
||||
@@ -220,6 +220,16 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
goto cleanup;
|
||||
ctx->allow_weak_crypto = tmp;
|
||||
|
||||
+ retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+ ctx->allow_des3 = tmp;
|
||||
+
|
||||
+ retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+ ctx->allow_rc4 = tmp;
|
||||
+
|
||||
retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
|
||||
index 2f95d89967..e6bde47afc 100755
|
||||
--- a/src/tests/gssapi/t_enctypes.py
|
||||
+++ b/src/tests/gssapi/t_enctypes.py
|
||||
@@ -10,8 +10,9 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
|
||||
|
||||
# These tests make assumptions about the default enctype lists, so set
|
||||
# them explicitly rather than relying on the library defaults.
|
||||
-supp='aes256-cts:normal aes128-cts:normal rc4-hmac:normal'
|
||||
-conf = {'libdefaults': {'permitted_enctypes': 'aes rc4'},
|
||||
+supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
|
||||
+conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
|
||||
+ 'allow_des3': 'true', 'allow_rc4': 'true'},
|
||||
'realms': {'$realm': {'supported_enctypes': supp}}}
|
||||
realm = K5Realm(krb5_conf=conf)
|
||||
shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
|
||||
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
|
||||
index a6f538b66d..75d9621dd6 100644
|
||||
--- a/src/tests/t_etype_info.py
|
||||
+++ b/src/tests/t_etype_info.py
|
||||
@@ -1,7 +1,8 @@
|
||||
from k5test import *
|
||||
|
||||
-supported_enctypes = 'aes128-cts rc4-hmac'
|
||||
-conf = {'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
|
||||
+supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
|
||||
+conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
|
||||
+ 'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
|
||||
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
|
||||
|
||||
realm.run([kadminl, 'addprinc', '-pw', 'pw', '+requires_preauth',
|
||||
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
|
||||
index 9024aee838..5a213617b5 100755
|
||||
--- a/src/tests/t_sesskeynego.py
|
||||
+++ b/src/tests/t_sesskeynego.py
|
||||
@@ -25,6 +25,8 @@ conf3 = {'libdefaults': {
|
||||
'default_tkt_enctypes': 'aes128-cts',
|
||||
'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
|
||||
conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
|
||||
+conf5 = {'libdefaults': {'allow_rc4': 'true'}}
|
||||
+conf6 = {'libdefaults': {'allow_des3': 'true'}}
|
||||
# Test with client request and session_enctypes preferring aes128, but
|
||||
# aes256 long-term key.
|
||||
realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
|
||||
@@ -54,10 +56,12 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
|
||||
'aes128-cts,aes256-cts'])
|
||||
test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
|
||||
|
||||
-# 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
|
||||
+# 3b: Skip RC4 (as the KDC does not allow it for session keys by
|
||||
+# default) and negotiate aes128-cts session key, with only an aes256
|
||||
+# long-term service key.
|
||||
realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
|
||||
'rc4-hmac,aes128-cts,aes256-cts'])
|
||||
-test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
|
||||
+test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
|
||||
realm.stop()
|
||||
|
||||
# 4: Check that permitted_enctypes is a default for session key enctypes.
|
||||
@@ -67,4 +71,24 @@ realm.run([kvno, 'user'],
|
||||
expected_trace=('etypes requested in TGS request: aes256-cts',))
|
||||
realm.stop()
|
||||
|
||||
+# 5: allow_rc4 permits negotiation of rc4-hmac session key.
|
||||
+realm = K5Realm(krb5_conf=conf5, create_host=False, get_creds=False)
|
||||
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
|
||||
+realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
|
||||
+test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
|
||||
+realm.stop()
|
||||
+
|
||||
+# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
|
||||
+realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
|
||||
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
|
||||
+realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
|
||||
+test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
|
||||
+realm.stop()
|
||||
+
|
||||
+# 7: default config negotiates aes256-sha1 session key for RC4-only service.
|
||||
+realm = K5Realm(create_host=False, get_creds=False)
|
||||
+realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
|
||||
+test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'DEPRECATED:arcfour-hmac')
|
||||
+realm.stop()
|
||||
+
|
||||
success('sesskeynego')
|
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
||||
index d823653aa0..8e5f5ba8e9 100644
|
||||
--- a/src/util/k5test.py
|
||||
+++ b/src/util/k5test.py
|
||||
@@ -1338,9 +1338,16 @@ _passes = [
|
||||
# No special settings; exercises AES256.
|
||||
('default', None, None, None),
|
||||
|
||||
+ # Exercise the DES3 enctype.
|
||||
+ ('des3', None,
|
||||
+ {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
|
||||
+ {'realms': {'$realm': {
|
||||
+ 'supported_enctypes': 'des3-cbc-sha1:normal',
|
||||
+ 'master_key_type': 'des3-cbc-sha1'}}}),
|
||||
+
|
||||
# Exercise the arcfour enctype.
|
||||
('arcfour', None,
|
||||
- {'libdefaults': {'permitted_enctypes': 'rc4'}},
|
||||
+ {'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
|
||||
{'realms': {'$realm': {
|
||||
'supported_enctypes': 'arcfour-hmac:normal',
|
||||
'master_key_type': 'arcfour-hmac'}}}),
|
||||
--
|
||||
2.49.0
|
||||
|
||||
260
0036-downstream-Remove-3des-support-cumulative-1.patch
Normal file
260
0036-downstream-Remove-3des-support-cumulative-1.patch
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
From b0993b57dbe584f9308cc7773b930efe76e19ba3 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 4 Apr 2025 15:08:36 +0200
|
||||
Subject: [PATCH] [downstream] Remove 3des support (cumulative 1)
|
||||
|
||||
Remove mentions for the triple-DES encryption type which were added
|
||||
since the previous downstream patch.
|
||||
---
|
||||
README | 15 +++++++--------
|
||||
doc/admin/conf_files/krb5_conf.rst | 6 ------
|
||||
doc/admin/enctypes.rst | 11 ++---------
|
||||
doc/mitK5features.rst | 5 ++---
|
||||
src/include/k5-int.h | 2 --
|
||||
src/kdc/kdc_util.c | 2 --
|
||||
src/lib/krb5/krb/init_ctx.c | 5 -----
|
||||
src/man/krb5.conf.man | 6 ------
|
||||
src/tests/gssapi/t_enctypes.py | 5 ++---
|
||||
src/tests/t_etype_info.py | 4 ++--
|
||||
src/tests/t_sesskeynego.py | 8 --------
|
||||
src/util/k5test.py | 7 -------
|
||||
12 files changed, 15 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/README b/README
|
||||
index 6d6f7f16e3..9341bd3dd8 100644
|
||||
--- a/README
|
||||
+++ b/README
|
||||
@@ -81,11 +81,11 @@ Triple-DES and RC4 transitions
|
||||
------------------------------
|
||||
|
||||
Beginning with the krb5-1.21 release, the KDC will not issue tickets
|
||||
-with triple-DES or RC4 session keys unless explicitly configured using
|
||||
-the new allow_des3 and allow_rc4 variables in [libdefaults]. To
|
||||
-facilitate the negotiation of session keys, the KDC will assume that
|
||||
-all services can handle aes256-sha1 session keys unless the service
|
||||
-principal has a session_enctypes string attribute.
|
||||
+with RC4 session keys unless explicitly configured using the new
|
||||
+allow_rc4 variable in [libdefaults]. To facilitate the negotiation of
|
||||
+session keys, the KDC will assume that all services can handle
|
||||
+aes256-sha1 session keys unless the service principal has a
|
||||
+session_enctypes string attribute.
|
||||
|
||||
Beginning with the krb5-1.19 release, a warning will be issued if
|
||||
initial credentials are acquired using the des3-cbc-sha1 encryption
|
||||
@@ -164,9 +164,8 @@ Developer experience:
|
||||
|
||||
Protocol evolution:
|
||||
|
||||
-* The KDC will no longer issue tickets with RC4 or triple-DES session
|
||||
- keys unless explicitly configured with the new allow_rc4 or
|
||||
- allow_des3 variables respectively.
|
||||
+* The KDC will no longer issue tickets with RC4 session keys unless
|
||||
+ explicitly configured with the new allow_rc4 variable.
|
||||
|
||||
* The KDC will assume that all services can handle aes256-sha1 session
|
||||
keys unless the service principal has a session_enctypes string
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index d51fd3ce7e..d20dcf18e3 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -95,12 +95,6 @@ Additionally, krb5.conf may include any of the relations described in
|
||||
|
||||
The libdefaults section may contain any of the following relations:
|
||||
|
||||
-**allow_des3**
|
||||
- Permit the KDC to issue tickets with des3-cbc-sha1 session keys.
|
||||
- In future releases, this flag will allow des3-cbc-sha1 to be used
|
||||
- at all. The default value for this tag is false. (Added in
|
||||
- release 1.21.)
|
||||
-
|
||||
**allow_rc4**
|
||||
Permit the KDC to issue tickets with arcfour-hmac session keys.
|
||||
In future releases, this flag will allow arcfour-hmac to be used
|
||||
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
|
||||
index 2b4ed7da0b..6ce4638d5e 100644
|
||||
--- a/doc/admin/enctypes.rst
|
||||
+++ b/doc/admin/enctypes.rst
|
||||
@@ -49,8 +49,8 @@ The KDC chooses the session key enctype by taking the intersection of
|
||||
its **permitted_enctypes** list, the list of long-term keys for the
|
||||
most recent kvno of the service, and the client's requested list of
|
||||
enctypes. Starting in krb5-1.21, all services are assumed to support
|
||||
-aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session
|
||||
-keys will not be issued by default.
|
||||
+aes256-cts-hmac-sha1-96; also, arcfour-hmac session keys will not be
|
||||
+issued by default.
|
||||
|
||||
Starting in krb5-1.11, it is possible to set a string attribute on a
|
||||
service principal to control what session key enctypes the KDC may
|
||||
@@ -90,13 +90,6 @@ affect how enctypes are chosen.
|
||||
acceptable risk for your environment and the weak enctypes are
|
||||
required for backward compatibility.
|
||||
|
||||
-**allow_des3**
|
||||
- was added in release 1.21 and defaults to *false*. Unless this
|
||||
- flag is set to *true*, the KDC will not issue tickets with
|
||||
- des3-cbc-sha1 session keys. In a future release, this flag will
|
||||
- control whether des3-cbc-sha1 is permitted in similar fashion to
|
||||
- weak enctypes.
|
||||
-
|
||||
**allow_rc4**
|
||||
was added in release 1.21 and defaults to *false*. Unless this
|
||||
flag is set to *true*, the KDC will not issue tickets with
|
||||
diff --git a/doc/mitK5features.rst b/doc/mitK5features.rst
|
||||
index cad0855724..64d746b0af 100644
|
||||
--- a/doc/mitK5features.rst
|
||||
+++ b/doc/mitK5features.rst
|
||||
@@ -659,9 +659,8 @@ Release 1.21
|
||||
|
||||
* Protocol evolution:
|
||||
|
||||
- - The KDC will no longer issue tickets with RC4 or triple-DES
|
||||
- session keys unless explicitly configured with the new allow_rc4
|
||||
- or allow_des3 variables respectively.
|
||||
+ - The KDC will no longer issue tickets with RC4 session keys unless
|
||||
+ explicitly configured with the new allow_rc4 variable.
|
||||
|
||||
- The KDC will assume that all services can handle aes256-sha1
|
||||
session keys unless the service principal has a session_enctypes
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index d0a263aa7d..82a763298d 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -181,7 +181,6 @@ typedef unsigned char u_char;
|
||||
* matches the variable name. Keep these alphabetized. */
|
||||
#define KRB5_CONF_ACL_FILE "acl_file"
|
||||
#define KRB5_CONF_ADMIN_SERVER "admin_server"
|
||||
-#define KRB5_CONF_ALLOW_DES3 "allow_des3"
|
||||
#define KRB5_CONF_ALLOW_RC4 "allow_rc4"
|
||||
#define KRB5_CONF_ALLOW_WEAK_CRYPTO "allow_weak_crypto"
|
||||
#define KRB5_CONF_AUTH_TO_LOCAL "auth_to_local"
|
||||
@@ -1243,7 +1242,6 @@ struct _krb5_context {
|
||||
struct _kdb_log_context *kdblog_context;
|
||||
|
||||
krb5_boolean allow_weak_crypto;
|
||||
- krb5_boolean allow_des3;
|
||||
krb5_boolean allow_rc4;
|
||||
krb5_boolean ignore_acceptor_hostname;
|
||||
krb5_boolean enforce_ok_as_delegate;
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index c7b6e4090d..bafcf5f728 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -1113,8 +1113,6 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
|
||||
* unless they are explicitly allowed. In the future they will be more
|
||||
* comprehensively disabled and eventually removed.
|
||||
*/
|
||||
- if (ktype[i] == ENCTYPE_DES3_CBC_SHA1 && !context->allow_des3)
|
||||
- continue;
|
||||
if (ktype[i] == ENCTYPE_ARCFOUR_HMAC && !context->allow_rc4)
|
||||
continue;
|
||||
|
||||
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
|
||||
index a32f8dbf03..82aba64c5e 100644
|
||||
--- a/src/lib/krb5/krb/init_ctx.c
|
||||
+++ b/src/lib/krb5/krb/init_ctx.c
|
||||
@@ -220,11 +220,6 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
goto cleanup;
|
||||
ctx->allow_weak_crypto = tmp;
|
||||
|
||||
- retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp);
|
||||
- if (retval)
|
||||
- goto cleanup;
|
||||
- ctx->allow_des3 = tmp;
|
||||
-
|
||||
retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
|
||||
index 6c0e9aff8c..4b53988712 100644
|
||||
--- a/src/man/krb5.conf.man
|
||||
+++ b/src/man/krb5.conf.man
|
||||
@@ -178,12 +178,6 @@ kdc.conf(5), but it is not a recommended practice.
|
||||
The libdefaults section may contain any of the following relations:
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
-\fBallow_des3\fP
|
||||
-Permit the KDC to issue tickets with des3\-cbc\-sha1 session keys.
|
||||
-In future releases, this flag will allow des3\-cbc\-sha1 to be used
|
||||
-at all. The default value for this tag is false. (Added in
|
||||
-release 1.21.)
|
||||
-.TP
|
||||
\fBallow_rc4\fP
|
||||
Permit the KDC to issue tickets with arcfour\-hmac session keys.
|
||||
In future releases, this flag will allow arcfour\-hmac to be used
|
||||
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
|
||||
index e6bde47afc..1bb8c40b6b 100755
|
||||
--- a/src/tests/gssapi/t_enctypes.py
|
||||
+++ b/src/tests/gssapi/t_enctypes.py
|
||||
@@ -10,9 +10,8 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
|
||||
|
||||
# These tests make assumptions about the default enctype lists, so set
|
||||
# them explicitly rather than relying on the library defaults.
|
||||
-supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
|
||||
-conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4',
|
||||
- 'allow_des3': 'true', 'allow_rc4': 'true'},
|
||||
+supp='aes256-cts:normal aes128-cts:normal rc4-hmac:normal'
|
||||
+conf = {'libdefaults': {'permitted_enctypes': 'aes rc4', 'allow_rc4': 'true'},
|
||||
'realms': {'$realm': {'supported_enctypes': supp}}}
|
||||
realm = K5Realm(krb5_conf=conf)
|
||||
shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
|
||||
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
|
||||
index 75d9621dd6..e82ff7ff07 100644
|
||||
--- a/src/tests/t_etype_info.py
|
||||
+++ b/src/tests/t_etype_info.py
|
||||
@@ -1,7 +1,7 @@
|
||||
from k5test import *
|
||||
|
||||
-supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac'
|
||||
-conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'},
|
||||
+supported_enctypes = 'aes128-cts rc4-hmac'
|
||||
+conf = {'libdefaults': {'allow_rc4': 'true'},
|
||||
'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
|
||||
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
|
||||
|
||||
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
|
||||
index 5a213617b5..c7dba0ff5b 100755
|
||||
--- a/src/tests/t_sesskeynego.py
|
||||
+++ b/src/tests/t_sesskeynego.py
|
||||
@@ -26,7 +26,6 @@ conf3 = {'libdefaults': {
|
||||
'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
|
||||
conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
|
||||
conf5 = {'libdefaults': {'allow_rc4': 'true'}}
|
||||
-conf6 = {'libdefaults': {'allow_des3': 'true'}}
|
||||
# Test with client request and session_enctypes preferring aes128, but
|
||||
# aes256 long-term key.
|
||||
realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
|
||||
@@ -78,13 +77,6 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac'])
|
||||
test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
|
||||
realm.stop()
|
||||
|
||||
-# 6: allow_des3 permits negotiation of des3-cbc-sha1 session key.
|
||||
-realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False)
|
||||
-realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server'])
|
||||
-realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1'])
|
||||
-test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96')
|
||||
-realm.stop()
|
||||
-
|
||||
# 7: default config negotiates aes256-sha1 session key for RC4-only service.
|
||||
realm = K5Realm(create_host=False, get_creds=False)
|
||||
realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server'])
|
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
||||
index 8e5f5ba8e9..b953827018 100644
|
||||
--- a/src/util/k5test.py
|
||||
+++ b/src/util/k5test.py
|
||||
@@ -1338,13 +1338,6 @@ _passes = [
|
||||
# No special settings; exercises AES256.
|
||||
('default', None, None, None),
|
||||
|
||||
- # Exercise the DES3 enctype.
|
||||
- ('des3', None,
|
||||
- {'libdefaults': {'permitted_enctypes': 'des3 aes256-sha1'}},
|
||||
- {'realms': {'$realm': {
|
||||
- 'supported_enctypes': 'des3-cbc-sha1:normal',
|
||||
- 'master_key_type': 'des3-cbc-sha1'}}}),
|
||||
-
|
||||
# Exercise the arcfour enctype.
|
||||
('arcfour', None,
|
||||
{'libdefaults': {'permitted_enctypes': 'rc4 aes256-sha1'}},
|
||||
--
|
||||
2.49.0
|
||||
|
||||
692
0037-Add-PKINIT-paChecksum2-from-MS-PKCA-v20230920.patch
Normal file
692
0037-Add-PKINIT-paChecksum2-from-MS-PKCA-v20230920.patch
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
From 9d03713af124c2096d071ba36893018da8d71655 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Tue, 14 Jan 2025 13:31:11 +0100
|
||||
Subject: [PATCH] Add PKINIT paChecksum2 from MS-PKCA v20230920
|
||||
|
||||
In 2023, Microsoft updated MS-PKCA to add the optional paChecksum2
|
||||
element in the PKAuthenticator sequence. This checksum accepts SHA-1,
|
||||
SHA-256, SHA-384, and SHA-512 digests.
|
||||
|
||||
In Windows Server 2025, this checksum becomes mandatory when using
|
||||
PKINIT with FFDH (but strangely not with ECDH if SHA-1 is configured as
|
||||
allowed).
|
||||
|
||||
[ghudson@mit.edu: refactored crypto interfaces to reduce complexity of
|
||||
calling code]
|
||||
|
||||
ticket: 9166 (new)
|
||||
(cherry picked from commit 310793ba63782af5ffa3a95d20e41f8f03ca7e00)
|
||||
---
|
||||
src/include/k5-int-pkinit.h | 25 ++--
|
||||
src/lib/krb5/asn.1/asn1_k_encode.c | 18 ++-
|
||||
src/plugins/preauth/pkinit/pkinit.h | 1 +
|
||||
src/plugins/preauth/pkinit/pkinit_clnt.c | 41 +++----
|
||||
src/plugins/preauth/pkinit/pkinit_constants.c | 42 +++++--
|
||||
src/plugins/preauth/pkinit/pkinit_crypto.h | 24 +++-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 116 +++++++++++++++++-
|
||||
src/plugins/preauth/pkinit/pkinit_kdf_test.c | 4 +-
|
||||
src/plugins/preauth/pkinit/pkinit_lib.c | 16 ++-
|
||||
src/plugins/preauth/pkinit/pkinit_srv.c | 38 ++----
|
||||
src/plugins/preauth/pkinit/pkinit_trace.h | 5 +-
|
||||
src/tests/asn.1/krb5_decode_test.c | 2 +-
|
||||
src/tests/asn.1/ktest.c | 7 +-
|
||||
src/tests/asn.1/ktest_equal.c | 2 +-
|
||||
src/tests/asn.1/pkinit_encode.out | 2 +-
|
||||
src/tests/asn.1/pkinit_trval.out | 2 +-
|
||||
16 files changed, 250 insertions(+), 95 deletions(-)
|
||||
|
||||
diff --git a/src/include/k5-int-pkinit.h b/src/include/k5-int-pkinit.h
|
||||
index 915904e518..cf6b1f99c5 100644
|
||||
--- a/src/include/k5-int-pkinit.h
|
||||
+++ b/src/include/k5-int-pkinit.h
|
||||
@@ -36,21 +36,28 @@
|
||||
* pkinit structures
|
||||
*/
|
||||
|
||||
-/* PKAuthenticator */
|
||||
-typedef struct _krb5_pk_authenticator {
|
||||
- krb5_int32 cusec; /* (0..999999) */
|
||||
- krb5_timestamp ctime;
|
||||
- krb5_int32 nonce; /* (0..4294967295) */
|
||||
- krb5_checksum paChecksum;
|
||||
- krb5_data *freshnessToken;
|
||||
-} krb5_pk_authenticator;
|
||||
-
|
||||
/* AlgorithmIdentifier */
|
||||
typedef struct _krb5_algorithm_identifier {
|
||||
krb5_data algorithm; /* OID */
|
||||
krb5_data parameters; /* Optional */
|
||||
} krb5_algorithm_identifier;
|
||||
|
||||
+/* PAChecksum2 */
|
||||
+typedef struct _krb5_pachecksum2 {
|
||||
+ krb5_data checksum;
|
||||
+ krb5_algorithm_identifier algorithmIdentifier;
|
||||
+} krb5_pachecksum2;
|
||||
+
|
||||
+/* PKAuthenticator */
|
||||
+typedef struct _krb5_pk_authenticator {
|
||||
+ krb5_int32 cusec; /* (0..999999) */
|
||||
+ krb5_timestamp ctime;
|
||||
+ krb5_int32 nonce; /* (0..4294967295) */
|
||||
+ krb5_data paChecksum;
|
||||
+ krb5_data *freshnessToken; /* Optional */
|
||||
+ krb5_pachecksum2 *paChecksum2; /* Optional */
|
||||
+} krb5_pk_authenticator;
|
||||
+
|
||||
/** AuthPack from RFC 4556*/
|
||||
typedef struct _krb5_auth_pack {
|
||||
krb5_pk_authenticator pkAuthenticator;
|
||||
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
|
||||
index 5378b5c23b..cf7b500837 100644
|
||||
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
|
||||
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
|
||||
@@ -1394,20 +1394,30 @@ DEFSEQTYPE(pkinit_supp_pub_info, krb5_pkinit_supp_pub_info,
|
||||
MAKE_ENCODER(encode_krb5_pkinit_supp_pub_info, pkinit_supp_pub_info);
|
||||
MAKE_ENCODER(encode_krb5_sp80056a_other_info, sp80056a_other_info);
|
||||
|
||||
-/* A krb5_checksum encoded as an OCTET STRING, for PKAuthenticator. */
|
||||
-DEFCOUNTEDTYPE(ostring_checksum, krb5_checksum, contents, length, octetstring);
|
||||
+DEFFIELD(pachecksum2_0, krb5_pachecksum2, checksum, 0, ostring_data);
|
||||
+DEFFIELD(pachecksum2_1, krb5_pachecksum2, algorithmIdentifier, 1,
|
||||
+ algorithm_identifier);
|
||||
+static const struct atype_info *pachecksum2_fields[] = {
|
||||
+ &k5_atype_pachecksum2_0, &k5_atype_pachecksum2_1
|
||||
+};
|
||||
+DEFSEQTYPE(pachecksum2, krb5_pachecksum2, pachecksum2_fields);
|
||||
+
|
||||
+DEFPTRTYPE(pachecksum2_ptr, pachecksum2);
|
||||
+DEFOPTIONALZEROTYPE(opt_pachecksum2_ptr, pachecksum2_ptr);
|
||||
|
||||
DEFFIELD(pk_authenticator_0, krb5_pk_authenticator, cusec, 0, int32);
|
||||
DEFFIELD(pk_authenticator_1, krb5_pk_authenticator, ctime, 1, kerberos_time);
|
||||
DEFFIELD(pk_authenticator_2, krb5_pk_authenticator, nonce, 2, int32);
|
||||
DEFFIELD(pk_authenticator_3, krb5_pk_authenticator, paChecksum, 3,
|
||||
- ostring_checksum);
|
||||
+ ostring_data);
|
||||
DEFFIELD(pk_authenticator_4, krb5_pk_authenticator, freshnessToken, 4,
|
||||
opt_ostring_data_ptr);
|
||||
+DEFFIELD(pk_authenticator_5, krb5_pk_authenticator, paChecksum2, 5,
|
||||
+ opt_pachecksum2_ptr);
|
||||
static const struct atype_info *pk_authenticator_fields[] = {
|
||||
&k5_atype_pk_authenticator_0, &k5_atype_pk_authenticator_1,
|
||||
&k5_atype_pk_authenticator_2, &k5_atype_pk_authenticator_3,
|
||||
- &k5_atype_pk_authenticator_4
|
||||
+ &k5_atype_pk_authenticator_4, &k5_atype_pk_authenticator_5
|
||||
};
|
||||
DEFSEQTYPE(pk_authenticator, krb5_pk_authenticator, pk_authenticator_fields);
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
|
||||
index 7ba7155bb4..a1564b6df2 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit.h
|
||||
@@ -338,6 +338,7 @@ void free_krb5_external_principal_identifier(krb5_external_principal_identifier
|
||||
void free_krb5_algorithm_identifiers(krb5_algorithm_identifier ***in);
|
||||
void free_krb5_algorithm_identifier(krb5_algorithm_identifier *in);
|
||||
void free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in);
|
||||
+void free_pachecksum2(krb5_context context, krb5_pachecksum2 **in);
|
||||
krb5_error_code pkinit_copy_krb5_data(krb5_data *dst, const krb5_data *src);
|
||||
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
index b08022a214..433f477538 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
@@ -56,10 +56,9 @@ use_content_info(krb5_context context, pkinit_req_context req,
|
||||
static krb5_error_code
|
||||
pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
|
||||
pkinit_req_context reqctx, krb5_timestamp ctsec,
|
||||
- krb5_int32 cusec, krb5_ui_4 nonce,
|
||||
- const krb5_checksum *cksum,
|
||||
- krb5_principal client, krb5_principal server,
|
||||
- krb5_data **as_req);
|
||||
+ krb5_int32 cusec, krb5_ui_4 nonce, const krb5_data *cksum,
|
||||
+ const krb5_pachecksum2 *cksum2, krb5_principal client,
|
||||
+ krb5_principal server, krb5_data **as_req);
|
||||
|
||||
static krb5_error_code
|
||||
pkinit_as_rep_parse(krb5_context context, pkinit_context plgctx,
|
||||
@@ -89,7 +88,8 @@ pa_pkinit_gen_req(krb5_context context,
|
||||
krb5_timestamp ctsec = 0;
|
||||
krb5_int32 cusec = 0;
|
||||
krb5_ui_4 nonce = 0;
|
||||
- krb5_checksum cksum;
|
||||
+ krb5_data cksum = empty_data();
|
||||
+ krb5_pachecksum2 *cksum2 = NULL;
|
||||
krb5_data *der_req = NULL;
|
||||
krb5_pa_data **return_pa_data = NULL;
|
||||
|
||||
@@ -118,15 +118,10 @@ pa_pkinit_gen_req(krb5_context context,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- retval = krb5_c_make_checksum(context, CKSUMTYPE_SHA1, NULL, 0, der_req,
|
||||
- &cksum);
|
||||
+ retval = crypto_generate_checksums(context, der_req, &cksum, &cksum2);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
- TRACE_PKINIT_CLIENT_REQ_CHECKSUM(context, &cksum);
|
||||
-#ifdef DEBUG_CKSUM
|
||||
- pkiDebug("calculating checksum on buf size (%d)\n", der_req->length);
|
||||
- print_buffer(der_req->data, der_req->length);
|
||||
-#endif
|
||||
+ TRACE_PKINIT_CLIENT_REQ_CHECKSUMS(context, &cksum, cksum2);
|
||||
|
||||
retval = cb->get_preauth_time(context, rock, TRUE, &ctsec, &cusec);
|
||||
if (retval)
|
||||
@@ -140,7 +135,8 @@ pa_pkinit_gen_req(krb5_context context,
|
||||
nonce = request->nonce;
|
||||
|
||||
retval = pkinit_as_req_create(context, plgctx, reqctx, ctsec, cusec,
|
||||
- nonce, &cksum, request->client, request->server, &out_data);
|
||||
+ nonce, &cksum, cksum2, request->client,
|
||||
+ request->server, &out_data);
|
||||
if (retval) {
|
||||
pkiDebug("error %d on pkinit_as_req_create; aborting PKINIT\n",
|
||||
(int) retval);
|
||||
@@ -168,23 +164,19 @@ pa_pkinit_gen_req(krb5_context context,
|
||||
|
||||
cleanup:
|
||||
krb5_free_data(context, der_req);
|
||||
- krb5_free_checksum_contents(context, &cksum);
|
||||
+ krb5_free_data_contents(context, &cksum);
|
||||
+ free_pachecksum2(context, &cksum2);
|
||||
krb5_free_data(context, out_data);
|
||||
krb5_free_pa_data(context, return_pa_data);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
-pkinit_as_req_create(krb5_context context,
|
||||
- pkinit_context plgctx,
|
||||
- pkinit_req_context reqctx,
|
||||
- krb5_timestamp ctsec,
|
||||
- krb5_int32 cusec,
|
||||
- krb5_ui_4 nonce,
|
||||
- const krb5_checksum * cksum,
|
||||
- krb5_principal client,
|
||||
- krb5_principal server,
|
||||
- krb5_data ** as_req)
|
||||
+pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
|
||||
+ pkinit_req_context reqctx, krb5_timestamp ctsec,
|
||||
+ krb5_int32 cusec, krb5_ui_4 nonce, const krb5_data *cksum,
|
||||
+ const krb5_pachecksum2 *cksum2, krb5_principal client,
|
||||
+ krb5_principal server, krb5_data **as_req)
|
||||
{
|
||||
krb5_error_code retval = ENOMEM;
|
||||
krb5_data spki = empty_data(), *coded_auth_pack = NULL;
|
||||
@@ -202,6 +194,7 @@ pkinit_as_req_create(krb5_context context,
|
||||
auth_pack.pkAuthenticator.paChecksum = *cksum;
|
||||
if (!reqctx->opts->disable_freshness)
|
||||
auth_pack.pkAuthenticator.freshnessToken = reqctx->freshness_token;
|
||||
+ auth_pack.pkAuthenticator.paChecksum2 = (krb5_pachecksum2 *)cksum2;
|
||||
auth_pack.clientDHNonce.length = 0;
|
||||
auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids;
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
index 905e90d29c..a32b373c32 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
@@ -34,25 +34,49 @@
|
||||
|
||||
/* RFC 8636 id-pkinit-kdf-ah-sha1: iso(1) identified-organization(3) dod(6)
|
||||
* internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha1(1) */
|
||||
-static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
|
||||
+static char kdf_sha1[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
|
||||
/* RFC 8636 id-pkinit-kdf-ah-sha256: iso(1) identified-organization(3) dod(6)
|
||||
* internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha256(2) */
|
||||
-static char sha256_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
|
||||
+static char kdf_sha256[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
|
||||
/* RFC 8636 id-pkinit-kdf-ah-sha512: iso(1) identified-organization(3) dod(6)
|
||||
* internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha512(3) */
|
||||
-static char sha512_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
|
||||
+static char kdf_sha512[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
|
||||
|
||||
-const krb5_data sha1_id = { KV5M_DATA, sizeof(sha1_oid), sha1_oid };
|
||||
-const krb5_data sha256_id = { KV5M_DATA, sizeof(sha256_oid), sha256_oid };
|
||||
-const krb5_data sha512_id = { KV5M_DATA, sizeof(sha512_oid), sha512_oid };
|
||||
+const krb5_data kdf_sha1_id = { KV5M_DATA, sizeof(kdf_sha1), kdf_sha1 };
|
||||
+const krb5_data kdf_sha256_id = { KV5M_DATA, sizeof(kdf_sha256), kdf_sha256 };
|
||||
+const krb5_data kdf_sha512_id = { KV5M_DATA, sizeof(kdf_sha512), kdf_sha512 };
|
||||
|
||||
krb5_data const * const supported_kdf_alg_ids[] = {
|
||||
- &sha256_id,
|
||||
- &sha1_id,
|
||||
- &sha512_id,
|
||||
+ &kdf_sha256_id,
|
||||
+ &kdf_sha1_id,
|
||||
+ &kdf_sha512_id,
|
||||
NULL
|
||||
};
|
||||
|
||||
+/* RFC 3370 sha-1: iso(1) identified-organization(3) oiw(14) secsig(3)
|
||||
+ * algorithm(2) 26 */
|
||||
+static char cms_sha1[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a };
|
||||
+/* RFC 5754 id-sha256: joint-iso-itu-t(2) country(16) us(840) organization(1)
|
||||
+ * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 */
|
||||
+static char cms_sha256[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
|
||||
+};
|
||||
+/* RFC 5754 id-sha384: joint-iso-itu-t(2) country(16) us(840) organization(1)
|
||||
+ * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 */
|
||||
+static char cms_sha384[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
|
||||
+};
|
||||
+/* RFC 5754 id-sha512: joint-iso-itu-t(2) country(16) us(840) organization(1)
|
||||
+ * gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 */
|
||||
+static char cms_sha512[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
|
||||
+};
|
||||
+
|
||||
+const krb5_data cms_sha1_id = { KV5M_DATA, sizeof(cms_sha1), cms_sha1 };
|
||||
+const krb5_data cms_sha256_id = { KV5M_DATA, sizeof(cms_sha256), cms_sha256 };
|
||||
+const krb5_data cms_sha384_id = { KV5M_DATA, sizeof(cms_sha384), cms_sha384 };
|
||||
+const krb5_data cms_sha512_id = { KV5M_DATA, sizeof(cms_sha512), cms_sha512 };
|
||||
+
|
||||
/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
||||
* rsadsi(113549) pkcs(1) 1 11 */
|
||||
static char sha256WithRSAEncr_oid[9] = {
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
index fd876e4850..3b12e904b1 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
@@ -562,9 +562,13 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
krb5_data *pk_as_rep,
|
||||
krb5_keyblock *key_block);
|
||||
|
||||
-extern const krb5_data sha1_id;
|
||||
-extern const krb5_data sha256_id;
|
||||
-extern const krb5_data sha512_id;
|
||||
+extern const krb5_data kdf_sha1_id;
|
||||
+extern const krb5_data kdf_sha256_id;
|
||||
+extern const krb5_data kdf_sha512_id;
|
||||
+extern const krb5_data cms_sha1_id;
|
||||
+extern const krb5_data cms_sha256_id;
|
||||
+extern const krb5_data cms_sha384_id;
|
||||
+extern const krb5_data cms_sha512_id;
|
||||
extern const krb5_data oakley_1024;
|
||||
extern const krb5_data oakley_2048;
|
||||
extern const krb5_data oakley_4096;
|
||||
@@ -597,4 +601,18 @@ crypto_req_cert_matching_data(krb5_context context,
|
||||
|
||||
int parse_dh_min_bits(krb5_context context, const char *str);
|
||||
|
||||
+/* Generate a SHA-1 checksum over body in *cksum1_out and a SHA-256 checksum
|
||||
+ * over body in *cksum2_out with appropriate metadata. */
|
||||
+krb5_error_code
|
||||
+crypto_generate_checksums(krb5_context context, const krb5_data *body,
|
||||
+ krb5_data *cksum1_out,
|
||||
+ krb5_pachecksum2 **cksum2_out);
|
||||
+
|
||||
+/* Verify the SHA-1 checksum in cksum1 and the tagged checksum in cksum2.
|
||||
+ * cksum2 may be NULL, in which case only cksum1 is verified. */
|
||||
+krb5_error_code
|
||||
+crypto_verify_checksums(krb5_context context, krb5_data *body,
|
||||
+ const krb5_data *cksum1,
|
||||
+ const krb5_pachecksum2 *cksum2);
|
||||
+
|
||||
#endif /* _PKINIT_CRYPTO_H */
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 402bf1b9b3..429b7d202c 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -2616,11 +2616,11 @@ cleanup:
|
||||
static const EVP_MD *
|
||||
algid_to_md(const krb5_data *alg_id)
|
||||
{
|
||||
- if (data_eq(*alg_id, sha1_id))
|
||||
+ if (data_eq(*alg_id, kdf_sha1_id))
|
||||
return EVP_sha1();
|
||||
- if (data_eq(*alg_id, sha256_id))
|
||||
+ if (data_eq(*alg_id, kdf_sha256_id))
|
||||
return EVP_sha256();
|
||||
- if (data_eq(*alg_id, sha512_id))
|
||||
+ if (data_eq(*alg_id, kdf_sha512_id))
|
||||
return EVP_sha512();
|
||||
return NULL;
|
||||
}
|
||||
@@ -5663,3 +5663,113 @@ parse_dh_min_bits(krb5_context context, const char *str)
|
||||
TRACE_PKINIT_DH_INVALID_MIN_BITS(context, str);
|
||||
return PKINIT_DEFAULT_DH_MIN_BITS;
|
||||
}
|
||||
+
|
||||
+/* Return the OpenSSL message digest type matching the given CMS OID, or NULL
|
||||
+ * if it doesn't match any of the CMS OIDs we know about. */
|
||||
+static const EVP_MD *
|
||||
+md_from_cms_oid(const krb5_data *alg_id)
|
||||
+{
|
||||
+ if (data_eq(*alg_id, cms_sha1_id))
|
||||
+ return EVP_sha1();
|
||||
+ if (data_eq(*alg_id, cms_sha256_id))
|
||||
+ return EVP_sha256();
|
||||
+ if (data_eq(*alg_id, cms_sha384_id))
|
||||
+ return EVP_sha384();
|
||||
+ if (data_eq(*alg_id, cms_sha512_id))
|
||||
+ return EVP_sha512();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Compute a message digest of the given type over body, placing the result in
|
||||
+ * *digest_out in allocated storage. Return true on success. */
|
||||
+static krb5_boolean
|
||||
+make_digest(const krb5_data *body, const EVP_MD *md, krb5_data *digest_out)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_data d;
|
||||
+
|
||||
+ if (md == NULL)
|
||||
+ return FALSE;
|
||||
+ ret = alloc_data(&d, EVP_MD_size(md));
|
||||
+ if (ret)
|
||||
+ return FALSE;
|
||||
+ if (!EVP_Digest(body->data, body->length, (uint8_t *)d.data, &d.length, md,
|
||||
+ NULL)) {
|
||||
+ free(d.data);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ *digest_out = d;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/* Return true if digest verifies for the given body and message digest
|
||||
+ * type. */
|
||||
+static krb5_boolean
|
||||
+check_digest(const krb5_data *body, const EVP_MD *md, const krb5_data *digest)
|
||||
+{
|
||||
+ unsigned int digest_len;
|
||||
+ uint8_t buf[EVP_MAX_MD_SIZE];
|
||||
+
|
||||
+ if (md == NULL)
|
||||
+ return FALSE;
|
||||
+ if (!EVP_Digest(body->data, body->length, buf, &digest_len, md, NULL))
|
||||
+ return FALSE;
|
||||
+ return (digest->length == digest_len &&
|
||||
+ CRYPTO_memcmp(digest->data, buf, digest_len) == 0);
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
+crypto_generate_checksums(krb5_context context, const krb5_data *body,
|
||||
+ krb5_data *cksum1_out, krb5_pachecksum2 **cksum2_out)
|
||||
+{
|
||||
+ krb5_data cksum1 = empty_data();
|
||||
+ krb5_pachecksum2 *cksum2 = NULL;
|
||||
+ krb5_error_code ret;
|
||||
+
|
||||
+ if (!make_digest(body, EVP_sha1(), &cksum1))
|
||||
+ goto fail;
|
||||
+
|
||||
+ cksum2 = k5alloc(sizeof(*cksum2), &ret);
|
||||
+ if (cksum2 == NULL)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (!make_digest(body, EVP_sha256(), &cksum2->checksum))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (krb5int_copy_data_contents(context, &cms_sha256_id,
|
||||
+ &cksum2->algorithmIdentifier.algorithm))
|
||||
+ goto fail;
|
||||
+
|
||||
+ cksum2->algorithmIdentifier.parameters = empty_data();
|
||||
+
|
||||
+ *cksum1_out = cksum1;
|
||||
+ *cksum2_out = cksum2;
|
||||
+ return 0;
|
||||
+
|
||||
+fail:
|
||||
+ krb5_free_data_contents(context, &cksum1);
|
||||
+ free_pachecksum2(context, &cksum2);
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
+crypto_verify_checksums(krb5_context context, krb5_data *body,
|
||||
+ const krb5_data *cksum1,
|
||||
+ const krb5_pachecksum2 *cksum2)
|
||||
+{
|
||||
+ const EVP_MD *md;
|
||||
+
|
||||
+ /* RFC 4556 doesn't say what error to return if the checksum doesn't match.
|
||||
+ * Windows returns this one. */
|
||||
+ if (!check_digest(body, EVP_sha1(), cksum1))
|
||||
+ return KRB5KRB_AP_ERR_MODIFIED;
|
||||
+
|
||||
+ if (cksum2 == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ md = md_from_cms_oid(&cksum2->algorithmIdentifier.algorithm);
|
||||
+ if (!check_digest(body, md, &cksum2->checksum))
|
||||
+ return KRB5KRB_AP_ERR_MODIFIED;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_kdf_test.c b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
|
||||
index 99c93ac128..dd6e8d7503 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_kdf_test.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
|
||||
@@ -126,7 +126,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* TEST 1: SHA-1/AES */
|
||||
/* set up algorithm id */
|
||||
- alg_id.algorithm = sha1_id;
|
||||
+ alg_id.algorithm = kdf_sha1_id;
|
||||
|
||||
enctype = enctype_aes;
|
||||
|
||||
@@ -157,7 +157,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* TEST 2: SHA-256/AES */
|
||||
/* set up algorithm id */
|
||||
- alg_id.algorithm = sha256_id;
|
||||
+ alg_id.algorithm = kdf_sha256_id;
|
||||
|
||||
enctype = enctype_aes;
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_lib.c b/src/plugins/preauth/pkinit/pkinit_lib.c
|
||||
index 25965eb5d2..891f47fd26 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_lib.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_lib.c
|
||||
@@ -29,6 +29,7 @@
|
||||
* SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
+#include "k5-int.h"
|
||||
#include "pkinit.h"
|
||||
|
||||
#define FAKECERT
|
||||
@@ -119,8 +120,9 @@ free_krb5_auth_pack(krb5_auth_pack **in)
|
||||
{
|
||||
if ((*in) == NULL) return;
|
||||
krb5_free_data_contents(NULL, &(*in)->clientPublicValue);
|
||||
- free((*in)->pkAuthenticator.paChecksum.contents);
|
||||
+ free((*in)->pkAuthenticator.paChecksum.data);
|
||||
krb5_free_data(NULL, (*in)->pkAuthenticator.freshnessToken);
|
||||
+ free_pachecksum2(NULL, &(*in)->pkAuthenticator.paChecksum2);
|
||||
if ((*in)->supportedCMSTypes != NULL)
|
||||
free_krb5_algorithm_identifiers(&((*in)->supportedCMSTypes));
|
||||
if ((*in)->supportedKDFs) {
|
||||
@@ -196,6 +198,18 @@ free_krb5_kdc_dh_key_info(krb5_kdc_dh_key_info **in)
|
||||
free(*in);
|
||||
}
|
||||
|
||||
+void
|
||||
+free_pachecksum2(krb5_context context, krb5_pachecksum2 **in)
|
||||
+{
|
||||
+ if (*in == NULL)
|
||||
+ return;
|
||||
+ krb5_free_data_contents(context, &(*in)->checksum);
|
||||
+ krb5_free_data_contents(context, &(*in)->algorithmIdentifier.algorithm);
|
||||
+ krb5_free_data_contents(context, &(*in)->algorithmIdentifier.parameters);
|
||||
+ free(*in);
|
||||
+ *in = NULL;
|
||||
+}
|
||||
+
|
||||
void
|
||||
init_krb5_pa_pk_as_req(krb5_pa_pk_as_req **in)
|
||||
{
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
index e22bcb195b..f558308483 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
@@ -428,11 +428,12 @@ pkinit_server_verify_padata(krb5_context context,
|
||||
krb5_data authp_data = {0, 0, NULL}, krb5_authz = {0, 0, NULL};
|
||||
krb5_pa_pk_as_req *reqp = NULL;
|
||||
krb5_auth_pack *auth_pack = NULL;
|
||||
+ krb5_pk_authenticator *pka;
|
||||
pkinit_kdc_context plgctx = NULL;
|
||||
pkinit_kdc_req_context reqctx = NULL;
|
||||
krb5_checksum cksum = {0, 0, 0, NULL};
|
||||
krb5_data *der_req = NULL;
|
||||
- krb5_data k5data, *ftoken;
|
||||
+ krb5_data k5data;
|
||||
int is_signed = 1;
|
||||
krb5_pa_data **e_data = NULL;
|
||||
krb5_kdcpreauth_modreq modreq = NULL;
|
||||
@@ -524,8 +525,9 @@ pkinit_server_verify_padata(krb5_context context,
|
||||
pkiDebug("failed to decode krb5_auth_pack\n");
|
||||
goto cleanup;
|
||||
}
|
||||
+ pka = &auth_pack->pkAuthenticator;
|
||||
|
||||
- retval = krb5_check_clockskew(context, auth_pack->pkAuthenticator.ctime);
|
||||
+ retval = krb5_check_clockskew(context, pka->ctime);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
|
||||
@@ -548,36 +550,14 @@ pkinit_server_verify_padata(krb5_context context,
|
||||
goto cleanup;
|
||||
}
|
||||
der_req = cb->request_body(context, rock);
|
||||
- retval = krb5_c_make_checksum(context, CKSUMTYPE_SHA1, NULL, 0, der_req,
|
||||
- &cksum);
|
||||
- if (retval) {
|
||||
- pkiDebug("unable to calculate AS REQ checksum\n");
|
||||
- goto cleanup;
|
||||
- }
|
||||
- if (cksum.length != auth_pack->pkAuthenticator.paChecksum.length ||
|
||||
- k5_bcmp(cksum.contents, auth_pack->pkAuthenticator.paChecksum.contents,
|
||||
- cksum.length) != 0) {
|
||||
- pkiDebug("failed to match the checksum\n");
|
||||
-#ifdef DEBUG_CKSUM
|
||||
- pkiDebug("calculating checksum on buf size (%d)\n", req_pkt->length);
|
||||
- print_buffer(req_pkt->data, req_pkt->length);
|
||||
- pkiDebug("received checksum type=%d size=%d ",
|
||||
- auth_pack->pkAuthenticator.paChecksum.checksum_type,
|
||||
- auth_pack->pkAuthenticator.paChecksum.length);
|
||||
- print_buffer(auth_pack->pkAuthenticator.paChecksum.contents,
|
||||
- auth_pack->pkAuthenticator.paChecksum.length);
|
||||
- pkiDebug("expected checksum type=%d size=%d ",
|
||||
- cksum.checksum_type, cksum.length);
|
||||
- print_buffer(cksum.contents, cksum.length);
|
||||
-#endif
|
||||
|
||||
- retval = KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED;
|
||||
+ retval = crypto_verify_checksums(context, der_req, &pka->paChecksum,
|
||||
+ pka->paChecksum2);
|
||||
+ if (retval)
|
||||
goto cleanup;
|
||||
- }
|
||||
|
||||
- ftoken = auth_pack->pkAuthenticator.freshnessToken;
|
||||
- if (ftoken != NULL) {
|
||||
- retval = cb->check_freshness_token(context, rock, ftoken);
|
||||
+ if (pka->freshnessToken != NULL) {
|
||||
+ retval = cb->check_freshness_token(context, rock, pka->freshnessToken);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
valid_freshness_token = TRUE;
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
index 1faa6816d7..7b68d4b3b1 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
|
||||
@@ -58,8 +58,9 @@
|
||||
TRACE(c, "PKINIT client verified DH reply")
|
||||
#define TRACE_PKINIT_CLIENT_REP_DH_FAIL(c) \
|
||||
TRACE(c, "PKINIT client could not verify DH reply")
|
||||
-#define TRACE_PKINIT_CLIENT_REQ_CHECKSUM(c, cksum) \
|
||||
- TRACE(c, "PKINIT client computed kdc-req-body checksum {cksum}", cksum)
|
||||
+#define TRACE_PKINIT_CLIENT_REQ_CHECKSUMS(c, ck1, ck2) \
|
||||
+ TRACE(c, "PKINIT client computed checksums: {hexdata} {hexdata}", \
|
||||
+ ck1, &(ck2)->checksum)
|
||||
#define TRACE_PKINIT_CLIENT_REQ_DH(c) \
|
||||
TRACE(c, "PKINIT client making DH request")
|
||||
#define TRACE_PKINIT_CLIENT_SAN_CONFIG_DNSNAME(c, host) \
|
||||
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
|
||||
index 2fa6dce8eb..f47849abad 100644
|
||||
--- a/src/tests/asn.1/krb5_decode_test.c
|
||||
+++ b/src/tests/asn.1/krb5_decode_test.c
|
||||
@@ -1174,7 +1174,7 @@ main(int argc, char **argv)
|
||||
/* decode_krb5_auth_pack */
|
||||
{
|
||||
setup(krb5_auth_pack,ktest_make_sample_auth_pack);
|
||||
- decode_run("krb5_auth_pack","","30 81 85 A0 35 30 33 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61",
|
||||
+ decode_run("krb5_auth_pack","","30 81 89 A0 39 30 37 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61",
|
||||
acc.decode_krb5_auth_pack,
|
||||
ktest_equal_auth_pack,ktest_free_auth_pack);
|
||||
ktest_empty_auth_pack(&ref);
|
||||
diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
|
||||
index d37e4fa7e6..7f54aa3184 100644
|
||||
--- a/src/tests/asn.1/ktest.c
|
||||
+++ b/src/tests/asn.1/ktest.c
|
||||
@@ -700,9 +700,7 @@ ktest_make_sample_pk_authenticator(krb5_pk_authenticator *p)
|
||||
p->cusec = SAMPLE_USEC;
|
||||
p->ctime = SAMPLE_TIME;
|
||||
p->nonce = SAMPLE_NONCE;
|
||||
- ktest_make_sample_checksum(&p->paChecksum);
|
||||
- /* We don't encode the checksum type, only the contents. */
|
||||
- p->paChecksum.checksum_type = 0;
|
||||
+ ktest_make_sample_data(&p->paChecksum);
|
||||
p->freshnessToken = ealloc(sizeof(krb5_data));
|
||||
ktest_make_sample_data(p->freshnessToken);
|
||||
}
|
||||
@@ -1604,8 +1602,7 @@ ktest_empty_pa_otp_req(krb5_pa_otp_req *p)
|
||||
static void
|
||||
ktest_empty_pk_authenticator(krb5_pk_authenticator *p)
|
||||
{
|
||||
- ktest_empty_checksum(&p->paChecksum);
|
||||
- p->paChecksum.contents = NULL;
|
||||
+ ktest_empty_data(&p->paChecksum);
|
||||
krb5_free_data(NULL, p->freshnessToken);
|
||||
p->freshnessToken = NULL;
|
||||
}
|
||||
diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c
|
||||
index b48a0285d2..13786dd1e5 100644
|
||||
--- a/src/tests/asn.1/ktest_equal.c
|
||||
+++ b/src/tests/asn.1/ktest_equal.c
|
||||
@@ -844,7 +844,7 @@ ktest_equal_pk_authenticator(krb5_pk_authenticator *ref,
|
||||
p = p && scalar_equal(cusec);
|
||||
p = p && scalar_equal(ctime);
|
||||
p = p && scalar_equal(nonce);
|
||||
- p = p && struct_equal(paChecksum, ktest_equal_checksum);
|
||||
+ p = p && data_eq(ref->paChecksum, var->paChecksum);
|
||||
return p;
|
||||
}
|
||||
|
||||
diff --git a/src/tests/asn.1/pkinit_encode.out b/src/tests/asn.1/pkinit_encode.out
|
||||
index 6ec7aaa36a..a764182e15 100644
|
||||
--- a/src/tests/asn.1/pkinit_encode.out
|
||||
+++ b/src/tests/asn.1/pkinit_encode.out
|
||||
@@ -1,7 +1,7 @@
|
||||
encode_krb5_pa_pk_as_req: 30 38 80 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 1E 80 08 6B 72 62 35 64 61 74 61 81 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61
|
||||
encode_krb5_pa_pk_as_rep(dhInfo): A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
|
||||
encode_krb5_pa_pk_as_rep(encKeyPack): 81 08 6B 72 62 35 64 61 74 61
|
||||
-encode_krb5_auth_pack: 30 81 85 A0 35 30 33 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 06 04 04 31 32 33 34 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
|
||||
+encode_krb5_auth_pack: 30 81 89 A0 39 30 37 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61
|
||||
encode_krb5_kdc_dh_key_info: 30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A
|
||||
encode_krb5_reply_key_pack: 30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34
|
||||
encode_krb5_sp80056a_other_info: 30 81 81 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A0 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 0A 04 08 6B 72 62 35 64 61 74 61
|
||||
diff --git a/src/tests/asn.1/pkinit_trval.out b/src/tests/asn.1/pkinit_trval.out
|
||||
index 46f4a34108..c47bd71f67 100644
|
||||
--- a/src/tests/asn.1/pkinit_trval.out
|
||||
+++ b/src/tests/asn.1/pkinit_trval.out
|
||||
@@ -38,7 +38,7 @@ encode_krb5_auth_pack:
|
||||
. . [0] [Integer] 123456
|
||||
. . [1] [Generalized Time] "19940610060317Z"
|
||||
. . [2] [Integer] 42
|
||||
-. . [3] [Octet String] "1234"
|
||||
+. . [3] [Octet String] "krb5data"
|
||||
. . [4] [Octet String] "krb5data"
|
||||
. [1] [Octet String] "pvalue"
|
||||
. [2] [Sequence/Sequence Of]
|
||||
--
|
||||
2.49.0
|
||||
|
||||
381
0038-downstream-Do-not-block-HMAC-MD4-5-in-FIPS-mode.patch
Normal file
381
0038-downstream-Do-not-block-HMAC-MD4-5-in-FIPS-mode.patch
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
From 33afd2a6cfdf87d153170b41fbabfb92be49c422 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 10 Apr 2025 10:04:22 +0200
|
||||
Subject: [PATCH] [downstream] Do not block HMAC-MD4/5 in FIPS mode
|
||||
|
||||
To ensure RC4 HMAC-MD5 was not used in FIPS mode, access to HMAC-MD4/5
|
||||
was not allowed in this mode. However, since we provide the
|
||||
"radius_md5_fips_override" configuration parameter to allow using RADIUS
|
||||
regardless to the FIPS restrictions, we should allow HMAC-MD5 to be used
|
||||
too in this case, because it is required for the newly supported
|
||||
Message-Authenticator attribute.
|
||||
|
||||
A FIPS mode check is added in calculate_mac() which will fail if
|
||||
"radius_md5_fips_override" is not true. It will not affect interactions
|
||||
between krb5kdc and ipa-otpd, because the Message-Authenticator
|
||||
attribute is not generated in this case.
|
||||
---
|
||||
src/lib/crypto/krb/crypto_int.h | 9 +++
|
||||
src/lib/crypto/openssl/Makefile.in | 9 ++-
|
||||
src/lib/crypto/openssl/common.c | 80 +++++++++++++++++++
|
||||
.../crypto/openssl/hash_provider/hash_evp.c | 62 ++------------
|
||||
src/lib/crypto/openssl/hmac.c | 15 ++--
|
||||
src/lib/krad/packet.c | 19 +++--
|
||||
6 files changed, 120 insertions(+), 74 deletions(-)
|
||||
create mode 100644 src/lib/crypto/openssl/common.c
|
||||
|
||||
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
|
||||
index 1ee4b30e02..ff67b6bd35 100644
|
||||
--- a/src/lib/crypto/krb/crypto_int.h
|
||||
+++ b/src/lib/crypto/krb/crypto_int.h
|
||||
@@ -36,6 +36,9 @@
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+
|
||||
+#include <openssl/provider.h>
|
||||
+
|
||||
/*
|
||||
* OpenSSL 3.0 relegates MD4 and RC4 to the legacy provider, which must be
|
||||
* explicitly loaded into a library context. Performing this loading within a
|
||||
@@ -660,4 +663,10 @@ iov_cursor_advance(struct iov_cursor *c, size_t nblocks)
|
||||
c->out_pos += nblocks * c->block_size;
|
||||
}
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+
|
||||
+krb5_error_code k5_get_ossl_legacy_libctx(OSSL_LIB_CTX **libctx);
|
||||
+
|
||||
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
+
|
||||
#endif /* CRYPTO_INT_H */
|
||||
diff --git a/src/lib/crypto/openssl/Makefile.in b/src/lib/crypto/openssl/Makefile.in
|
||||
index 8e4cdb8bbf..cc131000bd 100644
|
||||
--- a/src/lib/crypto/openssl/Makefile.in
|
||||
+++ b/src/lib/crypto/openssl/Makefile.in
|
||||
@@ -8,21 +8,24 @@ STLIBOBJS=\
|
||||
hmac.o \
|
||||
kdf.o \
|
||||
pbkdf2.o \
|
||||
- sha256.o
|
||||
+ sha256.o \
|
||||
+ common.o
|
||||
|
||||
OBJS=\
|
||||
$(OUTPRE)cmac.$(OBJEXT) \
|
||||
$(OUTPRE)hmac.$(OBJEXT) \
|
||||
$(OUTPRE)kdf.$(OBJEXT) \
|
||||
$(OUTPRE)pbkdf2.$(OBJEXT) \
|
||||
- $(OUTPRE)sha256.$(OBJEXT)
|
||||
+ $(OUTPRE)sha256.$(OBJEXT) \
|
||||
+ $(OUTPRE)common.$(OBJEXT)
|
||||
|
||||
SRCS=\
|
||||
$(srcdir)/cmac.c \
|
||||
$(srcdir)/hmac.c \
|
||||
$(srcdir)/kdf.c \
|
||||
$(srcdir)/pbkdf2.c \
|
||||
- $(srcdir)/sha256.c
|
||||
+ $(srcdir)/sha256.c \
|
||||
+ $(srcdir)/common.c
|
||||
|
||||
SUBDIROBJLISTS= md4/OBJS.ST \
|
||||
md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \
|
||||
diff --git a/src/lib/crypto/openssl/common.c b/src/lib/crypto/openssl/common.c
|
||||
new file mode 100644
|
||||
index 0000000000..ced43fd54c
|
||||
--- /dev/null
|
||||
+++ b/src/lib/crypto/openssl/common.c
|
||||
@@ -0,0 +1,80 @@
|
||||
+#include "crypto_int.h"
|
||||
+
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+
|
||||
+#include <openssl/provider.h>
|
||||
+#include <openssl/fips.h>
|
||||
+#include <threads.h>
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+typedef struct ossl_legacy_context {
|
||||
+ bool initialized;
|
||||
+ OSSL_LIB_CTX *libctx;
|
||||
+ OSSL_PROVIDER *default_provider;
|
||||
+ OSSL_PROVIDER *legacy_provider;
|
||||
+} ossl_legacy_context_t;
|
||||
+
|
||||
+static thread_local ossl_legacy_context_t g_ossl_legacy_ctx;
|
||||
+
|
||||
+static krb5_error_code
|
||||
+init_ossl_legacy_ctx(ossl_legacy_context_t *ctx)
|
||||
+{
|
||||
+ ctx->libctx = OSSL_LIB_CTX_new();
|
||||
+ if (!ctx->libctx)
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ /* Load both legacy and default provider as both may be needed. */
|
||||
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||
+
|
||||
+ if (!(ctx->default_provider && ctx->legacy_provider))
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ ctx->initialized = true;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+deinit_ossl_legacy_ctx(ossl_legacy_context_t *ctx)
|
||||
+{
|
||||
+ if (ctx->legacy_provider)
|
||||
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||
+
|
||||
+ if (ctx->default_provider)
|
||||
+ OSSL_PROVIDER_unload(ctx->default_provider);
|
||||
+
|
||||
+ if (ctx->libctx)
|
||||
+ OSSL_LIB_CTX_free(ctx->libctx);
|
||||
+
|
||||
+ ctx->initialized = false;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
+k5_get_ossl_legacy_libctx(OSSL_LIB_CTX **libctx)
|
||||
+{
|
||||
+ krb5_error_code err;
|
||||
+
|
||||
+ if (!FIPS_mode()) {
|
||||
+ if (libctx)
|
||||
+ *libctx = NULL;
|
||||
+ err = 0;
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ if (!g_ossl_legacy_ctx.initialized) {
|
||||
+ err = init_ossl_legacy_ctx(&g_ossl_legacy_ctx);
|
||||
+ if (err) {
|
||||
+ deinit_ossl_legacy_ctx(&g_ossl_legacy_ctx);
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (libctx)
|
||||
+ *libctx = g_ossl_legacy_ctx.libctx;
|
||||
+ err = 0;
|
||||
+
|
||||
+end:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
index eb2e693e9f..2fd5d383d6 100644
|
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
@@ -44,48 +44,7 @@
|
||||
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#endif
|
||||
|
||||
-#include <openssl/provider.h>
|
||||
#include <openssl/fips.h>
|
||||
-#include <threads.h>
|
||||
-
|
||||
-typedef struct ossl_lib_md_context {
|
||||
- OSSL_LIB_CTX *libctx;
|
||||
- OSSL_PROVIDER *default_provider;
|
||||
- OSSL_PROVIDER *legacy_provider;
|
||||
-} ossl_md_context_t;
|
||||
-
|
||||
-static thread_local ossl_md_context_t *ossl_md_ctx = NULL;
|
||||
-
|
||||
-static krb5_error_code
|
||||
-init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo)
|
||||
-{
|
||||
- ctx->libctx = OSSL_LIB_CTX_new();
|
||||
- if (!ctx->libctx)
|
||||
- return KRB5_CRYPTO_INTERNAL;
|
||||
-
|
||||
- /* Load both legacy and default provider as both may be needed. */
|
||||
- ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||
- ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||
-
|
||||
- if (!(ctx->default_provider && ctx->legacy_provider))
|
||||
- return KRB5_CRYPTO_INTERNAL;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-deinit_ossl_ctx(ossl_md_context_t *ctx)
|
||||
-{
|
||||
- if (ctx->legacy_provider)
|
||||
- OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||
-
|
||||
- if (ctx->default_provider)
|
||||
- OSSL_PROVIDER_unload(ctx->default_provider);
|
||||
-
|
||||
- if (ctx->libctx)
|
||||
- OSSL_LIB_CTX_free(ctx->libctx);
|
||||
-}
|
||||
-
|
||||
|
||||
static krb5_error_code
|
||||
hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
@@ -120,25 +79,14 @@ hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data,
|
||||
krb5_data *output)
|
||||
{
|
||||
krb5_error_code err;
|
||||
+ OSSL_LIB_CTX *ossl_libctx;
|
||||
EVP_MD *md = NULL;
|
||||
|
||||
- if (!ossl_md_ctx) {
|
||||
- ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
|
||||
- if (!ossl_md_ctx) {
|
||||
- err = ENOMEM;
|
||||
- goto end;
|
||||
- }
|
||||
-
|
||||
- err = init_ossl_md_ctx(ossl_md_ctx, algo);
|
||||
- if (err) {
|
||||
- deinit_ossl_ctx(ossl_md_ctx);
|
||||
- free(ossl_md_ctx);
|
||||
- ossl_md_ctx = NULL;
|
||||
- goto end;
|
||||
- }
|
||||
- }
|
||||
+ err = k5_get_ossl_legacy_libctx(&ossl_libctx);
|
||||
+ if (err)
|
||||
+ goto end;
|
||||
|
||||
- md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
|
||||
+ md = EVP_MD_fetch(ossl_libctx, algo, NULL);
|
||||
if (!md) {
|
||||
err = KRB5_CRYPTO_INTERNAL;
|
||||
goto end;
|
||||
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
|
||||
index 25a419d73a..8f9e88fec9 100644
|
||||
--- a/src/lib/crypto/openssl/hmac.c
|
||||
+++ b/src/lib/crypto/openssl/hmac.c
|
||||
@@ -59,7 +59,6 @@
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_names.h>
|
||||
-#include <openssl/fips.h>
|
||||
#else
|
||||
#include <openssl/hmac.h>
|
||||
#endif
|
||||
@@ -112,11 +111,7 @@ map_digest(const struct krb5_hash_provider *hash)
|
||||
return EVP_sha256();
|
||||
else if (hash == &krb5int_hash_sha384)
|
||||
return EVP_sha384();
|
||||
-
|
||||
- if (FIPS_mode())
|
||||
- return NULL;
|
||||
-
|
||||
- if (hash == &krb5int_hash_md5)
|
||||
+ else if (hash == &krb5int_hash_md5)
|
||||
return EVP_md5();
|
||||
else if (hash == &krb5int_hash_md4)
|
||||
return EVP_md4();
|
||||
@@ -138,13 +133,19 @@ krb5int_hmac_keyblock(const struct krb5_hash_provider *hash,
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
OSSL_PARAM params[2], *p = params;
|
||||
size_t i = 0, md_len;
|
||||
+ OSSL_LIB_CTX *ossl_libctx;
|
||||
+ krb5_error_code err;
|
||||
|
||||
if (md == NULL || keyblock->length > hash->blocksize)
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
if (output->length < hash->hashsize)
|
||||
return KRB5_BAD_MSIZE;
|
||||
|
||||
- mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||
+ err = k5_get_ossl_legacy_libctx(&ossl_libctx);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ mac = EVP_MAC_fetch(ossl_libctx, "HMAC", NULL);
|
||||
if (mac == NULL)
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
|
||||
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||
index 3c1a4d507e..b95c99df65 100644
|
||||
--- a/src/lib/krad/packet.c
|
||||
+++ b/src/lib/krad/packet.c
|
||||
@@ -278,7 +278,7 @@ lookup_msgauth_addr(const krad_packet *pkt)
|
||||
* auth, which may be from pkt or from a corresponding request.
|
||||
*/
|
||||
static krb5_error_code
|
||||
-calculate_mac(const char *secret, const krad_packet *pkt,
|
||||
+calculate_mac(krb5_context ctx, const char *secret, const krad_packet *pkt,
|
||||
const uint8_t auth[AUTH_FIELD_SIZE],
|
||||
uint8_t mac_out[MD5_DIGEST_SIZE])
|
||||
{
|
||||
@@ -288,6 +288,10 @@ calculate_mac(const char *secret, const krad_packet *pkt,
|
||||
krb5_crypto_iov input[5];
|
||||
krb5_data ksecr, mac;
|
||||
|
||||
+ /* Do not use HMAC-MD5 if not explicitly allowed */
|
||||
+ if (kr_use_fips(ctx))
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
msgauth_attr = lookup_msgauth_addr(pkt);
|
||||
if (msgauth_attr == NULL)
|
||||
return EINVAL;
|
||||
@@ -393,7 +397,8 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||
|
||||
if (msgauth_required) {
|
||||
/* Calculate and set the Message-Authenticator MAC. */
|
||||
- retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2);
|
||||
+ retval = calculate_mac(ctx, secret, pkt, pkt_auth(pkt),
|
||||
+ pkt_attr(pkt) + 2);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
}
|
||||
@@ -454,7 +459,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||
* section 5.14, use the authenticator from the request, not from the
|
||||
* response.
|
||||
*/
|
||||
- retval = calculate_mac(secret, pkt, pkt_auth(request),
|
||||
+ retval = calculate_mac(ctx, secret, pkt, pkt_auth(request),
|
||||
pkt_attr(pkt) + 2);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
@@ -476,7 +481,7 @@ error:
|
||||
/* Verify the Message-Authenticator value in pkt, using the provided
|
||||
* authenticator (which may be from pkt or from a corresponding request). */
|
||||
static krb5_error_code
|
||||
-verify_msgauth(const char *secret, const krad_packet *pkt,
|
||||
+verify_msgauth(krb5_context ctx, const char *secret, const krad_packet *pkt,
|
||||
const uint8_t auth[AUTH_FIELD_SIZE])
|
||||
{
|
||||
uint8_t mac[MD5_DIGEST_SIZE];
|
||||
@@ -488,7 +493,7 @@ verify_msgauth(const char *secret, const krad_packet *pkt,
|
||||
if (msgauth == NULL)
|
||||
return ENODATA;
|
||||
|
||||
- retval = calculate_mac(secret, pkt, auth, mac);
|
||||
+ retval = calculate_mac(ctx, secret, pkt, auth, mac);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@@ -561,7 +566,7 @@ krad_packet_decode_request(krb5_context ctx, const char *secret,
|
||||
|
||||
/* Verify Message-Authenticator if present. */
|
||||
if (has_pkt_msgauth(req)) {
|
||||
- retval = verify_msgauth(secret, req, pkt_auth(req));
|
||||
+ retval = verify_msgauth(ctx, secret, req, pkt_auth(req));
|
||||
if (retval) {
|
||||
krad_packet_free(req);
|
||||
return retval;
|
||||
@@ -613,7 +618,7 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
|
||||
|
||||
/* Verify Message-Authenticator if present. */
|
||||
if (has_pkt_msgauth(*rsppkt)) {
|
||||
- if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0)
|
||||
+ if (verify_msgauth(ctx, secret, *rsppkt, pkt_auth(tmp)) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
189
0039-Fix-strchr-conformance-to-C23.patch
Normal file
189
0039-Fix-strchr-conformance-to-C23.patch
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
From 1761e06398e4f043e4f540f57131c37fcc53a1b9 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Wed, 10 Dec 2025 10:42:02 +0200
|
||||
Subject: [PATCH] Fix strchr() conformance to C23
|
||||
|
||||
C23 7.28.5.1 specifies search functions such as strchr() as generic,
|
||||
returning const char * if the first argument is of type const char *.
|
||||
Fix uses of strchr() to conform to this change.
|
||||
|
||||
[jrische@redhat.com: altered changes to avoid casts; fixed an
|
||||
additional case]
|
||||
[ghudson@mit.edu: condensed some declarations; rewrote commit message]
|
||||
|
||||
ticket: 9191 (new)
|
||||
(cherry picked from commit 6cd8580d823585d50ee4f30efd9f7e855823a369)
|
||||
---
|
||||
src/lib/krb5/ccache/ccbase.c | 4 ++--
|
||||
src/lib/krb5/os/expand_path.c | 3 ++-
|
||||
src/lib/krb5/os/locate_kdc.c | 15 +++++++--------
|
||||
src/plugins/preauth/pkinit/pkinit_crypto.h | 2 +-
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 6 +++---
|
||||
src/plugins/preauth/pkinit/pkinit_identity.c | 2 +-
|
||||
src/plugins/preauth/pkinit/pkinit_matching.c | 2 +-
|
||||
src/tests/responder.c | 3 +--
|
||||
8 files changed, 18 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
|
||||
index 5a01320832..1aada91b5e 100644
|
||||
--- a/src/lib/krb5/ccache/ccbase.c
|
||||
+++ b/src/lib/krb5/ccache/ccbase.c
|
||||
@@ -201,8 +201,8 @@ krb5_cc_register(krb5_context context, const krb5_cc_ops *ops,
|
||||
krb5_error_code KRB5_CALLCONV
|
||||
krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache)
|
||||
{
|
||||
- char *pfx, *cp;
|
||||
- const char *resid;
|
||||
+ char *pfx;
|
||||
+ const char *cp, *resid;
|
||||
unsigned int pfxlen;
|
||||
krb5_error_code err;
|
||||
const krb5_cc_ops *ops;
|
||||
diff --git a/src/lib/krb5/os/expand_path.c b/src/lib/krb5/os/expand_path.c
|
||||
index 5cbccf08c8..6569b8820b 100644
|
||||
--- a/src/lib/krb5/os/expand_path.c
|
||||
+++ b/src/lib/krb5/os/expand_path.c
|
||||
@@ -454,7 +454,8 @@ k5_expand_path_tokens_extra(krb5_context context, const char *path_in,
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct k5buf buf;
|
||||
- char *tok_begin, *tok_end, *tok_val, **extra_tokens = NULL, *path;
|
||||
+ const char *tok_begin, *tok_end;
|
||||
+ char *tok_val, **extra_tokens = NULL, *path;
|
||||
const char *path_left;
|
||||
size_t nargs = 0, i;
|
||||
va_list ap;
|
||||
diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
|
||||
index edca5ac7eb..47e15c849f 100644
|
||||
--- a/src/lib/krb5/os/locate_kdc.c
|
||||
+++ b/src/lib/krb5/os/locate_kdc.c
|
||||
@@ -188,8 +188,8 @@ oom:
|
||||
}
|
||||
|
||||
static void
|
||||
-parse_uri_if_https(const char *host_or_uri, k5_transport *transport,
|
||||
- const char **host, const char **uri_path)
|
||||
+parse_uri_if_https(char *host_or_uri, k5_transport *transport,
|
||||
+ char **host, const char **uri_path)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
@@ -229,8 +229,7 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm,
|
||||
k5_transport transport, int udpport)
|
||||
{
|
||||
const char *realm_srv_names[4];
|
||||
- char **hostlist = NULL, *realmstr = NULL, *host = NULL;
|
||||
- const char *hostspec;
|
||||
+ char **hostlist = NULL, *realmstr = NULL, *host = NULL, *hostspec;
|
||||
krb5_error_code code;
|
||||
int i, default_port;
|
||||
|
||||
@@ -535,8 +534,8 @@ prof_locate_server(krb5_context context, const krb5_data *realm,
|
||||
* Return a NULL *host_out if there are any problems parsing the URI.
|
||||
*/
|
||||
static void
|
||||
-parse_uri_fields(const char *uri, k5_transport *transport_out,
|
||||
- const char **host_out, int *primary_out)
|
||||
+parse_uri_fields(char *uri, k5_transport *transport_out,
|
||||
+ char **host_out, int *primary_out)
|
||||
|
||||
{
|
||||
k5_transport transport;
|
||||
@@ -604,8 +603,8 @@ locate_uri(krb5_context context, const krb5_data *realm,
|
||||
krb5_error_code ret;
|
||||
k5_transport transport, host_trans;
|
||||
struct srv_dns_entry *answers, *entry;
|
||||
- char *host;
|
||||
- const char *host_field, *path;
|
||||
+ char *host, *host_field;
|
||||
+ const char *path;
|
||||
int port, def_port, primary;
|
||||
|
||||
ret = k5_make_uri_query(context, realm, req_service, &answers);
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
index 3b12e904b1..99e2394040 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
@@ -456,7 +456,7 @@ krb5_error_code crypto_load_cas_and_crls
|
||||
defines the storage type (file, directory, etc) */
|
||||
int catype, /* IN
|
||||
defines the ca type (anchor, intermediate, crls) */
|
||||
- char *id); /* IN
|
||||
+ const char *id); /* IN
|
||||
defines the location (filename, directory name, etc) */
|
||||
|
||||
/*
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 429b7d202c..6013080afc 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -4956,7 +4956,7 @@ load_cas_and_crls(krb5_context context,
|
||||
pkinit_req_crypto_context req_cryptoctx,
|
||||
pkinit_identity_crypto_context id_cryptoctx,
|
||||
int catype,
|
||||
- char *filename)
|
||||
+ const char *filename)
|
||||
{
|
||||
STACK_OF(X509_INFO) *sk = NULL;
|
||||
STACK_OF(X509) *ca_certs = NULL;
|
||||
@@ -5114,7 +5114,7 @@ load_cas_and_crls_dir(krb5_context context,
|
||||
pkinit_req_crypto_context req_cryptoctx,
|
||||
pkinit_identity_crypto_context id_cryptoctx,
|
||||
int catype,
|
||||
- char *dirname)
|
||||
+ const char *dirname)
|
||||
{
|
||||
krb5_error_code retval = EINVAL;
|
||||
DIR *d = NULL;
|
||||
@@ -5166,7 +5166,7 @@ crypto_load_cas_and_crls(krb5_context context,
|
||||
pkinit_identity_crypto_context id_cryptoctx,
|
||||
int idtype,
|
||||
int catype,
|
||||
- char *id)
|
||||
+ const char *id)
|
||||
{
|
||||
switch (idtype) {
|
||||
case IDTYPE_FILE:
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
|
||||
index a5a979f279..b06d519c66 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
|
||||
@@ -474,7 +474,7 @@ process_option_ca_crl(krb5_context context,
|
||||
const char *value,
|
||||
int catype)
|
||||
{
|
||||
- char *residual;
|
||||
+ const char *residual;
|
||||
unsigned int typelen;
|
||||
int idtype;
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c
|
||||
index b42485a50a..5a7f2ba3fa 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_matching.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_matching.c
|
||||
@@ -263,7 +263,7 @@ parse_rule_component(krb5_context context,
|
||||
char err_buf[128];
|
||||
int ret;
|
||||
struct keyword_desc *kw, *nextkw;
|
||||
- char *nk;
|
||||
+ const char *nk;
|
||||
int found_next_kw = 0;
|
||||
char *value = NULL;
|
||||
size_t len;
|
||||
diff --git a/src/tests/responder.c b/src/tests/responder.c
|
||||
index 82f870ea5d..4221a20283 100644
|
||||
--- a/src/tests/responder.c
|
||||
+++ b/src/tests/responder.c
|
||||
@@ -282,8 +282,7 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx)
|
||||
/* Provide a particular response for an OTP challenge. */
|
||||
if (data->otp_answer != NULL) {
|
||||
if (krb5_responder_otp_get_challenge(ctx, rctx, &ochl) == 0) {
|
||||
- key = strchr(data->otp_answer, '=');
|
||||
- if (key != NULL) {
|
||||
+ if (strchr(data->otp_answer, '=') != NULL) {
|
||||
/* Make a copy of the answer that we can chop up. */
|
||||
key = strdup(data->otp_answer);
|
||||
if (key == NULL)
|
||||
--
|
||||
2.51.1
|
||||
|
||||
226
0040-automated-fast.patch
Normal file
226
0040-automated-fast.patch
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
From 3baf9b93dc1dfe38585722c71d7268304cb4a01a Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Sun, 21 Sep 2025 11:14:51 +0300
|
||||
Subject: libkrb5: in case PKINIT is configured, attempt Anonymous
|
||||
PKINIT for FAST
|
||||
|
||||
If auto_fast_armor is configured for the realm or globally, optimistically
|
||||
assume that Anonymous PKINIT is supported as well and try to obtain it for
|
||||
FAST use in case no pre-made FAST channel was established by the caller.
|
||||
|
||||
This behavior will automatically enable use of passwordless pre-authentication
|
||||
methods which rely on FAST channel presence in deployments such as FreeIPA.
|
||||
|
||||
Notably, Microsoft Active Directory KDCs do not support Anonymous PKINIT. For
|
||||
these deployments only a machine account (host keytab) can be used to build a
|
||||
FAST channel. However, libkrb5 does not have access to /etc/krb5.keytab in a
|
||||
general case.
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
src/lib/krb5/krb/fast.c | 118 ++++++++++++++++++++++++++++++++++++++++
|
||||
src/lib/krb5/krb/fast.h | 2 +
|
||||
src/man/krb5.conf.man | 13 +++++
|
||||
3 files changed, 133 insertions(+)
|
||||
|
||||
diff --git a/src/lib/krb5/krb/fast.c b/src/lib/krb5/krb/fast.c
|
||||
index 62c9f0841..ee2e08189 100644
|
||||
--- a/src/lib/krb5/krb/fast.c
|
||||
+++ b/src/lib/krb5/krb/fast.c
|
||||
@@ -168,6 +168,109 @@ krb5int_fast_prep_req_body(krb5_context context,
|
||||
return retval;
|
||||
}
|
||||
|
||||
+static krb5_boolean
|
||||
+fast_is_pkinit_allowed(krb5_context context, krb5_data *realm)
|
||||
+{
|
||||
+ int value;
|
||||
+ krb5_error_code retval = EINVAL;
|
||||
+ char realmstr[1024];
|
||||
+ const char *option = "auto_fast_armor";
|
||||
+ const int def_value = FALSE;
|
||||
+
|
||||
+ if (realm != NULL && realm->length > sizeof(realmstr)-1)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (realm != NULL) {
|
||||
+ strncpy(realmstr, realm->data, realm->length);
|
||||
+ realmstr[realm->length] = '\0';
|
||||
+
|
||||
+ retval = profile_get_boolean(context->profile,
|
||||
+ KRB5_CONF_REALMS, realmstr,
|
||||
+ option, def_value, &value);
|
||||
+ }
|
||||
+
|
||||
+ return retval ? FALSE : value;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+fast_acquire_pkinit_armor(krb5_context context,
|
||||
+ struct krb5int_fast_request_state *state,
|
||||
+ krb5_get_init_creds_opt *opt, krb5_kdc_req *request)
|
||||
+{
|
||||
+ krb5_context ctx;
|
||||
+ krb5_get_init_creds_opt *options = NULL;
|
||||
+ krb5_error_code retval = 0;
|
||||
+ krb5_data *target_realm = &request->server->realm;
|
||||
+ krb5_creds creds;
|
||||
+ krb5_principal anon_princ = NULL;
|
||||
+ krb5_ccache out_cc;
|
||||
+
|
||||
+ /* short circuit, we are asked to perform Anonymous PKINIT already */
|
||||
+ if (opt->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* skip realms which do not allow use of automated FAST armor */
|
||||
+ if (!fast_is_pkinit_allowed(context, target_realm)) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ retval = krb5_init_context(&ctx);
|
||||
+ if (retval != 0) {
|
||||
+ return retval;
|
||||
+ }
|
||||
+ retval = krb5_get_init_creds_opt_alloc(ctx, &options);
|
||||
+ if (retval != 0) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ krb5_get_init_creds_opt_set_anonymous(options, 1);
|
||||
+ retval = krb5_cc_new_unique(ctx, "MEMORY", NULL, &out_cc);
|
||||
+ if (retval != 0) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ retval = krb5_get_init_creds_opt_set_out_ccache(ctx, options, out_cc);
|
||||
+ if (retval != 0) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ retval = krb5_build_principal_ext(ctx, &anon_princ,
|
||||
+ target_realm->length, target_realm->data,
|
||||
+ strlen(KRB5_WELLKNOWN_NAMESTR),
|
||||
+ KRB5_WELLKNOWN_NAMESTR,
|
||||
+ strlen(KRB5_ANONYMOUS_PRINCSTR),
|
||||
+ KRB5_ANONYMOUS_PRINCSTR, 0);
|
||||
+ if (retval != 0) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ retval = krb5_get_init_creds_password(ctx, &creds, anon_princ, 0,
|
||||
+ NULL /* no prompter */, NULL,
|
||||
+ 0, NULL /* service name */,
|
||||
+ options);
|
||||
+ if (retval == 0) {
|
||||
+ state->fast_state_flags |= KRB5INT_FAST_OWN_ARMOR;
|
||||
+ state->armor_ccache = out_cc;
|
||||
+ }
|
||||
+cleanup:
|
||||
+ if (retval != 0 && out_cc != NULL) {
|
||||
+ (void) krb5_cc_destroy(ctx, out_cc);
|
||||
+ }
|
||||
+ if (retval == 0) {
|
||||
+ krb5_free_cred_contents(ctx, &creds);
|
||||
+ }
|
||||
+ if (options != NULL) {
|
||||
+ krb5_get_init_creds_opt_free(ctx, options);
|
||||
+ }
|
||||
+ if (anon_princ != NULL) {
|
||||
+ krb5_free_principal(ctx, anon_princ);
|
||||
+ }
|
||||
+ krb5_free_context(ctx);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
krb5_error_code
|
||||
krb5int_fast_as_armor(krb5_context context,
|
||||
struct krb5int_fast_request_state *state,
|
||||
@@ -178,10 +281,20 @@ krb5int_fast_as_armor(krb5_context context,
|
||||
krb5_principal target_principal = NULL;
|
||||
krb5_data *target_realm;
|
||||
const char *ccname = k5_gic_opt_get_fast_ccache_name(opt);
|
||||
+ char *fast_ccname = NULL;
|
||||
krb5_flags fast_flags;
|
||||
|
||||
krb5_clear_error_message(context);
|
||||
target_realm = &request->server->realm;
|
||||
+ if (ccname == NULL) {
|
||||
+ retval = fast_acquire_pkinit_armor(context, state, opt, request);
|
||||
+ if (retval == 0) {
|
||||
+ retval = krb5_cc_get_full_name(context, state->armor_ccache, &fast_ccname);
|
||||
+ if (retval == 0 && fast_ccname != NULL)
|
||||
+ ccname = fast_ccname;
|
||||
+ }
|
||||
+ retval = 0;
|
||||
+ }
|
||||
if (ccname != NULL) {
|
||||
TRACE_FAST_ARMOR_CCACHE(context, ccname);
|
||||
state->fast_state_flags |= KRB5INT_FAST_ARMOR_AVAIL;
|
||||
@@ -220,6 +333,8 @@ krb5int_fast_as_armor(krb5_context context,
|
||||
krb5_cc_close(context, ccache);
|
||||
if (target_principal)
|
||||
krb5_free_principal(context, target_principal);
|
||||
+ if (fast_ccname)
|
||||
+ free(fast_ccname);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -615,6 +730,9 @@ krb5int_fast_free_state(krb5_context context,
|
||||
/*We are responsible for none of the store in the fast_outer_req*/
|
||||
krb5_free_keyblock(context, state->armor_key);
|
||||
krb5_free_fast_armor(context, state->armor);
|
||||
+ if (state->fast_state_flags & KRB5INT_FAST_OWN_ARMOR) {
|
||||
+ krb5_cc_destroy(context, state->armor_ccache);
|
||||
+ }
|
||||
free(state);
|
||||
}
|
||||
|
||||
diff --git a/src/lib/krb5/krb/fast.h b/src/lib/krb5/krb/fast.h
|
||||
index 7156ea203..e5fe8bd54 100644
|
||||
--- a/src/lib/krb5/krb/fast.h
|
||||
+++ b/src/lib/krb5/krb/fast.h
|
||||
@@ -34,6 +34,7 @@ struct krb5int_fast_request_state {
|
||||
krb5_kdc_req fast_outer_request;
|
||||
krb5_keyblock *armor_key; /*non-null means fast is in use*/
|
||||
krb5_fast_armor *armor;
|
||||
+ krb5_ccache armor_ccache;
|
||||
krb5_ui_4 fast_state_flags;
|
||||
krb5_ui_4 fast_options;
|
||||
krb5_int32 nonce;
|
||||
@@ -41,6 +42,7 @@ struct krb5int_fast_request_state {
|
||||
|
||||
#define KRB5INT_FAST_DO_FAST (1l<<0) /* Perform FAST */
|
||||
#define KRB5INT_FAST_ARMOR_AVAIL (1l<<1)
|
||||
+#define KRB5INT_FAST_OWN_ARMOR (1l<<2)
|
||||
|
||||
krb5_error_code
|
||||
krb5int_fast_prep_req_body(krb5_context context,
|
||||
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
|
||||
index d4caa2bd3..ac7649647 100644
|
||||
--- a/src/man/krb5.conf.man
|
||||
+++ b/src/man/krb5.conf.man
|
||||
@@ -650,6 +650,19 @@ primary KDC, in case the user\(aqs password has just been changed, and
|
||||
the updated database has not been propagated to the replica
|
||||
servers yet. New in release 1.19.
|
||||
.TP
|
||||
+\fBauto_fast_armor\fP
|
||||
+If this flag is true, then initial ticket request will use Anonymous
|
||||
+PKINIT to protect the communication as a FAST channel in case an application
|
||||
+did not provide its own FAST channel. This is useful for deployments where
|
||||
+pre-authentication methods require use of the FAST channel, such as
|
||||
+passwordless methods provided by FreeIPA. Microsoft Active Directory
|
||||
+implementation of PKINIT does not support Anonymous PKINIT feature.
|
||||
+As a result, \fIauto_fast_armor\fP defaults to false.
|
||||
+.sp
|
||||
+Use of \fIauto_fast_armor = true\fP requires properly configured PKINIT and
|
||||
+WELLKNOWN/ANONYMOUS principal defined on the KDC side. Consult KDC documentation
|
||||
+for details.
|
||||
+.TP
|
||||
\fBv4_instance_convert\fP
|
||||
This subsection allows the administrator to configure exceptions
|
||||
to the \fBdefault_domain\fP mapping rule. It contains V4 instances
|
||||
--
|
||||
2.51.0
|
||||
|
||||
40
0041-bail-if-prompter-is-not-specified-but-required.patch
Normal file
40
0041-bail-if-prompter-is-not-specified-but-required.patch
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
From ff580d9cf86202d45454a6b6f53accc22cb40b62 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Sun, 19 Oct 2025 18:14:29 +0300
|
||||
Subject: [PATCH] bail if prompter is not specified but required
|
||||
|
||||
GSSAPI gss_init_sec_context() may trigger credential re-initialization
|
||||
if the cred in ccache is expired. If automatic FAST armor is in use,
|
||||
we'd request Anonymous PKINIT and use it as an armor and this will
|
||||
enable seeing pre-authentication methods which require armor presence.
|
||||
|
||||
OTP is one of such methods and its use requires prompter to be set,
|
||||
but GSSAPI cannot specify a prompter and thus we should fail any
|
||||
pre-auth where a prompter wasn't passed.
|
||||
|
||||
PKINIT PKCS11 and SAM-2 preauth methods use KRB5_LIBOS_CANTREADPWD while PKINIT
|
||||
and gic_pwd.c use EIO. Use EIO here because we technically attempt to read a
|
||||
PIN rather than a password.
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
src/lib/krb5/krb/preauth_otp.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/lib/krb5/krb/preauth_otp.c b/src/lib/krb5/krb/preauth_otp.c
|
||||
index 07ffc15c2..48003da62 100644
|
||||
--- a/src/lib/krb5/krb/preauth_otp.c
|
||||
+++ b/src/lib/krb5/krb/preauth_otp.c
|
||||
@@ -479,6 +479,9 @@ doprompt(krb5_context context, krb5_prompter_fct prompter, void *prompter_data,
|
||||
krb5_error_code retval;
|
||||
krb5_prompt_type prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
|
||||
|
||||
+ if (prompter == NULL)
|
||||
+ return EIO;
|
||||
+
|
||||
if (prompttxt == NULL || out == NULL)
|
||||
return EINVAL;
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
|
|
@ -1,419 +0,0 @@
|
|||
From 6d36ea6fcfe281a8ce73fc5aa5c133f435d93fa4 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Fri, 20 Mar 2020 00:17:28 +0100
|
||||
Subject: [PATCH] Add channel bindings tests
|
||||
|
||||
[ghudson@mit.edu: adjusted test program to output channel-bound state
|
||||
instead of optionally enforcing it; adjusted tests to check program
|
||||
output; split out tests into separate Python script; made cosmetic
|
||||
changes]
|
||||
|
||||
ticket: 8900
|
||||
(cherry picked from commit b0b21b6d25b06f3e2b365dfe9dd4c99b3d43bf57)
|
||||
[rharwood@redhat.com: .gitignore]
|
||||
---
|
||||
src/plugins/gssapi/negoextest/main.c | 18 +++++
|
||||
src/tests/gssapi/Makefile.in | 49 ++++++------
|
||||
src/tests/gssapi/common.c | 25 ++++--
|
||||
src/tests/gssapi/common.h | 9 +++
|
||||
src/tests/gssapi/deps | 4 +
|
||||
src/tests/gssapi/t_bindings.c | 111 +++++++++++++++++++++++++++
|
||||
src/tests/gssapi/t_bindings.py | 43 +++++++++++
|
||||
src/tests/gssapi/t_negoex.py | 7 ++
|
||||
8 files changed, 237 insertions(+), 29 deletions(-)
|
||||
create mode 100644 src/tests/gssapi/t_bindings.c
|
||||
create mode 100644 src/tests/gssapi/t_bindings.py
|
||||
|
||||
diff --git a/src/plugins/gssapi/negoextest/main.c b/src/plugins/gssapi/negoextest/main.c
|
||||
index 6c340f41b..72fc5273a 100644
|
||||
--- a/src/plugins/gssapi/negoextest/main.c
|
||||
+++ b/src/plugins/gssapi/negoextest/main.c
|
||||
@@ -57,6 +57,15 @@ gss_init_sec_context(OM_uint32 *minor_status,
|
||||
const char *envstr;
|
||||
uint8_t hops, mech_last_octet;
|
||||
|
||||
+ envstr = getenv("GSS_INIT_BINDING");
|
||||
+ if (envstr != NULL) {
|
||||
+ assert(strlen(envstr) > 0);
|
||||
+ assert(input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS);
|
||||
+ assert(strlen(envstr) == input_chan_bindings->application_data.length);
|
||||
+ assert(strcmp((char *)input_chan_bindings->application_data.value,
|
||||
+ envstr) == 0);
|
||||
+ }
|
||||
+
|
||||
if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
|
||||
envstr = getenv("HOPS");
|
||||
hops = (envstr != NULL) ? atoi(envstr) : 1;
|
||||
@@ -112,6 +121,15 @@ gss_accept_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle,
|
||||
uint8_t hops, mech_last_octet;
|
||||
const char *envstr;
|
||||
|
||||
+ envstr = getenv("GSS_ACCEPT_BINDING");
|
||||
+ if (envstr != NULL) {
|
||||
+ assert(strlen(envstr) > 0);
|
||||
+ assert(input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS);
|
||||
+ assert(strlen(envstr) == input_chan_bindings->application_data.length);
|
||||
+ assert(strcmp((char *)input_chan_bindings->application_data.value,
|
||||
+ envstr) == 0);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* The unwrapped token sits at the end and is just one byte giving the
|
||||
* remaining number of hops. The final octet of the mech encoding should
|
||||
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
|
||||
index 5cc1e0f58..68c132b79 100644
|
||||
--- a/src/tests/gssapi/Makefile.in
|
||||
+++ b/src/tests/gssapi/Makefile.in
|
||||
@@ -9,33 +9,33 @@ LOCALINCLUDES = -I$(srcdir)/../../lib/gssapi/mechglue \
|
||||
-I../../lib/gssapi/generic
|
||||
|
||||
SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
|
||||
- $(srcdir)/t_accname.c $(srcdir)/t_add_cred.c $(srcdir)/t_ccselect.c \
|
||||
- $(srcdir)/t_ciflags.c $(srcdir)/t_context.c $(srcdir)/t_credstore.c \
|
||||
- $(srcdir)/t_enctypes.c $(srcdir)/t_err.c $(srcdir)/t_export_cred.c \
|
||||
- $(srcdir)/t_export_name.c $(srcdir)/t_gssexts.c \
|
||||
- $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c $(srcdir)/t_invalid.c \
|
||||
- $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \
|
||||
+ $(srcdir)/t_accname.c $(srcdir)/t_add_cred.c $(srcdir)/t_bindings.c \
|
||||
+ $(srcdir)/t_ccselect.c $(srcdir)/t_ciflags.c $(srcdir)/t_context.c \
|
||||
+ $(srcdir)/t_credstore.c $(srcdir)/t_enctypes.c $(srcdir)/t_err.c \
|
||||
+ $(srcdir)/t_export_cred.c $(srcdir)/t_export_name.c \
|
||||
+ $(srcdir)/t_gssexts.c $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c \
|
||||
+ $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \
|
||||
$(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
|
||||
$(srcdir)/t_lifetime.c $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c \
|
||||
$(srcdir)/t_pcontok.c $(srcdir)/t_prf.c $(srcdir)/t_s4u.c \
|
||||
$(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \
|
||||
$(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c
|
||||
|
||||
-OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_add_cred.o t_ccselect.o \
|
||||
- t_ciflags.o t_context.o t_credstore.o t_enctypes.o t_err.o \
|
||||
- t_export_cred.o t_export_name.o t_gssexts.o t_imp_cred.o t_imp_name.o \
|
||||
- t_invalid.o t_inq_cred.o t_inq_ctx.o t_inq_mechs_name.o t_iov.o \
|
||||
- t_lifetime.o t_namingexts.o t_oid.o t_pcontok.o t_prf.o t_s4u.o \
|
||||
- t_s4u2proxy_krb5.o t_saslname.o t_spnego.o t_srcattrs.o
|
||||
+OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_add_cred.o t_bindings.o \
|
||||
+ t_ccselect.o t_ciflags.o t_context.o t_credstore.o t_enctypes.o \
|
||||
+ t_err.o t_export_cred.o t_export_name.o t_gssexts.o t_imp_cred.o \
|
||||
+ t_imp_name.o t_invalid.o t_inq_cred.o t_inq_ctx.o t_inq_mechs_name.o \
|
||||
+ t_iov.o t_lifetime.o t_namingexts.o t_oid.o t_pcontok.o t_prf.o \
|
||||
+ t_s4u.o t_s4u2proxy_krb5.o t_saslname.o t_spnego.o t_srcattrs.o
|
||||
|
||||
COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
|
||||
COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
|
||||
|
||||
-all: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags t_context \
|
||||
- t_credstore t_enctypes t_err t_export_cred t_export_name t_gssexts \
|
||||
- t_imp_cred t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name \
|
||||
- t_iov t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u \
|
||||
- t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs
|
||||
+all: ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect t_ciflags \
|
||||
+ t_context t_credstore t_enctypes t_err t_export_cred t_export_name \
|
||||
+ t_gssexts t_imp_cred t_imp_name t_invalid t_inq_cred t_inq_ctx \
|
||||
+ t_inq_mechs_name t_iov t_lifetime t_namingexts t_oid t_pcontok t_prf \
|
||||
+ t_s4u t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs
|
||||
|
||||
check-unix: t_oid
|
||||
$(RUN_TEST) ./t_invalid
|
||||
@@ -43,11 +43,12 @@ check-unix: t_oid
|
||||
$(RUN_TEST) ./t_prf
|
||||
$(RUN_TEST) ./t_imp_name
|
||||
|
||||
-check-pytests: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags \
|
||||
- t_context t_credstore t_enctypes t_err t_export_cred t_export_name \
|
||||
- t_imp_cred t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime \
|
||||
- t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego t_srcattrs
|
||||
+check-pytests: ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect \
|
||||
+ t_ciflags t_context t_credstore t_enctypes t_err t_export_cred \
|
||||
+ t_export_name t_imp_cred t_inq_cred t_inq_ctx t_inq_mechs_name t_iov \
|
||||
+ t_lifetime t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego t_srcattrs
|
||||
$(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS)
|
||||
+ $(RUNPYTEST) $(srcdir)/t_bindings.py $(PYTESTFLAGS)
|
||||
$(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS)
|
||||
$(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS)
|
||||
$(RUNPYTEST) $(srcdir)/t_enctypes.py $(PYTESTFLAGS)
|
||||
@@ -64,6 +65,8 @@ t_accname: t_accname.o $(COMMON_DEPS)
|
||||
$(CC_LINK) -o $@ t_accname.o $(COMMON_LIBS)
|
||||
t_add_cred: t_add_cred.o $(COMMON_DEPS)
|
||||
$(CC_LINK) -o $@ t_add_cred.o $(COMMON_LIBS)
|
||||
+t_bindings: t_bindings.o $(COMMON_DEPS)
|
||||
+ $(CC_LINK) -o $@ t_bindings.o $(COMMON_LIBS)
|
||||
t_ccselect: t_ccselect.o $(COMMON_DEPS)
|
||||
$(CC_LINK) -o $@ t_ccselect.o $(COMMON_LIBS)
|
||||
t_ciflags: t_ciflags.o $(COMMON_DEPS)
|
||||
@@ -118,8 +121,8 @@ t_srcattrs: t_srcattrs.o $(COMMON_DEPS)
|
||||
$(CC_LINK) -o $@ t_srcattrs.o $(COMMON_LIBS)
|
||||
|
||||
clean:
|
||||
- $(RM) ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags
|
||||
- $(RM) t_context t_credstore t_enctypes t_err t_export_cred
|
||||
+ $(RM) ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect
|
||||
+ $(RM) t_ciflags t_context t_credstore t_enctypes t_err t_export_cred
|
||||
$(RM) t_export_name t_gssexts t_imp_cred t_imp_name t_invalid
|
||||
$(RM) t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime
|
||||
$(RM) t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5
|
||||
diff --git a/src/tests/gssapi/common.c b/src/tests/gssapi/common.c
|
||||
index 83e9d9bb8..7ba72f7b2 100644
|
||||
--- a/src/tests/gssapi/common.c
|
||||
+++ b/src/tests/gssapi/common.c
|
||||
@@ -115,6 +115,20 @@ establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
|
||||
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
|
||||
gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech,
|
||||
gss_cred_id_t *deleg_cred)
|
||||
+{
|
||||
+ return establish_contexts_ex(imech, icred, acred, tname, flags, ictx, actx,
|
||||
+ GSS_C_NO_CHANNEL_BINDINGS,
|
||||
+ GSS_C_NO_CHANNEL_BINDINGS, NULL, src_name,
|
||||
+ amech, deleg_cred);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+establish_contexts_ex(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
|
||||
+ gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
|
||||
+ gss_ctx_id_t *actx, gss_channel_bindings_t icb,
|
||||
+ gss_channel_bindings_t acb, OM_uint32 *aret_flags,
|
||||
+ gss_name_t *src_name, gss_OID *amech,
|
||||
+ gss_cred_id_t *deleg_cred)
|
||||
{
|
||||
OM_uint32 minor, imaj, amaj;
|
||||
gss_buffer_desc itok, atok;
|
||||
@@ -126,17 +140,16 @@ establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
|
||||
for (;;) {
|
||||
(void)gss_release_buffer(&minor, &itok);
|
||||
imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags,
|
||||
- GSS_C_INDEFINITE,
|
||||
- GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL,
|
||||
- &itok, NULL, NULL);
|
||||
+ GSS_C_INDEFINITE, icb, &atok, NULL, &itok,
|
||||
+ NULL, NULL);
|
||||
check_gsserr("gss_init_sec_context", imaj, minor);
|
||||
if (amaj == GSS_S_COMPLETE)
|
||||
break;
|
||||
|
||||
(void)gss_release_buffer(&minor, &atok);
|
||||
- amaj = gss_accept_sec_context(&minor, actx, acred, &itok,
|
||||
- GSS_C_NO_CHANNEL_BINDINGS, src_name,
|
||||
- amech, &atok, NULL, NULL, deleg_cred);
|
||||
+ amaj = gss_accept_sec_context(&minor, actx, acred, &itok, acb,
|
||||
+ src_name, amech, &atok, aret_flags, NULL,
|
||||
+ deleg_cred);
|
||||
check_gsserr("gss_accept_sec_context", amaj, minor);
|
||||
(void)gss_release_buffer(&minor, &itok);
|
||||
if (imaj == GSS_S_COMPLETE)
|
||||
diff --git a/src/tests/gssapi/common.h b/src/tests/gssapi/common.h
|
||||
index ae11b51d4..a5c8f87e6 100644
|
||||
--- a/src/tests/gssapi/common.h
|
||||
+++ b/src/tests/gssapi/common.h
|
||||
@@ -62,6 +62,15 @@ void establish_contexts(gss_OID imech, gss_cred_id_t icred,
|
||||
gss_name_t *src_name, gss_OID *amech,
|
||||
gss_cred_id_t *deleg_cred);
|
||||
|
||||
+/* Establish contexts with channel bindings. */
|
||||
+void establish_contexts_ex(gss_OID imech, gss_cred_id_t icred,
|
||||
+ gss_cred_id_t acred, gss_name_t tname,
|
||||
+ OM_uint32 flags, gss_ctx_id_t *ictx,
|
||||
+ gss_ctx_id_t *actx, gss_channel_bindings_t icb,
|
||||
+ gss_channel_bindings_t acb, OM_uint32 *aret_flags,
|
||||
+ gss_name_t *src_name, gss_OID *amech,
|
||||
+ gss_cred_id_t *deleg_cred);
|
||||
+
|
||||
/* Export *cred to a token, then release *cred and replace it by re-importing
|
||||
* the token. */
|
||||
void export_import_cred(gss_cred_id_t *cred);
|
||||
diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps
|
||||
index acd0e96f8..73e4d9a74 100644
|
||||
--- a/src/tests/gssapi/deps
|
||||
+++ b/src/tests/gssapi/deps
|
||||
@@ -33,6 +33,10 @@ $(OUTPRE)t_add_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
|
||||
$(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
|
||||
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
|
||||
common.h t_add_cred.c
|
||||
+$(OUTPRE)t_bindings.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
|
||||
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
|
||||
+ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
|
||||
+ common.h t_bindings.c
|
||||
$(OUTPRE)t_ccselect.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
|
||||
$(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
|
||||
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
|
||||
diff --git a/src/tests/gssapi/t_bindings.c b/src/tests/gssapi/t_bindings.c
|
||||
new file mode 100644
|
||||
index 000000000..e8906715b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/gssapi/t_bindings.c
|
||||
@@ -0,0 +1,111 @@
|
||||
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
+/*
|
||||
+ * Copyright (C) 2020 by Red Hat, Inc.
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ *
|
||||
+ * * Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ *
|
||||
+ * * Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in
|
||||
+ * the documentation and/or other materials provided with the
|
||||
+ * distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include "common.h"
|
||||
+
|
||||
+/*
|
||||
+ * Establish contexts (without and with GSS_C_DCE_STYLE) with the default
|
||||
+ * initiator name, a specified principal name as target name, initiator
|
||||
+ * bindings, and acceptor bindings. If any call is unsuccessful, display an
|
||||
+ * error message. Output "yes" or "no" to indicate whether the contexts were
|
||||
+ * reported as channel-bound on the acceptor. Exit with status 0 if all
|
||||
+ * operations are successful, or 1 if not.
|
||||
+ *
|
||||
+ * Usage: ./t_bindings [-s] targetname icb acb
|
||||
+ *
|
||||
+ * An icb or abc value of "-" will not specify channel bindings.
|
||||
+ */
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[])
|
||||
+{
|
||||
+ OM_uint32 minor, flags1, flags2;
|
||||
+ gss_name_t target_name;
|
||||
+ gss_ctx_id_t ictx, actx;
|
||||
+ struct gss_channel_bindings_struct icb_data = {0}, acb_data = {0};
|
||||
+ gss_channel_bindings_t icb = GSS_C_NO_CHANNEL_BINDINGS;
|
||||
+ gss_channel_bindings_t acb = GSS_C_NO_CHANNEL_BINDINGS;
|
||||
+ gss_OID_desc *mech;
|
||||
+
|
||||
+ argv++;
|
||||
+ argc--;
|
||||
+ if (*argv != NULL && strcmp(*argv, "-s") == 0) {
|
||||
+ mech = &mech_spnego;
|
||||
+ argv++;
|
||||
+ argc--;
|
||||
+ } else {
|
||||
+ mech = &mech_krb5;
|
||||
+ }
|
||||
+
|
||||
+ if (argc != 3) {
|
||||
+ fprintf(stderr, "Usage: t_bindings [-s] targetname icb acb\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ target_name = import_name(argv[0]);
|
||||
+
|
||||
+ if (strcmp(argv[1], "-") != 0) {
|
||||
+ icb_data.application_data.length = strlen(argv[1]);
|
||||
+ icb_data.application_data.value = argv[1];
|
||||
+ icb = &icb_data;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp(argv[2], "-") != 0) {
|
||||
+ acb_data.application_data.length = strlen(argv[2]);
|
||||
+ acb_data.application_data.value = argv[2];
|
||||
+ acb = &acb_data;
|
||||
+ }
|
||||
+
|
||||
+ establish_contexts_ex(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
|
||||
+ target_name, 0, &ictx, &actx, icb, acb, &flags1,
|
||||
+ NULL, NULL, NULL);
|
||||
+
|
||||
+ /* Try again with GSS_C_DCE_STYLE */
|
||||
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
|
||||
+ (void)gss_delete_sec_context(&minor, &actx, NULL);
|
||||
+
|
||||
+ establish_contexts_ex(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
|
||||
+ target_name, GSS_C_DCE_STYLE, &ictx, &actx, icb, acb,
|
||||
+ &flags2, NULL, NULL, NULL);
|
||||
+ assert((flags1 & GSS_C_CHANNEL_BOUND_FLAG) ==
|
||||
+ (flags2 & GSS_C_CHANNEL_BOUND_FLAG));
|
||||
+ printf("%s\n", (flags1 & GSS_C_CHANNEL_BOUND_FLAG) ? "yes" : "no");
|
||||
+
|
||||
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
|
||||
+ (void)gss_delete_sec_context(&minor, &actx, NULL);
|
||||
+ (void)gss_release_name(&minor, &target_name);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/tests/gssapi/t_bindings.py b/src/tests/gssapi/t_bindings.py
|
||||
new file mode 100644
|
||||
index 000000000..f377977b6
|
||||
--- /dev/null
|
||||
+++ b/src/tests/gssapi/t_bindings.py
|
||||
@@ -0,0 +1,43 @@
|
||||
+from k5test import *
|
||||
+
|
||||
+realm = K5Realm()
|
||||
+server = 'p:' + realm.host_princ
|
||||
+
|
||||
+mark('krb5 channel bindings')
|
||||
+realm.run(['./t_bindings', server, '-', '-'], expected_msg='no')
|
||||
+realm.run(['./t_bindings', server, 'a', '-'], expected_msg='no')
|
||||
+realm.run(['./t_bindings', server, 'a', 'a'], expected_msg='yes')
|
||||
+realm.run(['./t_bindings', server, '-', 'a'], expected_msg='no')
|
||||
+realm.run(['./t_bindings', server, 'a', 'x'],
|
||||
+ expected_code=1, expected_msg='Incorrect channel bindings')
|
||||
+
|
||||
+mark('SPNEGO channel bindings')
|
||||
+realm.run(['./t_bindings', '-s', server, '-', '-'], expected_msg='no')
|
||||
+realm.run(['./t_bindings', '-s', server, 'a', '-'], expected_msg='no')
|
||||
+realm.run(['./t_bindings', '-s', server, 'a', 'a'], expected_msg='yes')
|
||||
+realm.run(['./t_bindings', '-s', server, '-', 'a'], expected_msg='no')
|
||||
+realm.run(['./t_bindings', '-s', server, 'a', 'x'],
|
||||
+ expected_code=1, expected_msg='Incorrect channel bindings')
|
||||
+
|
||||
+client_aware_conf = {'libdefaults': {'client_aware_channel_bindings': 'true'}}
|
||||
+e = realm.special_env('cb_aware', False, krb5_conf=client_aware_conf)
|
||||
+
|
||||
+mark('krb5 client_aware_channel_bindings')
|
||||
+realm.run(['./t_bindings', server, '-', '-'], env=e, expected_msg='no')
|
||||
+realm.run(['./t_bindings', server, 'a', '-'], env=e, expected_msg='no')
|
||||
+realm.run(['./t_bindings', server, 'a', 'a'], env=e, expected_msg='yes')
|
||||
+realm.run(['./t_bindings', server, '-', 'a'], env=e,
|
||||
+ expected_code=1, expected_msg='Incorrect channel bindings')
|
||||
+realm.run(['./t_bindings', server, 'a', 'x'], env=e,
|
||||
+ expected_code=1, expected_msg='Incorrect channel bindings')
|
||||
+
|
||||
+mark('SPNEGO client_aware_channel_bindings')
|
||||
+realm.run(['./t_bindings', '-s', server, '-', '-'], env=e, expected_msg='no')
|
||||
+realm.run(['./t_bindings', '-s', server, 'a', '-'], env=e, expected_msg='no')
|
||||
+realm.run(['./t_bindings', '-s', server, 'a', 'a'], env=e, expected_msg='yes')
|
||||
+realm.run(['./t_bindings', '-s', server, '-', 'a'], env=e,
|
||||
+ expected_code=1, expected_msg='Incorrect channel bindings')
|
||||
+realm.run(['./t_bindings', '-s', server, 'a', 'x'], env=e,
|
||||
+ expected_code=1, expected_msg='Incorrect channel bindings')
|
||||
+
|
||||
+success('channel bindings tests')
|
||||
diff --git a/src/tests/gssapi/t_negoex.py b/src/tests/gssapi/t_negoex.py
|
||||
index 88470d2fa..a218899c4 100644
|
||||
--- a/src/tests/gssapi/t_negoex.py
|
||||
+++ b/src/tests/gssapi/t_negoex.py
|
||||
@@ -139,4 +139,11 @@ msgs = ('sending [3]AP_REQUEST', 'sending [7]CHALLENGE', 'sending [8]VERIFY',
|
||||
'sending [11]CHALLENGE', 'sending [12]VERIFY', 'sending [13]VERIFY')
|
||||
test({'HOPS': '4', 'KEY': 'accept-always'}, expected_trace=())
|
||||
|
||||
+mark('channel bindings')
|
||||
+e = realm.env.copy()
|
||||
+e.update({'HOPS': '1', 'GSS_INIT_BINDING': 'a', 'GSS_ACCEPT_BINDING': 'b'})
|
||||
+# The test mech will verify that the bindings are communicated to the
|
||||
+# mech, but does not set the channel-bound flag.
|
||||
+realm.run(['./t_bindings', '-s', 'h:host', 'a', 'b'], env=e, expected_msg='no')
|
||||
+
|
||||
success('NegoEx tests')
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
From 46ec975eb8f33b6d42c440758fc0deb826f87313 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Tue, 10 Mar 2020 13:13:17 +0100
|
||||
Subject: [PATCH] Add client_aware_channel_bindings option
|
||||
|
||||
Add client support for KERB_AP_OPTIONS_CBT in the form of a profile
|
||||
option "client_aware_gss_bindings". Adjust the make_etype_list()
|
||||
helper so that enctype negotiation and AP_OPTIONS can be included in
|
||||
the same IF-RELEVANT wrapper.
|
||||
|
||||
[ghudson@mit.edu: refactored; edited documentation; wrote commit
|
||||
message]
|
||||
|
||||
ticket: 8900
|
||||
(cherry picked from commit 225e6ef7f021cd1a8ef2a054af0ca58b7288fd81)
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 6 +
|
||||
src/include/k5-int.h | 1 +
|
||||
src/lib/krb5/krb/mk_req_ext.c | 177 +++++++++++++++--------------
|
||||
3 files changed, 98 insertions(+), 86 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index 38f450367..da5ad00f2 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -388,6 +388,12 @@ The libdefaults section may contain any of the following relations:
|
||||
credentials will fail if the client machine does not have a
|
||||
keytab. The default value is false.
|
||||
|
||||
+**client_aware_channel_bindings**
|
||||
+ If this flag is true, then all application protocol authentication
|
||||
+ requests will be flagged to indicate that the application supports
|
||||
+ channel bindings when operating over a secure channel. The
|
||||
+ default value is false.
|
||||
+
|
||||
.. _realms:
|
||||
|
||||
[realms]
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index 0d9af3d95..eb18a4cd6 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -299,6 +299,7 @@ typedef unsigned char u_char;
|
||||
#define KRB5_CONF_V4_INSTANCE_CONVERT "v4_instance_convert"
|
||||
#define KRB5_CONF_V4_REALM "v4_realm"
|
||||
#define KRB5_CONF_VERIFY_AP_REQ_NOFAIL "verify_ap_req_nofail"
|
||||
+#define KRB5_CONF_CLIENT_AWARE_GSS_BINDINGS "client_aware_channel_bindings"
|
||||
|
||||
/* Cache configuration variables */
|
||||
#define KRB5_CC_CONF_FAST_AVAIL "fast_avail"
|
||||
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
|
||||
index 9fc6a0e52..08504860c 100644
|
||||
--- a/src/lib/krb5/krb/mk_req_ext.c
|
||||
+++ b/src/lib/krb5/krb/mk_req_ext.c
|
||||
@@ -68,10 +68,9 @@
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
-make_etype_list(krb5_context context,
|
||||
- krb5_enctype *desired_etypes,
|
||||
- krb5_enctype tkt_enctype,
|
||||
- krb5_authdata ***authdata);
|
||||
+make_ap_authdata(krb5_context context, krb5_enctype *desired_enctypes,
|
||||
+ krb5_enctype tkt_enctype, krb5_boolean client_aware_cb,
|
||||
+ krb5_authdata ***authdata_out);
|
||||
|
||||
static krb5_error_code
|
||||
generate_authenticator(krb5_context,
|
||||
@@ -263,7 +262,8 @@ generate_authenticator(krb5_context context, krb5_authenticator *authent,
|
||||
krb5_enctype tkt_enctype)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
- krb5_authdata **ext_authdata = NULL;
|
||||
+ krb5_authdata **ext_authdata = NULL, **ap_authdata, **combined;
|
||||
+ int client_aware_cb;
|
||||
|
||||
authent->client = client;
|
||||
authent->checksum = cksum;
|
||||
@@ -297,99 +297,104 @@ generate_authenticator(krb5_context context, krb5_authenticator *authent,
|
||||
krb5_free_authdata(context, ext_authdata);
|
||||
}
|
||||
|
||||
- /* Only send EtypeList if we prefer another enctype to tkt_enctype */
|
||||
- if (desired_etypes != NULL && desired_etypes[0] != tkt_enctype) {
|
||||
- TRACE_MK_REQ_ETYPES(context, desired_etypes);
|
||||
- retval = make_etype_list(context, desired_etypes, tkt_enctype,
|
||||
- &authent->authorization_data);
|
||||
+ retval = profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS,
|
||||
+ KRB5_CONF_CLIENT_AWARE_GSS_BINDINGS, NULL,
|
||||
+ FALSE, &client_aware_cb);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ /* Add etype negotiation or channel-binding awareness authdata to the
|
||||
+ * front, if appropriate. */
|
||||
+ retval = make_ap_authdata(context, desired_etypes, tkt_enctype,
|
||||
+ client_aware_cb, &ap_authdata);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+ if (ap_authdata != NULL) {
|
||||
+ retval = krb5_merge_authdata(context, ap_authdata,
|
||||
+ authent->authorization_data, &combined);
|
||||
+ krb5_free_authdata(context, ap_authdata);
|
||||
if (retval)
|
||||
return retval;
|
||||
+ krb5_free_authdata(context, authent->authorization_data);
|
||||
+ authent->authorization_data = combined;
|
||||
}
|
||||
|
||||
return(krb5_us_timeofday(context, &authent->ctime, &authent->cusec));
|
||||
}
|
||||
|
||||
-/* RFC 4537 */
|
||||
+/* Set *out to a DER-encoded RFC 4537 etype list, or to NULL if no etype list
|
||||
+ * should be sent. */
|
||||
static krb5_error_code
|
||||
-make_etype_list(krb5_context context,
|
||||
- krb5_enctype *desired_etypes,
|
||||
- krb5_enctype tkt_enctype,
|
||||
- krb5_authdata ***authdata)
|
||||
+make_etype_list(krb5_context context, krb5_enctype *desired_enctypes,
|
||||
+ krb5_enctype tkt_enctype, krb5_data **out)
|
||||
{
|
||||
- krb5_error_code code;
|
||||
- krb5_etype_list etypes;
|
||||
- krb5_data *enc_etype_list;
|
||||
- krb5_data *ad_if_relevant;
|
||||
- krb5_authdata *etype_adata[2], etype_adatum, **adata;
|
||||
- int i;
|
||||
+ krb5_etype_list etlist;
|
||||
+ int count;
|
||||
|
||||
- etypes.etypes = desired_etypes;
|
||||
+ *out = NULL;
|
||||
|
||||
- for (etypes.length = 0;
|
||||
- etypes.etypes[etypes.length] != ENCTYPE_NULL;
|
||||
- etypes.length++)
|
||||
- {
|
||||
- /*
|
||||
- * RFC 4537:
|
||||
- *
|
||||
- * If the enctype of the ticket session key is included in the enctype
|
||||
- * list sent by the client, it SHOULD be the last on the list;
|
||||
- */
|
||||
- if (etypes.length && etypes.etypes[etypes.length - 1] == tkt_enctype)
|
||||
+ /* Only send a list if we prefer another enctype to tkt_enctype. */
|
||||
+ if (desired_enctypes == NULL || desired_enctypes[0] == tkt_enctype)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Count elements of desired_etypes, stopping at tkt_enctypes if present.
|
||||
+ * (Per RFC 4537, it must be the last option if it is included.) */
|
||||
+ for (count = 0; desired_enctypes[count] != ENCTYPE_NULL; count++) {
|
||||
+ if (count > 0 && desired_enctypes[count - 1] == tkt_enctype)
|
||||
break;
|
||||
}
|
||||
|
||||
- code = encode_krb5_etype_list(&etypes, &enc_etype_list);
|
||||
- if (code) {
|
||||
- return code;
|
||||
- }
|
||||
-
|
||||
- etype_adatum.magic = KV5M_AUTHDATA;
|
||||
- etype_adatum.ad_type = KRB5_AUTHDATA_ETYPE_NEGOTIATION;
|
||||
- etype_adatum.length = enc_etype_list->length;
|
||||
- etype_adatum.contents = (krb5_octet *)enc_etype_list->data;
|
||||
-
|
||||
- etype_adata[0] = &etype_adatum;
|
||||
- etype_adata[1] = NULL;
|
||||
-
|
||||
- /* Wrap in AD-IF-RELEVANT container */
|
||||
- code = encode_krb5_authdata(etype_adata, &ad_if_relevant);
|
||||
- if (code) {
|
||||
- krb5_free_data(context, enc_etype_list);
|
||||
- return code;
|
||||
- }
|
||||
-
|
||||
- krb5_free_data(context, enc_etype_list);
|
||||
-
|
||||
- adata = *authdata;
|
||||
- if (adata == NULL) {
|
||||
- adata = (krb5_authdata **)calloc(2, sizeof(krb5_authdata *));
|
||||
- i = 0;
|
||||
- } else {
|
||||
- for (i = 0; adata[i] != NULL; i++)
|
||||
- ;
|
||||
-
|
||||
- adata = (krb5_authdata **)realloc(*authdata,
|
||||
- (i + 2) * sizeof(krb5_authdata *));
|
||||
- }
|
||||
- if (adata == NULL) {
|
||||
- krb5_free_data(context, ad_if_relevant);
|
||||
- return ENOMEM;
|
||||
- }
|
||||
- *authdata = adata;
|
||||
-
|
||||
- adata[i] = (krb5_authdata *)malloc(sizeof(krb5_authdata));
|
||||
- if (adata[i] == NULL) {
|
||||
- krb5_free_data(context, ad_if_relevant);
|
||||
- return ENOMEM;
|
||||
- }
|
||||
- adata[i]->magic = KV5M_AUTHDATA;
|
||||
- adata[i]->ad_type = KRB5_AUTHDATA_IF_RELEVANT;
|
||||
- adata[i]->length = ad_if_relevant->length;
|
||||
- adata[i]->contents = (krb5_octet *)ad_if_relevant->data;
|
||||
- free(ad_if_relevant); /* contents owned by adata[i] */
|
||||
-
|
||||
- adata[i + 1] = NULL;
|
||||
-
|
||||
- return 0;
|
||||
+ etlist.etypes = desired_enctypes;
|
||||
+ etlist.length = count;
|
||||
+ return encode_krb5_etype_list(&etlist, out);
|
||||
+}
|
||||
+
|
||||
+/* Set *authdata_out to appropriate authenticator authdata for the request,
|
||||
+ * encoded in a single AD_IF_RELEVANT element. */
|
||||
+static krb5_error_code
|
||||
+make_ap_authdata(krb5_context context, krb5_enctype *desired_enctypes,
|
||||
+ krb5_enctype tkt_enctype, krb5_boolean client_aware_cb,
|
||||
+ krb5_authdata ***authdata_out)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_authdata etypes_ad, flags_ad, *list[3];
|
||||
+ krb5_data *der_etypes = NULL;
|
||||
+ size_t count = 0;
|
||||
+ uint8_t flagbuf[4];
|
||||
+ const uint32_t KERB_AP_OPTIONS_CBT = 0x4000;
|
||||
+
|
||||
+ *authdata_out = NULL;
|
||||
+
|
||||
+ /* Include an ETYPE_NEGOTIATION element if appropriate. */
|
||||
+ ret = make_etype_list(context, desired_enctypes, tkt_enctype, &der_etypes);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ if (der_etypes != NULL) {
|
||||
+ etypes_ad.magic = KV5M_AUTHDATA;
|
||||
+ etypes_ad.ad_type = KRB5_AUTHDATA_ETYPE_NEGOTIATION;
|
||||
+ etypes_ad.length = der_etypes->length;
|
||||
+ etypes_ad.contents = (uint8_t *)der_etypes->data;
|
||||
+ list[count++] = &etypes_ad;
|
||||
+ }
|
||||
+
|
||||
+ /* Include an AP_OPTIONS element if the CBT flag is configured. */
|
||||
+ if (client_aware_cb != 0) {
|
||||
+ store_32_le(KERB_AP_OPTIONS_CBT, flagbuf);
|
||||
+ flags_ad.magic = KV5M_AUTHDATA;
|
||||
+ flags_ad.ad_type = KRB5_AUTHDATA_AP_OPTIONS;
|
||||
+ flags_ad.length = 4;
|
||||
+ flags_ad.contents = flagbuf;
|
||||
+ list[count++] = &flags_ad;
|
||||
+ }
|
||||
+
|
||||
+ if (count > 0) {
|
||||
+ list[count] = NULL;
|
||||
+ ret = krb5_encode_authdata_container(context,
|
||||
+ KRB5_AUTHDATA_IF_RELEVANT,
|
||||
+ list, authdata_out);
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ krb5_free_data(context, der_etypes);
|
||||
+ return ret;
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
From 96a36ef54aecb48b71c1ae0cc85b83ef644c3bd0 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Sasek <Jiri.Sasek@Oracle.COM>
|
||||
Date: Fri, 13 Mar 2020 19:02:58 +0100
|
||||
Subject: [PATCH] Add finalization safety check to com_err
|
||||
|
||||
If the linker erroneously runs the libkrb5 finalizer after the
|
||||
libcom_err finalizer, the consequent remove_error_table() calls could
|
||||
crash due to accessing a destroyed mutex or an invalid et_list
|
||||
pointer. Add an unsynchronized check on finalized in
|
||||
remove_error_table(), and set et_list to null in com_err_terminate()
|
||||
after destroying the list.
|
||||
|
||||
[ghudson@mit.edu: minimized code hanges; rewrote comment and commit
|
||||
message]
|
||||
|
||||
ticket: 8890 (new)
|
||||
(cherry picked from commit 9d654aa05e26bbf22f140abde3436afeff2fdf8d)
|
||||
---
|
||||
src/util/et/error_message.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/util/et/error_message.c b/src/util/et/error_message.c
|
||||
index d7069a9df..7dc02a34e 100644
|
||||
--- a/src/util/et/error_message.c
|
||||
+++ b/src/util/et/error_message.c
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
static struct et_list *et_list;
|
||||
static k5_mutex_t et_list_lock = K5_MUTEX_PARTIAL_INITIALIZER;
|
||||
-static int terminated = 0; /* for debugging shlib fini sequence errors */
|
||||
+static int terminated = 0; /* for safety and finalization debugging */
|
||||
|
||||
MAKE_INIT_FUNCTION(com_err_initialize);
|
||||
MAKE_FINI_FUNCTION(com_err_terminate);
|
||||
@@ -69,6 +69,7 @@ void com_err_terminate(void)
|
||||
enext = e->next;
|
||||
free(e);
|
||||
}
|
||||
+ et_list = NULL;
|
||||
k5_mutex_unlock(&et_list_lock);
|
||||
k5_mutex_destroy(&et_list_lock);
|
||||
terminated = 1;
|
||||
@@ -280,6 +281,10 @@ remove_error_table(const struct error_table *et)
|
||||
{
|
||||
struct et_list **ep, *e;
|
||||
|
||||
+ /* Safety check in case libraries are finalized in the wrong order. */
|
||||
+ if (terminated)
|
||||
+ return ENOENT;
|
||||
+
|
||||
if (CALL_INIT_FUNCTION(com_err_initialize))
|
||||
return 0;
|
||||
k5_mutex_lock(&et_list_lock);
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
From b7aca8b57422cdc67a2d2bff385f09646ca037bc Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Sat, 31 Oct 2020 17:07:05 -0400
|
||||
Subject: [PATCH] Add recursion limit for ASN.1 indefinite lengths
|
||||
|
||||
The libkrb5 ASN.1 decoder supports BER indefinite lengths. It
|
||||
computes the tag length using recursion; the lack of a recursion limit
|
||||
allows an attacker to overrun the stack and cause the process to
|
||||
crash. Reported by Demi Obenour.
|
||||
|
||||
CVE-2020-28196:
|
||||
|
||||
In MIT krb5 releases 1.11 and later, an unauthenticated attacker can
|
||||
cause a denial of service for any client or server to which it can
|
||||
send an ASN.1-encoded Kerberos message of sufficient length.
|
||||
|
||||
ticket: 8959 (new)
|
||||
tags: pullup
|
||||
target_version: 1.18-next
|
||||
target_version: 1.17-next
|
||||
|
||||
(cherry picked from commit 57415dda6cf04e73ffc3723be518eddfae599bfd)
|
||||
---
|
||||
src/lib/krb5/asn.1/asn1_encode.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c
|
||||
index a160cf4fe..cd6b879f7 100644
|
||||
--- a/src/lib/krb5/asn.1/asn1_encode.c
|
||||
+++ b/src/lib/krb5/asn.1/asn1_encode.c
|
||||
@@ -356,7 +356,7 @@ make_tag(asn1buf *buf, const taginfo *t, size_t len)
|
||||
static krb5_error_code
|
||||
get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
|
||||
const uint8_t **contents_out, size_t *clen_out,
|
||||
- const uint8_t **remainder_out, size_t *rlen_out)
|
||||
+ const uint8_t **remainder_out, size_t *rlen_out, int recursion)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
uint8_t o;
|
||||
@@ -394,9 +394,11 @@ get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
|
||||
/* Indefinite form (should not be present in DER, but we accept it). */
|
||||
if (tag_out->construction != CONSTRUCTED)
|
||||
return ASN1_MISMATCH_INDEF;
|
||||
+ if (recursion >= 32)
|
||||
+ return ASN1_OVERFLOW;
|
||||
p = asn1;
|
||||
while (!(len >= 2 && p[0] == 0 && p[1] == 0)) {
|
||||
- ret = get_tag(p, len, &t, &c, &clen, &p, &len);
|
||||
+ ret = get_tag(p, len, &t, &c, &clen, &p, &len, recursion + 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -613,7 +615,7 @@ split_der(asn1buf *buf, uint8_t *const *der, size_t len, taginfo *tag_out)
|
||||
const uint8_t *contents, *remainder;
|
||||
size_t clen, rlen;
|
||||
|
||||
- ret = get_tag(*der, len, tag_out, &contents, &clen, &remainder, &rlen);
|
||||
+ ret = get_tag(*der, len, tag_out, &contents, &clen, &remainder, &rlen, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (rlen != 0)
|
||||
@@ -1199,7 +1201,7 @@ decode_atype(const taginfo *t, const uint8_t *asn1, size_t len,
|
||||
const uint8_t *rem;
|
||||
size_t rlen;
|
||||
if (!tag->implicit) {
|
||||
- ret = get_tag(asn1, len, &inner_tag, &asn1, &len, &rem, &rlen);
|
||||
+ ret = get_tag(asn1, len, &inner_tag, &asn1, &len, &rem, &rlen, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Note: we don't check rlen (it should be 0). */
|
||||
@@ -1420,7 +1422,7 @@ decode_sequence(const uint8_t *asn1, size_t len, const struct seq_info *seq,
|
||||
for (i = 0; i < seq->n_fields; i++) {
|
||||
if (len == 0)
|
||||
break;
|
||||
- ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
|
||||
+ ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len, 0);
|
||||
if (ret)
|
||||
goto error;
|
||||
/*
|
||||
@@ -1478,7 +1480,7 @@ decode_sequence_of(const uint8_t *asn1, size_t len,
|
||||
*seq_out = NULL;
|
||||
*count_out = 0;
|
||||
while (len > 0) {
|
||||
- ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
|
||||
+ ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len, 0);
|
||||
if (ret)
|
||||
goto error;
|
||||
if (!check_atype_tag(elemtype, &t)) {
|
||||
@@ -1584,7 +1586,7 @@ k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a,
|
||||
|
||||
*retrep = NULL;
|
||||
ret = get_tag((uint8_t *)code->data, code->length, &t, &contents,
|
||||
- &clen, &remainder, &rlen);
|
||||
+ &clen, &remainder, &rlen, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* rlen should be 0, but we don't check it (and due to padding in
|
||||
|
|
@ -1,404 +0,0 @@
|
|||
From 538d787aa7c10894cc0426f54db0d8248efcf7c9 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 17 Jun 2020 20:48:38 -0400
|
||||
Subject: [PATCH] Add three kvno options from Heimdal kgetcred
|
||||
|
||||
Add the flags --cached-only and --no-store, which pass the
|
||||
corresponding options to krb5_get_credentials(). Add the option
|
||||
--out-cache to write the retrieved credentials to a specified output
|
||||
cache.
|
||||
|
||||
Add a Python test script for kvno command-line options, including
|
||||
tests for the new options.
|
||||
|
||||
ticket: 8917 (new)
|
||||
(cherry picked from commit 876bab8418d7dd134c9d9db812ee2118d5ad58f0)
|
||||
---
|
||||
doc/user/user_commands/kvno.rst | 13 ++++
|
||||
src/clients/kvno/Makefile.in | 3 +
|
||||
src/clients/kvno/kvno.c | 115 +++++++++++++++++++++++---------
|
||||
src/clients/kvno/t_kvno.py | 75 +++++++++++++++++++++
|
||||
src/man/kvno.man | 13 ++++
|
||||
5 files changed, 187 insertions(+), 32 deletions(-)
|
||||
create mode 100644 src/clients/kvno/t_kvno.py
|
||||
|
||||
diff --git a/doc/user/user_commands/kvno.rst b/doc/user/user_commands/kvno.rst
|
||||
index 3892f0ca5..718313576 100644
|
||||
--- a/doc/user/user_commands/kvno.rst
|
||||
+++ b/doc/user/user_commands/kvno.rst
|
||||
@@ -74,6 +74,19 @@ OPTIONS
|
||||
client principal with the X.509 certificate in *cert_file*. The
|
||||
certificate file must be in PEM format.
|
||||
|
||||
+**--cached-only**
|
||||
+ Only retrieve credentials already present in the cache, not from
|
||||
+ the KDC.
|
||||
+
|
||||
+**--no-store**
|
||||
+ Do not store retrieved credentials in the cache. If
|
||||
+ **--out-cache** is also specified, credentials will still be
|
||||
+ stored into the output credential cache.
|
||||
+
|
||||
+**--out-cache** *ccache*
|
||||
+ Initialize *ccache* and store all retrieved credentials into it.
|
||||
+ Do not store acquired credentials in the input cache.
|
||||
+
|
||||
**--u2u** *ccache*
|
||||
Requests a user-to-user ticket. *ccache* must contain a local
|
||||
krbtgt ticket for the server principal. The reported version
|
||||
diff --git a/src/clients/kvno/Makefile.in b/src/clients/kvno/Makefile.in
|
||||
index 1c3f79392..5ba877271 100644
|
||||
--- a/src/clients/kvno/Makefile.in
|
||||
+++ b/src/clients/kvno/Makefile.in
|
||||
@@ -26,6 +26,9 @@ kvno: kvno.o $(KRB5_BASE_DEPLIBS)
|
||||
##WIN32## link $(EXE_LINKOPTS) /out:$@ $**
|
||||
##WIN32## $(_VC_MANIFEST_EMBED_EXE)
|
||||
|
||||
+check-pytests: kvno
|
||||
+ $(RUNPYTEST) $(srcdir)/t_kvno.py $(PYTESTFLAGS)
|
||||
+
|
||||
clean-unix::
|
||||
$(RM) kvno.o kvno
|
||||
|
||||
diff --git a/src/clients/kvno/kvno.c b/src/clients/kvno/kvno.c
|
||||
index 2472c0cfe..9d85864f6 100644
|
||||
--- a/src/clients/kvno/kvno.c
|
||||
+++ b/src/clients/kvno/kvno.c
|
||||
@@ -44,14 +44,17 @@ xusage()
|
||||
fprintf(stderr, _("usage: %s [-C] [-u] [-c ccache] [-e etype]\n"), prog);
|
||||
fprintf(stderr, _("\t[-k keytab] [-S sname] [{-I | -U} for_user | "
|
||||
"[-F cert_file] [-P]]\n"));
|
||||
- fprintf(stderr, _("\t[--u2u ccache] service1 service2 ...\n"));
|
||||
+ fprintf(stderr, _("\t[--cached-only] [--no-store] [--out-cache ccache] "
|
||||
+ "[--u2u ccache]\n"));
|
||||
+ fprintf(stderr, _("\tservice1 service2 ...\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void do_v5_kvno(int argc, char *argv[], char *ccachestr, char *etypestr,
|
||||
- char *keytab_name, char *sname, int canon, int unknown,
|
||||
- char *for_user, int for_user_enterprise,
|
||||
- char *for_user_cert_file, int proxy,
|
||||
+ char *keytab_name, char *sname, int cached_only,
|
||||
+ int canon, int no_store, int unknown, char *for_user,
|
||||
+ int for_user_enterprise, char *for_user_cert_file,
|
||||
+ int proxy, const char *out_ccname,
|
||||
const char *u2u_ccname);
|
||||
|
||||
#include <com_err.h>
|
||||
@@ -61,18 +64,21 @@ static void extended_com_err_fn(const char *myprog, errcode_t code,
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
- enum { OPTION_U2U = 256 };
|
||||
- struct option lopts[] = {
|
||||
- { "u2u", 1, NULL, OPTION_U2U },
|
||||
- { NULL, 0, NULL, 0 }
|
||||
- };
|
||||
+ enum { OPTION_U2U = 256, OPTION_OUT_CACHE = 257 };
|
||||
const char *shopts = "uCc:e:hk:qPS:I:U:F:";
|
||||
int option;
|
||||
char *etypestr = NULL, *ccachestr = NULL, *keytab_name = NULL;
|
||||
char *sname = NULL, *for_user = NULL, *u2u_ccname = NULL;
|
||||
- char *for_user_cert_file = NULL;
|
||||
+ char *for_user_cert_file = NULL, *out_ccname = NULL;
|
||||
int canon = 0, unknown = 0, proxy = 0, for_user_enterprise = 0;
|
||||
- int impersonate = 0;
|
||||
+ int impersonate = 0, cached_only = 0, no_store = 0;
|
||||
+ struct option lopts[] = {
|
||||
+ { "cached-only", 0, &cached_only, 1 },
|
||||
+ { "no-store", 0, &no_store, 1 },
|
||||
+ { "out-cache", 1, NULL, OPTION_OUT_CACHE },
|
||||
+ { "u2u", 1, NULL, OPTION_U2U },
|
||||
+ { NULL, 0, NULL, 0 }
|
||||
+ };
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
set_com_err_hook(extended_com_err_fn);
|
||||
@@ -135,6 +141,12 @@ main(int argc, char *argv[])
|
||||
case OPTION_U2U:
|
||||
u2u_ccname = optarg;
|
||||
break;
|
||||
+ case OPTION_OUT_CACHE:
|
||||
+ out_ccname = optarg;
|
||||
+ break;
|
||||
+ case 0:
|
||||
+ /* If this option set a flag, do nothing else now. */
|
||||
+ break;
|
||||
default:
|
||||
xusage();
|
||||
break;
|
||||
@@ -159,8 +171,9 @@ main(int argc, char *argv[])
|
||||
xusage();
|
||||
|
||||
do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr, keytab_name,
|
||||
- sname, canon, unknown, for_user, for_user_enterprise,
|
||||
- for_user_cert_file, proxy, u2u_ccname);
|
||||
+ sname, cached_only, canon, no_store, unknown, for_user,
|
||||
+ for_user_enterprise, for_user_cert_file, proxy, out_ccname,
|
||||
+ u2u_ccname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -274,14 +287,16 @@ static krb5_error_code
|
||||
kvno(const char *name, krb5_ccache ccache, krb5_principal me,
|
||||
krb5_enctype etype, krb5_keytab keytab, const char *sname,
|
||||
krb5_flags options, int unknown, krb5_principal for_user_princ,
|
||||
- krb5_data *for_user_cert, int proxy, krb5_data *u2u_ticket)
|
||||
+ krb5_data *for_user_cert, int proxy, krb5_data *u2u_ticket,
|
||||
+ krb5_creds **creds_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_principal server = NULL;
|
||||
krb5_ticket *ticket = NULL;
|
||||
- krb5_creds in_creds, *out_creds = NULL;
|
||||
+ krb5_creds in_creds, *creds = NULL;
|
||||
char *princ = NULL;
|
||||
|
||||
+ *creds_out = NULL;
|
||||
memset(&in_creds, 0, sizeof(in_creds));
|
||||
|
||||
if (sname != NULL) {
|
||||
@@ -321,13 +336,12 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
|
||||
in_creds.client = for_user_princ;
|
||||
in_creds.server = me;
|
||||
ret = krb5_get_credentials_for_user(context, options, ccache,
|
||||
- &in_creds, for_user_cert,
|
||||
- &out_creds);
|
||||
+ &in_creds, for_user_cert, &creds);
|
||||
} else {
|
||||
in_creds.client = me;
|
||||
in_creds.server = server;
|
||||
ret = krb5_get_credentials(context, options, ccache, &in_creds,
|
||||
- &out_creds);
|
||||
+ &creds);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
@@ -336,7 +350,7 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
|
||||
}
|
||||
|
||||
/* We need a native ticket. */
|
||||
- ret = krb5_decode_ticket(&out_creds->ticket, &ticket);
|
||||
+ ret = krb5_decode_ticket(&creds->ticket, &ticket);
|
||||
if (ret) {
|
||||
com_err(prog, ret, _("while decoding ticket for %s"), princ);
|
||||
goto cleanup;
|
||||
@@ -362,15 +376,15 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
|
||||
}
|
||||
|
||||
if (proxy) {
|
||||
- in_creds.client = out_creds->client;
|
||||
- out_creds->client = NULL;
|
||||
- krb5_free_creds(context, out_creds);
|
||||
- out_creds = NULL;
|
||||
+ in_creds.client = creds->client;
|
||||
+ creds->client = NULL;
|
||||
+ krb5_free_creds(context, creds);
|
||||
+ creds = NULL;
|
||||
in_creds.server = server;
|
||||
|
||||
ret = krb5_get_credentials_for_proxy(context, KRB5_GC_CANONICALIZE,
|
||||
ccache, &in_creds, ticket,
|
||||
- &out_creds);
|
||||
+ &creds);
|
||||
krb5_free_principal(context, in_creds.client);
|
||||
if (ret) {
|
||||
com_err(prog, ret, _("%s: constrained delegation failed"),
|
||||
@@ -379,10 +393,13 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
|
||||
}
|
||||
}
|
||||
|
||||
+ *creds_out = creds;
|
||||
+ creds = NULL;
|
||||
+
|
||||
cleanup:
|
||||
krb5_free_principal(context, server);
|
||||
krb5_free_ticket(context, ticket);
|
||||
- krb5_free_creds(context, out_creds);
|
||||
+ krb5_free_creds(context, creds);
|
||||
krb5_free_unparsed_name(context, princ);
|
||||
return ret;
|
||||
}
|
||||
@@ -428,19 +445,28 @@ cleanup:
|
||||
|
||||
static void
|
||||
do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
|
||||
- char *keytab_name, char *sname, int canon, int unknown,
|
||||
- char *for_user, int for_user_enterprise,
|
||||
- char *for_user_cert_file, int proxy, const char *u2u_ccname)
|
||||
+ char *keytab_name, char *sname, int cached_only, int canon,
|
||||
+ int no_store, int unknown, char *for_user, int for_user_enterprise,
|
||||
+ char *for_user_cert_file, int proxy, const char *out_ccname,
|
||||
+ const char *u2u_ccname)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
- int i, errors, flags;
|
||||
+ int i, errors, flags, initialized = 0;
|
||||
krb5_enctype etype;
|
||||
- krb5_ccache ccache;
|
||||
+ krb5_ccache ccache, out_ccache = NULL;
|
||||
krb5_principal me;
|
||||
krb5_keytab keytab = NULL;
|
||||
krb5_principal for_user_princ = NULL;
|
||||
- krb5_flags options = canon ? KRB5_GC_CANONICALIZE : 0;
|
||||
+ krb5_flags options = 0;
|
||||
krb5_data cert_data = empty_data(), *user_cert = NULL, *u2u_ticket = NULL;
|
||||
+ krb5_creds *creds;
|
||||
+
|
||||
+ if (canon)
|
||||
+ options |= KRB5_GC_CANONICALIZE;
|
||||
+ if (cached_only)
|
||||
+ options |= KRB5_GC_CACHED;
|
||||
+ if (no_store || out_ccname != NULL)
|
||||
+ options |= KRB5_GC_NO_STORE;
|
||||
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret) {
|
||||
@@ -467,6 +493,14 @@ do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+ if (out_ccname != NULL) {
|
||||
+ ret = krb5_cc_resolve(context, out_ccname, &out_ccache);
|
||||
+ if (ret) {
|
||||
+ com_err(prog, ret, _("while resolving output ccache"));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (keytab_name != NULL) {
|
||||
ret = krb5_kt_resolve(context, keytab_name, &keytab);
|
||||
if (ret) {
|
||||
@@ -513,8 +547,25 @@ do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
|
||||
errors = 0;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (kvno(names[i], ccache, me, etype, keytab, sname, options, unknown,
|
||||
- for_user_princ, user_cert, proxy, u2u_ticket) != 0)
|
||||
+ for_user_princ, user_cert, proxy, u2u_ticket, &creds) != 0) {
|
||||
errors++;
|
||||
+ } else if (out_ccache != NULL) {
|
||||
+ if (!initialized) {
|
||||
+ ret = krb5_cc_initialize(context, out_ccache, creds->client);
|
||||
+ if (ret) {
|
||||
+ com_err(prog, ret, _("while initializing output ccache"));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ initialized = 1;
|
||||
+ }
|
||||
+ ret = krb5_cc_store_cred(context, out_ccache, creds);
|
||||
+ if (ret) {
|
||||
+ com_err(prog, ret, _("while storing creds in output ccache"));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ krb5_free_creds(context, creds);
|
||||
}
|
||||
|
||||
if (keytab != NULL)
|
||||
diff --git a/src/clients/kvno/t_kvno.py b/src/clients/kvno/t_kvno.py
|
||||
new file mode 100644
|
||||
index 000000000..e98b90e8a
|
||||
--- /dev/null
|
||||
+++ b/src/clients/kvno/t_kvno.py
|
||||
@@ -0,0 +1,75 @@
|
||||
+from k5test import *
|
||||
+
|
||||
+realm = K5Realm()
|
||||
+
|
||||
+def check_cache(ccache, expected_services):
|
||||
+ # Fetch the klist output and skip past the header.
|
||||
+ lines = realm.run([klist, '-c', ccache]).splitlines()
|
||||
+ lines = lines[4:]
|
||||
+
|
||||
+ # For each line not beginning with an indent, match against the
|
||||
+ # expected service principals.
|
||||
+ svcs = {x: True for x in expected_services}
|
||||
+ for l in lines:
|
||||
+ if not l.startswith('\t'):
|
||||
+ svcprinc = l.split()[4]
|
||||
+ if svcprinc in svcs:
|
||||
+ del svcs[svcprinc]
|
||||
+ else:
|
||||
+ fail('unexpected service princ ' + svcprinc)
|
||||
+
|
||||
+ if svcs:
|
||||
+ fail('services not found in klist output: ' + ' '.join(svcs.keys()))
|
||||
+
|
||||
+
|
||||
+mark('no options')
|
||||
+realm.run([kvno, realm.user_princ], expected_msg='user@KRBTEST.COM: kvno = 1')
|
||||
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
|
||||
+
|
||||
+mark('-e')
|
||||
+msgs = ('etypes requested in TGS request: camellia128-cts',
|
||||
+ '/KDC has no support for encryption type')
|
||||
+realm.run([kvno, '-e', 'camellia128-cts', realm.host_princ],
|
||||
+ expected_code=1, expected_trace=msgs)
|
||||
+
|
||||
+mark('--cached-only')
|
||||
+realm.run([kvno, '--cached-only', realm.user_princ], expected_msg='kvno = 1')
|
||||
+realm.run([kvno, '--cached-only', realm.host_princ],
|
||||
+ expected_code=1, expected_msg='Matching credential not found')
|
||||
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
|
||||
+
|
||||
+mark('--no-store')
|
||||
+realm.run([kvno, '--no-store', realm.host_princ], expected_msg='kvno = 1')
|
||||
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
|
||||
+
|
||||
+mark('--out-cache') # and multiple services
|
||||
+out_ccache = os.path.join(realm.testdir, 'ccache.out')
|
||||
+realm.run([kvno, '--out-cache', out_ccache,
|
||||
+ realm.host_princ, realm.admin_princ])
|
||||
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
|
||||
+check_cache(out_ccache, [realm.host_princ, realm.admin_princ])
|
||||
+
|
||||
+mark('--out-cache --cached-only') # tests out-cache overwriting, and -q
|
||||
+realm.run([kvno, '--out-cache', out_ccache, '--cached-only', realm.host_princ],
|
||||
+ expected_code=1, expected_msg='Matching credential not found')
|
||||
+out = realm.run([kvno, '-q', '--out-cache', out_ccache, '--cached-only',
|
||||
+ realm.user_princ])
|
||||
+if out:
|
||||
+ fail('unexpected kvno output with -q')
|
||||
+check_cache(out_ccache, [realm.user_princ])
|
||||
+
|
||||
+mark('-U') # and -c
|
||||
+svc_ccache = os.path.join(realm.testdir, 'ccache.svc')
|
||||
+realm.run([kinit, '-k', '-c', svc_ccache, realm.host_princ])
|
||||
+realm.run([kvno, '-c', svc_ccache, '-U', 'user', realm.host_princ])
|
||||
+realm.run([klist, '-c', svc_ccache], expected_msg='for client user@')
|
||||
+realm.run([kvno, '-c', svc_ccache, '-U', 'user', '--out-cache', out_ccache,
|
||||
+ realm.host_princ])
|
||||
+out = realm.run([klist, '-c', out_ccache])
|
||||
+if ('Default principal: user@KRBTEST.COM' not in out):
|
||||
+ fail('wrong default principal in klist output')
|
||||
+
|
||||
+# More S4U options are tested in tests/gssapi/t_s4u.py.
|
||||
+# --u2u is tested in tests/t_u2u.py.
|
||||
+
|
||||
+success('kvno tests')
|
||||
diff --git a/src/man/kvno.man b/src/man/kvno.man
|
||||
index 005a2ec97..b9f6739eb 100644
|
||||
--- a/src/man/kvno.man
|
||||
+++ b/src/man/kvno.man
|
||||
@@ -95,6 +95,19 @@ Specifies that protocol transition is to be used, identifying the
|
||||
client principal with the X.509 certificate in \fIcert_file\fP\&. The
|
||||
certificate file must be in PEM format.
|
||||
.TP
|
||||
+\fB\-\-cached\-only\fP
|
||||
+Only retrieve credentials already present in the cache, not from
|
||||
+the KDC.
|
||||
+.TP
|
||||
+\fB\-\-no\-store\fP
|
||||
+Do not store retrieved credentials in the cache. If
|
||||
+\fB\-\-out\-cache\fP is also specified, credentials will still be
|
||||
+stored into the output credential cache.
|
||||
+.TP
|
||||
+\fB\-\-out\-cache\fP \fIccache\fP
|
||||
+Initialize \fIccache\fP and store all retrieved credentials into it.
|
||||
+Do not store acquired credentials in the input cache.
|
||||
+.TP
|
||||
\fB\-\-u2u\fP \fIccache\fP
|
||||
Requests a user\-to\-user ticket. \fIccache\fP must contain a local
|
||||
krbtgt ticket for the server principal. The reported version
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
From 758f5031fe9d6c1e3eb33818bc6d57cf8b4a3a72 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Tue, 22 Sep 2020 01:11:39 +0300
|
||||
Subject: [PATCH] Adjust KDC alias helper function contract
|
||||
|
||||
Change the name of is_client_alias() to is_client_db_alias(), and
|
||||
change the contract so that the already-canonical principal name comes
|
||||
from a DB entry (which is less flexible, but clearer since DB entries
|
||||
always contain canonical principal names). Make the function
|
||||
available outside of kdc_util.c.
|
||||
|
||||
[ghudson@mit.edu: clarified commit message]
|
||||
|
||||
(cherry picked from commit 9fb5f572dd6ce808b234cb60a573eac48136d7ca)
|
||||
---
|
||||
src/kdc/kdc_util.c | 14 +++++++-------
|
||||
src/kdc/kdc_util.h | 4 ++++
|
||||
2 files changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index dcb2df8dc..6330387d0 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -1463,10 +1463,10 @@ cleanup:
|
||||
return code;
|
||||
}
|
||||
|
||||
-/* Return true if princ canonicalizes to the same principal as canon. */
|
||||
-static krb5_boolean
|
||||
-is_client_alias(krb5_context context, krb5_const_principal canon,
|
||||
- krb5_const_principal princ)
|
||||
+/* Return true if princ canonicalizes to the same principal as entry's. */
|
||||
+krb5_boolean
|
||||
+is_client_db_alias(krb5_context context, const krb5_db_entry *entry,
|
||||
+ krb5_const_principal princ)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_db_entry *self;
|
||||
@@ -1475,7 +1475,7 @@ is_client_alias(krb5_context context, krb5_const_principal canon,
|
||||
ret = krb5_db_get_principal(context, princ,
|
||||
KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY, &self);
|
||||
if (!ret) {
|
||||
- is_self = krb5_principal_compare(context, canon, self->princ);
|
||||
+ is_self = krb5_principal_compare(context, entry->princ, self->princ);
|
||||
krb5_db_free_principal(context, self);
|
||||
}
|
||||
|
||||
@@ -1535,7 +1535,7 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
|
||||
|
||||
/* If the server is local, check that the request is for self. */
|
||||
if (!isflagset(c_flags, KRB5_KDB_FLAG_ISSUING_REFERRAL) &&
|
||||
- !is_client_alias(kdc_context, server->princ, client_princ)) {
|
||||
+ !is_client_db_alias(kdc_context, server, client_princ)) {
|
||||
*status = "INVALID_S4U2SELF_REQUEST_SERVER_MISMATCH";
|
||||
return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; /* match Windows error */
|
||||
}
|
||||
@@ -1728,7 +1728,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, unsigned int flags,
|
||||
}
|
||||
|
||||
client_princ = *stkt_authdata_client;
|
||||
- } else if (!is_client_alias(kdc_context, server->princ, server_princ)) {
|
||||
+ } else if (!is_client_db_alias(kdc_context, server, server_princ)) {
|
||||
*status = "EVIDENCE_TICKET_MISMATCH";
|
||||
return KRB5KDC_ERR_SERVER_NOMATCH;
|
||||
}
|
||||
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
|
||||
index 384b21ad2..2c9d8cf69 100644
|
||||
--- a/src/kdc/kdc_util.h
|
||||
+++ b/src/kdc/kdc_util.h
|
||||
@@ -344,6 +344,10 @@ log_tgs_badtrans(krb5_context ctx, krb5_principal cprinc,
|
||||
void
|
||||
log_tgs_alt_tgt(krb5_context context, krb5_principal p);
|
||||
|
||||
+krb5_boolean
|
||||
+is_client_db_alias(krb5_context context, const krb5_db_entry *entry,
|
||||
+ krb5_const_principal princ);
|
||||
+
|
||||
/* FAST*/
|
||||
enum krb5_fast_kdc_flags {
|
||||
KRB5_FAST_REPLY_KEY_USED = 0x1,
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
From ccc5b9663e229f20421c01836aa5ecb06f1f2a48 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Tue, 22 Sep 2020 01:17:11 +0300
|
||||
Subject: [PATCH] Allow aliases when matching U2U second ticket
|
||||
|
||||
In process_tgs_req() when verifying the user-to-user second ticket,
|
||||
compare the canonical names of the request server and the second
|
||||
ticket client.
|
||||
|
||||
[ghudson@mit.edu: expanded commit message; trimmed tests]
|
||||
|
||||
ticket: 8951 (new)
|
||||
(cherry picked from commit afc494ef9418e6be7fbb887364efa6606b10034a)
|
||||
---
|
||||
src/kdc/do_tgs_req.c | 2 +-
|
||||
src/tests/t_u2u.py | 25 +++++++++++++++++++++++++
|
||||
2 files changed, 26 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
||||
index 463a9c0dd..74cd19e96 100644
|
||||
--- a/src/kdc/do_tgs_req.c
|
||||
+++ b/src/kdc/do_tgs_req.c
|
||||
@@ -666,7 +666,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
*/
|
||||
krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
|
||||
krb5_principal client2 = t2enc->client;
|
||||
- if (!krb5_principal_compare(kdc_context, request->server, client2)) {
|
||||
+ if (!is_client_db_alias(kdc_context, server, client2)) {
|
||||
altcprinc = client2;
|
||||
errcode = KRB5KDC_ERR_SERVER_NOMATCH;
|
||||
status = "2ND_TKT_MISMATCH";
|
||||
diff --git a/src/tests/t_u2u.py b/src/tests/t_u2u.py
|
||||
index 1ca6ac87e..4b8a82a2f 100644
|
||||
--- a/src/tests/t_u2u.py
|
||||
+++ b/src/tests/t_u2u.py
|
||||
@@ -32,4 +32,29 @@ realm.run([kvno, '--u2u', realm.ccache, realm.user_princ])
|
||||
|
||||
realm.run([klist])
|
||||
|
||||
+realm.stop()
|
||||
+
|
||||
+# Load the test KDB module to test aliases
|
||||
+testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
|
||||
+ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
|
||||
+ 'WIN10': {'keys': 'aes128-cts'}}
|
||||
+kdcconf = {'realms': {'$realm': {'database_module': 'test'}},
|
||||
+ 'dbmodules': {'test': {'db_library': 'test',
|
||||
+ 'princs': testprincs,
|
||||
+ 'alias': {'HOST/win10': 'WIN10'}}}}
|
||||
+
|
||||
+realm = K5Realm(kdc_conf=kdcconf, create_kdb=False)
|
||||
+realm.start_kdc()
|
||||
+
|
||||
+# Create a second user principal and get tickets for it.
|
||||
+u2u_ccache = 'FILE:' + os.path.join(realm.testdir, 'ccu2u')
|
||||
+realm.extract_keytab('WIN10', realm.keytab)
|
||||
+realm.kinit('WIN10', None, ['-k', '-c', u2u_ccache])
|
||||
+
|
||||
+realm.extract_keytab(realm.user_princ, realm.keytab)
|
||||
+realm.kinit(realm.user_princ, None, ['-k'])
|
||||
+
|
||||
+realm.run([kvno, '--u2u', u2u_ccache, 'HOST/win10'], expected_msg='kvno = 0')
|
||||
+realm.run([kvno, '--u2u', u2u_ccache, 'WIN10'], expected_msg='kvno = 0')
|
||||
+
|
||||
success('user-to-user tests')
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
From 5b62f6f6a960e5a428a39a3e83e0a16dba5a914a Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 24 Feb 2020 15:58:59 -0500
|
||||
Subject: [PATCH] Allow certauth modules to set hw-authent flag
|
||||
|
||||
In PKINIT, if a certauth module returns KRB5_CERTAUTH_HWAUTH from its
|
||||
authorize method, set the hw-authent flag in the ticket.
|
||||
|
||||
ticket: 8879 (new)
|
||||
(cherry picked from commit 50fb43b4a2d97ce2cd53e1ced30e8e8224fede70)
|
||||
---
|
||||
doc/plugindev/certauth.rst | 7 +++++--
|
||||
src/include/krb5/certauth_plugin.h | 9 ++++++---
|
||||
src/lib/krb5/error_tables/k5e1_err.et | 1 +
|
||||
src/plugins/certauth/test/Makefile.in | 4 ++--
|
||||
src/plugins/certauth/test/main.c | 11 +++++++++--
|
||||
src/plugins/preauth/pkinit/pkinit_srv.c | 24 ++++++++++++++++--------
|
||||
src/tests/t_certauth.py | 13 +++++++++++++
|
||||
7 files changed, 52 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/doc/plugindev/certauth.rst b/doc/plugindev/certauth.rst
|
||||
index 8a7f7c5eb..3b715f738 100644
|
||||
--- a/doc/plugindev/certauth.rst
|
||||
+++ b/doc/plugindev/certauth.rst
|
||||
@@ -15,8 +15,11 @@ principal. **authorize** receives the DER-encoded certificate, the
|
||||
requested client principal, and a pointer to the client's
|
||||
krb5_db_entry (for modules that link against libkdb5). It returns the
|
||||
authorization status and optionally outputs a list of authentication
|
||||
-indicator strings to be added to the ticket. A module must use its
|
||||
-own internal or library-provided ASN.1 certificate decoder.
|
||||
+indicator strings to be added to the ticket. Beginning in release
|
||||
+1.19, the authorize method can request that the hardware
|
||||
+authentication bit be set in the ticket by returning
|
||||
+**KRB5_CERTAUTH_HWAUTH**. A module must use its own internal or
|
||||
+library-provided ASN.1 certificate decoder.
|
||||
|
||||
A module can optionally create and destroy module data with the
|
||||
**init** and **fini** methods. Module data objects last for the
|
||||
diff --git a/src/include/krb5/certauth_plugin.h b/src/include/krb5/certauth_plugin.h
|
||||
index 3074790f8..3466cf345 100644
|
||||
--- a/src/include/krb5/certauth_plugin.h
|
||||
+++ b/src/include/krb5/certauth_plugin.h
|
||||
@@ -85,14 +85,17 @@ typedef void
|
||||
(*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata);
|
||||
|
||||
/*
|
||||
- * Mandatory:
|
||||
- * Return 0 if the DER-encoded cert is authorized for PKINIT authentication by
|
||||
- * princ; otherwise return one of the following error codes:
|
||||
+ * Mandatory: return 0 or KRB5_CERTAUTH_HWAUTH if the DER-encoded cert is
|
||||
+ * authorized for PKINIT authentication by princ; otherwise return one of the
|
||||
+ * following error codes:
|
||||
* - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value
|
||||
* - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU
|
||||
* - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error
|
||||
* - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert
|
||||
*
|
||||
+ * Returning KRB5_CERTAUTH_HWAUTH will cause the hw-authent flag to be set in
|
||||
+ * the issued ticket (new in release 1.19).
|
||||
+ *
|
||||
* - opts is used by built-in modules to receive internal data, and must be
|
||||
* ignored by other modules.
|
||||
* - db_entry receives the client principal database entry, and can be ignored
|
||||
diff --git a/src/lib/krb5/error_tables/k5e1_err.et b/src/lib/krb5/error_tables/k5e1_err.et
|
||||
index ade5caecf..abd9f3bfe 100644
|
||||
--- a/src/lib/krb5/error_tables/k5e1_err.et
|
||||
+++ b/src/lib/krb5/error_tables/k5e1_err.et
|
||||
@@ -42,4 +42,5 @@ error_code KRB5_KCM_MALFORMED_REPLY, "Malformed reply from KCM daemon"
|
||||
error_code KRB5_KCM_RPC_ERROR, "Mach RPC error communicating with KCM daemon"
|
||||
error_code KRB5_KCM_REPLY_TOO_BIG, "KCM daemon reply too big"
|
||||
error_code KRB5_KCM_NO_SERVER, "No KCM server found"
|
||||
+error_code KRB5_CERTAUTH_HWAUTH, "Authorize and set hw-authent ticket flag"
|
||||
end
|
||||
diff --git a/src/plugins/certauth/test/Makefile.in b/src/plugins/certauth/test/Makefile.in
|
||||
index d3524084c..e94c13845 100644
|
||||
--- a/src/plugins/certauth/test/Makefile.in
|
||||
+++ b/src/plugins/certauth/test/Makefile.in
|
||||
@@ -5,8 +5,8 @@ LIBBASE=certauth_test
|
||||
LIBMAJOR=0
|
||||
LIBMINOR=0
|
||||
RELDIR=../plugins/certauth/test
|
||||
-SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS)
|
||||
-SHLIB_EXPLIBS=$(KRB5_BASE_LIBS)
|
||||
+SHLIB_EXPDEPS=$(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS)
|
||||
+SHLIB_EXPLIBS=$(KDB5_LIBS) $(KRB5_BASE_LIBS)
|
||||
|
||||
STLIBOBJS=main.o
|
||||
|
||||
diff --git a/src/plugins/certauth/test/main.c b/src/plugins/certauth/test/main.c
|
||||
index 77641230c..d4633b8cd 100644
|
||||
--- a/src/plugins/certauth/test/main.c
|
||||
+++ b/src/plugins/certauth/test/main.c
|
||||
@@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <k5-int.h>
|
||||
+#include <kdb.h>
|
||||
#include "krb5/certauth_plugin.h"
|
||||
|
||||
struct krb5_certauth_moddata_st {
|
||||
@@ -131,7 +132,8 @@ has_cn(krb5_context context, const uint8_t *cert, size_t cert_len,
|
||||
|
||||
/*
|
||||
* Test module 2 returns OK if princ matches the CN part of the subject name,
|
||||
- * and returns indicators of the module name and princ.
|
||||
+ * and returns indicators of the module name and princ. If the "hwauth" string
|
||||
+ * attribute is set on db_entry, it returns KRB5_CERTAUTH_HWAUTH.
|
||||
*/
|
||||
static krb5_error_code
|
||||
test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
|
||||
@@ -141,7 +143,7 @@ test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
|
||||
char ***authinds_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
- char *name = NULL, **ais = NULL;
|
||||
+ char *name = NULL, *strval = NULL, **ais = NULL;
|
||||
|
||||
*authinds_out = NULL;
|
||||
|
||||
@@ -167,6 +169,11 @@ test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
|
||||
|
||||
ais = NULL;
|
||||
|
||||
+ ret = krb5_dbe_get_string(context, (krb5_db_entry *)db_entry, "hwauth",
|
||||
+ &strval);
|
||||
+ ret = (strval != NULL) ? KRB5_CERTAUTH_HWAUTH : 0;
|
||||
+ krb5_dbe_free_string(context, strval);
|
||||
+
|
||||
cleanup:
|
||||
krb5_free_unparsed_name(context, name);
|
||||
return ret;
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
index feca11806..3ae56c064 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
|
||||
@@ -320,12 +320,12 @@ static krb5_error_code
|
||||
authorize_cert(krb5_context context, certauth_handle *certauth_modules,
|
||||
pkinit_kdc_context plgctx, pkinit_kdc_req_context reqctx,
|
||||
krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
|
||||
- krb5_principal client)
|
||||
+ krb5_principal client, krb5_boolean *hwauth_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
certauth_handle h;
|
||||
struct certauth_req_opts opts;
|
||||
- krb5_boolean accepted = FALSE;
|
||||
+ krb5_boolean accepted = FALSE, hwauth = FALSE;
|
||||
uint8_t *cert;
|
||||
size_t i, cert_len;
|
||||
void *db_ent = NULL;
|
||||
@@ -347,9 +347,10 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
|
||||
|
||||
/*
|
||||
* Check the certificate against each certauth module. For the certificate
|
||||
- * to be authorized at least one module must return 0, and no module can an
|
||||
- * error code other than KRB5_PLUGIN_NO_HANDLE (pass). Add indicators from
|
||||
- * modules that return 0 or pass.
|
||||
+ * to be authorized at least one module must return 0 or
|
||||
+ * KRB5_CERTAUTH_HWAUTH, and no module can return an error code other than
|
||||
+ * KRB5_PLUGIN_NO_HANDLE (pass). Add indicators from modules that return 0
|
||||
+ * or pass.
|
||||
*/
|
||||
ret = KRB5_PLUGIN_NO_HANDLE;
|
||||
for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) {
|
||||
@@ -359,6 +360,8 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
|
||||
&opts, db_ent, &ais);
|
||||
if (ret == 0)
|
||||
accepted = TRUE;
|
||||
+ else if (ret == KRB5_CERTAUTH_HWAUTH)
|
||||
+ accepted = hwauth = TRUE;
|
||||
else if (ret != KRB5_PLUGIN_NO_HANDLE)
|
||||
goto cleanup;
|
||||
|
||||
@@ -374,6 +377,7 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
|
||||
}
|
||||
}
|
||||
|
||||
+ *hwauth_out = hwauth;
|
||||
ret = accepted ? 0 : KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
|
||||
|
||||
cleanup:
|
||||
@@ -430,7 +434,7 @@ pkinit_server_verify_padata(krb5_context context,
|
||||
int is_signed = 1;
|
||||
krb5_pa_data **e_data = NULL;
|
||||
krb5_kdcpreauth_modreq modreq = NULL;
|
||||
- krb5_boolean valid_freshness_token = FALSE;
|
||||
+ krb5_boolean valid_freshness_token = FALSE, hwauth = FALSE;
|
||||
char **sp;
|
||||
|
||||
pkiDebug("pkinit_verify_padata: entered!\n");
|
||||
@@ -494,7 +498,7 @@ pkinit_server_verify_padata(krb5_context context,
|
||||
}
|
||||
if (is_signed) {
|
||||
retval = authorize_cert(context, moddata->certauth_modules, plgctx,
|
||||
- reqctx, cb, rock, request->client);
|
||||
+ reqctx, cb, rock, request->client, &hwauth);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
|
||||
@@ -613,6 +617,8 @@ pkinit_server_verify_padata(krb5_context context,
|
||||
|
||||
/* remember to set the PREAUTH flag in the reply */
|
||||
enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
|
||||
+ if (hwauth)
|
||||
+ enc_tkt_reply->flags |= TKT_FLG_HW_AUTH;
|
||||
modreq = (krb5_kdcpreauth_modreq)reqctx;
|
||||
reqctx = NULL;
|
||||
|
||||
@@ -1044,7 +1050,9 @@ pkinit_server_get_flags(krb5_context kcontext, krb5_preauthtype patype)
|
||||
{
|
||||
if (patype == KRB5_PADATA_PKINIT_KX)
|
||||
return PA_INFO;
|
||||
- return PA_SUFFICIENT | PA_REPLACES_KEY | PA_TYPED_E_DATA;
|
||||
+ /* PKINIT does not normally set the hw-authent ticket flag, but a
|
||||
+ * certauth module can cause it to do so. */
|
||||
+ return PA_SUFFICIENT | PA_REPLACES_KEY | PA_TYPED_E_DATA | PA_HARDWARE;
|
||||
}
|
||||
|
||||
static krb5_preauthtype supported_server_pa_types[] = {
|
||||
diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py
|
||||
index 9c7094525..0fe0fdb4a 100644
|
||||
--- a/src/tests/t_certauth.py
|
||||
+++ b/src/tests/t_certauth.py
|
||||
@@ -43,4 +43,17 @@ out = realm.kinit("user2@KRBTEST.COM",
|
||||
expected_code=1,
|
||||
expected_msg='kinit: Certificate mismatch')
|
||||
|
||||
+# Test the KRB5_CERTAUTH_HWAUTH return code.
|
||||
+mark('hw-authent flag tests')
|
||||
+# First test +requires_hwauth without causing the hw-authent ticket
|
||||
+# flag to be set. This currently results in a preauth loop.
|
||||
+realm.run([kadminl, 'modprinc', '+requires_hwauth', realm.user_princ])
|
||||
+realm.kinit(realm.user_princ,
|
||||
+ flags=['-X', 'X509_user_identity=%s' % file_identity],
|
||||
+ expected_code=1, expected_msg='Looping detected')
|
||||
+# Cause the test2 module to return KRB5_CERTAUTH_HWAUTH and try again.
|
||||
+realm.run([kadminl, 'setstr', realm.user_princ, 'hwauth', 'x'])
|
||||
+realm.kinit(realm.user_princ,
|
||||
+ flags=['-X', 'X509_user_identity=%s' % file_identity])
|
||||
+
|
||||
success("certauth tests")
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
From 594c9d225f470e73a46dd2a85c5e50571e90598c Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Sat, 11 Jul 2020 21:57:30 -0400
|
||||
Subject: [PATCH] Allow gss_unwrap_iov() of unpadded RC4 tokens
|
||||
|
||||
Windows Remote Management, when used with an RC4 session key, appears
|
||||
to generate GSS wrap tokens with no padding instead of the expected
|
||||
one byte (RFC 4757 section 7.3). These tokens cannot be decoded with
|
||||
gss_unwrap() or a STREAM buffer (even with Microsoft SSPI), but SSPI
|
||||
allows them to be decoded using explicit IOVs with either a
|
||||
zero-length padding buffer or no padding buffer. Allow these cases to
|
||||
work in kg_fixup_padding_iov(). (It is already possible to make this
|
||||
work with HEADER | DATA | DATA, but only by
|
||||
accident--kg_fixup_padding_iov() doesn't find a data buffer because
|
||||
kg_locate_iov() only looks for singleton buffers, so it exits early.)
|
||||
|
||||
ticket: 8926 (new)
|
||||
tags: pullup
|
||||
target_version: 1.18-next
|
||||
|
||||
(cherry picked from commit 3f204ddd567715ef360b4bb0b32961b6a9877f9d)
|
||||
---
|
||||
src/lib/gssapi/krb5/util_crypt.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
|
||||
index f7d3e92c4..d6c71aeb8 100644
|
||||
--- a/src/lib/gssapi/krb5/util_crypt.c
|
||||
+++ b/src/lib/gssapi/krb5/util_crypt.c
|
||||
@@ -638,16 +638,13 @@ kg_fixup_padding_iov(OM_uint32 *minor_status, gss_iov_buffer_desc *iov,
|
||||
data = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_DATA);
|
||||
padding = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
|
||||
|
||||
- if (data == NULL) {
|
||||
+ /* Do nothing if padding is absent or empty, to allow unwrapping of WinRM
|
||||
+ * unpadded RC4 tokens using an explicit IOV array. */
|
||||
+ if (data == NULL || padding == NULL || padding->buffer.length == 0) {
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
- if (padding == NULL || padding->buffer.length == 0) {
|
||||
- *minor_status = EINVAL;
|
||||
- return GSS_S_FAILURE;
|
||||
- }
|
||||
-
|
||||
p = (unsigned char *)padding->buffer.value;
|
||||
padlength = p[padding->buffer.length - 1];
|
||||
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
From dd8b146093d4bdf8a7d0c0eb8156b62d090448d7 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 30 Sep 2020 02:12:00 -0400
|
||||
Subject: [PATCH] Avoid passing DB entry structures in KDC
|
||||
|
||||
When validating AS or TGS requests, pass pointers to DB entry
|
||||
structures, not the structures themselves.
|
||||
|
||||
(cherry picked from commit 7ccc08a889b40693b2ce7f108f2cdda51bc04bff)
|
||||
---
|
||||
src/kdc/do_as_req.c | 4 ++--
|
||||
src/kdc/do_tgs_req.c | 2 +-
|
||||
src/kdc/kdc_util.c | 34 +++++++++++++++++-----------------
|
||||
src/kdc/kdc_util.h | 6 +++---
|
||||
src/kdc/tgs_policy.c | 35 ++++++++++++++++++-----------------
|
||||
5 files changed, 41 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
|
||||
index 9ae7b0a5e..c2dfea9b8 100644
|
||||
--- a/src/kdc/do_as_req.c
|
||||
+++ b/src/kdc/do_as_req.c
|
||||
@@ -663,8 +663,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
|
||||
au_state->stage = VALIDATE_POL;
|
||||
|
||||
if ((errcode = validate_as_request(kdc_active_realm,
|
||||
- state->request, *state->client,
|
||||
- *state->server, state->kdc_time,
|
||||
+ state->request, state->client,
|
||||
+ state->server, state->kdc_time,
|
||||
&state->status, &state->e_data))) {
|
||||
errcode += ERROR_TABLE_BASE_krb5;
|
||||
goto errout;
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
||||
index 74cd19e96..d345797c4 100644
|
||||
--- a/src/kdc/do_tgs_req.c
|
||||
+++ b/src/kdc/do_tgs_req.c
|
||||
@@ -260,7 +260,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
goto cleanup;
|
||||
|
||||
if ((retval = validate_tgs_request(kdc_active_realm,
|
||||
- request, *server, header_ticket,
|
||||
+ request, server, header_ticket,
|
||||
kdc_time, &status, &e_data))) {
|
||||
if (retval == KDC_ERR_POLICY || retval == KDC_ERR_BADOPTION)
|
||||
au_state->violation = PROT_CONSTRAINT;
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index a4a05b9fa..b2042862a 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -612,8 +612,8 @@ check_anon(kdc_realm_t *kdc_active_realm,
|
||||
KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_CNAME_IN_ADDL_TKT)
|
||||
int
|
||||
validate_as_request(kdc_realm_t *kdc_active_realm,
|
||||
- krb5_kdc_req *request, krb5_db_entry client,
|
||||
- krb5_db_entry server, krb5_timestamp kdc_time,
|
||||
+ krb5_kdc_req *request, krb5_db_entry *client,
|
||||
+ krb5_db_entry *server, krb5_timestamp kdc_time,
|
||||
const char **status, krb5_pa_data ***e_data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
@@ -627,7 +627,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
|
||||
}
|
||||
|
||||
/* The client must not be expired */
|
||||
- if (client.expiration && ts_after(kdc_time, client.expiration)) {
|
||||
+ if (client->expiration && ts_after(kdc_time, client->expiration)) {
|
||||
*status = "CLIENT EXPIRED";
|
||||
if (vague_errors)
|
||||
return(KRB_ERR_GENERIC);
|
||||
@@ -637,8 +637,8 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
|
||||
|
||||
/* The client's password must not be expired, unless the server is
|
||||
a KRB5_KDC_PWCHANGE_SERVICE. */
|
||||
- if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) &&
|
||||
- !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
|
||||
+ if (client->pw_expiration && ts_after(kdc_time, client->pw_expiration) &&
|
||||
+ !isflagset(server->attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
|
||||
*status = "CLIENT KEY EXPIRED";
|
||||
if (vague_errors)
|
||||
return(KRB_ERR_GENERIC);
|
||||
@@ -647,7 +647,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
|
||||
}
|
||||
|
||||
/* The server must not be expired */
|
||||
- if (server.expiration && ts_after(kdc_time, server.expiration)) {
|
||||
+ if (server->expiration && ts_after(kdc_time, server->expiration)) {
|
||||
*status = "SERVICE EXPIRED";
|
||||
return(KDC_ERR_SERVICE_EXP);
|
||||
}
|
||||
@@ -656,8 +656,8 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
|
||||
* If the client requires password changing, then only allow the
|
||||
* pwchange service.
|
||||
*/
|
||||
- if (isflagset(client.attributes, KRB5_KDB_REQUIRES_PWCHANGE) &&
|
||||
- !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
|
||||
+ if (isflagset(client->attributes, KRB5_KDB_REQUIRES_PWCHANGE) &&
|
||||
+ !isflagset(server->attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
|
||||
*status = "REQUIRED PWCHANGE";
|
||||
return(KDC_ERR_KEY_EXP);
|
||||
}
|
||||
@@ -665,37 +665,37 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
|
||||
/* Client and server must allow postdating tickets */
|
||||
if ((isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE) ||
|
||||
isflagset(request->kdc_options, KDC_OPT_POSTDATED)) &&
|
||||
- (isflagset(client.attributes, KRB5_KDB_DISALLOW_POSTDATED) ||
|
||||
- isflagset(server.attributes, KRB5_KDB_DISALLOW_POSTDATED))) {
|
||||
+ (isflagset(client->attributes, KRB5_KDB_DISALLOW_POSTDATED) ||
|
||||
+ isflagset(server->attributes, KRB5_KDB_DISALLOW_POSTDATED))) {
|
||||
*status = "POSTDATE NOT ALLOWED";
|
||||
return(KDC_ERR_CANNOT_POSTDATE);
|
||||
}
|
||||
|
||||
/* Check to see if client is locked out */
|
||||
- if (isflagset(client.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
|
||||
+ if (isflagset(client->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
|
||||
*status = "CLIENT LOCKED OUT";
|
||||
return(KDC_ERR_CLIENT_REVOKED);
|
||||
}
|
||||
|
||||
/* Check to see if server is locked out */
|
||||
- if (isflagset(server.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
|
||||
+ if (isflagset(server->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
|
||||
*status = "SERVICE LOCKED OUT";
|
||||
return(KDC_ERR_S_PRINCIPAL_UNKNOWN);
|
||||
}
|
||||
|
||||
/* Check to see if server is allowed to be a service */
|
||||
- if (isflagset(server.attributes, KRB5_KDB_DISALLOW_SVR)) {
|
||||
+ if (isflagset(server->attributes, KRB5_KDB_DISALLOW_SVR)) {
|
||||
*status = "SERVICE NOT ALLOWED";
|
||||
return(KDC_ERR_MUST_USE_USER2USER);
|
||||
}
|
||||
|
||||
- if (check_anon(kdc_active_realm, client.princ, request->server) != 0) {
|
||||
+ if (check_anon(kdc_active_realm, client->princ, request->server) != 0) {
|
||||
*status = "ANONYMOUS NOT ALLOWED";
|
||||
return(KDC_ERR_POLICY);
|
||||
}
|
||||
|
||||
/* Perform KDB module policy checks. */
|
||||
- ret = krb5_db_check_policy_as(kdc_context, request, &client, &server,
|
||||
+ ret = krb5_db_check_policy_as(kdc_context, request, client, server,
|
||||
kdc_time, status, e_data);
|
||||
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
|
||||
return errcode_to_protocol(ret);
|
||||
@@ -1568,8 +1568,8 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
|
||||
princ->pw_expiration = 0;
|
||||
clear(princ->attributes, KRB5_KDB_REQUIRES_PWCHANGE);
|
||||
|
||||
- code = validate_as_request(kdc_active_realm, request, *princ,
|
||||
- no_server, kdc_time, status, &e_data);
|
||||
+ code = validate_as_request(kdc_active_realm, request, princ,
|
||||
+ &no_server, kdc_time, status, &e_data);
|
||||
if (code) {
|
||||
krb5_db_free_principal(kdc_context, princ);
|
||||
krb5_free_pa_data(kdc_context, e_data);
|
||||
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
|
||||
index 42b7ee208..04007a8f5 100644
|
||||
--- a/src/kdc/kdc_util.h
|
||||
+++ b/src/kdc/kdc_util.h
|
||||
@@ -76,12 +76,12 @@ get_local_tgt(krb5_context context, const krb5_data *realm,
|
||||
krb5_db_entry **storage_out, krb5_keyblock *kb_out);
|
||||
|
||||
int
|
||||
-validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
|
||||
- krb5_db_entry, krb5_timestamp,
|
||||
+validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *,
|
||||
+ krb5_db_entry *, krb5_timestamp,
|
||||
const char **, krb5_pa_data ***);
|
||||
|
||||
int
|
||||
-validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
|
||||
+validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *,
|
||||
krb5_ticket *, krb5_timestamp,
|
||||
const char **, krb5_pa_data ***);
|
||||
|
||||
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
|
||||
index 554345ba5..3f4fa8499 100644
|
||||
--- a/src/kdc/tgs_policy.c
|
||||
+++ b/src/kdc/tgs_policy.c
|
||||
@@ -48,7 +48,7 @@ struct tgsflagrule {
|
||||
};
|
||||
|
||||
/* Service principal TGS policy checking functions */
|
||||
-typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry,
|
||||
+typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry *,
|
||||
krb5_ticket *, krb5_timestamp,
|
||||
const char **);
|
||||
|
||||
@@ -110,7 +110,7 @@ static const struct tgsflagrule svcdenyrules[] = {
|
||||
* A service principal can forbid some TGS-REQ options.
|
||||
*/
|
||||
static int
|
||||
-check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
|
||||
+check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry *server,
|
||||
krb5_ticket *tkt, krb5_timestamp kdc_time,
|
||||
const char **status)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
|
||||
r = &svcdenyrules[i];
|
||||
if (!(r->reqflags & req->kdc_options))
|
||||
continue;
|
||||
- if (r->checkflag & server.attributes) {
|
||||
+ if (r->checkflag & server->attributes) {
|
||||
*status = r->status;
|
||||
return r->err;
|
||||
}
|
||||
@@ -134,20 +134,20 @@ check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
|
||||
* A service principal can deny all TGS-REQs for it.
|
||||
*/
|
||||
static int
|
||||
-check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server,
|
||||
+check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry *server,
|
||||
krb5_ticket *tkt, krb5_timestamp kdc_time,
|
||||
const char **status)
|
||||
{
|
||||
- if (server.attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
|
||||
+ if (server->attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
|
||||
*status = "SERVER LOCKED OUT";
|
||||
return KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
||||
}
|
||||
- if ((server.attributes & KRB5_KDB_DISALLOW_SVR) &&
|
||||
+ if ((server->attributes & KRB5_KDB_DISALLOW_SVR) &&
|
||||
!(req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY)) {
|
||||
*status = "SERVER NOT ALLOWED";
|
||||
return KDC_ERR_MUST_USE_USER2USER;
|
||||
}
|
||||
- if (server.attributes & KRB5_KDB_DISALLOW_TGT_BASED) {
|
||||
+ if (server->attributes & KRB5_KDB_DISALLOW_TGT_BASED) {
|
||||
if (krb5_is_tgs_principal(tkt->server)) {
|
||||
*status = "TGT BASED NOT ALLOWED";
|
||||
return KDC_ERR_POLICY;
|
||||
@@ -160,17 +160,17 @@ check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server,
|
||||
* A service principal can require certain TGT flags.
|
||||
*/
|
||||
static int
|
||||
-check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server,
|
||||
+check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry *server,
|
||||
krb5_ticket *tkt,
|
||||
krb5_timestamp kdc_time, const char **status)
|
||||
{
|
||||
- if (server.attributes & KRB5_KDB_REQUIRES_HW_AUTH) {
|
||||
+ if (server->attributes & KRB5_KDB_REQUIRES_HW_AUTH) {
|
||||
if (!(tkt->enc_part2->flags & TKT_FLG_HW_AUTH)) {
|
||||
*status = "NO HW PREAUTH";
|
||||
return KRB_ERR_GENERIC;
|
||||
}
|
||||
}
|
||||
- if (server.attributes & KRB5_KDB_REQUIRES_PRE_AUTH) {
|
||||
+ if (server->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) {
|
||||
if (!(tkt->enc_part2->flags & TKT_FLG_PRE_AUTH)) {
|
||||
*status = "NO PREAUTH";
|
||||
return KRB_ERR_GENERIC;
|
||||
@@ -180,10 +180,10 @@ check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server,
|
||||
}
|
||||
|
||||
static int
|
||||
-check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
|
||||
+check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry *server, krb5_ticket *tkt,
|
||||
krb5_timestamp kdc_time, const char **status)
|
||||
{
|
||||
- if (server.expiration && ts_after(kdc_time, server.expiration)) {
|
||||
+ if (server->expiration && ts_after(kdc_time, server->expiration)) {
|
||||
*status = "SERVICE EXPIRED";
|
||||
return KDC_ERR_SERVICE_EXP;
|
||||
}
|
||||
@@ -191,8 +191,9 @@ check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
|
||||
}
|
||||
|
||||
static int
|
||||
-check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
|
||||
- krb5_timestamp kdc_time, const char **status)
|
||||
+check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry *server,
|
||||
+ krb5_ticket *tkt, krb5_timestamp kdc_time,
|
||||
+ const char **status)
|
||||
{
|
||||
int errcode;
|
||||
size_t i;
|
||||
@@ -317,7 +318,7 @@ check_tgs_tgt(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
|
||||
|
||||
int
|
||||
validate_tgs_request(kdc_realm_t *kdc_active_realm,
|
||||
- krb5_kdc_req *request, krb5_db_entry server,
|
||||
+ krb5_kdc_req *request, krb5_db_entry *server,
|
||||
krb5_ticket *ticket, krb5_timestamp kdc_time,
|
||||
const char **status, krb5_pa_data ***e_data)
|
||||
{
|
||||
@@ -367,8 +368,8 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm,
|
||||
}
|
||||
|
||||
/* Perform KDB module policy checks. */
|
||||
- ret = krb5_db_check_policy_tgs(kdc_context, request, &server,
|
||||
- ticket, status, e_data);
|
||||
+ ret = krb5_db_check_policy_tgs(kdc_context, request, server, ticket,
|
||||
+ status, e_data);
|
||||
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
|
||||
return errcode_to_protocol(ret);
|
||||
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
From f56afbeb7848322f3208edd55f2c12a9e32127f0 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 30 Mar 2020 15:26:02 -0400
|
||||
Subject: [PATCH] Correctly import "service@" GSS host-based name
|
||||
|
||||
The intended way to specify only a service in a GSS host-based name is
|
||||
to omit the "@" separator. Some applications include the separator
|
||||
but no hostname, and this happened to yield wildcard hostname behavior
|
||||
prior to commit 996353767fe8afa7f67a3b5b465e4d70e18bad7c when
|
||||
shortname qualification was added. To restore this behavior, check in
|
||||
parse_hostbased() that at least one character is present after the "@"
|
||||
separator before copying the hostname. Add a test case to t_gssapi.py.
|
||||
|
||||
ticket: 8892
|
||||
tags: pullup
|
||||
target_version: 1.18-next
|
||||
|
||||
(cherry picked from commit a2f047af0400ba8080dc26033fae2b17534501e2)
|
||||
---
|
||||
src/lib/gssapi/krb5/import_name.c | 4 ++--
|
||||
src/tests/gssapi/t_gssapi.py | 3 +++
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c
|
||||
index da2ab1423..21023dd76 100644
|
||||
--- a/src/lib/gssapi/krb5/import_name.c
|
||||
+++ b/src/lib/gssapi/krb5/import_name.c
|
||||
@@ -102,8 +102,8 @@ parse_hostbased(const char *str, size_t len,
|
||||
memcpy(service, str, servicelen);
|
||||
service[servicelen] = '\0';
|
||||
|
||||
- /* If present, copy the hostname. */
|
||||
- if (at != NULL) {
|
||||
+ /* Copy the hostname if present (at least one character after '@'). */
|
||||
+ if (len - servicelen > 1) {
|
||||
hostlen = len - servicelen - 1;
|
||||
host = malloc(hostlen + 1);
|
||||
if (host == NULL) {
|
||||
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
|
||||
index 54d5cf549..ecf982604 100755
|
||||
--- a/src/tests/gssapi/t_gssapi.py
|
||||
+++ b/src/tests/gssapi/t_gssapi.py
|
||||
@@ -47,6 +47,9 @@ realm.run(['./t_accname', 'p:service2/calvin', 'h:service2'],
|
||||
expected_msg='service2/calvin')
|
||||
realm.run(['./t_accname', 'p:service2/calvin', 'h:service1'], expected_code=1,
|
||||
expected_msg=' found in keytab but does not match server principal')
|
||||
+# Regression test for #8892 (trailing @ in name).
|
||||
+realm.run(['./t_accname', 'p:service1/andrew', 'h:service1@'],
|
||||
+ expected_msg='service1/abraham')
|
||||
|
||||
# Test with acceptor name containing service and host. Use the
|
||||
# client's un-canonicalized hostname as acceptor input to mirror what
|
||||
|
|
@ -1,371 +0,0 @@
|
|||
From c3d2c3bcafe0ac87d9cbbf37f1488ad642627fc3 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 27 May 2020 18:48:35 -0400
|
||||
Subject: [PATCH] Default dns_canonicalize_hostname to "fallback"
|
||||
|
||||
This change should mitigate some of the pain caused by the rdns=true
|
||||
default (generally associated with unwanted PTR records that cannot
|
||||
easily be changed), with a minimum of fallout.
|
||||
|
||||
Update the documentation and tests accordingly. In test environments,
|
||||
disable qualify_shortname and use the uncanonicalized system hostname
|
||||
(lowercased) to match the initial sn2princ result.
|
||||
|
||||
ticket: 8911 (new)
|
||||
---
|
||||
doc/admin/appl_servers.rst | 14 +++---
|
||||
doc/admin/conf_files/krb5_conf.rst | 9 ++--
|
||||
doc/admin/princ_dns.rst | 44 +++++++++++--------
|
||||
src/kadmin/testing/proto/krb5.conf.proto | 8 ++--
|
||||
src/kadmin/testing/scripts/env-setup.shin | 4 +-
|
||||
src/kadmin/testing/scripts/init_db | 3 +-
|
||||
src/kadmin/testing/scripts/start_servers | 3 +-
|
||||
.../testing/scripts/start_servers_local | 2 +-
|
||||
.../kadm5/unit-test/api.current/init-v2.exp | 6 +--
|
||||
src/lib/krb5/krb/init_ctx.c | 2 +-
|
||||
src/tests/dejagnu/config/default.exp | 5 +--
|
||||
src/tests/t_sn2princ.py | 5 ++-
|
||||
src/util/k5test.py | 25 +++--------
|
||||
13 files changed, 58 insertions(+), 72 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/appl_servers.rst b/doc/admin/appl_servers.rst
|
||||
index 5232db9af..afdf30297 100644
|
||||
--- a/doc/admin/appl_servers.rst
|
||||
+++ b/doc/admin/appl_servers.rst
|
||||
@@ -115,14 +115,12 @@ Getting DNS information correct
|
||||
-------------------------------
|
||||
|
||||
Several aspects of Kerberos rely on name service. When a hostname is
|
||||
-used to name a service, the Kerberos library canonicalizes the
|
||||
-hostname using forward and reverse name resolution. (The reverse name
|
||||
-resolution step can be turned off using the **rdns** variable in
|
||||
-:ref:`libdefaults`.) The result of this canonicalization must match
|
||||
-the principal entry in the host's keytab, or authentication will fail.
|
||||
-
|
||||
-Each host's canonical name must be the fully-qualified host name
|
||||
-(including the domain), and each host's IP address must
|
||||
+used to name a service, clients may canonicalize the hostname using
|
||||
+forward and possibly reverse name resolution. The result of this
|
||||
+canonicalization must match the principal entry in the host's keytab,
|
||||
+or authentication will fail. To work with all client canonicalization
|
||||
+configurations, each host's canonical name must be the fully-qualified
|
||||
+host name (including the domain), and each host's IP address must
|
||||
reverse-resolve to the canonical name.
|
||||
|
||||
Configuration of hostnames varies by operating system. On the
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index 3a8b9cf47..38f450367 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -188,11 +188,10 @@ The libdefaults section may contain any of the following relations:
|
||||
hostnames for use in service principal names. Setting this flag
|
||||
to false can improve security by reducing reliance on DNS, but
|
||||
means that short hostnames will not be canonicalized to
|
||||
- fully-qualified hostnames. The default value is true.
|
||||
-
|
||||
- If this option is set to ``fallback`` (new in release 1.18), DNS
|
||||
- canonicalization will only be performed the server hostname is not
|
||||
- found with the original name when requesting credentials.
|
||||
+ fully-qualified hostnames. If this option is set to ``fallback`` (new
|
||||
+ in release 1.18), DNS canonicalization will only be performed the
|
||||
+ server hostname is not found with the original name when
|
||||
+ requesting credentials. The default value is ``fallback``.
|
||||
|
||||
**dns_lookup_kdc**
|
||||
Indicate whether DNS SRV records should be used to locate the KDCs
|
||||
diff --git a/doc/admin/princ_dns.rst b/doc/admin/princ_dns.rst
|
||||
index e1d823f27..32a269afc 100644
|
||||
--- a/doc/admin/princ_dns.rst
|
||||
+++ b/doc/admin/princ_dns.rst
|
||||
@@ -31,27 +31,35 @@ based on rotating ``CNAME`` records in DNS.
|
||||
Service principal canonicalization
|
||||
----------------------------------
|
||||
|
||||
-MIT Kerberos clients currently always do forward resolution (looking
|
||||
-up the IPv4 and possibly IPv6 addresses using ``getaddrinfo()``) of
|
||||
-the hostname part of a host-based service principal to canonicalize
|
||||
-the hostname. They obtain the "canonical" name of the host when doing
|
||||
-so. By default, MIT Kerberos clients will also then do reverse DNS
|
||||
-resolution (looking up the hostname associated with the IPv4 or IPv6
|
||||
-address using ``getnameinfo()``) of the hostname. Using the
|
||||
-:ref:`krb5.conf(5)` setting::
|
||||
+In the MIT krb5 client library, canonicalization of host-based service
|
||||
+principals is controlled by the **dns_canonicalize_hostname**,
|
||||
+**rnds**, and **qualify_shortname** variables in :ref:`libdefaults`.
|
||||
|
||||
- [libdefaults]
|
||||
- rdns = false
|
||||
+If **dns_canonicalize_hostname** is set to ``true`` (the default value
|
||||
+before release 1.19), the client performs forward resolution by
|
||||
+looking up the IPv4 and/or IPv6 addresses of the hostname using
|
||||
+``getaddrinfo()``. This process will typically add a domain suffix to
|
||||
+the hostname if needed, and follow CNAME records in the DNS. If
|
||||
+**rdns** is also set to ``true`` (the default), the client will then
|
||||
+perform a reverse lookup of the first returned Internet address using
|
||||
+``getnameinfo()``, finding the name associated with the PTR record.
|
||||
|
||||
-will disable reverse DNS lookup on clients. The default setting is
|
||||
-"true".
|
||||
+If **dns_canonicalize_hostname** is set to ``false``, the hostname is
|
||||
+not canonicalized using DNS. If the hostname has only one component
|
||||
+(i.e. it contains no "." characters), the host's primary DNS search
|
||||
+domain will be appended, if there is one. The **qualify_shortname**
|
||||
+variable can be used to override or disable this suffix.
|
||||
+
|
||||
+If **dns_canonicalize_hostname** is set to ``fallback`` (the default
|
||||
+value in release 1.19 and later), the hostname is initially treated
|
||||
+according to the rules for ``dns_canonicalize_hostname=false``. If a
|
||||
+ticket request fails because the service principal is unknown, it the
|
||||
+hostname will be canonicalized according to the rules for
|
||||
+``dns_canonicalize_hostname=true`` and the request will be retried.
|
||||
+
|
||||
+In all cases, the hostname is converted to lowercase, and any trailing
|
||||
+dot is removed.
|
||||
|
||||
-Operating system bugs may prevent a setting of ``rdns = false`` from
|
||||
-disabling reverse DNS lookup. Some versions of GNU libc have a bug in
|
||||
-``getaddrinfo()`` that cause them to look up ``PTR`` records even when
|
||||
-not required. MIT Kerberos releases krb5-1.10.2 and newer have a
|
||||
-workaround for this problem, as does the krb5-1.9.x series as of
|
||||
-release krb5-1.9.4.
|
||||
|
||||
|
||||
Reverse DNS mismatches
|
||||
diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto
|
||||
index e710852d4..c0af716a5 100644
|
||||
--- a/src/kadmin/testing/proto/krb5.conf.proto
|
||||
+++ b/src/kadmin/testing/proto/krb5.conf.proto
|
||||
@@ -2,19 +2,19 @@
|
||||
default_realm = __REALM__
|
||||
default_keytab_name = FILE:__K5ROOT__/keytab
|
||||
dns_fallback = no
|
||||
+ qualify_shortname = ""
|
||||
plugin_base_dir = __PLUGIN_DIR__
|
||||
allow_weak_crypto = true
|
||||
|
||||
[realms]
|
||||
__REALM__ = {
|
||||
- kdc = __KDCHOST__:1750
|
||||
- admin_server = __KDCHOST__:1751
|
||||
+ kdc = __HOSTNAME__:1750
|
||||
+ admin_server = __HOSTNAME__:1751
|
||||
database_module = foobar_db2_module_blah
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
- __LOCALHOST__ = __REALM__
|
||||
- __KDCHOST__ = __REALM__
|
||||
+ __HOSTNAME__ = __REALM__
|
||||
|
||||
[logging]
|
||||
admin_server = FILE:__K5ROOT__/syslog
|
||||
diff --git a/src/kadmin/testing/scripts/env-setup.shin b/src/kadmin/testing/scripts/env-setup.shin
|
||||
index 969c5340c..88f8ad1aa 100755
|
||||
--- a/src/kadmin/testing/scripts/env-setup.shin
|
||||
+++ b/src/kadmin/testing/scripts/env-setup.shin
|
||||
@@ -71,8 +71,8 @@ BSDDB_DUMP=$TESTDIR/util/bsddb_dump; export BSDDB_DUMP
|
||||
CLNTTCL=$TESTDIR/util/kadm5_clnt_tcl; export CLNTTCL
|
||||
SRVTCL=$TESTDIR/util/kadm5_srv_tcl; export SRVTCL
|
||||
|
||||
-QUALNAME=`$BUILDTOP/tests/resolve/resolve -q | tr '[A-Z]' '[a-z]'`
|
||||
-export QUALNAME
|
||||
+HOSTNAME=`hostname | tr '[A-Z]' '[a-z]'`
|
||||
+export HOSTNAME
|
||||
|
||||
KRB5_CONFIG=$K5ROOT/krb5.conf; export KRB5_CONFIG
|
||||
KRB5_KDC_PROFILE=$K5ROOT/kdc.conf; export KRB5_KDC_PROFILE
|
||||
diff --git a/src/kadmin/testing/scripts/init_db b/src/kadmin/testing/scripts/init_db
|
||||
index e65826c96..216f62793 100755
|
||||
--- a/src/kadmin/testing/scripts/init_db
|
||||
+++ b/src/kadmin/testing/scripts/init_db
|
||||
@@ -79,8 +79,7 @@ fi
|
||||
# done
|
||||
|
||||
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
|
||||
- -e "s/__KDCHOST__/$QUALNAME/g" \
|
||||
- -e "s/__LOCALHOST__/$QUALNAME/g" \
|
||||
+ -e "s/__HOSTNAME__/$HOSTNAME/g" \
|
||||
-e "s#__MODDIR__#$MODDIR#g" \
|
||||
< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
|
||||
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
|
||||
diff --git a/src/kadmin/testing/scripts/start_servers b/src/kadmin/testing/scripts/start_servers
|
||||
index f23df0682..05519e4ee 100755
|
||||
--- a/src/kadmin/testing/scripts/start_servers
|
||||
+++ b/src/kadmin/testing/scripts/start_servers
|
||||
@@ -36,8 +36,7 @@ if [ $local = 0 ]; then
|
||||
|
||||
# Fix up the local krb5.conf to point to the remote
|
||||
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
|
||||
- -e "s/__KDCHOST__/$hostname/g" \
|
||||
- -e "s/__LOCALHOST__/$QUALNAME/g" \
|
||||
+ -e "s/__HOSTNAME__/$HOSTNAME/g" \
|
||||
-e "s#__MODDIR__#$TOP/../plugins/kdb#g"\
|
||||
-e "s#__PLUGIN_DIR__#$TOP/../plugins#g"\
|
||||
< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
|
||||
diff --git a/src/kadmin/testing/scripts/start_servers_local b/src/kadmin/testing/scripts/start_servers_local
|
||||
index 998ef9164..858e88031 100755
|
||||
--- a/src/kadmin/testing/scripts/start_servers_local
|
||||
+++ b/src/kadmin/testing/scripts/start_servers_local
|
||||
@@ -79,7 +79,7 @@ cat - > /tmp/start_servers_local$$ <<\EOF
|
||||
if { [catch {
|
||||
source $env(STOP)/testing/tcl/util.t
|
||||
set r $env(REALM)
|
||||
- set q $env(QUALNAME)
|
||||
+ set q $env(HOSTNAME)
|
||||
puts stdout [kadm5_init $env(SRVTCL) mrroot null \
|
||||
[config_params {KADM5_CONFIG_REALM} $r] \
|
||||
$KADM5_STRUCT_VERSION $KADM5_API_VERSION_3 server_handle]
|
||||
diff --git a/src/lib/kadm5/unit-test/api.current/init-v2.exp b/src/lib/kadm5/unit-test/api.current/init-v2.exp
|
||||
index 7a353d4e9..47764c212 100644
|
||||
--- a/src/lib/kadm5/unit-test/api.current/init-v2.exp
|
||||
+++ b/src/lib/kadm5/unit-test/api.current/init-v2.exp
|
||||
@@ -3,18 +3,14 @@ load_lib lib.t
|
||||
api_exit
|
||||
api_start
|
||||
|
||||
-if ![info exists RESOLVE] {
|
||||
- set RESOLVE [findfile $objdir/../../../tests/resolve/resolve]
|
||||
-}
|
||||
proc get_hostname { } {
|
||||
- global RESOLVE
|
||||
global hostname
|
||||
|
||||
if {[info exists hostname]} {
|
||||
return 1
|
||||
}
|
||||
|
||||
- catch "exec $RESOLVE -q >myname" exec_output
|
||||
+ catch "exec hostname >myname" exec_output
|
||||
if ![string match "" $exec_output] {
|
||||
send_log "$exec_output\n"
|
||||
verbose $exec_output
|
||||
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
|
||||
index 9a4741fa6..0b8ae6714 100644
|
||||
--- a/src/lib/krb5/krb/init_ctx.c
|
||||
+++ b/src/lib/krb5/krb/init_ctx.c
|
||||
@@ -237,7 +237,7 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
|
||||
ctx->enforce_ok_as_delegate = tmp;
|
||||
|
||||
retval = get_tristate(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, "fallback",
|
||||
- CANONHOST_FALLBACK, 1, &tmp);
|
||||
+ CANONHOST_FALLBACK, CANONHOST_FALLBACK, &tmp);
|
||||
if (retval)
|
||||
goto cleanup;
|
||||
ctx->dns_canonicalize_hostname = tmp;
|
||||
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp
|
||||
index 4d8c917cd..1e7777f1e 100644
|
||||
--- a/src/tests/dejagnu/config/default.exp
|
||||
+++ b/src/tests/dejagnu/config/default.exp
|
||||
@@ -268,7 +268,6 @@ foreach i {
|
||||
{KTUTIL $objdir/../../kadmin/ktutil/ktutil}
|
||||
{KLIST $objdir/../../clients/klist/klist}
|
||||
{KDESTROY $objdir/../../clients/kdestroy/kdestroy}
|
||||
- {RESOLVE $objdir/../resolve/resolve}
|
||||
{T_INETD $objdir/t_inetd}
|
||||
{KPROPLOG $objdir/../../kprop/kproplog}
|
||||
{KPASSWD $objdir/../../clients/kpasswd/kpasswd}
|
||||
@@ -462,7 +461,6 @@ proc setup_runtime_env { } {
|
||||
# 0 on failure.
|
||||
|
||||
proc get_hostname { } {
|
||||
- global RESOLVE
|
||||
global hostname
|
||||
global tmppwd
|
||||
|
||||
@@ -472,7 +470,7 @@ proc get_hostname { } {
|
||||
|
||||
envstack_push
|
||||
setup_runtime_env
|
||||
- catch "exec $RESOLVE -q >$tmppwd/hostname" exec_output
|
||||
+ catch "exec hostname >$tmppwd/hostname" exec_output
|
||||
envstack_pop
|
||||
if ![string match "" $exec_output] {
|
||||
verbose -log $exec_output
|
||||
@@ -710,6 +708,7 @@ proc setup_krb5_conf { {type client} } {
|
||||
puts $conffile "\[libdefaults\]"
|
||||
puts $conffile " default_realm = $REALMNAME"
|
||||
puts $conffile " dns_lookup_kdc = false"
|
||||
+ puts $conffile " qualify_shortname = \"\""
|
||||
if [info exists allow_weak_crypto($type)] {
|
||||
puts $conffile " allow_weak_crypto = $allow_weak_crypto($type)"
|
||||
} else {
|
||||
diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py
|
||||
index 26dcb91c2..f3e187286 100755
|
||||
--- a/src/tests/t_sn2princ.py
|
||||
+++ b/src/tests/t_sn2princ.py
|
||||
@@ -2,7 +2,8 @@ from k5test import *
|
||||
|
||||
offline = (len(args) > 0 and args[0] != "no")
|
||||
|
||||
-conf = {'domain_realm': {'kerberos.org': 'R1',
|
||||
+conf = {'libdefaults': {'dns_canonicalize_hostname': 'true'},
|
||||
+ 'domain_realm': {'kerberos.org': 'R1',
|
||||
'example.com': 'R2',
|
||||
'mit.edu': 'R3'}}
|
||||
no_rdns_conf = {'libdefaults': {'rdns': 'false'}}
|
||||
@@ -28,7 +29,7 @@ def testbase(host, nametype, princhost, princrealm, env=None):
|
||||
fail('Expected %s, got %s' % (expected, out))
|
||||
|
||||
def test(host, princhost, princrealm):
|
||||
- # Test with the host-based name type in the default environment.
|
||||
+ # Test with the host-based name type with canonicalization enabled.
|
||||
testbase(host, 'srv-hst', princhost, princrealm)
|
||||
|
||||
def testnc(host, princhost, princrealm):
|
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
||||
index eea92275d..5196cfa43 100644
|
||||
--- a/src/util/k5test.py
|
||||
+++ b/src/util/k5test.py
|
||||
@@ -193,7 +193,10 @@ Scripts may use the following functions and variables:
|
||||
|
||||
* plugins: The plugin directory in the build tree (absolute path).
|
||||
|
||||
-* hostname: This machine's fully-qualified domain name.
|
||||
+* hostname: The local hostname as it will initially appear in
|
||||
+ krb5_sname_to_principal() results. (Shortname qualification is
|
||||
+ turned off in the test environment to make this value easy to
|
||||
+ discover from Python.)
|
||||
|
||||
* null_input: A file opened to read /dev/null.
|
||||
|
||||
@@ -525,23 +528,6 @@ def _find_srctop():
|
||||
return os.path.abspath(root)
|
||||
|
||||
|
||||
-# Return the local hostname as it will be canonicalized by
|
||||
-# krb5_sname_to_principal. We can't simply use socket.getfqdn()
|
||||
-# because it explicitly prefers results containing periods and
|
||||
-# krb5_sname_to_principal doesn't care.
|
||||
-def _get_hostname():
|
||||
- hostname = socket.gethostname()
|
||||
- try:
|
||||
- ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
|
||||
- except socket.gaierror as e:
|
||||
- fail('Local hostname "%s" does not resolve: %s.' % (hostname, e[1]))
|
||||
- (family, socktype, proto, canonname, sockaddr) = ai[0]
|
||||
- try:
|
||||
- name = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
|
||||
- except socket.gaierror:
|
||||
- return canonname.lower()
|
||||
- return name[0].lower()
|
||||
-
|
||||
# Parse command line arguments, setting global option variables. Also
|
||||
# sets the global variable args to the positional arguments, which may
|
||||
# be used by the test script.
|
||||
@@ -1263,6 +1249,7 @@ _default_krb5_conf = {
|
||||
'libdefaults': {
|
||||
'default_realm': '$realm',
|
||||
'dns_lookup_kdc': 'false',
|
||||
+ 'qualify_shortname': '',
|
||||
'plugin_base_dir': '$plugins'},
|
||||
'realms': {'$realm': {
|
||||
'kdc': '$hostname:$port0',
|
||||
@@ -1356,7 +1343,7 @@ buildtop = _find_buildtop()
|
||||
srctop = _find_srctop()
|
||||
plugins = os.path.join(buildtop, 'plugins')
|
||||
runenv = _import_runenv()
|
||||
-hostname = _get_hostname()
|
||||
+hostname = socket.gethostname().lower()
|
||||
null_input = open(os.devnull, 'r')
|
||||
|
||||
# A DB pass is a tuple of: name, kdc_conf.
|
||||
|
|
@ -1,425 +0,0 @@
|
|||
From 51a9f8e7498591b22558a7a61d42a821030f9c4e Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 28 Feb 2020 10:11:49 +0100
|
||||
Subject: [PATCH] Do expiration warnings for all init_creds APIs
|
||||
|
||||
Move the password expiration warning code from gic_pwd.c to
|
||||
get_in_tkt.c. Call it from init_creds_step_reply() on successful
|
||||
completion.
|
||||
|
||||
[ghudson@mit.edu: added test case; simplified doc comment; moved call
|
||||
site to init_creds_step_reply(); rewrote commit message]
|
||||
|
||||
ticket: 8893 (new)
|
||||
(cherry picked from commit e1efb890f7ac31b32c68ab816ef118dbfb5a8c7e)
|
||||
---
|
||||
src/include/krb5/krb5.hin | 9 ++-
|
||||
src/lib/krb5/krb/get_in_tkt.c | 112 ++++++++++++++++++++++++++++++
|
||||
src/lib/krb5/krb/gic_pwd.c | 110 -----------------------------
|
||||
src/lib/krb5/krb/t_expire_warn.c | 47 +++++++++----
|
||||
src/lib/krb5/krb/t_expire_warn.py | 22 ++++--
|
||||
5 files changed, 165 insertions(+), 135 deletions(-)
|
||||
|
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||
index 6355e6540..f8269fb17 100644
|
||||
--- a/src/include/krb5/krb5.hin
|
||||
+++ b/src/include/krb5/krb5.hin
|
||||
@@ -7174,11 +7174,10 @@ typedef void
|
||||
*
|
||||
* Set a callback to receive password and account expiration times.
|
||||
*
|
||||
- * This option only applies to krb5_get_init_creds_password(). @a cb will be
|
||||
- * invoked if and only if credentials are successfully acquired. The callback
|
||||
- * will receive the @a context from the krb5_get_init_creds_password() call and
|
||||
- * the @a data argument supplied with this API. The remaining arguments should
|
||||
- * be interpreted as follows:
|
||||
+ * @a cb will be invoked if and only if credentials are successfully acquired.
|
||||
+ * The callback will receive the @a context from the calling function and the
|
||||
+ * @a data argument supplied with this API. The remaining arguments should be
|
||||
+ * interpreted as follows:
|
||||
*
|
||||
* If @a is_last_req is true, then the KDC reply contained last-req entries
|
||||
* which unambiguously indicated the password expiration, account expiration,
|
||||
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
||||
index 870df62a1..cc0f70e83 100644
|
||||
--- a/src/lib/krb5/krb/get_in_tkt.c
|
||||
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
||||
@@ -1482,6 +1482,116 @@ accept_method_data(krb5_context context, krb5_init_creds_context ctx)
|
||||
ctx->method_padata);
|
||||
}
|
||||
|
||||
+/* Return the password expiry time indicated by enc_part2. Set *is_last_req
|
||||
+ * if the information came from a last_req value. */
|
||||
+static void
|
||||
+get_expiry_times(krb5_enc_kdc_rep_part *enc_part2, krb5_timestamp *pw_exp,
|
||||
+ krb5_timestamp *acct_exp, krb5_boolean *is_last_req)
|
||||
+{
|
||||
+ krb5_last_req_entry **last_req;
|
||||
+ krb5_int32 lr_type;
|
||||
+
|
||||
+ *pw_exp = 0;
|
||||
+ *acct_exp = 0;
|
||||
+ *is_last_req = FALSE;
|
||||
+
|
||||
+ /* Look for last-req entries for password or account expiration. */
|
||||
+ if (enc_part2->last_req) {
|
||||
+ for (last_req = enc_part2->last_req; *last_req; last_req++) {
|
||||
+ lr_type = (*last_req)->lr_type;
|
||||
+ if (lr_type == KRB5_LRQ_ALL_PW_EXPTIME ||
|
||||
+ lr_type == KRB5_LRQ_ONE_PW_EXPTIME) {
|
||||
+ *is_last_req = TRUE;
|
||||
+ *pw_exp = (*last_req)->value;
|
||||
+ } else if (lr_type == KRB5_LRQ_ALL_ACCT_EXPTIME ||
|
||||
+ lr_type == KRB5_LRQ_ONE_ACCT_EXPTIME) {
|
||||
+ *is_last_req = TRUE;
|
||||
+ *acct_exp = (*last_req)->value;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* If we didn't find any, use the ambiguous key_exp field. */
|
||||
+ if (*is_last_req == FALSE)
|
||||
+ *pw_exp = enc_part2->key_exp;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Send an appropriate warning prompter if as_reply indicates that the password
|
||||
+ * is going to expire soon. If an expire callback was provided, use that
|
||||
+ * instead.
|
||||
+ */
|
||||
+static void
|
||||
+warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||
+ krb5_prompter_fct prompter, void *data,
|
||||
+ const char *in_tkt_service, krb5_kdc_rep *as_reply)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_expire_callback_func expire_cb;
|
||||
+ void *expire_data;
|
||||
+ krb5_timestamp pw_exp, acct_exp, now;
|
||||
+ krb5_boolean is_last_req;
|
||||
+ krb5_deltat delta;
|
||||
+ char ts[256], banner[1024];
|
||||
+
|
||||
+ if (as_reply == NULL || as_reply->enc_part2 == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ get_expiry_times(as_reply->enc_part2, &pw_exp, &acct_exp, &is_last_req);
|
||||
+
|
||||
+ k5_gic_opt_get_expire_cb(options, &expire_cb, &expire_data);
|
||||
+ if (expire_cb != NULL) {
|
||||
+ /* Invoke the expire callback and don't send prompter warnings. */
|
||||
+ (*expire_cb)(context, expire_data, pw_exp, acct_exp, is_last_req);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Don't warn if no password expiry value was sent. */
|
||||
+ if (pw_exp == 0)
|
||||
+ return;
|
||||
+
|
||||
+ /* Don't warn if the password is being changed. */
|
||||
+ if (in_tkt_service && strcmp(in_tkt_service, "kadmin/changepw") == 0)
|
||||
+ return;
|
||||
+
|
||||
+ /*
|
||||
+ * If the expiry time came from a last_req field, assume the KDC wants us
|
||||
+ * to warn. Otherwise, warn only if the expiry time is less than a week
|
||||
+ * from now.
|
||||
+ */
|
||||
+ ret = krb5_timeofday(context, &now);
|
||||
+ if (ret != 0)
|
||||
+ return;
|
||||
+ if (!is_last_req &&
|
||||
+ (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
|
||||
+ return;
|
||||
+
|
||||
+ if (!prompter)
|
||||
+ return;
|
||||
+
|
||||
+ ret = krb5_timestamp_to_string(pw_exp, ts, sizeof(ts));
|
||||
+ if (ret != 0)
|
||||
+ return;
|
||||
+
|
||||
+ delta = ts_delta(pw_exp, now);
|
||||
+ if (delta < 3600) {
|
||||
+ snprintf(banner, sizeof(banner),
|
||||
+ _("Warning: Your password will expire in less than one hour "
|
||||
+ "on %s"), ts);
|
||||
+ } else if (delta < 86400 * 2) {
|
||||
+ snprintf(banner, sizeof(banner),
|
||||
+ _("Warning: Your password will expire in %d hour%s on %s"),
|
||||
+ delta / 3600, delta < 7200 ? "" : "s", ts);
|
||||
+ } else {
|
||||
+ snprintf(banner, sizeof(banner),
|
||||
+ _("Warning: Your password will expire in %d days on %s"),
|
||||
+ delta / 86400, ts);
|
||||
+ }
|
||||
+
|
||||
+ /* PROMPTER_INVOCATION */
|
||||
+ (*prompter)(context, data, 0, banner, 0, 0);
|
||||
+}
|
||||
+
|
||||
static krb5_error_code
|
||||
init_creds_step_reply(krb5_context context,
|
||||
krb5_init_creds_context ctx,
|
||||
@@ -1693,6 +1803,8 @@ init_creds_step_reply(krb5_context context,
|
||||
|
||||
/* success */
|
||||
ctx->complete = TRUE;
|
||||
+ warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
|
||||
+ ctx->in_tkt_service, ctx->reply);
|
||||
|
||||
cleanup:
|
||||
krb5_free_pa_data(context, kdc_padata);
|
||||
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
|
||||
index 14ce23ba4..54e0a8ebe 100644
|
||||
--- a/src/lib/krb5/krb/gic_pwd.c
|
||||
+++ b/src/lib/krb5/krb/gic_pwd.c
|
||||
@@ -133,113 +133,6 @@ krb5_init_creds_set_password(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/* Return the password expiry time indicated by enc_part2. Set *is_last_req
|
||||
- * if the information came from a last_req value. */
|
||||
-static void
|
||||
-get_expiry_times(krb5_enc_kdc_rep_part *enc_part2, krb5_timestamp *pw_exp,
|
||||
- krb5_timestamp *acct_exp, krb5_boolean *is_last_req)
|
||||
-{
|
||||
- krb5_last_req_entry **last_req;
|
||||
- krb5_int32 lr_type;
|
||||
-
|
||||
- *pw_exp = 0;
|
||||
- *acct_exp = 0;
|
||||
- *is_last_req = FALSE;
|
||||
-
|
||||
- /* Look for last-req entries for password or account expiration. */
|
||||
- if (enc_part2->last_req) {
|
||||
- for (last_req = enc_part2->last_req; *last_req; last_req++) {
|
||||
- lr_type = (*last_req)->lr_type;
|
||||
- if (lr_type == KRB5_LRQ_ALL_PW_EXPTIME ||
|
||||
- lr_type == KRB5_LRQ_ONE_PW_EXPTIME) {
|
||||
- *is_last_req = TRUE;
|
||||
- *pw_exp = (*last_req)->value;
|
||||
- } else if (lr_type == KRB5_LRQ_ALL_ACCT_EXPTIME ||
|
||||
- lr_type == KRB5_LRQ_ONE_ACCT_EXPTIME) {
|
||||
- *is_last_req = TRUE;
|
||||
- *acct_exp = (*last_req)->value;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* If we didn't find any, use the ambiguous key_exp field. */
|
||||
- if (*is_last_req == FALSE)
|
||||
- *pw_exp = enc_part2->key_exp;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * Send an appropriate warning prompter if as_reply indicates that the password
|
||||
- * is going to expire soon. If an expire callback was provided, use that
|
||||
- * instead.
|
||||
- */
|
||||
-static void
|
||||
-warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||
- krb5_prompter_fct prompter, void *data,
|
||||
- const char *in_tkt_service, krb5_kdc_rep *as_reply)
|
||||
-{
|
||||
- krb5_error_code ret;
|
||||
- krb5_expire_callback_func expire_cb;
|
||||
- void *expire_data;
|
||||
- krb5_timestamp pw_exp, acct_exp, now;
|
||||
- krb5_boolean is_last_req;
|
||||
- krb5_deltat delta;
|
||||
- char ts[256], banner[1024];
|
||||
-
|
||||
- get_expiry_times(as_reply->enc_part2, &pw_exp, &acct_exp, &is_last_req);
|
||||
-
|
||||
- k5_gic_opt_get_expire_cb(options, &expire_cb, &expire_data);
|
||||
- if (expire_cb != NULL) {
|
||||
- /* Invoke the expire callback and don't send prompter warnings. */
|
||||
- (*expire_cb)(context, expire_data, pw_exp, acct_exp, is_last_req);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* Don't warn if no password expiry value was sent. */
|
||||
- if (pw_exp == 0)
|
||||
- return;
|
||||
-
|
||||
- /* Don't warn if the password is being changed. */
|
||||
- if (in_tkt_service && strcmp(in_tkt_service, "kadmin/changepw") == 0)
|
||||
- return;
|
||||
-
|
||||
- /*
|
||||
- * If the expiry time came from a last_req field, assume the KDC wants us
|
||||
- * to warn. Otherwise, warn only if the expiry time is less than a week
|
||||
- * from now.
|
||||
- */
|
||||
- ret = krb5_timeofday(context, &now);
|
||||
- if (ret != 0)
|
||||
- return;
|
||||
- if (!is_last_req &&
|
||||
- (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
|
||||
- return;
|
||||
-
|
||||
- if (!prompter)
|
||||
- return;
|
||||
-
|
||||
- ret = krb5_timestamp_to_string(pw_exp, ts, sizeof(ts));
|
||||
- if (ret != 0)
|
||||
- return;
|
||||
-
|
||||
- delta = ts_delta(pw_exp, now);
|
||||
- if (delta < 3600) {
|
||||
- snprintf(banner, sizeof(banner),
|
||||
- _("Warning: Your password will expire in less than one hour "
|
||||
- "on %s"), ts);
|
||||
- } else if (delta < 86400*2) {
|
||||
- snprintf(banner, sizeof(banner),
|
||||
- _("Warning: Your password will expire in %d hour%s on %s"),
|
||||
- delta / 3600, delta < 7200 ? "" : "s", ts);
|
||||
- } else {
|
||||
- snprintf(banner, sizeof(banner),
|
||||
- _("Warning: Your password will expire in %d days on %s"),
|
||||
- delta / 86400, ts);
|
||||
- }
|
||||
-
|
||||
- /* PROMPTER_INVOCATION */
|
||||
- (*prompter)(context, data, 0, banner, 0, 0);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Create a temporary options structure for getting a kadmin/changepw ticket,
|
||||
* based on the appplication-specified options. Propagate all application
|
||||
@@ -496,9 +389,6 @@ krb5_get_init_creds_password(krb5_context context,
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
- if (ret == 0)
|
||||
- warn_pw_expiry(context, options, prompter, data, in_tkt_service,
|
||||
- as_reply);
|
||||
free(chpw_opts);
|
||||
zapfree(gakpw.storage.data, gakpw.storage.length);
|
||||
memset(pw0array, 0, sizeof(pw0array));
|
||||
diff --git a/src/lib/krb5/krb/t_expire_warn.c b/src/lib/krb5/krb/t_expire_warn.c
|
||||
index 1e59acba1..dc8dc8fb3 100644
|
||||
--- a/src/lib/krb5/krb/t_expire_warn.c
|
||||
+++ b/src/lib/krb5/krb/t_expire_warn.c
|
||||
@@ -28,6 +28,13 @@
|
||||
|
||||
static int exp_dummy, prompt_dummy;
|
||||
|
||||
+static void
|
||||
+check(krb5_error_code code)
|
||||
+{
|
||||
+ if (code != 0)
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
static krb5_error_code
|
||||
prompter_cb(krb5_context ctx, void *data, const char *name,
|
||||
const char *banner, int num_prompts, krb5_prompt prompts[])
|
||||
@@ -52,36 +59,48 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
krb5_context ctx;
|
||||
+ krb5_init_creds_context icctx;
|
||||
krb5_get_init_creds_opt *opt;
|
||||
char *user, *password, *service = NULL;
|
||||
- krb5_boolean use_cb;
|
||||
+ krb5_boolean use_cb, stepwise;
|
||||
krb5_principal client;
|
||||
krb5_creds creds;
|
||||
|
||||
- if (argc < 4) {
|
||||
- fprintf(stderr, "Usage: %s username password {1|0} [service]\n",
|
||||
+ if (argc < 5) {
|
||||
+ fprintf(stderr, "Usage: %s username password {1|0} {1|0} [service]\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
user = argv[1];
|
||||
password = argv[2];
|
||||
use_cb = atoi(argv[3]);
|
||||
- if (argc >= 5)
|
||||
- service = argv[4];
|
||||
+ stepwise = atoi(argv[4]);
|
||||
+ if (argc >= 6)
|
||||
+ service = argv[5];
|
||||
|
||||
- assert(krb5_init_context(&ctx) == 0);
|
||||
- assert(krb5_get_init_creds_opt_alloc(ctx, &opt) == 0);
|
||||
+ check(krb5_init_context(&ctx));
|
||||
+ check(krb5_get_init_creds_opt_alloc(ctx, &opt));
|
||||
if (use_cb) {
|
||||
- assert(krb5_get_init_creds_opt_set_expire_callback(ctx, opt, expire_cb,
|
||||
- &exp_dummy) == 0);
|
||||
+ check(krb5_get_init_creds_opt_set_expire_callback(ctx, opt, expire_cb,
|
||||
+ &exp_dummy));
|
||||
+ }
|
||||
+ check(krb5_parse_name(ctx, user, &client));
|
||||
+ if (stepwise) {
|
||||
+ check(krb5_init_creds_init(ctx, client, prompter_cb, &prompt_dummy, 0,
|
||||
+ opt, &icctx));
|
||||
+ krb5_init_creds_set_password(ctx, icctx, password);
|
||||
+ if (service != NULL)
|
||||
+ check(krb5_init_creds_set_service(ctx, icctx, service));
|
||||
+ check(krb5_init_creds_get(ctx, icctx));
|
||||
+ krb5_init_creds_free(ctx, icctx);
|
||||
+ } else {
|
||||
+ check(krb5_get_init_creds_password(ctx, &creds, client, password,
|
||||
+ prompter_cb, &prompt_dummy, 0,
|
||||
+ service, opt));
|
||||
+ krb5_free_cred_contents(ctx, &creds);
|
||||
}
|
||||
- assert(krb5_parse_name(ctx, user, &client) == 0);
|
||||
- assert(krb5_get_init_creds_password(ctx, &creds, client, password,
|
||||
- prompter_cb, &prompt_dummy, 0, service,
|
||||
- opt) == 0);
|
||||
krb5_get_init_creds_opt_free(ctx, opt);
|
||||
krb5_free_principal(ctx, client);
|
||||
- krb5_free_cred_contents(ctx, &creds);
|
||||
krb5_free_context(ctx);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/src/lib/krb5/krb/t_expire_warn.py b/src/lib/krb5/krb/t_expire_warn.py
|
||||
index 781f2728a..e163cc7e4 100755
|
||||
--- a/src/lib/krb5/krb/t_expire_warn.py
|
||||
+++ b/src/lib/krb5/krb/t_expire_warn.py
|
||||
@@ -34,23 +34,33 @@ realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '12 hours',
|
||||
realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '3 days', 'days'])
|
||||
|
||||
# Check for expected prompter warnings when no expire callback is used.
|
||||
-output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '0'])
|
||||
+output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '0', '0'])
|
||||
if output:
|
||||
fail('Unexpected output for noexpire')
|
||||
-realm.run(['./t_expire_warn', 'minutes', 'pass', '0'],
|
||||
+realm.run(['./t_expire_warn', 'minutes', 'pass', '0', '0'],
|
||||
expected_msg=' less than one hour on ')
|
||||
-realm.run(['./t_expire_warn', 'hours', 'pass', '0'], expected_msg=' hours on ')
|
||||
-realm.run(['./t_expire_warn', 'days', 'pass', '0'], expected_msg=' days on ')
|
||||
+realm.run(['./t_expire_warn', 'hours', 'pass', '0', '0'],
|
||||
+ expected_msg=' hours on ')
|
||||
+realm.run(['./t_expire_warn', 'days', 'pass', '0', '0'],
|
||||
+ expected_msg=' days on ')
|
||||
+# Try one case with the stepwise interface.
|
||||
+realm.run(['./t_expire_warn', 'days', 'pass', '0', '1'],
|
||||
+ expected_msg=' days on ')
|
||||
|
||||
# Check for expected expire callback behavior. These tests are
|
||||
# carefully agnostic about whether the KDC supports last_req fields,
|
||||
# and could be made more specific if last_req support is added.
|
||||
-output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '1'])
|
||||
+output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '1', '0'])
|
||||
if 'password_expiration = 0\n' not in output or \
|
||||
'account_expiration = 0\n' not in output or \
|
||||
'is_last_req = ' not in output:
|
||||
fail('Expected callback output not seen for noexpire')
|
||||
-output = realm.run(['./t_expire_warn', 'days', 'pass', '1'])
|
||||
+output = realm.run(['./t_expire_warn', 'days', 'pass', '1', '0'])
|
||||
+if 'password_expiration = ' not in output or \
|
||||
+ 'password_expiration = 0\n' in output:
|
||||
+ fail('Expected non-zero password expiration not seen for days')
|
||||
+# Try one case with the stepwise interface.
|
||||
+output = realm.run(['./t_expire_warn', 'days', 'pass', '1', '1'])
|
||||
if 'password_expiration = ' not in output or \
|
||||
'password_expiration = 0\n' in output:
|
||||
fail('Expected non-zero password expiration not seen for days')
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
From b27a2f1f330afed53b034a66031f9a801b4568b7 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 23 Mar 2020 19:10:03 -0400
|
||||
Subject: [PATCH] Eliminate redundant PKINIT responder invocation
|
||||
|
||||
In pkinit_client_prep_questions(), only act if the input padata type
|
||||
is KRB5_PADATA_PK_AS_REQ. Otherwise we will ask questions again when
|
||||
the KDC issues a ticket.
|
||||
|
||||
Commit 7621d2f9a87214327ca3b2594e34dc7cea84596b (ticket 8242)
|
||||
unintentionally changed the behavior of pkinit_load_fs_cert_and_key(),
|
||||
causing pkinit_client_prep_questions() to do nothing on its first
|
||||
call. Restore the original behavior of returning 0 when prompting is
|
||||
deferred.
|
||||
|
||||
Modify the existing "FILE identity, password on key (responder)"
|
||||
PKINIT test to check that the responder is only invoked once.
|
||||
|
||||
ticket: 8885
|
||||
(cherry picked from commit f1286842ce7b9e507a4ce0a47f44ab361a98be63)
|
||||
---
|
||||
src/plugins/preauth/pkinit/pkinit_clnt.c | 5 +++++
|
||||
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 13 +++++++------
|
||||
src/tests/t_pkinit.py | 11 +++++++----
|
||||
3 files changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
index 2f0431991..9b991ffe0 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
|
||||
@@ -897,6 +897,11 @@ pkinit_client_prep_questions(krb5_context context,
|
||||
k5_json_object jval = NULL;
|
||||
k5_json_number jflag = NULL;
|
||||
|
||||
+ /* Don't ask questions for the informational padata items or when the
|
||||
+ * ticket is issued. */
|
||||
+ if (pa_data->pa_type != KRB5_PADATA_PK_AS_REQ)
|
||||
+ return 0;
|
||||
+
|
||||
if (!reqctx->identity_initialized) {
|
||||
pkinit_client_profile(context, plgctx, reqctx, cb, rock,
|
||||
&request->server->realm);
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index dd718c2be..dbb054378 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -4362,17 +4362,18 @@ pkinit_load_fs_cert_and_key(krb5_context context,
|
||||
|
||||
/* Load the certificate. */
|
||||
retval = get_cert(certname, &x);
|
||||
- if (retval != 0 || x == NULL) {
|
||||
- retval = oerr(context, 0, _("Cannot read certificate file '%s'"),
|
||||
+ if (retval) {
|
||||
+ retval = oerr(context, retval, _("Cannot read certificate file '%s'"),
|
||||
certname);
|
||||
- goto cleanup;
|
||||
}
|
||||
+ if (retval || x == NULL)
|
||||
+ goto cleanup;
|
||||
/* Load the key. */
|
||||
retval = get_key(context, id_cryptoctx, keyname, fsname, &y, password);
|
||||
- if (retval != 0 || y == NULL) {
|
||||
- retval = oerr(context, 0, _("Cannot read key file '%s'"), fsname);
|
||||
+ if (retval)
|
||||
+ retval = oerr(context, retval, _("Cannot read key file '%s'"), fsname);
|
||||
+ if (retval || y == NULL)
|
||||
goto cleanup;
|
||||
- }
|
||||
|
||||
id_cryptoctx->creds[cindex] = malloc(sizeof(struct _pkinit_cred_info));
|
||||
if (id_cryptoctx->creds[cindex] == NULL) {
|
||||
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
|
||||
index 69daf4987..ecd450e8a 100755
|
||||
--- a/src/tests/t_pkinit.py
|
||||
+++ b/src/tests/t_pkinit.py
|
||||
@@ -248,10 +248,13 @@ realm.run(['./adata', realm.host_princ],
|
||||
# supplied by the responder.
|
||||
# Supply the response in raw form.
|
||||
mark('FILE identity, password on key (responder)')
|
||||
-realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity,
|
||||
- '-r', 'pkinit={"%s": "encrypted"}' % file_enc_identity,
|
||||
- '-X', 'X509_user_identity=%s' % file_enc_identity,
|
||||
- realm.user_princ])
|
||||
+out = realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity,
|
||||
+ '-r', 'pkinit={"%s": "encrypted"}' % file_enc_identity,
|
||||
+ '-X', 'X509_user_identity=%s' % file_enc_identity,
|
||||
+ realm.user_princ])
|
||||
+# Regression test for #8885 (password question asked twice).
|
||||
+if out.count('OK: ') != 1:
|
||||
+ fail('Wrong number of responder calls')
|
||||
# Supply the response through the convenience API.
|
||||
realm.run(['./responder', '-X', 'X509_user_identity=%s' % file_enc_identity,
|
||||
'-p', '%s=%s' % (file_enc_identity, 'encrypted'), realm.user_princ])
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
From 5b42970afea248889fd3350448a40045d467ff3f Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 28 Jul 2020 12:58:26 -0400
|
||||
Subject: [PATCH] Fix input length checking in SPNEGO DER decoding
|
||||
|
||||
In get_mech_set(), check the length before reading the first byte, and
|
||||
decrease the length by the tag byte when reading and verifying the
|
||||
sequence length.
|
||||
|
||||
In get_req_flags(), check the length before reading the first byte,
|
||||
and check the context tag length after decoding it.
|
||||
|
||||
ticket: 8933 (new)
|
||||
tags: pullup
|
||||
target_version: 1.18-next
|
||||
target_version: 1.17-next
|
||||
|
||||
(cherry picked from commit 64f4b75a22212681ca293f8f09ddd24b0244d5b4)
|
||||
---
|
||||
src/lib/gssapi/spnego/spnego_mech.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
|
||||
index 4cf011143..13c351620 100644
|
||||
--- a/src/lib/gssapi/spnego/spnego_mech.c
|
||||
+++ b/src/lib/gssapi/spnego/spnego_mech.c
|
||||
@@ -3462,14 +3462,14 @@ get_mech_set(OM_uint32 *minor_status, unsigned char **buff_in,
|
||||
unsigned char *start;
|
||||
int i;
|
||||
|
||||
- if (**buff_in != SEQUENCE_OF)
|
||||
+ if (buff_length < 1 || **buff_in != SEQUENCE_OF)
|
||||
return (NULL);
|
||||
|
||||
start = *buff_in;
|
||||
(*buff_in)++;
|
||||
|
||||
- length = gssint_get_der_length(buff_in, buff_length, &bytes);
|
||||
- if (length < 0 || buff_length - bytes < (unsigned int)length)
|
||||
+ length = gssint_get_der_length(buff_in, buff_length - 1, &bytes);
|
||||
+ if (length < 0 || buff_length - 1 - bytes < (unsigned int)length)
|
||||
return NULL;
|
||||
|
||||
major_status = gss_create_empty_oid_set(minor_status,
|
||||
@@ -3549,11 +3549,11 @@ get_req_flags(unsigned char **buff_in, OM_uint32 bodysize,
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
- if (**buff_in != (CONTEXT | 0x01))
|
||||
+ if (bodysize < 1 || **buff_in != (CONTEXT | 0x01))
|
||||
return (0);
|
||||
|
||||
if (g_get_tag_and_length(buff_in, (CONTEXT | 0x01),
|
||||
- bodysize, &len) < 0)
|
||||
+ bodysize, &len) < 0 || len != 4)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
if (*(*buff_in)++ != BIT_STRING)
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
From ff47523d7d812fba24106f416aafa5d1f2c433a2 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 24 Jul 2020 16:05:24 -0400
|
||||
Subject: [PATCH] Fix leak in KERB_AP_OPTIONS_CBT server support
|
||||
|
||||
In check_cbt(), use a local variable to hold the retrieved authdata
|
||||
list, and free it before returning.
|
||||
|
||||
ticket: 8900
|
||||
(cherry picked from commit bf2ddff13c178e0c291f8fb382b040080d159e4f)
|
||||
---
|
||||
src/lib/gssapi/krb5/accept_sec_context.c | 23 +++++++++++++----------
|
||||
1 file changed, 13 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
index 175a24c4e..3d5b84b15 100644
|
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
@@ -433,27 +433,30 @@ static const uint8_t null_cb[CB_MD5_LEN];
|
||||
/* Look for AP_OPTIONS in authdata. If present and the options include
|
||||
* KERB_AP_OPTIONS_CBT, set *cbt_out to true. */
|
||||
static krb5_error_code
|
||||
-check_cbt(krb5_context context, krb5_authdata **authdata,
|
||||
+check_cbt(krb5_context context, krb5_authdata *const *authdata,
|
||||
krb5_boolean *cbt_out)
|
||||
{
|
||||
krb5_error_code code;
|
||||
+ krb5_authdata **ad;
|
||||
uint32_t ad_ap_options;
|
||||
const uint32_t KERB_AP_OPTIONS_CBT = 0x4000;
|
||||
|
||||
*cbt_out = FALSE;
|
||||
|
||||
code = krb5_find_authdata(context, NULL, authdata,
|
||||
- KRB5_AUTHDATA_AP_OPTIONS, &authdata);
|
||||
- if (code || authdata == NULL)
|
||||
+ KRB5_AUTHDATA_AP_OPTIONS, &ad);
|
||||
+ if (code || ad == NULL)
|
||||
return code;
|
||||
- if (authdata[1] != NULL || authdata[0]->length != 4)
|
||||
- return KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
+ if (ad[1] != NULL || ad[0]->length != 4) {
|
||||
+ code = KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
+ } else {
|
||||
+ ad_ap_options = load_32_le(ad[0]->contents);
|
||||
+ if (ad_ap_options & KERB_AP_OPTIONS_CBT)
|
||||
+ *cbt_out = TRUE;
|
||||
+ }
|
||||
|
||||
- ad_ap_options = load_32_le(authdata[0]->contents);
|
||||
- if (ad_ap_options & KERB_AP_OPTIONS_CBT)
|
||||
- *cbt_out = TRUE;
|
||||
-
|
||||
- return 0;
|
||||
+ krb5_free_authdata(context, ad);
|
||||
+ return code;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
From c3d96fca46cb2cc3ee9f4c2e2a4ed98bad3e310a Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 15 Oct 2020 18:15:29 -0400
|
||||
Subject: [PATCH] Fix minor static analysis defects
|
||||
|
||||
Remove an unused variable in krb5_ldap_create(). Handle the return
|
||||
value from krb5_dbe_get_string() in the certauth test plugin module.
|
||||
Handle the return value from k5_expand_path_tokens() in
|
||||
k5_rc_default(). Remove dead assignments in
|
||||
krb5_get_credentials_for_user() and kg_accept_krb5().
|
||||
|
||||
[ghudson@mit.edu: squashed and edited commit message; simplified
|
||||
k5_rc_default() change]
|
||||
|
||||
(cherry picked from commit b27461141810fddd299764928649148c5d0e99f3)
|
||||
---
|
||||
src/lib/gssapi/krb5/accept_sec_context.c | 4 +---
|
||||
src/lib/krb5/krb/s4u_creds.c | 1 -
|
||||
src/lib/krb5/rcache/rc_base.c | 2 ++
|
||||
src/plugins/certauth/test/main.c | 3 +++
|
||||
src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c | 4 ----
|
||||
5 files changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
index 3d5b84b15..e2c5e2b59 100644
|
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
@@ -671,7 +671,7 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
krb5_auth_context auth_context = NULL;
|
||||
krb5_ticket * ticket = NULL;
|
||||
const gss_OID_desc *mech_used = NULL;
|
||||
- OM_uint32 major_status = GSS_S_FAILURE;
|
||||
+ OM_uint32 major_status;
|
||||
OM_uint32 tmp_minor_status;
|
||||
krb5_error krb_error_data;
|
||||
krb5_data scratch;
|
||||
@@ -878,8 +878,6 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
if (major_status != GSS_S_COMPLETE)
|
||||
goto fail;
|
||||
|
||||
- major_status = GSS_S_FAILURE;
|
||||
-
|
||||
if (exts->iakerb.conv && !exts->iakerb.verified) {
|
||||
major_status = GSS_S_BAD_SIG;
|
||||
goto fail;
|
||||
diff --git a/src/lib/krb5/krb/s4u_creds.c b/src/lib/krb5/krb/s4u_creds.c
|
||||
index d8f486dc6..35a8843e5 100644
|
||||
--- a/src/lib/krb5/krb/s4u_creds.c
|
||||
+++ b/src/lib/krb5/krb/s4u_creds.c
|
||||
@@ -714,7 +714,6 @@ krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
|
||||
} else if (code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) {
|
||||
goto cleanup;
|
||||
}
|
||||
- code = 0;
|
||||
}
|
||||
|
||||
/* Note the authdata we asked for in the output creds. */
|
||||
diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c
|
||||
index 5f456d1f3..f9a482318 100644
|
||||
--- a/src/lib/krb5/rcache/rc_base.c
|
||||
+++ b/src/lib/krb5/rcache/rc_base.c
|
||||
@@ -56,6 +56,8 @@ k5_rc_default(krb5_context context, krb5_rcache *rc_out)
|
||||
&profstr) == 0 && profstr != NULL) {
|
||||
ret = k5_expand_path_tokens(context, profstr, &rcname);
|
||||
profile_release_string(profstr);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
ret = k5_rc_resolve(context, rcname, rc_out);
|
||||
free(rcname);
|
||||
return ret;
|
||||
diff --git a/src/plugins/certauth/test/main.c b/src/plugins/certauth/test/main.c
|
||||
index d4633b8cd..7e7a3ef4c 100644
|
||||
--- a/src/plugins/certauth/test/main.c
|
||||
+++ b/src/plugins/certauth/test/main.c
|
||||
@@ -171,6 +171,9 @@ test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
|
||||
|
||||
ret = krb5_dbe_get_string(context, (krb5_db_entry *)db_entry, "hwauth",
|
||||
&strval);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
ret = (strval != NULL) ? KRB5_CERTAUTH_HWAUTH : 0;
|
||||
krb5_dbe_free_string(context, strval);
|
||||
|
||||
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
|
||||
index 5b57c799a..2d6605666 100644
|
||||
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
|
||||
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
|
||||
@@ -55,7 +55,6 @@ krb5_ldap_create(krb5_context context, char *conf_section, char **db_args)
|
||||
krb5_error_code status = 0;
|
||||
krb5_ldap_realm_params *rparams = NULL;
|
||||
krb5_ldap_context *ldap_context=NULL;
|
||||
- krb5_boolean realm_obj_created = FALSE;
|
||||
int mask = 0;
|
||||
|
||||
/* Clear the global error string */
|
||||
@@ -109,9 +108,6 @@ krb5_ldap_create(krb5_context context, char *conf_section, char **db_args)
|
||||
if ((status = krb5_ldap_create_realm(context, rparams, mask)))
|
||||
goto cleanup;
|
||||
|
||||
- /* We just created the Realm container. Here starts our transaction tracking */
|
||||
- realm_obj_created = TRUE;
|
||||
-
|
||||
/* verify realm object */
|
||||
if ((status = krb5_ldap_read_realm_params(context,
|
||||
rparams->realm_name,
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From bf8567ed95991628f198e88403e30f78e2d74e15 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 14 May 2020 15:01:18 -0400
|
||||
Subject: [PATCH] Fix typo ("in in") in the ksu man page
|
||||
|
||||
(cherry picked from commit 1011841acdc1020f308ef4f569c6622f279d8c3f)
|
||||
---
|
||||
doc/user/user_commands/ksu.rst | 2 +-
|
||||
src/man/ksu.man | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/doc/user/user_commands/ksu.rst b/doc/user/user_commands/ksu.rst
|
||||
index 8d6c7ef79..933738229 100644
|
||||
--- a/doc/user/user_commands/ksu.rst
|
||||
+++ b/doc/user/user_commands/ksu.rst
|
||||
@@ -155,7 +155,7 @@ wrong password is typed in, ksu fails.
|
||||
.. note::
|
||||
|
||||
During authentication, only the tickets that could be
|
||||
- obtained without providing a password are cached in in the
|
||||
+ obtained without providing a password are cached in the
|
||||
source cache.
|
||||
|
||||
|
||||
diff --git a/src/man/ksu.man b/src/man/ksu.man
|
||||
index 81e34815d..8d4c6a359 100644
|
||||
--- a/src/man/ksu.man
|
||||
+++ b/src/man/ksu.man
|
||||
@@ -176,7 +176,7 @@ wrong password is typed in, ksu fails.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
During authentication, only the tickets that could be
|
||||
-obtained without providing a password are cached in in the
|
||||
+obtained without providing a password are cached in the
|
||||
source cache.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From e74f9424e47ab914c46e549fc5a2cbdf2615ef93 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Wed, 15 Jul 2020 15:42:20 -0400
|
||||
Subject: [PATCH] Ignore bad enctypes in krb5_string_to_keysalts()
|
||||
|
||||
Fixes a problem where the presence of legacy/unrecognized keysalts in
|
||||
supported_enctypes would prevent the kadmin programs from starting.
|
||||
|
||||
[ghudson@mit.edu: ideally we would put a warning in the kadmind log,
|
||||
but that is difficult to do when the parsing is done inside a library.
|
||||
Even adding a trace log is difficult because the kadm5 str_conv
|
||||
functions do not accept contexts.]
|
||||
|
||||
ticket: 8929 (new)
|
||||
(cherry picked from commit be5396ada0e8dabd68bd0aceb733cfca39a609bc)
|
||||
---
|
||||
src/lib/kadm5/str_conv.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/lib/kadm5/str_conv.c b/src/lib/kadm5/str_conv.c
|
||||
index 7cf51d316..798295606 100644
|
||||
--- a/src/lib/kadm5/str_conv.c
|
||||
+++ b/src/lib/kadm5/str_conv.c
|
||||
@@ -340,9 +340,10 @@ krb5_string_to_keysalts(const char *string, const char *tupleseps,
|
||||
while ((ksp = strtok_r(p, tseps, &tlasts)) != NULL) {
|
||||
/* Pass a null pointer to subsequent calls to strtok_r(). */
|
||||
p = NULL;
|
||||
- ret = string_to_keysalt(ksp, ksaltseps, &etype, &stype);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
+
|
||||
+ /* Discard unrecognized keysalts. */
|
||||
+ if (string_to_keysalt(ksp, ksaltseps, &etype, &stype) != 0)
|
||||
+ continue;
|
||||
|
||||
/* Ignore duplicate keysalts if caller asks. */
|
||||
if (!dups && krb5_keysalt_is_present(ksalts, nksalts, etype, stype))
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
From 651b9b8084ecff5553b7ef6ee723ce7c4438a9d8 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Scheel <ascheel@redhat.com>
|
||||
Date: Wed, 5 Jul 2017 11:38:30 -0400
|
||||
Subject: [PATCH] Implement GSS_C_CHANNEL_BOUND_FLAG
|
||||
|
||||
Define a new channel-bound GSS return flag, and set it in the krb5
|
||||
mech if the initiator sent channel bindings matching the acceptor's.
|
||||
Do not error out if the acceptor specifies channel bindings and the
|
||||
initiator does not send them.
|
||||
|
||||
[ghudson@mit.edu: simplified code changes; fleshed out commit message]
|
||||
|
||||
[iboukris: cherry-picked from another PR and reduced in scope]
|
||||
|
||||
ticket: 8899 (new)
|
||||
(cherry picked from commit 429a31146083fac21958631c2af572b08ec91022)
|
||||
---
|
||||
src/lib/gssapi/generic/gssapi_ext.h | 2 ++
|
||||
src/lib/gssapi/krb5/accept_sec_context.c | 18 +++++++++++++-----
|
||||
2 files changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
|
||||
index 218456e44..c675e8ebb 100644
|
||||
--- a/src/lib/gssapi/generic/gssapi_ext.h
|
||||
+++ b/src/lib/gssapi/generic/gssapi_ext.h
|
||||
@@ -595,6 +595,8 @@ gss_store_cred_into(
|
||||
* attribute (along with any applicable RFC 5587 attributes).
|
||||
*/
|
||||
|
||||
+#define GSS_C_CHANNEL_BOUND_FLAG 2048 /* 0x00000800 */
|
||||
+
|
||||
OM_uint32 KRB5_CALLCONV
|
||||
gssspi_query_meta_data(
|
||||
OM_uint32 *minor_status,
|
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
index 70dd7fc0c..9d3e2f4fe 100644
|
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
@@ -427,6 +427,9 @@ kg_process_extension(krb5_context context,
|
||||
GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE | \
|
||||
GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG)
|
||||
|
||||
+/* A zero-value channel binding, for comparison */
|
||||
+static const uint8_t null_cb[CB_MD5_LEN];
|
||||
+
|
||||
/*
|
||||
* The krb5 GSS mech appropriates the authenticator checksum field from RFC
|
||||
* 4120 to store structured data instead of a checksum, indicated with checksum
|
||||
@@ -435,9 +438,10 @@ kg_process_extension(krb5_context context,
|
||||
*
|
||||
* Interpret the checksum. Read delegated creds into *deleg_out if it is not
|
||||
* NULL. Set *flags_out to the allowed subset of token flags, plus
|
||||
- * GSS_C_DELEG_FLAG if a delegated credential was present. Process any
|
||||
- * extensions found using exts. On error, set *code_out to a krb5_error code
|
||||
- * for use as a minor status value.
|
||||
+ * GSS_C_DELEG_FLAG if a delegated credential was present and
|
||||
+ * GSS_C_CHANNEL_BOUND_FLAG if matching channel bindings are present. Process
|
||||
+ * any extensions found using exts. On error, set *code_out to a krb5_error
|
||||
+ * code for use as a minor status value.
|
||||
*/
|
||||
static OM_uint32
|
||||
process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
@@ -450,7 +454,7 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
krb5_error_code code = 0;
|
||||
OM_uint32 status, option_id, token_flags;
|
||||
size_t cb_len, option_len;
|
||||
- krb5_boolean valid;
|
||||
+ krb5_boolean valid, token_cb_present = FALSE, cb_match = FALSE;
|
||||
krb5_key subkey;
|
||||
krb5_data option, empty = empty_data();
|
||||
krb5_checksum cb_cksum;
|
||||
@@ -516,7 +520,9 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
goto fail;
|
||||
}
|
||||
assert(cb_cksum.length == cb_len);
|
||||
- if (k5_bcmp(token_cb, cb_cksum.contents, cb_len) != 0) {
|
||||
+ token_cb_present = (k5_bcmp(token_cb, null_cb, cb_len) != 0);
|
||||
+ cb_match = (k5_bcmp(token_cb, cb_cksum.contents, cb_len) == 0);
|
||||
+ if (token_cb_present && !cb_match) {
|
||||
status = GSS_S_BAD_BINDINGS;
|
||||
goto fail;
|
||||
}
|
||||
@@ -525,6 +531,8 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
/* Read the token flags and accept some of them as context flags. */
|
||||
token_flags = k5_input_get_uint32_le(&in);
|
||||
*flags_out = token_flags & INITIATOR_FLAGS;
|
||||
+ if (cb_match)
|
||||
+ *flags_out |= GSS_C_CHANNEL_BOUND_FLAG;
|
||||
|
||||
/* Read the delegated credential if present. */
|
||||
if (in.len >= 4 && (token_flags & GSS_C_DELEG_FLAG)) {
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
From bc89c6c720c4170d43010fead23550b80499c32a Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 16:04:21 +0100
|
||||
Subject: [PATCH] Implement KERB_AP_OPTIONS_CBT (server side)
|
||||
|
||||
Add server support for Microsoft's KERB_AP_OPTIONS_CBT as described in
|
||||
MS-KILE. If the client includes the AP option in the authenticator
|
||||
authdata and the server passed channel bindings, require the bindings
|
||||
to match.
|
||||
|
||||
[ghudson@mit.edu: refactored to put more logic in the helper function;
|
||||
added a comment; clarified commit message]
|
||||
|
||||
ticket: 8900 (new)
|
||||
(cherry picked from commit 4f7c77b64a048ca5e3199b26b31493698c777a9c)
|
||||
---
|
||||
src/include/krb5/krb5.hin | 1 +
|
||||
src/lib/gssapi/krb5/accept_sec_context.c | 45 +++++++++++++++++++++++-
|
||||
2 files changed, 45 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||
index f8269fb17..9264bede1 100644
|
||||
--- a/src/include/krb5/krb5.hin
|
||||
+++ b/src/include/krb5/krb5.hin
|
||||
@@ -1915,6 +1915,7 @@ krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype,
|
||||
#define KRB5_AUTHDATA_SIGNTICKET 512 /**< formerly 142 in krb5 1.8 */
|
||||
#define KRB5_AUTHDATA_FX_ARMOR 71
|
||||
#define KRB5_AUTHDATA_AUTH_INDICATOR 97
|
||||
+#define KRB5_AUTHDATA_AP_OPTIONS 143
|
||||
/** @} */ /* end of KRB5_AUTHDATA group */
|
||||
|
||||
/* password change constants */
|
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
index 9d3e2f4fe..175a24c4e 100644
|
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
@@ -430,6 +430,32 @@ kg_process_extension(krb5_context context,
|
||||
/* A zero-value channel binding, for comparison */
|
||||
static const uint8_t null_cb[CB_MD5_LEN];
|
||||
|
||||
+/* Look for AP_OPTIONS in authdata. If present and the options include
|
||||
+ * KERB_AP_OPTIONS_CBT, set *cbt_out to true. */
|
||||
+static krb5_error_code
|
||||
+check_cbt(krb5_context context, krb5_authdata **authdata,
|
||||
+ krb5_boolean *cbt_out)
|
||||
+{
|
||||
+ krb5_error_code code;
|
||||
+ uint32_t ad_ap_options;
|
||||
+ const uint32_t KERB_AP_OPTIONS_CBT = 0x4000;
|
||||
+
|
||||
+ *cbt_out = FALSE;
|
||||
+
|
||||
+ code = krb5_find_authdata(context, NULL, authdata,
|
||||
+ KRB5_AUTHDATA_AP_OPTIONS, &authdata);
|
||||
+ if (code || authdata == NULL)
|
||||
+ return code;
|
||||
+ if (authdata[1] != NULL || authdata[0]->length != 4)
|
||||
+ return KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
+
|
||||
+ ad_ap_options = load_32_le(authdata[0]->contents);
|
||||
+ if (ad_ap_options & KERB_AP_OPTIONS_CBT)
|
||||
+ *cbt_out = TRUE;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* The krb5 GSS mech appropriates the authenticator checksum field from RFC
|
||||
* 4120 to store structured data instead of a checksum, indicated with checksum
|
||||
@@ -454,7 +480,7 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
krb5_error_code code = 0;
|
||||
OM_uint32 status, option_id, token_flags;
|
||||
size_t cb_len, option_len;
|
||||
- krb5_boolean valid, token_cb_present = FALSE, cb_match = FALSE;
|
||||
+ krb5_boolean valid, client_cbt, token_cb_present = FALSE, cb_match = FALSE;
|
||||
krb5_key subkey;
|
||||
krb5_data option, empty = empty_data();
|
||||
krb5_checksum cb_cksum;
|
||||
@@ -582,6 +608,23 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
}
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * If the client asserts the KERB_AP_OPTIONS_CBT flag (from MS-KILE) in the
|
||||
+ * authenticator authdata, and the acceptor passed channel bindings,
|
||||
+ * require matching channel bindings from the client. The intent is to
|
||||
+ * prevent an authenticator generated for use outside of a TLS channel from
|
||||
+ * being used inside of one.
|
||||
+ */
|
||||
+ code = check_cbt(context, authenticator->authorization_data, &client_cbt);
|
||||
+ if (code) {
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (client_cbt && acceptor_cb != GSS_C_NO_CHANNEL_BINDINGS && !cb_match) {
|
||||
+ status = GSS_S_BAD_BINDINGS;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
status = GSS_S_COMPLETE;
|
||||
|
||||
fail:
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
From ed87237cdd70f72b309960a294a2bed26cef1579 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Fri, 4 Sep 2020 14:05:50 +0300
|
||||
Subject: [PATCH] Improve KDC alias checking for S4U requests
|
||||
|
||||
When processing an S4U2Self request, check for DB aliases when
|
||||
matching the TGT client against the request server. When processing
|
||||
an S4U2Proxy request, check for DB aliases when matching the TGT
|
||||
client against the evidence ticket server.
|
||||
|
||||
[ghudson@mit.edu: minor edits; rewrote commit message]
|
||||
|
||||
ticket: 8946 (new)
|
||||
(cherry picked from commit 05deeebfc096970b5d9aa67a48b14106cf1b9b56)
|
||||
---
|
||||
src/kdc/kdc_util.c | 74 ++++++++++++++++------------------------------
|
||||
1 file changed, 25 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index e3352f9cc..dcb2df8dc 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -1463,6 +1463,25 @@ cleanup:
|
||||
return code;
|
||||
}
|
||||
|
||||
+/* Return true if princ canonicalizes to the same principal as canon. */
|
||||
+static krb5_boolean
|
||||
+is_client_alias(krb5_context context, krb5_const_principal canon,
|
||||
+ krb5_const_principal princ)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_db_entry *self;
|
||||
+ krb5_boolean is_self = FALSE;
|
||||
+
|
||||
+ ret = krb5_db_get_principal(context, princ,
|
||||
+ KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY, &self);
|
||||
+ if (!ret) {
|
||||
+ is_self = krb5_principal_compare(context, canon, self->princ);
|
||||
+ krb5_db_free_principal(context, self);
|
||||
+ }
|
||||
+
|
||||
+ return is_self;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Protocol transition (S4U2Self)
|
||||
*/
|
||||
@@ -1481,7 +1500,6 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
|
||||
{
|
||||
krb5_error_code code;
|
||||
krb5_pa_data *pa_data;
|
||||
- int flags;
|
||||
krb5_db_entry *princ;
|
||||
krb5_s4u_userid *id;
|
||||
|
||||
@@ -1515,51 +1533,11 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
|
||||
}
|
||||
id = &(*s4u_x509_user)->user_id;
|
||||
|
||||
- /*
|
||||
- * We need to compare the client name in the TGT with the requested
|
||||
- * server name. Supporting server name aliases without assuming a
|
||||
- * global name service makes this difficult to do.
|
||||
- *
|
||||
- * The comparison below handles the following cases (note that the
|
||||
- * term "principal name" below excludes the realm).
|
||||
- *
|
||||
- * (1) The requested service is a host-based service with two name
|
||||
- * components, in which case we assume the principal name to
|
||||
- * contain sufficient qualifying information. The realm is
|
||||
- * ignored for the purpose of comparison.
|
||||
- *
|
||||
- * (2) The requested service name is an enterprise principal name:
|
||||
- * the service principal name is compared with the unparsed
|
||||
- * form of the client name (including its realm).
|
||||
- *
|
||||
- * (3) The requested service is some other name type: an exact
|
||||
- * match is required.
|
||||
- *
|
||||
- * An alternative would be to look up the server once again with
|
||||
- * FLAG_CANONICALIZE | FLAG_CLIENT_REFERRALS_ONLY set, do an exact
|
||||
- * match between the returned name and client_princ. However, this
|
||||
- * assumes that the client set FLAG_CANONICALIZE when requesting
|
||||
- * the TGT and that we have a global name service.
|
||||
- */
|
||||
- flags = 0;
|
||||
- switch (krb5_princ_type(kdc_context, request->server)) {
|
||||
- case KRB5_NT_SRV_HST: /* (1) */
|
||||
- if (krb5_princ_size(kdc_context, request->server) == 2)
|
||||
- flags |= KRB5_PRINCIPAL_COMPARE_IGNORE_REALM;
|
||||
- break;
|
||||
- case KRB5_NT_ENTERPRISE_PRINCIPAL: /* (2) */
|
||||
- flags |= KRB5_PRINCIPAL_COMPARE_ENTERPRISE;
|
||||
- break;
|
||||
- default: /* (3) */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (!krb5_principal_compare_flags(kdc_context,
|
||||
- request->server,
|
||||
- client_princ,
|
||||
- flags)) {
|
||||
- *status = "INVALID_S4U2SELF_REQUEST";
|
||||
- return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; /* match Windows error code */
|
||||
+ /* If the server is local, check that the request is for self. */
|
||||
+ if (!isflagset(c_flags, KRB5_KDB_FLAG_ISSUING_REFERRAL) &&
|
||||
+ !is_client_alias(kdc_context, server->princ, client_princ)) {
|
||||
+ *status = "INVALID_S4U2SELF_REQUEST_SERVER_MISMATCH";
|
||||
+ return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; /* match Windows error */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1750,9 +1728,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, unsigned int flags,
|
||||
}
|
||||
|
||||
client_princ = *stkt_authdata_client;
|
||||
- } else if (!krb5_principal_compare(kdc_context,
|
||||
- server->princ, /* after canon */
|
||||
- server_princ)) {
|
||||
+ } else if (!is_client_alias(kdc_context, server->princ, server_princ)) {
|
||||
*status = "EVIDENCE_TICKET_MISMATCH";
|
||||
return KRB5KDC_ERR_SERVER_NOMATCH;
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
From 4c96c8fef146337b7d3c0ebb4118a18818dd1f4e Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 9 Jun 2020 16:23:37 -0400
|
||||
Subject: [PATCH] Improve negoex_parse_token() code hygiene
|
||||
|
||||
If the while loop in negoex_parse_token() runs for zero iterations,
|
||||
major will be used initialized. Currently this cannot happen, but
|
||||
only because both of the call sites check for zero-length tokens.
|
||||
Initialize major for safety.
|
||||
|
||||
[ghudson@mit.edu: rewrote commit message]
|
||||
|
||||
(cherry picked from commit 4f91b6f8fa6fe1de662b3fdac0d59b7758ec642a)
|
||||
---
|
||||
src/lib/gssapi/spnego/negoex_util.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/spnego/negoex_util.c b/src/lib/gssapi/spnego/negoex_util.c
|
||||
index 700368456..99580fd79 100644
|
||||
--- a/src/lib/gssapi/spnego/negoex_util.c
|
||||
+++ b/src/lib/gssapi/spnego/negoex_util.c
|
||||
@@ -454,7 +454,7 @@ negoex_parse_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
|
||||
gss_const_buffer_t token,
|
||||
struct negoex_message **messages_out, size_t *count_out)
|
||||
{
|
||||
- OM_uint32 major;
|
||||
+ OM_uint32 major = GSS_S_COMPLETE;
|
||||
size_t count = 0;
|
||||
struct k5input in;
|
||||
struct negoex_message *messages = NULL, *newptr;
|
||||
|
|
@ -1,316 +0,0 @@
|
|||
From 5e79319edf3836d12dbc710ec1e2dd4405c9df35 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 25 Sep 2020 11:12:34 -0400
|
||||
Subject: [PATCH] Minimize usage of tgs_server in KDC
|
||||
|
||||
Where possible, use the realm of the request server principal
|
||||
(canonicalized via KDB lookup, if available) in preference to
|
||||
tgs_server. This change facilitates alias realm support and potential
|
||||
future support for serving multiple realms from the same KDB.
|
||||
|
||||
S4U2Self local user testing currently uses the uncanonicalized request
|
||||
realm after this change, which will require attention for alias realm
|
||||
support.
|
||||
|
||||
FAST armor ticket checking is unaffected by this change (it still
|
||||
compares against tgs_server). This check poses no issue for realm
|
||||
aliases, as both tgs_server and the armor ticket server should have
|
||||
canonical realms, but it will require attention for multi-realm KDB
|
||||
support.
|
||||
|
||||
Remove is_local_principal() as it is no longer used. Add an
|
||||
is_local_tgs_principal() helper and shorten is_cross_tgs_principal().
|
||||
|
||||
Move the header ticket lineage check from kdc_process_tgs_req() to
|
||||
process_tgs_req(), where we have the canonical request server name and
|
||||
a more natural indication of whether the request was an S4U2Self
|
||||
request.
|
||||
|
||||
(cherry picked from commit 90fedf8188fc47aa5a476a969af34671555df389)
|
||||
---
|
||||
src/kdc/do_as_req.c | 21 ++++++--------
|
||||
src/kdc/do_tgs_req.c | 16 ++++++++---
|
||||
src/kdc/kdc_util.c | 68 ++++++++++----------------------------------
|
||||
src/kdc/kdc_util.h | 3 +-
|
||||
src/kdc/tgs_policy.c | 16 ++++++-----
|
||||
5 files changed, 46 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
|
||||
index c2dfea9b8..e0ac33649 100644
|
||||
--- a/src/kdc/do_as_req.c
|
||||
+++ b/src/kdc/do_as_req.c
|
||||
@@ -620,18 +620,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
|
||||
}
|
||||
state->rock.client = state->client;
|
||||
|
||||
- /*
|
||||
- * If the backend returned a principal that is not in the local
|
||||
- * realm, then we need to refer the client to that realm.
|
||||
- */
|
||||
- if (!is_local_principal(kdc_active_realm, state->client->princ)) {
|
||||
- /* Entry is a referral to another realm */
|
||||
- state->status = "REFERRAL";
|
||||
- au_state->cl_realm = &state->client->princ->realm;
|
||||
- errcode = KRB5KDC_ERR_WRONG_REALM;
|
||||
- goto errout;
|
||||
- }
|
||||
-
|
||||
au_state->stage = SRVC_PRINC;
|
||||
|
||||
s_flags = 0;
|
||||
@@ -651,6 +639,15 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
+ /* If the KDB module returned a different realm for the client and server,
|
||||
+ * we need to issue a client realm referral. */
|
||||
+ if (!data_eq(state->server->princ->realm, state->client->princ->realm)) {
|
||||
+ state->status = "REFERRAL";
|
||||
+ au_state->cl_realm = &state->client->princ->realm;
|
||||
+ errcode = KRB5KDC_ERR_WRONG_REALM;
|
||||
+ goto errout;
|
||||
+ }
|
||||
+
|
||||
errcode = get_local_tgt(kdc_context, &state->request->server->realm,
|
||||
state->server, &state->local_tgt,
|
||||
&state->local_tgt_storage, &state->local_tgt_key);
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
||||
index d345797c4..8ea418e43 100644
|
||||
--- a/src/kdc/do_tgs_req.c
|
||||
+++ b/src/kdc/do_tgs_req.c
|
||||
@@ -268,7 +268,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- if (!is_local_principal(kdc_active_realm, header_ticket->server))
|
||||
+ if (!data_eq(header_server->princ->realm, sprinc->realm))
|
||||
setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
|
||||
if (is_referral)
|
||||
setflag(c_flags, KRB5_KDB_FLAG_ISSUING_REFERRAL);
|
||||
@@ -295,6 +295,15 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
au_state->s4u2self_user = NULL;
|
||||
}
|
||||
|
||||
+ /* Aside from cross-realm S4U2Self requests, do not accept header tickets
|
||||
+ * for local users issued by foreign realms. */
|
||||
+ if (s4u_x509_user == NULL && data_eq(cprinc->realm, sprinc->realm) &&
|
||||
+ isflagset(c_flags, KRB5_KDB_FLAG_CROSS_REALM)) {
|
||||
+ krb5_klog_syslog(LOG_INFO, _("PROCESS_TGS: failed lineage check"));
|
||||
+ retval = KRB5KDC_ERR_POLICY;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
if (errcode)
|
||||
goto cleanup;
|
||||
|
||||
@@ -583,13 +592,12 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
|
||||
/*
|
||||
* Only add the realm of the presented tgt to the transited list if
|
||||
- * it is different than the local realm (cross-realm) and it is different
|
||||
+ * it is different than the server realm (cross-realm) and it is different
|
||||
* than the realm of the client (since the realm of the client is already
|
||||
* implicitly part of the transited list and should not be explicitly
|
||||
* listed).
|
||||
*/
|
||||
- /* realm compare is like strcmp, but knows how to deal with these args */
|
||||
- if (krb5_realm_compare(kdc_context, header_ticket->server, tgs_server) ||
|
||||
+ if (!isflagset(c_flags, KRB5_KDB_FLAG_CROSS_REALM) ||
|
||||
krb5_realm_compare(kdc_context, header_ticket->server,
|
||||
enc_tkt_reply.client)) {
|
||||
/* tgt issued by local realm or issued by realm of client */
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index b2042862a..e0b65a87c 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -78,12 +78,6 @@ static krb5_error_code find_server_key(krb5_context,
|
||||
krb5_kvno, krb5_keyblock **,
|
||||
krb5_kvno *);
|
||||
|
||||
-krb5_boolean
|
||||
-is_local_principal(kdc_realm_t *kdc_active_realm, krb5_const_principal princ1)
|
||||
-{
|
||||
- return krb5_realm_compare(kdc_context, princ1, tgs_server);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Returns TRUE if the kerberos principal is the name of a Kerberos ticket
|
||||
* service.
|
||||
@@ -104,13 +98,16 @@ krb5_is_tgs_principal(krb5_const_principal principal)
|
||||
krb5_boolean
|
||||
is_cross_tgs_principal(krb5_const_principal principal)
|
||||
{
|
||||
- if (!krb5_is_tgs_principal(principal))
|
||||
- return FALSE;
|
||||
- if (!data_eq(*krb5_princ_component(kdc_context, principal, 1),
|
||||
- *krb5_princ_realm(kdc_context, principal)))
|
||||
- return TRUE;
|
||||
- else
|
||||
- return FALSE;
|
||||
+ return krb5_is_tgs_principal(principal) &&
|
||||
+ !data_eq(principal->data[1], principal->realm);
|
||||
+}
|
||||
+
|
||||
+/* Return true if princ is the name of a local TGS for any realm. */
|
||||
+krb5_boolean
|
||||
+is_local_tgs_principal(krb5_const_principal principal)
|
||||
+{
|
||||
+ return krb5_is_tgs_principal(principal) &&
|
||||
+ data_eq(principal->data[1], principal->realm);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -143,17 +140,6 @@ comp_cksum(krb5_context kcontext, krb5_data *source, krb5_ticket *ticket,
|
||||
return(0);
|
||||
}
|
||||
|
||||
-/* Return true if padata contains an entry of either S4U2Self type. */
|
||||
-static inline krb5_boolean
|
||||
-has_s4u2self_padata(krb5_pa_data **padata)
|
||||
-{
|
||||
- if (krb5int_find_pa_data(NULL, padata, KRB5_PADATA_FOR_USER) != NULL)
|
||||
- return TRUE;
|
||||
- if (krb5int_find_pa_data(NULL, padata, KRB5_PADATA_S4U_X509_USER) != NULL)
|
||||
- return TRUE;
|
||||
- return FALSE;
|
||||
-}
|
||||
-
|
||||
/* If a header ticket is decrypted, *ticket_out is filled in even on error. */
|
||||
krb5_error_code
|
||||
kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
|
||||
@@ -170,7 +156,6 @@ kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
|
||||
krb5_authdata **authdata = NULL;
|
||||
krb5_data scratch1;
|
||||
krb5_data * scratch = NULL;
|
||||
- krb5_boolean foreign_server = FALSE;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
krb5_authenticator * authenticator = NULL;
|
||||
krb5_checksum * his_cksum = NULL;
|
||||
@@ -199,19 +184,6 @@ kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* If the "server" principal in the ticket is not something
|
||||
- in the local realm, then we must refuse to service the request
|
||||
- if the client claims to be from the local realm.
|
||||
-
|
||||
- If we don't do this, then some other realm's nasty KDC can
|
||||
- claim to be authenticating a client from our realm, and we'll
|
||||
- give out tickets concurring with it!
|
||||
-
|
||||
- we set a flag here for checking below.
|
||||
- */
|
||||
- foreign_server = !is_local_principal(kdc_active_realm,
|
||||
- apreq->ticket->server);
|
||||
-
|
||||
if ((retval = krb5_auth_con_init(kdc_context, &auth_context)))
|
||||
goto cleanup;
|
||||
|
||||
@@ -265,15 +237,6 @@ kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
|
||||
goto cleanup_authenticator;
|
||||
}
|
||||
|
||||
- /* make sure the client is of proper lineage (see above) */
|
||||
- if (foreign_server && !has_s4u2self_padata(request->padata) &&
|
||||
- is_local_principal(kdc_active_realm, ticket->enc_part2->client)) {
|
||||
- /* someone in a foreign realm claiming to be local */
|
||||
- krb5_klog_syslog(LOG_INFO, _("PROCESS_TGS: failed lineage check"));
|
||||
- retval = KRB5KDC_ERR_POLICY;
|
||||
- goto cleanup_authenticator;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* Check application checksum vs. tgs request
|
||||
*
|
||||
@@ -591,12 +554,12 @@ int
|
||||
check_anon(kdc_realm_t *kdc_active_realm,
|
||||
krb5_principal client, krb5_principal server)
|
||||
{
|
||||
- /* If restrict_anon is set, reject requests from anonymous to principals
|
||||
- * other than the local TGT. */
|
||||
+ /* If restrict_anon is set, reject requests from anonymous clients to
|
||||
+ * server principals other than local TGTs. */
|
||||
if (kdc_active_realm->realm_restrict_anon &&
|
||||
krb5_principal_compare_any_realm(kdc_context, client,
|
||||
krb5_anonymous_principal()) &&
|
||||
- !krb5_principal_compare(kdc_context, server, tgs_server))
|
||||
+ !is_local_tgs_principal(server))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1527,7 +1490,7 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
|
||||
/*
|
||||
* Do not attempt to lookup principals in foreign realms.
|
||||
*/
|
||||
- if (is_local_principal(kdc_active_realm, id->user)) {
|
||||
+ if (data_eq(server->princ->realm, id->user->realm)) {
|
||||
krb5_db_entry no_server;
|
||||
krb5_pa_data **e_data = NULL;
|
||||
|
||||
@@ -1663,8 +1626,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, unsigned int flags,
|
||||
*/
|
||||
if (isflagset(flags, KRB5_KDB_FLAG_ISSUING_REFERRAL) ||
|
||||
!is_cross_tgs_principal(server->princ) ||
|
||||
- !krb5_principal_compare_any_realm(kdc_context, server->princ,
|
||||
- tgs_server) ||
|
||||
+ !data_eq(server->princ->data[1], proxy->princ->realm) ||
|
||||
!krb5_principal_compare(kdc_context, client_princ, server_princ)) {
|
||||
*status = "XREALM_EVIDENCE_TICKET_MISMATCH";
|
||||
return KRB5KDC_ERR_BADOPTION;
|
||||
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
|
||||
index 04007a8f5..a6bac4388 100644
|
||||
--- a/src/kdc/kdc_util.h
|
||||
+++ b/src/kdc/kdc_util.h
|
||||
@@ -37,10 +37,9 @@
|
||||
#include "reqstate.h"
|
||||
|
||||
krb5_error_code check_hot_list (krb5_ticket *);
|
||||
-krb5_boolean is_local_principal(kdc_realm_t *kdc_active_realm,
|
||||
- krb5_const_principal princ1);
|
||||
krb5_boolean krb5_is_tgs_principal (krb5_const_principal);
|
||||
krb5_boolean is_cross_tgs_principal(krb5_const_principal);
|
||||
+krb5_boolean is_local_tgs_principal(krb5_const_principal);
|
||||
krb5_error_code
|
||||
add_to_transited (krb5_data *,
|
||||
krb5_data *,
|
||||
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
|
||||
index 3f4fa8499..a5a00f0cc 100644
|
||||
--- a/src/kdc/tgs_policy.c
|
||||
+++ b/src/kdc/tgs_policy.c
|
||||
@@ -252,19 +252,21 @@ check_tgs_s4u2proxy(kdc_realm_t *kdc_active_realm,
|
||||
}
|
||||
|
||||
static int
|
||||
-check_tgs_u2u(kdc_realm_t *kdc_active_realm,
|
||||
- krb5_kdc_req *req, const char **status)
|
||||
+check_tgs_u2u(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
|
||||
+ krb5_const_principal server_princ, const char **status)
|
||||
{
|
||||
+ krb5_const_principal second_server_princ;
|
||||
+
|
||||
if (req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) {
|
||||
/* Check that second ticket is in request. */
|
||||
if (!req->second_ticket || !req->second_ticket[0]) {
|
||||
*status = "NO_2ND_TKT";
|
||||
return KDC_ERR_BADOPTION;
|
||||
}
|
||||
- /* Check that second ticket is a TGT. */
|
||||
- if (!krb5_principal_compare(kdc_context,
|
||||
- req->second_ticket[0]->server,
|
||||
- tgs_server)) {
|
||||
+ /* Check that second ticket is a TGT to the server realm. */
|
||||
+ second_server_princ = req->second_ticket[0]->server;
|
||||
+ if (!is_local_tgs_principal(second_server_princ) ||
|
||||
+ !data_eq(second_server_princ->data[1], server_princ->realm)) {
|
||||
*status = "2ND_TKT_NOT_TGS";
|
||||
return KDC_ERR_POLICY;
|
||||
}
|
||||
@@ -353,7 +355,7 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm,
|
||||
return(KRB_AP_ERR_REPEAT);
|
||||
}
|
||||
|
||||
- errcode = check_tgs_u2u(kdc_active_realm, request, status);
|
||||
+ errcode = check_tgs_u2u(kdc_active_realm, request, server->princ, status);
|
||||
if (errcode != 0)
|
||||
return errcode;
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From f0ac5c1efef5401f669dc176e62c09b0b01fa2d0 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 6 May 2020 16:03:13 -0400
|
||||
Subject: [PATCH] Omit KDC indicator check for S4U2Self requests
|
||||
|
||||
As there was no initial ticket exchange from the client for an
|
||||
S4U2Self request, the auth indicator check is inapplicable (and would
|
||||
always fail if any auth indicators are required).
|
||||
|
||||
ticket: 8902 (new)
|
||||
(cherry picked from commit 183631fbf72351c2d5fc7d60b2d9fc4d09fe7465)
|
||||
---
|
||||
src/kdc/do_tgs_req.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
||||
index 241f34e2a..463a9c0dd 100644
|
||||
--- a/src/kdc/do_tgs_req.c
|
||||
+++ b/src/kdc/do_tgs_req.c
|
||||
@@ -392,8 +392,8 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
}
|
||||
authtime = subject_tkt->times.authtime;
|
||||
|
||||
- /* Extract auth indicators from the subject ticket, except for S4U2Self
|
||||
- * requests (where the client didn't authenticate). */
|
||||
+ /* Extract and check auth indicators from the subject ticket, except for
|
||||
+ * S4U2Self requests (where the client didn't authenticate). */
|
||||
if (s4u_x509_user == NULL) {
|
||||
errcode = get_auth_indicators(kdc_context, subject_tkt, local_tgt,
|
||||
&local_tgt_key, &auth_indicators);
|
||||
@@ -401,12 +401,12 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
status = "GET_AUTH_INDICATORS";
|
||||
goto cleanup;
|
||||
}
|
||||
- }
|
||||
|
||||
- errcode = check_indicators(kdc_context, server, auth_indicators);
|
||||
- if (errcode) {
|
||||
- status = "HIGHER_AUTHENTICATION_REQUIRED";
|
||||
- goto cleanup;
|
||||
+ errcode = check_indicators(kdc_context, server, auth_indicators);
|
||||
+ if (errcode) {
|
||||
+ status = "HIGHER_AUTHENTICATION_REQUIRED";
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (is_referral)
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 5251097c927f476fe83ffe544b73fd2d785aaf2a Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Sat, 6 Jun 2020 11:03:37 +0200
|
||||
Subject: [PATCH] Omit PA_FOR_USER if we can't compute its checksum
|
||||
|
||||
OpenSSL in FIPS mode will refuse to perform hmac-md5. Omit the legacy
|
||||
PA_FOR_USER element in this case rather than failing out.
|
||||
|
||||
[ghudson@mit.edu: minor code and comment edits; wrote commit message]
|
||||
|
||||
ticket: 8912 (new)
|
||||
(cherry picked from commit 03f122bdb22cfa53c7d855ed929c9541e56365e0)
|
||||
---
|
||||
src/lib/krb5/krb/s4u_creds.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/src/lib/krb5/krb/s4u_creds.c b/src/lib/krb5/krb/s4u_creds.c
|
||||
index fc5c886d6..d8f486dc6 100644
|
||||
--- a/src/lib/krb5/krb/s4u_creds.c
|
||||
+++ b/src/lib/krb5/krb/s4u_creds.c
|
||||
@@ -534,6 +534,13 @@ krb5_get_self_cred_from_kdc(krb5_context context,
|
||||
if (s4u_user.user_id.user != NULL && s4u_user.user_id.user->length) {
|
||||
code = build_pa_for_user(context, tgtptr, &s4u_user.user_id,
|
||||
&in_padata[1]);
|
||||
+ /*
|
||||
+ * If we couldn't compute the hmac-md5 checksum, send only the
|
||||
+ * KRB5_PADATA_S4U_X509_USER; this will still work against modern
|
||||
+ * Windows and MIT KDCs.
|
||||
+ */
|
||||
+ if (code == KRB5_CRYPTO_INTERNAL)
|
||||
+ code = 0;
|
||||
if (code != 0) {
|
||||
krb5_free_pa_data(context, in_padata);
|
||||
goto cleanup;
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
From 17d9b74328f247de5f9d820ae008726632d11d2a Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Boukris <iboukris@gmail.com>
|
||||
Date: Tue, 28 Apr 2020 18:15:55 +0200
|
||||
Subject: [PATCH] Pass channel bindings through SPNEGO
|
||||
|
||||
ticket: 8907 (new)
|
||||
(cherry picked from commit d16325a24c34ec9a5f6fb4910987f162e0d4d9cd)
|
||||
---
|
||||
src/lib/gssapi/spnego/gssapiP_negoex.h | 8 ++---
|
||||
src/lib/gssapi/spnego/negoex_ctx.c | 34 +++++++++++----------
|
||||
src/lib/gssapi/spnego/spnego_mech.c | 41 +++++++++++++-------------
|
||||
3 files changed, 43 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/spnego/gssapiP_negoex.h b/src/lib/gssapi/spnego/gssapiP_negoex.h
|
||||
index 44b08f523..489ab7c42 100644
|
||||
--- a/src/lib/gssapi/spnego/gssapiP_negoex.h
|
||||
+++ b/src/lib/gssapi/spnego/gssapiP_negoex.h
|
||||
@@ -201,10 +201,10 @@ negoex_restrict_auth_schemes(spnego_gss_ctx_id_t ctx,
|
||||
OM_uint32
|
||||
negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
|
||||
- gss_buffer_t input_token, gss_buffer_t output_token,
|
||||
- OM_uint32 *time_rec);
|
||||
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
|
||||
+ gss_buffer_t output_token, OM_uint32 *time_rec);
|
||||
|
||||
OM_uint32
|
||||
negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
- gss_buffer_t input_token, gss_buffer_t output_token,
|
||||
- OM_uint32 *time_rec);
|
||||
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
|
||||
+ gss_buffer_t output_token, OM_uint32 *time_rec);
|
||||
diff --git a/src/lib/gssapi/spnego/negoex_ctx.c b/src/lib/gssapi/spnego/negoex_ctx.c
|
||||
index 18d9d4147..8848ee4db 100644
|
||||
--- a/src/lib/gssapi/spnego/negoex_ctx.c
|
||||
+++ b/src/lib/gssapi/spnego/negoex_ctx.c
|
||||
@@ -276,7 +276,8 @@ static OM_uint32
|
||||
mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
gss_name_t target, OM_uint32 req_flags, OM_uint32 time_req,
|
||||
struct negoex_message *messages, size_t nmessages,
|
||||
- gss_buffer_t output_token, OM_uint32 *time_rec)
|
||||
+ gss_channel_bindings_t bindings, gss_buffer_t output_token,
|
||||
+ OM_uint32 *time_rec)
|
||||
{
|
||||
OM_uint32 major, first_major = 0, first_minor = 0;
|
||||
struct negoex_auth_mech *mech = NULL;
|
||||
@@ -316,10 +317,9 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
mech = K5_TAILQ_FIRST(&ctx->negoex_mechs);
|
||||
|
||||
major = gss_init_sec_context(minor, cred, &mech->mech_context, target,
|
||||
- mech->oid, req_flags, time_req,
|
||||
- GSS_C_NO_CHANNEL_BINDINGS, input_token,
|
||||
- &ctx->actual_mech, output_token,
|
||||
- &ctx->ctx_flags, time_rec);
|
||||
+ mech->oid, req_flags, time_req, bindings,
|
||||
+ input_token, &ctx->actual_mech,
|
||||
+ output_token, &ctx->ctx_flags, time_rec);
|
||||
|
||||
if (major == GSS_S_COMPLETE)
|
||||
mech->complete = 1;
|
||||
@@ -351,7 +351,8 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
static OM_uint32
|
||||
mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
|
||||
gss_cred_id_t cred, struct negoex_message *messages,
|
||||
- size_t nmessages, gss_buffer_t output_token, OM_uint32 *time_rec)
|
||||
+ size_t nmessages, gss_channel_bindings_t bindings,
|
||||
+ gss_buffer_t output_token, OM_uint32 *time_rec)
|
||||
{
|
||||
OM_uint32 major, tmpmin;
|
||||
struct negoex_auth_mech *mech;
|
||||
@@ -395,10 +396,10 @@ mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
|
||||
gss_release_cred(&tmpmin, &ctx->deleg_cred);
|
||||
|
||||
major = gss_accept_sec_context(minor, &mech->mech_context, cred,
|
||||
- &msg->token, GSS_C_NO_CHANNEL_BINDINGS,
|
||||
- &ctx->internal_name, &ctx->actual_mech,
|
||||
- output_token, &ctx->ctx_flags,
|
||||
- time_rec, &ctx->deleg_cred);
|
||||
+ &msg->token, bindings, &ctx->internal_name,
|
||||
+ &ctx->actual_mech, output_token,
|
||||
+ &ctx->ctx_flags, time_rec,
|
||||
+ &ctx->deleg_cred);
|
||||
|
||||
if (major == GSS_S_COMPLETE)
|
||||
mech->complete = 1;
|
||||
@@ -609,8 +610,8 @@ make_output_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
|
||||
OM_uint32
|
||||
negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
|
||||
- gss_buffer_t input_token, gss_buffer_t output_token,
|
||||
- OM_uint32 *time_rec)
|
||||
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
|
||||
+ gss_buffer_t output_token, OM_uint32 *time_rec)
|
||||
{
|
||||
OM_uint32 major, tmpmin;
|
||||
gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
|
||||
@@ -663,7 +664,8 @@ negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
/* Process the input token and/or produce an output token. This may prune
|
||||
* the mech list, but on success there will be at least one mech entry. */
|
||||
major = mech_init(minor, ctx, cred, target_name, req_flags, time_req,
|
||||
- messages, nmessages, &mech_output_token, time_rec);
|
||||
+ messages, nmessages, bindings, &mech_output_token,
|
||||
+ time_rec);
|
||||
if (major != GSS_S_COMPLETE)
|
||||
goto cleanup;
|
||||
assert(!K5_TAILQ_EMPTY(&ctx->negoex_mechs));
|
||||
@@ -701,8 +703,8 @@ cleanup:
|
||||
|
||||
OM_uint32
|
||||
negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
- gss_buffer_t input_token, gss_buffer_t output_token,
|
||||
- OM_uint32 *time_rec)
|
||||
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
|
||||
+ gss_buffer_t output_token, OM_uint32 *time_rec)
|
||||
{
|
||||
OM_uint32 major, tmpmin;
|
||||
gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
|
||||
@@ -754,7 +756,7 @@ negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
|
||||
* prune the list to a single mech. Continue on error if an output token
|
||||
* is generated, so that we send the token to the initiator.
|
||||
*/
|
||||
- major = mech_accept(minor, ctx, cred, messages, nmessages,
|
||||
+ major = mech_accept(minor, ctx, cred, messages, nmessages, bindings,
|
||||
&mech_output_token, time_rec);
|
||||
if (major != GSS_S_COMPLETE && mech_output_token.length == 0)
|
||||
goto cleanup;
|
||||
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
|
||||
index 594fc5894..4cf011143 100644
|
||||
--- a/src/lib/gssapi/spnego/spnego_mech.c
|
||||
+++ b/src/lib/gssapi/spnego/spnego_mech.c
|
||||
@@ -130,6 +130,7 @@ init_ctx_reselect(OM_uint32 *, spnego_gss_ctx_id_t, OM_uint32,
|
||||
static OM_uint32
|
||||
init_ctx_call_init(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
|
||||
OM_uint32, gss_name_t, OM_uint32, OM_uint32, gss_buffer_t,
|
||||
+ gss_channel_bindings_t,
|
||||
gss_buffer_t, OM_uint32 *, send_token_flag *);
|
||||
|
||||
static OM_uint32
|
||||
@@ -144,8 +145,8 @@ acc_ctx_vfy_oid(OM_uint32 *, spnego_gss_ctx_id_t, gss_OID,
|
||||
OM_uint32 *, send_token_flag *);
|
||||
static OM_uint32
|
||||
acc_ctx_call_acc(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
|
||||
- gss_buffer_t, gss_buffer_t, OM_uint32 *, OM_uint32 *,
|
||||
- send_token_flag *);
|
||||
+ gss_buffer_t, gss_channel_bindings_t, gss_buffer_t,
|
||||
+ OM_uint32 *, OM_uint32 *, send_token_flag *);
|
||||
|
||||
static gss_OID
|
||||
negotiate_mech(spnego_gss_ctx_id_t, gss_OID_set, OM_uint32 *);
|
||||
@@ -905,6 +906,7 @@ init_ctx_call_init(OM_uint32 *minor_status,
|
||||
OM_uint32 req_flags,
|
||||
OM_uint32 time_req,
|
||||
gss_buffer_t mechtok_in,
|
||||
+ gss_channel_bindings_t bindings,
|
||||
gss_buffer_t mechtok_out,
|
||||
OM_uint32 *time_rec,
|
||||
send_token_flag *send_token)
|
||||
@@ -921,15 +923,14 @@ init_ctx_call_init(OM_uint32 *minor_status,
|
||||
if (gss_oid_equal(sc->internal_mech, &negoex_mech)) {
|
||||
ret = negoex_init(minor_status, sc, mcred, target_name,
|
||||
mech_req_flags, time_req, mechtok_in,
|
||||
- mechtok_out, time_rec);
|
||||
+ bindings, mechtok_out, time_rec);
|
||||
} else {
|
||||
ret = gss_init_sec_context(minor_status, mcred,
|
||||
&sc->ctx_handle, target_name,
|
||||
sc->internal_mech, mech_req_flags,
|
||||
- time_req, GSS_C_NO_CHANNEL_BINDINGS,
|
||||
- mechtok_in, &sc->actual_mech,
|
||||
- mechtok_out, &sc->ctx_flags,
|
||||
- time_rec);
|
||||
+ time_req, bindings, mechtok_in,
|
||||
+ &sc->actual_mech, mechtok_out,
|
||||
+ &sc->ctx_flags, time_rec);
|
||||
}
|
||||
|
||||
/* Bail out if the acceptor gave us an error token but the mech didn't
|
||||
@@ -981,8 +982,8 @@ init_ctx_call_init(OM_uint32 *minor_status,
|
||||
gss_delete_sec_context(&tmpmin, &sc->ctx_handle, GSS_C_NO_BUFFER);
|
||||
tmpret = init_ctx_call_init(&tmpmin, sc, spcred, acc_negState,
|
||||
target_name, req_flags, time_req,
|
||||
- mechtok_in, mechtok_out, time_rec,
|
||||
- send_token);
|
||||
+ mechtok_in, bindings, mechtok_out,
|
||||
+ time_rec, send_token);
|
||||
if (HARD_ERROR(tmpret))
|
||||
goto fail;
|
||||
*minor_status = tmpmin;
|
||||
@@ -1004,7 +1005,7 @@ spnego_gss_init_sec_context(
|
||||
gss_OID mech_type,
|
||||
OM_uint32 req_flags,
|
||||
OM_uint32 time_req,
|
||||
- gss_channel_bindings_t input_chan_bindings,
|
||||
+ gss_channel_bindings_t bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_OID *actual_mech,
|
||||
gss_buffer_t output_token,
|
||||
@@ -1084,8 +1085,8 @@ spnego_gss_init_sec_context(
|
||||
if (!spnego_ctx->mech_complete) {
|
||||
ret = init_ctx_call_init(minor_status, spnego_ctx, spcred,
|
||||
acc_negState, target_name, req_flags,
|
||||
- time_req, mechtok_in, &mechtok_out,
|
||||
- time_rec, &send_token);
|
||||
+ time_req, mechtok_in, bindings,
|
||||
+ &mechtok_out, time_rec, &send_token);
|
||||
if (ret != GSS_S_COMPLETE)
|
||||
goto cleanup;
|
||||
|
||||
@@ -1542,8 +1543,9 @@ cleanup:
|
||||
static OM_uint32
|
||||
acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
|
||||
spnego_gss_cred_id_t spcred, gss_buffer_t mechtok_in,
|
||||
- gss_buffer_t mechtok_out, OM_uint32 *time_rec,
|
||||
- OM_uint32 *negState, send_token_flag *tokflag)
|
||||
+ gss_channel_bindings_t bindings, gss_buffer_t mechtok_out,
|
||||
+ OM_uint32 *time_rec, OM_uint32 *negState,
|
||||
+ send_token_flag *tokflag)
|
||||
{
|
||||
OM_uint32 ret, tmpmin;
|
||||
gss_OID_desc mechoid;
|
||||
@@ -1568,13 +1570,12 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
|
||||
mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred;
|
||||
if (negoex) {
|
||||
ret = negoex_accept(minor_status, sc, mcred, mechtok_in,
|
||||
- mechtok_out, time_rec);
|
||||
+ bindings, mechtok_out, time_rec);
|
||||
} else {
|
||||
(void) gss_release_name(&tmpmin, &sc->internal_name);
|
||||
(void) gss_release_cred(&tmpmin, &sc->deleg_cred);
|
||||
ret = gss_accept_sec_context(minor_status, &sc->ctx_handle,
|
||||
- mcred, mechtok_in,
|
||||
- GSS_C_NO_CHANNEL_BINDINGS,
|
||||
+ mcred, mechtok_in, bindings,
|
||||
&sc->internal_name,
|
||||
&sc->actual_mech, mechtok_out,
|
||||
&sc->ctx_flags, time_rec,
|
||||
@@ -1620,7 +1621,7 @@ spnego_gss_accept_sec_context(
|
||||
gss_ctx_id_t *context_handle,
|
||||
gss_cred_id_t verifier_cred_handle,
|
||||
gss_buffer_t input_token,
|
||||
- gss_channel_bindings_t input_chan_bindings,
|
||||
+ gss_channel_bindings_t bindings,
|
||||
gss_name_t *src_name,
|
||||
gss_OID *mech_type,
|
||||
gss_buffer_t output_token,
|
||||
@@ -1734,8 +1735,8 @@ spnego_gss_accept_sec_context(
|
||||
*/
|
||||
if (negState != REQUEST_MIC && mechtok_in != GSS_C_NO_BUFFER) {
|
||||
ret = acc_ctx_call_acc(minor_status, sc, spcred, mechtok_in,
|
||||
- &mechtok_out, time_rec, &negState,
|
||||
- &return_token);
|
||||
+ bindings, &mechtok_out, time_rec,
|
||||
+ &negState, &return_token);
|
||||
}
|
||||
|
||||
/* Step 3: process or generate the MIC, if the negotiated mech is
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
From cec820485e8b854fe3ee42d0a67a77e7ad20595e Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Sun, 26 Apr 2020 19:55:54 -0400
|
||||
Subject: [PATCH] Pass gss_localname() through SPNEGO
|
||||
|
||||
ticket: 8897 (new)
|
||||
(cherry picked from commit f7b8a6432bd289bdc528017be122305f95b8e285)
|
||||
---
|
||||
src/lib/gssapi/spnego/gssapiP_spnego.h | 8 ++++++++
|
||||
src/lib/gssapi/spnego/spnego_mech.c | 9 ++++++++-
|
||||
2 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h
|
||||
index a93763314..066ec736f 100644
|
||||
--- a/src/lib/gssapi/spnego/gssapiP_spnego.h
|
||||
+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
|
||||
@@ -357,6 +357,14 @@ OM_uint32 KRB5_CALLCONV spnego_gss_wrap_size_limit
|
||||
OM_uint32 *max_input_size
|
||||
);
|
||||
|
||||
+OM_uint32 KRB5_CALLCONV spnego_gss_localname
|
||||
+(
|
||||
+ OM_uint32 *minor_status,
|
||||
+ const gss_name_t pname,
|
||||
+ const gss_const_OID mech_type,
|
||||
+ gss_buffer_t localname
|
||||
+);
|
||||
+
|
||||
OM_uint32 KRB5_CALLCONV spnego_gss_get_mic
|
||||
(
|
||||
OM_uint32 *minor_status,
|
||||
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
|
||||
index ec0bae6a4..594fc5894 100644
|
||||
--- a/src/lib/gssapi/spnego/spnego_mech.c
|
||||
+++ b/src/lib/gssapi/spnego/spnego_mech.c
|
||||
@@ -237,7 +237,7 @@ static struct gss_config spnego_mechanism =
|
||||
spnego_gss_inquire_context, /* gss_inquire_context */
|
||||
NULL, /* gss_internal_release_oid */
|
||||
spnego_gss_wrap_size_limit, /* gss_wrap_size_limit */
|
||||
- NULL, /* gssd_pname_to_uid */
|
||||
+ spnego_gss_localname,
|
||||
NULL, /* gss_userok */
|
||||
NULL, /* gss_export_name */
|
||||
spnego_gss_duplicate_name, /* gss_duplicate_name */
|
||||
@@ -2371,6 +2371,13 @@ spnego_gss_wrap_size_limit(
|
||||
return (ret);
|
||||
}
|
||||
|
||||
+OM_uint32 KRB5_CALLCONV
|
||||
+spnego_gss_localname(OM_uint32 *minor_status, const gss_name_t pname,
|
||||
+ const gss_const_OID mech_type, gss_buffer_t localname)
|
||||
+{
|
||||
+ return gss_localname(minor_status, pname, GSS_C_NO_OID, localname);
|
||||
+}
|
||||
+
|
||||
OM_uint32 KRB5_CALLCONV
|
||||
spnego_gss_get_mic(
|
||||
OM_uint32 *minor_status,
|
||||
|
|
@ -1,335 +0,0 @@
|
|||
From 9335481c00cd15170adec244ccff0a00a014bbab Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 5 Feb 2020 18:46:11 -0500
|
||||
Subject: [PATCH] Refactor KDC authdata list management helpers
|
||||
|
||||
Remove the unused concat_authorization_data(). Split merge_authdata()
|
||||
into two helpers, one to destructively merge without filtering and one
|
||||
to add copied elements while filtering out KDC-only authdata types.
|
||||
Remove context parameters where they aren't needed (taking advantage
|
||||
of knowledge that some libkrb5 functions don't use their context
|
||||
parameters).
|
||||
|
||||
(cherry picked from commit b2190fdc253de6024001e0f1ff9fe56c31042bb7)
|
||||
---
|
||||
src/kdc/kdc_authdata.c | 138 +++++++++++++++++++----------------------
|
||||
src/kdc/kdc_util.c | 50 ---------------
|
||||
src/kdc/kdc_util.h | 5 --
|
||||
3 files changed, 64 insertions(+), 129 deletions(-)
|
||||
|
||||
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
|
||||
index 1ebe87246..010922c27 100644
|
||||
--- a/src/kdc/kdc_authdata.c
|
||||
+++ b/src/kdc/kdc_authdata.c
|
||||
@@ -108,7 +108,7 @@ unload_authdata_plugins(krb5_context context)
|
||||
/* Return true if authdata should be filtered when copying from untrusted
|
||||
* authdata. If desired_type is non-zero, look only for that type. */
|
||||
static krb5_boolean
|
||||
-is_kdc_issued_authdatum(krb5_context context, krb5_authdata *authdata,
|
||||
+is_kdc_issued_authdatum(krb5_authdata *authdata,
|
||||
krb5_authdatatype desired_type)
|
||||
{
|
||||
krb5_boolean result = FALSE;
|
||||
@@ -117,7 +117,7 @@ is_kdc_issued_authdatum(krb5_context context, krb5_authdata *authdata,
|
||||
krb5_authdatatype *ad_types, *containee_types = NULL;
|
||||
|
||||
if (authdata->ad_type == KRB5_AUTHDATA_IF_RELEVANT) {
|
||||
- if (krb5int_get_authdata_containee_types(context, authdata, &count,
|
||||
+ if (krb5int_get_authdata_containee_types(NULL, authdata, &count,
|
||||
&containee_types) != 0)
|
||||
goto cleanup;
|
||||
ad_types = containee_types;
|
||||
@@ -152,7 +152,7 @@ cleanup:
|
||||
/* Return true if authdata contains any elements which should only come from
|
||||
* the KDC. If desired_type is non-zero, look only for that type. */
|
||||
static krb5_boolean
|
||||
-has_kdc_issued_authdata(krb5_context context, krb5_authdata **authdata,
|
||||
+has_kdc_issued_authdata(krb5_authdata **authdata,
|
||||
krb5_authdatatype desired_type)
|
||||
{
|
||||
int i;
|
||||
@@ -160,7 +160,7 @@ has_kdc_issued_authdata(krb5_context context, krb5_authdata **authdata,
|
||||
if (authdata == NULL)
|
||||
return FALSE;
|
||||
for (i = 0; authdata[i] != NULL; i++) {
|
||||
- if (is_kdc_issued_authdatum(context, authdata[i], desired_type))
|
||||
+ if (is_kdc_issued_authdatum(authdata[i], desired_type))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -181,66 +181,71 @@ has_mandatory_for_kdc_authdata(krb5_context context, krb5_authdata **authdata)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Add the elements of in_authdata to out_authdata. If copy is false,
|
||||
- * in_authdata is invalid on successful return. If ignore_kdc_issued is true,
|
||||
- * KDC-issued authdata is not copied.
|
||||
- */
|
||||
+/* Add elements from *new_elements to *existing_list, reallocating as
|
||||
+ * necessary. On success, release *new_elements and set it to NULL. */
|
||||
static krb5_error_code
|
||||
-merge_authdata(krb5_context context, krb5_authdata **in_authdata,
|
||||
- krb5_authdata ***out_authdata, krb5_boolean copy,
|
||||
- krb5_boolean ignore_kdc_issued)
|
||||
+merge_authdata(krb5_authdata ***existing_list, krb5_authdata ***new_elements)
|
||||
{
|
||||
- krb5_error_code ret;
|
||||
- size_t i, j, nadata = 0;
|
||||
- krb5_authdata **in_copy = NULL, **authdata = *out_authdata;
|
||||
+ size_t count = 0, ncount = 0;
|
||||
+ krb5_authdata **list = *existing_list, **nlist = *new_elements;
|
||||
|
||||
- if (in_authdata == NULL || in_authdata[0] == NULL)
|
||||
+ if (nlist == NULL)
|
||||
return 0;
|
||||
|
||||
- if (authdata != NULL) {
|
||||
- for (nadata = 0; authdata[nadata] != NULL; nadata++)
|
||||
- ;
|
||||
- }
|
||||
+ for (count = 0; list != NULL && list[count] != NULL; count++);
|
||||
+ for (ncount = 0; nlist[ncount] != NULL; ncount++);
|
||||
|
||||
- for (i = 0; in_authdata[i] != NULL; i++)
|
||||
- ;
|
||||
-
|
||||
- if (copy) {
|
||||
- ret = krb5_copy_authdata(context, in_authdata, &in_copy);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- in_authdata = in_copy;
|
||||
- }
|
||||
-
|
||||
- authdata = realloc(authdata, (nadata + i + 1) * sizeof(krb5_authdata *));
|
||||
- if (authdata == NULL) {
|
||||
- krb5_free_authdata(context, in_copy);
|
||||
+ list = realloc(list, (count + ncount + 1) * sizeof(*list));
|
||||
+ if (list == NULL)
|
||||
return ENOMEM;
|
||||
+
|
||||
+ memcpy(list + count, nlist, ncount * sizeof(*nlist));
|
||||
+ list[count + ncount] = NULL;
|
||||
+ free(nlist);
|
||||
+
|
||||
+ if (list[0] == NULL) {
|
||||
+ free(list);
|
||||
+ list = NULL;
|
||||
}
|
||||
|
||||
- for (i = 0, j = 0; in_authdata[i] != NULL; i++) {
|
||||
- if (ignore_kdc_issued &&
|
||||
- is_kdc_issued_authdatum(context, in_authdata[i], 0)) {
|
||||
- free(in_authdata[i]->contents);
|
||||
- free(in_authdata[i]);
|
||||
+ *new_elements = NULL;
|
||||
+ *existing_list = list;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Add a copy of new_elements to *existing_list, omitting KDC-issued
|
||||
+ * authdata. */
|
||||
+static krb5_error_code
|
||||
+add_filtered_authdata(krb5_authdata ***existing_list,
|
||||
+ krb5_authdata **new_elements)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_authdata **copy;
|
||||
+ size_t i, j;
|
||||
+
|
||||
+ if (new_elements == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = krb5_copy_authdata(NULL, new_elements, ©);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Remove KDC-issued elements from copy. */
|
||||
+ j = 0;
|
||||
+ for (i = 0; copy[i] != NULL; i++) {
|
||||
+ if (is_kdc_issued_authdatum(copy[i], 0)) {
|
||||
+ free(copy[i]->contents);
|
||||
+ free(copy[i]);
|
||||
} else {
|
||||
- authdata[nadata + j++] = in_authdata[i];
|
||||
+ copy[j++] = copy[i];
|
||||
}
|
||||
}
|
||||
+ copy[j] = NULL;
|
||||
|
||||
- authdata[nadata + j] = NULL;
|
||||
-
|
||||
- free(in_authdata);
|
||||
-
|
||||
- if (authdata[0] == NULL) {
|
||||
- free(authdata);
|
||||
- authdata = NULL;
|
||||
- }
|
||||
-
|
||||
- *out_authdata = authdata;
|
||||
-
|
||||
- return 0;
|
||||
+ /* Destructively merge the filtered copy into existing_list. */
|
||||
+ ret = merge_authdata(existing_list, ©);
|
||||
+ krb5_free_authdata(NULL, copy);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* Copy TGS-REQ authorization data into the ticket authdata. */
|
||||
@@ -289,10 +294,7 @@ copy_request_authdata(krb5_context context, krb5_keyblock *client_key,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* Add a copy of the requested authdata to the ticket, ignoring KDC-issued
|
||||
- * types. */
|
||||
- ret = merge_authdata(context, req->unenc_authdata, tkt_authdata, TRUE,
|
||||
- TRUE);
|
||||
+ ret = add_filtered_authdata(tkt_authdata, req->unenc_authdata);
|
||||
|
||||
cleanup:
|
||||
free(plaintext.data);
|
||||
@@ -307,9 +309,7 @@ copy_tgt_authdata(krb5_context context, krb5_kdc_req *request,
|
||||
if (has_mandatory_for_kdc_authdata(context, tgt_authdata))
|
||||
return KRB5KDC_ERR_POLICY;
|
||||
|
||||
- /* Add a copy of the TGT authdata to the ticket, ignoring KDC-issued
|
||||
- * types. */
|
||||
- return merge_authdata(context, tgt_authdata, tkt_authdata, TRUE, TRUE);
|
||||
+ return add_filtered_authdata(tkt_authdata, tgt_authdata);
|
||||
}
|
||||
|
||||
/* Fetch authorization data from KDB module. */
|
||||
@@ -374,8 +374,7 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
|
||||
|
||||
/* Put the KDB authdata first in the ticket. A successful merge places the
|
||||
* combined list in db_authdata and releases the old ticket authdata. */
|
||||
- ret = merge_authdata(context, enc_tkt_reply->authorization_data,
|
||||
- &db_authdata, FALSE, FALSE);
|
||||
+ ret = merge_authdata(&db_authdata, &enc_tkt_reply->authorization_data);
|
||||
if (ret)
|
||||
krb5_free_authdata(context, db_authdata);
|
||||
else
|
||||
@@ -404,8 +403,7 @@ make_signedpath_data(krb5_context context, krb5_const_principal client,
|
||||
return ret;
|
||||
|
||||
for (i = 0, j = 0; authdata[i] != NULL; i++) {
|
||||
- if (is_kdc_issued_authdatum(context, authdata[i],
|
||||
- KRB5_AUTHDATA_SIGNTICKET))
|
||||
+ if (is_kdc_issued_authdatum(authdata[i], KRB5_AUTHDATA_SIGNTICKET))
|
||||
continue;
|
||||
|
||||
sign_authdata[j++] = authdata[i];
|
||||
@@ -635,12 +633,8 @@ make_signedpath(krb5_context context, krb5_const_principal for_user_princ,
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
- /* Add the authdata to the ticket, without copying or filtering. */
|
||||
- ret = merge_authdata(context, if_relevant,
|
||||
- &enc_tkt_reply->authorization_data, FALSE, FALSE);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
- if_relevant = NULL; /* merge_authdata() freed */
|
||||
+ /* Add the signedpath authdata to the ticket. */
|
||||
+ ret = merge_authdata(&enc_tkt_reply->authorization_data, &if_relevant);
|
||||
|
||||
cleanup:
|
||||
free(sp.delegated);
|
||||
@@ -665,7 +659,7 @@ free_deleg_path(krb5_context context, krb5_principal *deleg_path)
|
||||
static krb5_boolean
|
||||
has_pac(krb5_context context, krb5_authdata **authdata)
|
||||
{
|
||||
- return has_kdc_issued_authdata(context, authdata, KRB5_AUTHDATA_WIN2K_PAC);
|
||||
+ return has_kdc_issued_authdata(authdata, KRB5_AUTHDATA_WIN2K_PAC);
|
||||
}
|
||||
|
||||
/* Verify AD-SIGNTICKET authdata if we need to, and insert an AD-SIGNEDPATH
|
||||
@@ -746,11 +740,7 @@ add_auth_indicators(krb5_context context, krb5_data *const *auth_indicators,
|
||||
goto cleanup;
|
||||
|
||||
/* Add the wrapped authdata to the ticket, without copying or filtering. */
|
||||
- ret = merge_authdata(context, cammac, &enc_tkt_reply->authorization_data,
|
||||
- FALSE, FALSE);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
- cammac = NULL; /* merge_authdata() freed */
|
||||
+ ret = merge_authdata(&enc_tkt_reply->authorization_data, &cammac);
|
||||
|
||||
cleanup:
|
||||
krb5_free_data(context, der_indicators);
|
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
|
||||
index 6330387d0..a4a05b9fa 100644
|
||||
--- a/src/kdc/kdc_util.c
|
||||
+++ b/src/kdc/kdc_util.c
|
||||
@@ -78,56 +78,6 @@ static krb5_error_code find_server_key(krb5_context,
|
||||
krb5_kvno, krb5_keyblock **,
|
||||
krb5_kvno *);
|
||||
|
||||
-/*
|
||||
- * concatenate first two authdata arrays, returning an allocated replacement.
|
||||
- * The replacement should be freed with krb5_free_authdata().
|
||||
- */
|
||||
-krb5_error_code
|
||||
-concat_authorization_data(krb5_context context,
|
||||
- krb5_authdata **first, krb5_authdata **second,
|
||||
- krb5_authdata ***output)
|
||||
-{
|
||||
- int i, j;
|
||||
- krb5_authdata **ptr, **retdata;
|
||||
-
|
||||
- /* count up the entries */
|
||||
- i = 0;
|
||||
- if (first)
|
||||
- for (ptr = first; *ptr; ptr++)
|
||||
- i++;
|
||||
- if (second)
|
||||
- for (ptr = second; *ptr; ptr++)
|
||||
- i++;
|
||||
-
|
||||
- retdata = (krb5_authdata **)malloc((i+1)*sizeof(*retdata));
|
||||
- if (!retdata)
|
||||
- return ENOMEM;
|
||||
- retdata[i] = 0; /* null-terminated array */
|
||||
- for (i = 0, j = 0, ptr = first; j < 2 ; ptr = second, j++)
|
||||
- while (ptr && *ptr) {
|
||||
- /* now walk & copy */
|
||||
- retdata[i] = (krb5_authdata *)malloc(sizeof(*retdata[i]));
|
||||
- if (!retdata[i]) {
|
||||
- krb5_free_authdata(context, retdata);
|
||||
- return ENOMEM;
|
||||
- }
|
||||
- *retdata[i] = **ptr;
|
||||
- if (!(retdata[i]->contents =
|
||||
- (krb5_octet *)malloc(retdata[i]->length))) {
|
||||
- free(retdata[i]);
|
||||
- retdata[i] = 0;
|
||||
- krb5_free_authdata(context, retdata);
|
||||
- return ENOMEM;
|
||||
- }
|
||||
- memcpy(retdata[i]->contents, (*ptr)->contents, retdata[i]->length);
|
||||
-
|
||||
- ptr++;
|
||||
- i++;
|
||||
- }
|
||||
- *output = retdata;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
krb5_boolean
|
||||
is_local_principal(kdc_realm_t *kdc_active_realm, krb5_const_principal princ1)
|
||||
{
|
||||
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
|
||||
index 2c9d8cf69..42b7ee208 100644
|
||||
--- a/src/kdc/kdc_util.h
|
||||
+++ b/src/kdc/kdc_util.h
|
||||
@@ -52,11 +52,6 @@ compress_transited (krb5_data *,
|
||||
krb5_principal,
|
||||
krb5_data *);
|
||||
krb5_error_code
|
||||
-concat_authorization_data (krb5_context,
|
||||
- krb5_authdata **,
|
||||
- krb5_authdata **,
|
||||
- krb5_authdata ***);
|
||||
-krb5_error_code
|
||||
fetch_last_req_info (krb5_db_entry *, krb5_last_req_entry ***);
|
||||
|
||||
krb5_error_code
|
||||
|
|
@ -1,479 +0,0 @@
|
|||
From c90cef2ebfbefc595798dd5dbb805575e1be0fbf Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Scheel <ascheel@redhat.com>
|
||||
Date: Fri, 30 Jun 2017 16:03:01 -0400
|
||||
Subject: [PATCH] Refactor krb5 GSS checksum handling
|
||||
|
||||
Separate out checksum handling from kg_accept_krb5() into a new helper
|
||||
process_checksum().
|
||||
|
||||
[ghudson@mit.edu: simplified checksum processing and made it use
|
||||
k5-input.h instead of TREAD_ macros; moved more flag handling into
|
||||
helper]
|
||||
|
||||
[iboukris: adjusted helper function arguments, allowing access to the
|
||||
full authenticator for subsequent changes]
|
||||
|
||||
(cherry picked from commit 64d56233f9816a2a93f6e8d3030c8ed6ce397735)
|
||||
[rharwood@redhat.com: problem with typo fix commit, I think]
|
||||
---
|
||||
src/lib/gssapi/krb5/accept_sec_context.c | 383 +++++++++++------------
|
||||
1 file changed, 179 insertions(+), 204 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
index c5bddb1e8..70dd7fc0c 100644
|
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
@@ -98,6 +98,7 @@
|
||||
*/
|
||||
|
||||
#include "k5-int.h"
|
||||
+#include "k5-input.h"
|
||||
#include "gssapiP_krb5.h"
|
||||
#ifdef HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
@@ -413,6 +414,174 @@ kg_process_extension(krb5_context context,
|
||||
return code;
|
||||
}
|
||||
|
||||
+/* The length of the MD5 channel bindings in an 0x8003 checksum */
|
||||
+#define CB_MD5_LEN 16
|
||||
+
|
||||
+/* The minimum length of an 0x8003 checksum value (4-byte channel bindings
|
||||
+ * length, 16-byte channel bindings, 4-byte flags) */
|
||||
+#define MIN_8003_LEN (4 + CB_MD5_LEN + 4)
|
||||
+
|
||||
+/* The flags we accept from the initiator's authenticator checksum. */
|
||||
+#define INITIATOR_FLAGS (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | \
|
||||
+ GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \
|
||||
+ GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE | \
|
||||
+ GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG)
|
||||
+
|
||||
+/*
|
||||
+ * The krb5 GSS mech appropriates the authenticator checksum field from RFC
|
||||
+ * 4120 to store structured data instead of a checksum, indicated with checksum
|
||||
+ * type 0x8003 (see RFC 4121 section 4.1.1). Some implementations instead send
|
||||
+ * no checksum, or a regular checksum over empty data.
|
||||
+ *
|
||||
+ * Interpret the checksum. Read delegated creds into *deleg_out if it is not
|
||||
+ * NULL. Set *flags_out to the allowed subset of token flags, plus
|
||||
+ * GSS_C_DELEG_FLAG if a delegated credential was present. Process any
|
||||
+ * extensions found using exts. On error, set *code_out to a krb5_error code
|
||||
+ * for use as a minor status value.
|
||||
+ */
|
||||
+static OM_uint32
|
||||
+process_checksum(OM_uint32 *minor_status, krb5_context context,
|
||||
+ gss_channel_bindings_t acceptor_cb,
|
||||
+ krb5_auth_context auth_context, krb5_flags ap_req_options,
|
||||
+ krb5_authenticator *authenticator, krb5_gss_ctx_ext_t exts,
|
||||
+ krb5_gss_cred_id_t *deleg_out, krb5_ui_4 *flags_out,
|
||||
+ krb5_error_code *code_out)
|
||||
+{
|
||||
+ krb5_error_code code = 0;
|
||||
+ OM_uint32 status, option_id, token_flags;
|
||||
+ size_t cb_len, option_len;
|
||||
+ krb5_boolean valid;
|
||||
+ krb5_key subkey;
|
||||
+ krb5_data option, empty = empty_data();
|
||||
+ krb5_checksum cb_cksum;
|
||||
+ const uint8_t *token_cb, *option_bytes;
|
||||
+ struct k5input in;
|
||||
+ const krb5_checksum *cksum = authenticator->checksum;
|
||||
+
|
||||
+ cb_cksum.contents = NULL;
|
||||
+
|
||||
+ if (cksum == NULL) {
|
||||
+ /*
|
||||
+ * Some SMB client implementations use handcrafted GSSAPI code that
|
||||
+ * does not provide a checksum. MS-KILE documents that the Microsoft
|
||||
+ * implementation considers a missing checksum acceptable; the server
|
||||
+ * assumes all flags are unset in this case, and does not check channel
|
||||
+ * bindings.
|
||||
+ */
|
||||
+ *flags_out = 0;
|
||||
+ } else if (cksum->checksum_type != CKSUMTYPE_KG_CB) {
|
||||
+ /* Samba sends a regular checksum. */
|
||||
+ code = krb5_auth_con_getkey_k(context, auth_context, &subkey);
|
||||
+ if (code) {
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Verifying the checksum ensures that this authenticator wasn't
|
||||
+ * replayed from one with a checksum over actual data. */
|
||||
+ code = krb5_k_verify_checksum(context, subkey,
|
||||
+ KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, &empty,
|
||||
+ cksum, &valid);
|
||||
+ krb5_k_free_key(context, subkey);
|
||||
+ if (code || !valid) {
|
||||
+ status = GSS_S_BAD_SIG;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Use ap_options from the request to guess the mutual flag. */
|
||||
+ *flags_out = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
|
||||
+ if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED)
|
||||
+ *flags_out |= GSS_C_MUTUAL_FLAG;
|
||||
+ } else {
|
||||
+ /* The checksum must contain at least a fixed 24-byte part. */
|
||||
+ if (cksum->length < MIN_8003_LEN) {
|
||||
+ status = GSS_S_BAD_BINDINGS;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ k5_input_init(&in, cksum->contents, cksum->length);
|
||||
+ cb_len = k5_input_get_uint32_le(&in);
|
||||
+ if (cb_len != CB_MD5_LEN) {
|
||||
+ code = KG_BAD_LENGTH;
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ token_cb = k5_input_get_bytes(&in, cb_len);
|
||||
+ if (acceptor_cb != GSS_C_NO_CHANNEL_BINDINGS) {
|
||||
+ code = kg_checksum_channel_bindings(context, acceptor_cb,
|
||||
+ &cb_cksum);
|
||||
+ if (code) {
|
||||
+ status = GSS_S_BAD_BINDINGS;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ assert(cb_cksum.length == cb_len);
|
||||
+ if (k5_bcmp(token_cb, cb_cksum.contents, cb_len) != 0) {
|
||||
+ status = GSS_S_BAD_BINDINGS;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Read the token flags and accept some of them as context flags. */
|
||||
+ token_flags = k5_input_get_uint32_le(&in);
|
||||
+ *flags_out = token_flags & INITIATOR_FLAGS;
|
||||
+
|
||||
+ /* Read the delegated credential if present. */
|
||||
+ if (in.len >= 4 && (token_flags & GSS_C_DELEG_FLAG)) {
|
||||
+ option_id = k5_input_get_uint16_le(&in);
|
||||
+ option_len = k5_input_get_uint16_le(&in);
|
||||
+ option_bytes = k5_input_get_bytes(&in, option_len);
|
||||
+ option = make_data((uint8_t *)option_bytes, option_len);
|
||||
+ if (in.status) {
|
||||
+ code = KG_BAD_LENGTH;
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Store the delegated credential. */
|
||||
+ code = rd_and_store_for_creds(context, auth_context, &option,
|
||||
+ deleg_out);
|
||||
+ if (code) {
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ *flags_out |= GSS_C_DELEG_FLAG;
|
||||
+ }
|
||||
+
|
||||
+ /* Process any extensions at the end of the checksum. Extensions use
|
||||
+ * 4-byte big-endian tag and length instead of 2-byte little-endian. */
|
||||
+ while (in.len > 0) {
|
||||
+ option_id = k5_input_get_uint32_be(&in);
|
||||
+ option_len = k5_input_get_uint32_be(&in);
|
||||
+ option_bytes = k5_input_get_bytes(&in, option_len);
|
||||
+ option = make_data((uint8_t *)option_bytes, option_len);
|
||||
+ if (in.status) {
|
||||
+ code = KG_BAD_LENGTH;
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ code = kg_process_extension(context, auth_context, option_id,
|
||||
+ &option, exts);
|
||||
+ if (code) {
|
||||
+ status = GSS_S_FAILURE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ status = GSS_S_COMPLETE;
|
||||
+
|
||||
+fail:
|
||||
+ free(cb_cksum.contents);
|
||||
+ *code_out = code;
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
static OM_uint32
|
||||
kg_accept_krb5(minor_status, context_handle,
|
||||
verifier_cred_handle, input_token,
|
||||
@@ -433,17 +602,13 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
krb5_gss_ctx_ext_t exts;
|
||||
{
|
||||
krb5_context context;
|
||||
- unsigned char *ptr, *ptr2;
|
||||
+ unsigned char *ptr;
|
||||
char *sptr;
|
||||
- OM_uint32 tmp;
|
||||
- size_t md5len;
|
||||
krb5_gss_cred_id_t cred = 0;
|
||||
krb5_data ap_rep, ap_req;
|
||||
- unsigned int i;
|
||||
krb5_error_code code;
|
||||
krb5_address addr, *paddr;
|
||||
krb5_authenticator *authdat = 0;
|
||||
- krb5_checksum reqcksum;
|
||||
krb5_gss_name_t name = NULL;
|
||||
krb5_ui_4 gss_flags = 0;
|
||||
krb5_gss_ctx_id_rec *ctx = NULL;
|
||||
@@ -451,8 +616,6 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
gss_buffer_desc token;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
krb5_ticket * ticket = NULL;
|
||||
- int option_id;
|
||||
- krb5_data option;
|
||||
const gss_OID_desc *mech_used = NULL;
|
||||
OM_uint32 major_status = GSS_S_FAILURE;
|
||||
OM_uint32 tmp_minor_status;
|
||||
@@ -463,7 +626,6 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
krb5int_access kaccess;
|
||||
int cred_rcache = 0;
|
||||
int no_encap = 0;
|
||||
- int token_deleg_flag = 0;
|
||||
krb5_flags ap_req_options = 0;
|
||||
krb5_enctype negotiated_etype;
|
||||
krb5_authdata_context ad_context = NULL;
|
||||
@@ -489,7 +651,6 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
output_token->length = 0;
|
||||
output_token->value = NULL;
|
||||
token.value = 0;
|
||||
- reqcksum.contents = 0;
|
||||
ap_req.data = 0;
|
||||
ap_rep.data = 0;
|
||||
|
||||
@@ -654,195 +815,16 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
|
||||
krb5_auth_con_getauthenticator(context, auth_context, &authdat);
|
||||
|
||||
- if (authdat->checksum == NULL) {
|
||||
- /*
|
||||
- * Some SMB client implementations use handcrafted GSSAPI code that
|
||||
- * does not provide a checksum. MS-KILE documents that the Microsoft
|
||||
- * implementation considers a missing checksum acceptable; the server
|
||||
- * assumes all flags are unset in this case, and does not check channel
|
||||
- * bindings.
|
||||
- */
|
||||
- gss_flags = 0;
|
||||
- } else if (authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) {
|
||||
- /* Samba does not send 0x8003 GSS-API checksums */
|
||||
- krb5_boolean valid;
|
||||
- krb5_key subkey;
|
||||
- krb5_data zero;
|
||||
+ major_status = process_checksum(minor_status, context, input_chan_bindings,
|
||||
+ auth_context, ap_req_options,
|
||||
+ authdat, exts,
|
||||
+ delegated_cred_handle ? &deleg_cred : NULL,
|
||||
+ &gss_flags, &code);
|
||||
|
||||
- code = krb5_auth_con_getkey_k(context, auth_context, &subkey);
|
||||
- if (code) {
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
+ if (major_status != GSS_S_COMPLETE)
|
||||
+ goto fail;
|
||||
|
||||
- zero.length = 0;
|
||||
- zero.data = "";
|
||||
-
|
||||
- code = krb5_k_verify_checksum(context,
|
||||
- subkey,
|
||||
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
|
||||
- &zero,
|
||||
- authdat->checksum,
|
||||
- &valid);
|
||||
- krb5_k_free_key(context, subkey);
|
||||
- if (code || !valid) {
|
||||
- major_status = GSS_S_BAD_SIG;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /* Use ap_options from the request to guess the mutual flag. */
|
||||
- gss_flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
|
||||
- if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED)
|
||||
- gss_flags |= GSS_C_MUTUAL_FLAG;
|
||||
- } else {
|
||||
- /* gss krb5 v1 */
|
||||
-
|
||||
- /* stash this now, for later. */
|
||||
- code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &md5len);
|
||||
- if (code) {
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /* verify that the checksum is correct */
|
||||
-
|
||||
- /*
|
||||
- The checksum may be either exactly 24 bytes, in which case
|
||||
- no options are specified, or greater than 24 bytes, in which case
|
||||
- one or more options are specified. Currently, the only valid
|
||||
- option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ).
|
||||
- */
|
||||
-
|
||||
- if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) ||
|
||||
- (authdat->checksum->length < 24)) {
|
||||
- code = 0;
|
||||
- major_status = GSS_S_BAD_BINDINGS;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- ptr = (unsigned char *) authdat->checksum->contents;
|
||||
-
|
||||
- TREAD_INT(ptr, tmp, 0);
|
||||
-
|
||||
- if (tmp != md5len) {
|
||||
- code = KG_BAD_LENGTH;
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- The following section of code attempts to implement the
|
||||
- optional channel binding facility as described in RFC2743.
|
||||
-
|
||||
- Since this facility is optional channel binding may or may
|
||||
- not have been provided by either the client or the server.
|
||||
-
|
||||
- If the server has specified input_chan_bindings equal to
|
||||
- GSS_C_NO_CHANNEL_BINDINGS then we skip the check. If
|
||||
- the server does provide channel bindings then we compute
|
||||
- a checksum and compare against those provided by the
|
||||
- client. */
|
||||
-
|
||||
- if ((code = kg_checksum_channel_bindings(context,
|
||||
- input_chan_bindings,
|
||||
- &reqcksum))) {
|
||||
- major_status = GSS_S_BAD_BINDINGS;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /* Always read the clients bindings - eventhough we might ignore them */
|
||||
- TREAD_STR(ptr, ptr2, reqcksum.length);
|
||||
-
|
||||
- if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS ) {
|
||||
- if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
|
||||
- xfree(reqcksum.contents);
|
||||
- reqcksum.contents = 0;
|
||||
- code = 0;
|
||||
- major_status = GSS_S_BAD_BINDINGS;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- }
|
||||
-
|
||||
- xfree(reqcksum.contents);
|
||||
- reqcksum.contents = 0;
|
||||
-
|
||||
- /* Read the token flags. Remember if GSS_C_DELEG_FLAG was set, but
|
||||
- * mask it out until we actually read a delegated credential. */
|
||||
- TREAD_INT(ptr, gss_flags, 0);
|
||||
- token_deleg_flag = (gss_flags & GSS_C_DELEG_FLAG);
|
||||
- gss_flags &= ~GSS_C_DELEG_FLAG;
|
||||
-
|
||||
- /* if the checksum length > 24, there are options to process */
|
||||
-
|
||||
- i = authdat->checksum->length - 24;
|
||||
- if (i && token_deleg_flag) {
|
||||
- if (i >= 4) {
|
||||
- TREAD_INT16(ptr, option_id, 0);
|
||||
- TREAD_INT16(ptr, option.length, 0);
|
||||
- i -= 4;
|
||||
-
|
||||
- if (i < option.length) {
|
||||
- code = KG_BAD_LENGTH;
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /* have to use ptr2, since option.data is wrong type and
|
||||
- macro uses ptr as both lvalue and rvalue */
|
||||
-
|
||||
- TREAD_STR(ptr, ptr2, option.length);
|
||||
- option.data = (char *) ptr2;
|
||||
-
|
||||
- i -= option.length;
|
||||
-
|
||||
- if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /* store the delegated credential */
|
||||
-
|
||||
- code = rd_and_store_for_creds(context, auth_context, &option,
|
||||
- (delegated_cred_handle) ?
|
||||
- &deleg_cred : NULL);
|
||||
- if (code) {
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- gss_flags |= GSS_C_DELEG_FLAG;
|
||||
- } /* if i >= 4 */
|
||||
- /* ignore any additional trailing data, for now */
|
||||
- }
|
||||
- while (i > 0) {
|
||||
- /* Process Type-Length-Data options */
|
||||
- if (i < 8) {
|
||||
- code = KG_BAD_LENGTH;
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
- TREAD_INT(ptr, option_id, 1);
|
||||
- TREAD_INT(ptr, option.length, 1);
|
||||
- i -= 8;
|
||||
- if (i < option.length) {
|
||||
- code = KG_BAD_LENGTH;
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
- TREAD_STR(ptr, ptr2, option.length);
|
||||
- option.data = (char *)ptr2;
|
||||
-
|
||||
- i -= option.length;
|
||||
-
|
||||
- code = kg_process_extension(context, auth_context,
|
||||
- option_id, &option, exts);
|
||||
- if (code != 0) {
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ major_status = GSS_S_FAILURE;
|
||||
|
||||
if (exts->iakerb.conv && !exts->iakerb.verified) {
|
||||
major_status = GSS_S_BAD_SIG;
|
||||
@@ -869,12 +851,7 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
ctx->mech_used = (gss_OID) mech_used;
|
||||
ctx->auth_context = auth_context;
|
||||
ctx->initiate = 0;
|
||||
- ctx->gss_flags = (GSS_C_TRANS_FLAG |
|
||||
- ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
|
||||
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
|
||||
- GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG |
|
||||
- GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG |
|
||||
- GSS_C_EXTENDED_ERROR_FLAG)));
|
||||
+ ctx->gss_flags = gss_flags | GSS_C_TRANS_FLAG;
|
||||
ctx->seed_init = 0;
|
||||
ctx->cred_rcache = cred_rcache;
|
||||
|
||||
@@ -1161,8 +1138,6 @@ fail:
|
||||
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
}
|
||||
- if (reqcksum.contents)
|
||||
- xfree(reqcksum.contents);
|
||||
if (ap_rep.data)
|
||||
krb5_free_data_contents(context, &ap_rep);
|
||||
if (major_status == GSS_S_COMPLETE ||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
From 7316aaa0e9249a88e919f2596d881f78970548bc Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Wed, 26 Feb 2020 18:27:17 -0500
|
||||
Subject: [PATCH] Refresh manually acquired creds from client keytab
|
||||
|
||||
If a client keytab is present but credentials are acquired manually,
|
||||
the credentials would not be refreshed because no refresh_time config
|
||||
var is set in the cache. Change kg_cred_time_to_refresh() to attempt
|
||||
a refresh from the client keytab on any credentials which will expire
|
||||
in the next 30 seconds.
|
||||
|
||||
[ghudson@mit.edu: adjused code and added test case]
|
||||
|
||||
ticket: 7976
|
||||
(cherry picked from commit 729896467e3c77904666019d6cbbda583ae49b95)
|
||||
---
|
||||
src/lib/gssapi/krb5/acquire_cred.c | 14 +++++++++++---
|
||||
src/tests/gssapi/t_client_keytab.py | 18 ++++++++++++++++++
|
||||
2 files changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
|
||||
index acc1868f8..4062f4741 100644
|
||||
--- a/src/lib/gssapi/krb5/acquire_cred.c
|
||||
+++ b/src/lib/gssapi/krb5/acquire_cred.c
|
||||
@@ -557,15 +557,23 @@ set_refresh_time(krb5_context context, krb5_ccache ccache,
|
||||
krb5_boolean
|
||||
kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
{
|
||||
- krb5_timestamp now;
|
||||
+ krb5_timestamp now, soon;
|
||||
|
||||
if (krb5_timeofday(context, &now))
|
||||
return FALSE;
|
||||
+ soon = ts_incr(now, 30);
|
||||
if (cred->refresh_time != 0 && !ts_after(cred->refresh_time, now)) {
|
||||
- set_refresh_time(context, cred->ccache,
|
||||
- ts_incr(cred->refresh_time, 30));
|
||||
+ set_refresh_time(context, cred->ccache, soon);
|
||||
return TRUE;
|
||||
}
|
||||
+
|
||||
+ /* If the creds will expire soon, try to refresh even if they weren't
|
||||
+ * acquired with a client keytab. */
|
||||
+ if (ts_after(soon, cred->expire)) {
|
||||
+ set_refresh_time(context, cred->ccache, soon);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py
|
||||
index e474a27c7..7847b3ecd 100755
|
||||
--- a/src/tests/gssapi/t_client_keytab.py
|
||||
+++ b/src/tests/gssapi/t_client_keytab.py
|
||||
@@ -124,4 +124,22 @@ realm.kinit(realm.user_princ, password('user'))
|
||||
realm.run(['./t_ccselect', phost], env=bad_cktname,
|
||||
expected_msg=realm.user_princ)
|
||||
|
||||
+mark('refresh of manually acquired creds')
|
||||
+
|
||||
+# Test 17: no name/ccache specified, manually acquired creds which
|
||||
+# will expire soon. Verify that creds are refreshed using the current
|
||||
+# client name, with refresh_time set in the refreshed ccache.
|
||||
+realm.kinit('bob', password('bob'), ['-l', '15s'])
|
||||
+realm.run(['./t_ccselect', phost], expected_msg='bob')
|
||||
+realm.run([klist, '-C'], expected_msg='refresh_time = ')
|
||||
+
|
||||
+# Test 18: no name/ccache specified, manually acquired creds with a
|
||||
+# client principal not present in the client keytab. A refresh is
|
||||
+# attempted but fails, and an expired ticket error results.
|
||||
+realm.kinit(realm.admin_princ, password('admin'), ['-l', '-1s'])
|
||||
+msgs = ('Getting initial credentials for user/admin@KRBTEST.COM',
|
||||
+ '/Matching credential not found')
|
||||
+realm.run(['./t_ccselect', phost], expected_code=1,
|
||||
+ expected_msg='Ticket expired', expected_trace=msgs)
|
||||
+
|
||||
success('Client keytab tests')
|
||||
|
|
@ -1,547 +0,0 @@
|
|||
From 3e75969e0c0a52ec3ca8195200fcdadaa63b324f Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Thu, 28 May 2020 18:41:02 -0400
|
||||
Subject: [PATCH] Remove resolver test utility
|
||||
|
||||
tests/resolve is no longer used after the previous commit.
|
||||
|
||||
[rharwood@redhat.com: .gitignore]
|
||||
---
|
||||
src/configure.ac | 5 +-
|
||||
src/tests/Makefile.in | 4 +-
|
||||
src/tests/resolve/Makefile.in | 28 ---
|
||||
src/tests/resolve/addrinfo-test.c | 306 -------------------------
|
||||
src/tests/resolve/deps | 14 --
|
||||
src/tests/resolve/fake-addrinfo-test.c | 3 -
|
||||
src/tests/resolve/resolve.c | 115 ----------
|
||||
7 files changed, 4 insertions(+), 471 deletions(-)
|
||||
delete mode 100644 src/tests/resolve/Makefile.in
|
||||
delete mode 100644 src/tests/resolve/addrinfo-test.c
|
||||
delete mode 100644 src/tests/resolve/deps
|
||||
delete mode 100644 src/tests/resolve/fake-addrinfo-test.c
|
||||
delete mode 100644 src/tests/resolve/resolve.c
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index aafc462f9..00b5ea4c5 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1540,7 +1540,6 @@ V5_AC_OUTPUT_MAKEFILE(.
|
||||
appl/simple appl/simple/client appl/simple/server
|
||||
appl/gss-sample appl/user_user
|
||||
|
||||
- tests tests/resolve tests/asn.1 tests/create tests/hammer
|
||||
- tests/verify tests/gssapi tests/dejagnu tests/threads tests/shlib
|
||||
- tests/gss-threads tests/misc
|
||||
+ tests tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi
|
||||
+ tests/dejagnu tests/threads tests/shlib tests/gss-threads tests/misc
|
||||
)
|
||||
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
|
||||
index 3f88f1713..6b7749129 100644
|
||||
--- a/src/tests/Makefile.in
|
||||
+++ b/src/tests/Makefile.in
|
||||
@@ -1,7 +1,7 @@
|
||||
mydir=tests
|
||||
BUILDTOP=$(REL)..
|
||||
-SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \
|
||||
- gss-threads misc threads softpkcs11
|
||||
+SUBDIRS = asn.1 create hammer verify gssapi dejagnu shlib gss-threads misc \
|
||||
+ threads softpkcs11
|
||||
|
||||
RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \
|
||||
GSS_MECH_CONFIG=mech.conf LC_ALL=C $(VALGRIND)
|
||||
diff --git a/src/tests/resolve/Makefile.in b/src/tests/resolve/Makefile.in
|
||||
deleted file mode 100644
|
||||
index 1f5954089..000000000
|
||||
--- a/src/tests/resolve/Makefile.in
|
||||
+++ /dev/null
|
||||
@@ -1,28 +0,0 @@
|
||||
-mydir=tests$(S)resolve
|
||||
-BUILDTOP=$(REL)..$(S)..
|
||||
-
|
||||
-OBJS=resolve.o addrinfo-test.o fake-addrinfo-test.o
|
||||
-SRCS=$(srcdir)/resolve.c $(srcdir)/addrinfo-test.c \
|
||||
- $(srcdir)/fake-addrinfo-test.c
|
||||
-
|
||||
-all: resolve addrinfo-test fake-addrinfo-test
|
||||
-
|
||||
-resolve: resolve.o
|
||||
- $(CC_LINK) -o $@ resolve.o $(SUPPORT_LIB) $(LIBS)
|
||||
-
|
||||
-addrinfo-test: addrinfo-test.o
|
||||
- $(CC_LINK) -o $@ addrinfo-test.o $(SUPPORT_LIB) $(LIBS)
|
||||
-
|
||||
-fake-addrinfo-test: fake-addrinfo-test.o
|
||||
- $(CC_LINK) -o $@ fake-addrinfo-test.o $(SUPPORT_LIB) $(LIBS)
|
||||
-
|
||||
-check: resolve addrinfo-test fake-addrinfo-test
|
||||
- $(RUN_TEST) ./resolve
|
||||
- $(RUN_TEST) ./addrinfo-test -p telnet
|
||||
- $(RUN_TEST) ./fake-addrinfo-test -p telnet
|
||||
-
|
||||
-install:
|
||||
-
|
||||
-clean:
|
||||
- $(RM) resolve addrinfo-test fake-addrinfo-test
|
||||
-
|
||||
diff --git a/src/tests/resolve/addrinfo-test.c b/src/tests/resolve/addrinfo-test.c
|
||||
deleted file mode 100644
|
||||
index e77640b62..000000000
|
||||
--- a/src/tests/resolve/addrinfo-test.c
|
||||
+++ /dev/null
|
||||
@@ -1,306 +0,0 @@
|
||||
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
-/* tests/resolve/addrinfo-test.c */
|
||||
-/*
|
||||
- * Copyright 2004 by the Massachusetts Institute of Technology.
|
||||
- * All Rights Reserved.
|
||||
- *
|
||||
- * Export of this software from the United States of America may
|
||||
- * require a specific license from the United States Government.
|
||||
- * It is the responsibility of any person or organization contemplating
|
||||
- * export to obtain such a license before exporting.
|
||||
- *
|
||||
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
- * distribute this software and its documentation for any purpose and
|
||||
- * without fee is hereby granted, provided that the above copyright
|
||||
- * notice appear in all copies and that both that copyright notice and
|
||||
- * this permission notice appear in supporting documentation, and that
|
||||
- * the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
- * to distribution of the software without specific, written prior
|
||||
- * permission. Furthermore if you modify this software you must label
|
||||
- * your software as modified software and not distribute it in such a
|
||||
- * fashion that it might be confused with the original M.I.T. software.
|
||||
- * M.I.T. makes no representations about the suitability of
|
||||
- * this software for any purpose. It is provided "as is" without express
|
||||
- * or implied warranty.
|
||||
- */
|
||||
-
|
||||
-/*
|
||||
- * A simple program to test the functionality of the getaddrinfo function.
|
||||
- *
|
||||
- * Usage:
|
||||
- * addrinfo-test [-t|-u|-R|-I] [-d|-s|-r] [-p port] [-P] [hostname]
|
||||
- *
|
||||
- * When invoked with no arguments, NULL is used for the node name,
|
||||
- * which (at least with a non-null "port") means a socket address
|
||||
- * is desired that can be used with connect() or bind() (depending
|
||||
- * on whether "-P" is given).
|
||||
- */
|
||||
-
|
||||
-#include <k5-platform.h>
|
||||
-#include <sys/types.h>
|
||||
-#include <sys/socket.h>
|
||||
-#include <netdb.h>
|
||||
-#include <netinet/in.h> /* needed for IPPROTO_* on NetBSD */
|
||||
-#ifdef USE_FAKE_ADDRINFO
|
||||
-#include "fake-addrinfo.h"
|
||||
-#endif
|
||||
-
|
||||
-static const char *protoname (int p) {
|
||||
- static char buf[30];
|
||||
-
|
||||
-#define X(N) if (p == IPPROTO_ ## N) return #N
|
||||
-
|
||||
- X(TCP);
|
||||
- X(UDP);
|
||||
- X(ICMP);
|
||||
-#ifdef IPPROTO_IPV6
|
||||
- X(IPV6);
|
||||
-#endif
|
||||
-#ifdef IPPROTO_GRE
|
||||
- X(GRE);
|
||||
-#endif
|
||||
-#ifdef IPPROTO_NONE
|
||||
- X(NONE);
|
||||
-#endif
|
||||
- X(RAW);
|
||||
-#ifdef IPPROTO_COMP
|
||||
- X(COMP);
|
||||
-#endif
|
||||
-
|
||||
- snprintf(buf, sizeof(buf), " %-2d", p);
|
||||
- return buf;
|
||||
-}
|
||||
-
|
||||
-static const char *socktypename (int t) {
|
||||
- static char buf[30];
|
||||
- switch (t) {
|
||||
- case SOCK_DGRAM: return "DGRAM";
|
||||
- case SOCK_STREAM: return "STREAM";
|
||||
- case SOCK_RAW: return "RAW";
|
||||
- case SOCK_RDM: return "RDM";
|
||||
- case SOCK_SEQPACKET: return "SEQPACKET";
|
||||
- }
|
||||
- snprintf(buf, sizeof(buf), " %-2d", t);
|
||||
- return buf;
|
||||
-}
|
||||
-
|
||||
-static char *whoami;
|
||||
-
|
||||
-static void usage () {
|
||||
- fprintf(stderr,
|
||||
- "usage:\n"
|
||||
- "\t%s [ options ] [host]\n"
|
||||
- "options:\n"
|
||||
- "\t-t\tspecify protocol IPPROTO_TCP\n"
|
||||
- "\t-u\tspecify protocol IPPROTO_UDP\n"
|
||||
- "\t-R\tspecify protocol IPPROTO_RAW\n"
|
||||
- "\t-I\tspecify protocol IPPROTO_ICMP\n"
|
||||
- "\n"
|
||||
- "\t-d\tspecify socket type SOCK_DGRAM\n"
|
||||
- "\t-s\tspecify socket type SOCK_STREAM\n"
|
||||
- "\t-r\tspecify socket type SOCK_RAW\n"
|
||||
- "\n"
|
||||
- "\t-4\tspecify address family AF_INET\n"
|
||||
-#ifdef AF_INET6
|
||||
- "\t-6\tspecify address family AF_INET6\n"
|
||||
-#endif
|
||||
- "\n"
|
||||
- "\t-p P\tspecify port P (service name or port number)\n"
|
||||
- "\t-N\thostname is numeric, skip DNS query\n"
|
||||
- "\t-n\tservice/port is numeric (sets AI_NUMERICSERV)\n"
|
||||
- "\t-P\tset AI_PASSIVE\n"
|
||||
- "\n"
|
||||
- "default: protocol 0, socket type 0, address family 0, null port\n"
|
||||
- ,
|
||||
- whoami);
|
||||
- /* [ -t | -u | -R | -I ] [ -d | -s | -r ] [ -p port ] */
|
||||
- exit (1);
|
||||
-}
|
||||
-
|
||||
-static const char *familyname (int f) {
|
||||
- static char buf[30];
|
||||
- switch (f) {
|
||||
- default:
|
||||
- snprintf(buf, sizeof(buf), "AF %d", f);
|
||||
- return buf;
|
||||
- case AF_INET: return "AF_INET";
|
||||
-#ifdef AF_INET6
|
||||
- case AF_INET6: return "AF_INET6";
|
||||
-#endif
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-#define eaistr(X) (X == EAI_SYSTEM ? strerror(errno) : gai_strerror(X))
|
||||
-
|
||||
-int main (int argc, char *argv[])
|
||||
-{
|
||||
- struct addrinfo *ap, *ap2;
|
||||
- int err, numerichost = 0, numericserv = 0;
|
||||
- char *hname, *port = 0, *sep;
|
||||
- struct addrinfo hints;
|
||||
-
|
||||
- whoami = strrchr(argv[0], '/');
|
||||
- if (whoami == 0)
|
||||
- whoami = argv[0];
|
||||
- else
|
||||
- whoami = whoami+1;
|
||||
-
|
||||
- memset(&hints, 0, sizeof(hints));
|
||||
- hints.ai_flags = 0;
|
||||
- hints.ai_socktype = 0;
|
||||
-
|
||||
- hname = 0;
|
||||
- hints.ai_family = 0;
|
||||
-
|
||||
- if (argc == 1)
|
||||
- usage ();
|
||||
-
|
||||
- while (++argv, --argc > 0) {
|
||||
- char *arg;
|
||||
- arg = *argv;
|
||||
-
|
||||
- if (*arg != '-')
|
||||
- hname = arg;
|
||||
- else if (arg[1] == 0 || arg[2] != 0)
|
||||
- usage ();
|
||||
- else
|
||||
- switch (arg[1]) {
|
||||
- case 'u':
|
||||
- hints.ai_protocol = IPPROTO_UDP;
|
||||
- break;
|
||||
- case 't':
|
||||
- hints.ai_protocol = IPPROTO_TCP;
|
||||
- break;
|
||||
- case 'R':
|
||||
- hints.ai_protocol = IPPROTO_RAW;
|
||||
- break;
|
||||
- case 'I':
|
||||
- hints.ai_protocol = IPPROTO_ICMP;
|
||||
- break;
|
||||
- case 'd':
|
||||
- hints.ai_socktype = SOCK_DGRAM;
|
||||
- break;
|
||||
- case 's':
|
||||
- hints.ai_socktype = SOCK_STREAM;
|
||||
- break;
|
||||
- case 'r':
|
||||
- hints.ai_socktype = SOCK_RAW;
|
||||
- break;
|
||||
- case 'p':
|
||||
- if (argv[1] == 0 || argv[1][0] == 0 || argv[1][0] == '-')
|
||||
- usage ();
|
||||
- port = argv[1];
|
||||
- argc--, argv++;
|
||||
- break;
|
||||
- case '4':
|
||||
- hints.ai_family = AF_INET;
|
||||
- break;
|
||||
-#ifdef AF_INET6
|
||||
- case '6':
|
||||
- hints.ai_family = AF_INET6;
|
||||
- break;
|
||||
-#endif
|
||||
- case 'N':
|
||||
- numerichost = 1;
|
||||
- break;
|
||||
- case 'n':
|
||||
- numericserv = 1;
|
||||
- break;
|
||||
- case 'P':
|
||||
- hints.ai_flags |= AI_PASSIVE;
|
||||
- break;
|
||||
- default:
|
||||
- usage ();
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (hname && !numerichost)
|
||||
- hints.ai_flags |= AI_CANONNAME;
|
||||
- if (numerichost) {
|
||||
-#ifdef AI_NUMERICHOST
|
||||
- hints.ai_flags |= AI_NUMERICHOST;
|
||||
-#else
|
||||
- fprintf(stderr, "AI_NUMERICHOST not defined on this platform\n");
|
||||
- exit(1);
|
||||
-#endif
|
||||
- }
|
||||
- if (numericserv) {
|
||||
-#ifdef AI_NUMERICSERV
|
||||
- hints.ai_flags |= AI_NUMERICSERV;
|
||||
-#else
|
||||
- fprintf(stderr, "AI_NUMERICSERV not defined on this platform\n");
|
||||
- exit(1);
|
||||
-#endif
|
||||
- }
|
||||
-
|
||||
- printf("getaddrinfo(hostname %s, service %s,\n"
|
||||
- " hints { ",
|
||||
- hname ? hname : "(null)", port ? port : "(null)");
|
||||
- sep = "";
|
||||
-#define Z(FLAG) if (hints.ai_flags & AI_##FLAG) printf("%s%s", sep, #FLAG), sep = "|"
|
||||
- Z(CANONNAME);
|
||||
- Z(PASSIVE);
|
||||
-#ifdef AI_NUMERICHOST
|
||||
- Z(NUMERICHOST);
|
||||
-#endif
|
||||
-#ifdef AI_NUMERICSERV
|
||||
- Z(NUMERICSERV);
|
||||
-#endif
|
||||
- if (sep[0] == 0)
|
||||
- printf ("no-flags");
|
||||
- if (hints.ai_family)
|
||||
- printf(" %s", familyname(hints.ai_family));
|
||||
- if (hints.ai_socktype)
|
||||
- printf(" SOCK_%s", socktypename(hints.ai_socktype));
|
||||
- if (hints.ai_protocol)
|
||||
- printf(" IPPROTO_%s", protoname(hints.ai_protocol));
|
||||
- printf(" }):\n");
|
||||
-
|
||||
- err = getaddrinfo(hname, port, &hints, &ap);
|
||||
- if (err) {
|
||||
- printf("\terror => %s\n", eaistr(err));
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- for (ap2 = ap; ap2; ap2 = ap2->ai_next) {
|
||||
- char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
|
||||
- /* If we don't do this, even AIX's own getnameinfo will reject
|
||||
- the sockaddr structures. The sa_len field doesn't get set
|
||||
- either, on AIX, but getnameinfo won't complain. */
|
||||
- if (ap2->ai_addr->sa_family == 0) {
|
||||
- printf("BAD: sa_family zero! fixing...\n");
|
||||
- ap2->ai_addr->sa_family = ap2->ai_family;
|
||||
- } else if (ap2->ai_addr->sa_family != ap2->ai_family) {
|
||||
- printf("BAD: sa_family != ai_family! fixing...\n");
|
||||
- ap2->ai_addr->sa_family = ap2->ai_family;
|
||||
- }
|
||||
- if (getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof(hbuf),
|
||||
- pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
|
||||
- strlcpy(hbuf, "...", sizeof(hbuf));
|
||||
- strlcpy(pbuf, "...", sizeof(pbuf));
|
||||
- }
|
||||
- printf("%p:\n"
|
||||
- "\tfamily = %s\tproto = %-4s\tsocktype = %s\n",
|
||||
- (void *) ap2, familyname(ap2->ai_family),
|
||||
- protoname (ap2->ai_protocol),
|
||||
- socktypename (ap2->ai_socktype));
|
||||
- if (ap2->ai_canonname) {
|
||||
- if (ap2->ai_canonname[0])
|
||||
- printf("\tcanonname = %s\n", ap2->ai_canonname);
|
||||
- else
|
||||
- printf("BAD: ai_canonname is set but empty!\n");
|
||||
- } else if (ap2 == ap && (hints.ai_flags & AI_CANONNAME)) {
|
||||
- printf("BAD: first ai_canonname is null!\n");
|
||||
- }
|
||||
- printf("\taddr = %-28s\tport = %s\n", hbuf, pbuf);
|
||||
-
|
||||
- err = getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof (hbuf),
|
||||
- pbuf, sizeof(pbuf), NI_NAMEREQD);
|
||||
- if (err)
|
||||
- printf("\tgetnameinfo(NI_NAMEREQD): %s\n", eaistr(err));
|
||||
- else
|
||||
- printf("\tgetnameinfo => %s, %s\n", hbuf, pbuf);
|
||||
- }
|
||||
- freeaddrinfo(ap);
|
||||
- return 0;
|
||||
-}
|
||||
diff --git a/src/tests/resolve/deps b/src/tests/resolve/deps
|
||||
deleted file mode 100644
|
||||
index 762d9adab..000000000
|
||||
--- a/src/tests/resolve/deps
|
||||
+++ /dev/null
|
||||
@@ -1,14 +0,0 @@
|
||||
-#
|
||||
-# Generated makefile dependencies follow.
|
||||
-#
|
||||
-$(OUTPRE)resolve.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
|
||||
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
|
||||
- resolve.c
|
||||
-$(OUTPRE)addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
|
||||
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
|
||||
- addrinfo-test.c
|
||||
-$(OUTPRE)fake-addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
|
||||
- $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-platform.h \
|
||||
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \
|
||||
- $(top_srcdir)/include/socket-utils.h addrinfo-test.c \
|
||||
- fake-addrinfo-test.c
|
||||
diff --git a/src/tests/resolve/fake-addrinfo-test.c b/src/tests/resolve/fake-addrinfo-test.c
|
||||
deleted file mode 100644
|
||||
index 86365a5ba..000000000
|
||||
--- a/src/tests/resolve/fake-addrinfo-test.c
|
||||
+++ /dev/null
|
||||
@@ -1,3 +0,0 @@
|
||||
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
-#define USE_FAKE_ADDRINFO
|
||||
-#include "addrinfo-test.c"
|
||||
diff --git a/src/tests/resolve/resolve.c b/src/tests/resolve/resolve.c
|
||||
deleted file mode 100644
|
||||
index ea0239113..000000000
|
||||
--- a/src/tests/resolve/resolve.c
|
||||
+++ /dev/null
|
||||
@@ -1,115 +0,0 @@
|
||||
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
-/* tests/resolve/resolve.c */
|
||||
-/*
|
||||
- * Copyright 1995 by the Massachusetts Institute of Technology.
|
||||
- * All Rights Reserved.
|
||||
- *
|
||||
- * Export of this software from the United States of America may
|
||||
- * require a specific license from the United States Government.
|
||||
- * It is the responsibility of any person or organization contemplating
|
||||
- * export to obtain such a license before exporting.
|
||||
- *
|
||||
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
- * distribute this software and its documentation for any purpose and
|
||||
- * without fee is hereby granted, provided that the above copyright
|
||||
- * notice appear in all copies and that both that copyright notice and
|
||||
- * this permission notice appear in supporting documentation, and that
|
||||
- * the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
- * to distribution of the software without specific, written prior
|
||||
- * permission. Furthermore if you modify this software you must label
|
||||
- * your software as modified software and not distribute it in such a
|
||||
- * fashion that it might be confused with the original M.I.T. software.
|
||||
- * M.I.T. makes no representations about the suitability of
|
||||
- * this software for any purpose. It is provided "as is" without express
|
||||
- * or implied warranty.
|
||||
- */
|
||||
-
|
||||
-/*
|
||||
- * A simple program to test the functionality of the resolver library.
|
||||
- * It simply will try to get the IP address of the host, and then look
|
||||
- * up the name from the address. If the resulting name does not contain the
|
||||
- * domain name, then the resolve library is broken.
|
||||
- *
|
||||
- * Warning: It is possible to fool this program into thinking everything is
|
||||
- * alright by a clever use of /etc/hosts - but this is better than nothing.
|
||||
- *
|
||||
- * Usage:
|
||||
- * resolve [hostname]
|
||||
- *
|
||||
- * When invoked with no arguments, gethostname is used for the local host.
|
||||
- *
|
||||
- */
|
||||
-
|
||||
-/* This program tests the resolve library and sees if it is broken... */
|
||||
-
|
||||
-#include "k5-platform.h"
|
||||
-#include <sys/types.h>
|
||||
-#include <sys/socket.h>
|
||||
-#include <arpa/inet.h>
|
||||
-#include <netdb.h>
|
||||
-#ifdef HAVE_SYS_PARAM_H
|
||||
-#include <sys/param.h>
|
||||
-#endif
|
||||
-
|
||||
-int
|
||||
-main(int argc, char **argv)
|
||||
-{
|
||||
- struct addrinfo *ai = NULL, hint;
|
||||
- char myname[MAXHOSTNAMELEN + 1], namebuf[NI_MAXHOST], abuf[256];
|
||||
- const char *addrstr;
|
||||
- int err, quiet = 0;
|
||||
-
|
||||
- argc--; argv++;
|
||||
- while (argc) {
|
||||
- if ((strcmp(*argv, "--quiet") == 0) ||
|
||||
- (strcmp(*argv, "-q") == 0)) {
|
||||
- quiet++;
|
||||
- } else
|
||||
- break;
|
||||
- argc--; argv++;
|
||||
- }
|
||||
-
|
||||
- if (argc >= 1) {
|
||||
- strlcpy(myname, *argv, sizeof(myname));
|
||||
- } else {
|
||||
- if(gethostname(myname, MAXHOSTNAMELEN)) {
|
||||
- perror("gethostname failure");
|
||||
- exit(1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- myname[MAXHOSTNAMELEN] = '\0'; /* for safety */
|
||||
-
|
||||
- /* Look up the address... */
|
||||
- if (!quiet)
|
||||
- printf("Hostname: %s\n", myname);
|
||||
-
|
||||
- memset(&hint, 0, sizeof(hint));
|
||||
- hint.ai_flags = AI_CANONNAME;
|
||||
- err = getaddrinfo(myname, 0, &hint, &ai);
|
||||
- if (err) {
|
||||
- fprintf(stderr,
|
||||
- "Could not look up address for hostname '%s' - fatal\n",
|
||||
- myname);
|
||||
- exit(2);
|
||||
- }
|
||||
-
|
||||
- if (!quiet) {
|
||||
- addrstr = inet_ntop(ai->ai_family, ai->ai_addr, abuf, sizeof(abuf));
|
||||
- if (addrstr != NULL)
|
||||
- printf("Host address: %s\n", addrstr);
|
||||
- }
|
||||
-
|
||||
- err = getnameinfo(ai->ai_addr, ai->ai_addrlen, namebuf, sizeof(namebuf),
|
||||
- NULL, 0, NI_NAMEREQD);
|
||||
- if (err && !quiet)
|
||||
- fprintf(stderr, "Error looking up IP address\n");
|
||||
-
|
||||
- printf("%s%s\n", quiet ? "" : "FQDN: ", err ? ai->ai_canonname : namebuf);
|
||||
-
|
||||
- if (!quiet)
|
||||
- printf("Resolve library appears to have passed the test\n");
|
||||
-
|
||||
- freeaddrinfo(ai);
|
||||
- return 0;
|
||||
-}
|
||||
|
|
@ -1,861 +0,0 @@
|
|||
From 404cc1152880a567fc27bb7c691a1a732692bbf9 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Sat, 15 Feb 2020 20:34:23 -0500
|
||||
Subject: [PATCH] Replace gssrpc tests with a Python script
|
||||
|
||||
Replace the dejagnu RPC test framework with a short Python script to
|
||||
do the same tests as fullrun.exp and gsserr.exp. Modify the server
|
||||
test program to facilitate use by k5test.py.
|
||||
|
||||
expire.exp, together with a comment in the client test program, was
|
||||
designed to test a libdb2 btree bug via the gssrpc server-side
|
||||
authentication code. That code was subsequently changed not to use
|
||||
libdb2, before it was merged into the main krb5 tree (in revision 1.23
|
||||
of svc_auth_gssapi.c, according to the changelog removed in commit
|
||||
2a43d772be1e45faa8e488d436b6e867371563fb). Remove the comment and do
|
||||
not replace that test sequence.
|
||||
|
||||
[rharwood@redhat.com: .gitignore]
|
||||
---
|
||||
src/configure.ac | 2 -
|
||||
src/lib/rpc/unit-test/Makefile.in | 36 +--
|
||||
src/lib/rpc/unit-test/client.c | 26 ---
|
||||
src/lib/rpc/unit-test/config/unix.exp | 176 --------------
|
||||
src/lib/rpc/unit-test/lib/helpers.exp | 234 -------------------
|
||||
src/lib/rpc/unit-test/rpc_test.0/expire.exp | 49 ----
|
||||
src/lib/rpc/unit-test/rpc_test.0/fullrun.exp | 91 --------
|
||||
src/lib/rpc/unit-test/rpc_test.0/gsserr.exp | 30 ---
|
||||
src/lib/rpc/unit-test/server.c | 13 +-
|
||||
src/lib/rpc/unit-test/t_rpc.py | 29 +++
|
||||
10 files changed, 41 insertions(+), 645 deletions(-)
|
||||
delete mode 100644 src/lib/rpc/unit-test/config/unix.exp
|
||||
delete mode 100644 src/lib/rpc/unit-test/lib/helpers.exp
|
||||
delete mode 100644 src/lib/rpc/unit-test/rpc_test.0/expire.exp
|
||||
delete mode 100644 src/lib/rpc/unit-test/rpc_test.0/fullrun.exp
|
||||
delete mode 100644 src/lib/rpc/unit-test/rpc_test.0/gsserr.exp
|
||||
create mode 100644 src/lib/rpc/unit-test/t_rpc.py
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 29be532cb..aafc462f9 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1102,8 +1102,6 @@ extern void endrpcent();],
|
||||
AC_MSG_RESULT($k5_cv_type_endrpcent)
|
||||
AC_DEFINE_UNQUOTED(ENDRPCENT_TYPE, $k5_cv_type_endrpcent, [Define as return type of endrpcent])
|
||||
K5_GEN_FILE(include/gssrpc/types.h:include/gssrpc/types.hin)
|
||||
-PASS=tcp
|
||||
-AC_SUBST(PASS)
|
||||
|
||||
# for pkinit
|
||||
AC_ARG_ENABLE([pkinit],
|
||||
diff --git a/src/lib/rpc/unit-test/Makefile.in b/src/lib/rpc/unit-test/Makefile.in
|
||||
index 0b6e5203d..309ae2b21 100644
|
||||
--- a/src/lib/rpc/unit-test/Makefile.in
|
||||
+++ b/src/lib/rpc/unit-test/Makefile.in
|
||||
@@ -16,10 +16,6 @@ server: server.o rpc_test_svc.o $(GSSRPC_DEPLIBS) $(KRB5_BASE_DEPLIBS)
|
||||
|
||||
client.o server.o: rpc_test.h
|
||||
|
||||
-runenv.exp: Makefile
|
||||
- $(RUN_SETUP); for i in $(RUN_VARS); do \
|
||||
- eval echo "set env\($$i\) \$$$$i"; done > runenv.exp
|
||||
-
|
||||
# If rpc_test.h and rpc_test_*.c do not work on your system, you can
|
||||
# try using rpcgen by uncommenting these lines (be sure to uncomment
|
||||
# then in the generated not Makefile.in).
|
||||
@@ -34,37 +30,9 @@ runenv.exp: Makefile
|
||||
# rm -f rpc_test.h rpc_test_clnt.c rpc_test_svc.c
|
||||
#
|
||||
|
||||
-check unit-test: unit-test-@DO_TEST@
|
||||
-
|
||||
-unit-test-:
|
||||
- @echo "+++"
|
||||
- @echo "+++ WARNING: lib/rpc unit tests not run."
|
||||
- @echo "+++ Either tcl, runtest, or Perl is unavailable."
|
||||
- @echo "+++"
|
||||
- @echo 'Skipped rpc tests: runtest or Perl not found' >> $(SKIPTESTS)
|
||||
-
|
||||
-unit-test-ok: unit-test-body
|
||||
-
|
||||
-PASS=@PASS@
|
||||
-unit-test-body: runenv.sh runenv.exp
|
||||
- $(RM) krb5cc_rpc_test_*
|
||||
- $(ENV_SETUP) $(VALGRIND) $(START_SERVERS)
|
||||
- RPC_TEST_KEYTAB=/tmp/rpc_test_keytab.$$$$ ; export RPC_TEST_KEYTAB ; \
|
||||
- trap "echo Failed, cleaning up... ; rm -f $$RPC_TEST_KEYTAB ; $(ENV_SETUP) $(STOP_SERVERS) ; trap '' 0 ; exit 1" 0 1 2 3 14 15 ; \
|
||||
- if $(ENV_SETUP) \
|
||||
- $(RUNTEST) SERVER=./server CLIENT=./client \
|
||||
- KINIT=$(BUILDTOP)/clients/kinit/kinit \
|
||||
- KDESTROY=$(BUILDTOP)/clients/kdestroy/kdestroy \
|
||||
- PRIOCNTL_HACK=@PRIOCNTL_HACK@ VALGRIND="$(VALGRIND)" \
|
||||
- PASS="$(PASS)" --tool rpc_test $(RUNTESTFLAGS) ; \
|
||||
- then \
|
||||
- echo Cleaning up... ; \
|
||||
- rm -f $$RPC_TEST_KEYTAB krb5cc_rpc_test_* ; \
|
||||
- $(ENV_SETUP) $(STOP_SERVERS) ; \
|
||||
- trap 0 ; exit 0 ; \
|
||||
- else exit 1 ; fi
|
||||
+check-pytests:
|
||||
+ $(RUNPYTEST) $(srcdir)/t_rpc.py $(PYTESTFLAGS)
|
||||
|
||||
clean:
|
||||
$(RM) server client
|
||||
- $(RM) dbg.log rpc_test.log rpc_test.sum runenv.exp
|
||||
|
||||
diff --git a/src/lib/rpc/unit-test/client.c b/src/lib/rpc/unit-test/client.c
|
||||
index 5edde49df..c9a812bc5 100644
|
||||
--- a/src/lib/rpc/unit-test/client.c
|
||||
+++ b/src/lib/rpc/unit-test/client.c
|
||||
@@ -231,32 +231,6 @@ main(argc, argv)
|
||||
else
|
||||
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
||||
|
||||
- /*
|
||||
- * Test fix for secure-rpc/586, part 1: btree keys must be
|
||||
- * unique. Create another context from the same credentials; it
|
||||
- * should have the same expiration time and will cause the server
|
||||
- * to abort if the clients are not differentiated.
|
||||
- *
|
||||
- * Test fix for secure-rpc/586, part 2: btree keys cannot be
|
||||
- * mutated in place. To test this: a second client, *with a
|
||||
- * later expiration time*, must be run. The second client should
|
||||
- * destroy itself *after* the first one; if the key-mutating bug
|
||||
- * is not fixed, the second client_data will be in the btree
|
||||
- * before the first, but its key will be larger; thus, when the
|
||||
- * first client calls AUTH_DESTROY, the server won't find it in
|
||||
- * the btree and call abort.
|
||||
- *
|
||||
- * For unknown reasons, running just a second client didn't
|
||||
- * tickle the bug; the btree code seemed to guess which node to
|
||||
- * look at first. Running a total of three clients does ticket
|
||||
- * the bug. Thus, the full test sequence looks like this:
|
||||
- *
|
||||
- * kinit -l 20m user && client server test@ddn 200
|
||||
- * sleep 1
|
||||
- * kini -l 30m user && client server test@ddn 300
|
||||
- * sleep 1
|
||||
- * kinit -l 40m user && client server test@ddn 400
|
||||
- */
|
||||
if (! auth_once) {
|
||||
tmp_auth = clnt->cl_auth;
|
||||
clnt->cl_auth = auth_gssapi_create_default(clnt, target);
|
||||
diff --git a/src/lib/rpc/unit-test/config/unix.exp b/src/lib/rpc/unit-test/config/unix.exp
|
||||
deleted file mode 100644
|
||||
index 18da62be4..000000000
|
||||
--- a/src/lib/rpc/unit-test/config/unix.exp
|
||||
+++ /dev/null
|
||||
@@ -1,176 +0,0 @@
|
||||
-#
|
||||
-# $Id$
|
||||
-#
|
||||
-
|
||||
-source runenv.exp
|
||||
-
|
||||
-set kill /bin/kill
|
||||
-set sleep /bin/sleep
|
||||
-set kinit $KINIT
|
||||
-set kdestroy $KDESTROY
|
||||
-
|
||||
-set hostname [exec hostname]
|
||||
-
|
||||
-# Hack around Solaris 9 kernel race condition that causes last output
|
||||
-# from a pty to get dropped.
|
||||
-if { $PRIOCNTL_HACK } {
|
||||
- catch {exec priocntl -s -c FX -m 30 -p 30 -i pid [getpid]}
|
||||
- rename spawn oldspawn
|
||||
- proc spawn { args } {
|
||||
- upvar 1 spawn_id spawn_id
|
||||
- set newargs {}
|
||||
- set inflags 1
|
||||
- set eatnext 0
|
||||
- foreach arg $args {
|
||||
- if { $arg == "-ignore" \
|
||||
- || $arg == "-open" \
|
||||
- || $arg == "-leaveopen" } {
|
||||
- lappend newargs $arg
|
||||
- set eatnext 1
|
||||
- continue
|
||||
- }
|
||||
- if [string match "-*" $arg] {
|
||||
- lappend newargs $arg
|
||||
- continue
|
||||
- }
|
||||
- if { $eatnext } {
|
||||
- set eatnext 0
|
||||
- lappend newargs $arg
|
||||
- continue
|
||||
- }
|
||||
- if { $inflags } {
|
||||
- set inflags 0
|
||||
- set newargs [concat $newargs {priocntl -e -c FX -p 0}]
|
||||
- }
|
||||
- lappend newargs $arg
|
||||
- }
|
||||
- set pid [eval oldspawn $newargs]
|
||||
- return $pid
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-if { [string length $VALGRIND] } {
|
||||
- rename spawn valgrind_aux_spawn
|
||||
- proc spawn { args } {
|
||||
- global VALGRIND
|
||||
- upvar 1 spawn_id spawn_id
|
||||
- set newargs {}
|
||||
- set inflags 1
|
||||
- set eatnext 0
|
||||
- foreach arg $args {
|
||||
- if { $arg == "-ignore" \
|
||||
- || $arg == "-open" \
|
||||
- || $arg == "-leaveopen" } {
|
||||
- lappend newargs $arg
|
||||
- set eatnext 1
|
||||
- continue
|
||||
- }
|
||||
- if [string match "-*" $arg] {
|
||||
- lappend newargs $arg
|
||||
- continue
|
||||
- }
|
||||
- if { $eatnext } {
|
||||
- set eatnext 0
|
||||
- lappend newargs $arg
|
||||
- continue
|
||||
- }
|
||||
- if { $inflags } {
|
||||
- set inflags 0
|
||||
- # Only run valgrind for local programs, not
|
||||
- # system ones.
|
||||
-#&&![string match "/bin/sh" $arg] sh is used to start kadmind!
|
||||
- if [string match "/" [string index $arg 0]]&&![string match "/bin/ls" $arg]&&![regexp {/kshd$} $arg] {
|
||||
- set newargs [concat $newargs $VALGRIND]
|
||||
- } elseif [string match "." [string index $arg 0]] {
|
||||
- set newargs [concat $newargs $VALGRIND]
|
||||
- }
|
||||
- }
|
||||
- lappend newargs $arg
|
||||
- }
|
||||
- set pid [eval valgrind_aux_spawn $newargs]
|
||||
- return $pid
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-# this will initialize the database and keytab
|
||||
-load_lib "helpers.exp"
|
||||
-
|
||||
-proc rpc_test_version {} {
|
||||
- global CLIENT
|
||||
- global SERVER
|
||||
-
|
||||
- clone_output "$CLIENT version <unknown>"
|
||||
- clone_output "$SERVER version <unknown>"
|
||||
-}
|
||||
-
|
||||
-proc rpc_test_load {} {
|
||||
- #
|
||||
-}
|
||||
-
|
||||
-# rpc_test_exit -- clean up and exit
|
||||
-proc rpc_test_exit {} {
|
||||
- global server_id
|
||||
- global server_pid
|
||||
- global server_started
|
||||
- global kill
|
||||
-
|
||||
- if {[catch {
|
||||
- expect {
|
||||
- -i $server_id
|
||||
- eof {
|
||||
- fail "server exited!"
|
||||
- verbose $expect_out(buffer) 1
|
||||
- }
|
||||
- timeout { pass "server survived" }
|
||||
- }
|
||||
- } tmp]} {
|
||||
- fail "server exited! (expect failed)"
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-#
|
||||
-# rpc_test_start -- start the rpc_test server running
|
||||
-#
|
||||
-proc rpc_test_start { } {
|
||||
- global SERVER PROT
|
||||
- global server_id
|
||||
- global server_pid
|
||||
- global server_started
|
||||
- global server_port
|
||||
- global env
|
||||
-
|
||||
- if [info exists server_pid] { rpc_test_exit }
|
||||
-
|
||||
- set env(KRB5_KTNAME) FILE:$env(RPC_TEST_KEYTAB)
|
||||
-
|
||||
- verbose "% $SERVER" 1
|
||||
- set server_pid [spawn $SERVER $PROT]
|
||||
- set server_id $spawn_id
|
||||
- set server_started 1
|
||||
- set server_port -1
|
||||
-
|
||||
- unset env(KRB5_KTNAME)
|
||||
-
|
||||
- set timeout 30
|
||||
-
|
||||
- expect {
|
||||
- -re "port: (\[0-9\]*)\r\n" {
|
||||
- set server_port $expect_out(1,string)
|
||||
- }
|
||||
- "running" { }
|
||||
- eof {
|
||||
- send_error "server exited!"
|
||||
- verbose $expect_out(buffer) 1
|
||||
- }
|
||||
- timeout {
|
||||
- send_error "server didn't start in $timeout seconds"
|
||||
- verbose $expect_out(buffer) 1
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-}
|
||||
-
|
||||
-set MULTIPASS {
|
||||
- {tcp PROT=-t dummy=[rpc_test_start]}
|
||||
- {udp PROT=-u dummy=[rpc_test_start]}
|
||||
-}
|
||||
diff --git a/src/lib/rpc/unit-test/lib/helpers.exp b/src/lib/rpc/unit-test/lib/helpers.exp
|
||||
deleted file mode 100644
|
||||
index eb2797c53..000000000
|
||||
--- a/src/lib/rpc/unit-test/lib/helpers.exp
|
||||
+++ /dev/null
|
||||
@@ -1,234 +0,0 @@
|
||||
-if {[info commands exp_version] != {}} {
|
||||
- set exp_version_4 [regexp {^4} [exp_version]]
|
||||
-} else {
|
||||
- set exp_version_4 [regexp {^4} [expect_version]]
|
||||
-}
|
||||
-
|
||||
-# Backward compatibility until we're using expect 5 everywhere
|
||||
-if {$exp_version_4} {
|
||||
- global wait_error_index wait_errno_index wait_status_index
|
||||
- set wait_error_index 0
|
||||
- set wait_errno_index 1
|
||||
- set wait_status_index 1
|
||||
-} else {
|
||||
- set wait_error_index 2
|
||||
- set wait_errno_index 3
|
||||
- set wait_status_index 3
|
||||
-}
|
||||
-
|
||||
-proc set_from_env {varname default_value} {
|
||||
- global env
|
||||
- upvar $varname v
|
||||
-
|
||||
- if [info exists env($varname)] {
|
||||
- set v $env($varname)
|
||||
- } else {
|
||||
- set v $default_value
|
||||
- }
|
||||
-}
|
||||
-proc expect_tcl_prompt {} {
|
||||
- global kadmin_tcl_spawn_id
|
||||
- expect {
|
||||
- -i $kadmin_tcl_spawn_id
|
||||
- -re "^% $" { }
|
||||
- -re . { perror "unexpected output {$expect_out(buffer)} from subprocess, expecting tcl prompt" }
|
||||
- timeout { perror "timeout waiting for tcl prompt" }
|
||||
- eof { perror "eof from subprocess when expecting tcl prompt" }
|
||||
- }
|
||||
-}
|
||||
-proc send_tcl_cmd_await_echo {cmd} {
|
||||
- global kadmin_tcl_spawn_id
|
||||
- send -i $kadmin_tcl_spawn_id "$cmd\n"
|
||||
- expect {
|
||||
- -i $kadmin_tcl_spawn_id
|
||||
- -ex "$cmd\r\n" { }
|
||||
- timeout { perror "timeout waiting for tcl subprocess to echo input" }
|
||||
- eof { perror "eof waiting for tcl subprocess to echo input" }
|
||||
- }
|
||||
-}
|
||||
-proc expect_kadm_ok {} {
|
||||
- global kadmin_tcl_spawn_id
|
||||
- expect {
|
||||
- -i $kadmin_tcl_spawn_id
|
||||
- -re "^OK KADM5_OK \[^\n\]*\n" {}
|
||||
- -re "^ERROR \[^\n\]*\n" { perror "kadmin tcl subprocess reported unexpected error" }
|
||||
- -re "^marshall_new_creds: \[^\n\]*\n" { exp_continue }
|
||||
- -re "^gssapi_\[^\n\]*\n" { exp_continue }
|
||||
- -re "^\r?\n" { exp_continue }
|
||||
- eof { perror "kadmin tcl subprocess died" }
|
||||
- default { perror "didn't get ok back" }
|
||||
- }
|
||||
-}
|
||||
-proc setup_database {} {
|
||||
- global env spawn_id kadmin_tcl_spawn_id TESTDIR CANON_HOST
|
||||
-
|
||||
- # XXXXX
|
||||
- set_from_env TOP {/x/x/x/x/x}
|
||||
- send_user "TOP=$TOP\n"
|
||||
-
|
||||
- set_from_env TESTDIR $env(TOP)/testing
|
||||
- set_from_env CLNTTCL $TESTDIR/util/kadm5_clnt_tcl
|
||||
- set_from_env TCLUTIL $TESTDIR/tcl/util.t
|
||||
- set env(TCLUTIL) $TCLUTIL
|
||||
- set env(PATH) "$TOP/install/admin:$env(PATH)"
|
||||
-
|
||||
- # $VERBOSE ?
|
||||
-
|
||||
- if [info exists spawn_id] { set x $spawn_id }
|
||||
- spawn $CLNTTCL
|
||||
- set kadmin_tcl_spawn_id $spawn_id
|
||||
- if [info exists x] { set spawn_id $x }
|
||||
-
|
||||
- expect_tcl_prompt
|
||||
- # tcl 8.4 for some reason screws up autodetection of output EOL
|
||||
- # translation. Work around it for now.
|
||||
- send_tcl_cmd_await_echo "if { \[info commands fconfigure\] != \"\" } { fconfigure stdout -translation lf }"
|
||||
- expect_tcl_prompt
|
||||
- send_tcl_cmd_await_echo "source {$TCLUTIL}"
|
||||
- expect_tcl_prompt
|
||||
- send_tcl_cmd_await_echo "set h {$CANON_HOST}"
|
||||
- expect {
|
||||
- -ex "$CANON_HOST\r\n" { }
|
||||
- timeout { perror "timeout waiting for subprocess" }
|
||||
- eof { perror "eof from subprocess" }
|
||||
- }
|
||||
- expect_tcl_prompt
|
||||
-
|
||||
- send_tcl_cmd_await_echo {kadm5_init admin admin $KADM5_ADMIN_SERVICE null $KADM5_STRUCT_VERSION $KADM5_API_VERSION_2 server_handle}
|
||||
- expect_kadm_ok
|
||||
- expect "^% "
|
||||
- send_tcl_cmd_await_echo {kadm5_create_principal $server_handle [simple_principal server/$h] {KADM5_PRINCIPAL} admin}
|
||||
- expect_kadm_ok
|
||||
- expect "^% "
|
||||
- send_tcl_cmd_await_echo {kadm5_randkey_principal $server_handle server/$h key null}
|
||||
- expect_kadm_ok
|
||||
- expect "^% "
|
||||
- send_tcl_cmd_await_echo {kadm5_create_principal $server_handle [simple_principal notserver/$h] {KADM5_PRINCIPAL} admin}
|
||||
- expect_kadm_ok
|
||||
- expect "^% "
|
||||
- send_tcl_cmd_await_echo {kadm5_randkey_principal $server_handle notserver/$h key null}
|
||||
- expect_kadm_ok
|
||||
- expect "^% "
|
||||
- send_tcl_cmd_await_echo {kadm5_destroy $server_handle}
|
||||
- expect_kadm_ok
|
||||
- expect "^% "
|
||||
- wait -nowait -i $spawn_id
|
||||
- close -i $spawn_id
|
||||
-}
|
||||
-
|
||||
-if ![info exists CANON_HOST] {
|
||||
- set CANON_HOST $env(QUALNAME)
|
||||
- setup_database
|
||||
- file delete $env(RPC_TEST_KEYTAB)
|
||||
- exec $env(TOP)/cli/kadmin -p admin -w admin ktadd -k $env(RPC_TEST_KEYTAB) server/$CANON_HOST
|
||||
-}
|
||||
-
|
||||
-
|
||||
-proc kinit {princ pass lifetime} {
|
||||
- global kinit
|
||||
- global wait_error_index wait_errno_index wait_status_index
|
||||
-
|
||||
- spawn -noecho $kinit -5 -l $lifetime $princ
|
||||
- expect {
|
||||
- -re "Password for $princ.*: " { send "$pass\n"; expect eof }
|
||||
- timeout { perror "Timeout waiting for kinit"; close }
|
||||
- eof
|
||||
- }
|
||||
-
|
||||
- set ret [wait]
|
||||
- if {[lindex $ret $wait_error_index] == -1} {
|
||||
- perror \
|
||||
- "wait(kinit $princ) returned error [lindex $ret $wait_errno_index]"
|
||||
- } else {
|
||||
- if {[lindex $ret $wait_status_index] != 0} {
|
||||
- perror \
|
||||
- "kinit $princ failed with [lindex $ret $wait_status_index]"
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-proc flush_server {} {
|
||||
- global server_id
|
||||
- global expect_out
|
||||
-
|
||||
- verbose "flushing server output" 1
|
||||
-
|
||||
- while {1} {
|
||||
- set timeout 5
|
||||
-
|
||||
- expect {
|
||||
- -i $server_id
|
||||
- -re "^.+$" {
|
||||
- verbose "server output: $expect_out(buffer)"
|
||||
- }
|
||||
- timeout { break }
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-proc start_client {testname ccname user password lifetime count
|
||||
- {target ""}} {
|
||||
- global env CLIENT PROT hostname server_port spawn_id verbose
|
||||
-
|
||||
- if {$target == ""} {
|
||||
- set target "server@$hostname"
|
||||
- }
|
||||
-
|
||||
- set env(KRB5CCNAME) FILE:[pwd]/krb5cc_rpc_test_$ccname
|
||||
- kinit $user $password $lifetime
|
||||
-
|
||||
- if {$verbose > 0} {
|
||||
- spawn $CLIENT -a 1 -s 1 -m 1 $PROT $hostname $server_port $target $count
|
||||
- } else {
|
||||
- spawn $CLIENT $PROT $hostname $server_port $target $count
|
||||
- }
|
||||
-
|
||||
- verbose "$testname: client $ccname started"
|
||||
-
|
||||
- unset env(KRB5CCNAME)
|
||||
-}
|
||||
-
|
||||
-proc eof_client {testname ccname id status} {
|
||||
- verbose "$testname: eof'ing for client $ccname" 1
|
||||
-
|
||||
- expect {
|
||||
- -i $id
|
||||
- -re "^marshall_new_creds\[^\n\]*\n" { exp_continue }
|
||||
- -re "^gssapi_\[^\n\]*\n" { exp_continue }
|
||||
- -re "^\r?\n" { exp_continue }
|
||||
- eof { verbose $expect_out(buffer) 1 }
|
||||
- timeout {
|
||||
- fail "$testname: timeout waiting for client $ccname to exit"
|
||||
- }
|
||||
- }
|
||||
- wait_client $testname $ccname $id $status
|
||||
-}
|
||||
-
|
||||
-
|
||||
-proc wait_client {testname ccname id status} {
|
||||
- global env
|
||||
- global kill
|
||||
- global kdestroy
|
||||
- global wait_error_index wait_errno_index wait_status_index
|
||||
-
|
||||
- verbose "$testname: waiting for client $ccname" 1
|
||||
-
|
||||
- set ret [wait -i $id]
|
||||
- if {[lindex $ret $wait_error_index] == -1} {
|
||||
- fail \
|
||||
- "$testname: wait $ccname returned error [lindex $ret $wait_errno_index]"
|
||||
- } else {
|
||||
- if {[lindex $ret $wait_status_index] == $status} {
|
||||
- pass "$testname: client $ccname"
|
||||
- } else {
|
||||
- fail "$testname: client $ccname: unexpected return status [lindex $ret $wait_status_index], should be $status."
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- set env(KRB5CCNAME) FILE:[pwd]/krb5cc_rpc_test_$ccname
|
||||
- if {[catch "exec $kdestroy -5"] != 0} {
|
||||
- perror "$testname: cannot destroy client $ccname ccache"
|
||||
- }
|
||||
-
|
||||
- unset env(KRB5CCNAME)
|
||||
-}
|
||||
diff --git a/src/lib/rpc/unit-test/rpc_test.0/expire.exp b/src/lib/rpc/unit-test/rpc_test.0/expire.exp
|
||||
deleted file mode 100644
|
||||
index e19cca0ef..000000000
|
||||
--- a/src/lib/rpc/unit-test/rpc_test.0/expire.exp
|
||||
+++ /dev/null
|
||||
@@ -1,49 +0,0 @@
|
||||
-set timeout 40
|
||||
-
|
||||
-load_lib "helpers.exp"
|
||||
-
|
||||
-global server_started
|
||||
-
|
||||
-proc expired {} {
|
||||
- global spawn_id server_id
|
||||
-
|
||||
- start_client expired expired testuser notathena -1m 100
|
||||
- eof_client expired expired $spawn_id 2
|
||||
-
|
||||
- expect {
|
||||
- -i $server_id
|
||||
- -re "rpc_test server: Authen.*failed:.*credential.*expired" { pass "expired" }
|
||||
- timeout { fail "expired: timeout waiting for expired creds error" }
|
||||
- }
|
||||
-
|
||||
- flush_server
|
||||
-}
|
||||
-
|
||||
-# This test doesn't work after #6948, because the client won't try to
|
||||
-# authenticate using an expired TGT.
|
||||
-#if { $server_started } {expired }
|
||||
-
|
||||
-proc overlap {} {
|
||||
- global spawn_id
|
||||
-
|
||||
- start_client expire 1 testuser notathena 20m 100
|
||||
- set client1_id $spawn_id
|
||||
- flush_server
|
||||
-
|
||||
- start_client expire 2 testuser notathena 40m 300
|
||||
- set client2_id $spawn_id
|
||||
- flush_server
|
||||
-
|
||||
- start_client expire 3 testuser notathena 60m 500
|
||||
- set client3_id $spawn_id
|
||||
- flush_server
|
||||
-
|
||||
- eof_client expire 1 $client1_id 0
|
||||
- eof_client expire 2 $client2_id 0
|
||||
- eof_client expire 3 $client3_id 0
|
||||
-
|
||||
- flush_server
|
||||
-}
|
||||
-if { $server_started } {overlap}
|
||||
-
|
||||
-
|
||||
diff --git a/src/lib/rpc/unit-test/rpc_test.0/fullrun.exp b/src/lib/rpc/unit-test/rpc_test.0/fullrun.exp
|
||||
deleted file mode 100644
|
||||
index 73083de1f..000000000
|
||||
--- a/src/lib/rpc/unit-test/rpc_test.0/fullrun.exp
|
||||
+++ /dev/null
|
||||
@@ -1,91 +0,0 @@
|
||||
-set timeout 120
|
||||
-
|
||||
-load_lib "helpers.exp"
|
||||
-
|
||||
-global spawn_id
|
||||
-global server_id
|
||||
-global server_started
|
||||
-
|
||||
-if { !$server_started } {return}
|
||||
-
|
||||
-# Start the client and do a full run
|
||||
-start_client "full run" fullrun testuser notathena 8h 1026
|
||||
-set client_id $spawn_id
|
||||
-
|
||||
-#
|
||||
-# test: did we get 11 dots?
|
||||
-#
|
||||
-verbose "Starting RPC echo test. This will take about 50 seconds.\n"
|
||||
-
|
||||
-set ver_line "rpc_test server: bad verifier\[^\r\n\]*\[\r\n]+"
|
||||
-
|
||||
-set dots 0
|
||||
-set server_lines 0
|
||||
-while {1} {
|
||||
- expect {
|
||||
- -i $server_id
|
||||
- -re $ver_line {
|
||||
- verbose "Got line from server."
|
||||
- incr server_lines
|
||||
- }
|
||||
- default {
|
||||
- exp_continue
|
||||
- }
|
||||
-
|
||||
- -i $client_id
|
||||
- . {
|
||||
- incr dots
|
||||
- verbose "$expect_out(buffer)" 1
|
||||
- if ($dots==11) { break }
|
||||
- }
|
||||
- eof {
|
||||
- #
|
||||
- # test: was the exit status right?
|
||||
- #
|
||||
- wait_client "full run" fullrun $client_id 0
|
||||
- break
|
||||
- }
|
||||
-
|
||||
- timeout {
|
||||
- verbose "Timeout waiting for dot\n" 1
|
||||
- fail "full run: timeout waiting for dot"
|
||||
- break
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-if {$dots==11} {
|
||||
- pass "fullrun: echo test"
|
||||
-} else {
|
||||
- fail "fullrun: echo test: expected 11 dots, got $dots"
|
||||
-}
|
||||
-
|
||||
-#
|
||||
-# test: server logged four bad verifiers?
|
||||
-#
|
||||
-verbose "full run: checking server output"
|
||||
-
|
||||
-# Small timeout, since the server should have already printed everything
|
||||
-set timeout 5
|
||||
-
|
||||
-while {$server_lines < 4} {
|
||||
- expect {
|
||||
- -i $server_id
|
||||
- -re $ver_line {
|
||||
- incr server_lines
|
||||
- }
|
||||
- -re ".+\r\n" {
|
||||
- verbose "Unexpected server output: $expect_out(buffer)"
|
||||
- }
|
||||
- default {
|
||||
- break
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-if {$server_lines == 4} {
|
||||
- pass "fullrun: bad verifiers"
|
||||
-} else {
|
||||
- fail "fullrun: expected four bad verifiers, got $server_lines"
|
||||
-}
|
||||
-
|
||||
-flush_server
|
||||
diff --git a/src/lib/rpc/unit-test/rpc_test.0/gsserr.exp b/src/lib/rpc/unit-test/rpc_test.0/gsserr.exp
|
||||
deleted file mode 100644
|
||||
index 005971989..000000000
|
||||
--- a/src/lib/rpc/unit-test/rpc_test.0/gsserr.exp
|
||||
+++ /dev/null
|
||||
@@ -1,30 +0,0 @@
|
||||
-set timeout 30
|
||||
-
|
||||
-load_lib "helpers.exp"
|
||||
-
|
||||
-global spawn_id
|
||||
-global server_id
|
||||
-global server_started
|
||||
-global hostname
|
||||
-
|
||||
-if { !$server_started } {return}
|
||||
-
|
||||
-start_client "gss err" gsserr testuser notathena 8h 1026 notserver@$hostname
|
||||
-
|
||||
-eof_client "gss err" gsserr $spawn_id 2
|
||||
-
|
||||
-#
|
||||
-# test: server logged an authentication attempted failed?
|
||||
-#
|
||||
-verbose "gss err: checking server output"
|
||||
-
|
||||
-expect {
|
||||
- -i $server_id
|
||||
- -re "rpc_test server: Authent.*failed: .* not found in keytab" {
|
||||
- pass "gss err: server logged auth error"
|
||||
- }
|
||||
- eof { fail "gss err: server exited" }
|
||||
- timeout { fail "gss err: timeout waiting for server output" }
|
||||
-}
|
||||
-
|
||||
-flush_server
|
||||
diff --git a/src/lib/rpc/unit-test/server.c b/src/lib/rpc/unit-test/server.c
|
||||
index 13e99bb06..c3bbcbf8c 100644
|
||||
--- a/src/lib/rpc/unit-test/server.c
|
||||
+++ b/src/lib/rpc/unit-test/server.c
|
||||
@@ -37,7 +37,7 @@ static void rpc_test_badverf(gss_name_t client, gss_name_t server,
|
||||
caddr_t data);
|
||||
|
||||
#ifndef SERVICE_NAME
|
||||
-#define SERVICE_NAME "server"
|
||||
+#define SERVICE_NAME "host"
|
||||
#endif
|
||||
|
||||
static void usage()
|
||||
@@ -120,7 +120,6 @@ main(int argc, char **argv)
|
||||
prot == IPPROTO_TCP ? "tcp" : "udp");
|
||||
exit(1);
|
||||
}
|
||||
- printf("port: %d\n", (int)transp->xp_port);
|
||||
|
||||
if (svcauth_gssapi_set_names(names, 0) == FALSE) {
|
||||
fprintf(stderr, "unable to set gssapi names\n");
|
||||
@@ -144,6 +143,8 @@ main(int argc, char **argv)
|
||||
signal(SIGTERM, handlesig);
|
||||
#endif
|
||||
printf("running\n");
|
||||
+ printf("port: %d\n", (int)transp->xp_port);
|
||||
+ fflush(stdout);
|
||||
|
||||
svc_run();
|
||||
fprintf(stderr, "svc_run returned");
|
||||
@@ -177,6 +178,7 @@ static void rpc_test_badverf(gss_name_t client, gss_name_t server,
|
||||
inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr),
|
||||
ntohs(rqst->rq_xprt->xp_raddr.sin_port),
|
||||
(int) server_name.length, (char *) server_name.value);
|
||||
+ fflush(stdout);
|
||||
|
||||
(void) gss_release_buffer(&minor_stat, &client_name);
|
||||
(void) gss_release_buffer(&minor_stat, &server_name);
|
||||
@@ -211,6 +213,7 @@ void rpc_test_badauth(OM_uint32 major, OM_uint32 minor,
|
||||
printf("rpc_test server: Authentication attempt failed: %s", a);
|
||||
log_badauth_display_status(major, minor);
|
||||
printf("\n");
|
||||
+ fflush(stdout);
|
||||
}
|
||||
|
||||
void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
|
||||
@@ -220,6 +223,7 @@ void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
|
||||
|
||||
a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
|
||||
printf("Miscellaneous RPC error: %s, %s\n", a, error);
|
||||
+ fflush(stdout);
|
||||
}
|
||||
|
||||
void log_badauth_display_status(OM_uint32 major, OM_uint32 minor)
|
||||
@@ -243,10 +247,12 @@ void log_badauth_display_status_1(OM_uint32 code, int type, int rec)
|
||||
log_badauth_display_status_1(gssstat,GSS_C_GSS_CODE,1);
|
||||
log_badauth_display_status_1(minor_stat,
|
||||
GSS_C_MECH_CODE, 1);
|
||||
- } else
|
||||
+ } else {
|
||||
printf("GSS-API authentication error %.*s: "
|
||||
"recursive failure!\n", (int) msg.length,
|
||||
(char *)msg.value);
|
||||
+ }
|
||||
+ fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -256,4 +262,5 @@ void log_badauth_display_status_1(OM_uint32 code, int type, int rec)
|
||||
if (!msg_ctx)
|
||||
break;
|
||||
}
|
||||
+ fflush(stdout);
|
||||
}
|
||||
diff --git a/src/lib/rpc/unit-test/t_rpc.py b/src/lib/rpc/unit-test/t_rpc.py
|
||||
new file mode 100644
|
||||
index 000000000..4e565d25c
|
||||
--- /dev/null
|
||||
+++ b/src/lib/rpc/unit-test/t_rpc.py
|
||||
@@ -0,0 +1,29 @@
|
||||
+import re
|
||||
+
|
||||
+from k5test import *
|
||||
+
|
||||
+realm = K5Realm()
|
||||
+
|
||||
+server = realm.start_server(['./server', '-t'], 'running')
|
||||
+line = server.stdout.readline()
|
||||
+portstr = re.match(r'^port: (\d+)$', line).group(1)
|
||||
+
|
||||
+realm.run(['./client', '-t', hostname, portstr, 'host@' + hostname, '1026'],
|
||||
+ expected_msg='...........')
|
||||
+
|
||||
+for i in range(4):
|
||||
+ line = server.stdout.readline()
|
||||
+ if 'rpc_test server: bad verifier from user@KRBTEST.COM at ' not in line:
|
||||
+ fail('unexpected server message: ' + line)
|
||||
+ output(line)
|
||||
+
|
||||
+realm.addprinc('nokey/' + hostname)
|
||||
+
|
||||
+realm.run(['./client', '-t', hostname, portstr, 'nokey@' + hostname, '1026'],
|
||||
+ expected_code=2)
|
||||
+
|
||||
+line = server.stdout.readline()
|
||||
+if 'rpc_test server: Authentication attempt failed: ' not in line:
|
||||
+ fail('unexpected server message: ' + line)
|
||||
+
|
||||
+success('gssrpc auth_gssapi tests')
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
From 52e3695cc5ef00766e12adfe8ed276c2885e71bb Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 20 Aug 2020 17:49:29 -0400
|
||||
Subject: [PATCH] Unify kvno option documentation
|
||||
|
||||
Add missing kvno options to the kvno.rst synopsis and option
|
||||
descriptions, and to the kvno usage message. Remove mention of '-h'
|
||||
(help text), from kvno.rst as it is an implicit option. Note that the
|
||||
three new caching options were added in release 1.19.
|
||||
|
||||
Indicate the two exclusions (-u/-S and --u2u with the S4U2Self options)
|
||||
and dependency (-P on S4U2Self) where they are missing.
|
||||
|
||||
Switch xusage() to print only a single localized string, rather than
|
||||
running each line of output through localization separately.
|
||||
|
||||
Leave kvno -C undocumented for now, as the semantics of
|
||||
KRB5_GC_CANONICALIZE are minimally useful and likely to change.
|
||||
|
||||
[ghudson@mit.edu: edited documentation and commit message]
|
||||
|
||||
ticket: 7476
|
||||
tags: pullup
|
||||
target_version: 1.18-next
|
||||
|
||||
(cherry picked from commit becd1ad6830b526d08ddaf5b2b6f213154c6446c)
|
||||
---
|
||||
doc/user/user_commands/kvno.rst | 24 +++++++++++++-----------
|
||||
src/clients/kvno/kvno.c | 15 +++++++++------
|
||||
src/man/kvno.man | 24 +++++++++++++-----------
|
||||
3 files changed, 35 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/doc/user/user_commands/kvno.rst b/doc/user/user_commands/kvno.rst
|
||||
index 718313576..65c44e1c0 100644
|
||||
--- a/doc/user/user_commands/kvno.rst
|
||||
+++ b/doc/user/user_commands/kvno.rst
|
||||
@@ -10,13 +10,9 @@ SYNOPSIS
|
||||
[**-c** *ccache*]
|
||||
[**-e** *etype*]
|
||||
[**-q**]
|
||||
-[**-h**]
|
||||
+[**-u** | **-S** *sname*]
|
||||
[**-P**]
|
||||
-[**-S** *sname*]
|
||||
-[**-I** *for_user*]
|
||||
-[**-U** *for_user*]
|
||||
-[**-F** *cert_file*]
|
||||
-[**--u2u** *ccache*]
|
||||
+[[{**-F** *cert_file* | {**-I** | **-U**} *for_user*} [**-P**]] | **--u2u** *ccache*]
|
||||
*service1 service2* ...
|
||||
|
||||
|
||||
@@ -39,13 +35,18 @@ OPTIONS
|
||||
of all the services named on the command line. This is useful in
|
||||
certain backward compatibility situations.
|
||||
|
||||
+**-k** *keytab*
|
||||
+ Decrypt the acquired tickets using *keytab* to confirm their
|
||||
+ validity.
|
||||
+
|
||||
**-q**
|
||||
Suppress printing output when successful. If a service ticket
|
||||
cannot be obtained, an error message will still be printed and
|
||||
kvno will exit with nonzero status.
|
||||
|
||||
-**-h**
|
||||
- Prints a usage statement and exits.
|
||||
+**-u**
|
||||
+ Use the unknown name type in requested service principal names.
|
||||
+ This option Cannot be used with *-S*.
|
||||
|
||||
**-P**
|
||||
Specifies that the *service1 service2* ... arguments are to be
|
||||
@@ -76,16 +77,17 @@ OPTIONS
|
||||
|
||||
**--cached-only**
|
||||
Only retrieve credentials already present in the cache, not from
|
||||
- the KDC.
|
||||
+ the KDC. (Added in release 1.19.)
|
||||
|
||||
**--no-store**
|
||||
Do not store retrieved credentials in the cache. If
|
||||
**--out-cache** is also specified, credentials will still be
|
||||
- stored into the output credential cache.
|
||||
+ stored into the output credential cache. (Added in release 1.19.)
|
||||
|
||||
**--out-cache** *ccache*
|
||||
Initialize *ccache* and store all retrieved credentials into it.
|
||||
- Do not store acquired credentials in the input cache.
|
||||
+ Do not store acquired credentials in the input cache. (Added in
|
||||
+ release 1.19.)
|
||||
|
||||
**--u2u** *ccache*
|
||||
Requests a user-to-user ticket. *ccache* must contain a local
|
||||
diff --git a/src/clients/kvno/kvno.c b/src/clients/kvno/kvno.c
|
||||
index 9d85864f6..c5f6bf700 100644
|
||||
--- a/src/clients/kvno/kvno.c
|
||||
+++ b/src/clients/kvno/kvno.c
|
||||
@@ -38,15 +38,18 @@
|
||||
static char *prog;
|
||||
static int quiet = 0;
|
||||
|
||||
+#define XUSAGE_BREAK "\n\t"
|
||||
+
|
||||
static void
|
||||
xusage()
|
||||
{
|
||||
- fprintf(stderr, _("usage: %s [-C] [-u] [-c ccache] [-e etype]\n"), prog);
|
||||
- fprintf(stderr, _("\t[-k keytab] [-S sname] [{-I | -U} for_user | "
|
||||
- "[-F cert_file] [-P]]\n"));
|
||||
- fprintf(stderr, _("\t[--cached-only] [--no-store] [--out-cache ccache] "
|
||||
- "[--u2u ccache]\n"));
|
||||
- fprintf(stderr, _("\tservice1 service2 ...\n"));
|
||||
+ fprintf(stderr, _("usage: %s [-c ccache] [-e etype] [-k keytab] [-q] "
|
||||
+ "[-u | -S sname]" XUSAGE_BREAK
|
||||
+ "[[{-F cert_file | {-I | -U} for_user} [-P]] | "
|
||||
+ "--u2u ccache]" XUSAGE_BREAK
|
||||
+ "[--cached-only] [--no-store] [--out-cache] "
|
||||
+ "service1 service2 ...\n"),
|
||||
+ prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
diff --git a/src/man/kvno.man b/src/man/kvno.man
|
||||
index b9f6739eb..22318324d 100644
|
||||
--- a/src/man/kvno.man
|
||||
+++ b/src/man/kvno.man
|
||||
@@ -36,13 +36,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
[\fB\-c\fP \fIccache\fP]
|
||||
[\fB\-e\fP \fIetype\fP]
|
||||
[\fB\-q\fP]
|
||||
-[\fB\-h\fP]
|
||||
+[\fB\-u\fP | \fB\-S\fP \fIsname\fP]
|
||||
[\fB\-P\fP]
|
||||
-[\fB\-S\fP \fIsname\fP]
|
||||
-[\fB\-I\fP \fIfor_user\fP]
|
||||
-[\fB\-U\fP \fIfor_user\fP]
|
||||
-[\fB\-F\fP \fIcert_file\fP]
|
||||
-[\fB\-\-u2u\fP \fIccache\fP]
|
||||
+[[{\fB\-F\fP \fIcert_file\fP | {\fB\-I\fP | \fB\-U\fP} \fIfor_user\fP} [\fB\-P\fP]] | \fB\-\-u2u\fP \fIccache\fP]
|
||||
\fIservice1 service2\fP ...
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
@@ -60,13 +56,18 @@ Specifies the enctype which will be requested for the session key
|
||||
of all the services named on the command line. This is useful in
|
||||
certain backward compatibility situations.
|
||||
.TP
|
||||
+\fB\-k\fP \fIkeytab\fP
|
||||
+Decrypt the acquired tickets using \fIkeytab\fP to confirm their
|
||||
+validity.
|
||||
+.TP
|
||||
\fB\-q\fP
|
||||
Suppress printing output when successful. If a service ticket
|
||||
cannot be obtained, an error message will still be printed and
|
||||
kvno will exit with nonzero status.
|
||||
.TP
|
||||
-\fB\-h\fP
|
||||
-Prints a usage statement and exits.
|
||||
+\fB\-u\fP
|
||||
+Use the unknown name type in requested service principal names.
|
||||
+This option Cannot be used with \fI\-S\fP\&.
|
||||
.TP
|
||||
\fB\-P\fP
|
||||
Specifies that the \fIservice1 service2\fP ... arguments are to be
|
||||
@@ -97,16 +98,17 @@ certificate file must be in PEM format.
|
||||
.TP
|
||||
\fB\-\-cached\-only\fP
|
||||
Only retrieve credentials already present in the cache, not from
|
||||
-the KDC.
|
||||
+the KDC. (Added in release 1.19.)
|
||||
.TP
|
||||
\fB\-\-no\-store\fP
|
||||
Do not store retrieved credentials in the cache. If
|
||||
\fB\-\-out\-cache\fP is also specified, credentials will still be
|
||||
-stored into the output credential cache.
|
||||
+stored into the output credential cache. (Added in release 1.19.)
|
||||
.TP
|
||||
\fB\-\-out\-cache\fP \fIccache\fP
|
||||
Initialize \fIccache\fP and store all retrieved credentials into it.
|
||||
-Do not store acquired credentials in the input cache.
|
||||
+Do not store acquired credentials in the input cache. (Added in
|
||||
+release 1.19.)
|
||||
.TP
|
||||
\fB\-\-u2u\fP \fIccache\fP
|
||||
Requests a user\-to\-user ticket. \fIccache\fP must contain a local
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
From 3e0d464f55320b393e32285f31710c24758a9101 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 4 Mar 2020 17:18:51 -0500
|
||||
Subject: [PATCH] Use two queues for concurrent t_otp.py daemons
|
||||
|
||||
t_otp.py occasionally fails during the #8708 regression test, reading
|
||||
a true answer instead of the expected false answer during the first
|
||||
verify() call. Most likely the daemons are writing their answers to
|
||||
the shared queue out of order. Use a separate queue for the second
|
||||
daemon to ensure correct correlation of results.
|
||||
|
||||
(cherry picked from commit c03f67eefec05db19e84e889fab7c25904929633)
|
||||
---
|
||||
src/tests/t_otp.py | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
|
||||
index cba871a0f..c3b820a41 100755
|
||||
--- a/src/tests/t_otp.py
|
||||
+++ b/src/tests/t_otp.py
|
||||
@@ -256,16 +256,17 @@ verify(daemon, queue, True, realm.user_princ, 'accept')
|
||||
## tokens configured, with the first rejecting and the second
|
||||
## accepting. With the bug, the KDC incorrectly rejects the request
|
||||
## and then performs invalid memory accesses, most likely crashing.
|
||||
+queue2 = Queue()
|
||||
daemon1 = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept1', queue))
|
||||
-daemon2 = UnixRadiusDaemon(args=(socket_file, None, 'accept2', queue))
|
||||
+daemon2 = UnixRadiusDaemon(args=(socket_file, None, 'accept2', queue2))
|
||||
daemon1.start()
|
||||
queue.get()
|
||||
daemon2.start()
|
||||
-queue.get()
|
||||
+queue2.get()
|
||||
oconf = '[' + otpconfig_1('udp') + ', ' + otpconfig_1('unix') + ']'
|
||||
realm.run([kadminl, 'setstr', realm.user_princ, 'otp', oconf])
|
||||
realm.kinit(realm.user_princ, 'accept2', flags=flags)
|
||||
verify(daemon1, queue, False, realm.user_princ.split('@')[0], 'accept2')
|
||||
-verify(daemon2, queue, True, realm.user_princ, 'accept2')
|
||||
+verify(daemon2, queue2, True, realm.user_princ, 'accept2')
|
||||
|
||||
success('OTP tests')
|
||||
1
ci.fmf
Normal file
1
ci.fmf
Normal file
|
|
@ -0,0 +1 @@
|
|||
resultsdb-testcase: separate
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
From 30ece66508c8e10f704cd2860dfd421ebee15897 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 23 Aug 2016 16:45:26 -0400
|
||||
Subject: [PATCH] [downstream] Adjust build configuration
|
||||
|
||||
Build binaries in this package as RELRO PIEs, libraries as partial RELRO,
|
||||
and install shared libraries with the execute bit set on them. Prune out
|
||||
the -L/usr/lib* and PIE flags where they might leak out and affect
|
||||
apps which just want to link with the libraries. FIXME: needs to check and
|
||||
not just assume that the compiler supports using these flags.
|
||||
|
||||
Last-updated: krb5-1.15-beta1
|
||||
---
|
||||
src/build-tools/krb5-config.in | 7 +++++++
|
||||
src/config/pre.in | 2 +-
|
||||
src/config/shlib.conf | 5 +++--
|
||||
3 files changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
|
||||
index c17cb5eb5..1891dea99 100755
|
||||
--- a/src/build-tools/krb5-config.in
|
||||
+++ b/src/build-tools/krb5-config.in
|
||||
@@ -226,6 +226,13 @@ if test -n "$do_libs"; then
|
||||
-e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \
|
||||
-e 's#\$(CFLAGS)##'`
|
||||
|
||||
+ if test `dirname $libdir` = /usr ; then
|
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"`
|
||||
+ fi
|
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"`
|
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"`
|
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"`
|
||||
+
|
||||
if test $library = 'kdb'; then
|
||||
lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
|
||||
library=krb5
|
||||
diff --git a/src/config/pre.in b/src/config/pre.in
|
||||
index 917357df9..a8540ae2a 100644
|
||||
--- a/src/config/pre.in
|
||||
+++ b/src/config/pre.in
|
||||
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
|
||||
INSTALL_SCRIPT=@INSTALL_PROGRAM@
|
||||
INSTALL_DATA=@INSTALL_DATA@
|
||||
INSTALL_SHLIB=@INSTALL_SHLIB@
|
||||
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
|
||||
+INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755
|
||||
## This is needed because autoconf will sometimes define @exec_prefix@ to be
|
||||
## ${prefix}.
|
||||
prefix=@prefix@
|
||||
diff --git a/src/config/shlib.conf b/src/config/shlib.conf
|
||||
index 3e4af6c02..2b20c3fda 100644
|
||||
--- a/src/config/shlib.conf
|
||||
+++ b/src/config/shlib.conf
|
||||
@@ -423,7 +423,7 @@ mips-*-netbsd*)
|
||||
# Linux ld doesn't default to stuffing the SONAME field...
|
||||
# Use objdump -x to examine the fields of the library
|
||||
# UNDEF_CHECK is suppressed by --enable-asan
|
||||
- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)'
|
||||
+ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK) -Wl,-z,relro -Wl,--warn-shared-textrel'
|
||||
UNDEF_CHECK='-Wl,--no-undefined'
|
||||
# $(EXPORT_CHECK) runs export-check.pl when in maintainer mode.
|
||||
LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)'
|
||||
@@ -435,7 +435,8 @@ mips-*-netbsd*)
|
||||
SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
|
||||
PROFFLAGS=-pg
|
||||
PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)'
|
||||
- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)'
|
||||
+ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)'
|
||||
+ INSTALL_SHLIB='${INSTALL} -m755'
|
||||
CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
|
||||
CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)'
|
||||
CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)'
|
||||
|
|
@ -1,752 +0,0 @@
|
|||
From 040dd62418b918adc993b9cc3e1e80fc232286c4 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Fri, 15 Nov 2019 20:05:16 +0000
|
||||
Subject: [PATCH] [downstream] Use backported version of OpenSSL-3 KDF
|
||||
interface
|
||||
|
||||
Last-updated: krb5-1.17
|
||||
---
|
||||
src/configure.ac | 4 +
|
||||
src/lib/crypto/krb/derive.c | 356 +++++++++++++-----
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 257 ++++++++-----
|
||||
3 files changed, 428 insertions(+), 189 deletions(-)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index d4e4da525..29be532cb 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -282,6 +282,10 @@ AC_SUBST(CRYPTO_IMPL)
|
||||
AC_SUBST(CRYPTO_IMPL_CFLAGS)
|
||||
AC_SUBST(CRYPTO_IMPL_LIBS)
|
||||
|
||||
+AC_CHECK_FUNCS(EVP_KDF_CTX_new_id EVP_KDF_ctrl EVP_KDF_derive,
|
||||
+ AC_DEFINE(OSSL_KDFS, 1, [Define if using OpenSSL KDFs]),
|
||||
+ AC_MSG_ERROR([backported OpenSSL KDFs not found]))
|
||||
+
|
||||
AC_ARG_WITH([prng-alg],
|
||||
AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]),
|
||||
[PRNG_ALG=$withval
|
||||
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
|
||||
index 6707a7308..915a173dd 100644
|
||||
--- a/src/lib/crypto/krb/derive.c
|
||||
+++ b/src/lib/crypto/krb/derive.c
|
||||
@@ -27,6 +27,13 @@
|
||||
|
||||
#include "crypto_int.h"
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#else
|
||||
+#error "Refusing to build without OpenSSL KDFs!"
|
||||
+#endif
|
||||
+
|
||||
static krb5_key
|
||||
find_cached_dkey(struct derived_key *list, const krb5_data *constant)
|
||||
{
|
||||
@@ -77,55 +84,193 @@ cleanup:
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
static krb5_error_code
|
||||
-derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
- krb5_key inkey, krb5_data *outrnd,
|
||||
- const krb5_data *in_constant)
|
||||
+openssl_kbdkf_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *label, const krb5_data *context)
|
||||
{
|
||||
- size_t blocksize, keybytes, n;
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_MD *digest;
|
||||
+
|
||||
+ if (!strcmp(hash->hash_name, "SHA1"))
|
||||
+ digest = EVP_sha1();
|
||||
+ else if (!strcmp(hash->hash_name, "SHA-256"))
|
||||
+ digest = EVP_sha256();
|
||||
+ else if (!strcmp(hash->hash_name, "SHA-384"))
|
||||
+ digest = EVP_sha384();
|
||||
+ else
|
||||
+ goto done;
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
|
||||
+ if (!ctx)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
|
||||
+ EVP_KDF_KB_MAC_TYPE_HMAC) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length) != 1 ||
|
||||
+ (context->length > 0 &&
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_INFO, context->data,
|
||||
+ context->length) != 1) ||
|
||||
+ (label->length > 0 &&
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, label->data,
|
||||
+ label->length) != 1) ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
|
||||
+ outrnd->length) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+openssl_kbkdf_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_CIPHER *cipher;
|
||||
+ static unsigned char zeroes[16];
|
||||
+
|
||||
+ memset(zeroes, 0, sizeof(zeroes));
|
||||
+
|
||||
+ if (enc->keylength == 16)
|
||||
+ cipher = EVP_camellia_128_cbc();
|
||||
+ else if (enc->keylength == 32)
|
||||
+ cipher = EVP_camellia_256_cbc();
|
||||
+ else
|
||||
+ goto done;
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
|
||||
+ if (!ctx)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MODE,
|
||||
+ EVP_KDF_KB_MODE_FEEDBACK) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
|
||||
+ EVP_KDF_KB_MAC_TYPE_CMAC) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, in_constant->data,
|
||||
+ in_constant->length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_SEED, zeroes,
|
||||
+ sizeof(zeroes)) != 1 ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
|
||||
+ outrnd->length) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+openssl_krb5kdf(const struct krb5_enc_provider *enc, krb5_key inkey,
|
||||
+ krb5_data *outrnd, const krb5_data *in_constant)
|
||||
+{
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_CIPHER *cipher;
|
||||
+
|
||||
+ if (inkey->keyblock.length != enc->keylength ||
|
||||
+ outrnd->length != enc->keybytes) {
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+ }
|
||||
+
|
||||
+ if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 16)
|
||||
+ cipher = EVP_aes_128_cbc();
|
||||
+ else if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 32)
|
||||
+ cipher = EVP_aes_256_cbc();
|
||||
+ else if (enc->keylength == 24)
|
||||
+ cipher = EVP_des_ede3_cbc();
|
||||
+ else
|
||||
+ goto done;
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KRB5KDF);
|
||||
+ if (ctx == NULL)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KRB5KDF_CONSTANT,
|
||||
+ in_constant->data, in_constant->length) != 1 ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
|
||||
+ outrnd->length) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#else /* OSSL_KDFS */
|
||||
+
|
||||
+/*
|
||||
+ * NIST SP800-108 KDF in counter mode (section 5.1).
|
||||
+ * Parameters:
|
||||
+ * - HMAC (with hash as the hash provider) is the PRF.
|
||||
+ * - A block counter of four bytes is used.
|
||||
+ * - Four bytes are used to encode the output length in the PRF input.
|
||||
+ *
|
||||
+ * There are no uses requiring more than a single PRF invocation.
|
||||
+ */
|
||||
+static krb5_error_code
|
||||
+builtin_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *label,
|
||||
+ const krb5_data *context)
|
||||
+{
|
||||
+ krb5_crypto_iov iov[5];
|
||||
krb5_error_code ret;
|
||||
- krb5_data block = empty_data();
|
||||
+ krb5_data prf;
|
||||
+ unsigned char ibuf[4], lbuf[4];
|
||||
|
||||
- blocksize = enc->block_size;
|
||||
- keybytes = enc->keybytes;
|
||||
-
|
||||
- if (blocksize == 1)
|
||||
- return KRB5_BAD_ENCTYPE;
|
||||
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
||||
+ if (hash == NULL || outrnd->length > hash->hashsize)
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
|
||||
/* Allocate encryption data buffer. */
|
||||
- ret = alloc_data(&block, blocksize);
|
||||
+ ret = alloc_data(&prf, hash->hashsize);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Initialize the input block. */
|
||||
- if (in_constant->length == blocksize) {
|
||||
- memcpy(block.data, in_constant->data, blocksize);
|
||||
- } else {
|
||||
- krb5int_nfold(in_constant->length * 8,
|
||||
- (unsigned char *) in_constant->data,
|
||||
- blocksize * 8, (unsigned char *) block.data);
|
||||
- }
|
||||
+ /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
||||
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[0].data = make_data(ibuf, sizeof(ibuf));
|
||||
+ store_32_be(1, ibuf);
|
||||
+ /* Label */
|
||||
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[1].data = *label;
|
||||
+ /* 0x00: separator byte */
|
||||
+ iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[2].data = make_data("", 1);
|
||||
+ /* Context */
|
||||
+ iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[3].data = *context;
|
||||
+ /* [L]2: four-byte big-endian binary string giving the output length */
|
||||
+ iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[4].data = make_data(lbuf, sizeof(lbuf));
|
||||
+ store_32_be(outrnd->length * 8, lbuf);
|
||||
|
||||
- /* Loop encrypting the blocks until enough key bytes are generated. */
|
||||
- n = 0;
|
||||
- while (n < keybytes) {
|
||||
- ret = encrypt_block(enc, inkey, &block);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
-
|
||||
- if ((keybytes - n) <= blocksize) {
|
||||
- memcpy(outrnd->data + n, block.data, (keybytes - n));
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- memcpy(outrnd->data + n, block.data, blocksize);
|
||||
- n += blocksize;
|
||||
- }
|
||||
-
|
||||
-cleanup:
|
||||
- zapfree(block.data, blocksize);
|
||||
+ ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
||||
+ if (!ret)
|
||||
+ memcpy(outrnd->data, prf.data, outrnd->length);
|
||||
+ zapfree(prf.data, prf.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -139,9 +284,9 @@ cleanup:
|
||||
* - Four bytes are used to encode the output length in the PRF input.
|
||||
*/
|
||||
static krb5_error_code
|
||||
-derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
- krb5_key inkey, krb5_data *outrnd,
|
||||
- const krb5_data *in_constant)
|
||||
+builtin_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
{
|
||||
size_t blocksize, keybytes, n;
|
||||
krb5_crypto_iov iov[6];
|
||||
@@ -204,56 +349,94 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * NIST SP800-108 KDF in counter mode (section 5.1).
|
||||
- * Parameters:
|
||||
- * - HMAC (with hash as the hash provider) is the PRF.
|
||||
- * - A block counter of four bytes is used.
|
||||
- * - Four bytes are used to encode the output length in the PRF input.
|
||||
- *
|
||||
- * There are no uses requiring more than a single PRF invocation.
|
||||
- */
|
||||
+static krb5_error_code
|
||||
+builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+ size_t blocksize, keybytes, n;
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_data block = empty_data();
|
||||
+
|
||||
+ blocksize = enc->block_size;
|
||||
+ keybytes = enc->keybytes;
|
||||
+
|
||||
+ if (blocksize == 1)
|
||||
+ return KRB5_BAD_ENCTYPE;
|
||||
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ /* Allocate encryption data buffer. */
|
||||
+ ret = alloc_data(&block, blocksize);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Initialize the input block. */
|
||||
+ if (in_constant->length == blocksize) {
|
||||
+ memcpy(block.data, in_constant->data, blocksize);
|
||||
+ } else {
|
||||
+ krb5int_nfold(in_constant->length * 8,
|
||||
+ (unsigned char *) in_constant->data,
|
||||
+ blocksize * 8, (unsigned char *) block.data);
|
||||
+ }
|
||||
+
|
||||
+ /* Loop encrypting the blocks until enough key bytes are generated. */
|
||||
+ n = 0;
|
||||
+ while (n < keybytes) {
|
||||
+ ret = encrypt_block(enc, inkey, &block);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if ((keybytes - n) <= blocksize) {
|
||||
+ memcpy(outrnd->data + n, block.data, (keybytes - n));
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(outrnd->data + n, block.data, blocksize);
|
||||
+ n += blocksize;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ zapfree(block.data, blocksize);
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif /* OSSL_KDFS */
|
||||
+
|
||||
krb5_error_code
|
||||
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
krb5_key inkey, krb5_data *outrnd,
|
||||
const krb5_data *label, const krb5_data *context)
|
||||
{
|
||||
- krb5_crypto_iov iov[5];
|
||||
- krb5_error_code ret;
|
||||
- krb5_data prf;
|
||||
- unsigned char ibuf[4], lbuf[4];
|
||||
+#ifdef OSSL_KDFS
|
||||
+ return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context);
|
||||
+#else
|
||||
+ return builtin_sp800_108_counter_hmac(hash, inkey, outrnd, label,
|
||||
+ context);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
- if (hash == NULL || outrnd->length > hash->hashsize)
|
||||
- return KRB5_CRYPTO_INTERNAL;
|
||||
+static krb5_error_code
|
||||
+k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+#ifdef OSSL_KDFS
|
||||
+ return openssl_kbkdf_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
+#else
|
||||
+ return builtin_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
- /* Allocate encryption data buffer. */
|
||||
- ret = alloc_data(&prf, hash->hashsize);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
||||
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[0].data = make_data(ibuf, sizeof(ibuf));
|
||||
- store_32_be(1, ibuf);
|
||||
- /* Label */
|
||||
- iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[1].data = *label;
|
||||
- /* 0x00: separator byte */
|
||||
- iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[2].data = make_data("", 1);
|
||||
- /* Context */
|
||||
- iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[3].data = *context;
|
||||
- /* [L]2: four-byte big-endian binary string giving the output length */
|
||||
- iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[4].data = make_data(lbuf, sizeof(lbuf));
|
||||
- store_32_be(outrnd->length * 8, lbuf);
|
||||
-
|
||||
- ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
||||
- if (!ret)
|
||||
- memcpy(outrnd->data, prf.data, outrnd->length);
|
||||
- zapfree(prf.data, prf.length);
|
||||
- return ret;
|
||||
+static krb5_error_code
|
||||
+k5_derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+#ifdef OSSL_KDFS
|
||||
+ return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
|
||||
+#else
|
||||
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
+#endif
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -266,10 +449,9 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
|
||||
|
||||
switch (alg) {
|
||||
case DERIVE_RFC3961:
|
||||
- return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
+ return k5_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
case DERIVE_SP800_108_CMAC:
|
||||
- return derive_random_sp800_108_feedback_cmac(enc, inkey, outrnd,
|
||||
- in_constant);
|
||||
+ return k5_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
case DERIVE_SP800_108_HMAC:
|
||||
return k5_sp800_108_counter_hmac(hash, inkey, outrnd, in_constant,
|
||||
&empty);
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 52976895b..dd718c2be 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -38,6 +38,13 @@
|
||||
#include <dirent.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#else
|
||||
+#error "Refusing to build without OpenSSL KDFs!"
|
||||
+#endif
|
||||
+
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
@@ -2331,11 +2338,51 @@ pkinit_alg_values(krb5_context context,
|
||||
}
|
||||
} /* pkinit_alg_values() */
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
+static krb5_error_code
|
||||
+openssl_sskdf(krb5_context context, size_t hash_bytes, krb5_data *key,
|
||||
+ krb5_data *info, char *out, size_t out_len)
|
||||
+{
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_MD *digest;
|
||||
|
||||
-/* pkinit_alg_agility_kdf() --
|
||||
- * This function generates a key using the KDF described in
|
||||
- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt. The algorithm is
|
||||
- * described as follows:
|
||||
+ /* RFC 8636 defines a SHA384 variant, but we don't use it. */
|
||||
+ if (hash_bytes == 20) {
|
||||
+ digest = EVP_sha1();
|
||||
+ } else if (hash_bytes == 32) {
|
||||
+ digest = EVP_sha256();
|
||||
+ } else if (hash_bytes == 64) {
|
||||
+ digest = EVP_sha512();
|
||||
+ } else {
|
||||
+ krb5_set_error_message(context, ret, "Bad hash type for SSKDF");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
|
||||
+ if (!ctx) {
|
||||
+ oerr(context, ret, _("Failed to instantiate SSKDF"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key->data,
|
||||
+ key->length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSKDF_INFO, info->data,
|
||||
+ info->length) != 1 ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)out, out_len) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+#else
|
||||
+/*
|
||||
+ * Generate a key using the KDF described in RFC 8636, also known as SSKDF
|
||||
+ * (single-step kdf). Our caller precomputes `reps`, but otherwise the
|
||||
+ * algorithm is as follows:
|
||||
*
|
||||
* 1. reps = keydatalen (K) / hash length (H)
|
||||
*
|
||||
@@ -2349,95 +2396,16 @@ pkinit_alg_values(krb5_context context,
|
||||
*
|
||||
* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes.
|
||||
*/
|
||||
-krb5_error_code
|
||||
-pkinit_alg_agility_kdf(krb5_context context,
|
||||
- krb5_data *secret,
|
||||
- krb5_data *alg_oid,
|
||||
- krb5_const_principal party_u_info,
|
||||
- krb5_const_principal party_v_info,
|
||||
- krb5_enctype enctype,
|
||||
- krb5_data *as_req,
|
||||
- krb5_data *pk_as_rep,
|
||||
- krb5_keyblock *key_block)
|
||||
+static krb5_error_code
|
||||
+builtin_sskdf(krb5_context context, unsigned int reps, size_t hash_len,
|
||||
+ const EVP_MD *(*EVP_func)(void), krb5_data *secret,
|
||||
+ krb5_data *other_info, char *out, size_t out_len)
|
||||
{
|
||||
krb5_error_code retval = 0;
|
||||
|
||||
- unsigned int reps = 0;
|
||||
- uint32_t counter = 1; /* Does this type work on Windows? */
|
||||
+ uint32_t counter = 1;
|
||||
size_t offset = 0;
|
||||
- size_t hash_len = 0;
|
||||
- size_t rand_len = 0;
|
||||
- size_t key_len = 0;
|
||||
- krb5_data random_data;
|
||||
- krb5_sp80056a_other_info other_info_fields;
|
||||
- krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
||||
- krb5_data *other_info = NULL;
|
||||
- krb5_data *supp_pub_info = NULL;
|
||||
- krb5_algorithm_identifier alg_id;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
- const EVP_MD *(*EVP_func)(void);
|
||||
-
|
||||
- /* initialize random_data here to make clean-up safe */
|
||||
- random_data.length = 0;
|
||||
- random_data.data = NULL;
|
||||
-
|
||||
- /* allocate and initialize the key block */
|
||||
- key_block->magic = 0;
|
||||
- key_block->enctype = enctype;
|
||||
- if (0 != (retval = krb5_c_keylengths(context, enctype, &rand_len,
|
||||
- &key_len)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- random_data.length = rand_len;
|
||||
- key_block->length = key_len;
|
||||
-
|
||||
- if (NULL == (key_block->contents = malloc(key_block->length))) {
|
||||
- retval = ENOMEM;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
- memset (key_block->contents, 0, key_block->length);
|
||||
-
|
||||
- /* If this is anonymous pkinit, use the anonymous principle for party_u_info */
|
||||
- if (party_u_info && krb5_principal_compare_any_realm(context, party_u_info,
|
||||
- krb5_anonymous_principal()))
|
||||
- party_u_info = (krb5_principal)krb5_anonymous_principal();
|
||||
-
|
||||
- if (0 != (retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- /* 1. reps = keydatalen (K) / hash length (H) */
|
||||
- reps = key_block->length/hash_len;
|
||||
-
|
||||
- /* ... and round up, if necessary */
|
||||
- if (key_block->length > (reps * hash_len))
|
||||
- reps++;
|
||||
-
|
||||
- /* Allocate enough space in the random data buffer to hash directly into
|
||||
- * it, even if the last hash will make it bigger than the key length. */
|
||||
- if (NULL == (random_data.data = malloc(reps * hash_len))) {
|
||||
- retval = ENOMEM;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
- /* Encode the ASN.1 octet string for "SuppPubInfo" */
|
||||
- supp_pub_info_fields.enctype = enctype;
|
||||
- supp_pub_info_fields.as_req = *as_req;
|
||||
- supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
||||
- if (0 != ((retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
||||
- &supp_pub_info))))
|
||||
- goto cleanup;
|
||||
-
|
||||
- /* Now encode the ASN.1 octet string for "OtherInfo" */
|
||||
- memset(&alg_id, 0, sizeof alg_id);
|
||||
- alg_id.algorithm = *alg_oid; /*alias*/
|
||||
-
|
||||
- other_info_fields.algorithm_identifier = alg_id;
|
||||
- other_info_fields.party_u_info = (krb5_principal) party_u_info;
|
||||
- other_info_fields.party_v_info = (krb5_principal) party_v_info;
|
||||
- other_info_fields.supp_pub_info = *supp_pub_info;
|
||||
- if (0 != (retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info)))
|
||||
- goto cleanup;
|
||||
|
||||
/* 2. Initialize a 32-bit, big-endian bit string counter as 1.
|
||||
* 3. For i = 1 to reps by 1, do the following:
|
||||
@@ -2471,8 +2439,9 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes. */
|
||||
- if (!EVP_DigestFinal(ctx, (uint8_t *)random_data.data + offset, &s)) {
|
||||
+ /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K
|
||||
+ * bytes. */
|
||||
+ if (!EVP_DigestFinal(ctx, (unsigned char *)out + offset, &s)) {
|
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
||||
"Call to OpenSSL EVP_DigestUpdate() returned an error.");
|
||||
retval = KRB5_CRYPTO_INTERNAL;
|
||||
@@ -2484,26 +2453,110 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
EVP_MD_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
-
|
||||
- retval = krb5_c_random_to_key(context, enctype, &random_data,
|
||||
- key_block);
|
||||
-
|
||||
cleanup:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
+ return retval;
|
||||
+} /* builtin_sskdf() */
|
||||
+#endif /* OSSL_KDFS */
|
||||
|
||||
- /* If this has been an error, free the allocated key_block, if any */
|
||||
- if (retval) {
|
||||
- krb5_free_keyblock_contents(context, key_block);
|
||||
+/* id-pkinit-kdf family, as specified by RFC 8636. */
|
||||
+krb5_error_code
|
||||
+pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
|
||||
+ krb5_data *alg_oid, krb5_const_principal party_u_info,
|
||||
+ krb5_const_principal party_v_info,
|
||||
+ krb5_enctype enctype, krb5_data *as_req,
|
||||
+ krb5_data *pk_as_rep, krb5_keyblock *key_block)
|
||||
+{
|
||||
+ krb5_error_code retval;
|
||||
+ size_t hash_len = 0, rand_len = 0, key_len = 0;
|
||||
+ const EVP_MD *(*EVP_func)(void);
|
||||
+ krb5_sp80056a_other_info other_info_fields;
|
||||
+ krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
||||
+ krb5_data *other_info = NULL, *supp_pub_info = NULL;
|
||||
+ krb5_data random_data = empty_data();
|
||||
+ krb5_algorithm_identifier alg_id;
|
||||
+ unsigned int reps;
|
||||
+
|
||||
+ /* Allocate and initialize the key block. */
|
||||
+ key_block->magic = 0;
|
||||
+ key_block->enctype = enctype;
|
||||
+
|
||||
+ /* Use separate variables to avoid alignment restriction problems. */
|
||||
+ retval = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+ random_data.length = rand_len;
|
||||
+ key_block->length = key_len;
|
||||
+
|
||||
+ key_block->contents = k5calloc(key_block->length, 1, &retval);
|
||||
+ if (key_block->contents == NULL)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* If this is anonymous pkinit, use the anonymous principle for
|
||||
+ * party_u_info. */
|
||||
+ if (party_u_info &&
|
||||
+ krb5_principal_compare_any_realm(context, party_u_info,
|
||||
+ krb5_anonymous_principal())) {
|
||||
+ party_u_info = (krb5_principal)krb5_anonymous_principal();
|
||||
}
|
||||
|
||||
- /* free other allocated resources, either way */
|
||||
- if (random_data.data)
|
||||
- free(random_data.data);
|
||||
+ retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* 1. reps = keydatalen (K) / hash length (H) */
|
||||
+ reps = key_block->length / hash_len;
|
||||
+
|
||||
+ /* ... and round up, if necessary. */
|
||||
+ if (key_block->length > (reps * hash_len))
|
||||
+ reps++;
|
||||
+
|
||||
+ /* Allocate enough space in the random data buffer to hash directly into
|
||||
+ * it, even if the last hash will make it bigger than the key length. */
|
||||
+ random_data.data = k5alloc(reps * hash_len, &retval);
|
||||
+ if (random_data.data == NULL)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Encode the ASN.1 octet string for "SuppPubInfo". */
|
||||
+ supp_pub_info_fields.enctype = enctype;
|
||||
+ supp_pub_info_fields.as_req = *as_req;
|
||||
+ supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
||||
+ retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
||||
+ &supp_pub_info);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Now encode the ASN.1 octet string for "OtherInfo". */
|
||||
+ memset(&alg_id, 0, sizeof(alg_id));
|
||||
+ alg_id.algorithm = *alg_oid;
|
||||
+ other_info_fields.algorithm_identifier = alg_id;
|
||||
+ other_info_fields.party_u_info = (krb5_principal)party_u_info;
|
||||
+ other_info_fields.party_v_info = (krb5_principal)party_v_info;
|
||||
+ other_info_fields.supp_pub_info = *supp_pub_info;
|
||||
+ retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+#ifdef OSSL_KDFS
|
||||
+ retval = openssl_sskdf(context, hash_len, secret, other_info,
|
||||
+ random_data.data, key_block->length);
|
||||
+#else
|
||||
+ retval = builtin_sskdf(context, reps, hash_len, EVP_func, secret,
|
||||
+ other_info, random_data.data, key_block->length);
|
||||
+#endif
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ retval = krb5_c_random_to_key(context, enctype, &random_data, key_block);
|
||||
+cleanup:
|
||||
+ if (retval)
|
||||
+ krb5_free_keyblock_contents(context, key_block);
|
||||
+
|
||||
+ zapfree(random_data.data, random_data.length);
|
||||
krb5_free_data(context, other_info);
|
||||
krb5_free_data(context, supp_pub_info);
|
||||
-
|
||||
return retval;
|
||||
-} /*pkinit_alg_agility_kdf() */
|
||||
+}
|
||||
|
||||
/* Call DH_compute_key() and ensure that we left-pad short results instead of
|
||||
* leaving junk bytes at the end of the buffer. */
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
From 4254bee1b97edeb0848efce635bcf1b56306f968 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 23 Aug 2016 16:46:21 -0400
|
||||
Subject: [PATCH] [downstream] netlib and dns
|
||||
|
||||
We want to be able to use --with-netlib and --enable-dns at the same time.
|
||||
|
||||
Last-updated: krb5-1.3.1
|
||||
---
|
||||
src/aclocal.m4 | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
||||
index 6796fec53..c4358988a 100644
|
||||
--- a/src/aclocal.m4
|
||||
+++ b/src/aclocal.m4
|
||||
@@ -724,6 +724,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
|
||||
LIBS="$LIBS $withval"
|
||||
AC_MSG_RESULT("netlib will use \'$withval\'")
|
||||
fi
|
||||
+ KRB5_AC_ENABLE_DNS
|
||||
],dnl
|
||||
[AC_LIBRARY_NET]
|
||||
)])dnl
|
||||
8
gating.yaml
Normal file
8
gating.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
--- !Policy
|
||||
product_versions:
|
||||
- fedora-*
|
||||
decision_contexts:
|
||||
- bodhi_update_push_stable
|
||||
subject_type: koji_build
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tests.functional}
|
||||
|
|
@ -6,9 +6,9 @@ AssertPathExists=!/var/kerberos/krb5kdc/kpropd.acl
|
|||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=/var/run/kadmind.pid
|
||||
PIDFile=/run/kadmind.pid
|
||||
EnvironmentFile=-/etc/sysconfig/kadmin
|
||||
ExecStart=/usr/sbin/kadmind -P /var/run/kadmind.pid $KADMIND_ARGS
|
||||
ExecStart=/usr/sbin/kadmind -P /run/kadmind.pid $KADMIND_ARGS
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
|
|
|
|||
10
kdc.conf
10
kdc.conf
|
|
@ -1,3 +1,7 @@
|
|||
[libdefaults]
|
||||
# Allow RC4 HMAC-MD5 for session keys (see CVE-2022-37966)
|
||||
#allow_rc4 = true
|
||||
|
||||
[kdcdefaults]
|
||||
kdc_ports = 88
|
||||
kdc_tcp_ports = 88
|
||||
|
|
@ -5,10 +9,12 @@
|
|||
|
||||
[realms]
|
||||
EXAMPLE.COM = {
|
||||
#master_key_type = aes256-cts
|
||||
master_key_type = aes256-cts-hmac-sha384-192
|
||||
acl_file = /var/kerberos/krb5kdc/kadm5.acl
|
||||
dict_file = /usr/share/dict/words
|
||||
default_principal_flags = +preauth
|
||||
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
|
||||
supported_enctypes = aes256-cts:normal aes128-cts:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal
|
||||
supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal camellia256-cts-cmac:normal camellia128-cts-cmac:normal arcfour-hmac-md5:normal
|
||||
# Supported encryption types for FIPS mode:
|
||||
#supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
d /var/run/krb5kdc 0755 root root
|
||||
d /run/krb5kdc 0755 root root
|
||||
|
|
|
|||
18
krb5-tests
Normal file
18
krb5-tests
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
export RPM_PACKAGE_NAME={{ name }}
|
||||
export RPM_PACKAGE_VERSION={{ version }}
|
||||
export RPM_PACKAGE_RELEASE={{ release }}
|
||||
export RPM_ARCH={{ arch }}
|
||||
export RPM_BUILD_NCPUS="$(getconf _NPROCESSORS_ONLN)"
|
||||
|
||||
testdir="$(mktemp -d)"
|
||||
trap "rm -rf ${testdir}" EXIT
|
||||
|
||||
build_flags="$(eval "echo $(rpm --eval '%{_smp_mflags}')")"
|
||||
|
||||
mkdir "${testdir}/{{ name }}-tests"
|
||||
cp -rp /usr/share/{{ name }}-tests/{{ arch }} "${testdir}/{{ name }}-tests/"
|
||||
make -C "${testdir}/{{ name }}-tests/{{ arch }}/" $build_flags
|
||||
keyctl session - make -C "${testdir}/{{ name }}-tests/{{ arch }}/" check
|
||||
|
|
@ -5,9 +5,9 @@ After=syslog.target network.target network-online.target
|
|||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=/var/run/krb5kdc.pid
|
||||
PIDFile=/run/krb5kdc.pid
|
||||
EnvironmentFile=-/etc/sysconfig/krb5kdc
|
||||
ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS
|
||||
ExecStart=/usr/sbin/krb5kdc -P /run/krb5kdc.pid $KRB5KDC_ARGS
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
|
|
|
|||
5
plans/tests.fmf
Normal file
5
plans/tests.fmf
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
summary: Tests
|
||||
discover:
|
||||
how: fmf
|
||||
execute:
|
||||
how: tmt
|
||||
17
rpminspect.yaml
Normal file
17
rpminspect.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
inspections:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1956479
|
||||
badfuncs: off
|
||||
|
||||
# Not a Java package
|
||||
javabytecode: off
|
||||
|
||||
# I need to be able to *add* functions, and also we export internal
|
||||
# functions that are not considered part of our ABI.
|
||||
abidiff: off
|
||||
|
||||
# These just flag when things change "too much"
|
||||
changedfiles: off
|
||||
filesize: off
|
||||
patches: off
|
||||
upstream: off
|
||||
4
sources
4
sources
|
|
@ -1,2 +1,2 @@
|
|||
SHA512 (krb5-1.18.2.tar.gz) = 7cbb1b28e677fea3e0794e93951f3caaa2c49bb1175dd187951e72a466cc69d96c3b833d838000fe911c1a437d96a558e550f27c53a8b332fb9dfc7cbb7ec44c
|
||||
SHA512 (krb5-1.18.2.tar.gz.asc) = 70775a06104b4d792d278da2efa92e94ddacb4ea319bfe2b253f5afcfec27f3bc5ddd12560294a265e3cf3d4fc74bcbfc3f5eeff8634d66c00d67e18dc93a74a
|
||||
SHA512 (krb5-1.21.3.tar.gz) = 87bc06607f4d95ff604169cea22180703a42d667af05f66f1569b8bd592670c42820b335e5c279e8b4f066d1e7da20f1948a1e4def7c5d295c170cbfc7f49c71
|
||||
SHA512 (krb5-1.21.3.tar.gz.asc) = 8992a5f5247315b9846aa73be4ee1ea223c0231a52d5c6c28718b1f3e3b45d62e2dad4aa5543a83163d1369bb79886b6c1c22766f22d8aa2f6b2575c54d0075c
|
||||
|
|
|
|||
2
tests/got-audit/got-audit.gdb
Normal file
2
tests/got-audit/got-audit.gdb
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
gef config gef.disable_color True
|
||||
got-audit --all
|
||||
12
tests/got-audit/kdc.conf
Normal file
12
tests/got-audit/kdc.conf
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[kdcdefaults]
|
||||
kdc_ports = 88
|
||||
kdc_tcp_ports = 88
|
||||
|
||||
[realms]
|
||||
${krb5REALM1} = {
|
||||
#master_key_type = aes256-cts
|
||||
acl_file = /var/kerberos/krb5kdc/kadm5.acl
|
||||
dict_file = /usr/share/dict/words
|
||||
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
|
||||
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
|
||||
}
|
||||
29
tests/got-audit/krb5.conf
Normal file
29
tests/got-audit/krb5.conf
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# To opt out of the system crypto-policies configuration of krb5, remove the
|
||||
# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
|
||||
includedir /etc/krb5.conf.d/
|
||||
|
||||
[logging]
|
||||
default = FILE:/var/log/krb5libs.log
|
||||
kdc = FILE:/var/log/krb5kdc.log
|
||||
admin_server = FILE:/var/log/kadmind.log
|
||||
|
||||
[libdefaults]
|
||||
default_realm = ${krb5REALM1}
|
||||
dns_lookup_realm = false
|
||||
ticket_lifetime = 24h
|
||||
renew_lifetime = 7d
|
||||
forwardable = true
|
||||
rdns = false
|
||||
default_ccache_name = KEYRING:persistent:%{uid}
|
||||
|
||||
[realms]
|
||||
${krb5REALM1} = {
|
||||
kdc = localhost.localdomain
|
||||
admin_server = localhost.localdomain
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
${krb5HostName} = ${krb5REALM1}
|
||||
|
||||
[capaths]
|
||||
${krb5REALM1} = .
|
||||
12
tests/got-audit/main.fmf
Normal file
12
tests/got-audit/main.fmf
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
summary: Audit the GOT for signs of tampering
|
||||
description: |
|
||||
Pointers in the server process GOT will be checked to ensure that
|
||||
each function pointer's value is within a shared object file
|
||||
that exports a symbol of that name, and that no shared object
|
||||
files export conflicting symbols.
|
||||
contact: Gordon Messmer <gordon.messmer@gmail.com>
|
||||
require+:
|
||||
- gdb-gef # needed to test got-audit
|
||||
- krb5-server
|
||||
test: ./runtest.sh
|
||||
framework: beakerlib
|
||||
121
tests/got-audit/runtest.sh
Executable file
121
tests/got-audit/runtest.sh
Executable file
|
|
@ -0,0 +1,121 @@
|
|||
#!/bin/bash
|
||||
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# runtest.sh of /CoreOS/openssh/Sanity/got-audit
|
||||
# Description: Check pointers in the server process GOT for signs of tampering
|
||||
# Author: Gordon Messmer <gordon.messmer@gmail.com>
|
||||
#
|
||||
|
||||
# Include Beaker environment
|
||||
. /usr/share/beakerlib/beakerlib.sh || exit 1
|
||||
|
||||
krb5REALM1='TEST1.REDHAT.COM'
|
||||
krb5HostName=`hostname`
|
||||
krb5DomainName=`hostname -d`
|
||||
krb5User='alice'
|
||||
krb5UserPass='alice'
|
||||
krb5UserKrbPass='aaa'
|
||||
krb5User2='bob'
|
||||
krb5User3='carl'
|
||||
krb5KDCPass='qwe'
|
||||
krb5RootPass='rrr'
|
||||
|
||||
krb5conf="/etc/krb5.conf"
|
||||
krb5confdir="/etc/krb5.conf.d"
|
||||
krb5kdcconf="/var/kerberos/krb5kdc/kdc.conf"
|
||||
krb5kadmacl="/var/kerberos/krb5kdc/kadm5.acl"
|
||||
|
||||
rlJournalStart
|
||||
rlPhaseStartSetup
|
||||
rlServiceStart sshd
|
||||
rlRun "TestDir=\$(pwd)"
|
||||
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
|
||||
rlRun "pushd $TmpDir"
|
||||
rlRun "auditfile=\$(mktemp --tmpdir=${TmpDir})"
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartSetup "KDC and kadmind setup"
|
||||
# Stop and backup
|
||||
rlRun "rlServiceStop kadmin krb5kdc"
|
||||
rlRun "rm -f /var/kerberos/krb5kdc/principal* /var/kerberos/krb5kdc/.k5*"
|
||||
rlFileBackup $krb5conf /var/kerberos/krb5kdc /etc/sysconfig/{kadmin,krb5kdc} /etc/hosts
|
||||
rlFileBackup --clean /root/.k5login
|
||||
[ -e /etc/krb5.keytab ] && rlFileBackup /etc/krb5.keytab
|
||||
[ -e $krb5confdir ] && rlFileBackup $krb5confdir
|
||||
# Basic setup of KDC and krb5.conf
|
||||
rlRun "sed -i \"s/\[libdefaults\]/[libdefaults]\n default_realm = $krb5REALM1/\" $krb5conf"
|
||||
rlRun "sed -i \"s/\[realms\]/[realms]\n $krb5REALM1 = {\n kdc = $krb5HostName\n admin_server = $krb5HostName\n }/\" $krb5conf"
|
||||
if [ "$krb5DomainName" ]; then
|
||||
rlRun "sed -i \"s/\[domain_realm\]/[domain_realm]\n .$krb5DomainName = $krb5REALM1\n $krb5DomainName = $krb5REALM1/\" $krb5conf"
|
||||
else
|
||||
rlRun "sed -i \"s/\[domain_realm\]/[domain_realm]\n $krb5HostName = $krb5REALM1/\" $krb5conf"
|
||||
fi
|
||||
rlRun "sed -i s/EXAMPLE.COM/$krb5REALM1/ $krb5kdcconf"
|
||||
# Configure the kadmin ACL
|
||||
rlRun "echo \"*/master@$krb5REALM1 *\" > $krb5kadmacl"
|
||||
if rlIsFedora '>=31';then
|
||||
rlLog "Modify supported_enctypes for Fedora >=31. Remove *DES ciphers."
|
||||
rlRun "sed -i \"s/supported_enctypes.*/supported_enctypes = aes256-cts:normal aes128-cts:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal/\" /var/kerberos/krb5kdc/kdc.conf"
|
||||
elif rlIsRHEL '8' && [ `rpm -q --qf '%{VERSION}' krb5-server | cut -d"." -f2` -lt 18 ];then
|
||||
rlLog "Modify supported_enctypes for RHEL-8."
|
||||
rlRun "sed -i \"s/supported_enctypes.*/supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal/\" /var/kerberos/krb5kdc/kdc.conf"
|
||||
else
|
||||
#RHEL-8 Bug 1802334 - [Rebase] krb5: rebase to 1.18:
|
||||
#- Removal of *DES encryption types
|
||||
#https://bugzilla.redhat.com/show_bug.cgi?id=1802334
|
||||
rlLog "Modify supported_enctypes for RHEL-8 with krb-1.18. Remove *DES ciphers."
|
||||
rlRun "sed -i \"s/supported_enctypes.*/supported_enctypes = aes256-cts:normal aes128-cts:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal/\" /var/kerberos/krb5kdc/kdc.conf"
|
||||
fi
|
||||
# Create the realm databases
|
||||
rlRun "rngd -r /dev/urandom"
|
||||
rlRun "kdb5_util create -s -r $krb5REALM1 -P $krb5KDCPass"
|
||||
rlRun "rlServiceStart kadmin krb5kdc"
|
||||
rlRun "kadmin.local -r $krb5REALM1 -q \"addprinc -pw $krb5RootPass root/master\""
|
||||
rlRun "kadmin.local -r $krb5REALM1 -q \"addprinc -pw $krb5UserKrbPass $krb5User\""
|
||||
rlRun "kadmin.local -r $krb5REALM1 -q \"addprinc -randkey host/$krb5HostName\""
|
||||
rlRun "kadmin.local -r $krb5REALM1 -q \"ktadd host/$krb5HostName\""
|
||||
# Create test system user
|
||||
[ $krb5User != "root" ] && rlRun "useradd $krb5User"
|
||||
rlRun "echo $krb5UserPass | passwd --stdin $krb5User"
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartTest "Run GEF got-audit"
|
||||
rlRun "systemctl restart krb5kdc.service"
|
||||
rlRun "systemctl restart kadmin.service"
|
||||
rlRun "systemctl --no-pager status krb5kdc.service"
|
||||
rlRun "systemctl --no-pager status kadmin.service"
|
||||
|
||||
rlRun "SERVICE_PID=\$( systemctl show --property=MainPID krb5kdc.service | cut -f2 -d= )"
|
||||
rlRun "echo SERVICE_PID is '$SERVICE_PID'"
|
||||
[ -n "$SERVICE_PID" ] || rlFail "No service pid was found"
|
||||
rlRun "gdb-gef --pid '$SERVICE_PID' --command='$TestDir'/got-audit.gdb --batch > '$auditfile'"
|
||||
# Basic test: ensure that at least one symbol is found in libc.so,
|
||||
# to verify that the report looks plausible.
|
||||
rlAssertGrep " : /.*/libc.so" "$auditfile"
|
||||
# Ensure the got-audit did not report any errors
|
||||
rlAssertNotGrep " :: ERROR" "$auditfile"
|
||||
rlRun "cp '$auditfile' '$TMT_TEST_DATA'/krb5kdc-got-audit.txt"
|
||||
|
||||
rlRun "SERVICE_PID=\$( systemctl show --property=MainPID kadmin.service | cut -f2 -d= )"
|
||||
rlRun "echo SERVICE_PID is '$SERVICE_PID'"
|
||||
[ -n "$SERVICE_PID" ] || rlFail "No service pid was found"
|
||||
rlRun "gdb-gef --pid '$SERVICE_PID' --command='$TestDir'/got-audit.gdb --batch > '$auditfile'"
|
||||
# Basic test: ensure that at least one symbol is found in libc.so,
|
||||
# to verify that the report looks plausible.
|
||||
rlAssertGrep " : /.*/libc.so" "$auditfile"
|
||||
# Ensure the got-audit did not report any errors
|
||||
rlAssertNotGrep " :: ERROR" "$auditfile"
|
||||
rlRun "cp '$auditfile' '$TMT_TEST_DATA'/kadmin-got-audit.txt"
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartCleanup
|
||||
rlRun "rm -rf /var/kerberos/krb5kdc/* /var/kerberos/krb5kdc/.k5* /etc/krb5* /etc/sysconfig/{kadmin,krb5kdc}"
|
||||
rlFileRestore
|
||||
rlServiceRestore krb5kdc kadmin
|
||||
[ $krb5User != "root" ] && rlRun "userdel -r -f $krb5User"
|
||||
rlRun "popd"
|
||||
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
|
||||
rlPhaseEnd
|
||||
rlJournalPrintText
|
||||
rlJournalEnd
|
||||
|
|
@ -55,6 +55,7 @@ $(METADATA): Makefile
|
|||
@echo "TestTime: 20m" >> $(METADATA)
|
||||
@echo "RunFor: krb5" >> $(METADATA)
|
||||
@echo "Requires: expect krb5-server krb5-workstation openssh-clients openssh-server rng-tools" >> $(METADATA)
|
||||
@echo "Requires: setools-console" >> $(METADATA)
|
||||
@echo "Priority: Normal" >> $(METADATA)
|
||||
@echo "License: GPLv2" >> $(METADATA)
|
||||
@echo "Confidential: no" >> $(METADATA)
|
||||
21
tests/inplace-upgrade-sanity/TC#0378369.fmf
Normal file
21
tests/inplace-upgrade-sanity/TC#0378369.fmf
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
tag:
|
||||
- CI-Tier-1
|
||||
- CI-Tier-1-krb5
|
||||
- Fedora 31
|
||||
- Fedora 32
|
||||
- FedoraReady
|
||||
- IDM-CI-gating
|
||||
- NoRHEL4
|
||||
- NoRHEL5
|
||||
- TIPpass
|
||||
- TIPpass_Security
|
||||
- Tier1
|
||||
- Tier1security
|
||||
- rhel_upgrade
|
||||
tier: '1'
|
||||
adjust:
|
||||
- enabled: false
|
||||
when: distro == rhel-4, rhel-5
|
||||
continue: false
|
||||
extra-nitrate: TC#0378369
|
||||
extra-summary: /CoreOS/krb5/Sanity/inplace-upgrade-sanity-test
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue