Blame SOURCES/Add-APIs-for-marshalling-credentials.patch

57b2bb
From de01999b35773196749ba714f233649c9528aaad Mon Sep 17 00:00:00 2001
57b2bb
From: Robbie Harwood <rharwood@redhat.com>
57b2bb
Date: Thu, 14 Jan 2021 18:13:09 -0500
57b2bb
Subject: [PATCH] Add APIs for marshalling credentials
57b2bb
57b2bb
Faciliate KCM daemon implementations by providing functions to
57b2bb
deserialize and reserialize credentials in the FILE v4 format.
57b2bb
57b2bb
[ghudson@mit.edu: minor editorial changes]
57b2bb
57b2bb
ticket: 8980 (new)
57b2bb
(cherry picked from commit 18ea3bd2fca55b789b7de9c663624bc11d348fa6)
57b2bb
(cherry picked from commit 3d11179707923b033fa413387a33296b673ff52d)
57b2bb
[rharwood@redhat.com: function backport, so conflict in krb5_32.def]
57b2bb
---
57b2bb
 doc/appdev/refs/api/index.rst   |  2 ++
57b2bb
 src/include/krb5/krb5.hin       | 36 ++++++++++++++++++++++
57b2bb
 src/lib/krb5/ccache/ccmarshal.c | 53 +++++++++++++++++++++++++++++++++
57b2bb
 src/lib/krb5/ccache/t_marshal.c | 15 +++++++++-
57b2bb
 src/lib/krb5/libkrb5.exports    |  2 ++
57b2bb
 src/lib/krb5_32.def             |  4 +++
57b2bb
 6 files changed, 111 insertions(+), 1 deletion(-)
57b2bb
57b2bb
diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst
57b2bb
index 727d9b492..9e03fd386 100644
57b2bb
--- a/doc/appdev/refs/api/index.rst
57b2bb
+++ b/doc/appdev/refs/api/index.rst
57b2bb
@@ -232,6 +232,7 @@ Rarely used public interfaces
57b2bb
    krb5_kt_remove_entry.rst
57b2bb
    krb5_kt_start_seq_get.rst
57b2bb
    krb5_make_authdata_kdc_issued.rst
57b2bb
+   krb5_marshal_credentials.rst
57b2bb
    krb5_merge_authdata.rst
57b2bb
    krb5_mk_1cred.rst
57b2bb
    krb5_mk_error.rst
57b2bb
@@ -285,6 +286,7 @@ Rarely used public interfaces
57b2bb
    krb5_tkt_creds_get_times.rst
57b2bb
    krb5_tkt_creds_init.rst
57b2bb
    krb5_tkt_creds_step.rst
57b2bb
+   krb5_unmarshal_credentials.rst
57b2bb
    krb5_verify_init_creds.rst
57b2bb
    krb5_verify_init_creds_opt_init.rst
57b2bb
    krb5_verify_init_creds_opt_set_ap_req_nofail.rst
57b2bb
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
57b2bb
index 9264bede1..d2cf1eba2 100644
57b2bb
--- a/src/include/krb5/krb5.hin
57b2bb
+++ b/src/include/krb5/krb5.hin
57b2bb
@@ -3125,6 +3125,42 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
57b2bb
                      krb5_ccache ccache, krb5_creds *in_creds,
57b2bb
                      krb5_creds **out_creds);
57b2bb
 
