You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
7.1 KiB
220 lines
7.1 KiB
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
|
|
|