358 lines
11 KiB
Diff
358 lines
11 KiB
Diff
From 505bc85ec31ad8cfa66be0dc99d19599cd1a9497 Mon Sep 17 00:00:00 2001
|
|
From: Simo Sorce <ssorce@redhat.com>
|
|
Date: Fri, 6 Jul 2012 11:15:15 -0400
|
|
Subject: [PATCH 50/79] Move code into common krb5 utils
|
|
|
|
This moves the decoding function that reads the keys from the ber format
|
|
into a structure in the common krb5 util code right below the function
|
|
that encodes the same data structure into a ber format.
|
|
This way the 2 functions are in the same place and can be both used by
|
|
all ia components.
|
|
---
|
|
daemons/ipa-kdb/ipa_kdb_principals.c | 148 ++--------------------------------
|
|
util/ipa_krb5.c | 150 +++++++++++++++++++++++++++++++++++
|
|
util/ipa_krb5.h | 2 +
|
|
3 files changed, 159 insertions(+), 141 deletions(-)
|
|
|
|
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
|
|
index d87d6fe9f82b479db6ab8e6b59a8b5ee580b9a27..6f8b296fa4cb19cbfe5c37536316d6f0e7f83b9c 100644
|
|
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
|
|
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
|
|
@@ -205,152 +205,18 @@ static int ipadb_ldap_attr_to_key_data(LDAP *lcontext, LDAPMessage *le,
|
|
krb5_kvno *res_mkvno)
|
|
{
|
|
struct berval **vals;
|
|
- krb5_key_data *keys = NULL;
|
|
- BerElement *be = NULL;
|
|
- void *tmp;
|
|
- int i = 0;
|
|
- int ret = ENOENT;
|
|
+ int mkvno;
|
|
+ int ret;
|
|
|
|
vals = ldap_get_values_len(lcontext, le, attrname);
|
|
- if (vals) {
|
|
- ber_tag_t tag;
|
|
- ber_int_t major_vno;
|
|
- ber_int_t minor_vno;
|
|
- ber_int_t kvno;
|
|
- ber_int_t mkvno;
|
|
- ber_int_t type;
|
|
- ber_tag_t seqtag;
|
|
- ber_len_t seqlen;
|
|
- ber_len_t setlen;
|
|
- ber_tag_t retag;
|
|
- ber_tag_t opttag;
|
|
- struct berval tval;
|
|
-
|
|
- be = ber_alloc_t(LBER_USE_DER);
|
|
- if (!be) {
|
|
- return ENOMEM;
|
|
- }
|
|
-
|
|
- /* reinit the ber element with the new val */
|
|
- ber_init2(be, vals[0], LBER_USE_DER);
|
|
-
|
|
- /* fill key_data struct with the data */
|
|
- retag = ber_scanf(be, "{t[i]t[i]t[i]t[i]t[{",
|
|
- &tag, &major_vno,
|
|
- &tag, &minor_vno,
|
|
- &tag, &kvno,
|
|
- &tag, &mkvno,
|
|
- &seqtag);
|
|
- if (retag == LBER_ERROR ||
|
|
- major_vno != 1 ||
|
|
- minor_vno != 1 ||
|
|
- seqtag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 4)) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- retag = ber_skip_tag(be, &seqlen);
|
|
-
|
|
- /* sequence of keys */
|
|
- for (i = 0; retag == LBER_SEQUENCE; i++) {
|
|
-
|
|
- tmp = realloc(keys, (i + 1) * sizeof(krb5_key_data));
|
|
- if (!tmp) {
|
|
- ret = ENOMEM;
|
|
- goto done;
|
|
- }
|
|
- keys = tmp;
|
|
-
|
|
- memset(&keys[i], 0, sizeof(krb5_key_data));
|
|
-
|
|
- keys[i].key_data_kvno = kvno;
|
|
-
|
|
- /* do we have a salt type ? (optional) */
|
|
- retag = ber_scanf(be, "t", &opttag);
|
|
- if (retag == LBER_ERROR) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
- if (opttag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) {
|
|
- keys[i].key_data_ver = 2;
|
|
-
|
|
- retag = ber_scanf(be, "[l{tl[i]",
|
|
- &seqlen, &tag, &setlen, &type);
|
|
- if (tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
- keys[i].key_data_type[1] = type;
|
|
-
|
|
- /* do we have salt data ? (optional) */
|
|
- if (seqlen > setlen + 2) {
|
|
- retag = ber_scanf(be, "t[o]", &tag, &tval);
|
|
- if (retag == LBER_ERROR ||
|
|
- tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
- keys[i].key_data_length[1] = tval.bv_len;
|
|
- keys[i].key_data_contents[1] = (krb5_octet *)tval.bv_val;
|
|
- }
|
|
-
|
|
- retag = ber_scanf(be, "}]t", &opttag);
|
|
- if (retag == LBER_ERROR) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- } else {
|
|
- keys[i].key_data_ver = 1;
|
|
- }
|
|
-
|
|
- if (opttag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /* get the key */
|
|
- retag = ber_scanf(be, "[{t[i]t[o]}]", &tag, &type, &tag, &tval);
|
|
- if (retag == LBER_ERROR) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
- keys[i].key_data_type[0] = type;
|
|
- keys[i].key_data_length[0] = tval.bv_len;
|
|
- keys[i].key_data_contents[0] = (krb5_octet *)tval.bv_val;
|
|
-
|
|
- /* check for sk2params */
|
|
- retag = ber_peek_tag(be, &setlen);
|
|
- if (retag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 2)) {
|
|
- /* not supported yet, skip */
|
|
- retag = ber_scanf(be, "t[x]}");
|
|
- } else {
|
|
- retag = ber_scanf(be, "}");
|
|
- }
|
|
- if (retag == LBER_ERROR) {
|
|
- ret = EINVAL;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- retag = ber_skip_tag(be, &seqlen);
|
|
- }
|
|
- *result = keys;
|
|
- *num = i;
|
|
- *res_mkvno = mkvno;
|
|
- ret = 0;
|
|
+ if (!vals) {
|
|
+ return ENOENT;
|
|
}
|
|
|
|
-done:
|
|
- ber_free(be, 0); /* internal buffer is 'vals[0]' */
|
|
+ ret = ber_decode_krb5_key_data(vals[0], &mkvno, num, result);
|
|
ldap_value_free_len(vals);
|
|
- if (ret) {
|
|
- for (i -= 1; keys && i >= 0; i--) {
|
|
- free(keys[i].key_data_contents[0]);
|
|
- free(keys[i].key_data_contents[1]);
|
|
- }
|
|
- free(keys);
|
|
- *result = NULL;
|
|
- *num = 0;
|
|
+ if (ret == 0) {
|
|
+ *res_mkvno = mkvno;
|
|
}
|
|
return ret;
|
|
}
|
|
diff --git a/util/ipa_krb5.c b/util/ipa_krb5.c
|
|
index 0240c079ecd38271e5dbb36ec8c6a091001cfce7..934fd27d80cdd846f4de631b2dd587b0ad0f325c 100644
|
|
--- a/util/ipa_krb5.c
|
|
+++ b/util/ipa_krb5.c
|
|
@@ -427,6 +427,156 @@ done:
|
|
return ret;
|
|
}
|
|
|
|
+int ber_decode_krb5_key_data(struct berval *encoded, int *m_kvno,
|
|
+ int *numk, krb5_key_data **data)
|
|
+{
|
|
+ krb5_key_data *keys = NULL;
|
|
+ BerElement *be = NULL;
|
|
+ void *tmp;
|
|
+ int i = 0;
|
|
+ ber_tag_t tag;
|
|
+ ber_int_t major_vno;
|
|
+ ber_int_t minor_vno;
|
|
+ ber_int_t kvno;
|
|
+ ber_int_t mkvno;
|
|
+ ber_int_t type;
|
|
+ ber_tag_t seqtag;
|
|
+ ber_len_t seqlen;
|
|
+ ber_len_t setlen;
|
|
+ ber_tag_t retag;
|
|
+ ber_tag_t opttag;
|
|
+ struct berval tval;
|
|
+ int ret;
|
|
+
|
|
+ be = ber_alloc_t(LBER_USE_DER);
|
|
+ if (!be) {
|
|
+ return ENOMEM;
|
|
+ }
|
|
+
|
|
+ /* reinit the ber element with the new val */
|
|
+ ber_init2(be, encoded, LBER_USE_DER);
|
|
+
|
|
+ /* fill key_data struct with the data */
|
|
+ retag = ber_scanf(be, "{t[i]t[i]t[i]t[i]t[{",
|
|
+ &tag, &major_vno,
|
|
+ &tag, &minor_vno,
|
|
+ &tag, &kvno,
|
|
+ &tag, &mkvno,
|
|
+ &seqtag);
|
|
+ if (retag == LBER_ERROR ||
|
|
+ major_vno != 1 ||
|
|
+ minor_vno != 1 ||
|
|
+ seqtag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 4)) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ retag = ber_skip_tag(be, &seqlen);
|
|
+
|
|
+ /* sequence of keys */
|
|
+ for (i = 0; retag == LBER_SEQUENCE; i++) {
|
|
+
|
|
+ tmp = realloc(keys, (i + 1) * sizeof(krb5_key_data));
|
|
+ if (!tmp) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+ keys = tmp;
|
|
+
|
|
+ memset(&keys[i], 0, sizeof(krb5_key_data));
|
|
+
|
|
+ keys[i].key_data_kvno = kvno;
|
|
+
|
|
+ /* do we have a salt type ? (optional) */
|
|
+ retag = ber_scanf(be, "t", &opttag);
|
|
+ if (retag == LBER_ERROR) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+ if (opttag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) {
|
|
+ keys[i].key_data_ver = 2;
|
|
+
|
|
+ retag = ber_scanf(be, "[l{tl[i]",
|
|
+ &seqlen, &tag, &setlen, &type);
|
|
+ if (tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+ keys[i].key_data_type[1] = type;
|
|
+
|
|
+ /* do we have salt data ? (optional) */
|
|
+ if (seqlen > setlen + 2) {
|
|
+ retag = ber_scanf(be, "t[o]", &tag, &tval);
|
|
+ if (retag == LBER_ERROR ||
|
|
+ tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+ keys[i].key_data_length[1] = tval.bv_len;
|
|
+ keys[i].key_data_contents[1] = (krb5_octet *)tval.bv_val;
|
|
+ }
|
|
+
|
|
+ retag = ber_scanf(be, "}]t", &opttag);
|
|
+ if (retag == LBER_ERROR) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ } else {
|
|
+ keys[i].key_data_ver = 1;
|
|
+ }
|
|
+
|
|
+ if (opttag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ /* get the key */
|
|
+ retag = ber_scanf(be, "[{t[i]t[o]}]", &tag, &type, &tag, &tval);
|
|
+ if (retag == LBER_ERROR) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+ keys[i].key_data_type[0] = type;
|
|
+ keys[i].key_data_length[0] = tval.bv_len;
|
|
+ keys[i].key_data_contents[0] = (krb5_octet *)tval.bv_val;
|
|
+
|
|
+ /* check for sk2params */
|
|
+ retag = ber_peek_tag(be, &setlen);
|
|
+ if (retag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 2)) {
|
|
+ /* not supported yet, skip */
|
|
+ retag = ber_scanf(be, "t[x]}");
|
|
+ } else {
|
|
+ retag = ber_scanf(be, "}");
|
|
+ }
|
|
+ if (retag == LBER_ERROR) {
|
|
+ ret = EINVAL;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ retag = ber_skip_tag(be, &seqlen);
|
|
+ }
|
|
+
|
|
+ ret = 0;
|
|
+
|
|
+done:
|
|
+ ber_free(be, 0); /* internal buffer is 'encoded' */
|
|
+ if (ret) {
|
|
+ for (i -= 1; keys && i >= 0; i--) {
|
|
+ free(keys[i].key_data_contents[0]);
|
|
+ free(keys[i].key_data_contents[1]);
|
|
+ }
|
|
+ free(keys);
|
|
+ keys = NULL;
|
|
+ mkvno = 0;
|
|
+ }
|
|
+ *m_kvno = mkvno;
|
|
+ *numk = i;
|
|
+ *data = keys;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
krb5_error_code parse_bval_key_salt_tuples(krb5_context kcontext,
|
|
const char * const *vals,
|
|
int n_vals,
|
|
diff --git a/util/ipa_krb5.h b/util/ipa_krb5.h
|
|
index 97ffc47b5017507cd58e130755cfe050a287b30c..7fb0355724e3c4f522097df417d2686b85619319 100644
|
|
--- a/util/ipa_krb5.h
|
|
+++ b/util/ipa_krb5.h
|
|
@@ -49,6 +49,8 @@ void ipa_krb5_free_key_data(krb5_key_data *keys, int num_keys);
|
|
int ber_encode_krb5_key_data(krb5_key_data *data,
|
|
int numk, int mkvno,
|
|
struct berval **encoded);
|
|
+int ber_decode_krb5_key_data(struct berval *encoded, int *m_kvno,
|
|
+ int *numk, krb5_key_data **data);
|
|
|
|
krb5_error_code parse_bval_key_salt_tuples(krb5_context kcontext,
|
|
const char * const *vals,
|
|
--
|
|
1.7.11.2
|
|
|