57b2bb
+/**
57b2bb
+ * Serialize a @c krb5_creds object.
57b2bb
+ *
57b2bb
+ * @param [in]  context         Library context
57b2bb
+ * @param [in]  creds           The credentials object to serialize
57b2bb
+ * @param [out] data_out        The serialized credentials
57b2bb
+ *
57b2bb
+ * Serialize @a creds in the format used by the FILE ccache format (vesion 4)
57b2bb
+ * and KCM ccache protocol.
57b2bb
+ *
57b2bb
+ * Use krb5_free_data() to free @a data_out when it is no longer needed.
57b2bb
+ *
57b2bb
+ * @retval 0 Success; otherwise - Kerberos error codes
57b2bb
+ */
57b2bb
+krb5_error_code KRB5_CALLCONV
57b2bb
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds,
57b2bb
+                         krb5_data **data_out);
57b2bb
+
57b2bb
+/**
57b2bb
+ * Deserialize a @c krb5_creds object.
57b2bb
+ *
57b2bb
+ * @param [in]  context         Library context
57b2bb
+ * @param [in]  data            The serialized credentials
57b2bb
+ * @param [out] creds_out       The resulting creds object
57b2bb
+ *
57b2bb
+ * Deserialize @a data to credentials in the format used by the FILE ccache
57b2bb
+ * format (vesion 4) and KCM ccache protocol.
57b2bb
+ *
57b2bb
+ * Use krb5_free_creds() to free @a creds_out when it is no longer needed.
57b2bb
+ *
57b2bb
+ * @retval 0 Success; otherwise - Kerberos error codes
57b2bb
+ */
57b2bb
+krb5_error_code KRB5_CALLCONV
57b2bb
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data,
57b2bb
+                           krb5_creds **creds_out);
57b2bb
+
57b2bb
 /** @deprecated Replaced by krb5_get_validated_creds. */
57b2bb
 krb5_error_code KRB5_CALLCONV
57b2bb
 krb5_get_credentials_validate(krb5_context context, krb5_flags options,
57b2bb
diff --git a/src/lib/krb5/ccache/ccmarshal.c b/src/lib/krb5/ccache/ccmarshal.c
57b2bb
index ae634ccab..ab284e721 100644
57b2bb
--- a/src/lib/krb5/ccache/ccmarshal.c
57b2bb
+++ b/src/lib/krb5/ccache/ccmarshal.c
57b2bb
@@ -515,3 +515,56 @@ k5_marshal_mcred(struct k5buf *buf, krb5_creds *mcred)
57b2bb
     if (mcred->second_ticket.length > 0)
57b2bb
         put_data(buf, version, &mcred->second_ticket);
57b2bb
 }
