|
|
bb7cd1 |
From aa309f35905951c6fdd12d286bb3aeeb61a62088 Mon Sep 17 00:00:00 2001
|
|
|
bb7cd1 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
bb7cd1 |
Date: Tue, 20 Sep 2016 22:03:30 +0200
|
|
|
bb7cd1 |
Subject: [PATCH 21/36] UTIL: krb5 principal (un)marshalling
|
|
|
bb7cd1 |
MIME-Version: 1.0
|
|
|
bb7cd1 |
Content-Type: text/plain; charset=UTF-8
|
|
|
bb7cd1 |
Content-Transfer-Encoding: 8bit
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
The KCM responder needs to read the contents of the principal blob that
|
|
|
bb7cd1 |
the Kerberos library sends. Since libkrb5 doesn't export any API to do
|
|
|
bb7cd1 |
so, we need to implement marshalling and unmarshalling of the principal
|
|
|
bb7cd1 |
ourselves.
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
In future, when the KCM server also supports renewals, we will also need
|
|
|
bb7cd1 |
to unmarshall the credentials, but until that is not really needed, the
|
|
|
bb7cd1 |
credentials will be stored as a blob.
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
|
|
bb7cd1 |
Reviewed-by: Simo Sorce <simo@redhat.com>
|
|
|
bb7cd1 |
---
|
|
|
bb7cd1 |
src/util/sss_krb5.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
bb7cd1 |
src/util/sss_krb5.h | 9 +++
|
|
|
bb7cd1 |
2 files changed, 204 insertions(+)
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
|
|
|
bb7cd1 |
index 4808a7703d07bb4eba91f14a7a515aadaec1774b..d461cf881566af37f31524c16f6a5f1511a5dc89 100644
|
|
|
bb7cd1 |
--- a/src/util/sss_krb5.c
|
|
|
bb7cd1 |
+++ b/src/util/sss_krb5.c
|
|
|
bb7cd1 |
@@ -24,6 +24,7 @@
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
#include "config.h"
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
+#include "util/sss_iobuf.h"
|
|
|
bb7cd1 |
#include "util/util.h"
|
|
|
bb7cd1 |
#include "util/sss_krb5.h"
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
@@ -1128,3 +1129,197 @@ done:
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
return res;
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+static errno_t iobuf_read_uint32be(struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ uint32_t *_val)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ uint32_t beval;
|
|
|
bb7cd1 |
+ errno_t ret;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = sss_iobuf_read_uint32(iobuf, &beval);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ *_val = be32toh(beval);
|
|
|
bb7cd1 |
+ return EOK;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+static errno_t iobuf_write_uint32be(struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ uint32_t val)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ uint32_t beval;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ beval = htobe32(val);
|
|
|
bb7cd1 |
+ return sss_iobuf_write_uint32(iobuf, beval);
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+static errno_t iobuf_get_len_bytes(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
+ struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ uint32_t *_nbytes,
|
|
|
bb7cd1 |
+ uint8_t **_bytes)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ errno_t ret;
|
|
|
bb7cd1 |
+ uint32_t nbytes;
|
|
|
bb7cd1 |
+ uint8_t *bytes = NULL;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_read_uint32be(iobuf, &nbytes);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ bytes = talloc_zero_size(mem_ctx, nbytes);
|
|
|
bb7cd1 |
+ if (bytes == NULL) {
|
|
|
bb7cd1 |
+ return ENOMEM;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = sss_iobuf_read_len(iobuf, nbytes, bytes);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ talloc_free(bytes);
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ *_bytes = bytes;
|
|
|
bb7cd1 |
+ *_nbytes = nbytes;
|
|
|
bb7cd1 |
+ return EOK;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+static errno_t get_krb5_data(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
+ struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ krb5_data *k5data)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ errno_t ret;
|
|
|
bb7cd1 |
+ uint32_t nbytes;
|
|
|
bb7cd1 |
+ uint8_t *bytes = NULL;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_get_len_bytes(mem_ctx, iobuf, &nbytes, &bytes);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ talloc_free(bytes);
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ k5data->data = (char *) bytes; /* FIXME - the cast is ugly */
|
|
|
bb7cd1 |
+ k5data->length = nbytes;
|
|
|
bb7cd1 |
+ return EOK;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+static errno_t set_krb5_data(struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ krb5_data *k5data)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ errno_t ret;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_write_uint32be(iobuf, k5data->length);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (k5data->length > 0) {
|
|
|
bb7cd1 |
+ ret = sss_iobuf_write_len(iobuf,
|
|
|
bb7cd1 |
+ (uint8_t *) k5data->data,
|
|
|
bb7cd1 |
+ k5data->length);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ return EOK;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+/* FIXME - it would be nice if Kerberos exported these APIs.. */
|
|
|
bb7cd1 |
+krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
+ struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ krb5_principal *_princ)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ krb5_principal princ = NULL;
|
|
|
bb7cd1 |
+ krb5_error_code ret;
|
|
|
bb7cd1 |
+ uint32_t ncomps;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (iobuf == NULL || _princ == NULL) {
|
|
|
bb7cd1 |
+ return EINVAL;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ princ = talloc_zero(mem_ctx, struct krb5_principal_data);
|
|
|
bb7cd1 |
+ if (princ == NULL) {
|
|
|
bb7cd1 |
+ return ENOMEM;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ princ->magic = KV5M_PRINCIPAL;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_read_uint32be(iobuf, (uint32_t *) &princ->type);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ goto fail;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_read_uint32be(iobuf, &ncomps);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ goto fail;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (ncomps > sss_iobuf_get_capacity(iobuf)) {
|
|
|
bb7cd1 |
+ /* Sanity check to avoid large allocations */
|
|
|
bb7cd1 |
+ ret = EINVAL;
|
|
|
bb7cd1 |
+ goto fail;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (ncomps != 0) {
|
|
|
bb7cd1 |
+ princ->data = talloc_zero_array(princ, krb5_data, ncomps);
|
|
|
bb7cd1 |
+ if (princ->data == NULL) {
|
|
|
bb7cd1 |
+ ret = ENOMEM;
|
|
|
bb7cd1 |
+ goto fail;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ princ->length = ncomps;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = get_krb5_data(princ, iobuf, &princ->realm);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ goto fail;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ for (size_t i = 0; i < ncomps; i++) {
|
|
|
bb7cd1 |
+ ret = get_krb5_data(princ->data, iobuf, &princ->data[i]);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ goto fail;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ *_princ = princ;
|
|
|
bb7cd1 |
+ return 0;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+fail:
|
|
|
bb7cd1 |
+ talloc_free(princ);
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+krb5_error_code sss_krb5_marshal_princ(krb5_principal princ,
|
|
|
bb7cd1 |
+ struct sss_iobuf *iobuf)
|
|
|
bb7cd1 |
+{
|
|
|
bb7cd1 |
+ krb5_error_code ret;
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (iobuf == NULL || princ == NULL) {
|
|
|
bb7cd1 |
+ return EINVAL;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_write_uint32be(iobuf, princ->type);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = iobuf_write_uint32be(iobuf, princ->length);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ ret = set_krb5_data(iobuf, &princ->realm);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ for (int i = 0; i < princ->length; i++) {
|
|
|
bb7cd1 |
+ ret = set_krb5_data(iobuf, &princ->data[i]);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ return EOK;
|
|
|
bb7cd1 |
+}
|
|
|
bb7cd1 |
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
|
|
|
bb7cd1 |
index ac0f6082c75a8878f72346733e592b7575d44089..0d9043be98749b1a21a1b74c68f07298fa27f230 100644
|
|
|
bb7cd1 |
--- a/src/util/sss_krb5.h
|
|
|
bb7cd1 |
+++ b/src/util/sss_krb5.h
|
|
|
bb7cd1 |
@@ -32,6 +32,7 @@
|
|
|
bb7cd1 |
#include <krb5.h>
|
|
|
bb7cd1 |
#endif
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
+#include "util/sss_iobuf.h"
|
|
|
bb7cd1 |
#include "util/util.h"
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
#define KRB5_CHILD_LOG_FILE "krb5_child"
|
|
|
bb7cd1 |
@@ -186,4 +187,12 @@ krb5_error_code sss_krb5_kt_have_content(krb5_context context,
|
|
|
bb7cd1 |
krb5_keytab keytab);
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
bool sss_krb5_realm_has_proxy(const char *realm);
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+krb5_error_code sss_krb5_marshal_princ(krb5_principal princ,
|
|
|
bb7cd1 |
+ struct sss_iobuf *iobuf);
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
+ struct sss_iobuf *iobuf,
|
|
|
bb7cd1 |
+ krb5_principal *_princ);
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
#endif /* __SSS_KRB5_H__ */
|
|
|
bb7cd1 |
--
|
|
|
bb7cd1 |
2.9.3
|
|
|
bb7cd1 |
|