Toshaan Bharvani
2 years ago
commit
1e31c3d5ea
51 changed files with 21184 additions and 0 deletions
@ -0,0 +1,220 @@
@@ -0,0 +1,220 @@
|
||||
From 3d11179707923b033fa413387a33296b673ff52d Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Thu, 14 Jan 2021 18:13:09 -0500 |
||||
Subject: [PATCH] Add APIs for marshalling credentials |
||||
|
||||
Faciliate KCM daemon implementations by providing functions to |
||||
deserialize and reserialize credentials in the FILE v4 format. |
||||
|
||||
[ghudson@mit.edu: minor editorial changes] |
||||
|
||||
ticket: 8980 (new) |
||||
(cherry picked from commit 18ea3bd2fca55b789b7de9c663624bc11d348fa6) |
||||
--- |
||||
doc/appdev/refs/api/index.rst | 2 ++ |
||||
src/include/krb5/krb5.hin | 36 ++++++++++++++++++++++ |
||||
src/lib/krb5/ccache/ccmarshal.c | 53 +++++++++++++++++++++++++++++++++ |
||||
src/lib/krb5/ccache/t_marshal.c | 15 +++++++++- |
||||
src/lib/krb5/libkrb5.exports | 2 ++ |
||||
src/lib/krb5_32.def | 4 +++ |
||||
6 files changed, 111 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst |
||||
index 727d9b492..9e03fd386 100644 |
||||
--- a/doc/appdev/refs/api/index.rst |
||||
+++ b/doc/appdev/refs/api/index.rst |
||||
@@ -232,6 +232,7 @@ Rarely used public interfaces |
||||
krb5_kt_remove_entry.rst |
||||
krb5_kt_start_seq_get.rst |
||||
krb5_make_authdata_kdc_issued.rst |
||||
+ krb5_marshal_credentials.rst |
||||
krb5_merge_authdata.rst |
||||
krb5_mk_1cred.rst |
||||
krb5_mk_error.rst |
||||
@@ -285,6 +286,7 @@ Rarely used public interfaces |
||||
krb5_tkt_creds_get_times.rst |
||||
krb5_tkt_creds_init.rst |
||||
krb5_tkt_creds_step.rst |
||||
+ krb5_unmarshal_credentials.rst |
||||
krb5_verify_init_creds.rst |
||||
krb5_verify_init_creds_opt_init.rst |
||||
krb5_verify_init_creds_opt_set_ap_req_nofail.rst |
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin |
||||
index 63e67a2ba..c26dde535 100644 |
||||
--- a/src/include/krb5/krb5.hin |
||||
+++ b/src/include/krb5/krb5.hin |
||||
@@ -3125,6 +3125,42 @@ krb5_get_credentials(krb5_context context, krb5_flags options, |
||||
krb5_ccache ccache, krb5_creds *in_creds, |
||||
krb5_creds **out_creds); |
||||
|
||||
+/** |
||||
+ * Serialize a @c krb5_creds object. |
||||
+ * |
||||
+ * @param [in] context Library context |
||||
+ * @param [in] creds The credentials object to serialize |
||||
+ * @param [out] data_out The serialized credentials |
||||
+ * |
||||
+ * Serialize @a creds in the format used by the FILE ccache format (vesion 4) |
||||
+ * and KCM ccache protocol. |
||||
+ * |
||||
+ * Use krb5_free_data() to free @a data_out when it is no longer needed. |
||||
+ * |
||||
+ * @retval 0 Success; otherwise - Kerberos error codes |
||||
+ */ |
||||
+krb5_error_code KRB5_CALLCONV |
||||
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds, |
||||
+ krb5_data **data_out); |
||||
+ |
||||
+/** |
||||
+ * Deserialize a @c krb5_creds object. |
||||
+ * |
||||
+ * @param [in] context Library context |
||||
+ * @param [in] data The serialized credentials |
||||
+ * @param [out] creds_out The resulting creds object |
||||
+ * |
||||
+ * Deserialize @a data to credentials in the format used by the FILE ccache |
||||
+ * format (vesion 4) and KCM ccache protocol. |
||||
+ * |
||||
+ * Use krb5_free_creds() to free @a creds_out when it is no longer needed. |
||||
+ * |
||||
+ * @retval 0 Success; otherwise - Kerberos error codes |
||||
+ */ |
||||
+krb5_error_code KRB5_CALLCONV |
||||
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data, |
||||
+ krb5_creds **creds_out); |
||||
+ |
||||
/** @deprecated Replaced by krb5_get_validated_creds. */ |
||||
krb5_error_code KRB5_CALLCONV |
||||
krb5_get_credentials_validate(krb5_context context, krb5_flags options, |
||||
diff --git a/src/lib/krb5/ccache/ccmarshal.c b/src/lib/krb5/ccache/ccmarshal.c |
||||
index ae634ccab..ab284e721 100644 |
||||
--- a/src/lib/krb5/ccache/ccmarshal.c |
||||
+++ b/src/lib/krb5/ccache/ccmarshal.c |
||||
@@ -515,3 +515,56 @@ k5_marshal_mcred(struct k5buf *buf, krb5_creds *mcred) |
||||
if (mcred->second_ticket.length > 0) |
||||
put_data(buf, version, &mcred->second_ticket); |
||||
} |
||||
+ |
||||
+krb5_error_code KRB5_CALLCONV |
||||
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds, |
||||
+ krb5_data **data_out) |
||||
+{ |
||||
+ krb5_error_code ret; |
||||
+ krb5_data *data; |
||||
+ struct k5buf buf; |
||||
+ |
||||
+ *data_out = NULL; |
||||
+ |
||||
+ data = k5alloc(sizeof(krb5_data), &ret); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
+ k5_buf_init_dynamic(&buf); |
||||
+ k5_marshal_cred(&buf, 4, in_creds); |
||||
+ |
||||
+ ret = k5_buf_status(&buf); |
||||
+ if (ret) { |
||||
+ free(data); |
||||
+ return ret; |
||||
+ } |
||||
+ |
||||
+ /* Steal payload from buf. */ |
||||
+ *data = make_data(buf.data, buf.len); |
||||
+ *data_out = data; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+krb5_error_code KRB5_CALLCONV |
||||
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data, |
||||
+ krb5_creds **creds_out) |
||||
+{ |
||||
+ krb5_error_code ret; |
||||
+ krb5_creds *creds; |
||||
+ |
||||
+ *creds_out = NULL; |
||||
+ |
||||
+ creds = k5alloc(sizeof(krb5_creds), &ret); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
+ ret = k5_unmarshal_cred((unsigned char *)data->data, data->length, 4, |
||||
+ creds); |
||||
+ if (ret) { |
||||
+ free(creds); |
||||
+ return ret; |
||||
+ } |
||||
+ |
||||
+ *creds_out = creds; |
||||
+ return 0; |
||||
+} |
||||
diff --git a/src/lib/krb5/ccache/t_marshal.c b/src/lib/krb5/ccache/t_marshal.c |
||||
index bd0284afa..96e0931a2 100644 |
||||
--- a/src/lib/krb5/ccache/t_marshal.c |
||||
+++ b/src/lib/krb5/ccache/t_marshal.c |
||||
@@ -268,13 +268,14 @@ main(int argc, char **argv) |
||||
krb5_context context; |
||||
krb5_ccache cache; |
||||
krb5_principal princ; |
||||
- krb5_creds cred1, cred2; |
||||
+ krb5_creds cred1, cred2, *alloc_cred; |
||||
krb5_cc_cursor cursor; |
||||
const char *filename; |
||||
char *ccname, filebuf[256]; |
||||
int version, fd; |
||||
const struct test *t; |
||||
struct k5buf buf; |
||||
+ krb5_data ser_data, *alloc_data; |
||||
|
||||
if (argc != 2) |
||||
abort(); |
||||
@@ -285,6 +286,18 @@ main(int argc, char **argv) |
||||
if (krb5_init_context(&context) != 0) |
||||
abort(); |
||||
|
||||
+ /* Test public functions for unmarshalling and marshalling. */ |
||||
+ ser_data = make_data((char *)tests[3].cred1, tests[3].cred1len); |
||||
+ if (krb5_unmarshal_credentials(context, &ser_data, &alloc_cred) != 0) |
||||
+ abort(); |
||||
+ verify_cred1(alloc_cred); |
||||
+ if (krb5_marshal_credentials(context, alloc_cred, &alloc_data) != 0) |
||||
+ abort(); |
||||
+ assert(alloc_data->length == tests[3].cred1len); |
||||
+ assert(memcmp(tests[3].cred1, alloc_data->data, alloc_data->length) == 0); |
||||
+ krb5_free_data(context, alloc_data); |
||||
+ krb5_free_creds(context, alloc_cred); |
||||
+ |
||||
for (version = FIRST_VERSION; version <= 4; version++) { |
||||
t = &tests[version - 1]; |
||||
|
||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports |
||||
index 2d9d56530..adbfa332b 100644 |
||||
--- a/src/lib/krb5/libkrb5.exports |
||||
+++ b/src/lib/krb5/libkrb5.exports |
||||
@@ -489,6 +489,7 @@ krb5_lock_file |
||||
krb5_make_authdata_kdc_issued |
||||
krb5_make_full_ipaddr |
||||
krb5_make_fulladdr |
||||
+krb5_marshal_credentials |
||||
krb5_mcc_ops |
||||
krb5_merge_authdata |
||||
krb5_mk_1cred |
||||
@@ -592,6 +593,7 @@ krb5_timeofday |
||||
krb5_timestamp_to_sfstring |
||||
krb5_timestamp_to_string |
||||
krb5_unlock_file |
||||
+krb5_unmarshal_credentials |
||||
krb5_unpack_full_ipaddr |
||||
krb5_unparse_name |
||||
krb5_unparse_name_ext |
||||
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def |
||||
index 4953907aa..60b8dd311 100644 |
||||
--- a/src/lib/krb5_32.def |
||||
+++ b/src/lib/krb5_32.def |
||||
@@ -503,3 +503,7 @@ EXPORTS |
||||
; new in 1.19 |
||||
k5_cc_store_primary_cred @470 ; PRIVATE |
||||
k5_kt_have_match @471 ; PRIVATE GSSAPI |
||||
+ |
||||
+; new in 1.20 |
||||
+ krb5_marshal_credentials @472 |
||||
+ krb5_unmarshal_credentials @473 |
@ -0,0 +1,359 @@
@@ -0,0 +1,359 @@
|
||||
From 418e64100d1e3f8c8e3f773909347bad270a2921 Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com> |
||||
Date: Thu, 11 Feb 2021 15:33:10 +0100 |
||||
Subject: [PATCH] Add KCM_OP_GET_CRED_LIST for faster iteration |
||||
|
||||
For large caches, one IPC operation per credential dominates the cost |
||||
of iteration. Instead transfer the whole list of credentials to the |
||||
client in one IPC operation. |
||||
|
||||
Add optional support for the new opcode to the test KCM server to |
||||
allow testing of the main and fallback code paths. |
||||
|
||||
[ghudson@mit.edu: fixed memory leaks and potential memory errors; |
||||
adjusted code style and comments; rewrote commit message; added |
||||
kcmserver.py support and tests] |
||||
|
||||
ticket: 8990 (new) |
||||
(cherry picked from commit 81bdb47d8ded390263d8ee48f71d5c312b4f1736) |
||||
(cherry picked from commit a0ee8b02e56c65e5dcd569caed0e151cef004ef4) |
||||
--- |
||||
src/include/kcm.h | 12 ++- |
||||
src/lib/krb5/ccache/cc_kcm.c | 144 ++++++++++++++++++++++++++++++++--- |
||||
src/tests/kcmserver.py | 28 ++++++- |
||||
src/tests/t_ccache.py | 10 ++- |
||||
4 files changed, 175 insertions(+), 19 deletions(-) |
||||
|
||||
diff --git a/src/include/kcm.h b/src/include/kcm.h |
||||
index 5ea1447cd..e4140c3a0 100644 |
||||
--- a/src/include/kcm.h |
||||
+++ b/src/include/kcm.h |
||||
@@ -51,9 +51,9 @@ |
||||
* |
||||
* All replies begin with a 32-bit big-endian reply code. |
||||
* |
||||
- * Parameters are appended to the request or reply with no delimiters. Flags |
||||
- * and time offsets are stored as 32-bit big-endian integers. Names are |
||||
- * marshalled as zero-terminated strings. Principals and credentials are |
||||
+ * Parameters are appended to the request or reply with no delimiters. Flags, |
||||
+ * time offsets, and lengths are stored as 32-bit big-endian integers. Names |
||||
+ * are marshalled as zero-terminated strings. Principals and credentials are |
||||
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists |
||||
* are not delimited, so nothing can come after them. |
||||
*/ |
||||
@@ -89,7 +89,11 @@ typedef enum kcm_opcode { |
||||
KCM_OP_HAVE_NTLM_CRED, |
||||
KCM_OP_DEL_NTLM_CRED, |
||||
KCM_OP_DO_NTLM_AUTH, |
||||
- KCM_OP_GET_NTLM_USER_LIST |
||||
+ KCM_OP_GET_NTLM_USER_LIST, |
||||
+ |
||||
+ /* MIT extensions */ |
||||
+ KCM_OP_MIT_EXTENSION_BASE = 13000, |
||||
+ KCM_OP_GET_CRED_LIST, /* (name) -> (count, count*{len, cred}) */ |
||||
} kcm_opcode; |
||||
|
||||
#endif /* KCM_H */ |
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c |
||||
index 9093f894d..772928e4d 100644 |
||||
--- a/src/lib/krb5/ccache/cc_kcm.c |
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c |
||||
@@ -61,6 +61,17 @@ struct uuid_list { |
||||
size_t pos; |
||||
}; |
||||
|
||||
+struct cred_list { |
||||
+ krb5_creds *creds; |
||||
+ size_t count; |
||||
+ size_t pos; |
||||
+}; |
||||
+ |
||||
+struct kcm_cursor { |
||||
+ struct uuid_list *uuids; |
||||
+ struct cred_list *creds; |
||||
+}; |
||||
+ |
||||
struct kcmio { |
||||
SOCKET fd; |
||||
#ifdef __APPLE__ |
||||
@@ -489,6 +500,69 @@ free_uuid_list(struct uuid_list *uuids) |
||||
free(uuids); |
||||
} |
||||
|
||||
+static void |
||||
+free_cred_list(struct cred_list *list) |
||||
+{ |
||||
+ size_t i; |
||||
+ |
||||
+ if (list == NULL) |
||||
+ return; |
||||
+ |
||||
+ /* Creds are transferred to the caller as list->pos is incremented, so we |
||||
+ * can start freeing there. */ |
||||
+ for (i = list->pos; i < list->count; i++) |
||||
+ krb5_free_cred_contents(NULL, &list->creds[i]); |
||||
+ free(list->creds); |
||||
+ free(list); |
||||
+} |
||||
+ |
||||
+/* Fetch a cred list from req->reply. */ |
||||
+static krb5_error_code |
||||
+kcmreq_get_cred_list(struct kcmreq *req, struct cred_list **creds_out) |
||||
+{ |
||||
+ struct cred_list *list; |
||||
+ const unsigned char *data; |
||||
+ krb5_error_code ret = 0; |
||||
+ size_t count, len, i; |
||||
+ |
||||
+ *creds_out = NULL; |
||||
+ |
||||
+ /* Check a rough bound on the count to prevent very large allocations. */ |
||||
+ count = k5_input_get_uint32_be(&req->reply); |
||||
+ if (count > req->reply.len / 4) |
||||
+ return KRB5_KCM_MALFORMED_REPLY; |
||||
+ |
||||
+ list = malloc(sizeof(*list)); |
||||
+ if (list == NULL) |
||||
+ return ENOMEM; |
||||
+ |
||||
+ list->creds = NULL; |
||||
+ list->count = count; |
||||
+ list->pos = 0; |
||||
+ list->creds = k5calloc(count, sizeof(*list->creds), &ret); |
||||
+ if (list->creds == NULL) { |
||||
+ free(list); |
||||
+ return ret; |
||||
+ } |
||||
+ |
||||
+ for (i = 0; i < count; i++) { |
||||
+ len = k5_input_get_uint32_be(&req->reply); |
||||
+ data = k5_input_get_bytes(&req->reply, len); |
||||
+ if (data == NULL) |
||||
+ break; |
||||
+ ret = k5_unmarshal_cred(data, len, 4, &list->creds[i]); |
||||
+ if (ret) |
||||
+ break; |
||||
+ } |
||||
+ if (i < count) { |
||||
+ free_cred_list(list); |
||||
+ return (ret == ENOMEM) ? ENOMEM : KRB5_KCM_MALFORMED_REPLY; |
||||
+ } |
||||
+ |
||||
+ *creds_out = list; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
static void |
||||
kcmreq_free(struct kcmreq *req) |
||||
{ |
||||
@@ -753,33 +827,53 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache, |
||||
{ |
||||
krb5_error_code ret; |
||||
struct kcmreq req = EMPTY_KCMREQ; |
||||
- struct uuid_list *uuids; |
||||
+ struct uuid_list *uuids = NULL; |
||||
+ struct cred_list *creds = NULL; |
||||
+ struct kcm_cursor *cursor; |
||||
|
||||
*cursor_out = NULL; |
||||
|
||||
get_kdc_offset(context, cache); |
||||
|
||||
- kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache); |
||||
+ kcmreq_init(&req, KCM_OP_GET_CRED_LIST, cache); |
||||
ret = cache_call(context, cache, &req); |
||||
- if (ret) |
||||
+ if (ret == 0) { |
||||
+ /* GET_CRED_LIST is available. */ |
||||
+ ret = kcmreq_get_cred_list(&req, &creds); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ } else if (ret == KRB5_FCC_INTERNAL) { |
||||
+ /* Fall back to GET_CRED_UUID_LIST. */ |
||||
+ kcmreq_free(&req); |
||||
+ kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache); |
||||
+ ret = cache_call(context, cache, &req); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ ret = kcmreq_get_uuid_list(&req, &uuids); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ } else { |
||||
goto cleanup; |
||||
- ret = kcmreq_get_uuid_list(&req, &uuids); |
||||
- if (ret) |
||||
+ } |
||||
+ |
||||
+ cursor = k5alloc(sizeof(*cursor), &ret); |
||||
+ if (cursor == NULL) |
||||
goto cleanup; |
||||
- *cursor_out = (krb5_cc_cursor)uuids; |
||||
+ cursor->uuids = uuids; |
||||
+ cursor->creds = creds; |
||||
+ *cursor_out = (krb5_cc_cursor)cursor; |
||||
|
||||
cleanup: |
||||
kcmreq_free(&req); |
||||
return ret; |
||||
} |
||||
|
||||
-static krb5_error_code KRB5_CALLCONV |
||||
-kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, |
||||
- krb5_creds *cred_out) |
||||
+static krb5_error_code |
||||
+next_cred_by_uuid(krb5_context context, krb5_ccache cache, |
||||
+ struct uuid_list *uuids, krb5_creds *cred_out) |
||||
{ |
||||
krb5_error_code ret; |
||||
struct kcmreq req; |
||||
- struct uuid_list *uuids = (struct uuid_list *)*cursor; |
||||
|
||||
memset(cred_out, 0, sizeof(*cred_out)); |
||||
|
||||
@@ -797,11 +891,39 @@ kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, |
||||
return map_invalid(ret); |
||||
} |
||||
|
||||
+static krb5_error_code KRB5_CALLCONV |
||||
+kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, |
||||
+ krb5_creds *cred_out) |
||||
+{ |
||||
+ struct kcm_cursor *c = (struct kcm_cursor *)*cursor; |
||||
+ struct cred_list *list; |
||||
+ |
||||
+ if (c->uuids != NULL) |
||||
+ return next_cred_by_uuid(context, cache, c->uuids, cred_out); |
||||
+ |
||||
+ list = c->creds; |
||||
+ if (list->pos >= list->count) |
||||
+ return KRB5_CC_END; |
||||
+ |
||||
+ /* Transfer memory ownership of one cred to the caller. */ |
||||
+ *cred_out = list->creds[list->pos]; |
||||
+ memset(&list->creds[list->pos], 0, sizeof(*list->creds)); |
||||
+ list->pos++; |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
static krb5_error_code KRB5_CALLCONV |
||||
kcm_end_seq_get(krb5_context context, krb5_ccache cache, |
||||
krb5_cc_cursor *cursor) |
||||
{ |
||||
- free_uuid_list((struct uuid_list *)*cursor); |
||||
+ struct kcm_cursor *c = *cursor; |
||||
+ |
||||
+ if (c == NULL) |
||||
+ return 0; |
||||
+ free_uuid_list(c->uuids); |
||||
+ free_cred_list(c->creds); |
||||
+ free(c); |
||||
*cursor = NULL; |
||||
return 0; |
||||
} |
||||
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py |
||||
index 57432e5a7..8c5e66ff1 100644 |
||||
--- a/src/tests/kcmserver.py |
||||
+++ b/src/tests/kcmserver.py |
||||
@@ -23,6 +23,7 @@ |
||||
# traceback.print_exception(etype, value, tb, file=f) |
||||
# sys.excepthook = ehook |
||||
|
||||
+import optparse |
||||
import select |
||||
import socket |
||||
import struct |
||||
@@ -49,12 +50,14 @@ class KCMOpcodes(object): |
||||
SET_DEFAULT_CACHE = 21 |
||||
GET_KDC_OFFSET = 22 |
||||
SET_KDC_OFFSET = 23 |
||||
+ GET_CRED_LIST = 13001 |
||||
|
||||
|
||||
class KRB5Errors(object): |
||||
KRB5_CC_END = -1765328242 |
||||
KRB5_CC_NOSUPP = -1765328137 |
||||
KRB5_FCC_NOFILE = -1765328189 |
||||
+ KRB5_FCC_INTERNAL = -1765328188 |
||||
|
||||
|
||||
def make_uuid(): |
||||
@@ -183,6 +186,14 @@ def op_set_kdc_offset(argbytes): |
||||
return 0, b'' |
||||
|
||||
|
||||
+def op_get_cred_list(argbytes): |
||||
+ name, rest = unmarshal_name(argbytes) |
||||
+ cache = get_cache(name) |
||||
+ creds = [cache.creds[u] for u in cache.cred_uuids] |
||||
+ return 0, (struct.pack('>L', len(creds)) + |
||||
+ b''.join(struct.pack('>L', len(c)) + c for c in creds)) |
||||
+ |
||||
+ |
||||
ophandlers = { |
||||
KCMOpcodes.GEN_NEW : op_gen_new, |
||||
KCMOpcodes.INITIALIZE : op_initialize, |
||||
@@ -197,7 +208,8 @@ ophandlers = { |
||||
KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache, |
||||
KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache, |
||||
KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset, |
||||
- KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset |
||||
+ KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset, |
||||
+ KCMOpcodes.GET_CRED_LIST : op_get_cred_list |
||||
} |
||||
|
||||
# Read and respond to a request from the socket s. |
||||
@@ -215,7 +227,11 @@ def service_request(s): |
||||
|
||||
majver, minver, op = struct.unpack('>BBH', req[:4]) |
||||
argbytes = req[4:] |
||||
- code, payload = ophandlers[op](argbytes) |
||||
+ |
||||
+ if op in ophandlers: |
||||
+ code, payload = ophandlers[op](argbytes) |
||||
+ else: |
||||
+ code, payload = KRB5Errors.KRB5_FCC_INTERNAL, b'' |
||||
|
||||
# The KCM response is the code (4 bytes) and the response payload. |
||||
# The Heimdal IPC response is the length of the KCM response (4 |
||||
@@ -226,9 +242,15 @@ def service_request(s): |
||||
s.sendall(hipc_response) |
||||
return True |
||||
|
||||
+parser = optparse.OptionParser() |
||||
+parser.add_option('-c', '--credlist', action='store_true', dest='credlist', |
||||
+ default=False, help='Support KCM_OP_GET_CRED_LIST') |
||||
+(options, args) = parser.parse_args() |
||||
+if not options.credlist: |
||||
+ del ophandlers[KCMOpcodes.GET_CRED_LIST] |
||||
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) |
||||
-server.bind(sys.argv[1]) |
||||
+server.bind(args[0]) |
||||
server.listen(5) |
||||
select_input = [server,] |
||||
sys.stderr.write('starting...\n') |
||||
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py |
||||
index 66804afa5..90040fb7b 100755 |
||||
--- a/src/tests/t_ccache.py |
||||
+++ b/src/tests/t_ccache.py |
||||
@@ -125,10 +125,18 @@ def collection_test(realm, ccname): |
||||
|
||||
|
||||
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc')) |
||||
+ |
||||
+# Test KCM without and with GET_CRED_LIST support. |
||||
kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py') |
||||
-realm.start_server([sys.executable, kcmserver_path, kcm_socket_path], |
||||
+kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path], |
||||
+ 'starting...') |
||||
+collection_test(realm, 'KCM:') |
||||
+stop_daemon(kcmd) |
||||
+os.remove(kcm_socket_path) |
||||
+realm.start_server([sys.executable, kcmserver_path, '-c', kcm_socket_path], |
||||
'starting...') |
||||
collection_test(realm, 'KCM:') |
||||
+ |
||||
if test_keyring: |
||||
def cleanup_keyring(anchor, name): |
||||
out = realm.run(['keyctl', 'list', anchor]) |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
From 2f039fc910022c9569fe6941a194f0b26bd6c894 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 20 Sep 2019 16:11:29 -0400 |
||||
Subject: [PATCH] Add buildsystem detection of the OpenSSL-3 KDF interface |
||||
|
||||
(cherry picked from commit a3e03dfd40928c4615bd9b8546eac0c104377850) |
||||
--- |
||||
src/configure.ac | 4 ++++ |
||||
1 file changed, 4 insertions(+) |
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac |
||||
index eb6307468..9c2e816fe 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) |
||||
|
||||
+if test "$CRYPTO_IMPL" = openssl; then |
||||
+ AC_CHECK_FUNCS(EVP_KDF_fetch) |
||||
+fi |
||||
+ |
||||
AC_ARG_WITH([prng-alg], |
||||
AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]), |
||||
[PRNG_ALG=$withval |
@ -0,0 +1,201 @@
@@ -0,0 +1,201 @@
|
||||
From 2a6a4568ed1df4ed89604b09fa11785c9ae38c67 Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Fri, 22 Apr 2022 14:12:37 +0200 |
||||
Subject: [PATCH] Add configure variable for default PKCS#11 module |
||||
|
||||
[ghudson@mit.edu: added documentation of configure variable and doc |
||||
substitution; shortened commit message] |
||||
|
||||
ticket: 9058 (new) |
||||
--- |
||||
doc/admin/conf_files/krb5_conf.rst | 2 +- |
||||
doc/build/options2configure.rst | 3 +++ |
||||
doc/conf.py | 3 +++ |
||||
doc/mitK5defaults.rst | 25 +++++++++++++------------ |
||||
src/configure.ac | 8 ++++++++ |
||||
src/doc/Makefile.in | 2 ++ |
||||
src/man/Makefile.in | 4 +++- |
||||
src/man/krb5.conf.man | 2 +- |
||||
src/plugins/preauth/pkinit/pkinit.h | 1 - |
||||
9 files changed, 34 insertions(+), 16 deletions(-) |
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst |
||||
index adba8238d..3d25c9a12 100644 |
||||
--- a/doc/admin/conf_files/krb5_conf.rst |
||||
+++ b/doc/admin/conf_files/krb5_conf.rst |
||||
@@ -1020,7 +1020,7 @@ information for PKINIT is as follows: |
||||
All keyword/values are optional. *modname* specifies the location |
||||
of a library implementing PKCS #11. If a value is encountered |
||||
with no keyword, it is assumed to be the *modname*. If no |
||||
- module-name is specified, the default is ``opensc-pkcs11.so``. |
||||
+ module-name is specified, the default is |pkcs11_modname|. |
||||
``slotid=`` and/or ``token=`` may be specified to force the use of |
||||
a particular smard card reader or token if there is more than one |
||||
available. ``certid=`` and/or ``certlabel=`` may be specified to |
||||
diff --git a/doc/build/options2configure.rst b/doc/build/options2configure.rst |
||||
index a8959626d..8f8ac911c 100644 |
||||
--- a/doc/build/options2configure.rst |
||||
+++ b/doc/build/options2configure.rst |
||||
@@ -143,6 +143,9 @@ Environment variables |
||||
This option allows one to specify libraries to be passed to the |
||||
linker (e.g., ``-l<library>``) |
||||
|
||||
+**PKCS11_MODNAME=**\ *library* |
||||
+ Override the built-in default PKCS11 library name. |
||||
+ |
||||
**SS_LIB=**\ *libs*... |
||||
If ``-lss`` is not the correct way to link in your installed ss |
||||
library, for example if additional support libraries are needed, |
||||
diff --git a/doc/conf.py b/doc/conf.py |
||||
index 4fb6aae14..29fd53375 100644 |
||||
--- a/doc/conf.py |
||||
+++ b/doc/conf.py |
||||
@@ -235,6 +235,7 @@ if 'mansubs' in tags: |
||||
ccache = '``@CCNAME@``' |
||||
keytab = '``@KTNAME@``' |
||||
ckeytab = '``@CKTNAME@``' |
||||
+ pkcs11_modname = '``@PKCS11MOD@``' |
||||
elif 'pathsubs' in tags: |
||||
# Read configured paths from a file produced by the build system. |
||||
exec(open("paths.py").read()) |
||||
@@ -248,6 +249,7 @@ else: |
||||
ccache = ':ref:`DEFCCNAME <paths>`' |
||||
keytab = ':ref:`DEFKTNAME <paths>`' |
||||
ckeytab = ':ref:`DEFCKTNAME <paths>`' |
||||
+ pkcs11_modname = ':ref:`PKCS11_MODNAME <paths>`' |
||||
|
||||
rst_epilog = '\n' |
||||
|
||||
@@ -268,6 +270,7 @@ else: |
||||
rst_epilog += '.. |ccache| replace:: %s\n' % ccache |
||||
rst_epilog += '.. |keytab| replace:: %s\n' % keytab |
||||
rst_epilog += '.. |ckeytab| replace:: %s\n' % ckeytab |
||||
+ rst_epilog += '.. |pkcs11_modname| replace:: %s\n' % pkcs11_modname |
||||
rst_epilog += ''' |
||||
.. |krb5conf| replace:: ``/etc/krb5.conf`` |
||||
.. |defkeysalts| replace:: ``aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal`` |
||||
diff --git a/doc/mitK5defaults.rst b/doc/mitK5defaults.rst |
||||
index 74e69f4ad..aea7af3db 100644 |
||||
--- a/doc/mitK5defaults.rst |
||||
+++ b/doc/mitK5defaults.rst |
||||
@@ -59,18 +59,19 @@ subdirectories of ``/usr/local``. When MIT krb5 is integrated into an |
||||
operating system, the paths are generally chosen to match the |
||||
operating system's filesystem layout. |
||||
|
||||
-========================== ============= =========================== =========================== |
||||
-Description Symbolic name Custom build path Typical OS path |
||||
-========================== ============= =========================== =========================== |
||||
-User programs BINDIR ``/usr/local/bin`` ``/usr/bin`` |
||||
-Libraries and plugins LIBDIR ``/usr/local/lib`` ``/usr/lib`` |
||||
-Parent of KDC state dir LOCALSTATEDIR ``/usr/local/var`` ``/var`` |
||||
-Parent of KDC runtime dir RUNSTATEDIR ``/usr/local/var/run`` ``/run`` |
||||
-Administrative programs SBINDIR ``/usr/local/sbin`` ``/usr/sbin`` |
||||
-Alternate krb5.conf dir SYSCONFDIR ``/usr/local/etc`` ``/etc`` |
||||
-Default ccache name DEFCCNAME ``FILE:/tmp/krb5cc_%{uid}`` ``FILE:/tmp/krb5cc_%{uid}`` |
||||
-Default keytab name DEFKTNAME ``FILE:/etc/krb5.keytab`` ``FILE:/etc/krb5.keytab`` |
||||
-========================== ============= =========================== =========================== |
||||
+========================== ============== =========================== =========================== |
||||
+Description Symbolic name Custom build path Typical OS path |
||||
+========================== ============== =========================== =========================== |
||||
+User programs BINDIR ``/usr/local/bin`` ``/usr/bin`` |
||||
+Libraries and plugins LIBDIR ``/usr/local/lib`` ``/usr/lib`` |
||||
+Parent of KDC state dir LOCALSTATEDIR ``/usr/local/var`` ``/var`` |
||||
+Parent of KDC runtime dir RUNSTATEDIR ``/usr/local/var/run`` ``/run`` |
||||
+Administrative programs SBINDIR ``/usr/local/sbin`` ``/usr/sbin`` |
||||
+Alternate krb5.conf dir SYSCONFDIR ``/usr/local/etc`` ``/etc`` |
||||
+Default ccache name DEFCCNAME ``FILE:/tmp/krb5cc_%{uid}`` ``FILE:/tmp/krb5cc_%{uid}`` |
||||
+Default keytab name DEFKTNAME ``FILE:/etc/krb5.keytab`` ``FILE:/etc/krb5.keytab`` |
||||
+Default PKCS11 module PKCS11_MODNAME ``opensc-pkcs11.so`` ``opensc-pkcs11.so`` |
||||
+========================== ============== =========================== =========================== |
||||
|
||||
The default client keytab name (DEFCKTNAME) typically defaults to |
||||
``FILE:/usr/local/var/krb5/user/%{euid}/client.keytab`` for a custom |
||||
diff --git a/src/configure.ac b/src/configure.ac |
||||
index 363d5d62d..3a0633177 100644 |
||||
--- a/src/configure.ac |
||||
+++ b/src/configure.ac |
||||
@@ -1466,6 +1466,14 @@ AC_DEFINE_UNQUOTED(DEFKTNAME, ["$DEFKTNAME"], [Define to default keytab name]) |
||||
AC_DEFINE_UNQUOTED(DEFCKTNAME, ["$DEFCKTNAME"], |
||||
[Define to default client keytab name]) |
||||
|
||||
+AC_ARG_VAR(PKCS11_MODNAME, [Default PKCS11 module name]) |
||||
+if test "${PKCS11_MODNAME+set}" != set; then |
||||
+ PKCS11_MODNAME=opensc-pkcs11.so |
||||
+fi |
||||
+AC_MSG_NOTICE([Default PKCS11 module name: $PKCS11_MODNAME]) |
||||
+AC_DEFINE_UNQUOTED(PKCS11_MODNAME, ["$PKCS11_MODNAME"], |
||||
+ [Default PKCS11 module name]) |
||||
+ |
||||
AC_CONFIG_FILES([build-tools/krb5-config], [chmod +x build-tools/krb5-config]) |
||||
AC_CONFIG_FILES([build-tools/kadm-server.pc |
||||
build-tools/kadm-client.pc |
||||
diff --git a/src/doc/Makefile.in b/src/doc/Makefile.in |
||||
index 379bc3651..a1b0cff0a 100644 |
||||
--- a/src/doc/Makefile.in |
||||
+++ b/src/doc/Makefile.in |
||||
@@ -10,6 +10,7 @@ sysconfdir=@sysconfdir@ |
||||
DEFCCNAME=@DEFCCNAME@ |
||||
DEFKTNAME=@DEFKTNAME@ |
||||
DEFCKTNAME=@DEFCKTNAME@ |
||||
+PKCS11_MODNAME=@PKCS11_MODNAME@ |
||||
|
||||
RST_SOURCES= _static \ |
||||
_templates \ |
||||
@@ -118,6 +119,7 @@ paths.py: |
||||
echo 'ccache = "``$(DEFCCNAME)``"' >> $@ |
||||
echo 'keytab = "``$(DEFKTNAME)``"' >> $@ |
||||
echo 'ckeytab = "``$(DEFCKTNAME)``"' >> $@ |
||||
+ echo 'pkcs11_modname = "``$(PKCS11_MODNAME)``"' >> $@ |
||||
|
||||
# Dummy rule that man/Makefile can invoke |
||||
version.py: $(docsrc)/version.py |
||||
diff --git a/src/man/Makefile.in b/src/man/Makefile.in |
||||
index 00b1b2de0..85cae0914 100644 |
||||
--- a/src/man/Makefile.in |
||||
+++ b/src/man/Makefile.in |
||||
@@ -8,6 +8,7 @@ sysconfdir=@sysconfdir@ |
||||
DEFCCNAME=@DEFCCNAME@ |
||||
DEFKTNAME=@DEFKTNAME@ |
||||
DEFCKTNAME=@DEFCKTNAME@ |
||||
+PKCS11_MODNAME=@PKCS11_MODNAME@ |
||||
|
||||
MANSUBS=k5identity.sub k5login.sub k5srvutil.sub kadm5.acl.sub kadmin.sub \ |
||||
kadmind.sub kdb5_ldap_util.sub kdb5_util.sub kdc.conf.sub \ |
||||
@@ -47,7 +48,8 @@ $(docsrc)/version.py: $(top_srcdir)/patchlevel.h |
||||
-e 's|@SYSCONFDIR@|$(sysconfdir)|g' \ |
||||
-e 's|@CCNAME@|$(DEFCCNAME)|g' \ |
||||
-e 's|@KTNAME@|$(DEFKTNAME)|g' \ |
||||
- -e 's|@CKTNAME@|$(DEFCKTNAME)|g' $? > $@ |
||||
+ -e 's|@CKTNAME@|$(DEFCKTNAME)|g' \ |
||||
+ -e 's|@PKCS11MOD@|$(PKCS11_MODNAME)|g' $? > $@ |
||||
|
||||
all: $(MANSUBS) |
||||
|
||||
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man |
||||
index 3a702ca8f..e4202723f 100644 |
||||
--- a/src/man/krb5.conf.man |
||||
+++ b/src/man/krb5.conf.man |
||||
@@ -1151,7 +1151,7 @@ user\(aqs certificate and private key. |
||||
All keyword/values are optional. \fImodname\fP specifies the location |
||||
of a library implementing PKCS #11. If a value is encountered |
||||
with no keyword, it is assumed to be the \fImodname\fP\&. If no |
||||
-module\-name is specified, the default is \fBopensc\-pkcs11.so\fP\&. |
||||
+module\-name is specified, the default is \fB@PKCS11MOD@\fP\&. |
||||
\fBslotid=\fP and/or \fBtoken=\fP may be specified to force the use of |
||||
a particular smard card reader or token if there is more than one |
||||
available. \fBcertid=\fP and/or \fBcertlabel=\fP may be specified to |
||||
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h |
||||
index b437fd53f..a2018cb10 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit.h |
||||
+++ b/src/plugins/preauth/pkinit/pkinit.h |
||||
@@ -42,7 +42,6 @@ |
||||
#ifndef WITHOUT_PKCS11 |
||||
#include "pkcs11.h" |
||||
|
||||
-#define PKCS11_MODNAME "opensc-pkcs11.so" |
||||
#define PK_SIGLEN_GUESS 1000 |
||||
#define PK_NOSLOT 999999 |
||||
#endif |
||||
-- |
||||
2.35.1 |
||||
|
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
From c76a01279bbbbcfd296d2ead8f6e2a5bee7e8443 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Fri, 15 Jan 2021 14:43:34 -0500 |
||||
Subject: [PATCH] Add hostname canonicalization helper to k5test.py |
||||
|
||||
To facilitate fallback tests, add a canonicalize_hostname() function |
||||
to k5test.py which works similarly to krb5_expand_hostname(). Use it |
||||
in t_gssapi.py for the recently-added acceptor name fallback test. |
||||
|
||||
(cherry picked from commit 225fffe4e912772acea3a01d45bafb60bfb80948) |
||||
--- |
||||
src/tests/gssapi/t_gssapi.py | 11 +++-------- |
||||
src/util/k5test.py | 22 ++++++++++++++++++++++ |
||||
2 files changed, 25 insertions(+), 8 deletions(-) |
||||
|
||||
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py |
||||
index 1af6f31c2..e22cec427 100755 |
||||
--- a/src/tests/gssapi/t_gssapi.py |
||||
+++ b/src/tests/gssapi/t_gssapi.py |
||||
@@ -8,7 +8,7 @@ for realm in multipass_realms(): |
||||
realm.run(['./t_iov', '-s', 'p:' + realm.host_princ]) |
||||
realm.run(['./t_pcontok', 'p:' + realm.host_princ]) |
||||
|
||||
-realm = K5Realm(krb5_conf={'libdefaults': {'rdns': 'false'}}) |
||||
+realm = K5Realm() |
||||
|
||||
# Test gss_add_cred(). |
||||
realm.run(['./t_add_cred']) |
||||
@@ -62,13 +62,8 @@ realm.run(['./t_accname', 'p:host/-nomatch-', |
||||
expected_msg=' not found in keytab') |
||||
|
||||
# If possible, test with an acceptor name requiring fallback to match |
||||
-# against a keytab entry. Forward-canonicalize the hostname, relying |
||||
-# on the rdns=false realm setting. |
||||
-try: |
||||
- ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME) |
||||
- (family, socktype, proto, canonname, sockaddr) = ai[0] |
||||
-except socket.gaierror: |
||||
- canonname = hostname |
||||
+# against a keytab entry. |
||||
+canonname = canonicalize_hostname(hostname) |
||||
if canonname != hostname: |
||||
os.rename(realm.keytab, realm.keytab + '.save') |
||||
canonprinc = 'host/' + canonname |
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py |
||||
index 789b0f4b9..251d11a9d 100644 |
||||
--- a/src/util/k5test.py |
||||
+++ b/src/util/k5test.py |
||||
@@ -155,6 +155,10 @@ Scripts may use the following functions and variables: |
||||
* password(name): Return a weakly random password based on name. The |
||||
password will be consistent across calls with the same name. |
||||
|
||||
+* canonicalize_hostname(name, rdns=True): Return the DNS |
||||
+ canonicalization of name, optionally using reverse DNS. On error, |
||||
+ return name converted to lowercase. |
||||
+ |
||||
* stop_daemon(proc): Stop a daemon process started with |
||||
realm.start_server() or realm.start_in_inetd(). Only necessary if |
||||
the port needs to be reused; daemon processes will be stopped |
||||
@@ -458,6 +462,24 @@ def password(name): |
||||
return name + str(os.getpid()) |
||||
|
||||
|
||||
+def canonicalize_hostname(name, rdns=True): |
||||
+ """Canonicalize name using DNS, optionally with reverse DNS.""" |
||||
+ try: |
||||
+ ai = socket.getaddrinfo(name, None, 0, 0, 0, socket.AI_CANONNAME) |
||||
+ except socket.gaierror as e: |
||||
+ return name.lower() |
||||
+ (family, socktype, proto, canonname, sockaddr) = ai[0] |
||||
+ |
||||
+ if not rdns: |
||||
+ return canonname.lower() |
||||
+ |
||||
+ try: |
||||
+ rname = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD) |
||||
+ except socket.gaierror: |
||||
+ return canonname.lower() |
||||
+ return rname[0].lower() |
||||
+ |
||||
+ |
||||
# Exit handler which ensures processes are cleaned up and, on failure, |
||||
# prints messages to help developers debug the problem. |
||||
def _onexit(): |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
From 4c2f596da5ddb8a1687a4f9c969d5a8dcd2cbcc7 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Thu, 3 Jun 2021 16:03:07 -0400 |
||||
Subject: [PATCH] Allow kinit with keytab to defer canonicalization |
||||
|
||||
[ghudson@mit.edu: added tests] |
||||
|
||||
ticket: 9012 (new) |
||||
(cherry picked from commit 5e6a6efc5df689d9fb8730d0227167ffbb6ece0e) |
||||
(cherry picked from commit 090c7319652466339e3e6482bdd1b5a294638dff) |
||||
--- |
||||
src/clients/kinit/kinit.c | 11 ----------- |
||||
src/tests/t_keytab.py | 13 +++++++++++++ |
||||
2 files changed, 13 insertions(+), 11 deletions(-) |
||||
|
||||
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c |
||||
index d1f5d74c3..5a6d7237c 100644 |
||||
--- a/src/clients/kinit/kinit.c |
||||
+++ b/src/clients/kinit/kinit.c |
||||
@@ -510,17 +510,6 @@ k5_begin(struct k_opts *opts, struct k5_data *k5) |
||||
_("when creating default server principal name")); |
||||
goto cleanup; |
||||
} |
||||
- if (k5->me->realm.data[0] == 0) { |
||||
- ret = krb5_unparse_name(k5->ctx, k5->me, &k5->name); |
||||
- if (ret == 0) { |
||||
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN, |
||||
- _("(principal %s)"), k5->name); |
||||
- } else { |
||||
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN, |
||||
- _("for local services")); |
||||
- } |
||||
- goto cleanup; |
||||
- } |
||||
} else if (k5->out_cc != NULL) { |
||||
/* If the output ccache is initialized, use its principal. */ |
||||
if (krb5_cc_get_principal(k5->ctx, k5->out_cc, &princ) == 0) |
||||
diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py |
||||
index 850375c92..a9adebb26 100755 |
||||
--- a/src/tests/t_keytab.py |
||||
+++ b/src/tests/t_keytab.py |
||||
@@ -41,6 +41,19 @@ realm.kinit(realm.user_princ, flags=['-i'], |
||||
expected_msg='keytab specified, forcing -k') |
||||
realm.klist(realm.user_princ) |
||||
|
||||
+# Test default principal for -k. This operation requires |
||||
+# canonicalization against the keytab in krb5_get_init_creds_keytab() |
||||
+# as the krb5_sname_to_principal() result won't have a realm. Try |
||||
+# with and without without fallback processing since the code paths |
||||
+# are different. |
||||
+mark('default principal for -k') |
||||
+realm.run([kinit, '-k']) |
||||
+realm.klist(realm.host_princ) |
||||
+no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}} |
||||
+no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) |
||||
+realm.run([kinit, '-k'], env=no_canon) |
||||
+realm.klist(realm.host_princ) |
||||
+ |
||||
# Test extracting keys with multiple key versions present. |
||||
mark('multi-kvno extract') |
||||
os.remove(realm.keytab) |
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
From 92a4b760d741494dacbb4d9db4cf2db9e3b01f2c Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Mon, 29 Mar 2021 14:32:56 -0400 |
||||
Subject: [PATCH] Fix KCM flag transmission for remove_cred |
||||
|
||||
MIT krb5 uses low bits for KRB5_TC flags, while Heimdal uses high bits |
||||
so that the same flag word can also hold KRB5_GC flags. Add a mapping |
||||
function and send the Heimdal flag values when performing a |
||||
remove_cred operation. |
||||
|
||||
ticket: 8995 |
||||
(cherry picked from commit 11a82cf424f9c905bb73680c64524f087090d4ef) |
||||
(cherry picked from commit 04f0de4420508161ce439f262f2761ff51a07ab0) |
||||
--- |
||||
src/include/kcm.h | 19 +++++++++++++++++++ |
||||
src/lib/krb5/ccache/cc_kcm.c | 36 +++++++++++++++++++++++++++++++++++- |
||||
2 files changed, 54 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/include/kcm.h b/src/include/kcm.h |
||||
index e4140c3a0..9b66f1cbd 100644 |
||||
--- a/src/include/kcm.h |
||||
+++ b/src/include/kcm.h |
||||
@@ -56,8 +56,27 @@ |
||||
* are marshalled as zero-terminated strings. Principals and credentials are |
||||
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists |
||||
* are not delimited, so nothing can come after them. |
||||
+ * |
||||
+ * Flag words must use Heimdal flag values, which are not the same as MIT krb5 |
||||
+ * values for KRB5_GC and KRB5_TC constants. The same flag word may contain |
||||
+ * both kinds of flags in Heimdal, but not in MIT krb5. Defines for the |
||||
+ * applicable Heimdal flag values are given below using KCM_GC and KCM_TC |
||||
+ * prefixes. |
||||
*/ |
||||
|
||||
+#define KCM_GC_CACHED (1U << 0) |
||||
+ |
||||
+#define KCM_TC_DONT_MATCH_REALM (1U << 31) |
||||
+#define KCM_TC_MATCH_KEYTYPE (1U << 30) |
||||
+#define KCM_TC_MATCH_SRV_NAMEONLY (1U << 29) |
||||
+#define KCM_TC_MATCH_FLAGS_EXACT (1U << 28) |
||||
+#define KCM_TC_MATCH_FLAGS (1U << 27) |
||||
+#define KCM_TC_MATCH_TIMES_EXACT (1U << 26) |
||||
+#define KCM_TC_MATCH_TIMES (1U << 25) |
||||
+#define KCM_TC_MATCH_AUTHDATA (1U << 24) |
||||
+#define KCM_TC_MATCH_2ND_TKT (1U << 23) |
||||
+#define KCM_TC_MATCH_IS_SKEY (1U << 22) |
||||
+ |
||||
/* Opcodes without comments are currently unused in the MIT client |
||||
* implementation. */ |
||||
typedef enum kcm_opcode { |
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c |
||||
index 772928e4d..1f81a2190 100644 |
||||
--- a/src/lib/krb5/ccache/cc_kcm.c |
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c |
||||
@@ -110,6 +110,40 @@ map_invalid(krb5_error_code code) |
||||
KRB5_KCM_MALFORMED_REPLY : code; |
||||
} |
||||
|
||||
+/* |
||||
+ * Map an MIT krb5 KRB5_TC flag word to the equivalent Heimdal flag word. Note |
||||
+ * that there is no MIT krb5 equivalent for Heimdal's KRB5_TC_DONT_MATCH_REALM |
||||
+ * (which is like KRB5_TC_MATCH_SRV_NAMEONLY but also applies to the client |
||||
+ * principal) and no Heimdal equivalent for MIT krb5's KRB5_TC_SUPPORTED_KTYPES |
||||
+ * (which matches against enctypes from the krb5_context rather than the |
||||
+ * matching cred). |
||||
+ */ |
||||
+static inline krb5_flags |
||||
+map_tcflags(krb5_flags mitflags) |
||||
+{ |
||||
+ krb5_flags heimflags = 0; |
||||
+ |
||||
+ if (mitflags & KRB5_TC_MATCH_TIMES) |
||||
+ heimflags |= KCM_TC_MATCH_TIMES; |
||||
+ if (mitflags & KRB5_TC_MATCH_IS_SKEY) |
||||
+ heimflags |= KCM_TC_MATCH_IS_SKEY; |
||||
+ if (mitflags & KRB5_TC_MATCH_FLAGS) |
||||
+ heimflags |= KCM_TC_MATCH_FLAGS; |
||||
+ if (mitflags & KRB5_TC_MATCH_TIMES_EXACT) |
||||
+ heimflags |= KCM_TC_MATCH_TIMES_EXACT; |
||||
+ if (mitflags & KRB5_TC_MATCH_FLAGS_EXACT) |
||||
+ heimflags |= KCM_TC_MATCH_FLAGS_EXACT; |
||||
+ if (mitflags & KRB5_TC_MATCH_AUTHDATA) |
||||
+ heimflags |= KCM_TC_MATCH_AUTHDATA; |
||||
+ if (mitflags & KRB5_TC_MATCH_SRV_NAMEONLY) |
||||
+ heimflags |= KCM_TC_MATCH_SRV_NAMEONLY; |
||||
+ if (mitflags & KRB5_TC_MATCH_2ND_TKT) |
||||
+ heimflags |= KCM_TC_MATCH_2ND_TKT; |
||||
+ if (mitflags & KRB5_TC_MATCH_KTYPE) |
||||
+ heimflags |= KCM_TC_MATCH_KEYTYPE; |
||||
+ return heimflags; |
||||
+} |
||||
+ |
||||
/* Begin a request for the given opcode. If cache is non-null, supply the |
||||
* cache name as a request parameter. */ |
||||
static void |
||||
@@ -936,7 +970,7 @@ kcm_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, |
||||
struct kcmreq req; |
||||
|
||||
kcmreq_init(&req, KCM_OP_REMOVE_CRED, cache); |
||||
- k5_buf_add_uint32_be(&req.reqbuf, flags); |
||||
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags)); |
||||
k5_marshal_mcred(&req.reqbuf, mcred); |
||||
ret = cache_call(context, cache, &req); |
||||
kcmreq_free(&req); |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
From b4f3df953015bf6d2d4c973b458f778f31615c11 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Tue, 11 May 2021 14:04:07 -0400 |
||||
Subject: [PATCH] Fix KCM retrieval support for sssd |
||||
|
||||
Commit 795ebba8c039be172ab93cd41105c73ffdba0fdb added a retrieval |
||||
handler using KCM_OP_RETRIEVE, falling back on the same error codes as |
||||
the previous KCM_OP_GET_CRED_LIST support. But sssd (as of 2.4) |
||||
returns KRB5_CC_NOSUPP instead of KRB5_CC_IO if it recognizes an |
||||
opcode but does not implement it. Add a helper function to recognize |
||||
all known unsupported-opcode error codes, and use it in kcm_retrieve() |
||||
and kcm_start_seq_get(). |
||||
|
||||
ticket: 8997 |
||||
(cherry picked from commit da103e36e13f3c846bcddbe38dd518a21e5260a0) |
||||
(cherry picked from commit a5b2cff51808cd86fe8195e7ac074ecd25c3344d) |
||||
--- |
||||
src/lib/krb5/ccache/cc_kcm.c | 18 ++++++++++++++++-- |
||||
1 file changed, 16 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c |
||||
index 23fcf13ea..18505cd3d 100644 |
||||
--- a/src/lib/krb5/ccache/cc_kcm.c |
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c |
||||
@@ -144,6 +144,20 @@ map_tcflags(krb5_flags mitflags) |
||||
return heimflags; |
||||
} |
||||
|
||||
+/* |
||||
+ * Return true if code could indicate an unsupported operation. Heimdal's KCM |
||||
+ * returns KRB5_FCC_INTERNAL. sssd's KCM daemon (as of sssd 2.4) returns |
||||
+ * KRB5_CC_NO_SUPP if it recognizes the operation but does not implement it, |
||||
+ * and KRB5_CC_IO if it doesn't recognize the operation (which is unfortunate |
||||
+ * since it could also indicate a communication failure). |
||||
+ */ |
||||
+static krb5_boolean |
||||
+unsupported_op_error(krb5_error_code code) |
||||
+{ |
||||
+ return code == KRB5_FCC_INTERNAL || code == KRB5_CC_IO || |
||||
+ code == KRB5_CC_NOSUPP; |
||||
+} |
||||
+ |
||||
/* Begin a request for the given opcode. If cache is non-null, supply the |
||||
* cache name as a request parameter. */ |
||||
static void |
||||
@@ -841,7 +855,7 @@ kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags, |
||||
ret = cache_call(context, cache, &req); |
||||
|
||||
/* Fall back to iteration if the server does not support retrieval. */ |
||||
- if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) { |
||||
+ if (unsupported_op_error(ret)) { |
||||
ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred, |
||||
cred_out); |
||||
goto cleanup; |
||||
@@ -922,7 +936,7 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache, |
||||
ret = kcmreq_get_cred_list(&req, &creds); |
||||
if (ret) |
||||
goto cleanup; |
||||
- } else if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) { |
||||
+ } else if (unsupported_op_error(ret)) { |
||||
/* Fall back to GET_CRED_UUID_LIST. */ |
||||
kcmreq_free(&req); |
||||
kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache); |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
From 0a8dfc380fe3b210662ba1b1d452fcec2f84841b Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Tue, 3 Aug 2021 01:15:27 -0400 |
||||
Subject: [PATCH] Fix KDC null deref on TGS inner body null server |
||||
|
||||
After the KDC decodes a FAST inner body, it does not check for a null |
||||
server. Prior to commit 39548a5b17bbda9eeb63625a201cfd19b9de1c5b this |
||||
would typically result in an error from krb5_unparse_name(), but with |
||||
the addition of get_local_tgt() it results in a null dereference. Add |
||||
a null check. |
||||
|
||||
Reported by Joseph Sutton of Catalyst. |
||||
|
||||
CVE-2021-37750: |
||||
|
||||
In MIT krb5 releases 1.14 and later, an authenticated attacker can |
||||
cause a null dereference in the KDC by sending a FAST TGS request with |
||||
no server field. |
||||
|
||||
ticket: 9008 (new) |
||||
tags: pullup |
||||
target_version: 1.19-next |
||||
target_version: 1.18-next |
||||
|
||||
(cherry picked from commit d775c95af7606a51bf79547a94fa52ddd1cb7f49) |
||||
(cherry picked from commit bb8fa495d00ccd931eec87a01b8920636cf7903e) |
||||
(cherry picked from commit dfe383f8251d0edc7e5e08ec5e4fdd9b7f902b2a) |
||||
--- |
||||
src/kdc/do_tgs_req.c | 5 +++++ |
||||
1 file changed, 5 insertions(+) |
||||
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c |
||||
index 463a9c0dd..7c596a111 100644 |
||||
--- a/src/kdc/do_tgs_req.c |
||||
+++ b/src/kdc/do_tgs_req.c |
||||
@@ -208,6 +208,11 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt, |
||||
status = "FIND_FAST"; |
||||
goto cleanup; |
||||
} |
||||
+ if (sprinc == NULL) { |
||||
+ status = "NULL_SERVER"; |
||||
+ errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; |
||||
+ goto cleanup; |
||||
+ } |
||||
|
||||
errcode = get_local_tgt(kdc_context, &sprinc->realm, header_server, |
||||
&local_tgt, &local_tgt_storage, &local_tgt_key); |
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
From 3fe94b5854c56da38ba14994b6c371c3e3b9094e Mon Sep 17 00:00:00 2001 |
||||
From: Joseph Sutton <josephsutton@catalyst.net.nz> |
||||
Date: Wed, 7 Jul 2021 11:47:44 +1200 |
||||
Subject: [PATCH] Fix KDC null deref on bad encrypted challenge |
||||
|
||||
The function ec_verify() in src/kdc/kdc_preauth_ec.c contains a check |
||||
to avoid further processing if the armor key is NULL. However, this |
||||
check is bypassed by a call to k5memdup0() which overwrites retval |
||||
with 0 if the allocation succeeds. If the armor key is NULL, a call |
||||
to krb5_c_fx_cf2_simple() will then dereference it, resulting in a |
||||
crash. Add a check before the k5memdup0() call to avoid overwriting |
||||
retval. |
||||
|
||||
CVE-2021-36222: |
||||
|
||||
In MIT krb5 releases 1.16 and later, an unauthenticated attacker can |
||||
cause a null dereference in the KDC by sending a request containing a |
||||
PA-ENCRYPTED-CHALLENGE padata element without using FAST. |
||||
|
||||
[ghudson@mit.edu: trimmed patch; added test case; edited commit |
||||
message] |
||||
|
||||
ticket: 9007 (new) |
||||
tags: pullup |
||||
target_version: 1.19-next |
||||
target_version: 1.18-next |
||||
|
||||
(cherry picked from commit fc98f520caefff2e5ee9a0026fdf5109944b3562) |
||||
(cherry picked from commit 791211b00a53b394376d096c881b725ee739a936) |
||||
--- |
||||
src/kdc/kdc_preauth_ec.c | 3 ++- |
||||
src/tests/Makefile.in | 1 + |
||||
src/tests/t_cve-2021-36222.py | 46 +++++++++++++++++++++++++++++++++++ |
||||
3 files changed, 49 insertions(+), 1 deletion(-) |
||||
create mode 100644 src/tests/t_cve-2021-36222.py |
||||
|
||||
diff --git a/src/kdc/kdc_preauth_ec.c b/src/kdc/kdc_preauth_ec.c |
||||
index 7e636b3f9..43a9902cc 100644 |
||||
--- a/src/kdc/kdc_preauth_ec.c |
||||
+++ b/src/kdc/kdc_preauth_ec.c |
||||
@@ -87,7 +87,8 @@ ec_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, |
||||
} |
||||
|
||||
/* Check for a configured FAST ec auth indicator. */ |
||||
- realmstr = k5memdup0(realm.data, realm.length, &retval); |
||||
+ if (retval == 0) |
||||
+ realmstr = k5memdup0(realm.data, realm.length, &retval); |
||||
if (realmstr != NULL) |
||||
retval = profile_get_string(context->profile, KRB5_CONF_REALMS, |
||||
realmstr, |
||||
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in |
||||
index ab416cc5f..20f27d748 100644 |
||||
--- a/src/tests/Makefile.in |
||||
+++ b/src/tests/Makefile.in |
||||
@@ -159,6 +159,7 @@ check-pytests: unlockiter s4u2self |
||||
$(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS) |
||||
$(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS) |
||||
$(RUNPYTEST) $(srcdir)/t_cve-2013-1417.py $(PYTESTFLAGS) |
||||
+ $(RUNPYTEST) $(srcdir)/t_cve-2021-36222.py $(PYTESTFLAGS) |
||||
$(RM) au.log |
||||
$(RUNPYTEST) $(srcdir)/t_audit.py $(PYTESTFLAGS) |
||||
$(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \ |
||||
diff --git a/src/tests/t_cve-2021-36222.py b/src/tests/t_cve-2021-36222.py |
||||
new file mode 100644 |
||||
index 000000000..57e04993b |
||||
--- /dev/null |
||||
+++ b/src/tests/t_cve-2021-36222.py |
||||
@@ -0,0 +1,46 @@ |
||||
+import socket |
||||
+from k5test import * |
||||
+ |
||||
+realm = K5Realm() |
||||
+ |
||||
+# CVE-2021-36222 KDC null dereference on encrypted challenge preauth |
||||
+# without FAST |
||||
+ |
||||
+s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
||||
+a = (hostname, realm.portbase) |
||||
+ |
||||
+m = ('6A81A0' '30819D' # [APPLICATION 10] SEQUENCE |
||||
+ 'A103' '0201' '05' # [1] pvno = 5 |
||||
+ 'A203' '0201' '0A' # [2] msg-type = 10 |
||||
+ 'A30E' '300C' # [3] padata = SEQUENCE OF |
||||
+ '300A' # SEQUENCE |
||||
+ 'A104' '0202' '008A' # [1] padata-type = PA-ENCRYPTED-CHALLENGE |
||||
+ 'A202' '0400' # [2] padata-value = "" |
||||
+ 'A48180' '307E' # [4] req-body = SEQUENCE |
||||
+ 'A007' '0305' '0000000000' # [0] kdc-options = 0 |
||||
+ 'A120' '301E' # [1] cname = SEQUENCE |
||||
+ 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL |
||||
+ 'A117' '3015' # [1] name-string = SEQUENCE-OF |
||||
+ '1B06' '6B7262746774' # krbtgt |
||||
+ '1B0B' '4B5242544553542E434F4D' |
||||
+ # KRBTEST.COM |
||||
+ 'A20D' '1B0B' '4B5242544553542E434F4D' |
||||
+ # [2] realm = KRBTEST.COM |
||||
+ 'A320' '301E' # [3] sname = SEQUENCE |
||||
+ 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL |
||||
+ 'A117' '3015' # [1] name-string = SEQUENCE-OF |
||||
+ '1B06' '6B7262746774' # krbtgt |
||||
+ '1B0B' '4B5242544553542E434F4D' |
||||
+ # KRBTEST.COM |
||||
+ 'A511' '180F' '31393934303631303036303331375A' |
||||
+ # [5] till = 19940610060317Z |
||||
+ 'A703' '0201' '00' # [7] nonce = 0 |
||||
+ 'A808' '3006' # [8] etype = SEQUENCE OF |
||||
+ '020112' '020111') # aes256-cts aes128-cts |
||||
+ |
||||
+s.sendto(bytes.fromhex(m), a) |
||||
+ |
||||
+# Make sure kinit still works. |
||||
+realm.kinit(realm.user_princ, password('user')) |
||||
+ |
||||
+success('CVE-2021-36222 regression test') |
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
From 7d68cfc84cd7d0657c01afa52dfe69181b401a4a Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Mon, 17 Oct 2022 20:25:11 -0400 |
||||
Subject: [PATCH] Fix integer overflows in PAC parsing |
||||
|
||||
In krb5_parse_pac(), check for buffer counts large enough to threaten |
||||
integer overflow in the header length and memory length calculations. |
||||
Avoid potential integer overflows when checking the length of each |
||||
buffer. |
||||
|
||||
CVE-2022-42898: |
||||
|
||||
In MIT krb5 releases 1.8 and later, an authenticated attacker may be |
||||
able to cause a KDC or kadmind process to crash by reading beyond the |
||||
bounds of allocated memory, creating a denial of service. A |
||||
privileged attacker may similarly be able to cause a Kerberos or GSS |
||||
application service to crash. On 32-bit platforms, an attacker can |
||||
also cause insufficient memory to be allocated for the result, |
||||
potentially leading to remote code execution in a KDC, kadmind, or GSS |
||||
or Kerberos application server process. An attacker with the |
||||
privileges of a cross-realm KDC may be able to extract secrets from |
||||
the KDC process's memory by having them copied into the PAC of a new |
||||
ticket. |
||||
|
||||
ticket: 9074 (new) |
||||
tags: pullup |
||||
target_version: 1.20-next |
||||
target_version: 1.19-next |
||||
--- |
||||
src/lib/krb5/krb/pac.c | 9 +++++++-- |
||||
src/lib/krb5/krb/t_pac.c | 18 ++++++++++++++++++ |
||||
2 files changed, 25 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c |
||||
index 950beda657..1b9ef12276 100644 |
||||
--- a/src/lib/krb5/krb/pac.c |
||||
+++ b/src/lib/krb5/krb/pac.c |
||||
@@ -27,6 +27,8 @@ |
||||
#include "k5-int.h" |
||||
#include "authdata.h" |
||||
|
||||
+#define MAX_BUFFERS 4096 |
||||
+ |
||||
/* draft-brezak-win2k-krb-authz-00 */ |
||||
|
||||
/* |
||||
@@ -316,6 +318,9 @@ krb5_pac_parse(krb5_context context, |
||||
if (version != 0) |
||||
return EINVAL; |
||||
|
||||
+ if (cbuffers < 1 || cbuffers > MAX_BUFFERS) |
||||
+ return ERANGE; |
||||
+ |
||||
header_len = PACTYPE_LENGTH + (cbuffers * PAC_INFO_BUFFER_LENGTH); |
||||
if (len < header_len) |
||||
return ERANGE; |
||||
@@ -348,8 +353,8 @@ krb5_pac_parse(krb5_context context, |
||||
krb5_pac_free(context, pac); |
||||
return EINVAL; |
||||
} |
||||
- if (buffer->Offset < header_len || |
||||
- buffer->Offset + buffer->cbBufferSize > len) { |
||||
+ if (buffer->Offset < header_len || buffer->Offset > len || |
||||
+ buffer->cbBufferSize > len - buffer->Offset) { |
||||
krb5_pac_free(context, pac); |
||||
return ERANGE; |
||||
} |
||||
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c |
||||
index ee47152ee4..ccd165380d 100644 |
||||
--- a/src/lib/krb5/krb/t_pac.c |
||||
+++ b/src/lib/krb5/krb/t_pac.c |
||||
@@ -431,6 +431,16 @@ static const unsigned char s4u_pac_ent_xrealm[] = { |
||||
0x8a, 0x81, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x00 |
||||
}; |
||||
|
||||
+static const unsigned char fuzz1[] = { |
||||
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, |
||||
+ 0x06, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf5 |
||||
+}; |
||||
+ |
||||
+static const unsigned char fuzz2[] = { |
||||
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, |
||||
+ 0x20, 0x20 |
||||
+}; |
||||
+ |
||||
static const char *s4u_principal = "w2k8u@ACME.COM"; |
||||
static const char *s4u_enterprise = "w2k8u@abc@ACME.COM"; |
||||
|
||||
@@ -646,6 +656,14 @@ main(int argc, char **argv) |
||||
krb5_free_principal(context, sep); |
||||
} |
||||
|
||||
+ /* Check problematic PACs found by fuzzing. */ |
||||
+ ret = krb5_pac_parse(context, fuzz1, sizeof(fuzz1), &pac); |
||||
+ if (!ret) |
||||
+ err(context, ret, "krb5_pac_parse should have failed"); |
||||
+ ret = krb5_pac_parse(context, fuzz2, sizeof(fuzz2), &pac); |
||||
+ if (!ret) |
||||
+ err(context, ret, "krb5_pac_parse should have failed"); |
||||
+ |
||||
/* |
||||
* Test empty free |
||||
*/ |
||||
-- |
||||
2.37.3 |
||||
|
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
From 51938a8b731740299fe47d132b8840edba4141bc Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Sat, 29 May 2021 12:05:49 -0400 |
||||
Subject: [PATCH] Fix k5tls module for OpenSSL 3 |
||||
|
||||
Starting in OpenSSL 3, connection termination without a close_notify |
||||
alert causes SSL_read() to return SSL_ERROR_SSL instead of |
||||
SSL_ERROR_SYSCALL. OpenSSL 3 also provides a new option |
||||
SSL_OP_IGNORE_UNEXPECTED_EOF which allows an application to explicitly |
||||
ignore possible truncation attacks and receive SSL_ERROR_ZERO_RETURN |
||||
instead. |
||||
|
||||
Remove the call to SSL_CTX_get_options() since SSL_CTX_set_options() |
||||
doesn't clear existing options. |
||||
|
||||
[ghudson@mit.edu: edited commit message and comment] |
||||
|
||||
(cherry picked from commit aa9b4a2a64046afd2fab7cb49c346295874a5fb6) |
||||
(cherry picked from commit 201e38845e9f70234bcaa9ba7c25b28e38169b0a) |
||||
--- |
||||
src/plugins/tls/k5tls/openssl.c | 17 ++++++++++++++--- |
||||
1 file changed, 14 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c |
||||
index 76a43b3cd..99fda7ffc 100644 |
||||
--- a/src/plugins/tls/k5tls/openssl.c |
||||
+++ b/src/plugins/tls/k5tls/openssl.c |
||||
@@ -433,7 +433,7 @@ setup(krb5_context context, SOCKET fd, const char *servername, |
||||
char **anchors, k5_tls_handle *handle_out) |
||||
{ |
||||
int e; |
||||
- long options; |
||||
+ long options = SSL_OP_NO_SSLv2; |
||||
SSL_CTX *ctx = NULL; |
||||
SSL *ssl = NULL; |
||||
k5_tls_handle handle = NULL; |
||||
@@ -448,8 +448,19 @@ setup(krb5_context context, SOCKET fd, const char *servername, |
||||
ctx = SSL_CTX_new(SSLv23_client_method()); |
||||
if (ctx == NULL) |
||||
goto error; |
||||
- options = SSL_CTX_get_options(ctx); |
||||
- SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2); |
||||
+ |
||||
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF |
||||
+ /* |
||||
+ * For OpenSSL 3 and later, mark close_notify alerts as optional. We don't |
||||
+ * need to worry about truncation attacks because the protocols this module |
||||
+ * is used with (Kerberos and change-password) receive a single |
||||
+ * length-delimited message from the server. For prior versions of OpenSSL |
||||
+ * we check for SSL_ERROR_SYSCALL when reading instead (this error changes |
||||
+ * to SSL_ERROR_SSL in OpenSSL 3). |
||||
+ */ |
||||
+ options |= SSL_OP_IGNORE_UNEXPECTED_EOF; |
||||
+#endif |
||||
+ SSL_CTX_set_options(ctx, options); |
||||
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); |
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0); |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
From ddbd548562d951d327a10c9dcb975418427f6fea Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Mon, 7 Jun 2021 15:00:41 -0400 |
||||
Subject: [PATCH] Fix kadmin -k with fallback or referral realm |
||||
|
||||
kadmin -k produces a client principal name with |
||||
krb5_sname_to_principal(), but it gets converted to a string and back |
||||
due to the signature of kadm5_init_with_skey(), which loses track of |
||||
the name type, so no canonicalization is performed. |
||||
|
||||
In libkadm5clnt initialization, recognize the important subset of this |
||||
case--an empty realm indicates either fallback processing or the |
||||
referral realm--and restore the host-based name type so that the |
||||
client principal can be canonicalized against the keytab. |
||||
|
||||
ticket: 9013 (new) |
||||
(cherry picked from commit dcb79089276624d7ddf44e08d35bd6d7d7e557d2) |
||||
(cherry picked from commit cd8ff035f5b4720a8fc457355726f7bd0eab5eaa) |
||||
--- |
||||
src/lib/kadm5/clnt/client_init.c | 7 +++++++ |
||||
src/tests/t_kadmin.py | 12 ++++++++++++ |
||||
2 files changed, 19 insertions(+) |
||||
|
||||
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c |
||||
index aa1223bb3..0aaca701f 100644 |
||||
--- a/src/lib/kadm5/clnt/client_init.c |
||||
+++ b/src/lib/kadm5/clnt/client_init.c |
||||
@@ -221,9 +221,16 @@ init_any(krb5_context context, char *client_name, enum init_type init_type, |
||||
return KADM5_MISSING_KRB5_CONF_PARAMS; |
||||
} |
||||
|
||||
+ /* |
||||
+ * Parse the client name. If it has an empty realm, it is almost certainly |
||||
+ * a host-based principal using DNS fallback processing or the referral |
||||
+ * realm, so give it the appropriate name type for canonicalization. |
||||
+ */ |
||||
code = krb5_parse_name(handle->context, client_name, &client); |
||||
if (code) |
||||
goto error; |
||||
+ if (init_type == INIT_SKEY && client->realm.length == 0) |
||||
+ client->type = KRB5_NT_SRV_HST; |
||||
|
||||
/* |
||||
* Get credentials. Also does some fallbacks in case kadmin/fqdn |
||||
diff --git a/src/tests/t_kadmin.py b/src/tests/t_kadmin.py |
||||
index fe6a3cc2e..98453d92e 100644 |
||||
--- a/src/tests/t_kadmin.py |
||||
+++ b/src/tests/t_kadmin.py |
||||
@@ -51,4 +51,16 @@ for i in range(200): |
||||
realm.run_kadmin(['addprinc', '-randkey', 'foo%d' % i]) |
||||
realm.run_kadmin(['listprincs'], expected_msg='foo199') |
||||
|
||||
+# Test kadmin -k with the default principal, with and without |
||||
+# fallback. This operation requires canonicalization against the |
||||
+# keytab in krb5_get_init_creds_keytab() as the |
||||
+# krb5_sname_to_principal() result won't have a realm. Try with and |
||||
+# without without fallback processing since the code paths are |
||||
+# different. |
||||
+mark('kadmin -k') |
||||
+realm.run([kadmin, '-k', 'getprinc', realm.host_princ]) |
||||
+no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}} |
||||
+no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) |
||||
+realm.run([kadmin, '-k', 'getprinc', realm.host_princ], env=no_canon) |
||||
+ |
||||
success('kadmin and kpasswd tests') |
@ -0,0 +1,552 @@
@@ -0,0 +1,552 @@
|
||||
From f85a818fe1a7438db7e1ea579818da67e0be017d Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Sat, 15 May 2021 17:35:25 -0400 |
||||
Subject: [PATCH] Fix softpkcs11 build issues with openssl 3.0 |
||||
|
||||
EVP_PKEY_get0_RSA() has been modified to have const return type. Remove |
||||
its usages in favor of the EVP_PKEY interface. Also remove calls to |
||||
RSA_blinding_off(), which we don't need and would require a non-const |
||||
object. Similarly, remove RSA_set_method() calls that set a pre-existing |
||||
default. |
||||
|
||||
Since softpkcs11 doesn't link against krb5 and can't use zap(), allocate |
||||
buffers with OPENSSL_malloc() so can use OPENSSL_clear_free(). |
||||
|
||||
Move several argument validation checks to the top of their functions. |
||||
|
||||
Fix some incorrect/inconsistent log messages. |
||||
|
||||
(cherry picked from commit 00de1aad7b3647b91017c7009b0bc65cd0c8b2e0) |
||||
(cherry picked from commit a86b780ef275b35e8dc1e6d1886ec8e8d941f7c4) |
||||
--- |
||||
src/tests/softpkcs11/main.c | 360 ++++++++++++++---------------------- |
||||
1 file changed, 141 insertions(+), 219 deletions(-) |
||||
|
||||
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c |
||||
index 1cccdfb43..caa537b68 100644 |
||||
--- a/src/tests/softpkcs11/main.c |
||||
+++ b/src/tests/softpkcs11/main.c |
||||
@@ -375,10 +375,9 @@ add_st_object(void) |
||||
return NULL; |
||||
soft_token.object.objs = objs; |
||||
|
||||
- o = malloc(sizeof(*o)); |
||||
+ o = calloc(1, sizeof(*o)); |
||||
if (o == NULL) |
||||
return NULL; |
||||
- memset(o, 0, sizeof(*o)); |
||||
o->attrs = NULL; |
||||
o->num_attributes = 0; |
||||
o->object_handle = soft_token.object.num_objs; |
||||
@@ -424,7 +423,7 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key) |
||||
CK_ULONG modulus_bits = 0; |
||||
CK_BYTE *exponent = NULL; |
||||
size_t exponent_len = 0; |
||||
- RSA *rsa; |
||||
+ const RSA *rsa; |
||||
const BIGNUM *n, *e; |
||||
|
||||
rsa = EVP_PKEY_get0_RSA(key); |
||||
@@ -445,8 +444,6 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key) |
||||
add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, |
||||
exponent, exponent_len); |
||||
|
||||
- RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); |
||||
- |
||||
free(modulus); |
||||
free(exponent); |
||||
} |
||||
@@ -679,10 +676,6 @@ add_certificate(char *label, |
||||
} else { |
||||
/* XXX verify keytype */ |
||||
|
||||
- if (key_type == CKK_RSA) |
||||
- RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key), |
||||
- RSA_PKCS1_OpenSSL()); |
||||
- |
||||
if (X509_check_private_key(cert, o->u.private_key.key) != 1) { |
||||
EVP_PKEY_free(o->u.private_key.key); |
||||
o->u.private_key.key = NULL; |
||||
@@ -695,7 +688,7 @@ add_certificate(char *label, |
||||
} |
||||
|
||||
ret = CKR_OK; |
||||
- out: |
||||
+out: |
||||
if (ret != CKR_OK) { |
||||
st_logf("something went wrong when adding cert!\n"); |
||||
|
||||
@@ -1224,8 +1217,6 @@ C_Login(CK_SESSION_HANDLE hSession, |
||||
} |
||||
|
||||
/* XXX check keytype */ |
||||
- RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key), |
||||
- RSA_PKCS1_OpenSSL()); |
||||
|
||||
if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) { |
||||
EVP_PKEY_free(o->u.private_key.key); |
||||
@@ -1495,8 +1486,9 @@ C_Encrypt(CK_SESSION_HANDLE hSession, |
||||
struct st_object *o; |
||||
void *buffer = NULL; |
||||
CK_RV ret; |
||||
- RSA *rsa; |
||||
- int padding, len, buffer_len, padding_len; |
||||
+ size_t buffer_len = 0; |
||||
+ int padding; |
||||
+ EVP_PKEY_CTX *ctx = NULL; |
||||
|
||||
st_logf("Encrypt\n"); |
||||
|
||||
@@ -1512,70 +1504,58 @@ C_Encrypt(CK_SESSION_HANDLE hSession, |
||||
return CKR_ARGUMENTS_BAD; |
||||
} |
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.public_key); |
||||
- |
||||
- if (rsa == NULL) |
||||
- return CKR_ARGUMENTS_BAD; |
||||
- |
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ |
||||
- |
||||
- buffer_len = RSA_size(rsa); |
||||
- |
||||
- buffer = malloc(buffer_len); |
||||
- if (buffer == NULL) { |
||||
- ret = CKR_DEVICE_MEMORY; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- ret = CKR_OK; |
||||
- switch(state->encrypt_mechanism->mechanism) { |
||||
- case CKM_RSA_PKCS: |
||||
- padding = RSA_PKCS1_PADDING; |
||||
- padding_len = RSA_PKCS1_PADDING_SIZE; |
||||
- break; |
||||
- case CKM_RSA_X_509: |
||||
- padding = RSA_NO_PADDING; |
||||
- padding_len = 0; |
||||
- break; |
||||
- default: |
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- if ((CK_ULONG)buffer_len + padding_len < ulDataLen) { |
||||
- ret = CKR_ARGUMENTS_BAD; |
||||
- goto out; |
||||
- } |
||||
- |
||||
if (pulEncryptedDataLen == NULL) { |
||||
st_logf("pulEncryptedDataLen NULL\n"); |
||||
ret = CKR_ARGUMENTS_BAD; |
||||
goto out; |
||||
} |
||||
|
||||
- if (pData == NULL_PTR) { |
||||
+ if (pData == NULL) { |
||||
st_logf("data NULL\n"); |
||||
ret = CKR_ARGUMENTS_BAD; |
||||
goto out; |
||||
} |
||||
|
||||
- len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding); |
||||
- if (len <= 0) { |
||||
+ switch(state->encrypt_mechanism->mechanism) { |
||||
+ case CKM_RSA_PKCS: |
||||
+ padding = RSA_PKCS1_PADDING; |
||||
+ break; |
||||
+ case CKM_RSA_X_509: |
||||
+ padding = RSA_NO_PADDING; |
||||
+ break; |
||||
+ default: |
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL); |
||||
+ if (ctx == NULL || EVP_PKEY_encrypt_init(ctx) <= 0 || |
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || |
||||
+ EVP_PKEY_encrypt(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) { |
||||
ret = CKR_DEVICE_ERROR; |
||||
goto out; |
||||
} |
||||
- if (len > buffer_len) |
||||
- abort(); |
||||
|
||||
- if (pEncryptedData != NULL_PTR) |
||||
- memcpy(pEncryptedData, buffer, len); |
||||
- *pulEncryptedDataLen = len; |
||||
- |
||||
- out: |
||||
- if (buffer) { |
||||
- memset(buffer, 0, buffer_len); |
||||
- free(buffer); |
||||
+ buffer = OPENSSL_malloc(buffer_len); |
||||
+ if (buffer == NULL) { |
||||
+ ret = CKR_DEVICE_MEMORY; |
||||
+ goto out; |
||||
} |
||||
+ |
||||
+ if (EVP_PKEY_encrypt(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) { |
||||
+ ret = CKR_DEVICE_ERROR; |
||||
+ goto out; |
||||
+ } |
||||
+ st_logf("Encrypt done\n"); |
||||
+ |
||||
+ if (pEncryptedData != NULL) |
||||
+ memcpy(pEncryptedData, buffer, buffer_len); |
||||
+ *pulEncryptedDataLen = buffer_len; |
||||
+ |
||||
+ ret = CKR_OK; |
||||
+out: |
||||
+ OPENSSL_clear_free(buffer, buffer_len); |
||||
+ EVP_PKEY_CTX_free(ctx); |
||||
return ret; |
||||
} |
||||
|
||||
@@ -1646,8 +1626,9 @@ C_Decrypt(CK_SESSION_HANDLE hSession, |
||||
struct st_object *o; |
||||
void *buffer = NULL; |
||||
CK_RV ret; |
||||
- RSA *rsa; |
||||
- int padding, len, buffer_len, padding_len; |
||||
+ size_t buffer_len = 0; |
||||
+ int padding; |
||||
+ EVP_PKEY_CTX *ctx = NULL; |
||||
|
||||
st_logf("Decrypt\n"); |
||||
|
||||
@@ -1663,41 +1644,6 @@ C_Decrypt(CK_SESSION_HANDLE hSession, |
||||
return CKR_ARGUMENTS_BAD; |
||||
} |
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); |
||||
- |
||||
- if (rsa == NULL) |
||||
- return CKR_ARGUMENTS_BAD; |
||||
- |
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ |
||||
- |
||||
- buffer_len = RSA_size(rsa); |
||||
- |
||||
- buffer = malloc(buffer_len); |
||||
- if (buffer == NULL) { |
||||
- ret = CKR_DEVICE_MEMORY; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- ret = CKR_OK; |
||||
- switch(state->decrypt_mechanism->mechanism) { |
||||
- case CKM_RSA_PKCS: |
||||
- padding = RSA_PKCS1_PADDING; |
||||
- padding_len = RSA_PKCS1_PADDING_SIZE; |
||||
- break; |
||||
- case CKM_RSA_X_509: |
||||
- padding = RSA_NO_PADDING; |
||||
- padding_len = 0; |
||||
- break; |
||||
- default: |
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- if ((CK_ULONG)buffer_len + padding_len < ulEncryptedDataLen) { |
||||
- ret = CKR_ARGUMENTS_BAD; |
||||
- goto out; |
||||
- } |
||||
- |
||||
if (pulDataLen == NULL) { |
||||
st_logf("pulDataLen NULL\n"); |
||||
ret = CKR_ARGUMENTS_BAD; |
||||
@@ -1710,24 +1656,48 @@ C_Decrypt(CK_SESSION_HANDLE hSession, |
||||
goto out; |
||||
} |
||||
|
||||
- len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer, |
||||
- rsa, padding); |
||||
- if (len <= 0) { |
||||
+ switch(state->decrypt_mechanism->mechanism) { |
||||
+ case CKM_RSA_PKCS: |
||||
+ padding = RSA_PKCS1_PADDING; |
||||
+ break; |
||||
+ case CKM_RSA_X_509: |
||||
+ padding = RSA_NO_PADDING; |
||||
+ break; |
||||
+ default: |
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL); |
||||
+ if (ctx == NULL || EVP_PKEY_decrypt_init(ctx) <= 0 || |
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || |
||||
+ EVP_PKEY_decrypt(ctx, NULL, &buffer_len, pEncryptedData, |
||||
+ ulEncryptedDataLen) <= 0) { |
||||
ret = CKR_DEVICE_ERROR; |
||||
goto out; |
||||
} |
||||
- if (len > buffer_len) |
||||
- abort(); |
||||
+ |
||||
+ buffer = OPENSSL_malloc(buffer_len); |
||||
+ if (buffer == NULL) { |
||||
+ ret = CKR_DEVICE_MEMORY; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ if (EVP_PKEY_decrypt(ctx, buffer, &buffer_len, pEncryptedData, |
||||
+ ulEncryptedDataLen) <= 0) { |
||||
+ ret = CKR_DEVICE_ERROR; |
||||
+ goto out; |
||||
+ } |
||||
+ st_logf("Decrypt done\n"); |
||||
|
||||
if (pData != NULL_PTR) |
||||
- memcpy(pData, buffer, len); |
||||
- *pulDataLen = len; |
||||
+ memcpy(pData, buffer, buffer_len); |
||||
+ *pulDataLen = buffer_len; |
||||
|
||||
- out: |
||||
- if (buffer) { |
||||
- memset(buffer, 0, buffer_len); |
||||
- free(buffer); |
||||
- } |
||||
+ ret = CKR_OK; |
||||
+out: |
||||
+ OPENSSL_clear_free(buffer, buffer_len); |
||||
+ EVP_PKEY_CTX_free(ctx); |
||||
return ret; |
||||
} |
||||
|
||||
@@ -1806,8 +1776,9 @@ C_Sign(CK_SESSION_HANDLE hSession, |
||||
struct st_object *o; |
||||
void *buffer = NULL; |
||||
CK_RV ret; |
||||
- RSA *rsa; |
||||
- int padding, len, buffer_len, padding_len; |
||||
+ int padding; |
||||
+ size_t buffer_len = 0; |
||||
+ EVP_PKEY_CTX *ctx = NULL; |
||||
|
||||
st_logf("Sign\n"); |
||||
VERIFY_SESSION_HANDLE(hSession, &state); |
||||
@@ -1822,40 +1793,6 @@ C_Sign(CK_SESSION_HANDLE hSession, |
||||
return CKR_ARGUMENTS_BAD; |
||||
} |
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.private_key.key); |
||||
- |
||||
- if (rsa == NULL) |
||||
- return CKR_ARGUMENTS_BAD; |
||||
- |
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ |
||||
- |
||||
- buffer_len = RSA_size(rsa); |
||||
- |
||||
- buffer = malloc(buffer_len); |
||||
- if (buffer == NULL) { |
||||
- ret = CKR_DEVICE_MEMORY; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- switch(state->sign_mechanism->mechanism) { |
||||
- case CKM_RSA_PKCS: |
||||
- padding = RSA_PKCS1_PADDING; |
||||
- padding_len = RSA_PKCS1_PADDING_SIZE; |
||||
- break; |
||||
- case CKM_RSA_X_509: |
||||
- padding = RSA_NO_PADDING; |
||||
- padding_len = 0; |
||||
- break; |
||||
- default: |
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- if ((CK_ULONG)buffer_len < ulDataLen + padding_len) { |
||||
- ret = CKR_ARGUMENTS_BAD; |
||||
- goto out; |
||||
- } |
||||
- |
||||
if (pulSignatureLen == NULL) { |
||||
st_logf("signature len NULL\n"); |
||||
ret = CKR_ARGUMENTS_BAD; |
||||
@@ -1868,26 +1805,46 @@ C_Sign(CK_SESSION_HANDLE hSession, |
||||
goto out; |
||||
} |
||||
|
||||
- len = RSA_private_encrypt(ulDataLen, pData, buffer, rsa, padding); |
||||
- st_logf("private encrypt done\n"); |
||||
- if (len <= 0) { |
||||
+ switch(state->sign_mechanism->mechanism) { |
||||
+ case CKM_RSA_PKCS: |
||||
+ padding = RSA_PKCS1_PADDING; |
||||
+ break; |
||||
+ case CKM_RSA_X_509: |
||||
+ padding = RSA_NO_PADDING; |
||||
+ break; |
||||
+ default: |
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL); |
||||
+ if (ctx == NULL || EVP_PKEY_sign_init(ctx) <= 0 || |
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || |
||||
+ EVP_PKEY_sign(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) { |
||||
ret = CKR_DEVICE_ERROR; |
||||
goto out; |
||||
} |
||||
- if (len > buffer_len) |
||||
- abort(); |
||||
|
||||
- if (pSignature != NULL_PTR) |
||||
- memcpy(pSignature, buffer, len); |
||||
- *pulSignatureLen = len; |
||||
+ buffer = OPENSSL_malloc(buffer_len); |
||||
+ if (buffer == NULL) { |
||||
+ ret = CKR_DEVICE_MEMORY; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ if (EVP_PKEY_sign(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) { |
||||
+ ret = CKR_DEVICE_ERROR; |
||||
+ goto out; |
||||
+ } |
||||
+ st_logf("Sign done\n"); |
||||
+ |
||||
+ if (pSignature != NULL) |
||||
+ memcpy(pSignature, buffer, buffer_len); |
||||
+ *pulSignatureLen = buffer_len; |
||||
|
||||
ret = CKR_OK; |
||||
- |
||||
- out: |
||||
- if (buffer) { |
||||
- memset(buffer, 0, buffer_len); |
||||
- free(buffer); |
||||
- } |
||||
+out: |
||||
+ OPENSSL_clear_free(buffer, buffer_len); |
||||
+ EVP_PKEY_CTX_free(ctx); |
||||
return ret; |
||||
} |
||||
|
||||
@@ -1951,10 +1908,9 @@ C_Verify(CK_SESSION_HANDLE hSession, |
||||
{ |
||||
struct session_state *state; |
||||
struct st_object *o; |
||||
- void *buffer = NULL; |
||||
CK_RV ret; |
||||
- RSA *rsa; |
||||
- int padding, len, buffer_len; |
||||
+ int padding; |
||||
+ EVP_PKEY_CTX *ctx = NULL; |
||||
|
||||
st_logf("Verify\n"); |
||||
VERIFY_SESSION_HANDLE(hSession, &state); |
||||
@@ -1969,39 +1925,6 @@ C_Verify(CK_SESSION_HANDLE hSession, |
||||
return CKR_ARGUMENTS_BAD; |
||||
} |
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.public_key); |
||||
- |
||||
- if (rsa == NULL) |
||||
- return CKR_ARGUMENTS_BAD; |
||||
- |
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */ |
||||
- |
||||
- buffer_len = RSA_size(rsa); |
||||
- |
||||
- buffer = malloc(buffer_len); |
||||
- if (buffer == NULL) { |
||||
- ret = CKR_DEVICE_MEMORY; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- ret = CKR_OK; |
||||
- switch(state->verify_mechanism->mechanism) { |
||||
- case CKM_RSA_PKCS: |
||||
- padding = RSA_PKCS1_PADDING; |
||||
- break; |
||||
- case CKM_RSA_X_509: |
||||
- padding = RSA_NO_PADDING; |
||||
- break; |
||||
- default: |
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- if ((CK_ULONG)buffer_len < ulDataLen) { |
||||
- ret = CKR_ARGUMENTS_BAD; |
||||
- goto out; |
||||
- } |
||||
- |
||||
if (pSignature == NULL) { |
||||
st_logf("signature NULL\n"); |
||||
ret = CKR_ARGUMENTS_BAD; |
||||
@@ -2014,34 +1937,34 @@ C_Verify(CK_SESSION_HANDLE hSession, |
||||
goto out; |
||||
} |
||||
|
||||
- len = RSA_public_decrypt(ulDataLen, pData, buffer, rsa, padding); |
||||
- st_logf("private encrypt done\n"); |
||||
- if (len <= 0) { |
||||
+ switch(state->verify_mechanism->mechanism) { |
||||
+ case CKM_RSA_PKCS: |
||||
+ padding = RSA_PKCS1_PADDING; |
||||
+ break; |
||||
+ case CKM_RSA_X_509: |
||||
+ padding = RSA_NO_PADDING; |
||||
+ break; |
||||
+ default: |
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED; |
||||
+ goto out; |
||||
+ } |
||||
+ |
||||
+ ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL); |
||||
+ if (ctx == NULL || EVP_PKEY_verify_init(ctx) <= 0 || |
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || |
||||
+ EVP_PKEY_verify(ctx, pSignature, ulSignatureLen, pData, |
||||
+ ulDataLen) <= 0) { |
||||
ret = CKR_DEVICE_ERROR; |
||||
goto out; |
||||
} |
||||
- if (len > buffer_len) |
||||
- abort(); |
||||
+ st_logf("Verify done\n"); |
||||
|
||||
- if ((CK_ULONG)len != ulSignatureLen) { |
||||
- ret = CKR_GENERAL_ERROR; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- if (memcmp(pSignature, buffer, len) != 0) { |
||||
- ret = CKR_GENERAL_ERROR; |
||||
- goto out; |
||||
- } |
||||
- |
||||
- out: |
||||
- if (buffer) { |
||||
- memset(buffer, 0, buffer_len); |
||||
- free(buffer); |
||||
- } |
||||
+ ret = CKR_OK; |
||||
+out: |
||||
+ EVP_PKEY_CTX_free(ctx); |
||||
return ret; |
||||
} |
||||
|
||||
- |
||||
CK_RV |
||||
C_VerifyUpdate(CK_SESSION_HANDLE hSession, |
||||
CK_BYTE_PTR pPart, |
||||
@@ -2072,7 +1995,6 @@ C_GenerateRandom(CK_SESSION_HANDLE hSession, |
||||
return CKR_FUNCTION_NOT_SUPPORTED; |
||||
} |
||||
|
||||
- |
||||
CK_FUNCTION_LIST funcs = { |
||||
{ 2, 11 }, |
||||
C_Initialize, |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
From 8f70ad82a645ccb7fb1677d260baa5e4112890d4 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Mon, 7 Jun 2021 13:27:29 -0400 |
||||
Subject: [PATCH] Fix some principal realm canonicalization cases |
||||
|
||||
The no_hostrealm and subst_defrealm flags in struct canonprinc were |
||||
only applied when dns_canonicalize_hostname=fallback; in the other |
||||
cases, the initial krb5_sname_to_principal() result is treated as |
||||
canonical. For no_hostrealm this limitation doesn't currently matter, |
||||
because all uses pass a principal with no realm as input. However, |
||||
subst_defrealm is used to convert the referral realm to the default |
||||
realm in krb5_get_init_creds_keytab(), krb5_cc_cache_match(), and |
||||
gss_acquire_cred() when it needs to check the desired name against a |
||||
specified ccache. |
||||
|
||||
In k5_canonprinc(), if the input principal is a |
||||
krb5_sname_to_principal() result and fallback isn't in effect, apply |
||||
subst_defrealm. Document in os-proto.h that no_hostrealm doesn't |
||||
remove an existing realm and that krb5_sname_to_principal() may |
||||
already have looked one up. |
||||
|
||||
ticket: 9011 (new) |
||||
(cherry picked from commit c077d0c6430c4ac163443aacc03d14d206a4cbb8) |
||||
(cherry picked from commit 5ae9bc98f23aeaa2ce17debe5a9b0cf1130e54ed) |
||||
--- |
||||
src/lib/krb5/os/os-proto.h | 13 +++++++++---- |
||||
src/lib/krb5/os/sn2princ.c | 24 +++++++++++++++++++++--- |
||||
2 files changed, 30 insertions(+), 7 deletions(-) |
||||
|
||||
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h |
||||
index 7d5e7978f..a985f2aec 100644 |
||||
--- a/src/lib/krb5/os/os-proto.h |
||||
+++ b/src/lib/krb5/os/os-proto.h |
||||
@@ -85,10 +85,15 @@ struct sendto_callback_info { |
||||
|
||||
/* |
||||
* Initialize with all zeros except for princ. Set no_hostrealm to disable |
||||
- * host-to-realm lookup, which ordinarily happens after canonicalizing the host |
||||
- * part. Set subst_defrealm to substitute the default realm for the referral |
||||
- * realm after realm lookup (this has no effect if no_hostrealm is set). Free |
||||
- * with free_canonprinc() when done. |
||||
+ * host-to-realm lookup, which ordinarily happens during fallback processing |
||||
+ * after canonicalizing the host part. Set subst_defrealm to substitute the |
||||
+ * default realm for the referral realm after realm lookup. Do not set both |
||||
+ * flags. Free with free_canonprinc() when done. |
||||
+ * |
||||
+ * no_hostrealm only applies if fallback processing is in use |
||||
+ * (dns_canonicalize_hostname = fallback). It will not remove the realm if |
||||
+ * krb5_sname_to_principal() already canonicalized the hostname and looked up a |
||||
+ * realm. subst_defrealm applies whether or not fallback processing is in use. |
||||
*/ |
||||
struct canonprinc { |
||||
krb5_const_principal princ; |
||||
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c |
||||
index c99b7da17..93c155932 100644 |
||||
--- a/src/lib/krb5/os/sn2princ.c |
||||
+++ b/src/lib/krb5/os/sn2princ.c |
||||
@@ -271,18 +271,36 @@ krb5_error_code |
||||
k5_canonprinc(krb5_context context, struct canonprinc *iter, |
||||
krb5_const_principal *princ_out) |
||||
{ |
||||
+ krb5_error_code ret; |
||||
int step = ++iter->step; |
||||
|
||||
*princ_out = NULL; |
||||
|
||||
- /* If we're not doing fallback, the input principal is canonical. */ |
||||
- if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK || |
||||
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 || |
||||
+ /* If the hostname isn't from krb5_sname_to_principal(), the input |
||||
+ * principal is canonical. */ |
||||
+ if (iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 || |
||||
iter->princ->data[1].length == 0) { |
||||
*princ_out = (step == 1) ? iter->princ : NULL; |
||||
return 0; |
||||
} |
||||
|
||||
+ /* If we're not doing fallback, the hostname is canonical, but we may need |
||||
+ * to substitute the default realm. */ |
||||
+ if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK) { |
||||
+ if (step > 1) |
||||
+ return 0; |
||||
+ iter->copy = *iter->princ; |
||||
+ if (iter->subst_defrealm && iter->copy.realm.length == 0) { |
||||
+ ret = krb5_get_default_realm(context, &iter->realm); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ iter->copy = *iter->princ; |
||||
+ iter->copy.realm = string2data(iter->realm); |
||||
+ } |
||||
+ *princ_out = &iter->copy; |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
/* Canonicalize without DNS at step 1, with DNS at step 2. */ |
||||
if (step > 2) |
||||
return 0; |
@ -0,0 +1,301 @@
@@ -0,0 +1,301 @@
|
||||
From e3f3d31a3db23f6c8437cd0efe45f67a7f4fc6aa Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Sat, 15 May 2021 21:18:06 -0400 |
||||
Subject: [PATCH] Handle OpenSSL 3's providers |
||||
|
||||
OpenSSL 3 compartmentalizes what algorithms it uses, which for us means |
||||
another hoop to jump through to use dubious cryptography. (Right now, |
||||
we need to load "legacy" in order to access MD4 and RC4.) |
||||
|
||||
Use our normal initializer logic to set up providers both in the OpenSSL |
||||
provider an the PKINIT plugin. Since DT_FINI is too late, release them |
||||
using atexit() as OpenSSL does. |
||||
|
||||
(cherry picked from commit bea5a703a06da1f1ab56821b77a2d3661cb0dda4) |
||||
[rharwood@redhat.com: work around des3 removal and rc4 fips changes] |
||||
--- |
||||
src/configure.ac | 1 + |
||||
src/lib/crypto/openssl/enc_provider/aes.c | 16 ++++++ |
||||
.../crypto/openssl/enc_provider/camellia.c | 16 ++++++ |
||||
src/lib/crypto/openssl/enc_provider/rc4.c | 4 ++ |
||||
.../crypto/openssl/hash_provider/hash_evp.c | 5 ++ |
||||
src/lib/crypto/openssl/init.c | 53 +++++++++++++++++++ |
||||
src/plugins/preauth/pkinit/Makefile.in | 1 + |
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 33 ++++++++++-- |
||||
8 files changed, 126 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac |
||||
index 9c2e816fe..20066918b 100644 |
||||
--- a/src/configure.ac |
||||
+++ b/src/configure.ac |
||||
@@ -284,6 +284,7 @@ AC_SUBST(CRYPTO_IMPL_LIBS) |
||||
|
||||
if test "$CRYPTO_IMPL" = openssl; then |
||||
AC_CHECK_FUNCS(EVP_KDF_fetch) |
||||
+ AC_CHECK_FUNCS(OSSL_PROVIDER_load) |
||||
fi |
||||
|
||||
AC_ARG_WITH([prng-alg], |
||||
diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c |
||||
index 6b4622fe9..31c90a69d 100644 |
||||
--- a/src/lib/crypto/openssl/enc_provider/aes.c |
||||
+++ b/src/lib/crypto/openssl/enc_provider/aes.c |
||||
@@ -68,6 +68,10 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
EVP_CIPHER_CTX *ctx; |
||||
struct iov_cursor cursor; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
ctx = EVP_CIPHER_CTX_new(); |
||||
if (ctx == NULL) |
||||
return ENOMEM; |
||||
@@ -102,6 +106,10 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
EVP_CIPHER_CTX *ctx; |
||||
struct iov_cursor cursor; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
ctx = EVP_CIPHER_CTX_new(); |
||||
if (ctx == NULL) |
||||
return ENOMEM; |
||||
@@ -137,6 +145,10 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
struct iov_cursor cursor; |
||||
AES_KEY enck; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
memset(iv_cts,0,sizeof(iv_cts)); |
||||
if (ivec && ivec->data){ |
||||
if (ivec->length != sizeof(iv_cts)) |
||||
@@ -190,6 +202,10 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
struct iov_cursor cursor; |
||||
AES_KEY deck; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
memset(iv_cts,0,sizeof(iv_cts)); |
||||
if (ivec && ivec->data){ |
||||
if (ivec->length != sizeof(iv_cts)) |
||||
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c |
||||
index f79679a0b..7cc7fc6fb 100644 |
||||
--- a/src/lib/crypto/openssl/enc_provider/camellia.c |
||||
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c |
||||
@@ -92,6 +92,10 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
EVP_CIPHER_CTX *ctx; |
||||
struct iov_cursor cursor; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
ctx = EVP_CIPHER_CTX_new(); |
||||
if (ctx == NULL) |
||||
return ENOMEM; |
||||
@@ -126,6 +130,10 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
EVP_CIPHER_CTX *ctx; |
||||
struct iov_cursor cursor; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
ctx = EVP_CIPHER_CTX_new(); |
||||
if (ctx == NULL) |
||||
return ENOMEM; |
||||
@@ -161,6 +169,10 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
struct iov_cursor cursor; |
||||
CAMELLIA_KEY enck; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
memset(iv_cts,0,sizeof(iv_cts)); |
||||
if (ivec && ivec->data){ |
||||
if (ivec->length != sizeof(iv_cts)) |
||||
@@ -214,6 +226,10 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, |
||||
struct iov_cursor cursor; |
||||
CAMELLIA_KEY deck; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
memset(iv_cts,0,sizeof(iv_cts)); |
||||
if (ivec && ivec->data){ |
||||
if (ivec->length != sizeof(iv_cts)) |
||||
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c |
||||
index 9bf407899..a10cb5192 100644 |
||||
--- a/src/lib/crypto/openssl/enc_provider/rc4.c |
||||
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c |
||||
@@ -66,6 +66,10 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data, |
||||
EVP_CIPHER_CTX *ctx = NULL; |
||||
struct arcfour_state *arcstate; |
||||
|
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
if (FIPS_mode()) |
||||
return KRB5_CRYPTO_INTERNAL; |
||||
|
||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c |
||||
index 2eb5139c0..09d7b3896 100644 |
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c |
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c |
||||
@@ -41,6 +41,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, |
||||
const krb5_data *d; |
||||
size_t i; |
||||
int ok; |
||||
+ krb5_error_code ret; |
||||
+ |
||||
+ ret = krb5int_crypto_init(); |
||||
+ if (ret) |
||||
+ return ret; |
||||
|
||||
if (output->length != (unsigned int)EVP_MD_size(type)) |
||||
return KRB5_CRYPTO_INTERNAL; |
||||
diff --git a/src/lib/crypto/openssl/init.c b/src/lib/crypto/openssl/init.c |
||||
index 1139bce53..f72dbfe81 100644 |
||||
--- a/src/lib/crypto/openssl/init.c |
||||
+++ b/src/lib/crypto/openssl/init.c |
||||
@@ -26,12 +26,65 @@ |
||||
|
||||
#include "crypto_int.h" |
||||
|
||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD |
||||
+ |
||||
+/* |
||||
+ * Starting in OpenSSL 3, algorithms are grouped into containers called |
||||
+ * "providers", not all of which are loaded by default. At time of writing, |
||||
+ * we need MD4 and RC4 from the legacy provider. Oddly, 3DES is not in |
||||
+ * legacy. |
||||
+ */ |
||||
+ |
||||
+#include <openssl/provider.h> |
||||
+ |
||||
+static OSSL_PROVIDER *legacy_provider = NULL; |
||||
+static OSSL_PROVIDER *default_provider = NULL; |
||||
+ |
||||
+static void |
||||
+unload_providers(void) |
||||
+{ |
||||
+ if (default_provider != NULL) |
||||
+ (void)OSSL_PROVIDER_unload(default_provider); |
||||
+ if (legacy_provider != NULL) |
||||
+ (void)OSSL_PROVIDER_unload(legacy_provider); |
||||
+ default_provider = NULL; |
||||
+ legacy_provider = NULL; |
||||
+} |
||||
+ |
||||
+int |
||||
+krb5int_crypto_impl_init(void) |
||||
+{ |
||||
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); |
||||
+ default_provider = OSSL_PROVIDER_load(NULL, "default"); |
||||
+ |
||||
+ /* |
||||
+ * Someone might build openssl without the legacy provider. They will |
||||
+ * have a bad time, but some things will still work. I don't know think |
||||
+ * this configuration is worth supporting. |
||||
+ */ |
||||
+ if (legacy_provider == NULL || default_provider == NULL) |
||||
+ abort(); |
||||
+ |
||||
+ /* |
||||
+ * If we attempt to do this with our normal LIBFINIFUNC logic (DT_FINI), |
||||
+ * OpenSSL will have cleaned itself up by the time we're invoked. OpenSSL |
||||
+ * registers its cleanup (OPENSSL_cleanup) with atexit() - do the same and |
||||
+ * we'll be higher on the stack. |
||||
+ */ |
||||
+ atexit(unload_providers); |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+#else /* !HAVE_OSSL_PROVIDER_LOAD */ |
||||
+ |
||||
int |
||||
krb5int_crypto_impl_init(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
+#endif |
||||
+ |
||||
void |
||||
krb5int_crypto_impl_cleanup(void) |
||||
{ |
||||
diff --git a/src/plugins/preauth/pkinit/Makefile.in b/src/plugins/preauth/pkinit/Makefile.in |
||||
index 15ca0eb48..d20fb18a8 100644 |
||||
--- a/src/plugins/preauth/pkinit/Makefile.in |
||||
+++ b/src/plugins/preauth/pkinit/Makefile.in |
||||
@@ -5,6 +5,7 @@ MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR) |
||||
LIBBASE=pkinit |
||||
LIBMAJOR=0 |
||||
LIBMINOR=0 |
||||
+LIBINITFUNC=pkinit_openssl_init |
||||
RELDIR=../plugins/preauth/pkinit |
||||
# Depends on libk5crypto and libkrb5 |
||||
SHLIB_EXPDEPS = \ |
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
index 350c2118a..42e5c581d 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
@@ -44,6 +44,13 @@ |
||||
#include <openssl/params.h> |
||||
#endif |
||||
|
||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD |
||||
+#include <openssl/provider.h> |
||||
+ |
||||
+static OSSL_PROVIDER *legacy_provider = NULL; |
||||
+static OSSL_PROVIDER *default_provider = NULL; |
||||
+#endif |
||||
+ |
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ); |
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ); |
||||
|
||||
@@ -2937,12 +2944,32 @@ cleanup: |
||||
return retval; |
||||
} |
||||
|
||||
+/* pkinit_openssl_init() and unload_providers() are largely duplicated from |
||||
+ * lib/crypto/openssl/init.c - see explanations there. */ |
||||
+static void |
||||
+unload_providers(void) |
||||
+{ |
||||
+ if (default_provider != NULL) |
||||
+ (void)OSSL_PROVIDER_unload(default_provider); |
||||
+ if (legacy_provider != NULL) |
||||
+ (void)OSSL_PROVIDER_unload(legacy_provider); |
||||
+ default_provider = NULL; |
||||
+ legacy_provider = NULL; |
||||
+} |
||||
+ |
||||
int |
||||
pkinit_openssl_init() |
||||
{ |
||||
- /* Initialize OpenSSL. */ |
||||
- ERR_load_crypto_strings(); |
||||
- OpenSSL_add_all_algorithms(); |
||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD |
||||
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); |
||||
+ default_provider = OSSL_PROVIDER_load(NULL, "default"); |
||||
+ |
||||
+ if (legacy_provider == NULL || default_provider == NULL) |
||||
+ abort(); |
||||
+ |
||||
+ atexit(unload_providers); |
||||
+#endif |
||||
+ |
||||
return 0; |
||||
} |
||||
|
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
From 68a557557ab8a3208fab8a70daf4d970b9fc4787 Mon Sep 17 00:00:00 2001 |
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com> |
||||
Date: Tue, 30 Mar 2021 14:35:28 +0200 |
||||
Subject: [PATCH] Make KCM iteration fallback work with sssd-kcm |
||||
|
||||
sssd-kcm returns KRB5_CC_IO if the operation code is not known. |
||||
|
||||
ticket: 8990 |
||||
(cherry picked from commit 06afae820a44c1dc96ad88a0b16c3e50bc938b2a) |
||||
(cherry picked from commit 2dbca7e14c945d6394e0e05f285a068dcd541295) |
||||
--- |
||||
src/lib/krb5/ccache/cc_kcm.c | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c |
||||
index 1f81a2190..46705f1da 100644 |
||||
--- a/src/lib/krb5/ccache/cc_kcm.c |
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c |
||||
@@ -876,7 +876,7 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache, |
||||
ret = kcmreq_get_cred_list(&req, &creds); |
||||
if (ret) |
||||
goto cleanup; |
||||
- } else if (ret == KRB5_FCC_INTERNAL) { |
||||
+ } else if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) { |
||||
/* Fall back to GET_CRED_UUID_LIST. */ |
||||
kcmreq_free(&req); |
||||
kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache); |
@ -0,0 +1,365 @@
@@ -0,0 +1,365 @@
|
||||
From b778f10e31e566269768cba92a0005f35e134333 Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Wed, 19 Jan 2022 19:46:08 +0100 |
||||
Subject: [PATCH] Make kprop work for dump files larger than 4GB |
||||
|
||||
If the dump file size does not fit in 32 bits, encode four zero bytes |
||||
(forcing an error for unmodified kpropd) followed by the size in the |
||||
next 64 bits. |
||||
|
||||
Add a functional test case, but only run it when an environment |
||||
variable is set, as processing a 4GB dump file is too |
||||
resource-intensive for make check. |
||||
|
||||
[ghudson@mit.edu: edited comments and commit message; eliminated use |
||||
of defined constant in some cases; added test case] |
||||
|
||||
ticket: 9053 (new) |
||||
--- |
||||
src/kprop/kprop.c | 37 +++++++++++++++++++++---------------- |
||||
src/kprop/kprop.h | 12 ++++++++++++ |
||||
src/kprop/kprop_util.c | 42 ++++++++++++++++++++++++++++++++++++++++++ |
||||
src/kprop/kpropd.c | 33 +++++++++++++++++++++------------ |
||||
src/tests/t_kprop.py | 34 ++++++++++++++++++++++++++++++++++ |
||||
5 files changed, 130 insertions(+), 28 deletions(-) |
||||
|
||||
diff --git a/src/kprop/kprop.c b/src/kprop/kprop.c |
||||
index 0b53aae7e..5adb4d31f 100644 |
||||
--- a/src/kprop/kprop.c |
||||
+++ b/src/kprop/kprop.c |
||||
@@ -25,6 +25,7 @@ |
||||
*/ |
||||
|
||||
#include "k5-int.h" |
||||
+#include <inttypes.h> |
||||
#include <locale.h> |
||||
#include <sys/file.h> |
||||
#include <signal.h> |
||||
@@ -71,11 +72,11 @@ static void open_connection(krb5_context context, char *host, int *fd_out); |
||||
static void kerberos_authenticate(krb5_context context, |
||||
krb5_auth_context *auth_context, int fd, |
||||
krb5_principal me, krb5_creds **new_creds); |
||||
-static int open_database(krb5_context context, char *data_fn, int *size); |
||||
+static int open_database(krb5_context context, char *data_fn, off_t *size); |
||||
static void close_database(krb5_context context, int fd); |
||||
static void xmit_database(krb5_context context, |
||||
krb5_auth_context auth_context, krb5_creds *my_creds, |
||||
- int fd, int database_fd, int in_database_size); |
||||
+ int fd, int database_fd, off_t in_database_size); |
||||
static void send_error(krb5_context context, krb5_creds *my_creds, int fd, |
||||
char *err_text, krb5_error_code err_code); |
||||
static void update_last_prop_file(char *hostname, char *file_name); |
||||
@@ -90,7 +91,8 @@ static void usage() |
||||
int |
||||
main(int argc, char **argv) |
||||
{ |
||||
- int fd, database_fd, database_size; |
||||
+ int fd, database_fd; |
||||
+ off_t database_size; |
||||
krb5_error_code retval; |
||||
krb5_context context; |
||||
krb5_creds *my_creds; |
||||
@@ -339,7 +341,7 @@ kerberos_authenticate(krb5_context context, krb5_auth_context *auth_context, |
||||
* in the size of the database file. |
||||
*/ |
||||
static int |
||||
-open_database(krb5_context context, char *data_fn, int *size) |
||||
+open_database(krb5_context context, char *data_fn, off_t *size) |
||||
{ |
||||
struct stat stbuf, stbuf_ok; |
||||
char *data_ok_fn; |
||||
@@ -413,19 +415,18 @@ close_database(krb5_context context, int fd) |
||||
static void |
||||
xmit_database(krb5_context context, krb5_auth_context auth_context, |
||||
krb5_creds *my_creds, int fd, int database_fd, |
||||
- int in_database_size) |
||||
+ off_t in_database_size) |
||||
{ |
||||
krb5_int32 n; |
||||
krb5_data inbuf, outbuf; |
||||
- char buf[KPROP_BUFSIZ]; |
||||
+ char buf[KPROP_BUFSIZ], dbsize_buf[KPROP_DBSIZE_MAX_BUFSIZ]; |
||||
krb5_error_code retval; |
||||
krb5_error *error; |
||||
- krb5_ui_4 database_size = in_database_size, send_size, sent_size; |
||||
+ uint64_t database_size = in_database_size, send_size, sent_size; |
||||
|
||||
/* Send over the size. */ |
||||
- send_size = htonl(database_size); |
||||
- inbuf.data = (char *)&send_size; |
||||
- inbuf.length = sizeof(send_size); /* must be 4, really */ |
||||
+ inbuf = make_data(dbsize_buf, sizeof(dbsize_buf)); |
||||
+ encode_database_size(database_size, &inbuf); |
||||
/* KPROP_CKSUMTYPE */ |
||||
retval = krb5_mk_safe(context, auth_context, &inbuf, &outbuf, NULL); |
||||
if (retval) { |
||||
@@ -460,7 +461,7 @@ xmit_database(krb5_context context, krb5_auth_context auth_context, |
||||
retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL); |
||||
if (retval) { |
||||
snprintf(buf, sizeof(buf), |
||||
- "while encoding database block starting at %d", |
||||
+ "while encoding database block starting at %"PRIu64, |
||||
sent_size); |
||||
com_err(progname, retval, "%s", buf); |
||||
send_error(context, my_creds, fd, buf, retval); |
||||
@@ -471,14 +472,14 @@ xmit_database(krb5_context context, krb5_auth_context auth_context, |
||||
if (retval) { |
||||
krb5_free_data_contents(context, &outbuf); |
||||
com_err(progname, retval, |
||||
- _("while sending database block starting at %d"), |
||||
+ _("while sending database block starting at %"PRIu64), |
||||
sent_size); |
||||
exit(1); |
||||
} |
||||
krb5_free_data_contents(context, &outbuf); |
||||
sent_size += n; |
||||
if (debug) |
||||
- printf("%d bytes sent.\n", sent_size); |
||||
+ printf("%"PRIu64" bytes sent.\n", sent_size); |
||||
} |
||||
if (sent_size != database_size) { |
||||
com_err(progname, 0, _("Premature EOF found for database file!")); |
||||
@@ -533,10 +534,14 @@ xmit_database(krb5_context context, krb5_auth_context auth_context, |
||||
exit(1); |
||||
} |
||||
|
||||
- memcpy(&send_size, outbuf.data, sizeof(send_size)); |
||||
- send_size = ntohl(send_size); |
||||
+ retval = decode_database_size(&outbuf, &send_size); |
||||
+ if (retval) { |
||||
+ com_err(progname, retval, _("malformed sent database size message")); |
||||
+ exit(1); |
||||
+ } |
||||
if (send_size != database_size) { |
||||
- com_err(progname, 0, _("Kpropd sent database size %d, expecting %d"), |
||||
+ com_err(progname, 0, _("Kpropd sent database size %"PRIu64 |
||||
+ ", expecting %"PRIu64), |
||||
send_size, database_size); |
||||
exit(1); |
||||
} |
||||
diff --git a/src/kprop/kprop.h b/src/kprop/kprop.h |
||||
index 75331cc8a..3a319b535 100644 |
||||
--- a/src/kprop/kprop.h |
||||
+++ b/src/kprop/kprop.h |
||||
@@ -32,6 +32,7 @@ |
||||
#define KPROP_PROT_VERSION "kprop5_01" |
||||
|
||||
#define KPROP_BUFSIZ 32768 |
||||
+#define KPROP_DBSIZE_MAX_BUFSIZ 12 /* max length of an encoded DB size */ |
||||
|
||||
/* pathnames are in osconf.h, included via k5-int.h */ |
||||
|
||||
@@ -41,3 +42,14 @@ int sockaddr2krbaddr(krb5_context context, int family, struct sockaddr *sa, |
||||
krb5_error_code |
||||
sn2princ_realm(krb5_context context, const char *hostname, const char *sname, |
||||
const char *realm, krb5_principal *princ_out); |
||||
+ |
||||
+/* |
||||
+ * Encode size in four bytes (for backward compatibility) if it fits; otherwise |
||||
+ * use the larger encoding. buf must be allocated with at least |
||||
+ * KPROP_DBSIZE_MAX_BUFSIZ bytes. |
||||
+ */ |
||||
+void encode_database_size(uint64_t size, krb5_data *buf); |
||||
+ |
||||
+/* Decode a database size. Return KRB5KRB_ERR_GENERIC if buf has an invalid |
||||
+ * length or did not encode a 32-bit size compactly. */ |
||||
+krb5_error_code decode_database_size(const krb5_data *buf, uint64_t *size_out); |
||||
diff --git a/src/kprop/kprop_util.c b/src/kprop/kprop_util.c |
||||
index c2b2e8764..c0aa2c89b 100644 |
||||
--- a/src/kprop/kprop_util.c |
||||
+++ b/src/kprop/kprop_util.c |
||||
@@ -92,3 +92,45 @@ sn2princ_realm(krb5_context context, const char *hostname, const char *sname, |
||||
*princ_out = princ; |
||||
return 0; |
||||
} |
||||
+ |
||||
+void |
||||
+encode_database_size(uint64_t size, krb5_data *buf) |
||||
+{ |
||||
+ assert(buf->length >= 12); |
||||
+ if (size > 0 && size <= UINT32_MAX) { |
||||
+ /* Encode in 32 bits for backward compatibility. */ |
||||
+ store_32_be(size, buf->data); |
||||
+ buf->length = 4; |
||||
+ } else { |
||||
+ /* Set the first 32 bits to 0 and encode in the following 64 bits. */ |
||||
+ store_32_be(0, buf->data); |
||||
+ store_64_be(size, buf->data + 4); |
||||
+ buf->length = 12; |
||||
+ } |
||||
+} |
||||
+ |
||||
+krb5_error_code |
||||
+decode_database_size(const krb5_data *buf, uint64_t *size_out) |
||||
+{ |
||||
+ uint64_t size; |
||||
+ |
||||
+ if (buf->length == 12) { |
||||
+ /* A 12-byte buffer must have the first four bytes zeroed. */ |
||||
+ if (load_32_be(buf->data) != 0) |
||||
+ return KRB5KRB_ERR_GENERIC; |
||||
+ |
||||
+ /* The size is stored in the next 64 bits. Values from 1..2^32-1 must |
||||
+ * be encoded in four bytes. */ |
||||
+ size = load_64_be(buf->data + 4); |
||||
+ if (size > 0 && size <= UINT32_MAX) |
||||
+ return KRB5KRB_ERR_GENERIC; |
||||
+ } else if (buf->length == 4) { |
||||
+ size = load_32_be(buf->data); |
||||
+ } else { |
||||
+ /* Invalid buffer size. */ |
||||
+ return KRB5KRB_ERR_GENERIC; |
||||
+ } |
||||
+ |
||||
+ *size_out = size; |
||||
+ return 0; |
||||
+} |
||||
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c |
||||
index c6b8efc28..dd6c697c0 100644 |
||||
--- a/src/kprop/kpropd.c |
||||
+++ b/src/kprop/kpropd.c |
||||
@@ -55,6 +55,7 @@ |
||||
#include "com_err.h" |
||||
#include "fake-addrinfo.h" |
||||
|
||||
+#include <inttypes.h> |
||||
#include <locale.h> |
||||
#include <ctype.h> |
||||
#include <sys/file.h> |
||||
@@ -1358,9 +1359,10 @@ static void |
||||
recv_database(krb5_context context, int fd, int database_fd, |
||||
krb5_data *confmsg) |
||||
{ |
||||
- krb5_ui_4 database_size, received_size; |
||||
+ uint64_t database_size, received_size; |
||||
int n; |
||||
char buf[1024]; |
||||
+ char dbsize_buf[KPROP_DBSIZE_MAX_BUFSIZ]; |
||||
krb5_data inbuf, outbuf; |
||||
krb5_error_code retval; |
||||
|
||||
@@ -1382,10 +1384,17 @@ recv_database(krb5_context context, int fd, int database_fd, |
||||
_("while decoding database size from client")); |
||||
exit(1); |
||||
} |
||||
- memcpy(&database_size, outbuf.data, sizeof(database_size)); |
||||
+ |
||||
+ retval = decode_database_size(&outbuf, &database_size); |
||||
+ if (retval) { |
||||
+ send_error(context, fd, retval, "malformed database size message"); |
||||
+ com_err(progname, retval, |
||||
+ _("malformed database size message from client")); |
||||
+ exit(1); |
||||
+ } |
||||
+ |
||||
krb5_free_data_contents(context, &inbuf); |
||||
krb5_free_data_contents(context, &outbuf); |
||||
- database_size = ntohl(database_size); |
||||
|
||||
/* Initialize the initial vector. */ |
||||
retval = krb5_auth_con_initivector(context, auth_context); |
||||
@@ -1405,7 +1414,7 @@ recv_database(krb5_context context, int fd, int database_fd, |
||||
retval = krb5_read_message(context, &fd, &inbuf); |
||||
if (retval) { |
||||
snprintf(buf, sizeof(buf), |
||||
- "while reading database block starting at offset %d", |
||||
+ "while reading database block starting at offset %"PRIu64, |
||||
received_size); |
||||
com_err(progname, retval, "%s", buf); |
||||
send_error(context, fd, retval, buf); |
||||
@@ -1416,8 +1425,8 @@ recv_database(krb5_context context, int fd, int database_fd, |
||||
retval = krb5_rd_priv(context, auth_context, &inbuf, &outbuf, NULL); |
||||
if (retval) { |
||||
snprintf(buf, sizeof(buf), |
||||
- "while decoding database block starting at offset %d", |
||||
- received_size); |
||||
+ "while decoding database block starting at offset %" |
||||
+ PRIu64, received_size); |
||||
com_err(progname, retval, "%s", buf); |
||||
send_error(context, fd, retval, buf); |
||||
krb5_free_data_contents(context, &inbuf); |
||||
@@ -1427,13 +1436,13 @@ recv_database(krb5_context context, int fd, int database_fd, |
||||
krb5_free_data_contents(context, &inbuf); |
||||
if (n < 0) { |
||||
snprintf(buf, sizeof(buf), |
||||
- "while writing database block starting at offset %d", |
||||
+ "while writing database block starting at offset %"PRIu64, |
||||
received_size); |
||||
send_error(context, fd, errno, buf); |
||||
} else if ((unsigned int)n != outbuf.length) { |
||||
snprintf(buf, sizeof(buf), |
||||
"incomplete write while writing database block starting " |
||||
- "at \noffset %d (%d written, %d expected)", |
||||
+ "at \noffset %"PRIu64" (%d written, %d expected)", |
||||
received_size, n, outbuf.length); |
||||
send_error(context, fd, KRB5KRB_ERR_GENERIC, buf); |
||||
} |
||||
@@ -1444,7 +1453,8 @@ recv_database(krb5_context context, int fd, int database_fd, |
||||
/* OK, we've seen the entire file. Did we get too many bytes? */ |
||||
if (received_size > database_size) { |
||||
snprintf(buf, sizeof(buf), |
||||
- "Received %d bytes, expected %d bytes for database file", |
||||
+ "Received %"PRIu64" bytes, expected %"PRIu64 |
||||
+ " bytes for database file", |
||||
received_size, database_size); |
||||
send_error(context, fd, KRB5KRB_ERR_GENERIC, buf); |
||||
} |
||||
@@ -1454,9 +1464,8 @@ recv_database(krb5_context context, int fd, int database_fd, |
||||
|
||||
/* Create message acknowledging number of bytes received, but |
||||
* don't send it until kdb5_util returns successfully. */ |
||||
- database_size = htonl(database_size); |
||||
- inbuf.data = (char *)&database_size; |
||||
- inbuf.length = sizeof(database_size); |
||||
+ inbuf = make_data(dbsize_buf, sizeof(dbsize_buf)); |
||||
+ encode_database_size(database_size, &inbuf); |
||||
retval = krb5_mk_safe(context,auth_context,&inbuf,confmsg,NULL); |
||||
if (retval) { |
||||
com_err(progname, retval, "while encoding # of received bytes"); |
||||
diff --git a/src/tests/t_kprop.py b/src/tests/t_kprop.py |
||||
index d96f7c560..4421a7c35 100755 |
||||
--- a/src/tests/t_kprop.py |
||||
+++ b/src/tests/t_kprop.py |
||||
@@ -87,5 +87,39 @@ realm.run([kdb5_util, 'dump', dumpfile]) |
||||
realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) |
||||
check_output(kpropd) |
||||
realm.run([kadminl, 'listprincs'], replica3, expected_msg='wakawaka') |
||||
+stop_daemon(kpropd) |
||||
+ |
||||
+# This test is too resource-intensive to be included in "make check" |
||||
+# by default, but it can be enabled in the environment to test the |
||||
+# propagation of databases large enough to require a 12-byte encoding |
||||
+# of the database size. |
||||
+if 'KPROP_LARGE_DB_TEST' in os.environ: |
||||
+ output('Generating >4GB dumpfile\n') |
||||
+ with open(dumpfile, 'w') as f: |
||||
+ f.write('kdb5_util load_dump version 6\n') |
||||
+ f.write('princ\t38\t15\t3\t1\t0\tK/M@KRBTEST.COM\t64\t86400\t0\t0\t0' |
||||
+ '\t0\t0\t0\t8\t2\t0100\t9\t8\t0100010000000000\t2\t28' |
||||
+ '\tb93e105164625f6372656174696f6e404b5242544553542e434f4d00' |
||||
+ '\t1\t1\t18\t62\t2000408c027c250e8cc3b81476414f2214d57c1ce' |
||||
+ '38891e29792e87258247c73547df4d5756266931dd6686b62270e6568' |
||||
+ '95a31ec66bfe913b4f15226227\t-1;\n') |
||||
+ for i in range(1, 20000000): |
||||
+ f.write('princ\t38\t21\t1\t1\t0\tp%08d@KRBTEST.COM' % i) |
||||
+ f.write('\t0\t86400\t0\t0\t0\t0\t0\t0\t2\t27' |
||||
+ '\td73e1051757365722f61646d696e404b5242544553542e434f4d00' |
||||
+ '\t1\t1\t17\t46' |
||||
+ '\t10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c49' |
||||
+ '5605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf\t-1;\n') |
||||
+ assert os.path.getsize(dumpfile) > 4 * 1024 * 1024 * 1024 |
||||
+ with open(dumpfile + '.dump_ok', 'w') as f: |
||||
+ f.write('\0') |
||||
+ conf_large = {'dbmodules': {'db': {'database_name': '$testdir/db.large'}}, |
||||
+ 'realms': {'$realm': {'iprop_resync_timeout': '3600'}}} |
||||
+ large = realm.special_env('large', True, kdc_conf=conf_large) |
||||
+ kpropd = realm.start_kpropd(large, ['-d']) |
||||
+ realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) |
||||
+ check_output(kpropd) |
||||
+ realm.run([kadminl, 'getprinc', 'p19999999'], env=large, |
||||
+ expected_msg='Principal: p19999999') |
||||
|
||||
success('kprop tests') |
||||
-- |
||||
2.37.3 |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,150 @@
@@ -0,0 +1,150 @@
|
||||
From c99ecf1bb49e2fbd0bf30a7b357cf06407b9588a Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Sat, 15 May 2021 18:04:58 -0400 |
||||
Subject: [PATCH] Remove deprecated OpenSSL calls from softpkcs11 |
||||
|
||||
Rewrite add_pubkey_info() in terms of the EVP_PKEY interface. In this |
||||
process, fix its unchecked allocations and fail fast for non-RSA keys. |
||||
|
||||
(cherry picked from commit d6bf42279675100e3e4fe7c6e08eef74d49624cb) |
||||
(cherry picked from commit 5072bfdfaddae762680d0f9d97afa6dbf8274760) |
||||
--- |
||||
src/configure.ac | 1 + |
||||
src/tests/softpkcs11/main.c | 106 ++++++++++++++++++++++++------------ |
||||
2 files changed, 72 insertions(+), 35 deletions(-) |
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac |
||||
index 3e1052db7..eb6307468 100644 |
||||
--- a/src/configure.ac |
||||
+++ b/src/configure.ac |
||||
@@ -1114,6 +1114,7 @@ int i = 1; |
||||
])], k5_cv_openssl_version_okay=yes, k5_cv_openssl_version_okay=no)]) |
||||
old_LIBS="$LIBS" |
||||
AC_CHECK_LIB(crypto, PKCS7_get_signer_info) |
||||
+ AC_CHECK_FUNCS(EVP_PKEY_get_bn_param) |
||||
LIBS="$old_LIBS" |
||||
fi |
||||
if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then |
||||
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c |
||||
index caa537b68..86b4ef711 100644 |
||||
--- a/src/tests/softpkcs11/main.c |
||||
+++ b/src/tests/softpkcs11/main.c |
||||
@@ -413,47 +413,83 @@ add_object_attribute(struct st_object *o, |
||||
return CKR_OK; |
||||
} |
||||
|
||||
+#ifdef HAVE_EVP_PKEY_GET_BN_PARAM |
||||
+ |
||||
+/* Declare owner pointers since EVP_PKEY_get_bn_param() gives us copies. */ |
||||
+#define DECLARE_BIGNUM(name) BIGNUM *name = NULL |
||||
+#define RELEASE_BIGNUM(bn) BN_clear_free(bn) |
||||
static CK_RV |
||||
-add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key) |
||||
+get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e) |
||||
{ |
||||
- switch (key_type) { |
||||
- case CKK_RSA: { |
||||
- CK_BYTE *modulus = NULL; |
||||
- size_t modulus_len = 0; |
||||
- CK_ULONG modulus_bits = 0; |
||||
- CK_BYTE *exponent = NULL; |
||||
- size_t exponent_len = 0; |
||||
- const RSA *rsa; |
||||
- const BIGNUM *n, *e; |
||||
+ if (EVP_PKEY_get_bn_param(key, "n", n) == 0 || |
||||
+ EVP_PKEY_get_bn_param(key, "e", e) == 0) |
||||
+ return CKR_DEVICE_ERROR; |
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(key); |
||||
- RSA_get0_key(rsa, &n, &e, NULL); |
||||
- modulus_bits = BN_num_bits(n); |
||||
- |
||||
- modulus_len = BN_num_bytes(n); |
||||
- modulus = malloc(modulus_len); |
||||
- BN_bn2bin(n, modulus); |
||||
- |
||||
- exponent_len = BN_num_bytes(e); |
||||
- exponent = malloc(exponent_len); |
||||
- BN_bn2bin(e, exponent); |
||||
- |
||||
- add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len); |
||||
- add_object_attribute(o, 0, CKA_MODULUS_BITS, |
||||
- &modulus_bits, sizeof(modulus_bits)); |
||||
- add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, |
||||
- exponent, exponent_len); |
||||
- |
||||
- free(modulus); |
||||
- free(exponent); |
||||
- } |
||||
- default: |
||||
- /* XXX */ |
||||
- break; |
||||
- } |
||||
return CKR_OK; |
||||
} |
||||
|
||||
+#else |
||||
+ |
||||
+/* Declare const pointers since the old API gives us aliases. */ |
||||
+#define DECLARE_BIGNUM(name) const BIGNUM *name |
||||
+#define RELEASE_BIGNUM(bn) |
||||
+static CK_RV |
||||
+get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e) |
||||
+{ |
||||
+ const RSA *rsa; |
||||
+ |
||||
+ rsa = EVP_PKEY_get0_RSA(key); |
||||
+ RSA_get0_key(rsa, n, e, NULL); |
||||
+ |
||||
+ return CKR_OK; |
||||
+} |
||||
+ |
||||
+#endif |
||||
+ |
||||
+static CK_RV |
||||
+add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key) |
||||
+{ |
||||
+ CK_BYTE *modulus = NULL, *exponent = 0; |
||||
+ size_t modulus_len = 0, exponent_len = 0; |
||||
+ CK_ULONG modulus_bits = 0; |
||||
+ CK_RV ret; |
||||
+ DECLARE_BIGNUM(n); |
||||
+ DECLARE_BIGNUM(e); |
||||
+ |
||||
+ if (key_type != CKK_RSA) |
||||
+ abort(); |
||||
+ |
||||
+ ret = get_bignums(key, &n, &e); |
||||
+ if (ret != CKR_OK) |
||||
+ goto done; |
||||
+ |
||||
+ modulus_bits = BN_num_bits(n); |
||||
+ modulus_len = BN_num_bytes(n); |
||||
+ exponent_len = BN_num_bytes(e); |
||||
+ |
||||
+ modulus = malloc(modulus_len); |
||||
+ exponent = malloc(exponent_len); |
||||
+ if (modulus == NULL || exponent == NULL) { |
||||
+ ret = CKR_DEVICE_MEMORY; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ BN_bn2bin(n, modulus); |
||||
+ BN_bn2bin(e, exponent); |
||||
+ |
||||
+ add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len); |
||||
+ add_object_attribute(o, 0, CKA_MODULUS_BITS, &modulus_bits, |
||||
+ sizeof(modulus_bits)); |
||||
+ add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, exponent, exponent_len); |
||||
+ |
||||
+ ret = CKR_OK; |
||||
+done: |
||||
+ free(modulus); |
||||
+ free(exponent); |
||||
+ RELEASE_BIGNUM(n); |
||||
+ RELEASE_BIGNUM(e); |
||||
+ return ret; |
||||
+} |
||||
|
||||
static int |
||||
pem_callback(char *buf, int num, int w, void *key) |
@ -0,0 +1,188 @@
@@ -0,0 +1,188 @@
|
||||
From dea9421ccdbe5c8f63aae85341a8f091c6019407 Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Wed, 1 Jun 2022 18:02:04 +0200 |
||||
Subject: [PATCH] Set reasonable supportedCMSTypes in PKINIT |
||||
|
||||
The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know |
||||
the algorithms it supports for verification of the CMS data signature. |
||||
(The MIT krb5 KDC currently ignores this list, but other |
||||
implementations use it.) |
||||
|
||||
Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption. |
||||
|
||||
[ghudson@mit.edu: simplified code and used appropriate helpers; edited |
||||
commit message] |
||||
|
||||
ticket: 9066 (new) |
||||
--- |
||||
src/plugins/preauth/pkinit/Makefile.in | 4 +- |
||||
src/plugins/preauth/pkinit/pkinit_clnt.c | 8 ++++ |
||||
...nit_kdf_constants.c => pkinit_constants.c} | 24 ++++++++++++ |
||||
src/plugins/preauth/pkinit/pkinit_crypto.h | 16 ++++++++ |
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 39 +++++++++++++++++++ |
||||
5 files changed, 89 insertions(+), 2 deletions(-) |
||||
rename src/plugins/preauth/pkinit/{pkinit_kdf_constants.c => pkinit_constants.c} (76%) |
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/Makefile.in b/src/plugins/preauth/pkinit/Makefile.in |
||||
index d20fb18a8..97aaded03 100644 |
||||
--- a/src/plugins/preauth/pkinit/Makefile.in |
||||
+++ b/src/plugins/preauth/pkinit/Makefile.in |
||||
@@ -18,7 +18,7 @@ STLIBOBJS= \ |
||||
pkinit_srv.o \ |
||||
pkinit_lib.o \ |
||||
pkinit_clnt.o \ |
||||
- pkinit_kdf_constants.o \ |
||||
+ pkinit_constants.o \ |
||||
pkinit_profile.o \ |
||||
pkinit_identity.o \ |
||||
pkinit_matching.o \ |
||||
@@ -29,7 +29,7 @@ SRCS= \ |
||||
$(srcdir)/pkinit_srv.c \ |
||||
$(srcdir)/pkinit_lib.c \ |
||||
$(srcdir)/pkinit_kdf_test.c \ |
||||
- $(srcdir)/pkinit_kdf_constants.c \ |
||||
+ $(srcdir)/pkinit_constants.c \ |
||||
$(srcdir)/pkinit_clnt.c \ |
||||
$(srcdir)/pkinit_profile.c \ |
||||
$(srcdir)/pkinit_identity.c \ |
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c |
||||
index a385da7c3..2817cc213 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c |
||||
@@ -212,6 +212,14 @@ pkinit_as_req_create(krb5_context context, |
||||
auth_pack.clientPublicValue = &info; |
||||
auth_pack.supportedKDFs = (krb5_data **)supported_kdf_alg_ids; |
||||
|
||||
+ /* add List of CMS algorithms */ |
||||
+ retval = create_krb5_supportedCMSTypes(context, plgctx->cryptoctx, |
||||
+ reqctx->cryptoctx, |
||||
+ reqctx->idctx, &cmstypes); |
||||
+ auth_pack.supportedCMSTypes = cmstypes; |
||||
+ if (retval) |
||||
+ goto cleanup; |
||||
+ |
||||
switch(protocol) { |
||||
case DH_PROTOCOL: |
||||
TRACE_PKINIT_CLIENT_REQ_DH(context); |
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_kdf_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c |
||||
similarity index 76% |
||||
rename from src/plugins/preauth/pkinit/pkinit_kdf_constants.c |
||||
rename to src/plugins/preauth/pkinit/pkinit_constants.c |
||||
index 1604f1670..1832e8f7b 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_kdf_constants.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c |
||||
@@ -57,3 +57,27 @@ krb5_data const * const supported_kdf_alg_ids[] = { |
||||
&sha512_id, |
||||
NULL |
||||
}; |
||||
+ |
||||
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840) |
||||
+ * rsadsi(113549) pkcs(1) 1 11 */ |
||||
+static char sha256WithRSAEncr_oid[9] = { |
||||
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b |
||||
+}; |
||||
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840) |
||||
+ * rsadsi(113549) pkcs(1) 1 13 */ |
||||
+static char sha512WithRSAEncr_oid[9] = { |
||||
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d |
||||
+}; |
||||
+ |
||||
+const krb5_data sha256WithRSAEncr_id = { |
||||
+ KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid |
||||
+}; |
||||
+const krb5_data sha512WithRSAEncr_id = { |
||||
+ KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid |
||||
+}; |
||||
+ |
||||
+krb5_data const * const supported_cms_algs[] = { |
||||
+ &sha512WithRSAEncr_id, |
||||
+ &sha256WithRSAEncr_id, |
||||
+ NULL |
||||
+}; |
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h |
||||
index 1f9868351..f38a77093 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h |
||||
@@ -380,6 +380,18 @@ krb5_error_code server_process_dh |
||||
unsigned int *server_key_len_out); /* OUT |
||||
receives length of DH secret key */ |
||||
|
||||
+/* |
||||
+ * this functions takes in crypto specific representation of |
||||
+ * supportedCMSTypes and creates a list of |
||||
+ * krb5_algorithm_identifier |
||||
+ */ |
||||
+krb5_error_code create_krb5_supportedCMSTypes |
||||
+ (krb5_context context, /* IN */ |
||||
+ pkinit_plg_crypto_context plg_cryptoctx, /* IN */ |
||||
+ pkinit_req_crypto_context req_cryptoctx, /* IN */ |
||||
+ pkinit_identity_crypto_context id_cryptoctx, /* IN */ |
||||
+ krb5_algorithm_identifier ***supportedCMSTypes); /* OUT */ |
||||
+ |
||||
/* |
||||
* this functions takes in crypto specific representation of |
||||
* trustedCertifiers and creates a list of |
||||
@@ -617,6 +629,10 @@ extern const size_t krb5_pkinit_sha512_oid_len; |
||||
*/ |
||||
extern krb5_data const * const supported_kdf_alg_ids[]; |
||||
|
||||
+/* CMS signature algorithms supported by this implementation, in order of |
||||
+ * decreasing preference. */ |
||||
+extern krb5_data const * const supported_cms_algs[]; |
||||
+ |
||||
krb5_error_code |
||||
crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, |
||||
uint8_t **der_out, size_t *der_len); |
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
index 2a6ef4aaa..41a7464b5 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
@@ -5582,6 +5582,45 @@ cleanup: |
||||
return retval; |
||||
} |
||||
|
||||
+krb5_error_code |
||||
+create_krb5_supportedCMSTypes(krb5_context context, |
||||
+ pkinit_plg_crypto_context plg_cryptoctx, |
||||
+ pkinit_req_crypto_context req_cryptoctx, |
||||
+ pkinit_identity_crypto_context id_cryptoctx, |
||||
+ krb5_algorithm_identifier ***algs_out) |
||||
+{ |
||||
+ krb5_error_code ret; |
||||
+ krb5_algorithm_identifier **algs = NULL; |
||||
+ size_t i, count; |
||||
+ |
||||
+ *algs_out = NULL; |
||||
+ |
||||
+ /* Count supported OIDs and allocate list (including null terminator). */ |
||||
+ for (count = 0; supported_cms_algs[count] != NULL; count++); |
||||
+ algs = k5calloc(count + 1, sizeof(*algs), &ret); |
||||
+ if (algs == NULL) |
||||
+ goto cleanup; |
||||
+ |
||||
+ /* Add an algorithm identifier for each OID, with no parameters. */ |
||||
+ for (i = 0; i < count; i++) { |
||||
+ algs[i] = k5alloc(sizeof(*algs[i]), &ret); |
||||
+ if (algs[i] == NULL) |
||||
+ goto cleanup; |
||||
+ ret = krb5int_copy_data_contents(context, supported_cms_algs[i], |
||||
+ &algs[i]->algorithm); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ algs[i]->parameters = empty_data(); |
||||
+ } |
||||
+ |
||||
+ *algs_out = algs; |
||||
+ algs = NULL; |
||||
+ |
||||
+cleanup: |
||||
+ free_krb5_algorithm_identifiers(&algs); |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
krb5_error_code |
||||
create_krb5_trustedCertifiers(krb5_context context, |
||||
pkinit_plg_crypto_context plg_cryptoctx, |
||||
-- |
||||
2.35.3 |
||||
|
@ -0,0 +1,578 @@
@@ -0,0 +1,578 @@
|
||||
From e33835c4b6c6ce71757e9f659db03afa4bfd9a9a Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Fri, 15 Jan 2021 13:51:34 -0500 |
||||
Subject: [PATCH] Support host-based GSS initiator names |
||||
|
||||
When checking if we can get initial credentials in the GSS krb5 mech, |
||||
use krb5_kt_have_match() to support fallback iteration. When scanning |
||||
the ccache or getting initial credentials, rewrite cred->name->princ |
||||
to the canonical client name. When a name check is necessary (such as |
||||
when the caller specifies both a name and ccache), use a new internal |
||||
API k5_sname_compare() to support fallback iteration. Add fallback |
||||
iteration to krb5_cc_cache_match() to allow host-based names to be |
||||
canonicalized against the cache collection. |
||||
|
||||
Create and store the matching principal for acceptor names in |
||||
acquire_accept_cred() so that it isn't affected by changes in |
||||
cred->name->princ during acquire_init_cred(). |
||||
|
||||
ticket: 8978 (new) |
||||
(cherry picked from commit c374ab40dd059a5938ffc0440d87457ac5da3a46) |
||||
--- |
||||
src/include/k5-int.h | 9 +++ |
||||
src/include/k5-trace.h | 3 + |
||||
src/lib/gssapi/krb5/accept_sec_context.c | 15 +--- |
||||
src/lib/gssapi/krb5/acquire_cred.c | 89 ++++++++++++++---------- |
||||
src/lib/gssapi/krb5/gssapiP_krb5.h | 1 + |
||||
src/lib/gssapi/krb5/rel_cred.c | 1 + |
||||
src/lib/krb5/ccache/cccursor.c | 57 +++++++++++---- |
||||
src/lib/krb5/libkrb5.exports | 1 + |
||||
src/lib/krb5/os/sn2princ.c | 23 +++++- |
||||
src/lib/krb5_32.def | 1 + |
||||
src/tests/gssapi/t_client_keytab.py | 44 ++++++++++++ |
||||
src/tests/gssapi/t_credstore.py | 32 +++++++++ |
||||
12 files changed, 214 insertions(+), 62 deletions(-) |
||||
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h |
||||
index efb523689..46f2ce2d3 100644 |
||||
--- a/src/include/k5-int.h |
||||
+++ b/src/include/k5-int.h |
||||
@@ -2411,4 +2411,13 @@ void k5_change_error_message_code(krb5_context ctx, krb5_error_code oldcode, |
||||
#define k5_prependmsg krb5_prepend_error_message |
||||
#define k5_wrapmsg krb5_wrap_error_message |
||||
|
||||
+/* |
||||
+ * Like krb5_principal_compare(), but with canonicalization of sname if |
||||
+ * fallback is enabled. This function should be avoided if multiple matches |
||||
+ * are required, since repeated canonicalization is inefficient. |
||||
+ */ |
||||
+krb5_boolean |
||||
+k5_sname_compare(krb5_context context, krb5_const_principal sname, |
||||
+ krb5_const_principal princ); |
||||
+ |
||||
#endif /* _KRB5_INT_H */ |
||||
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h |
||||
index b3e039dc8..79b5a7a85 100644 |
||||
--- a/src/include/k5-trace.h |
||||
+++ b/src/include/k5-trace.h |
||||
@@ -105,6 +105,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); |
||||
|
||||
#endif /* DISABLE_TRACING */ |
||||
|
||||
+#define TRACE_CC_CACHE_MATCH(c, princ, ret) \ |
||||
+ TRACE(c, "Matching {princ} in collection with result: {kerr}", \ |
||||
+ princ, ret) |
||||
#define TRACE_CC_DESTROY(c, cache) \ |
||||
TRACE(c, "Destroying ccache {ccache}", cache) |
||||
#define TRACE_CC_GEN_NEW(c, cache) \ |
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c |
||||
index fcf2c2152..a1d7e0d96 100644 |
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c |
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c |
||||
@@ -683,7 +683,6 @@ kg_accept_krb5(minor_status, context_handle, |
||||
krb5_flags ap_req_options = 0; |
||||
krb5_enctype negotiated_etype; |
||||
krb5_authdata_context ad_context = NULL; |
||||
- krb5_principal accprinc = NULL; |
||||
krb5_ap_req *request = NULL; |
||||
|
||||
code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); |
||||
@@ -849,17 +848,9 @@ kg_accept_krb5(minor_status, context_handle, |
||||
} |
||||
} |
||||
|
||||
- if (!cred->default_identity) { |
||||
- if ((code = kg_acceptor_princ(context, cred->name, &accprinc))) { |
||||
- major_status = GSS_S_FAILURE; |
||||
- goto fail; |
||||
- } |
||||
- } |
||||
- |
||||
- code = krb5_rd_req_decoded(context, &auth_context, request, accprinc, |
||||
- cred->keytab, &ap_req_options, NULL); |
||||
- |
||||
- krb5_free_principal(context, accprinc); |
||||
+ code = krb5_rd_req_decoded(context, &auth_context, request, |
||||
+ cred->acceptor_mprinc, cred->keytab, |
||||
+ &ap_req_options, NULL); |
||||
if (code) { |
||||
major_status = GSS_S_FAILURE; |
||||
goto fail; |
||||
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c |
||||
index 632ee7def..e226a0269 100644 |
||||
--- a/src/lib/gssapi/krb5/acquire_cred.c |
||||
+++ b/src/lib/gssapi/krb5/acquire_cred.c |
||||
@@ -123,11 +123,11 @@ gss_krb5int_register_acceptor_identity(OM_uint32 *minor_status, |
||||
/* Try to verify that keytab contains at least one entry for name. Return 0 if |
||||
* it does, KRB5_KT_NOTFOUND if it doesn't, or another error as appropriate. */ |
||||
static krb5_error_code |
||||
-check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name) |
||||
+check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name, |
||||
+ krb5_principal mprinc) |
||||
{ |
||||
krb5_error_code code; |
||||
krb5_keytab_entry ent; |
||||
- krb5_principal accprinc = NULL; |
||||
char *princname; |
||||
|
||||
if (name->service == NULL) { |
||||
@@ -141,21 +141,15 @@ check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name) |
||||
if (kt->ops->start_seq_get == NULL) |
||||
return 0; |
||||
|
||||
- /* Get the partial principal for the acceptor name. */ |
||||
- code = kg_acceptor_princ(context, name, &accprinc); |
||||
- if (code) |
||||
- return code; |
||||
- |
||||
- /* Scan the keytab for host-based entries matching accprinc. */ |
||||
- code = k5_kt_have_match(context, kt, accprinc); |
||||
+ /* Scan the keytab for host-based entries matching mprinc. */ |
||||
+ code = k5_kt_have_match(context, kt, mprinc); |
||||
if (code == KRB5_KT_NOTFOUND) { |
||||
- if (krb5_unparse_name(context, accprinc, &princname) == 0) { |
||||
+ if (krb5_unparse_name(context, mprinc, &princname) == 0) { |
||||
k5_setmsg(context, code, _("No key table entry found matching %s"), |
||||
princname); |
||||
free(princname); |
||||
} |
||||
} |
||||
- krb5_free_principal(context, accprinc); |
||||
return code; |
||||
} |
||||
|
||||
@@ -202,8 +196,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, |
||||
} |
||||
|
||||
if (cred->name != NULL) { |
||||
+ code = kg_acceptor_princ(context, cred->name, &cred->acceptor_mprinc); |
||||
+ if (code) { |
||||
+ major = GSS_S_FAILURE; |
||||
+ goto cleanup; |
||||
+ } |
||||
+ |
||||
/* Make sure we have keys matching the desired name in the keytab. */ |
||||
- code = check_keytab(context, kt, cred->name); |
||||
+ code = check_keytab(context, kt, cred->name, cred->acceptor_mprinc); |
||||
if (code) { |
||||
if (code == KRB5_KT_NOTFOUND) { |
||||
k5_change_error_message_code(context, code, KG_KEYTAB_NOMATCH); |
||||
@@ -324,7 +324,6 @@ static krb5_boolean |
||||
can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred) |
||||
{ |
||||
krb5_error_code code; |
||||
- krb5_keytab_entry entry; |
||||
|
||||
if (cred->password != NULL) |
||||
return TRUE; |
||||
@@ -336,20 +335,21 @@ can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred) |
||||
if (cred->name == NULL) |
||||
return !krb5_kt_have_content(context, cred->client_keytab); |
||||
|
||||
- /* Check if we have a keytab key for the client principal. */ |
||||
- code = krb5_kt_get_entry(context, cred->client_keytab, cred->name->princ, |
||||
- 0, 0, &entry); |
||||
- if (code) { |
||||
- krb5_clear_error_message(context); |
||||
- return FALSE; |
||||
- } |
||||
- krb5_free_keytab_entry_contents(context, &entry); |
||||
- return TRUE; |
||||
+ /* |
||||
+ * Check if we have a keytab key for the client principal. This is a bit |
||||
+ * more permissive than we really want because krb5_kt_have_match() |
||||
+ * supports wildcarding and obeys ignore_acceptor_hostname, but that should |
||||
+ * generally be harmless. |
||||
+ */ |
||||
+ code = k5_kt_have_match(context, cred->client_keytab, cred->name->princ); |
||||
+ return code == 0; |
||||
} |
||||
|
||||
-/* Scan cred->ccache for name, expiry time, impersonator, refresh time. */ |
||||
+/* Scan cred->ccache for name, expiry time, impersonator, refresh time. If |
||||
+ * check_name is true, verify the cache name against the credential name. */ |
||||
static krb5_error_code |
||||
-scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred) |
||||
+scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred, |
||||
+ krb5_boolean check_name) |
||||
{ |
||||
krb5_error_code code; |
||||
krb5_ccache ccache = cred->ccache; |
||||
@@ -365,23 +365,31 @@ scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred) |
||||
if (code) |
||||
return code; |
||||
|
||||
- /* Credentials cache principal must match the initiator name. */ |
||||
code = krb5_cc_get_principal(context, ccache, &ccache_princ); |
||||
if (code != 0) |
||||
goto cleanup; |
||||
- if (cred->name != NULL && |
||||
- !krb5_principal_compare(context, ccache_princ, cred->name->princ)) { |
||||
- code = KG_CCACHE_NOMATCH; |
||||
- goto cleanup; |
||||
- } |
||||
|
||||
- /* Save the ccache principal as the credential name if not already set. */ |
||||
- if (!cred->name) { |
||||
+ if (cred->name == NULL) { |
||||
+ /* Save the ccache principal as the credential name. */ |
||||
code = kg_init_name(context, ccache_princ, NULL, NULL, NULL, |
||||
KG_INIT_NAME_NO_COPY, &cred->name); |
||||
if (code) |
||||
goto cleanup; |
||||
ccache_princ = NULL; |
||||
+ } else { |
||||
+ /* Check against the desired name if needed. */ |
||||
+ if (check_name) { |
||||
+ if (!k5_sname_compare(context, cred->name->princ, ccache_princ)) { |
||||
+ code = KG_CCACHE_NOMATCH; |
||||
+ goto cleanup; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ /* Replace the credential name principal with the canonical client |
||||
+ * principal, retaining acceptor_mprinc if set. */ |
||||
+ krb5_free_principal(context, cred->name->princ); |
||||
+ cred->name->princ = ccache_princ; |
||||
+ ccache_princ = NULL; |
||||
} |
||||
|
||||
assert(cred->name->princ != NULL); |
||||
@@ -447,7 +455,7 @@ get_cache_for_name(krb5_context context, krb5_gss_cred_id_rec *cred) |
||||
assert(cred->name != NULL && cred->ccache == NULL); |
||||
#ifdef USE_LEASH |
||||
code = get_ccache_leash(context, cred->name->princ, &cred->ccache); |
||||
- return code ? code : scan_ccache(context, cred); |
||||
+ return code ? code : scan_ccache(context, cred, TRUE); |
||||
#else |
||||
/* Check first whether we can acquire tickets, to avoid overwriting the |
||||
* extended error message from krb5_cc_cache_match. */ |
||||
@@ -456,7 +464,7 @@ get_cache_for_name(krb5_context context, krb5_gss_cred_id_rec *cred) |
||||
/* Look for an existing cache for the client principal. */ |
||||
code = krb5_cc_cache_match(context, cred->name->princ, &cred->ccache); |
||||
if (code == 0) |
||||
- return scan_ccache(context, cred); |
||||
+ return scan_ccache(context, cred, FALSE); |
||||
if (code != KRB5_CC_NOTFOUND || !can_get) |
||||
return code; |
||||
krb5_clear_error_message(context); |
||||
@@ -633,6 +641,13 @@ get_initial_cred(krb5_context context, const struct verify_params *verify, |
||||
kg_cred_set_initial_refresh(context, cred, &creds.times); |
||||
cred->have_tgt = TRUE; |
||||
cred->expire = creds.times.endtime; |
||||
+ |
||||
+ /* Steal the canonical client principal name from creds and save it in the |
||||
+ * credential name, retaining acceptor_mprinc if set. */ |
||||
+ krb5_free_principal(context, cred->name->princ); |
||||
+ cred->name->princ = creds.client; |
||||
+ creds.client = NULL; |
||||
+ |
||||
krb5_free_cred_contents(context, &creds); |
||||
cleanup: |
||||
krb5_get_init_creds_opt_free(context, opt); |
||||
@@ -721,7 +736,7 @@ acquire_init_cred(krb5_context context, OM_uint32 *minor_status, |
||||
|
||||
if (cred->ccache != NULL) { |
||||
/* The caller specified a ccache; check what's in it. */ |
||||
- code = scan_ccache(context, cred); |
||||
+ code = scan_ccache(context, cred, TRUE); |
||||
if (code == KRB5_FCC_NOFILE) { |
||||
/* See if we can get initial creds. If the caller didn't specify |
||||
* a name, pick one from the client keytab. */ |
||||
@@ -984,7 +999,7 @@ kg_cred_resolve(OM_uint32 *minor_status, krb5_context context, |
||||
} |
||||
} |
||||
if (cred->ccache != NULL) { |
||||
- code = scan_ccache(context, cred); |
||||
+ code = scan_ccache(context, cred, FALSE); |
||||
if (code) |
||||
goto kerr; |
||||
} |
||||
@@ -996,7 +1011,7 @@ kg_cred_resolve(OM_uint32 *minor_status, krb5_context context, |
||||
code = krb5int_cc_default(context, &cred->ccache); |
||||
if (code) |
||||
goto kerr; |
||||
- code = scan_ccache(context, cred); |
||||
+ code = scan_ccache(context, cred, FALSE); |
||||
if (code == KRB5_FCC_NOFILE) { |
||||
/* Default ccache doesn't exist; fall through to client keytab. */ |
||||
krb5_cc_close(context, cred->ccache); |
||||
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h |
||||
index 3bacdcd35..fd7abbd77 100644 |
||||
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h |
||||
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h |
||||
@@ -175,6 +175,7 @@ typedef struct _krb5_gss_cred_id_rec { |
||||
/* name/type of credential */ |
||||
gss_cred_usage_t usage; |
||||
krb5_gss_name_t name; |
||||
+ krb5_principal acceptor_mprinc; |
||||
krb5_principal impersonator; |
||||
unsigned int default_identity : 1; |
||||
unsigned int iakerb_mech : 1; |
||||
diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c |
||||
index a9515daf7..0da6c1b95 100644 |
||||
--- a/src/lib/gssapi/krb5/rel_cred.c |
||||
+++ b/src/lib/gssapi/krb5/rel_cred.c |
||||
@@ -72,6 +72,7 @@ krb5_gss_release_cred(minor_status, cred_handle) |
||||
if (cred->name) |
||||
kg_release_name(context, &cred->name); |
||||
|
||||
+ krb5_free_principal(context, cred->acceptor_mprinc); |
||||
krb5_free_principal(context, cred->impersonator); |
||||
|
||||
if (cred->req_enctypes) |
||||
diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c |
||||
index 8f5872116..760216d05 100644 |
||||
--- a/src/lib/krb5/ccache/cccursor.c |
||||
+++ b/src/lib/krb5/ccache/cccursor.c |
||||
@@ -30,6 +30,7 @@ |
||||
|
||||
#include "cc-int.h" |
||||
#include "../krb/int-proto.h" |
||||
+#include "../os/os-proto.h" |
||||
|
||||
#include <assert.h> |
||||
|
||||
@@ -141,18 +142,18 @@ krb5_cccol_cursor_free(krb5_context context, |
||||
return 0; |
||||
} |
||||
|
||||
-krb5_error_code KRB5_CALLCONV |
||||
-krb5_cc_cache_match(krb5_context context, krb5_principal client, |
||||
- krb5_ccache *cache_out) |
||||
+static krb5_error_code |
||||
+match_caches(krb5_context context, krb5_const_principal client, |
||||
+ krb5_ccache *cache_out) |
||||
{ |
||||
krb5_error_code ret; |
||||
krb5_cccol_cursor cursor; |
||||
krb5_ccache cache = NULL; |
||||
krb5_principal princ; |
||||
- char *name; |
||||
krb5_boolean eq; |
||||
|
||||
*cache_out = NULL; |
||||
+ |
||||
ret = krb5_cccol_cursor_new(context, &cursor); |
||||
if (ret) |
||||
return ret; |
||||
@@ -169,20 +170,52 @@ krb5_cc_cache_match(krb5_context context, krb5_principal client, |
||||
krb5_cc_close(context, cache); |
||||
} |
||||
krb5_cccol_cursor_free(context, &cursor); |
||||
+ |
||||
if (ret) |
||||
return ret; |
||||
- if (cache == NULL) { |
||||
- ret = krb5_unparse_name(context, client, &name); |
||||
- if (ret == 0) { |
||||
- k5_setmsg(context, KRB5_CC_NOTFOUND, |
||||
+ if (cache == NULL) |
||||
+ return KRB5_CC_NOTFOUND; |
||||
+ |
||||
+ *cache_out = cache; |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+krb5_error_code KRB5_CALLCONV |
||||
+krb5_cc_cache_match(krb5_context context, krb5_principal client, |
||||
+ krb5_ccache *cache_out) |
||||
+{ |
||||
+ krb5_error_code ret; |
||||
+ struct canonprinc iter = { client, .subst_defrealm = TRUE }; |
||||
+ krb5_const_principal canonprinc = NULL; |
||||
+ krb5_ccache cache = NULL; |
||||
+ char *name; |
||||
+ |
||||
+ *cache_out = NULL; |
||||
+ |
||||
+ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && |
||||
+ canonprinc != NULL) { |
||||
+ ret = match_caches(context, canonprinc, &cache); |
||||
+ if (ret != KRB5_CC_NOTFOUND) |
||||
+ break; |
||||
+ } |
||||
+ free_canonprinc(&iter); |
||||
+ |
||||
+ if (ret == 0 && canonprinc == NULL) { |
||||
+ ret = KRB5_CC_NOTFOUND; |
||||
+ if (krb5_unparse_name(context, client, &name) == 0) { |
||||
+ k5_setmsg(context, ret, |
||||
_("Can't find client principal %s in cache collection"), |
||||
name); |
||||
krb5_free_unparsed_name(context, name); |
||||
} |
||||
- ret = KRB5_CC_NOTFOUND; |
||||
- } else |
||||
- *cache_out = cache; |
||||
- return ret; |
||||
+ } |
||||
+ |
||||
+ TRACE_CC_CACHE_MATCH(context, client, ret); |
||||
+ if (ret) |
||||
+ return ret; |
||||
+ |
||||
+ *cache_out = cache; |
||||
+ return 0; |
||||
} |
||||
|
||||
/* Store the error state for code from context into errsave, but only if code |
||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports |
||||
index adbfa332b..df6e2ffbe 100644 |
||||
--- a/src/lib/krb5/libkrb5.exports |
||||
+++ b/src/lib/krb5/libkrb5.exports |
||||
@@ -181,6 +181,7 @@ k5_size_authdata_context |
||||
k5_size_context |
||||
k5_size_keyblock |
||||
k5_size_principal |
||||
+k5_sname_compare |
||||
k5_unmarshal_cred |
||||
k5_unmarshal_princ |
||||
k5_unwrap_cammac_svc |
||||
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c |
||||
index 8b7214189..c99b7da17 100644 |
||||
--- a/src/lib/krb5/os/sn2princ.c |
||||
+++ b/src/lib/krb5/os/sn2princ.c |
||||
@@ -277,7 +277,8 @@ k5_canonprinc(krb5_context context, struct canonprinc *iter, |
||||
|
||||
/* If we're not doing fallback, the input principal is canonical. */ |
||||
if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK || |
||||
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2) { |
||||
+ iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 || |
||||
+ iter->princ->data[1].length == 0) { |
||||
*princ_out = (step == 1) ? iter->princ : NULL; |
||||
return 0; |
||||
} |
||||
@@ -288,6 +289,26 @@ k5_canonprinc(krb5_context context, struct canonprinc *iter, |
||||
return canonicalize_princ(context, iter, step == 2, princ_out); |
||||
} |
||||
|
||||
+krb5_boolean |
||||
+k5_sname_compare(krb5_context context, krb5_const_principal sname, |
||||
+ krb5_const_principal princ) |
||||
+{ |
||||
+ krb5_error_code ret; |
||||
+ struct canonprinc iter = { sname, .subst_defrealm = TRUE }; |
||||
+ krb5_const_principal canonprinc = NULL; |
||||
+ krb5_boolean match = FALSE; |
||||
+ |
||||
+ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && |
||||
+ canonprinc != NULL) { |
||||
+ if (krb5_principal_compare(context, canonprinc, princ)) { |
||||
+ match = TRUE; |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ free_canonprinc(&iter); |
||||
+ return match; |
||||
+} |
||||
+ |
||||
krb5_error_code KRB5_CALLCONV |
||||
krb5_sname_to_principal(krb5_context context, const char *hostname, |
||||
const char *sname, krb5_int32 type, |
||||
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def |
||||
index 60b8dd311..cf690dbe4 100644 |
||||
--- a/src/lib/krb5_32.def |
||||
+++ b/src/lib/krb5_32.def |
||||
@@ -507,3 +507,4 @@ EXPORTS |
||||
; new in 1.20 |
||||
krb5_marshal_credentials @472 |
||||
krb5_unmarshal_credentials @473 |
||||
+ k5_sname_compare @474 ; PRIVATE GSSAPI |
||||
diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py |
||||
index 7847b3ecd..9a61d53b8 100755 |
||||
--- a/src/tests/gssapi/t_client_keytab.py |
||||
+++ b/src/tests/gssapi/t_client_keytab.py |
||||
@@ -141,5 +141,49 @@ 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) |
||||
+realm.run([kdestroy, '-A']) |
||||
+ |
||||
+# Test 19: host-based initiator name |
||||
+mark('host-based initiator name') |
||||
+hsvc = 'h:svc@' + hostname |
||||
+svcprinc = 'svc/%s@%s' % (hostname, realm.realm) |
||||
+realm.addprinc(svcprinc) |
||||
+realm.extract_keytab(svcprinc, realm.client_keytab) |
||||
+# On the first run we match against the keytab while getting tickets, |
||||
+# substituting the default realm. |
||||
+msgs = ('/Can\'t find client principal svc/%s@ in' % hostname, |
||||
+ 'Getting initial credentials for svc/%s@' % hostname, |
||||
+ 'Found entries for %s in keytab' % svcprinc, |
||||
+ 'Retrieving %s from FILE:%s' % (svcprinc, realm.client_keytab), |
||||
+ 'Storing %s -> %s in' % (svcprinc, realm.krbtgt_princ), |
||||
+ 'Retrieving %s -> %s from' % (svcprinc, realm.krbtgt_princ), |
||||
+ 'authenticator for %s -> %s' % (svcprinc, realm.host_princ)) |
||||
+realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs) |
||||
+# On the second run we match against the collection. |
||||
+msgs = ('Matching svc/%s@ in collection with result: 0' % hostname, |
||||
+ 'Getting credentials %s -> %s' % (svcprinc, realm.host_princ), |
||||
+ 'authenticator for %s -> %s' % (svcprinc, realm.host_princ)) |
||||
+realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs) |
||||
+realm.run([kdestroy, '-A']) |
||||
+ |
||||
+# Test 20: host-based initiator name with fallback |
||||
+mark('host-based fallback initiator name') |
||||
+canonname = canonicalize_hostname(hostname) |
||||
+if canonname != hostname: |
||||
+ hfsvc = 'h:fsvc@' + hostname |
||||
+ canonprinc = 'fsvc/%s@%s' % (canonname, realm.realm) |
||||
+ realm.addprinc(canonprinc) |
||||
+ realm.extract_keytab(canonprinc, realm.client_keytab) |
||||
+ msgs = ('/Can\'t find client principal fsvc/%s@ in' % hostname, |
||||
+ 'Found entries for %s in keytab' % canonprinc, |
||||
+ 'authenticator for %s -> %s' % (canonprinc, realm.host_princ)) |
||||
+ realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs) |
||||
+ msgs = ('Matching fsvc/%s@ in collection with result: 0' % hostname, |
||||
+ 'Getting credentials %s -> %s' % (canonprinc, realm.host_princ)) |
||||
+ realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs) |
||||
+ realm.run([kdestroy, '-A']) |
||||
+else: |
||||
+ skipped('GSS initiator name fallback test', |
||||
+ '%s does not canonicalize to a different name' % hostname) |
||||
|
||||
success('Client keytab tests') |
||||
diff --git a/src/tests/gssapi/t_credstore.py b/src/tests/gssapi/t_credstore.py |
||||
index c11975bf5..9be57bb82 100644 |
||||
--- a/src/tests/gssapi/t_credstore.py |
||||
+++ b/src/tests/gssapi/t_credstore.py |
||||
@@ -15,6 +15,38 @@ msgs = ('Storing %s -> %s in %s' % (service_cs, realm.krbtgt_princ, |
||||
realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache, |
||||
'keytab', servicekeytab], expected_trace=msgs) |
||||
|
||||
+mark('matching') |
||||
+scc = 'FILE:' + os.path.join(realm.testdir, 'service_cache') |
||||
+realm.kinit(realm.host_princ, flags=['-k', '-c', scc]) |
||||
+realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc]) |
||||
+realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc]) |
||||
+realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc]) |
||||
+realm.run(['./t_credstore', '-i', 'p:wrong', 'ccache', scc], |
||||
+ expected_code=1, expected_msg='does not match desired name') |
||||
+realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc], |
||||
+ expected_code=1, expected_msg='does not match desired name') |
||||
+realm.run(['./t_credstore', '-i', 'h:svc', 'ccache', scc], |
||||
+ expected_code=1, expected_msg='does not match desired name') |
||||
+ |
||||
+mark('matching (fallback)') |
||||
+canonname = canonicalize_hostname(hostname) |
||||
+if canonname != hostname: |
||||
+ canonprinc = 'host/%s@%s' % (canonname, realm.realm) |
||||
+ realm.addprinc(canonprinc) |
||||
+ realm.extract_keytab(canonprinc, realm.keytab) |
||||
+ realm.kinit(canonprinc, flags=['-k', '-c', scc]) |
||||
+ realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc]) |
||||
+ realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc]) |
||||
+ realm.run(['./t_credstore', '-i', 'h:host@' + canonname, 'ccache', scc]) |
||||
+ realm.run(['./t_credstore', '-i', 'p:' + canonprinc, 'ccache', scc]) |
||||
+ realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc], |
||||
+ expected_code=1, expected_msg='does not match desired name') |
||||
+ realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc], |
||||
+ expected_code=1, expected_msg='does not match desired name') |
||||
+else: |
||||
+ skipped('fallback matching test', |
||||
+ '%s does not canonicalize to a different name' % hostname) |
||||
+ |
||||
mark('rcache') |
||||
# t_credstore -r should produce a replay error normally, but not with |
||||
# rcache set to "none:". |
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
From ad8e02485791023dcf66ef4612616f03895ceeb3 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Fri, 4 Mar 2022 00:45:00 -0500 |
||||
Subject: [PATCH] Try harder to avoid password change replay errors |
||||
|
||||
Commit d7b3018d338fc9c989c3fa17505870f23c3759a8 (ticket 7905) changed |
||||
change_set_password() to prefer TCP. However, because UDP_LAST falls |
||||
back to UDP after one second, we can still get a replay error due to a |
||||
dropped packet, before the TCP layer has a chance to retry. |
||||
|
||||
Instead, try k5_sendto() with NO_UDP, and only fall back to UDP after |
||||
TCP fails completely without reaching a server. In sendto_kdc.c, |
||||
implement an ONLY_UDP transport strategy to allow the UDP fallback. |
||||
|
||||
ticket: 9037 |
||||
--- |
||||
src/lib/krb5/os/changepw.c | 9 ++++++++- |
||||
src/lib/krb5/os/os-proto.h | 1 + |
||||
src/lib/krb5/os/sendto_kdc.c | 12 ++++++++---- |
||||
3 files changed, 17 insertions(+), 5 deletions(-) |
||||
|
||||
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c |
||||
index 9f968da7f..c59232586 100644 |
||||
--- a/src/lib/krb5/os/changepw.c |
||||
+++ b/src/lib/krb5/os/changepw.c |
||||
@@ -255,9 +255,16 @@ change_set_password(krb5_context context, |
||||
callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; |
||||
krb5_free_data_contents(callback_ctx.context, &chpw_rep); |
||||
|
||||
+ /* UDP retransmits may be seen as replays. Only try UDP after other |
||||
+ * transports fail completely. */ |
||||
code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, |
||||
- &sl, UDP_LAST, &callback_info, &chpw_rep, |
||||
+ &sl, NO_UDP, &callback_info, &chpw_rep, |
||||
ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); |
||||
+ if (code == KRB5_KDC_UNREACH) { |
||||
+ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, |
||||
+ &sl, ONLY_UDP, &callback_info, &chpw_rep, |
||||
+ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); |
||||
+ } |
||||
if (code) |
||||
goto cleanup; |
||||
|
||||
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h |
||||
index a985f2aec..91d2791ce 100644 |
||||
--- a/src/lib/krb5/os/os-proto.h |
||||
+++ b/src/lib/krb5/os/os-proto.h |
||||
@@ -49,6 +49,7 @@ typedef enum { |
||||
UDP_FIRST = 0, |
||||
UDP_LAST, |
||||
NO_UDP, |
||||
+ ONLY_UDP |
||||
} k5_transport_strategy; |
||||
|
||||
/* A single server hostname or address. */ |
||||
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c |
||||
index 0eedec175..c7f5d861a 100644 |
||||
--- a/src/lib/krb5/os/sendto_kdc.c |
||||
+++ b/src/lib/krb5/os/sendto_kdc.c |
||||
@@ -802,11 +802,14 @@ resolve_server(krb5_context context, const krb5_data *realm, |
||||
int err, result; |
||||
char portbuf[PORT_LENGTH]; |
||||
|
||||
- /* Skip UDP entries if we don't want UDP. */ |
||||
+ /* Skip entries excluded by the strategy. */ |
||||
if (strategy == NO_UDP && entry->transport == UDP) |
||||
return 0; |
||||
+ if (strategy == ONLY_UDP && entry->transport != UDP && |
||||
+ entry->transport != TCP_OR_UDP) |
||||
+ return 0; |
||||
|
||||
- transport = (strategy == UDP_FIRST) ? UDP : TCP; |
||||
+ transport = (strategy == UDP_FIRST || strategy == ONLY_UDP) ? UDP : TCP; |
||||
if (entry->hostname == NULL) { |
||||
/* Added by a module, so transport is either TCP or UDP. */ |
||||
ai.ai_socktype = socktype_for_transport(entry->transport); |
||||
@@ -850,8 +853,9 @@ resolve_server(krb5_context context, const krb5_data *realm, |
||||
} |
||||
|
||||
/* For TCP_OR_UDP entries, add each address again with the non-preferred |
||||
- * transport, unless we are avoiding UDP. Flag these as deferred. */ |
||||
- if (retval == 0 && entry->transport == TCP_OR_UDP && strategy != NO_UDP) { |
||||
+ * transport, if there is one. Flag these as deferred. */ |
||||
+ if (retval == 0 && entry->transport == TCP_OR_UDP && |
||||
+ (strategy == UDP_FIRST || strategy == UDP_LAST)) { |
||||
transport = (strategy == UDP_FIRST) ? TCP : UDP; |
||||
for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { |
||||
a->ai_socktype = socktype_for_transport(transport); |
||||
-- |
||||
2.35.1 |
||||
|
@ -0,0 +1,236 @@
@@ -0,0 +1,236 @@
|
||||
From 43e3bca2a711de257091454bc5e25a985340d847 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Fri, 26 Mar 2021 23:38:54 -0400 |
||||
Subject: [PATCH] Use KCM_OP_RETRIEVE in KCM client |
||||
|
||||
In kcm_retrieve(), try KCM_OP_RETRIEVE. Fall back to iteration if the |
||||
server doesn't implement it, or if we can an answer incompatible with |
||||
KRB5_TC_SUPPORTED_KTYPES. |
||||
|
||||
In kcmserver.py, implement partial decoding for creds and cred tags so |
||||
that we can do a basic principal name match. |
||||
|
||||
ticket: 8997 (new) |
||||
(cherry picked from commit 795ebba8c039be172ab93cd41105c73ffdba0fdb) |
||||
(cherry picked from commit c56d4b87de0f30a38dc61d374ad225d02d581eb3) |
||||
--- |
||||
src/include/kcm.h | 2 +- |
||||
src/lib/krb5/ccache/cc_kcm.c | 52 +++++++++++++++++++++++++++++++++--- |
||||
src/tests/kcmserver.py | 44 +++++++++++++++++++++++++++--- |
||||
src/tests/t_ccache.py | 11 +++++--- |
||||
4 files changed, 99 insertions(+), 10 deletions(-) |
||||
|
||||
diff --git a/src/include/kcm.h b/src/include/kcm.h |
||||
index 9b66f1cbd..85c20d345 100644 |
||||
--- a/src/include/kcm.h |
||||
+++ b/src/include/kcm.h |
||||
@@ -87,7 +87,7 @@ typedef enum kcm_opcode { |
||||
KCM_OP_INITIALIZE, /* (name, princ) -> () */ |
||||
KCM_OP_DESTROY, /* (name) -> () */ |
||||
KCM_OP_STORE, /* (name, cred) -> () */ |
||||
- KCM_OP_RETRIEVE, |
||||
+ KCM_OP_RETRIEVE, /* (name, flags, credtag) -> (cred) */ |
||||
KCM_OP_GET_PRINCIPAL, /* (name) -> (princ) */ |
||||
KCM_OP_GET_CRED_UUID_LIST, /* (name) -> (uuid, ...) */ |
||||
KCM_OP_GET_CRED_BY_UUID, /* (name, uuid) -> (cred) */ |
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c |
||||
index 46705f1da..23fcf13ea 100644 |
||||
--- a/src/lib/krb5/ccache/cc_kcm.c |
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c |
||||
@@ -826,9 +826,55 @@ static krb5_error_code KRB5_CALLCONV |
||||
kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags, |
||||
krb5_creds *mcred, krb5_creds *cred_out) |
||||
{ |
||||
- /* There is a KCM opcode for retrieving creds, but Heimdal's client doesn't |
||||
- * use it. It causes the KCM daemon to actually make a TGS request. */ |
||||
- return k5_cc_retrieve_cred_default(context, cache, flags, mcred, cred_out); |
||||
+ krb5_error_code ret; |
||||
+ struct kcmreq req = EMPTY_KCMREQ; |
||||
+ krb5_creds cred; |
||||
+ krb5_enctype *enctypes = NULL; |
||||
+ |
||||
+ memset(&cred, 0, sizeof(cred)); |
||||
+ |
||||
+ /* Include KCM_GC_CACHED in flags to prevent Heimdal's sssd from making a |
||||
+ * TGS request itself. */ |
||||
+ kcmreq_init(&req, KCM_OP_RETRIEVE, cache); |
||||
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags) | KCM_GC_CACHED); |
||||
+ k5_marshal_mcred(&req.reqbuf, mcred); |
||||
+ ret = cache_call(context, cache, &req); |
||||
+ |
||||
+ /* Fall back to iteration if the server does not support retrieval. */ |
||||
+ if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) { |
||||
+ ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred, |
||||
+ cred_out); |
||||
+ goto cleanup; |
||||
+ } |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ |
||||
+ ret = k5_unmarshal_cred(req.reply.ptr, req.reply.len, 4, &cred); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ |
||||
+ /* In rare cases we might retrieve a credential with a session key this |
||||
+ * context can't support, in which case we must retry using iteration. */ |
||||
+ if (flags & KRB5_TC_SUPPORTED_KTYPES) { |
||||
+ ret = krb5_get_tgs_ktypes(context, cred.server, &enctypes); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ if (!k5_etypes_contains(enctypes, cred.keyblock.enctype)) { |
||||
+ ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred, |
||||
+ cred_out); |
||||
+ goto cleanup; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ *cred_out = cred; |
||||
+ memset(&cred, 0, sizeof(cred)); |
||||
+ |
||||
+cleanup: |
||||
+ kcmreq_free(&req); |
||||
+ krb5_free_cred_contents(context, &cred); |
||||
+ free(enctypes); |
||||
+ /* Heimdal's KCM returns KRB5_CC_END if no cred is found. */ |
||||
+ return (ret == KRB5_CC_END) ? KRB5_CC_NOTFOUND : map_invalid(ret); |
||||
} |
||||
|
||||
static krb5_error_code KRB5_CALLCONV |
||||
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py |
||||
index 8c5e66ff1..25e6f2bbe 100644 |
||||
--- a/src/tests/kcmserver.py |
||||
+++ b/src/tests/kcmserver.py |
||||
@@ -40,6 +40,7 @@ class KCMOpcodes(object): |
||||
INITIALIZE = 4 |
||||
DESTROY = 5 |
||||
STORE = 6 |
||||
+ RETRIEVE = 7 |
||||
GET_PRINCIPAL = 8 |
||||
GET_CRED_UUID_LIST = 9 |
||||
GET_CRED_BY_UUID = 10 |
||||
@@ -54,6 +55,7 @@ class KCMOpcodes(object): |
||||
|
||||
|
||||
class KRB5Errors(object): |
||||
+ KRB5_CC_NOTFOUND = -1765328243 |
||||
KRB5_CC_END = -1765328242 |
||||
KRB5_CC_NOSUPP = -1765328137 |
||||
KRB5_FCC_NOFILE = -1765328189 |
||||
@@ -86,11 +88,29 @@ def get_cache(name): |
||||
return cache |
||||
|
||||
|
||||
+def unpack_data(argbytes): |
||||
+ dlen, = struct.unpack('>L', argbytes[:4]) |
||||
+ return argbytes[4:dlen+4], argbytes[dlen+4:] |
||||
+ |
||||
+ |
||||
def unmarshal_name(argbytes): |
||||
offset = argbytes.find(b'\0') |
||||
return argbytes[0:offset], argbytes[offset+1:] |
||||
|
||||
|
||||
+def unmarshal_princ(argbytes): |
||||
+ # Ignore the type at argbytes[0:4]. |
||||
+ ncomps, = struct.unpack('>L', argbytes[4:8]) |
||||
+ realm, rest = unpack_data(argbytes[8:]) |
||||
+ comps = [] |
||||
+ for i in range(ncomps): |
||||
+ comp, rest = unpack_data(rest) |
||||
+ comps.append(comp) |
||||
+ # Asssume no quoting is needed. |
||||
+ princ = b'/'.join(comps) + b'@' + realm |
||||
+ return princ, rest |
||||
+ |
||||
+ |
||||
def op_gen_new(argbytes): |
||||
# Does not actually check for uniqueness. |
||||
global next_unique |
||||
@@ -126,6 +146,22 @@ def op_store(argbytes): |
||||
return 0, b'' |
||||
|
||||
|
||||
+def op_retrieve(argbytes): |
||||
+ name, rest = unmarshal_name(argbytes) |
||||
+ # Ignore the flags at rest[0:4] and the header at rest[4:8]. |
||||
+ # Assume there are client and server creds in the tag and match |
||||
+ # only against them. |
||||
+ cprinc, rest = unmarshal_princ(rest[8:]) |
||||
+ sprinc, rest = unmarshal_princ(rest) |
||||
+ cache = get_cache(name) |
||||
+ for cred in (cache.creds[u] for u in cache.cred_uuids): |
||||
+ cred_cprinc, rest = unmarshal_princ(cred) |
||||
+ cred_sprinc, rest = unmarshal_princ(rest) |
||||
+ if cred_cprinc == cprinc and cred_sprinc == sprinc: |
||||
+ return 0, cred |
||||
+ return KRB5Errors.KRB5_CC_NOTFOUND, b'' |
||||
+ |
||||
+ |
||||
def op_get_principal(argbytes): |
||||
name, rest = unmarshal_name(argbytes) |
||||
cache = get_cache(name) |
||||
@@ -199,6 +235,7 @@ ophandlers = { |
||||
KCMOpcodes.INITIALIZE : op_initialize, |
||||
KCMOpcodes.DESTROY : op_destroy, |
||||
KCMOpcodes.STORE : op_store, |
||||
+ KCMOpcodes.RETRIEVE : op_retrieve, |
||||
KCMOpcodes.GET_PRINCIPAL : op_get_principal, |
||||
KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list, |
||||
KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid, |
||||
@@ -243,10 +280,11 @@ def service_request(s): |
||||
return True |
||||
|
||||
parser = optparse.OptionParser() |
||||
-parser.add_option('-c', '--credlist', action='store_true', dest='credlist', |
||||
- default=False, help='Support KCM_OP_GET_CRED_LIST') |
||||
+parser.add_option('-f', '--fallback', action='store_true', dest='fallback', |
||||
+ default=False, help='Do not support RETRIEVE/GET_CRED_LIST') |
||||
(options, args) = parser.parse_args() |
||||
-if not options.credlist: |
||||
+if options.fallback: |
||||
+ del ophandlers[KCMOpcodes.RETRIEVE] |
||||
del ophandlers[KCMOpcodes.GET_CRED_LIST] |
||||
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) |
||||
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py |
||||
index 90040fb7b..6ea9fb969 100755 |
||||
--- a/src/tests/t_ccache.py |
||||
+++ b/src/tests/t_ccache.py |
||||
@@ -25,7 +25,7 @@ from k5test import * |
||||
kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm') |
||||
conf = {'libdefaults': {'kcm_socket': kcm_socket_path, |
||||
'kcm_mach_service': '-'}} |
||||
-realm = K5Realm(create_host=False, krb5_conf=conf) |
||||
+realm = K5Realm(krb5_conf=conf) |
||||
|
||||
keyctl = which('keyctl') |
||||
out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1) |
||||
@@ -71,6 +71,11 @@ def collection_test(realm, ccname): |
||||
realm.kinit('alice', password('alice')) |
||||
realm.run([klist], expected_msg='Default principal: alice@') |
||||
realm.run([klist, '-A', '-s']) |
||||
+ realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1') |
||||
+ realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1') |
||||
+ out = realm.run([klist]) |
||||
+ if out.count(realm.host_princ) != 1: |
||||
+ fail('Wrong number of service tickets in cache') |
||||
realm.run([kdestroy]) |
||||
output = realm.run([klist], expected_code=1) |
||||
if 'No credentials cache' not in output and 'not found' not in output: |
||||
@@ -126,14 +131,14 @@ def collection_test(realm, ccname): |
||||
|
||||
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc')) |
||||
|
||||
-# Test KCM without and with GET_CRED_LIST support. |
||||
+# Test KCM with and without RETRIEVE and GET_CRED_LIST support. |
||||
kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py') |
||||
kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path], |
||||
'starting...') |
||||
collection_test(realm, 'KCM:') |
||||
stop_daemon(kcmd) |
||||
os.remove(kcm_socket_path) |
||||
-realm.start_server([sys.executable, kcmserver_path, '-c', kcm_socket_path], |
||||
+realm.start_server([sys.executable, kcmserver_path, '-f', kcm_socket_path], |
||||
'starting...') |
||||
collection_test(realm, 'KCM:') |
||||
|
@ -0,0 +1,485 @@
@@ -0,0 +1,485 @@
|
||||
From 21e3b9a4463f1d1aeb71de8a27c298f1307d186b Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 4 Oct 2019 14:49:29 -0400 |
||||
Subject: [PATCH] Use OpenSSL's KBKDF and KRB5KDF for deriving long-term keys |
||||
|
||||
If supported, use OpenSSL-provided KBKDF (aes-sha2 and camellia) and |
||||
KRB5KDF (3des and aes-sha1). We already use OpenSSL's PBKDF2 where |
||||
appropriate. OpenSSL added support for these KDFs in 3.0. |
||||
|
||||
OpenSSL's restrictions to use KRB5KDF in FIPS mode are bypassed in case |
||||
AES SHA-1 HMAC encryption types are allowed by the crypto policy. |
||||
|
||||
(cherry picked from commit ef8d11f6fb1232201c9efd2ae2ed567023fb85d2) |
||||
[rharwood@redhat.com: 3des removal] |
||||
--- |
||||
src/lib/crypto/krb/derive.c | 409 ++++++++++++++++++++++++++++-------- |
||||
1 file changed, 324 insertions(+), 85 deletions(-) |
||||
|
||||
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c |
||||
index 6707a7308..8e474b38e 100644 |
||||
--- a/src/lib/crypto/krb/derive.c |
||||
+++ b/src/lib/crypto/krb/derive.c |
||||
@@ -27,6 +27,12 @@ |
||||
|
||||
#include "crypto_int.h" |
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
+#include <openssl/core_names.h> |
||||
+#include <openssl/evp.h> |
||||
+#include <openssl/kdf.h> |
||||
+#endif |
||||
+ |
||||
static krb5_key |
||||
find_cached_dkey(struct derived_key *list, const krb5_data *constant) |
||||
{ |
||||
@@ -77,55 +83,251 @@ cleanup: |
||||
return ENOMEM; |
||||
} |
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
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_data block = empty_data(); |
||||
+ EVP_KDF *kdf = NULL; |
||||
+ EVP_KDF_CTX *kctx = NULL; |
||||
+ OSSL_PARAM params[6]; |
||||
+ size_t i = 0; |
||||
+ char *digest; |
||||
|
||||
- blocksize = enc->block_size; |
||||
- keybytes = enc->keybytes; |
||||
+ /* On NULL hash, preserve default behavior for pbkdf2_string_to_key(). */ |
||||
+ if (hash == NULL || !strcmp(hash->hash_name, "SHA1")) { |
||||
+ digest = "SHA1"; |
||||
+ } else if (!strcmp(hash->hash_name, "SHA-256")) { |
||||
+ digest = "SHA256"; |
||||
+ } else if (!strcmp(hash->hash_name, "SHA-384")) { |
||||
+ digest = "SHA384"; |
||||
+ } else { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
|
||||
- if (blocksize == 1) |
||||
- return KRB5_BAD_ENCTYPE; |
||||
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) |
||||
+ kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); |
||||
+ if (!kdf) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kctx = EVP_KDF_CTX_new(kdf); |
||||
+ if (!kctx) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, |
||||
+ digest, 0); |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, |
||||
+ "HMAC", 0); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, |
||||
+ inkey->keyblock.contents, |
||||
+ inkey->keyblock.length); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, |
||||
+ context->data, |
||||
+ context->length); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, |
||||
+ label->data, |
||||
+ label->length); |
||||
+ params[i] = OSSL_PARAM_construct_end(); |
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length, |
||||
+ params) <= 0) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ ret = 0; |
||||
+done: |
||||
+ if (ret) |
||||
+ zap(outrnd->data, outrnd->length); |
||||
+ EVP_KDF_free(kdf); |
||||
+ EVP_KDF_CTX_free(kctx); |
||||
+ 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; |
||||
+ EVP_KDF *kdf = NULL; |
||||
+ EVP_KDF_CTX *kctx = NULL; |
||||
+ OSSL_PARAM params[7]; |
||||
+ size_t i = 0; |
||||
+ char *cipher; |
||||
+ static unsigned char zeroes[16]; |
||||
+ |
||||
+ memset(zeroes, 0, sizeof(zeroes)); |
||||
+ |
||||
+ if (!memcmp(enc, &krb5int_enc_camellia128, sizeof(*enc))) { |
||||
+ cipher = "CAMELLIA-128-CBC"; |
||||
+ } else if (!memcmp(enc, &krb5int_enc_camellia256, sizeof(*enc))) { |
||||
+ cipher = "CAMELLIA-256-CBC"; |
||||
+ } else { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); |
||||
+ if (!kdf) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kctx = EVP_KDF_CTX_new(kdf); |
||||
+ if (!kctx) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, |
||||
+ "FEEDBACK", 0); |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, |
||||
+ "CMAC", 0); |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, |
||||
+ cipher, 0); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, |
||||
+ inkey->keyblock.contents, |
||||
+ inkey->keyblock.length); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, |
||||
+ in_constant->data, |
||||
+ in_constant->length); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, |
||||
+ zeroes, sizeof(zeroes)); |
||||
+ params[i] = OSSL_PARAM_construct_end(); |
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length, |
||||
+ params) <= 0) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ ret = 0; |
||||
+done: |
||||
+ if (ret) |
||||
+ zap(outrnd->data, outrnd->length); |
||||
+ EVP_KDF_free(kdf); |
||||
+ EVP_KDF_CTX_free(kctx); |
||||
+ 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; |
||||
+ EVP_KDF *kdf = NULL; |
||||
+ EVP_KDF_CTX *kctx = NULL; |
||||
+ OSSL_PARAM params[4]; |
||||
+ size_t i = 0; |
||||
+ char *cipher; |
||||
+ |
||||
+ if (inkey->keyblock.length != enc->keylength || |
||||
+ outrnd->length != enc->keybytes) { |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ } |
||||
+ |
||||
+ if (!memcmp(enc, &krb5int_enc_aes128, sizeof(*enc))) { |
||||
+ cipher = "AES-128-CBC"; |
||||
+ } else if (!memcmp(enc, &krb5int_enc_aes256, sizeof(*enc))) { |
||||
+ cipher = "AES-256-CBC"; |
||||
+ } else { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips"); |
||||
+ if (kdf == NULL) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kctx = EVP_KDF_CTX_new(kdf); |
||||
+ if (kctx == NULL) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, |
||||
+ cipher, 0); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, |
||||
+ inkey->keyblock.contents, |
||||
+ inkey->keyblock.length); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_CONSTANT, |
||||
+ in_constant->data, |
||||
+ in_constant->length); |
||||
+ params[i] = OSSL_PARAM_construct_end(); |
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length, |
||||
+ params) <= 0) { |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ ret = 0; |
||||
+done: |
||||
+ if (ret) |
||||
+ zap(outrnd->data, outrnd->length); |
||||
+ EVP_KDF_free(kdf); |
||||
+ EVP_KDF_CTX_free(kctx); |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
+#else /* HAVE_EVP_KDF_FETCH */ |
||||
+ |
||||
+/* |
||||
+ * 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 prf; |
||||
+ unsigned char ibuf[4], lbuf[4]; |
||||
+ |
||||
+ 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 +341,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 +406,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 /* HAVE_EVP_KDF_FETCH */ |
||||
+ |
||||
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 HAVE_EVP_KDF_FETCH |
||||
+ 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 |
||||
+sp800_108_feedback_cmac(const struct krb5_enc_provider *enc, |
||||
+ krb5_key inkey, krb5_data *outrnd, |
||||
+ const krb5_data *in_constant) |
||||
+{ |
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
+ 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 |
||||
+derive_random_rfc3961(const struct krb5_enc_provider *enc, |
||||
+ krb5_key inkey, krb5_data *outrnd, |
||||
+ const krb5_data *in_constant) |
||||
+{ |
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
+ return openssl_krb5kdf(enc, inkey, outrnd, in_constant); |
||||
+#else |
||||
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant); |
||||
+#endif |
||||
} |
||||
|
||||
krb5_error_code |
||||
@@ -268,8 +508,7 @@ krb5int_derive_random(const struct krb5_enc_provider *enc, |
||||
case DERIVE_RFC3961: |
||||
return 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 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); |
@ -0,0 +1,408 @@
@@ -0,0 +1,408 @@
|
||||
From 8bbb492f2be1418e1e4bb2cf197414810dac9589 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 20 Sep 2019 17:20:59 -0400 |
||||
Subject: [PATCH] Use OpenSSL's SSKDF in PKINIT when available |
||||
|
||||
Starting in 3.0, OpenSSL implements SSKDF, which is the basis of our |
||||
id-pkinit-kdf (RFC 8636). Factor out common setup code around |
||||
other_info. Adjust code to comply to existing style. |
||||
|
||||
(cherry picked from commit 4376a22e41fb639be31daf81275a332d3f930996) |
||||
--- |
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 294 +++++++++++------- |
||||
1 file changed, 181 insertions(+), 113 deletions(-) |
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
index e1153344e..350c2118a 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
@@ -38,6 +38,12 @@ |
||||
#include <dirent.h> |
||||
#include <arpa/inet.h> |
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
+#include <openssl/core_names.h> |
||||
+#include <openssl/kdf.h> |
||||
+#include <openssl/params.h> |
||||
+#endif |
||||
+ |
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context ); |
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context ); |
||||
|
||||
@@ -2294,15 +2300,16 @@ cleanup: |
||||
} |
||||
|
||||
|
||||
-/** |
||||
+/* |
||||
* Given an algorithm_identifier, this function returns the hash length |
||||
* and EVP function associated with that algorithm. |
||||
+ * |
||||
+ * RFC 8636 defines a SHA384 variant, but we don't use it. |
||||
*/ |
||||
static krb5_error_code |
||||
-pkinit_alg_values(krb5_context context, |
||||
- const krb5_data *alg_id, |
||||
- size_t *hash_bytes, |
||||
- const EVP_MD *(**func)(void)) |
||||
+pkinit_alg_values(krb5_context context, const krb5_data *alg_id, |
||||
+ size_t *hash_bytes, const EVP_MD *(**func)(void), |
||||
+ char **hash_name) |
||||
{ |
||||
*hash_bytes = 0; |
||||
*func = NULL; |
||||
@@ -2311,18 +2318,21 @@ pkinit_alg_values(krb5_context context, |
||||
krb5_pkinit_sha1_oid_len))) { |
||||
*hash_bytes = 20; |
||||
*func = &EVP_sha1; |
||||
+ *hash_name = strdup("SHA1"); |
||||
return 0; |
||||
} else if ((alg_id->length == krb5_pkinit_sha256_oid_len) && |
||||
(0 == memcmp(alg_id->data, krb5_pkinit_sha256_oid, |
||||
krb5_pkinit_sha256_oid_len))) { |
||||
*hash_bytes = 32; |
||||
*func = &EVP_sha256; |
||||
+ *hash_name = strdup("SHA256"); |
||||
return 0; |
||||
} else if ((alg_id->length == krb5_pkinit_sha512_oid_len) && |
||||
(0 == memcmp(alg_id->data, krb5_pkinit_sha512_oid, |
||||
krb5_pkinit_sha512_oid_len))) { |
||||
*hash_bytes = 64; |
||||
*func = &EVP_sha512; |
||||
+ *hash_name = strdup("SHA512"); |
||||
return 0; |
||||
} else { |
||||
krb5_set_error_message(context, KRB5_ERR_BAD_S2K_PARAMS, |
||||
@@ -2331,11 +2341,60 @@ pkinit_alg_values(krb5_context context, |
||||
} |
||||
} /* pkinit_alg_values() */ |
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
+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, char *digest) |
||||
+{ |
||||
+ krb5_error_code ret; |
||||
+ EVP_KDF *kdf = NULL; |
||||
+ EVP_KDF_CTX *kctx = NULL; |
||||
+ OSSL_PARAM params[4]; |
||||
+ size_t i = 0; |
||||
|
||||
-/* 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: |
||||
+ if (digest == NULL) { |
||||
+ ret = oerr(context, ENOMEM, |
||||
+ _("Failed to allocate space for digest algorithm name")); |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); |
||||
+ if (kdf == NULL) { |
||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL, _("Failed to fetch SSKDF")); |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ kctx = EVP_KDF_CTX_new(kdf); |
||||
+ if (!kctx) { |
||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL, |
||||
+ _("Failed to instantiate SSKDF")); |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, |
||||
+ digest, 0); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, |
||||
+ key->data, key->length); |
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, |
||||
+ info->data, info->length); |
||||
+ params[i] = OSSL_PARAM_construct_end(); |
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)out, out_len, params) <= 0) { |
||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL, |
||||
+ _("Failed to derive key using SSKDF")); |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ ret = 0; |
||||
+done: |
||||
+ EVP_KDF_free(kdf); |
||||
+ EVP_KDF_CTX_free(kctx); |
||||
+ 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 +2408,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; |
||||
+ krb5_error_code ret = 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: |
||||
@@ -2450,7 +2430,7 @@ pkinit_alg_agility_kdf(krb5_context context, |
||||
|
||||
ctx = EVP_MD_CTX_new(); |
||||
if (ctx == NULL) { |
||||
- retval = KRB5_CRYPTO_INTERNAL; |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
goto cleanup; |
||||
} |
||||
|
||||
@@ -2458,7 +2438,7 @@ pkinit_alg_agility_kdf(krb5_context context, |
||||
if (!EVP_DigestInit(ctx, EVP_func())) { |
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL, |
||||
"Call to OpenSSL EVP_DigestInit() returned an error."); |
||||
- retval = KRB5_CRYPTO_INTERNAL; |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
goto cleanup; |
||||
} |
||||
|
||||
@@ -2467,15 +2447,16 @@ pkinit_alg_agility_kdf(krb5_context context, |
||||
!EVP_DigestUpdate(ctx, other_info->data, other_info->length)) { |
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL, |
||||
"Call to OpenSSL EVP_DigestUpdate() returned an error."); |
||||
- retval = KRB5_CRYPTO_INTERNAL; |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
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; |
||||
+ ret = KRB5_CRYPTO_INTERNAL; |
||||
goto cleanup; |
||||
} |
||||
offset += s; |
||||
@@ -2484,26 +2465,113 @@ 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 ret; |
||||
+} /* builtin_sskdf() */ |
||||
+#endif /* HAVE_EVP_KDF_FETCH */ |
||||
|
||||
- /* 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 ret; |
||||
+ 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; |
||||
+ char *hash_name = NULL; |
||||
+ |
||||
+ /* Allocate and initialize the key block. */ |
||||
+ key_block->magic = 0; |
||||
+ key_block->enctype = enctype; |
||||
+ |
||||
+ /* Use separate variables to avoid alignment restriction problems. */ |
||||
+ ret = krb5_c_keylengths(context, enctype, &rand_len, &key_len); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ random_data.length = rand_len; |
||||
+ key_block->length = key_len; |
||||
+ |
||||
+ key_block->contents = k5calloc(key_block->length, 1, &ret); |
||||
+ 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); |
||||
+ ret = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func, |
||||
+ &hash_name); |
||||
+ if (ret) |
||||
+ 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, &ret); |
||||
+ 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; |
||||
+ ret = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields, |
||||
+ &supp_pub_info); |
||||
+ if (ret) |
||||
+ 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; |
||||
+ ret = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ |
||||
+#ifdef HAVE_EVP_KDF_FETCH |
||||
+ ret = openssl_sskdf(context, hash_len, secret, other_info, |
||||
+ random_data.data, key_block->length, hash_name); |
||||
+#else |
||||
+ ret = builtin_sskdf(context, reps, hash_len, EVP_func, secret, |
||||
+ other_info, random_data.data, key_block->length); |
||||
+#endif |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ |
||||
+ ret = krb5_c_random_to_key(context, enctype, &random_data, key_block); |
||||
+cleanup: |
||||
+ if (ret) |
||||
+ krb5_free_keyblock_contents(context, key_block); |
||||
+ |
||||
+ free(hash_name); |
||||
+ 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() */ |
||||
+ return ret; |
||||
+} |
||||
|
||||
/* Call DH_compute_key() and ensure that we left-pad short results instead of |
||||
* leaving junk bytes at the end of the buffer. */ |
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
From f0740c131b69f3346f07e7b7b03ebf27c50c0ccd Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Fri, 11 Mar 2022 11:33:56 +0100 |
||||
Subject: [PATCH] Use SHA-256 instead of SHA-1 for PKINIT CMS digest |
||||
|
||||
Various organizations including NIST have been strongly recommending to |
||||
stop using SHA-1 for digital signatures for some years already. CMS |
||||
digest is used to generate such signatures, hence it should be upgraded |
||||
to use SHA-256. |
||||
--- |
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 27 ++++++++++--------- |
||||
1 file changed, 14 insertions(+), 13 deletions(-) |
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
index 42e5c581d..2a6ef4aaa 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |
||||
@@ -1240,7 +1240,7 @@ cms_signeddata_create(krb5_context context, |
||||
/* will not fill-out EVP_PKEY because it's on the smartcard */ |
||||
|
||||
/* Set digest algs */ |
||||
- p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1); |
||||
+ p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha256); |
||||
|
||||
if (p7si->digest_alg->parameter != NULL) |
||||
ASN1_TYPE_free(p7si->digest_alg->parameter); |
||||
@@ -1251,17 +1251,17 @@ cms_signeddata_create(krb5_context context, |
||||
/* Set sig algs */ |
||||
if (p7si->digest_enc_alg->parameter != NULL) |
||||
ASN1_TYPE_free(p7si->digest_enc_alg->parameter); |
||||
- p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption); |
||||
+ p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha256WithRSAEncryption); |
||||
if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new())) |
||||
goto cleanup; |
||||
p7si->digest_enc_alg->parameter->type = V_ASN1_NULL; |
||||
|
||||
/* add signed attributes */ |
||||
- /* compute sha1 digest over the EncapsulatedContentInfo */ |
||||
+ /* compute sha256 digest over the EncapsulatedContentInfo */ |
||||
ctx = EVP_MD_CTX_new(); |
||||
if (ctx == NULL) |
||||
goto cleanup; |
||||
- EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); |
||||
+ EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); |
||||
EVP_DigestUpdate(ctx, data, data_len); |
||||
md_tmp = EVP_MD_CTX_md(ctx); |
||||
EVP_DigestFinal_ex(ctx, md_data, &md_len); |
||||
@@ -1289,9 +1289,10 @@ cms_signeddata_create(krb5_context context, |
||||
goto cleanup2; |
||||
|
||||
#ifndef WITHOUT_PKCS11 |
||||
- /* Some tokens can only do RSAEncryption without sha1 hash */ |
||||
- /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash |
||||
- * function and the hash value into an ASN.1 value of type DigestInfo |
||||
+ /* Some tokens can only do RSAEncryption without sha256 hash */ |
||||
+ /* to compute sha256WithRSAEncryption, encode the algorithm ID for the |
||||
+ * hash function and the hash value into an ASN.1 value of type |
||||
+ * DigestInfo |
||||
* DigestInfo::=SEQUENCE { |
||||
* digestAlgorithm AlgorithmIdentifier, |
||||
* digest OCTET STRING } |
||||
@@ -1310,7 +1311,7 @@ cms_signeddata_create(krb5_context context, |
||||
alg = X509_ALGOR_new(); |
||||
if (alg == NULL) |
||||
goto cleanup2; |
||||
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha1), V_ASN1_NULL, NULL); |
||||
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha256), V_ASN1_NULL, NULL); |
||||
alg_len = i2d_X509_ALGOR(alg, NULL); |
||||
|
||||
digest = ASN1_OCTET_STRING_new(); |
||||
@@ -1339,7 +1340,7 @@ cms_signeddata_create(krb5_context context, |
||||
#endif |
||||
{ |
||||
pkiDebug("mech = %s\n", |
||||
- id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS"); |
||||
+ id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA256_RSA_PKCS" : "FS"); |
||||
retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen, |
||||
&sig, &sig_len); |
||||
} |
||||
@@ -4189,7 +4190,7 @@ create_signature(unsigned char **sig, unsigned int *sig_len, |
||||
ctx = EVP_MD_CTX_new(); |
||||
if (ctx == NULL) |
||||
return ENOMEM; |
||||
- EVP_SignInit(ctx, EVP_sha1()); |
||||
+ EVP_SignInit(ctx, EVP_sha256()); |
||||
EVP_SignUpdate(ctx, data, data_len); |
||||
*sig_len = EVP_PKEY_size(pkey); |
||||
if ((*sig = malloc(*sig_len)) == NULL) |
||||
@@ -4663,10 +4664,10 @@ pkinit_get_certs_pkcs11(krb5_context context, |
||||
|
||||
#ifndef PKINIT_USE_MECH_LIST |
||||
/* |
||||
- * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but |
||||
+ * We'd like to use CKM_SHA256_RSA_PKCS for signing if it's available, but |
||||
* many cards seems to be confused about whether they are capable of |
||||
* this or not. The safe thing seems to be to ignore the mechanism list, |
||||
- * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves. |
||||
+ * always use CKM_RSA_PKCS and calculate the sha256 digest ourselves. |
||||
*/ |
||||
|
||||
id_cryptoctx->mech = CKM_RSA_PKCS; |
||||
@@ -4694,7 +4695,7 @@ pkinit_get_certs_pkcs11(krb5_context context, |
||||
if (mechp[i] == CKM_RSA_PKCS) { |
||||
/* This seems backwards... */ |
||||
id_cryptoctx->mech = |
||||
- (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS; |
||||
+ (info.flags & CKF_SIGN) ? CKM_SHA256_RSA_PKCS : CKM_RSA_PKCS; |
||||
} |
||||
} |
||||
free(mechp); |
||||
-- |
||||
2.35.1 |
||||
|
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
From 790f485cf57e4de65351c29c41666db6370ef367 Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Thu, 5 May 2022 17:15:12 +0200 |
||||
Subject: [PATCH] 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#2068458 |
||||
--- |
||||
src/lib/krad/remote.c | 36 ++++++++++++++++++++++++++++++++++-- |
||||
1 file changed, 34 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c |
||||
index eca432424..c8912892c 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,36 @@ 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) |
||||
@@ -455,8 +486,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.35.1 |
||||
|
@ -0,0 +1,699 @@
@@ -0,0 +1,699 @@
|
||||
From 4f8cba1780bc167c52de2a791cad6a1817508bbe Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Wed, 23 Feb 2022 17:34:33 +0100 |
||||
Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4 |
||||
|
||||
NB: Use openssl's PRNG in FIPS mode and taint within krad. |
||||
|
||||
A lot of the FIPS error conditions from OpenSSL are incredibly |
||||
mysterious (at best, things return NULL unexpectedly; at worst, |
||||
internal assertions are tripped; most of the time, you just get |
||||
ENOMEM). In order to cope with this, we need to have some level of |
||||
awareness of what we can and can't safely call. |
||||
|
||||
This will slow down some calls slightly (FIPS_mode() takes multiple |
||||
locks), but not for any ciphers we care about - which is to say that |
||||
AES is fine. Shame about SPAKE though. |
||||
|
||||
post6 restores MD4 (and therefore keygen-only RC4). |
||||
|
||||
post7 restores MD5 and adds radius_md5_fips_override. |
||||
|
||||
post8 restores MD4/MD5 for OpenSSL 3.0 |
||||
|
||||
Use OpenSSL 3.0 library context to access MD4 and MD5 lazily from |
||||
legacy provider if RC4 encryption type is enabled, without affecting |
||||
global context. |
||||
|
||||
Remove EVP_MD_CTX_FLAG_NON_FIPS_ALLOW flag since does not have any |
||||
effect anymore. |
||||
|
||||
post9 load both default and legacy provider into library context |
||||
|
||||
Last-updated: krb5-1.19 |
||||
--- |
||||
doc/admin/conf_files/krb5_conf.rst | 6 ++ |
||||
src/lib/crypto/krb/prng.c | 11 ++- |
||||
.../crypto/openssl/enc_provider/camellia.c | 6 ++ |
||||
src/lib/crypto/openssl/enc_provider/rc4.c | 13 ++- |
||||
.../crypto/openssl/hash_provider/hash_evp.c | 93 ++++++++++++++++++- |
||||
src/lib/crypto/openssl/hmac.c | 6 +- |
||||
src/lib/krad/attr.c | 46 ++++++--- |
||||
src/lib/krad/attrset.c | 5 +- |
||||
src/lib/krad/internal.h | 28 +++++- |
||||
src/lib/krad/packet.c | 22 +++-- |
||||
src/lib/krad/remote.c | 10 +- |
||||
src/lib/krad/t_attr.c | 3 +- |
||||
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, 230 insertions(+), 35 deletions(-) |
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst |
||||
index 675175955..adba8238d 100644 |
||||
--- a/doc/admin/conf_files/krb5_conf.rst |
||||
+++ b/doc/admin/conf_files/krb5_conf.rst |
||||
@@ -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.) |
||||
|
||||
+**radius_md5_fips_override** |
||||
+ Downstream-only option to enable use of MD5 in RADIUS |
||||
+ communication (libkrad). This allows for local (or protected |
||||
+ tunnel) communication with a RADIUS server that doesn't use krad |
||||
+ (e.g., freeradius) while in FIPS mode. |
||||
+ |
||||
**rdns** |
||||
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 |
||||
--- a/src/lib/crypto/krb/prng.c |
||||
+++ b/src/lib/crypto/krb/prng.c |
||||
@@ -26,6 +26,8 @@ |
||||
|
||||
#include "crypto_int.h" |
||||
|
||||
+#include <openssl/rand.h> |
||||
+ |
||||
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) |
||||
{ |
||||
const char *device; |
||||
-#if defined(__linux__) && defined(SYS_getrandom) |
||||
int r; |
||||
|
||||
+ /* A wild FIPS mode appeared! */ |
||||
+ if (FIPS_mode()) { |
||||
+ /* The return codes on this API are not good */ |
||||
+ r = RAND_bytes(buf, len); |
||||
+ return r == 1; |
||||
+ } |
||||
+ |
||||
+#if defined(__linux__) && defined(SYS_getrandom) |
||||
while (len > 0) { |
||||
/* |
||||
* 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 |
||||
--- 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, |
||||
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE]; |
||||
struct iov_cursor cursor; |
||||
|
||||
+ if (FIPS_mode()) |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ |
||||
if (output->length < CAMELLIA_BLOCK_SIZE) |
||||
return KRB5_BAD_MSIZE; |
||||
|
||||
@@ -331,6 +334,9 @@ static krb5_error_code |
||||
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage, |
||||
krb5_data *state) |
||||
{ |
||||
+ if (FIPS_mode()) |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ |
||||
state->length = 16; |
||||
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 bc87c6f42..9bf407899 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, |
||||
EVP_CIPHER_CTX *ctx = NULL; |
||||
struct arcfour_state *arcstate; |
||||
|
||||
+ if (FIPS_mode()) |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ |
||||
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, |
||||
static void |
||||
k5_arcfour_free_state(krb5_data *state) |
||||
{ |
||||
- struct arcfour_state *arcstate = (void *)state->data; |
||||
+ struct arcfour_state *arcstate; |
||||
+ |
||||
+ if (FIPS_mode()) |
||||
+ return; |
||||
+ |
||||
+ arcstate = (void *) state->data; |
||||
|
||||
EVP_CIPHER_CTX_free(arcstate->ctx); |
||||
free(arcstate); |
||||
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key, |
||||
{ |
||||
struct arcfour_state *arcstate; |
||||
|
||||
+ if (FIPS_mode()) |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ |
||||
/* |
||||
* 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..57bca3fec 100644 |
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c |
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c |
||||
@@ -32,6 +32,46 @@ |
||||
|
||||
#include "crypto_int.h" |
||||
#include <openssl/evp.h> |
||||
+#include <openssl/provider.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, |
||||
@@ -61,16 +101,65 @@ 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; |
||||
+} |
||||
+ |
||||
static krb5_error_code |
||||
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) |
||||
{ |
||||
- return hash_evp(EVP_md4(), data, num_data, output); |
||||
+ /* |
||||
+ * MD4 is needed in FIPS mode to perform key generation for RC4 keys used |
||||
+ * by IPA. These keys are only used along a (separately) secured channel |
||||
+ * for legacy reasons when performing trusts to Active Directory. |
||||
+ */ |
||||
+ return FIPS_mode() ? hash_legacy_evp("MD4", data, num_data, output) |
||||
+ : hash_evp(EVP_md4(), data, num_data, output); |
||||
} |
||||
|
||||
static krb5_error_code |
||||
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) |
||||
{ |
||||
- 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); |
||||
} |
||||
|
||||
static krb5_error_code |
||||
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c |
||||
index 7dc59dcc0..769a50c00 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) |
||||
return EVP_sha256(); |
||||
else if (!strncmp(hash->hash_name, "SHA-384",7)) |
||||
return EVP_sha384(); |
||||
- else if (!strncmp(hash->hash_name, "MD5", 3)) |
||||
+ |
||||
+ if (FIPS_mode()) |
||||
+ return NULL; |
||||
+ |
||||
+ if (!strncmp(hash->hash_name, "MD5", 3)) |
||||
return EVP_md5(); |
||||
else if (!strncmp(hash->hash_name, "MD4", 3)) |
||||
return EVP_md4(); |
||||
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c |
||||
index 9c13d9d75..42d354a3b 100644 |
||||
--- a/src/lib/krad/attr.c |
||||
+++ b/src/lib/krad/attr.c |
||||
@@ -38,7 +38,8 @@ |
||||
typedef krb5_error_code |
||||
(*attribute_transform_fn)(krb5_context ctx, const char *secret, |
||||
const unsigned char *auth, const krb5_data *in, |
||||
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); |
||||
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips); |
||||
|
||||
typedef struct { |
||||
const char *name; |
||||
@@ -51,12 +52,14 @@ typedef struct { |
||||
static krb5_error_code |
||||
user_password_encode(krb5_context ctx, const char *secret, |
||||
const unsigned char *auth, const krb5_data *in, |
||||
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); |
||||
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips); |
||||
|
||||
static krb5_error_code |
||||
user_password_decode(krb5_context ctx, const char *secret, |
||||
const unsigned char *auth, const krb5_data *in, |
||||
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); |
||||
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, |
||||
+ krb5_boolean *ignored); |
||||
|
||||
static const attribute_record attributes[UCHAR_MAX] = { |
||||
{"User-Name", 1, MAX_ATTRSIZE, NULL, NULL}, |
||||
@@ -128,7 +131,8 @@ static const attribute_record attributes[UCHAR_MAX] = { |
||||
static krb5_error_code |
||||
user_password_encode(krb5_context ctx, const char *secret, |
||||
const unsigned char *auth, const krb5_data *in, |
||||
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen) |
||||
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips) |
||||
{ |
||||
const unsigned char *indx; |
||||
krb5_error_code retval; |
||||
@@ -154,8 +158,15 @@ user_password_encode(krb5_context ctx, const char *secret, |
||||
for (blck = 0, indx = auth; blck * BLOCKSIZE < len; blck++) { |
||||
memcpy(tmp.data + seclen, indx, BLOCKSIZE); |
||||
|
||||
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp, |
||||
- &sum); |
||||
+ if (kr_use_fips(ctx)) { |
||||
+ /* Skip encryption here. Taint so that we won't pass it out of |
||||
+ * the machine by accident. */ |
||||
+ *is_fips = TRUE; |
||||
+ sum.contents = calloc(1, BLOCKSIZE); |
||||
+ } else { |
||||
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp, |
||||
+ &sum); |
||||
+ } |
||||
if (retval != 0) { |
||||
zap(tmp.data, tmp.length); |
||||
zap(outbuf, len); |
||||
@@ -180,7 +191,8 @@ user_password_encode(krb5_context ctx, const char *secret, |
||||
static krb5_error_code |
||||
user_password_decode(krb5_context ctx, const char *secret, |
||||
const unsigned char *auth, const krb5_data *in, |
||||
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen) |
||||
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips) |
||||
{ |
||||
const unsigned char *indx; |
||||
krb5_error_code retval; |
||||
@@ -204,8 +216,15 @@ user_password_decode(krb5_context ctx, const char *secret, |
||||
for (blck = 0, indx = auth; blck * BLOCKSIZE < in->length; blck++) { |
||||
memcpy(tmp.data + seclen, indx, BLOCKSIZE); |
||||
|
||||
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, |
||||
- &tmp, &sum); |
||||
+ if (kr_use_fips(ctx)) { |
||||
+ /* Skip encryption here. Taint so that we won't pass it out of |
||||
+ * the machine by accident. */ |
||||
+ *is_fips = TRUE; |
||||
+ sum.contents = calloc(1, BLOCKSIZE); |
||||
+ } else { |
||||
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, |
||||
+ &tmp, &sum); |
||||
+ } |
||||
if (retval != 0) { |
||||
zap(tmp.data, tmp.length); |
||||
zap(outbuf, in->length); |
||||
@@ -248,7 +267,7 @@ krb5_error_code |
||||
kr_attr_encode(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) |
||||
+ size_t *outlen, krb5_boolean *is_fips) |
||||
{ |
||||
krb5_error_code retval; |
||||
|
||||
@@ -265,7 +284,8 @@ kr_attr_encode(krb5_context ctx, const char *secret, |
||||
return 0; |
||||
} |
||||
|
||||
- return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen); |
||||
+ return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen, |
||||
+ is_fips); |
||||
} |
||||
|
||||
krb5_error_code |
||||
@@ -274,6 +294,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, |
||||
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen) |
||||
{ |
||||
krb5_error_code retval; |
||||
+ krb5_boolean ignored; |
||||
|
||||
retval = kr_attr_valid(type, in); |
||||
if (retval != 0) |
||||
@@ -288,7 +309,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, |
||||
return 0; |
||||
} |
||||
|
||||
- return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen); |
||||
+ return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen, |
||||
+ &ignored); |
||||
} |
||||
|
||||
krad_attr |
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c |
||||
index 03c613716..d89982a13 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) |
||||
krb5_error_code |
||||
kr_attrset_encode(const krad_attrset *set, const char *secret, |
||||
const unsigned char *auth, |
||||
- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen) |
||||
+ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips) |
||||
{ |
||||
unsigned char buffer[MAX_ATTRSIZE]; |
||||
krb5_error_code retval; |
||||
@@ -181,7 +182,7 @@ kr_attrset_encode(const krad_attrset *set, const char *secret, |
||||
|
||||
K5_TAILQ_FOREACH(a, &set->list, list) { |
||||
retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr, |
||||
- buffer, &attrlen); |
||||
+ buffer, &attrlen, is_fips); |
||||
if (retval != 0) |
||||
return retval; |
||||
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h |
||||
index 0143d155a..223ffd730 100644 |
||||
--- a/src/lib/krad/internal.h |
||||
+++ b/src/lib/krad/internal.h |
||||
@@ -39,6 +39,8 @@ |
||||
#include <sys/socket.h> |
||||
#include <netdb.h> |
||||
|
||||
+#include <openssl/crypto.h> |
||||
+ |
||||
#ifndef UCHAR_MAX |
||||
#define UCHAR_MAX 255 |
||||
#endif |
||||
@@ -49,6 +51,13 @@ |
||||
|
||||
typedef struct krad_remote_st krad_remote; |
||||
|
||||
+struct krad_packet_st { |
||||
+ char buffer[KRAD_PACKET_SIZE_MAX]; |
||||
+ krad_attrset *attrset; |
||||
+ krb5_data pkt; |
||||
+ krb5_boolean is_fips; |
||||
+}; |
||||
+ |
||||
/* Validate constraints of an attribute. */ |
||||
krb5_error_code |
||||
kr_attr_valid(krad_attr type, const krb5_data *data); |
||||
@@ -57,7 +66,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data); |
||||
krb5_error_code |
||||
kr_attr_encode(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); |
||||
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips); |
||||
|
||||
/* Decode an attribute. */ |
||||
krb5_error_code |
||||
@@ -69,7 +79,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, |
||||
krb5_error_code |
||||
kr_attrset_encode(const krad_attrset *set, const char *secret, |
||||
const unsigned char *auth, |
||||
- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen); |
||||
+ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen, |
||||
+ krb5_boolean *is_fips); |
||||
|
||||
/* Decode attributes from a buffer. */ |
||||
krb5_error_code |
||||
@@ -152,4 +163,17 @@ gai_error_code(int err) |
||||
} |
||||
} |
||||
|
||||
+static inline krb5_boolean |
||||
+kr_use_fips(krb5_context ctx) |
||||
+{ |
||||
+ int val = 0; |
||||
+ |
||||
+ if (!FIPS_mode()) |
||||
+ return 0; |
||||
+ |
||||
+ 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 |
||||
--- a/src/lib/krad/packet.c |
||||
+++ b/src/lib/krad/packet.c |
||||
@@ -53,12 +53,6 @@ typedef unsigned char uchar; |
||||
#define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH)) |
||||
#define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR)) |
||||
|
||||
-struct krad_packet_st { |
||||
- char buffer[KRAD_PACKET_SIZE_MAX]; |
||||
- krad_attrset *attrset; |
||||
- krb5_data pkt; |
||||
-}; |
||||
- |
||||
typedef struct { |
||||
uchar x[(UCHAR_MAX + 1) / 8]; |
||||
} idmap; |
||||
@@ -187,8 +181,14 @@ auth_generate_response(krb5_context ctx, const char *secret, |
||||
memcpy(data.data + response->pkt.length, secret, strlen(secret)); |
||||
|
||||
/* Hash it. */ |
||||
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data, |
||||
- &hash); |
||||
+ if (kr_use_fips(ctx)) { |
||||
+ /* This checksum does very little security-wise anyway, so don't |
||||
+ * taint. */ |
||||
+ hash.contents = calloc(1, AUTH_FIELD_SIZE); |
||||
+ } else { |
||||
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data, |
||||
+ &hash); |
||||
+ } |
||||
free(data.data); |
||||
if (retval != 0) |
||||
return retval; |
||||
@@ -276,7 +276,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code, |
||||
|
||||
/* Encode the attributes. */ |
||||
retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt), |
||||
- &attrset_len); |
||||
+ &attrset_len, &pkt->is_fips); |
||||
if (retval != 0) |
||||
goto error; |
||||
|
||||
@@ -314,7 +314,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code, |
||||
|
||||
/* Encode the attributes. */ |
||||
retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt), |
||||
- &attrset_len); |
||||
+ &attrset_len, &pkt->is_fips); |
||||
if (retval != 0) |
||||
goto error; |
||||
|
||||
@@ -451,6 +451,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret, |
||||
const krb5_data * |
||||
krad_packet_encode(const krad_packet *pkt) |
||||
{ |
||||
+ if (pkt->is_fips) |
||||
+ return NULL; |
||||
return &pkt->pkt; |
||||
} |
||||
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c |
||||
index c96a9b4ee..eca432424 100644 |
||||
--- a/src/lib/krad/remote.c |
||||
+++ b/src/lib/krad/remote.c |
||||
@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr) |
||||
request *r; |
||||
|
||||
K5_TAILQ_FOREACH(r, &rr->list, list) { |
||||
- tmp = krad_packet_encode(r->request); |
||||
+ tmp = &r->request->pkt; |
||||
|
||||
/* If the packet has already been sent, do nothing. */ |
||||
if (r->sent == tmp->length) |
||||
@@ -359,7 +359,7 @@ on_io_read(krad_remote *rr) |
||||
if (req != NULL) { |
||||
K5_TAILQ_FOREACH(r, &rr->list, list) { |
||||
if (r->request == req && |
||||
- r->sent == krad_packet_encode(req)->length) { |
||||
+ r->sent == req->pkt.length) { |
||||
request_finish(r, 0, rsp); |
||||
break; |
||||
} |
||||
@@ -455,6 +455,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; |
||||
+ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL && |
||||
+ rr->info->ai_family != AF_UNIX) { |
||||
+ /* This would expose cleartext passwords, so abort. */ |
||||
+ retval = ESOCKTNOSUPPORT; |
||||
+ goto error; |
||||
+ } |
||||
|
||||
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 |
||||
--- a/src/lib/krad/t_attr.c |
||||
+++ b/src/lib/krad/t_attr.c |
||||
@@ -50,6 +50,7 @@ main() |
||||
const char *tmp; |
||||
krb5_data in; |
||||
size_t len; |
||||
+ krb5_boolean is_fips = FALSE; |
||||
|
||||
noerror(krb5_init_context(&ctx)); |
||||
|
||||
@@ -73,7 +74,7 @@ main() |
||||
in = string2data((char *)decoded); |
||||
retval = kr_attr_encode(ctx, secret, auth, |
||||
krad_attr_name2num("User-Password"), |
||||
- &in, outbuf, &len); |
||||
+ &in, outbuf, &len, &is_fips); |
||||
insist(retval == 0); |
||||
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 |
||||
--- a/src/lib/krad/t_attrset.c |
||||
+++ b/src/lib/krad/t_attrset.c |
||||
@@ -49,6 +49,7 @@ main() |
||||
krb5_context ctx; |
||||
size_t len = 0, encode_len; |
||||
krb5_data tmp; |
||||
+ krb5_boolean is_fips = FALSE; |
||||
|
||||
noerror(krb5_init_context(&ctx)); |
||||
noerror(krad_attrset_new(ctx, &set)); |
||||
@@ -62,7 +63,8 @@ main() |
||||
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, buffer, &encode_len, |
||||
+ &is_fips)); |
||||
krad_attrset_free(set); |
||||
|
||||
/* 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 |
||||
--- a/src/plugins/preauth/spake/spake_client.c |
||||
+++ b/src/plugins/preauth/spake/spake_client.c |
||||
@@ -38,6 +38,8 @@ |
||||
#include "groups.h" |
||||
#include <krb5/clpreauth_plugin.h> |
||||
|
||||
+#include <openssl/crypto.h> |
||||
+ |
||||
typedef struct reqstate_st { |
||||
krb5_pa_spake *msg; /* set in prep_questions, used in process */ |
||||
krb5_keyblock *initial_key; |
||||
@@ -375,6 +377,10 @@ clpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver, |
||||
|
||||
if (maj_ver != 1) |
||||
return KRB5_PLUGIN_VER_NOTSUPP; |
||||
+ |
||||
+ if (FIPS_mode()) |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ |
||||
vt = (krb5_clpreauth_vtable)vtable; |
||||
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 |
||||
--- a/src/plugins/preauth/spake/spake_kdc.c |
||||
+++ b/src/plugins/preauth/spake/spake_kdc.c |
||||
@@ -41,6 +41,8 @@ |
||||
|
||||
#include <krb5/kdcpreauth_plugin.h> |
||||
|
||||
+#include <openssl/crypto.h> |
||||
+ |
||||
/* |
||||
* 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, |
||||
|
||||
if (maj_ver != 1) |
||||
return KRB5_PLUGIN_VER_NOTSUPP; |
||||
+ |
||||
+ if (FIPS_mode()) |
||||
+ return KRB5_CRYPTO_INTERNAL; |
||||
+ |
||||
vt = (krb5_kdcpreauth_vtable)vtable; |
||||
vt->name = "spake"; |
||||
vt->pa_type_list = pa_types; |
||||
-- |
||||
2.35.1 |
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,727 @@
@@ -0,0 +1,727 @@
|
||||
From 20cbbd0b273af56c6d527c8e6b9d96eef49926f2 Mon Sep 17 00:00:00 2001 |
||||
From: Julien Rische <jrische@redhat.com> |
||||
Date: Thu, 31 Mar 2022 18:24:39 +0200 |
||||
Subject: [PATCH] Use newly enforced dejagnu path naming convention |
||||
|
||||
Since version 1.6.3, dejagnu started to enforce a naming convention that |
||||
was already in place, but not mandatory: dejagnu test directories have |
||||
to be named "testsuite". If they don't implicit relative sub-paths |
||||
resolution (e.g. "lib", "config") is not forking. |
||||
|
||||
This commit renames kadm5 library's unit tests and global tests |
||||
directories to match this requirement. |
||||
|
||||
Resolves: rhbz#2053133 |
||||
|
||||
Signed-off-by: Julien Rische <jrische@redhat.com> |
||||
--- |
||||
src/configure.ac | 4 +-- |
||||
src/lib/kadm5/Makefile.in | 2 +- |
||||
.../{unit-test => testsuite}/Makefile.in | 28 +++++++++--------- |
||||
.../api.2/crte-policy.exp | 0 |
||||
.../api.2/get-policy.exp | 0 |
||||
.../api.2/mod-policy.exp | 0 |
||||
.../api.current/chpass-principal-v2.exp | 0 |
||||
.../api.current/chpass-principal.exp | 0 |
||||
.../api.current/crte-policy.exp | 0 |
||||
.../api.current/crte-principal.exp | 0 |
||||
.../api.current/destroy.exp | 0 |
||||
.../api.current/dlte-policy.exp | 0 |
||||
.../api.current/dlte-principal.exp | 0 |
||||
.../api.current/get-policy.exp | 0 |
||||
.../api.current/get-principal-v2.exp | 0 |
||||
.../api.current/get-principal.exp | 0 |
||||
.../api.current/init-v2.exp | 0 |
||||
.../api.current/init.exp | 0 |
||||
.../api.current/mod-policy.exp | 0 |
||||
.../api.current/mod-principal-v2.exp | 0 |
||||
.../api.current/mod-principal.exp | 0 |
||||
.../api.current/randkey-principal-v2.exp | 0 |
||||
.../api.current/randkey-principal.exp | 0 |
||||
.../{unit-test => testsuite}/config/unix.exp | 0 |
||||
src/lib/kadm5/{unit-test => testsuite}/deps | 0 |
||||
.../{unit-test => testsuite}/destroy-test.c | 0 |
||||
.../diff-files/destroy-1 | 0 |
||||
.../diff-files/no-diffs | 0 |
||||
.../{unit-test => testsuite}/handle-test.c | 0 |
||||
.../{unit-test => testsuite}/init-test.c | 0 |
||||
.../{unit-test => testsuite}/iter-test.c | 0 |
||||
.../kadm5/{unit-test => testsuite}/lib/lib.t | 2 +- |
||||
.../{unit-test => testsuite}/lock-test.c | 0 |
||||
.../{unit-test => testsuite}/randkey-test.c | 0 |
||||
.../{unit-test => testsuite}/setkey-test.c | 0 |
||||
.../kadm5/{unit-test => testsuite}/site.exp | 0 |
||||
src/tests/Makefile.in | 2 +- |
||||
src/tests/t_authdata.py | 2 +- |
||||
src/tests/t_certauth.py | 2 +- |
||||
src/tests/t_pkinit.py | 2 +- |
||||
src/tests/t_proxy.py | 12 ++++---- |
||||
src/tests/{dejagnu => testsuite}/Makefile.in | 4 +-- |
||||
.../{dejagnu => testsuite}/config/default.exp | 2 +- |
||||
src/tests/{dejagnu => testsuite}/deps | 0 |
||||
.../krb-standalone/gssapi.exp | 2 +- |
||||
.../krb-standalone/kprop.exp | 0 |
||||
.../krb-standalone/princexpire.exp | 0 |
||||
.../krb-standalone/sample.exp | 2 +- |
||||
.../krb-standalone/simple.exp | 2 +- |
||||
.../krb-standalone/standalone.exp | 0 |
||||
.../krb-standalone/tcp.exp | 0 |
||||
.../pkinit-certs/ca.pem | 0 |
||||
.../pkinit-certs/generic.p12 | Bin |
||||
.../pkinit-certs/generic.pem | 0 |
||||
.../pkinit-certs/kdc.pem | 0 |
||||
.../pkinit-certs/make-certs.sh | 0 |
||||
.../pkinit-certs/privkey-enc.pem | 0 |
||||
.../pkinit-certs/privkey.pem | 0 |
||||
.../pkinit-certs/user-enc.p12 | Bin |
||||
.../pkinit-certs/user-upn.p12 | Bin |
||||
.../pkinit-certs/user-upn.pem | 0 |
||||
.../pkinit-certs/user-upn2.p12 | Bin |
||||
.../pkinit-certs/user-upn2.pem | 0 |
||||
.../pkinit-certs/user-upn3.p12 | Bin |
||||
.../pkinit-certs/user-upn3.pem | 0 |
||||
.../pkinit-certs/user.p12 | Bin |
||||
.../pkinit-certs/user.pem | 0 |
||||
.../{dejagnu => testsuite}/proxy-certs/ca.pem | 0 |
||||
.../proxy-certs/make-certs.sh | 0 |
||||
.../proxy-certs/proxy-badsig.pem | 0 |
||||
.../proxy-certs/proxy-ideal.pem | 0 |
||||
.../proxy-certs/proxy-no-match.pem | 0 |
||||
.../proxy-certs/proxy-san.pem | 0 |
||||
.../proxy-certs/proxy-subject.pem | 0 |
||||
src/tests/{dejagnu => testsuite}/t_inetd.c | 2 +- |
||||
src/util/k5test.py | 2 +- |
||||
76 files changed, 36 insertions(+), 36 deletions(-) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/Makefile.in (86%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.2/crte-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.2/get-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.2/mod-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/chpass-principal-v2.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/chpass-principal.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/crte-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/crte-principal.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/destroy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/dlte-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/dlte-principal.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/get-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/get-principal-v2.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/get-principal.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/init-v2.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/init.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/mod-policy.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/mod-principal-v2.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/mod-principal.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/randkey-principal-v2.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/api.current/randkey-principal.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/config/unix.exp (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/deps (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/destroy-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/diff-files/destroy-1 (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/diff-files/no-diffs (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/handle-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/init-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/iter-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/lib/lib.t (99%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/lock-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/randkey-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/setkey-test.c (100%) |
||||
rename src/lib/kadm5/{unit-test => testsuite}/site.exp (100%) |
||||
rename src/tests/{dejagnu => testsuite}/Makefile.in (92%) |
||||
rename src/tests/{dejagnu => testsuite}/config/default.exp (99%) |
||||
rename src/tests/{dejagnu => testsuite}/deps (100%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/gssapi.exp (98%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/kprop.exp (100%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/princexpire.exp (100%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/sample.exp (98%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/simple.exp (98%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/standalone.exp (100%) |
||||
rename src/tests/{dejagnu => testsuite}/krb-standalone/tcp.exp (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/ca.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/generic.p12 (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/generic.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/kdc.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/make-certs.sh (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/privkey-enc.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/privkey.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-enc.p12 (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn.p12 (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn2.p12 (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn2.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn3.p12 (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user-upn3.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user.p12 (100%) |
||||
rename src/tests/{dejagnu => testsuite}/pkinit-certs/user.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/ca.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/make-certs.sh (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-badsig.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-ideal.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-no-match.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-san.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/proxy-certs/proxy-subject.pem (100%) |
||||
rename src/tests/{dejagnu => testsuite}/t_inetd.c (99%) |
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac |
||||
index 20066918b..363d5d62d 100644 |
||||
--- a/src/configure.ac |
||||
+++ b/src/configure.ac |
||||
@@ -1500,7 +1500,7 @@ V5_AC_OUTPUT_MAKEFILE(. |
||||
|
||||
lib/rpc lib/rpc/unit-test |
||||
|
||||
- lib/kadm5 lib/kadm5/clnt lib/kadm5/srv lib/kadm5/unit-test |
||||
+ lib/kadm5 lib/kadm5/clnt lib/kadm5/srv lib/kadm5/testsuite |
||||
lib/krad |
||||
lib/apputils |
||||
|
||||
@@ -1544,5 +1544,5 @@ V5_AC_OUTPUT_MAKEFILE(. |
||||
appl/gss-sample appl/user_user |
||||
|
||||
tests tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi |
||||
- tests/dejagnu tests/threads tests/shlib tests/gss-threads tests/misc |
||||
+ tests/testsuite tests/threads tests/shlib tests/gss-threads tests/misc |
||||
) |
||||
diff --git a/src/lib/kadm5/Makefile.in b/src/lib/kadm5/Makefile.in |
||||
index c4eaad38d..76fc4b548 100644 |
||||
--- a/src/lib/kadm5/Makefile.in |
||||
+++ b/src/lib/kadm5/Makefile.in |
||||
@@ -1,6 +1,6 @@ |
||||
mydir=lib$(S)kadm5 |
||||
BUILDTOP=$(REL)..$(S).. |
||||
-SUBDIRS = clnt srv unit-test |
||||
+SUBDIRS = clnt srv testsuite |
||||
|
||||
##DOSBUILDTOP = ..\.. |
||||
|
||||
diff --git a/src/lib/kadm5/unit-test/Makefile.in b/src/lib/kadm5/testsuite/Makefile.in |
||||
similarity index 86% |
||||
rename from src/lib/kadm5/unit-test/Makefile.in |
||||
rename to src/lib/kadm5/testsuite/Makefile.in |
||||
index 68fa097ff..5a55b786b 100644 |
||||
--- a/src/lib/kadm5/unit-test/Makefile.in |
||||
+++ b/src/lib/kadm5/testsuite/Makefile.in |
||||
@@ -1,4 +1,4 @@ |
||||
-mydir=lib$(S)kadm5$(S)unit-test |
||||
+mydir=lib$(S)kadm5$(S)testsuite |
||||
BUILDTOP=$(REL)..$(S)..$(S).. |
||||
KDB_DEP_LIB=$(DL_LIB) $(THREAD_LINKOPTS) |
||||
|
||||
@@ -61,7 +61,7 @@ runenv.exp: Makefile |
||||
eval echo "set env\($$i\) \$$$$i"; done > runenv.exp |
||||
|
||||
# |
||||
-# The unit-test targets |
||||
+# The testsuite targets |
||||
# |
||||
|
||||
check: check-@DO_TEST@ |
||||
@@ -72,13 +72,13 @@ check-: |
||||
@echo "+++ Either tcl, runtest, or Perl is unavailable." |
||||
@echo "+++" |
||||
|
||||
-check-ok unit-test: unit-test-client unit-test-server |
||||
+check-ok testsuite: testsuite-client testsuite-server |
||||
|
||||
-unit-test-client: unit-test-client-setup unit-test-client-body \ |
||||
- unit-test-client-cleanup |
||||
+testsuite-client: testsuite-client-setup testsuite-client-body \ |
||||
+ testsuite-client-cleanup |
||||
|
||||
-unit-test-server: unit-test-server-setup unit-test-server-body \ |
||||
- unit-test-server-cleanup |
||||
+testsuite-server: testsuite-server-setup testsuite-server-body \ |
||||
+ testsuite-server-cleanup |
||||
|
||||
test-randkey: randkey-test |
||||
$(ENV_SETUP) $(VALGRIND) ./randkey-test |
||||
@@ -98,19 +98,19 @@ test-destroy: destroy-test |
||||
test-setkey-client: client-setkey-test |
||||
$(ENV_SETUP) $(VALGRIND) ./client-setkey-test testkeys admin admin |
||||
|
||||
-unit-test-client-setup: runenv.sh |
||||
+testsuite-client-setup: runenv.sh |
||||
$(ENV_SETUP) $(VALGRIND) $(START_SERVERS) |
||||
|
||||
-unit-test-client-cleanup: |
||||
+testsuite-client-cleanup: |
||||
$(ENV_SETUP) $(STOP_SERVERS) |
||||
|
||||
-unit-test-server-setup: runenv.sh |
||||
+testsuite-server-setup: runenv.sh |
||||
$(ENV_SETUP) $(VALGRIND) $(START_SERVERS_LOCAL) |
||||
|
||||
-unit-test-server-cleanup: |
||||
+testsuite-server-cleanup: |
||||
$(ENV_SETUP) $(STOP_SERVERS_LOCAL) |
||||
|
||||
-unit-test-client-body: site.exp test-noauth test-destroy test-handle-client \ |
||||
+testsuite-client-body: site.exp test-noauth test-destroy test-handle-client \ |
||||
test-setkey-client runenv.exp |
||||
$(ENV_SETUP) $(RUNTEST) --tool api RPC=1 API=$(CLNTTCL) \ |
||||
KINIT=$(BUILDTOP)/clients/kinit/kinit \ |
||||
@@ -121,7 +121,7 @@ unit-test-client-body: site.exp test-noauth test-destroy test-handle-client \ |
||||
-mv api.log capi.log |
||||
-mv api.sum capi.sum |
||||
|
||||
-unit-test-server-body: site.exp test-handle-server lock-test |
||||
+testsuite-server-body: site.exp test-handle-server lock-test |
||||
$(ENV_SETUP) $(RUNTEST) --tool api RPC=0 API=$(SRVTCL) \ |
||||
LOCKTEST=./lock-test \ |
||||
KADMIN_LOCAL=$(BUILDTOP)/kadmin/cli/kadmin.local \ |
||||
@@ -140,4 +140,4 @@ clean: |
||||
$(RM) lock-test lock-test.o |
||||
$(RM) server-iter-test iter-test.o |
||||
$(RM) server-setkey-test client-setkey-test setkey-test.o |
||||
- $(RM) *.log *.plog *.sum *.psum unit-test-log.* runenv.exp |
||||
+ $(RM) *.log *.plog *.sum *.psum testsuite-log.* runenv.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.2/crte-policy.exp b/src/lib/kadm5/testsuite/api.2/crte-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.2/crte-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.2/crte-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.2/get-policy.exp b/src/lib/kadm5/testsuite/api.2/get-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.2/get-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.2/get-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.2/mod-policy.exp b/src/lib/kadm5/testsuite/api.2/mod-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.2/mod-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.2/mod-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/chpass-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/chpass-principal-v2.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/chpass-principal-v2.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/chpass-principal-v2.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/chpass-principal.exp b/src/lib/kadm5/testsuite/api.current/chpass-principal.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/chpass-principal.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/chpass-principal.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/crte-policy.exp b/src/lib/kadm5/testsuite/api.current/crte-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/crte-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/crte-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/crte-principal.exp b/src/lib/kadm5/testsuite/api.current/crte-principal.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/crte-principal.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/crte-principal.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/destroy.exp b/src/lib/kadm5/testsuite/api.current/destroy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/destroy.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/destroy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/dlte-policy.exp b/src/lib/kadm5/testsuite/api.current/dlte-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/dlte-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/dlte-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/dlte-principal.exp b/src/lib/kadm5/testsuite/api.current/dlte-principal.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/dlte-principal.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/dlte-principal.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/get-policy.exp b/src/lib/kadm5/testsuite/api.current/get-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/get-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/get-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/get-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/get-principal-v2.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/get-principal-v2.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/get-principal-v2.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/get-principal.exp b/src/lib/kadm5/testsuite/api.current/get-principal.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/get-principal.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/get-principal.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/init-v2.exp b/src/lib/kadm5/testsuite/api.current/init-v2.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/init-v2.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/init-v2.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/init.exp b/src/lib/kadm5/testsuite/api.current/init.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/init.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/init.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/mod-policy.exp b/src/lib/kadm5/testsuite/api.current/mod-policy.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/mod-policy.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/mod-policy.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/mod-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/mod-principal-v2.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/mod-principal-v2.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/mod-principal-v2.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/mod-principal.exp b/src/lib/kadm5/testsuite/api.current/mod-principal.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/mod-principal.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/mod-principal.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/randkey-principal-v2.exp b/src/lib/kadm5/testsuite/api.current/randkey-principal-v2.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/randkey-principal-v2.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/randkey-principal-v2.exp |
||||
diff --git a/src/lib/kadm5/unit-test/api.current/randkey-principal.exp b/src/lib/kadm5/testsuite/api.current/randkey-principal.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/api.current/randkey-principal.exp |
||||
rename to src/lib/kadm5/testsuite/api.current/randkey-principal.exp |
||||
diff --git a/src/lib/kadm5/unit-test/config/unix.exp b/src/lib/kadm5/testsuite/config/unix.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/config/unix.exp |
||||
rename to src/lib/kadm5/testsuite/config/unix.exp |
||||
diff --git a/src/lib/kadm5/unit-test/deps b/src/lib/kadm5/testsuite/deps |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/deps |
||||
rename to src/lib/kadm5/testsuite/deps |
||||
diff --git a/src/lib/kadm5/unit-test/destroy-test.c b/src/lib/kadm5/testsuite/destroy-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/destroy-test.c |
||||
rename to src/lib/kadm5/testsuite/destroy-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/diff-files/destroy-1 b/src/lib/kadm5/testsuite/diff-files/destroy-1 |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/diff-files/destroy-1 |
||||
rename to src/lib/kadm5/testsuite/diff-files/destroy-1 |
||||
diff --git a/src/lib/kadm5/unit-test/diff-files/no-diffs b/src/lib/kadm5/testsuite/diff-files/no-diffs |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/diff-files/no-diffs |
||||
rename to src/lib/kadm5/testsuite/diff-files/no-diffs |
||||
diff --git a/src/lib/kadm5/unit-test/handle-test.c b/src/lib/kadm5/testsuite/handle-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/handle-test.c |
||||
rename to src/lib/kadm5/testsuite/handle-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/init-test.c b/src/lib/kadm5/testsuite/init-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/init-test.c |
||||
rename to src/lib/kadm5/testsuite/init-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/iter-test.c b/src/lib/kadm5/testsuite/iter-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/iter-test.c |
||||
rename to src/lib/kadm5/testsuite/iter-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/lib/lib.t b/src/lib/kadm5/testsuite/lib/lib.t |
||||
similarity index 99% |
||||
rename from src/lib/kadm5/unit-test/lib/lib.t |
||||
rename to src/lib/kadm5/testsuite/lib/lib.t |
||||
index 3444775cf..327946849 100644 |
||||
--- a/src/lib/kadm5/unit-test/lib/lib.t |
||||
+++ b/src/lib/kadm5/testsuite/lib/lib.t |
||||
@@ -226,7 +226,7 @@ proc end_dump_compare {name} { |
||||
global RPC |
||||
|
||||
if { ! $RPC } { |
||||
-# set file $TOP/admin/lib/unit-test/diff-files/$name |
||||
+# set file $TOP/admin/lib/testsuite/diff-files/$name |
||||
# exec $env(SIMPLE_DUMP) > /tmp/dump.after |
||||
# exec $env(COMPARE_DUMP) /tmp/dump.before /tmp/dump.after $file |
||||
} |
||||
diff --git a/src/lib/kadm5/unit-test/lock-test.c b/src/lib/kadm5/testsuite/lock-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/lock-test.c |
||||
rename to src/lib/kadm5/testsuite/lock-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/randkey-test.c b/src/lib/kadm5/testsuite/randkey-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/randkey-test.c |
||||
rename to src/lib/kadm5/testsuite/randkey-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/setkey-test.c b/src/lib/kadm5/testsuite/setkey-test.c |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/setkey-test.c |
||||
rename to src/lib/kadm5/testsuite/setkey-test.c |
||||
diff --git a/src/lib/kadm5/unit-test/site.exp b/src/lib/kadm5/testsuite/site.exp |
||||
similarity index 100% |
||||
rename from src/lib/kadm5/unit-test/site.exp |
||||
rename to src/lib/kadm5/testsuite/site.exp |
||||
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in |
||||
index 20f27d748..1198dca0c 100644 |
||||
--- a/src/tests/Makefile.in |
||||
+++ b/src/tests/Makefile.in |
||||
@@ -1,6 +1,6 @@ |
||||
mydir=tests |
||||
BUILDTOP=$(REL).. |
||||
-SUBDIRS = asn.1 create hammer verify gssapi dejagnu shlib gss-threads misc \ |
||||
+SUBDIRS = asn.1 create hammer verify gssapi testsuite shlib gss-threads misc \ |
||||
threads softpkcs11 |
||||
|
||||
RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \ |
||||
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py |
||||
index 2e01f46bc..e5135f435 100644 |
||||
--- a/src/tests/t_authdata.py |
||||
+++ b/src/tests/t_authdata.py |
||||
@@ -57,7 +57,7 @@ if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): |
||||
skipped('anonymous ticket authdata tests', 'PKINIT not built') |
||||
else: |
||||
# Set up a realm with PKINIT support and get anonymous tickets. |
||||
- certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') |
||||
+ certs = os.path.join(srctop, 'tests', 'testsuite', 'pkinit-certs') |
||||
ca_pem = os.path.join(certs, 'ca.pem') |
||||
kdc_pem = os.path.join(certs, 'kdc.pem') |
||||
privkey_pem = os.path.join(certs, 'privkey.pem') |
||||
diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py |
||||
index 0fe0fdb4a..bfa5bfc96 100644 |
||||
--- a/src/tests/t_certauth.py |
||||
+++ b/src/tests/t_certauth.py |
||||
@@ -4,7 +4,7 @@ from k5test import * |
||||
if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): |
||||
skip_rest('certauth tests', 'PKINIT module not built') |
||||
|
||||
-certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') |
||||
+certs = os.path.join(srctop, 'tests', 'testsuite', 'pkinit-certs') |
||||
ca_pem = os.path.join(certs, 'ca.pem') |
||||
kdc_pem = os.path.join(certs, 'kdc.pem') |
||||
privkey_pem = os.path.join(certs, 'privkey.pem') |
||||
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py |
||||
index aee4da2b1..8763ce484 100755 |
||||
--- a/src/tests/t_pkinit.py |
||||
+++ b/src/tests/t_pkinit.py |
||||
@@ -7,7 +7,7 @@ if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): |
||||
soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so') |
||||
|
||||
# Construct a krb5.conf fragment configuring pkinit. |
||||
-certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') |
||||
+certs = os.path.join(srctop, 'tests', 'testsuite', 'pkinit-certs') |
||||
ca_pem = os.path.join(certs, 'ca.pem') |
||||
kdc_pem = os.path.join(certs, 'kdc.pem') |
||||
user_pem = os.path.join(certs, 'user.pem') |
||||
diff --git a/src/tests/t_proxy.py b/src/tests/t_proxy.py |
||||
index 3069eaa8f..6ae5c8c8e 100755 |
||||
--- a/src/tests/t_proxy.py |
||||
+++ b/src/tests/t_proxy.py |
||||
@@ -10,17 +10,17 @@ except: |
||||
|
||||
# Construct a krb5.conf fragment configuring the client to use a local proxy |
||||
# server. |
||||
-proxysubjectpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', |
||||
+proxysubjectpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', |
||||
'proxy-subject.pem') |
||||
-proxysanpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', |
||||
+proxysanpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', |
||||
'proxy-san.pem') |
||||
-proxyidealpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', |
||||
+proxyidealpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', |
||||
'proxy-ideal.pem') |
||||
-proxywrongpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', |
||||
+proxywrongpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', |
||||
'proxy-no-match.pem') |
||||
-proxybadpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', |
||||
+proxybadpem = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', |
||||
'proxy-badsig.pem') |
||||
-proxyca = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'ca.pem') |
||||
+proxyca = os.path.join(srctop, 'tests', 'testsuite', 'proxy-certs', 'ca.pem') |
||||
proxyurl = 'https://localhost:$port5/KdcProxy' |
||||
proxyurlupcase = 'https://LocalHost:$port5/KdcProxy' |
||||
proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy' |
||||
diff --git a/src/tests/dejagnu/Makefile.in b/src/tests/testsuite/Makefile.in |
||||
similarity index 92% |
||||
rename from src/tests/dejagnu/Makefile.in |
||||
rename to src/tests/testsuite/Makefile.in |
||||
index e78e270ed..d3efe3606 100644 |
||||
--- a/src/tests/dejagnu/Makefile.in |
||||
+++ b/src/tests/testsuite/Makefile.in |
||||
@@ -1,4 +1,4 @@ |
||||
-mydir=tests$(S)dejagnu |
||||
+mydir=tests$(S)testsuite |
||||
BUILDTOP=$(REL)..$(S).. |
||||
RUNTEST = @RUNTEST@ $(DEJAFLAGS) |
||||
RUNTESTFLAGS = |
||||
@@ -13,7 +13,7 @@ check: check-runtest-@HAVE_RUNTEST@ |
||||
|
||||
check-runtest-no: |
||||
@echo "+++" |
||||
- @echo "+++ WARNING: tests/dejagnu tests not run." |
||||
+ @echo "+++ WARNING: tests/testsuite tests not run." |
||||
@echo "+++ runtest is unavailable." |
||||
@echo "+++" |
||||
@echo 'Skipped dejagnu tests: runtest not found' >> $(SKIPTESTS) |
||||
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/testsuite/config/default.exp |
||||
similarity index 99% |
||||
rename from src/tests/dejagnu/config/default.exp |
||||
rename to src/tests/testsuite/config/default.exp |
||||
index 302dee74c..1492fac32 100644 |
||||
--- a/src/tests/dejagnu/config/default.exp |
||||
+++ b/src/tests/testsuite/config/default.exp |
||||
@@ -256,7 +256,7 @@ verbose "Test realm is $REALMNAME" |
||||
|
||||
# Find some programs we need. We use the binaries from the build tree |
||||
# if they exist. If they do not, then they must be in PATH. We |
||||
-# expect $objdir to be ...tests/dejagnu. |
||||
+# expect $objdir to be ...tests/testsuite. |
||||
|
||||
foreach i { |
||||
{KDB5_UTIL $objdir/../../kadmin/dbutil/kdb5_util} |
||||
diff --git a/src/tests/dejagnu/deps b/src/tests/testsuite/deps |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/deps |
||||
rename to src/tests/testsuite/deps |
||||
diff --git a/src/tests/dejagnu/krb-standalone/gssapi.exp b/src/tests/testsuite/krb-standalone/gssapi.exp |
||||
similarity index 98% |
||||
rename from src/tests/dejagnu/krb-standalone/gssapi.exp |
||||
rename to src/tests/testsuite/krb-standalone/gssapi.exp |
||||
index e3357e769..d176e210c 100644 |
||||
--- a/src/tests/dejagnu/krb-standalone/gssapi.exp |
||||
+++ b/src/tests/testsuite/krb-standalone/gssapi.exp |
||||
@@ -2,7 +2,7 @@ |
||||
# This is a DejaGnu test script. |
||||
# This script tests that the GSS-API tester functions correctly. |
||||
|
||||
-# This mostly just calls procedures in test/dejagnu/config/default.exp. |
||||
+# This mostly just calls procedures in test/testsuite/config/default.exp. |
||||
|
||||
if ![info exists KDESTROY] { |
||||
set KDESTROY [findfile $objdir/../../clients/kdestroy/kdestroy] |
||||
diff --git a/src/tests/dejagnu/krb-standalone/kprop.exp b/src/tests/testsuite/krb-standalone/kprop.exp |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/krb-standalone/kprop.exp |
||||
rename to src/tests/testsuite/krb-standalone/kprop.exp |
||||
diff --git a/src/tests/dejagnu/krb-standalone/princexpire.exp b/src/tests/testsuite/krb-standalone/princexpire.exp |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/krb-standalone/princexpire.exp |
||||
rename to src/tests/testsuite/krb-standalone/princexpire.exp |
||||
diff --git a/src/tests/dejagnu/krb-standalone/sample.exp b/src/tests/testsuite/krb-standalone/sample.exp |
||||
similarity index 98% |
||||
rename from src/tests/dejagnu/krb-standalone/sample.exp |
||||
rename to src/tests/testsuite/krb-standalone/sample.exp |
||||
index 93a75f1d0..009de5ddb 100644 |
||||
--- a/src/tests/dejagnu/krb-standalone/sample.exp |
||||
+++ b/src/tests/testsuite/krb-standalone/sample.exp |
||||
@@ -2,7 +2,7 @@ |
||||
# This is a DejaGnu test script. |
||||
# This script tests that sample user-user communication works. |
||||
|
||||
-# This mostly just calls procedures in test/dejagnu/config/default.exp. |
||||
+# This mostly just calls procedures in test/testsuite/config/default.exp. |
||||
|
||||
if ![info exists KLIST] { |
||||
set KLIST [findfile $objdir/../../clients/klist/klist] |
||||
diff --git a/src/tests/dejagnu/krb-standalone/simple.exp b/src/tests/testsuite/krb-standalone/simple.exp |
||||
similarity index 98% |
||||
rename from src/tests/dejagnu/krb-standalone/simple.exp |
||||
rename to src/tests/testsuite/krb-standalone/simple.exp |
||||
index d8b218248..92b33066e 100644 |
||||
--- a/src/tests/dejagnu/krb-standalone/simple.exp |
||||
+++ b/src/tests/testsuite/krb-standalone/simple.exp |
||||
@@ -2,7 +2,7 @@ |
||||
# This is a DejaGnu test script. |
||||
# This script tests that krb-safe and krb-priv messages work. |
||||
|
||||
-# This mostly just calls procedures in test/dejagnu/config/default.exp. |
||||
+# This mostly just calls procedures in test/testsuite/config/default.exp. |
||||
|
||||
if ![info exists KLIST] { |
||||
set KLIST [findfile $objdir/../../clients/klist/klist] |
||||
diff --git a/src/tests/dejagnu/krb-standalone/standalone.exp b/src/tests/testsuite/krb-standalone/standalone.exp |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/krb-standalone/standalone.exp |
||||
rename to src/tests/testsuite/krb-standalone/standalone.exp |
||||
diff --git a/src/tests/dejagnu/krb-standalone/tcp.exp b/src/tests/testsuite/krb-standalone/tcp.exp |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/krb-standalone/tcp.exp |
||||
rename to src/tests/testsuite/krb-standalone/tcp.exp |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/ca.pem b/src/tests/testsuite/pkinit-certs/ca.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/ca.pem |
||||
rename to src/tests/testsuite/pkinit-certs/ca.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/generic.p12 b/src/tests/testsuite/pkinit-certs/generic.p12 |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/generic.p12 |
||||
rename to src/tests/testsuite/pkinit-certs/generic.p12 |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/generic.pem b/src/tests/testsuite/pkinit-certs/generic.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/generic.pem |
||||
rename to src/tests/testsuite/pkinit-certs/generic.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/kdc.pem b/src/tests/testsuite/pkinit-certs/kdc.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/kdc.pem |
||||
rename to src/tests/testsuite/pkinit-certs/kdc.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/testsuite/pkinit-certs/make-certs.sh |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
rename to src/tests/testsuite/pkinit-certs/make-certs.sh |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/privkey-enc.pem b/src/tests/testsuite/pkinit-certs/privkey-enc.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/privkey-enc.pem |
||||
rename to src/tests/testsuite/pkinit-certs/privkey-enc.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/privkey.pem b/src/tests/testsuite/pkinit-certs/privkey.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/privkey.pem |
||||
rename to src/tests/testsuite/pkinit-certs/privkey.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-enc.p12 b/src/tests/testsuite/pkinit-certs/user-enc.p12 |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-enc.p12 |
||||
rename to src/tests/testsuite/pkinit-certs/user-enc.p12 |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn.p12 b/src/tests/testsuite/pkinit-certs/user-upn.p12 |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-upn.p12 |
||||
rename to src/tests/testsuite/pkinit-certs/user-upn.p12 |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn.pem b/src/tests/testsuite/pkinit-certs/user-upn.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-upn.pem |
||||
rename to src/tests/testsuite/pkinit-certs/user-upn.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn2.p12 b/src/tests/testsuite/pkinit-certs/user-upn2.p12 |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-upn2.p12 |
||||
rename to src/tests/testsuite/pkinit-certs/user-upn2.p12 |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn2.pem b/src/tests/testsuite/pkinit-certs/user-upn2.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-upn2.pem |
||||
rename to src/tests/testsuite/pkinit-certs/user-upn2.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.p12 b/src/tests/testsuite/pkinit-certs/user-upn3.p12 |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-upn3.p12 |
||||
rename to src/tests/testsuite/pkinit-certs/user-upn3.p12 |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.pem b/src/tests/testsuite/pkinit-certs/user-upn3.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user-upn3.pem |
||||
rename to src/tests/testsuite/pkinit-certs/user-upn3.pem |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user.p12 b/src/tests/testsuite/pkinit-certs/user.p12 |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user.p12 |
||||
rename to src/tests/testsuite/pkinit-certs/user.p12 |
||||
diff --git a/src/tests/dejagnu/pkinit-certs/user.pem b/src/tests/testsuite/pkinit-certs/user.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/pkinit-certs/user.pem |
||||
rename to src/tests/testsuite/pkinit-certs/user.pem |
||||
diff --git a/src/tests/dejagnu/proxy-certs/ca.pem b/src/tests/testsuite/proxy-certs/ca.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/ca.pem |
||||
rename to src/tests/testsuite/proxy-certs/ca.pem |
||||
diff --git a/src/tests/dejagnu/proxy-certs/make-certs.sh b/src/tests/testsuite/proxy-certs/make-certs.sh |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/make-certs.sh |
||||
rename to src/tests/testsuite/proxy-certs/make-certs.sh |
||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-badsig.pem b/src/tests/testsuite/proxy-certs/proxy-badsig.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/proxy-badsig.pem |
||||
rename to src/tests/testsuite/proxy-certs/proxy-badsig.pem |
||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-ideal.pem b/src/tests/testsuite/proxy-certs/proxy-ideal.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/proxy-ideal.pem |
||||
rename to src/tests/testsuite/proxy-certs/proxy-ideal.pem |
||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-no-match.pem b/src/tests/testsuite/proxy-certs/proxy-no-match.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/proxy-no-match.pem |
||||
rename to src/tests/testsuite/proxy-certs/proxy-no-match.pem |
||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-san.pem b/src/tests/testsuite/proxy-certs/proxy-san.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/proxy-san.pem |
||||
rename to src/tests/testsuite/proxy-certs/proxy-san.pem |
||||
diff --git a/src/tests/dejagnu/proxy-certs/proxy-subject.pem b/src/tests/testsuite/proxy-certs/proxy-subject.pem |
||||
similarity index 100% |
||||
rename from src/tests/dejagnu/proxy-certs/proxy-subject.pem |
||||
rename to src/tests/testsuite/proxy-certs/proxy-subject.pem |
||||
diff --git a/src/tests/dejagnu/t_inetd.c b/src/tests/testsuite/t_inetd.c |
||||
similarity index 99% |
||||
rename from src/tests/dejagnu/t_inetd.c |
||||
rename to src/tests/testsuite/t_inetd.c |
||||
index abcde50fa..2bad2cf65 100644 |
||||
--- a/src/tests/dejagnu/t_inetd.c |
||||
+++ b/src/tests/testsuite/t_inetd.c |
||||
@@ -1,5 +1,5 @@ |
||||
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
||||
-/* tests/dejagnu/t_inetd.c */ |
||||
+/* tests/testsuite/t_inetd.c */ |
||||
/* |
||||
* Copyright 1991 by the Massachusetts Institute of Technology. |
||||
* All Rights Reserved. |
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py |
||||
index 251d11a9d..908a1495c 100644 |
||||
--- a/src/util/k5test.py |
||||
+++ b/src/util/k5test.py |
||||
@@ -1383,7 +1383,7 @@ kswitch = os.path.join(buildtop, 'clients', 'kswitch', 'kswitch') |
||||
kvno = os.path.join(buildtop, 'clients', 'kvno', 'kvno') |
||||
kdestroy = os.path.join(buildtop, 'clients', 'kdestroy', 'kdestroy') |
||||
kpasswd = os.path.join(buildtop, 'clients', 'kpasswd', 'kpasswd') |
||||
-t_inetd = os.path.join(buildtop, 'tests', 'dejagnu', 't_inetd') |
||||
+t_inetd = os.path.join(buildtop, 'tests', 'testsuite', 't_inetd') |
||||
kproplog = os.path.join(buildtop, 'kprop', 'kproplog') |
||||
kpropd = os.path.join(buildtop, 'kprop', 'kpropd') |
||||
kprop = os.path.join(buildtop, 'kprop', 'kprop') |
||||
-- |
||||
2.35.1 |
||||
|
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From d5ea86ef491feb38f12e6aa53b7579ac02675df6 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 |
||||
|
||||
We want to keep these y.tab.c files around because the debuginfo points to |
||||
them. It would be more elegant at the end to use symbolic links, but that |
||||
could mess up people working in the tree on other things. |
||||
|
||||
Last-updated: krb5-1.9 |
||||
--- |
||||
src/kadmin/cli/Makefile.in | 5 +++++ |
||||
src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +- |
||||
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 |
||||
--- a/src/kadmin/cli/Makefile.in |
||||
+++ b/src/kadmin/cli/Makefile.in |
||||
@@ -37,3 +37,8 @@ clean-unix:: |
||||
# CC_LINK is not meant for compilation and this use may break in the future. |
||||
datetest: getdate.c |
||||
$(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c |
||||
+ |
||||
+%.c: %.y |
||||
+ $(RM) y.tab.c $@ |
||||
+ $(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 |
||||
--- 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) |
||||
getdate.c: $(GETDATE) |
||||
$(RM) getdate.c y.tab.c |
||||
$(YACC) $(GETDATE) |
||||
- $(MV) y.tab.c getdate.c |
||||
+ $(CP) y.tab.c getdate.c |
||||
|
||||
install: |
||||
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG) |
@ -0,0 +1,774 @@
@@ -0,0 +1,774 @@
|
||||
From 90ba715be48c2e1b6c7ca53cb1d75f3af2c388d6 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 |
||||
|
||||
Modify ksu so that it performs account and session management on behalf of |
||||
the target user account, mimicking the action of regular su. The default |
||||
service name is "ksu", because on Fedora at least the configuration used |
||||
is determined by whether or not a login shell is being opened, and so |
||||
this may need to vary, too. At run-time, ksu's behavior can be reset to |
||||
the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu] |
||||
section of /etc/krb5.conf. |
||||
|
||||
When enabled, ksu gains a dependency on libpam. |
||||
|
||||
Originally RT#5939, though it's changed since then to perform the account |
||||
and session management before dropping privileges, and to apply on top of |
||||
changes we're proposing for how it handles cache collections. |
||||
|
||||
Last-updated: krb5-1.18-beta1 |
||||
--- |
||||
src/aclocal.m4 | 69 +++++++ |
||||
src/clients/ksu/Makefile.in | 8 +- |
||||
src/clients/ksu/main.c | 88 +++++++- |
||||
src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++ |
||||
src/clients/ksu/pam.h | 57 ++++++ |
||||
src/configure.ac | 2 + |
||||
6 files changed, 610 insertions(+), 3 deletions(-) |
||||
create mode 100644 src/clients/ksu/pam.c |
||||
create mode 100644 src/clients/ksu/pam.h |
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4 |
||||
index 024d6370c..ca9fcf664 100644 |
||||
--- a/src/aclocal.m4 |
||||
+++ b/src/aclocal.m4 |
||||
@@ -1677,3 +1677,72 @@ if test "$with_ldap" = yes; then |
||||
OPENLDAP_PLUGIN=yes |
||||
fi |
||||
])dnl |
||||
+dnl |
||||
+dnl |
||||
+dnl Use PAM instead of local crypt() compare for checking local passwords, |
||||
+dnl and perform PAM account, session management, and password-changing where |
||||
+dnl appropriate. |
||||
+dnl |
||||
+AC_DEFUN(KRB5_WITH_PAM,[ |
||||
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])], |
||||
+ withpam="$withval",withpam=auto) |
||||
+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])], |
||||
+ withksupamservice="$withval",withksupamservice=ksu) |
||||
+old_LIBS="$LIBS" |
||||
+if test "$withpam" != no ; then |
||||
+ AC_MSG_RESULT([checking for PAM...]) |
||||
+ PAM_LIBS= |
||||
+ |
||||
+ AC_CHECK_HEADERS(security/pam_appl.h) |
||||
+ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then |
||||
+ if test "$withpam" = auto ; then |
||||
+ AC_MSG_RESULT([Unable to locate security/pam_appl.h.]) |
||||
+ withpam=no |
||||
+ else |
||||
+ AC_MSG_ERROR([Unable to locate security/pam_appl.h.]) |
||||
+ fi |
||||
+ fi |
||||
+ |
||||
+ LIBS= |
||||
+ unset ac_cv_func_pam_start |
||||
+ AC_CHECK_FUNCS(putenv pam_start) |
||||
+ if test "x$ac_cv_func_pam_start" = xno ; then |
||||
+ unset ac_cv_func_pam_start |
||||
+ AC_CHECK_LIB(dl,dlopen) |
||||
+ AC_CHECK_FUNCS(pam_start) |
||||
+ if test "x$ac_cv_func_pam_start" = xno ; then |
||||
+ AC_CHECK_LIB(pam,pam_start) |
||||
+ unset ac_cv_func_pam_start |
||||
+ unset ac_cv_func_pam_getenvlist |
||||
+ AC_CHECK_FUNCS(pam_start pam_getenvlist) |
||||
+ if test "x$ac_cv_func_pam_start" = xyes ; then |
||||
+ PAM_LIBS="$LIBS" |
||||
+ else |
||||
+ if test "$withpam" = auto ; then |
||||
+ AC_MSG_RESULT([Unable to locate libpam.]) |
||||
+ withpam=no |
||||
+ else |
||||
+ AC_MSG_ERROR([Unable to locate libpam.]) |
||||
+ fi |
||||
+ fi |
||||
+ fi |
||||
+ fi |
||||
+ if test "$withpam" != no ; then |
||||
+ AC_MSG_NOTICE([building with PAM support]) |
||||
+ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM]) |
||||
+ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice", |
||||
+ [Define to the name of the PAM service name to be used by ksu.]) |
||||
+ PAM_LIBS="$LIBS" |
||||
+ NON_PAM_MAN=".\\\" " |
||||
+ PAM_MAN= |
||||
+ else |
||||
+ PAM_MAN=".\\\" " |
||||
+ NON_PAM_MAN= |
||||
+ fi |
||||
+fi |
||||
+LIBS="$old_LIBS" |
||||
+AC_SUBST(PAM_LIBS) |
||||
+AC_SUBST(PAM_MAN) |
||||
+AC_SUBST(NON_PAM_MAN) |
||||
+])dnl |
||||
+ |
||||
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in |
||||
index 8b4edce4d..9d58f29b5 100644 |
||||
--- a/src/clients/ksu/Makefile.in |
||||
+++ b/src/clients/ksu/Makefile.in |
||||
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S).. |
||||
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"' |
||||
|
||||
KSU_LIBS=@KSU_LIBS@ |
||||
+PAM_LIBS=@PAM_LIBS@ |
||||
|
||||
SRCS = \ |
||||
$(srcdir)/krb_auth_su.c \ |
||||
$(srcdir)/ccache.c \ |
||||
$(srcdir)/authorization.c \ |
||||
$(srcdir)/main.c \ |
||||
+ $(srcdir)/pam.c \ |
||||
$(srcdir)/heuristic.c \ |
||||
$(srcdir)/xmalloc.c \ |
||||
$(srcdir)/setenv.c |
||||
@@ -17,13 +19,17 @@ OBJS = \ |
||||
ccache.o \ |
||||
authorization.o \ |
||||
main.o \ |
||||
+ pam.o \ |
||||
heuristic.o \ |
||||
xmalloc.o @SETENVOBJ@ |
||||
|
||||
all: ksu |
||||
|
||||
ksu: $(OBJS) $(KRB5_BASE_DEPLIBS) |
||||
- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) |
||||
+ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS) |
||||
+ |
||||
+pam.o: pam.c |
||||
+ $(CC) $(ALL_CFLAGS) -c $< |
||||
|
||||
clean: |
||||
$(RM) ksu |
||||
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c |
||||
index af1286172..931f05404 100644 |
||||
--- a/src/clients/ksu/main.c |
||||
+++ b/src/clients/ksu/main.c |
||||
@@ -26,6 +26,7 @@ |
||||
* KSU was written by: Ari Medvinsky, ari@isi.edu |
||||
*/ |
||||
|
||||
+#include "autoconf.h" |
||||
#include "ksu.h" |
||||
#include "adm_proto.h" |
||||
#include <sys/types.h> |
||||
@@ -33,6 +34,10 @@ |
||||
#include <signal.h> |
||||
#include <grp.h> |
||||
|
||||
+#ifdef USE_PAM |
||||
+#include "pam.h" |
||||
+#endif |
||||
+ |
||||
/* globals */ |
||||
char * prog_name; |
||||
int auth_debug =0; |
||||
@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN]; |
||||
char k5users_path[MAXPATHLEN]; |
||||
char * gb_err = NULL; |
||||
int quiet = 0; |
||||
+int force_fork = 0; |
||||
/***********/ |
||||
|
||||
#define KS_TEMPORARY_CACHE "MEMORY:_ksu" |
||||
@@ -536,6 +542,23 @@ main (argc, argv) |
||||
prog_name,target_user,client_name, |
||||
source_user,ontty()); |
||||
|
||||
+#ifdef USE_PAM |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, |
||||
+ NULL, source_user, |
||||
+ ttyname(STDERR_FILENO)) != 0) { |
||||
+ fprintf(stderr, "Access denied for %s.\n", target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ if (appl_pam_requires_chauthtok()) { |
||||
+ fprintf(stderr, "Password change required for %s.\n", |
||||
+ target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ force_fork++; |
||||
+ } |
||||
+#endif |
||||
+ |
||||
/* Run authorization as target.*/ |
||||
if (krb5_seteuid(target_uid)) { |
||||
com_err(prog_name, errno, _("while switching to target for " |
||||
@@ -596,6 +619,24 @@ main (argc, argv) |
||||
|
||||
exit(1); |
||||
} |
||||
+#ifdef USE_PAM |
||||
+ } else { |
||||
+ /* we always do PAM account management, even for root */ |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, |
||||
+ NULL, source_user, |
||||
+ ttyname(STDERR_FILENO)) != 0) { |
||||
+ fprintf(stderr, "Access denied for %s.\n", target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ if (appl_pam_requires_chauthtok()) { |
||||
+ fprintf(stderr, "Password change required for %s.\n", |
||||
+ target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ force_fork++; |
||||
+ } |
||||
+#endif |
||||
} |
||||
|
||||
if( some_rest_copy){ |
||||
@@ -653,6 +694,30 @@ main (argc, argv) |
||||
exit(1); |
||||
} |
||||
|
||||
+#ifdef USE_PAM |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_session_open() != 0) { |
||||
+ fprintf(stderr, "Error opening session for %s.\n", target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ if (auth_debug){ |
||||
+ printf(" Opened PAM session.\n"); |
||||
+ } |
||||
+#endif |
||||
+ if (appl_pam_cred_init()) { |
||||
+ fprintf(stderr, "Error initializing credentials for %s.\n", |
||||
+ target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ if (auth_debug){ |
||||
+ printf(" Initialized PAM credentials.\n"); |
||||
+ } |
||||
+#endif |
||||
+ } |
||||
+#endif |
||||
+ |
||||
/* set permissions */ |
||||
if (setgid(target_pwd->pw_gid) < 0) { |
||||
perror("ksu: setgid"); |
||||
@@ -750,7 +815,7 @@ main (argc, argv) |
||||
fprintf(stderr, "program to be execed %s\n",params[0]); |
||||
} |
||||
|
||||
- if( keep_target_cache ) { |
||||
+ if( keep_target_cache && !force_fork ) { |
||||
execv(params[0], params); |
||||
com_err(prog_name, errno, _("while trying to execv %s"), params[0]); |
||||
sweep_up(ksu_context, cc_target); |
||||
@@ -780,16 +845,35 @@ main (argc, argv) |
||||
if (ret_pid == -1) { |
||||
com_err(prog_name, errno, _("while calling waitpid")); |
||||
} |
||||
- sweep_up(ksu_context, cc_target); |
||||
+ if( !keep_target_cache ) { |
||||
+ sweep_up(ksu_context, cc_target); |
||||
+ } |
||||
exit (statusp); |
||||
case -1: |
||||
com_err(prog_name, errno, _("while trying to fork.")); |
||||
sweep_up(ksu_context, cc_target); |
||||
exit (1); |
||||
case 0: |
||||
+#ifdef USE_PAM |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_setenv() != 0) { |
||||
+ fprintf(stderr, "Error setting up environment for %s.\n", |
||||
+ target_user); |
||||
+ exit (1); |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ if (auth_debug){ |
||||
+ printf(" Set up PAM environment.\n"); |
||||
+ } |
||||
+#endif |
||||
+ } |
||||
+#endif |
||||
execv(params[0], params); |
||||
com_err(prog_name, errno, _("while trying to execv %s"), |
||||
params[0]); |
||||
+ if( keep_target_cache ) { |
||||
+ sweep_up(ksu_context, cc_target); |
||||
+ } |
||||
exit (1); |
||||
} |
||||
} |
||||
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c |
||||
new file mode 100644 |
||||
index 000000000..cbfe48704 |
||||
--- /dev/null |
||||
+++ b/src/clients/ksu/pam.c |
||||
@@ -0,0 +1,389 @@ |
||||
+/* |
||||
+ * src/clients/ksu/pam.c |
||||
+ * |
||||
+ * Copyright 2007,2009,2010 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. |
||||
+ * |
||||
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be |
||||
+ * used to endorse or promote products derived from this software without |
||||
+ * specific prior written permission. |
||||
+ * |
||||
+ * 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 OWNER 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. |
||||
+ * |
||||
+ * Convenience wrappers for using PAM. |
||||
+ */ |
||||
+ |
||||
+#include "autoconf.h" |
||||
+#ifdef USE_PAM |
||||
+#include <sys/types.h> |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <string.h> |
||||
+#include <unistd.h> |
||||
+#include "k5-int.h" |
||||
+#include "pam.h" |
||||
+ |
||||
+#ifndef MAXPWSIZE |
||||
+#define MAXPWSIZE 128 |
||||
+#endif |
||||
+ |
||||
+static int appl_pam_started; |
||||
+static pid_t appl_pam_starter = -1; |
||||
+static int appl_pam_session_opened; |
||||
+static int appl_pam_creds_initialized; |
||||
+static int appl_pam_pwchange_required; |
||||
+static pam_handle_t *appl_pamh; |
||||
+static struct pam_conv appl_pam_conv; |
||||
+static char *appl_pam_user; |
||||
+struct appl_pam_non_interactive_args { |
||||
+ const char *user; |
||||
+ const char *password; |
||||
+}; |
||||
+ |
||||
+int |
||||
+appl_pam_enabled(krb5_context context, const char *section) |
||||
+{ |
||||
+ int enabled = 1; |
||||
+ if ((context != NULL) && (context->profile != NULL)) { |
||||
+ if (profile_get_boolean(context->profile, |
||||
+ section, |
||||
+ USE_PAM_CONFIGURATION_KEYWORD, |
||||
+ NULL, |
||||
+ enabled, &enabled) != 0) { |
||||
+ enabled = 1; |
||||
+ } |
||||
+ } |
||||
+ return enabled; |
||||
+} |
||||
+ |
||||
+void |
||||
+appl_pam_cleanup(void) |
||||
+{ |
||||
+ if (getpid() != appl_pam_starter) { |
||||
+ return; |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ printf("Called to clean up PAM.\n"); |
||||
+#endif |
||||
+ if (appl_pam_creds_initialized) { |
||||
+#ifdef DEBUG |
||||
+ printf("Deleting PAM credentials.\n"); |
||||
+#endif |
||||
+ pam_setcred(appl_pamh, PAM_DELETE_CRED); |
||||
+ appl_pam_creds_initialized = 0; |
||||
+ } |
||||
+ if (appl_pam_session_opened) { |
||||
+#ifdef DEBUG |
||||
+ printf("Closing PAM session.\n"); |
||||
+#endif |
||||
+ pam_close_session(appl_pamh, 0); |
||||
+ appl_pam_session_opened = 0; |
||||
+ } |
||||
+ appl_pam_pwchange_required = 0; |
||||
+ if (appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Shutting down PAM.\n"); |
||||
+#endif |
||||
+ pam_end(appl_pamh, 0); |
||||
+ appl_pam_started = 0; |
||||
+ appl_pam_starter = -1; |
||||
+ free(appl_pam_user); |
||||
+ appl_pam_user = NULL; |
||||
+ } |
||||
+} |
||||
+static int |
||||
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg, |
||||
+ struct pam_response **presp, void *appdata_ptr) |
||||
+{ |
||||
+ const struct pam_message *message; |
||||
+ struct pam_response *resp; |
||||
+ int i, code; |
||||
+ char *pwstring, pwbuf[MAXPWSIZE]; |
||||
+ unsigned int pwsize; |
||||
+ resp = malloc(sizeof(struct pam_response) * num_msg); |
||||
+ if (resp == NULL) { |
||||
+ return PAM_BUF_ERR; |
||||
+ } |
||||
+ memset(resp, 0, sizeof(struct pam_response) * num_msg); |
||||
+ code = PAM_SUCCESS; |
||||
+ for (i = 0; i < num_msg; i++) { |
||||
+ message = &(msg[0][i]); /* XXX */ |
||||
+ message = msg[i]; /* XXX */ |
||||
+ pwstring = NULL; |
||||
+ switch (message->msg_style) { |
||||
+ case PAM_TEXT_INFO: |
||||
+ case PAM_ERROR_MSG: |
||||
+ printf("[%s]\n", message->msg ? message->msg : ""); |
||||
+ fflush(stdout); |
||||
+ resp[i].resp = NULL; |
||||
+ resp[i].resp_retcode = PAM_SUCCESS; |
||||
+ break; |
||||
+ case PAM_PROMPT_ECHO_ON: |
||||
+ case PAM_PROMPT_ECHO_OFF: |
||||
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) { |
||||
+ if (fgets(pwbuf, sizeof(pwbuf), |
||||
+ stdin) != NULL) { |
||||
+ pwbuf[strcspn(pwbuf, "\r\n")] = '\0'; |
||||
+ pwstring = pwbuf; |
||||
+ } |
||||
+ } else { |
||||
+ pwstring = getpass(message->msg ? |
||||
+ message->msg : |
||||
+ ""); |
||||
+ } |
||||
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) { |
||||
+ pwsize = strlen(pwstring); |
||||
+ resp[i].resp = malloc(pwsize + 1); |
||||
+ if (resp[i].resp == NULL) { |
||||
+ resp[i].resp_retcode = PAM_BUF_ERR; |
||||
+ } else { |
||||
+ memcpy(resp[i].resp, pwstring, pwsize); |
||||
+ resp[i].resp[pwsize] = '\0'; |
||||
+ resp[i].resp_retcode = PAM_SUCCESS; |
||||
+ } |
||||
+ } else { |
||||
+ resp[i].resp_retcode = PAM_CONV_ERR; |
||||
+ code = PAM_CONV_ERR; |
||||
+ } |
||||
+ break; |
||||
+ default: |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ *presp = resp; |
||||
+ return code; |
||||
+} |
||||
+static int |
||||
+appl_pam_non_interactive_converse(int num_msg, |
||||
+ const struct pam_message **msg, |
||||
+ struct pam_response **presp, |
||||
+ void *appdata_ptr) |
||||
+{ |
||||
+ const struct pam_message *message; |
||||
+ struct pam_response *resp; |
||||
+ int i, code; |
||||
+ unsigned int pwsize; |
||||
+ struct appl_pam_non_interactive_args *args; |
||||
+ const char *pwstring; |
||||
+ resp = malloc(sizeof(struct pam_response) * num_msg); |
||||
+ if (resp == NULL) { |
||||
+ return PAM_BUF_ERR; |
||||
+ } |
||||
+ args = appdata_ptr; |
||||
+ memset(resp, 0, sizeof(struct pam_response) * num_msg); |
||||
+ code = PAM_SUCCESS; |
||||
+ for (i = 0; i < num_msg; i++) { |
||||
+ message = &((*msg)[i]); |
||||
+ message = msg[i]; |
||||
+ pwstring = NULL; |
||||
+ switch (message->msg_style) { |
||||
+ case PAM_TEXT_INFO: |
||||
+ case PAM_ERROR_MSG: |
||||
+ break; |
||||
+ case PAM_PROMPT_ECHO_ON: |
||||
+ case PAM_PROMPT_ECHO_OFF: |
||||
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) { |
||||
+ /* assume "user" */ |
||||
+ pwstring = args->user; |
||||
+ } else { |
||||
+ /* assume "password" */ |
||||
+ pwstring = args->password; |
||||
+ } |
||||
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) { |
||||
+ pwsize = strlen(pwstring); |
||||
+ resp[i].resp = malloc(pwsize + 1); |
||||
+ if (resp[i].resp == NULL) { |
||||
+ resp[i].resp_retcode = PAM_BUF_ERR; |
||||
+ } else { |
||||
+ memcpy(resp[i].resp, pwstring, pwsize); |
||||
+ resp[i].resp[pwsize] = '\0'; |
||||
+ resp[i].resp_retcode = PAM_SUCCESS; |
||||
+ } |
||||
+ } else { |
||||
+ resp[i].resp_retcode = PAM_CONV_ERR; |
||||
+ code = PAM_CONV_ERR; |
||||
+ } |
||||
+ break; |
||||
+ default: |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ *presp = resp; |
||||
+ return code; |
||||
+} |
||||
+static int |
||||
+appl_pam_start(const char *service, int interactive, |
||||
+ const char *login_username, |
||||
+ const char *non_interactive_password, |
||||
+ const char *hostname, |
||||
+ const char *ruser, |
||||
+ const char *tty) |
||||
+{ |
||||
+ static int exit_handler_registered; |
||||
+ static struct appl_pam_non_interactive_args args; |
||||
+ int ret = 0; |
||||
+ if (appl_pam_started && |
||||
+ (strcmp(login_username, appl_pam_user) != 0)) { |
||||
+ appl_pam_cleanup(); |
||||
+ appl_pam_user = NULL; |
||||
+ } |
||||
+ if (!appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n", |
||||
+ service, login_username); |
||||
+#endif |
||||
+ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv)); |
||||
+ appl_pam_conv.conv = interactive ? |
||||
+ &appl_pam_interactive_converse : |
||||
+ &appl_pam_non_interactive_converse; |
||||
+ memset(&args, 0, sizeof(args)); |
||||
+ args.user = strdup(login_username); |
||||
+ args.password = non_interactive_password ? |
||||
+ strdup(non_interactive_password) : |
||||
+ NULL; |
||||
+ appl_pam_conv.appdata_ptr = &args; |
||||
+ ret = pam_start(service, login_username, |
||||
+ &appl_pam_conv, &appl_pamh); |
||||
+ if (ret == 0) { |
||||
+ if (hostname != NULL) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting PAM_RHOST to \"%s\".\n", hostname); |
||||
+#endif |
||||
+ pam_set_item(appl_pamh, PAM_RHOST, hostname); |
||||
+ } |
||||
+ if (ruser != NULL) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting PAM_RUSER to \"%s\".\n", ruser); |
||||
+#endif |
||||
+ pam_set_item(appl_pamh, PAM_RUSER, ruser); |
||||
+ } |
||||
+ if (tty != NULL) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting PAM_TTY to \"%s\".\n", tty); |
||||
+#endif |
||||
+ pam_set_item(appl_pamh, PAM_TTY, tty); |
||||
+ } |
||||
+ if (!exit_handler_registered && |
||||
+ (atexit(appl_pam_cleanup) != 0)) { |
||||
+ pam_end(appl_pamh, 0); |
||||
+ appl_pamh = NULL; |
||||
+ ret = -1; |
||||
+ } else { |
||||
+ appl_pam_started = 1; |
||||
+ appl_pam_starter = getpid(); |
||||
+ appl_pam_user = strdup(login_username); |
||||
+ exit_handler_registered = 1; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_acct_mgmt(const char *service, int interactive, |
||||
+ const char *login_username, |
||||
+ const char *non_interactive_password, |
||||
+ const char *hostname, |
||||
+ const char *ruser, |
||||
+ const char *tty) |
||||
+{ |
||||
+ int ret; |
||||
+ appl_pam_pwchange_required = 0; |
||||
+ ret = appl_pam_start(service, interactive, login_username, |
||||
+ non_interactive_password, hostname, ruser, tty); |
||||
+ if (ret == 0) { |
||||
+#ifdef DEBUG |
||||
+ printf("Calling pam_acct_mgmt().\n"); |
||||
+#endif |
||||
+ ret = pam_acct_mgmt(appl_pamh, 0); |
||||
+ switch (ret) { |
||||
+ case PAM_IGNORE: |
||||
+ ret = 0; |
||||
+ break; |
||||
+ case PAM_NEW_AUTHTOK_REQD: |
||||
+ appl_pam_pwchange_required = 1; |
||||
+ ret = 0; |
||||
+ break; |
||||
+ default: |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_requires_chauthtok(void) |
||||
+{ |
||||
+ return appl_pam_pwchange_required; |
||||
+} |
||||
+int |
||||
+appl_pam_session_open(void) |
||||
+{ |
||||
+ int ret = 0; |
||||
+ if (appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Opening PAM session.\n"); |
||||
+#endif |
||||
+ ret = pam_open_session(appl_pamh, 0); |
||||
+ if (ret == 0) { |
||||
+ appl_pam_session_opened = 1; |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_setenv(void) |
||||
+{ |
||||
+ int ret = 0; |
||||
+#ifdef HAVE_PAM_GETENVLIST |
||||
+#ifdef HAVE_PUTENV |
||||
+ int i; |
||||
+ char **list; |
||||
+ if (appl_pam_started) { |
||||
+ list = pam_getenvlist(appl_pamh); |
||||
+ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting \"%s\" in environment.\n", list[i]); |
||||
+#endif |
||||
+ putenv(list[i]); |
||||
+ } |
||||
+ } |
||||
+#endif |
||||
+#endif |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_cred_init(void) |
||||
+{ |
||||
+ int ret = 0; |
||||
+ if (appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Initializing PAM credentials.\n"); |
||||
+#endif |
||||
+ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED); |
||||
+ if (ret == 0) { |
||||
+ appl_pam_creds_initialized = 1; |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+#endif |
||||
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h |
||||
new file mode 100644 |
||||
index 000000000..0ab76569c |
||||
--- /dev/null |
||||
+++ b/src/clients/ksu/pam.h |
||||
@@ -0,0 +1,57 @@ |
||||
+/* |
||||
+ * src/clients/ksu/pam.h |
||||
+ * |
||||
+ * Copyright 2007,2009,2010 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. |
||||
+ * |
||||
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be |
||||
+ * used to endorse or promote products derived from this software without |
||||
+ * specific prior written permission. |
||||
+ * |
||||
+ * 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 OWNER 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. |
||||
+ * |
||||
+ * Convenience wrappers for using PAM. |
||||
+ */ |
||||
+ |
||||
+#include <krb5.h> |
||||
+#ifdef HAVE_SECURITY_PAM_APPL_H |
||||
+#include <security/pam_appl.h> |
||||
+#endif |
||||
+ |
||||
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam" |
||||
+ |
||||
+#ifdef USE_PAM |
||||
+int appl_pam_enabled(krb5_context context, const char *section); |
||||
+int appl_pam_acct_mgmt(const char *service, int interactive, |
||||
+ const char *local_username, |
||||
+ const char *non_interactive_password, |
||||
+ const char *hostname, |
||||
+ const char *ruser, |
||||
+ const char *tty); |
||||
+int appl_pam_requires_chauthtok(void); |
||||
+int appl_pam_session_open(void); |
||||
+int appl_pam_setenv(void); |
||||
+int appl_pam_cred_init(void); |
||||
+void appl_pam_cleanup(void); |
||||
+#endif |
||||
diff --git a/src/configure.ac b/src/configure.ac |
||||
index 4eb080784..693f76a81 100644 |
||||
--- a/src/configure.ac |
||||
+++ b/src/configure.ac |
||||
@@ -1389,6 +1389,8 @@ AC_SUBST([VERTO_VERSION]) |
||||
|
||||
AC_PATH_PROG(GROFF, groff) |
||||
|
||||
+KRB5_WITH_PAM |
||||
+ |
||||
# Make localedir work in autoconf 2.5x. |
||||
if test "${localedir+set}" != set; then |
||||
localedir='$(datadir)/locale' |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
From ad123366e5fb2694cf6d9f4f292a001a761b78fa 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 5afb96e58..4a4d460e3 100644 |
||||
--- a/src/aclocal.m4 |
||||
+++ b/src/aclocal.m4 |
||||
@@ -718,6 +718,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 |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
[Unit] |
||||
Description=Kerberos 5 Password-changing and Administration |
||||
Wants=network-online.target |
||||
After=syslog.target network.target network-online.target |
||||
AssertPathExists=!/var/kerberos/krb5kdc/kpropd.acl |
||||
|
||||
[Service] |
||||
Type=forking |
||||
PIDFile=/run/kadmind.pid |
||||
EnvironmentFile=-/etc/sysconfig/kadmin |
||||
ExecStart=/usr/sbin/kadmind -P /run/kadmind.pid $KADMIND_ARGS |
||||
ExecReload=/bin/kill -HUP $MAINPID |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
/var/log/kadmind.log { |
||||
missingok |
||||
notifempty |
||||
monthly |
||||
rotate 12 |
||||
postrotate |
||||
systemctl reload kadmin.service || true |
||||
endscript |
||||
} |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
[kdcdefaults] |
||||
kdc_ports = 88 |
||||
kdc_tcp_ports = 88 |
||||
spake_preauth_kdc_challenge = edwards25519 |
||||
|
||||
[realms] |
||||
EXAMPLE.COM = { |
||||
#master_key_type = aes256-cts |
||||
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 |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
[Unit] |
||||
Description=Kerberos 5 Propagation |
||||
Wants=network-online.target |
||||
After=syslog.target network.target network-online.target |
||||
AssertPathExists=/var/kerberos/krb5kdc/kpropd.acl |
||||
|
||||
[Service] |
||||
Type=forking |
||||
EnvironmentFile=-/etc/sysconfig/kprop |
||||
ExecStart=/usr/sbin/kpropd $KPROPD_ARGS |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,69 @@
@@ -0,0 +1,69 @@
|
||||
From 0ac0fd2d349e4d5ef7379182f4d7ce480edd8d2b Mon Sep 17 00:00:00 2001 |
||||
From: Sumit Bose <sbose@redhat.com> |
||||
Date: Mon, 8 Nov 2021 17:48:50 +0100 |
||||
Subject: [PATCH 2/2] Support larger RADIUS attributes in libkrad |
||||
|
||||
In kr_attrset_decode(), explicitly treat the length byte as unsigned. |
||||
Otherwise attributes longer than 125 characters will be rejected with |
||||
EBADMSG. |
||||
|
||||
Add a 253-character-long NAS-Identifier attribute to the tests to make |
||||
sure that attributes with the maximal number of characters are working |
||||
as expected. |
||||
|
||||
[ghudson@mit.edu: used uint8_t cast per current practices; edited |
||||
commit message] |
||||
|
||||
ticket: 9036 (new) |
||||
--- |
||||
src/lib/krad/attrset.c | 2 +- |
||||
src/lib/krad/t_packet.c | 13 +++++++++++++ |
||||
2 files changed, 14 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c |
||||
index d89982a13..6ec031e32 100644 |
||||
--- a/src/lib/krad/attrset.c |
||||
+++ b/src/lib/krad/attrset.c |
||||
@@ -218,7 +218,7 @@ kr_attrset_decode(krb5_context ctx, const krb5_data *in, const char *secret, |
||||
|
||||
for (i = 0; i + 2 < in->length; ) { |
||||
type = in->data[i++]; |
||||
- tmp = make_data(&in->data[i + 1], in->data[i] - 2); |
||||
+ tmp = make_data(&in->data[i + 1], (uint8_t)in->data[i] - 2); |
||||
i += tmp.length + 1; |
||||
|
||||
retval = (in->length < i) ? EBADMSG : 0; |
||||
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c |
||||
index 0a92e9cc2..c22489144 100644 |
||||
--- a/src/lib/krad/t_packet.c |
||||
+++ b/src/lib/krad/t_packet.c |
||||
@@ -57,6 +57,14 @@ make_packet(krb5_context ctx, const krb5_data *username, |
||||
krb5_error_code retval; |
||||
const krb5_data *data; |
||||
int i = 0; |
||||
+ krb5_data nas_id; |
||||
+ |
||||
+ nas_id = string2data("12345678901234567890123456789012345678901234567890" |
||||
+ "12345678901234567890123456789012345678901234567890" |
||||
+ "12345678901234567890123456789012345678901234567890" |
||||
+ "12345678901234567890123456789012345678901234567890" |
||||
+ "12345678901234567890123456789012345678901234567890" |
||||
+ "123"); |
||||
|
||||
retval = krad_attrset_new(ctx, &set); |
||||
if (retval != 0) |
||||
@@ -71,6 +79,11 @@ make_packet(krb5_context ctx, const krb5_data *username, |
||||
if (retval != 0) |
||||
goto out; |
||||
|
||||
+ retval = krad_attrset_add(set, krad_attr_name2num("NAS-Identifier"), |
||||
+ &nas_id); |
||||
+ if (retval != 0) |
||||
+ goto out; |
||||
+ |
||||
retval = krad_packet_new_request(ctx, "foo", |
||||
krad_code_name2num("Access-Request"), |
||||
set, iterator, &i, &tmp); |
||||
-- |
||||
2.35.3 |
||||
|
@ -0,0 +1,171 @@
@@ -0,0 +1,171 @@
|
||||
From a8551b609fd50458ca3c06a9dd345b6cdf18689b Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Tue, 9 Nov 2021 13:00:43 -0500 |
||||
Subject: [PATCH 1/2] Avoid use after free during libkrad cleanup |
||||
|
||||
libkrad client requests contain a list of references to remotes, with |
||||
no back-references or reference counts. To prevent accesses to |
||||
dangling references during cleanup, cancel all requests on all remotes |
||||
before freeing any remotes. |
||||
|
||||
Remove the code for aging out unused servers. This code was fairly |
||||
safe as all requests referencing a remote should have completed or |
||||
timed out during an hour of disuse, but in the current design we have |
||||
no way to guarantee or check that. The set of addresses we send |
||||
RADIUS requests to will generally be small, so aging out servers is |
||||
unnecessary. |
||||
|
||||
ticket: 9035 (new) |
||||
--- |
||||
src/lib/krad/client.c | 42 ++++++++++++++--------------------------- |
||||
src/lib/krad/internal.h | 4 ++++ |
||||
src/lib/krad/remote.c | 11 ++++++++--- |
||||
3 files changed, 26 insertions(+), 31 deletions(-) |
||||
|
||||
diff --git a/src/lib/krad/client.c b/src/lib/krad/client.c |
||||
index 6365dd1c6..810940afc 100644 |
||||
--- a/src/lib/krad/client.c |
||||
+++ b/src/lib/krad/client.c |
||||
@@ -64,7 +64,6 @@ struct request_st { |
||||
|
||||
struct server_st { |
||||
krad_remote *serv; |
||||
- time_t last; |
||||
K5_LIST_ENTRY(server_st) list; |
||||
}; |
||||
|
||||
@@ -81,15 +80,10 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret, |
||||
krad_remote **out) |
||||
{ |
||||
krb5_error_code retval; |
||||
- time_t currtime; |
||||
server *srv; |
||||
|
||||
- if (time(&currtime) == (time_t)-1) |
||||
- return errno; |
||||
- |
||||
K5_LIST_FOREACH(srv, &rc->servers, list) { |
||||
if (kr_remote_equals(srv->serv, ai, secret)) { |
||||
- srv->last = currtime; |
||||
*out = srv->serv; |
||||
return 0; |
||||
} |
||||
@@ -98,7 +92,6 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret, |
||||
srv = calloc(1, sizeof(server)); |
||||
if (srv == NULL) |
||||
return ENOMEM; |
||||
- srv->last = currtime; |
||||
|
||||
retval = kr_remote_new(rc->kctx, rc->vctx, ai, secret, &srv->serv); |
||||
if (retval != 0) { |
||||
@@ -173,28 +166,12 @@ request_new(krad_client *rc, krad_code code, const krad_attrset *attrs, |
||||
return 0; |
||||
} |
||||
|
||||
-/* Close remotes that haven't been used in a while. */ |
||||
-static void |
||||
-age(struct server_head *head, time_t currtime) |
||||
-{ |
||||
- server *srv, *tmp; |
||||
- |
||||
- K5_LIST_FOREACH_SAFE(srv, head, list, tmp) { |
||||
- if (currtime == (time_t)-1 || currtime - srv->last > 60 * 60) { |
||||
- K5_LIST_REMOVE(srv, list); |
||||
- kr_remote_free(srv->serv); |
||||
- free(srv); |
||||
- } |
||||
- } |
||||
-} |
||||
- |
||||
/* Handle a response from a server (or related errors). */ |
||||
static void |
||||
on_response(krb5_error_code retval, const krad_packet *reqp, |
||||
const krad_packet *rspp, void *data) |
||||
{ |
||||
request *req = data; |
||||
- time_t currtime; |
||||
size_t i; |
||||
|
||||
/* Do nothing if we are already completed. */ |
||||
@@ -221,10 +198,6 @@ on_response(krb5_error_code retval, const krad_packet *reqp, |
||||
for (i = 0; req->remotes[i].remote != NULL; i++) |
||||
kr_remote_cancel(req->remotes[i].remote, req->remotes[i].packet); |
||||
|
||||
- /* Age out servers that haven't been used in a while. */ |
||||
- if (time(&currtime) != (time_t)-1) |
||||
- age(&req->rc->servers, currtime); |
||||
- |
||||
request_free(req); |
||||
} |
||||
|
||||
@@ -247,10 +220,23 @@ krad_client_new(krb5_context kctx, verto_ctx *vctx, krad_client **out) |
||||
void |
||||
krad_client_free(krad_client *rc) |
||||
{ |
||||
+ server *srv; |
||||
+ |
||||
if (rc == NULL) |
||||
return; |
||||
|
||||
- age(&rc->servers, -1); |
||||
+ /* Cancel all requests before freeing any remotes, since each request's |
||||
+ * callback data may contain references to multiple remotes. */ |
||||
+ K5_LIST_FOREACH(srv, &rc->servers, list) |
||||
+ kr_remote_cancel_all(srv->serv); |
||||
+ |
||||
+ while (!K5_LIST_EMPTY(&rc->servers)) { |
||||
+ srv = K5_LIST_FIRST(&rc->servers); |
||||
+ K5_LIST_REMOVE(srv, list); |
||||
+ kr_remote_free(srv->serv); |
||||
+ free(srv); |
||||
+ } |
||||
+ |
||||
free(rc); |
||||
} |
||||
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h |
||||
index 223ffd730..fa012db78 100644 |
||||
--- a/src/lib/krad/internal.h |
||||
+++ b/src/lib/krad/internal.h |
||||
@@ -120,6 +120,10 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs, |
||||
void |
||||
kr_remote_cancel(krad_remote *rr, const krad_packet *pkt); |
||||
|
||||
+/* Cancel all requests awaiting responses. */ |
||||
+void |
||||
+kr_remote_cancel_all(krad_remote *rr); |
||||
+ |
||||
/* Determine if this remote object refers to the remote resource identified |
||||
* by the addrinfo struct and the secret. */ |
||||
krb5_boolean |
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c |
||||
index c8912892c..01a5fd2a4 100644 |
||||
--- a/src/lib/krad/remote.c |
||||
+++ b/src/lib/krad/remote.c |
||||
@@ -452,15 +452,20 @@ error: |
||||
return retval; |
||||
} |
||||
|
||||
+void |
||||
+kr_remote_cancel_all(krad_remote *rr) |
||||
+{ |
||||
+ while (!K5_TAILQ_EMPTY(&rr->list)) |
||||
+ request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL); |
||||
+} |
||||
+ |
||||
void |
||||
kr_remote_free(krad_remote *rr) |
||||
{ |
||||
if (rr == NULL) |
||||
return; |
||||
|
||||
- while (!K5_TAILQ_EMPTY(&rr->list)) |
||||
- request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL); |
||||
- |
||||
+ kr_remote_cancel_all(rr); |
||||
free(rr->secret); |
||||
if (rr->info != NULL) |
||||
free(rr->info->ai_addr); |
||||
-- |
||||
2.35.3 |
||||
|
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
d /run/krb5kdc 0755 root root |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
# 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] |
||||
dns_lookup_realm = false |
||||
ticket_lifetime = 24h |
||||
renew_lifetime = 7d |
||||
forwardable = true |
||||
rdns = false |
||||
pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt |
||||
spake_preauth_groups = edwards25519 |
||||
dns_canonicalize_hostname = fallback |
||||
qualify_shortname = "" |
||||
# default_realm = EXAMPLE.COM |
||||
|
||||
[realms] |
||||
# EXAMPLE.COM = { |
||||
# kdc = kerberos.example.com |
||||
# admin_server = kerberos.example.com |
||||
# } |
||||
|
||||
[domain_realm] |
||||
# .example.com = EXAMPLE.COM |
||||
# example.com = EXAMPLE.COM |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
/var/log/krb5kdc.log { |
||||
missingok |
||||
notifempty |
||||
monthly |
||||
rotate 12 |
||||
postrotate |
||||
systemctl reload krb5kdc.service || true |
||||
endscript |
||||
} |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
[Unit] |
||||
Description=Kerberos 5 KDC |
||||
Wants=network-online.target |
||||
After=syslog.target network.target network-online.target |
||||
|
||||
[Service] |
||||
Type=forking |
||||
PIDFile=/run/krb5kdc.pid |
||||
EnvironmentFile=-/etc/sysconfig/krb5kdc |
||||
ExecStart=/usr/sbin/krb5kdc -P /run/krb5kdc.pid $KRB5KDC_ARGS |
||||
ExecReload=/bin/kill -HUP $MAINPID |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
#%PAM-1.0 |
||||
auth include su |
||||
account include su |
||||
session include su |
Loading…
Reference in new issue