57b2bb
+
57b2bb
+krb5_error_code KRB5_CALLCONV
57b2bb
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds,
57b2bb
+                         krb5_data **data_out)
57b2bb
+{
57b2bb
+    krb5_error_code ret;
57b2bb
+    krb5_data *data;
57b2bb
+    struct k5buf buf;
57b2bb
+
57b2bb
+    *data_out = NULL;
57b2bb
+
57b2bb
+    data = k5alloc(sizeof(krb5_data), &ret;;
57b2bb
+    if (ret)
57b2bb
+        return ret;
57b2bb
+
57b2bb
+    k5_buf_init_dynamic(&buf;;
57b2bb
+    k5_marshal_cred(&buf, 4, in_creds);
57b2bb
+
57b2bb
+    ret = k5_buf_status(&buf;;
57b2bb
+    if (ret) {
57b2bb
+        free(data);
57b2bb
+        return ret;
57b2bb
+    }
57b2bb
+
57b2bb
+    /* Steal payload from buf. */
57b2bb
+    *data = make_data(buf.data, buf.len);
57b2bb
+    *data_out = data;
57b2bb
+    return 0;
57b2bb
+}
57b2bb
+
57b2bb
+krb5_error_code KRB5_CALLCONV
57b2bb
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data,
57b2bb
+                           krb5_creds **creds_out)
57b2bb
+{
57b2bb
+    krb5_error_code ret;
57b2bb
+    krb5_creds *creds;
57b2bb
+
57b2bb
+    *creds_out = NULL;
57b2bb
+
57b2bb
+    creds = k5alloc(sizeof(krb5_creds), &ret;;
57b2bb
+    if (ret)
57b2bb
+        return ret;
57b2bb
+
57b2bb
+    ret = k5_unmarshal_cred((unsigned char *)data->data, data->length, 4,
57b2bb
+                            creds);
57b2bb
+    if (ret) {
57b2bb
+        free(creds);
57b2bb
+        return ret;
57b2bb
+    }
57b2bb
+
57b2bb
+    *creds_out = creds;
57b2bb
+    return 0;
57b2bb
+}
57b2bb
diff --git a/src/lib/krb5/ccache/t_marshal.c b/src/lib/krb5/ccache/t_marshal.c
57b2bb
index 144554c30..47ec2e94d 100644
57b2bb
--- a/src/lib/krb5/ccache/t_marshal.c
57b2bb
+++ b/src/lib/krb5/ccache/t_marshal.c
57b2bb
@@ -268,13 +268,14 @@ main(int argc, char **argv)
57b2bb
     krb5_context context;
57b2bb
     krb5_ccache cache;
57b2bb
     krb5_principal princ;
57b2bb
-    krb5_creds cred1, cred2;
57b2bb
+    krb5_creds cred1, cred2, *alloc_cred;
57b2bb
     krb5_cc_cursor cursor;
57b2bb
     const char *filename;
57b2bb
     char *ccname, filebuf[256];
57b2bb
     int version, fd;
57b2bb
     const struct test *t;
57b2bb
     struct k5buf buf;
57b2bb
+    krb5_data ser_data, *alloc_data;
57b2bb
 
57b2bb
     if (argc != 2)
57b2bb
         abort();
57b2bb
@@ -285,6 +286,18 @@ main(int argc, char **argv)
57b2bb
     if (krb5_init_context(&context) != 0)
57b2bb
         abort();
57b2bb
 
57b2bb
+    /* Test public functions for unmarshalling and marshalling. */
57b2bb
+    ser_data = make_data((char *)tests[3].cred1, tests[3].cred1len);
57b2bb
+    if (krb5_unmarshal_credentials(context, &ser_data, &alloc_cred) != 0)
57b2bb
+        abort();
57b2bb
+    verify_cred1(alloc_cred);
57b2bb
+    if (krb5_marshal_credentials(context, alloc_cred, &alloc_data) != 0)
57b2bb
+        abort();
57b2bb
+    assert(alloc_data->length == tests[3].cred1len);
57b2bb
+    assert(memcmp(tests[3].cred1, alloc_data->data, alloc_data->length) == 0);
57b2bb
+    krb5_free_data(context, alloc_data);
57b2bb
+    krb5_free_creds(context, alloc_cred);
57b2bb
+
57b2bb
     for (version = FIRST_VERSION; version <= 4; version++) {
57b2bb
         t = &tests[version - 1];
57b2bb
 
57b2bb
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
57b2bb
index cab5b3b17..48ae46f5c 100644
57b2bb
--- a/src/lib/krb5/libkrb5.exports
57b2bb
+++ b/src/lib/krb5/libkrb5.exports
57b2bb
@@ -488,6 +488,7 @@ krb5_lock_file
57b2bb
 krb5_make_authdata_kdc_issued
57b2bb
 krb5_make_full_ipaddr
57b2bb
 krb5_make_fulladdr
57b2bb
+krb5_marshal_credentials
57b2bb
 krb5_mcc_ops
57b2bb
 krb5_merge_authdata
57b2bb
 krb5_mk_1cred
57b2bb
@@ -592,6 +593,7 @@ krb5_timeofday
57b2bb
 krb5_timestamp_to_sfstring
57b2bb
 krb5_timestamp_to_string
57b2bb
 krb5_unlock_file
57b2bb
+krb5_unmarshal_credentials
57b2bb
 krb5_unpack_full_ipaddr
57b2bb
 krb5_unparse_name
57b2bb
 krb5_unparse_name_ext
57b2bb
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
57b2bb
index de5823c17..209c6aaef 100644
57b2bb
--- a/src/lib/krb5_32.def
57b2bb
+++ b/src/lib/krb5_32.def
57b2bb
@@ -502,3 +502,7 @@ EXPORTS
57b2bb
 
57b2bb
 ; new in 1.19
57b2bb
 	k5_cc_store_primary_cred			@470 ; PRIVATE
57b2bb
+
57b2bb
+; new in 1.20
57b2bb
+	krb5_marshal_credentials			@472
57b2bb
+	krb5_unmarshal_credentials			@473