|
|
e3ffab |
From 55172f11776453c0f8defb1363dd144b29f181d3 Mon Sep 17 00:00:00 2001
|
|
|
e3ffab |
From: Simo Sorce <simo@redhat.com>
|
|
|
e3ffab |
Date: Mon, 17 Nov 2014 15:19:57 -0500
|
|
|
e3ffab |
Subject: [PATCH] Use asn1c helpers to encode/decode the getkeytab control
|
|
|
e3ffab |
|
|
|
e3ffab |
Replaces manual encoding with automatically generated code.
|
|
|
e3ffab |
|
|
|
e3ffab |
Fixes:
|
|
|
e3ffab |
https://fedorahosted.org/freeipa/ticket/4718
|
|
|
e3ffab |
https://fedorahosted.org/freeipa/ticket/4728
|
|
|
e3ffab |
|
|
|
e3ffab |
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
e3ffab |
Reviewed-By: Nathaniel McCallum <npmccallum@redhat.com>
|
|
|
e3ffab |
---
|
|
|
e3ffab |
Makefile | 1 +
|
|
|
e3ffab |
daemons/configure.ac | 2 +
|
|
|
e3ffab |
.../ipa-slapi-plugins/ipa-pwd-extop/Makefile.am | 7 +-
|
|
|
e3ffab |
.../ipa-pwd-extop/ipa_pwd_extop.c | 241 ++++----------------
|
|
|
e3ffab |
ipa-client/Makefile.am | 4 +
|
|
|
e3ffab |
ipa-client/configure.ac | 2 +
|
|
|
e3ffab |
ipa-client/ipa-getkeytab.c | 246 ++++-----------------
|
|
|
e3ffab |
7 files changed, 107 insertions(+), 396 deletions(-)
|
|
|
e3ffab |
|
|
|
e3ffab |
diff --git a/Makefile b/Makefile
|
|
|
e3ffab |
index c1a298f91717246e8dab5e3f0de47d0ac9b2ae35..8fd0c60e392d720f47c8ee7c4b674727dc5eb789 100644
|
|
|
e3ffab |
--- a/Makefile
|
|
|
e3ffab |
+++ b/Makefile
|
|
|
e3ffab |
@@ -75,6 +75,7 @@ client: client-autogen
|
|
|
e3ffab |
|
|
|
e3ffab |
bootstrap-autogen: version-update client-autogen
|
|
|
e3ffab |
@echo "Building IPA $(IPA_VERSION)"
|
|
|
e3ffab |
+ cd asn1; if [ ! -e Makefile ]; then ../autogen.sh --prefix=/usr --sysconfdir=/etc --localstatedir=/var --libdir=$(LIBDIR); fi
|
|
|
e3ffab |
cd daemons; if [ ! -e Makefile ]; then ../autogen.sh --prefix=/usr --sysconfdir=/etc --localstatedir=/var --libdir=$(LIBDIR) --with-openldap; fi
|
|
|
e3ffab |
cd install; if [ ! -e Makefile ]; then ../autogen.sh --prefix=/usr --sysconfdir=/etc --localstatedir=/var --libdir=$(LIBDIR); fi
|
|
|
e3ffab |
|
|
|
e3ffab |
diff --git a/daemons/configure.ac b/daemons/configure.ac
|
|
|
e3ffab |
index bfcdeadcd1dc73762d8c773ee50210d9bdb91e92..e81aa60e381e035aff73bf27475fc0f101a5fbf9 100644
|
|
|
e3ffab |
--- a/daemons/configure.ac
|
|
|
e3ffab |
+++ b/daemons/configure.ac
|
|
|
e3ffab |
@@ -5,6 +5,7 @@ AC_INIT([ipa-server],
|
|
|
e3ffab |
[https://hosted.fedoraproject.org/projects/freeipa/newticket])
|
|
|
e3ffab |
|
|
|
e3ffab |
AC_CONFIG_HEADERS([config.h])
|
|
|
e3ffab |
+AC_CONFIG_SUBDIRS([../asn1])
|
|
|
e3ffab |
|
|
|
e3ffab |
AM_INIT_AUTOMAKE([foreign])
|
|
|
e3ffab |
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
|
|
|
e3ffab |
@@ -305,6 +306,7 @@ AC_SUBST(LDFLAGS)
|
|
|
e3ffab |
|
|
|
e3ffab |
AC_CONFIG_FILES([
|
|
|
e3ffab |
Makefile
|
|
|
e3ffab |
+ ../asn1/Makefile
|
|
|
e3ffab |
ipa-kdb/Makefile
|
|
|
e3ffab |
ipa-sam/Makefile
|
|
|
e3ffab |
ipa-otpd/Makefile
|
|
|
e3ffab |
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/Makefile.am b/daemons/ipa-slapi-plugins/ipa-pwd-extop/Makefile.am
|
|
|
e3ffab |
index 4cf80ec802b40bb579a44fc9357c6a8119dab577..77beca2da0810ed5507d95b21f99d22f63b05fc1 100644
|
|
|
e3ffab |
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/Makefile.am
|
|
|
e3ffab |
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/Makefile.am
|
|
|
e3ffab |
@@ -6,6 +6,7 @@ KRB5_UTIL_DIR = ../../../util
|
|
|
e3ffab |
KRB5_UTIL_SRCS = $(KRB5_UTIL_DIR)/ipa_krb5.c \
|
|
|
e3ffab |
$(KRB5_UTIL_DIR)/ipa_pwd.c \
|
|
|
e3ffab |
$(KRB5_UTIL_DIR)/ipa_pwd_ntlm.c
|
|
|
e3ffab |
+ASN1_UTIL_DIR=../../../asn1
|
|
|
e3ffab |
|
|
|
e3ffab |
AM_CPPFLAGS = \
|
|
|
e3ffab |
-I. \
|
|
|
e3ffab |
@@ -13,6 +14,7 @@ AM_CPPFLAGS = \
|
|
|
e3ffab |
-I$(srcdir)/../libotp \
|
|
|
e3ffab |
-I$(PLUGIN_COMMON_DIR) \
|
|
|
e3ffab |
-I$(KRB5_UTIL_DIR) \
|
|
|
e3ffab |
+ -I$(ASN1_UTIL_DIR) \
|
|
|
e3ffab |
-I$(COMMON_BER_DIR) \
|
|
|
e3ffab |
-DPREFIX=\""$(prefix)"\" \
|
|
|
e3ffab |
-DBINDIR=\""$(bindir)"\" \
|
|
|
e3ffab |
@@ -38,7 +40,10 @@ AM_LDFLAGS = \
|
|
|
e3ffab |
# Plugin Binary
|
|
|
e3ffab |
plugindir = $(libdir)/dirsrv/plugins
|
|
|
e3ffab |
plugin_LTLIBRARIES = libipa_pwd_extop.la
|
|
|
e3ffab |
-libipa_pwd_extop_la_LIBADD = $(builddir)/../libotp/libotp.la
|
|
|
e3ffab |
+libipa_pwd_extop_la_LIBADD = \
|
|
|
e3ffab |
+ $(builddir)/../libotp/libotp.la \
|
|
|
e3ffab |
+ $(ASN1_UTIL_DIR)/libipaasn1.la \
|
|
|
e3ffab |
+ $(NULL)
|
|
|
e3ffab |
libipa_pwd_extop_la_SOURCES = \
|
|
|
e3ffab |
authcfg.c \
|
|
|
e3ffab |
common.c \
|
|
|
e3ffab |
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
|
|
|
e3ffab |
index b87ae0dc7a180008228f31293b49212df80584e8..ceea49cab50b0836c882240f210339e60d26729b 100644
|
|
|
e3ffab |
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
|
|
|
e3ffab |
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
|
|
|
e3ffab |
@@ -40,6 +40,7 @@
|
|
|
e3ffab |
#include "ipapwd.h"
|
|
|
e3ffab |
#include "util.h"
|
|
|
e3ffab |
#include "authcfg.h"
|
|
|
e3ffab |
+#include "ipa_asn1.h"
|
|
|
e3ffab |
|
|
|
e3ffab |
/*
|
|
|
e3ffab |
* Password Modify - LDAP Extended Operation.
|
|
|
e3ffab |
@@ -1310,31 +1311,7 @@ free_and_return:
|
|
|
e3ffab |
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
-/* Format of getkeytab request
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * KeytabGetRequest ::= CHOICE {
|
|
|
e3ffab |
- * newkeys [0] Newkeys,
|
|
|
e3ffab |
- * curkeys [1] CurrentKeys,
|
|
|
e3ffab |
- * reply [2] Reply
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * NewKeys ::= SEQUENCE {
|
|
|
e3ffab |
- * serviceIdentity [0] OCTET STRING,
|
|
|
e3ffab |
- * enctypes [1] SEQUENCE OF Int16
|
|
|
e3ffab |
- * password [2] OCTET STRING OPTIONAL,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * CurrentKeys ::= SEQUENCE {
|
|
|
e3ffab |
- * serviceIdentity [0] OCTET STRING,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- */
|
|
|
e3ffab |
-
|
|
|
e3ffab |
-#define GK_REQUEST_NEWKEYS (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
|
|
|
e3ffab |
-#define GK_REQUEST_CURKEYS (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREQ_SVCNAME_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREQ_ENCTYPES_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREQ_PASSWORD_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
|
|
|
e3ffab |
-
|
|
|
e3ffab |
+/* decode a getkeytab control request using libipaasn1 helpers */
|
|
|
e3ffab |
static int decode_getkeytab_request(struct berval *extop, bool *wantold,
|
|
|
e3ffab |
char **_svcname, char **_password,
|
|
|
e3ffab |
krb5_key_salt_tuple **kenctypes,
|
|
|
e3ffab |
@@ -1342,96 +1319,44 @@ static int decode_getkeytab_request(struct berval *extop, bool *wantold,
|
|
|
e3ffab |
{
|
|
|
e3ffab |
int rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
char *err_msg = NULL;
|
|
|
e3ffab |
- BerElement *ber = NULL;
|
|
|
e3ffab |
- ber_len_t tlen;
|
|
|
e3ffab |
- ber_tag_t rtag;
|
|
|
e3ffab |
- ber_tag_t ttag;
|
|
|
e3ffab |
- ber_tag_t ctag;
|
|
|
e3ffab |
char *svcname = NULL;
|
|
|
e3ffab |
char *password = NULL;
|
|
|
e3ffab |
- ber_int_t enctype;
|
|
|
e3ffab |
+ long *etypes = NULL;
|
|
|
e3ffab |
+ int numtypes = 0;
|
|
|
e3ffab |
krb5_key_salt_tuple *enctypes = NULL;
|
|
|
e3ffab |
- int num = 0;
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- ber = ber_init(extop);
|
|
|
e3ffab |
- if (ber == NULL) {
|
|
|
e3ffab |
- err_msg = "KeytabGet Request decode failed.\n";
|
|
|
e3ffab |
- rc = LDAP_PROTOCOL_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- /* check this is a request */
|
|
|
e3ffab |
- rtag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- if (rtag != GK_REQUEST_NEWKEYS && rtag != GK_REQUEST_CURKEYS) {
|
|
|
e3ffab |
- LOG_FATAL("ber_peek_tag failed, wrong request type\n");
|
|
|
e3ffab |
- err_msg = "Invalid payload.\n";
|
|
|
e3ffab |
- rc = LDAP_PROTOCOL_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- /* ber parse code */
|
|
|
e3ffab |
- ttag = ber_scanf(ber, "{ta", &ctag, &svcname);
|
|
|
e3ffab |
- if (ttag == LBER_ERROR || ctag != GKREQ_SVCNAME_TAG) {
|
|
|
e3ffab |
- LOG_FATAL("ber_scanf failed to decode service name\n");
|
|
|
e3ffab |
- err_msg = "Invalid payload.\n";
|
|
|
e3ffab |
+ bool newkt;
|
|
|
e3ffab |
+ bool ret;
|
|
|
e3ffab |
+ int i;
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ ret = ipaasn1_dec_getkt(extop->bv_val, extop->bv_len, &newkt,
|
|
|
e3ffab |
+ &svcname, &password, &etypes, &numtypes);
|
|
|
e3ffab |
+ if (!ret) {
|
|
|
e3ffab |
+ err_msg = "Failed to decode GetKeytab Control.\n";
|
|
|
e3ffab |
rc = LDAP_PROTOCOL_ERROR;
|
|
|
e3ffab |
goto done;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
- if (rtag == GK_REQUEST_CURKEYS) {
|
|
|
e3ffab |
- rc = LDAP_SUCCESS;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- ttag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- if (ttag != GKREQ_ENCTYPES_TAG) {
|
|
|
e3ffab |
- LOG_FATAL("ber_peek_tag failed to find enctypes\n");
|
|
|
e3ffab |
- err_msg = "Invalid payload.\n";
|
|
|
e3ffab |
- rc = LDAP_PROTOCOL_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- ttag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- for (num = 0; ttag == LBER_INTEGER; num++) {
|
|
|
e3ffab |
- if ((num % 10) == 0) {
|
|
|
e3ffab |
- /* allocate space for at least 10 more enctypes */
|
|
|
e3ffab |
- enctypes = realloc(enctypes,
|
|
|
e3ffab |
- (num + 10) * sizeof(krb5_key_salt_tuple));
|
|
|
e3ffab |
+ if (newkt) {
|
|
|
e3ffab |
+ if (numtypes) {
|
|
|
e3ffab |
+ enctypes = malloc(numtypes * sizeof(krb5_key_salt_tuple));
|
|
|
e3ffab |
if (!enctypes) {
|
|
|
e3ffab |
LOG_FATAL("allocation failed\n");
|
|
|
e3ffab |
err_msg = "Internal error\n";
|
|
|
e3ffab |
rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
goto done;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- ttag = ber_scanf(ber, "i", &enctype);
|
|
|
e3ffab |
- if (ttag == LBER_ERROR) {
|
|
|
e3ffab |
- LOG_FATAL("ber_scanf failed to decode enctype\n");
|
|
|
e3ffab |
- err_msg = "Invalid payload.\n";
|
|
|
e3ffab |
- rc = LDAP_PROTOCOL_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- enctypes[num].ks_enctype = enctype;
|
|
|
e3ffab |
- enctypes[num].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
|
|
|
e3ffab |
- ttag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
|
|
|
e3ffab |
- /* ttag peek done as last step of the previous for loop */
|
|
|
e3ffab |
- if (ttag == GKREQ_PASSWORD_TAG) {
|
|
|
e3ffab |
- /* optional password present */
|
|
|
e3ffab |
- ttag = ber_scanf(ber, "a", &password);
|
|
|
e3ffab |
- if (ttag == LBER_ERROR) {
|
|
|
e3ffab |
- LOG_FATAL("ber_scanf failed to decode password\n");
|
|
|
e3ffab |
- err_msg = "Invalid payload.\n";
|
|
|
e3ffab |
- rc = LDAP_PROTOCOL_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
+ for (i = 0; i < numtypes; i++) {
|
|
|
e3ffab |
+ enctypes[i].ks_enctype = etypes[i];
|
|
|
e3ffab |
+ enctypes[i].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
|
|
|
e3ffab |
+ }
|
|
|
e3ffab |
}
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
rc = LDAP_SUCCESS;
|
|
|
e3ffab |
|
|
|
e3ffab |
done:
|
|
|
e3ffab |
+ free(etypes);
|
|
|
e3ffab |
if (rc != LDAP_SUCCESS) {
|
|
|
e3ffab |
free(password);
|
|
|
e3ffab |
free(svcname);
|
|
|
e3ffab |
@@ -1440,78 +1365,34 @@ done:
|
|
|
e3ffab |
} else {
|
|
|
e3ffab |
*_password = password;
|
|
|
e3ffab |
*_svcname = svcname;
|
|
|
e3ffab |
- *wantold = (rtag == GK_REQUEST_CURKEYS);
|
|
|
e3ffab |
+ *wantold = (newkt == false);
|
|
|
e3ffab |
*kenctypes = enctypes;
|
|
|
e3ffab |
- *num_kenctypes = num;
|
|
|
e3ffab |
+ *num_kenctypes = numtypes;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
- if (ber) ber_free(ber, 1);
|
|
|
e3ffab |
return rc;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
-/* Format of getkeytab reply
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * Reply ::= SEQUENCE {
|
|
|
e3ffab |
- * new_kvno Int32
|
|
|
e3ffab |
- * keys SEQUENCE OF KrbKey,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * KrbKey ::= SEQUENCE {
|
|
|
e3ffab |
- * key [0] EncryptionKey,
|
|
|
e3ffab |
- * salt [1] KrbSalt OPTIONAL,
|
|
|
e3ffab |
- * s2kparams [2] OCTET STRING OPTIONAL,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * EncryptionKey ::= SEQUENCE {
|
|
|
e3ffab |
- * keytype [0] Int32,
|
|
|
e3ffab |
- * keyvalue [1] OCTET STRING
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * KrbSalt ::= SEQUENCE {
|
|
|
e3ffab |
- * type [0] Int32,
|
|
|
e3ffab |
- * salt [1] OCTET STRING
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- */
|
|
|
e3ffab |
-
|
|
|
e3ffab |
-#define GK_REPLY_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
|
|
|
e3ffab |
-#define GKREP_KEY_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
|
|
|
e3ffab |
-#define GKREP_SALT_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREP_S2KPARAMS_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
|
|
|
e3ffab |
-#define GKREP_KEYTYPE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
|
|
|
e3ffab |
-#define GKREP_KEYVALUE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREP_SALTTYPE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
|
|
|
e3ffab |
-#define GKREP_SALTVALUE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-
|
|
|
e3ffab |
static int encode_getkeytab_reply(krb5_context krbctx,
|
|
|
e3ffab |
krb5_keyblock *kmkey, int mkvno,
|
|
|
e3ffab |
krb5_key_data *keys, int num_keys,
|
|
|
e3ffab |
struct berval **_bvp)
|
|
|
e3ffab |
{
|
|
|
e3ffab |
int rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
+ struct krb_key_salt ksdata[num_keys];
|
|
|
e3ffab |
+ struct keys_container ksc = { num_keys, ksdata };
|
|
|
e3ffab |
struct berval *bvp = NULL;
|
|
|
e3ffab |
- BerElement *ber = NULL;
|
|
|
e3ffab |
- ber_int_t kvno;
|
|
|
e3ffab |
- krb5_data plain = { 0 };
|
|
|
e3ffab |
+ int kvno;
|
|
|
e3ffab |
+ bool ret;
|
|
|
e3ffab |
|
|
|
e3ffab |
- ber = ber_alloc();
|
|
|
e3ffab |
- if (!ber) {
|
|
|
e3ffab |
- LOG_OOM();
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ memset(ksdata, '\0', num_keys * sizeof(struct krb_key_salt));
|
|
|
e3ffab |
|
|
|
e3ffab |
/* uses last key kvno */
|
|
|
e3ffab |
kvno = keys[num_keys-1].key_data_kvno;
|
|
|
e3ffab |
|
|
|
e3ffab |
- rc = ber_printf(ber, "t{i{", GK_REPLY_TAG, kvno);
|
|
|
e3ffab |
- if (rc == -1) {
|
|
|
e3ffab |
- rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- LOG_FATAL("Failed to initiate key buffer\n");
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
for (int i = 0; i < num_keys; i++) {
|
|
|
e3ffab |
krb5_enc_data cipher = { 0 };
|
|
|
e3ffab |
+ krb5_data plain = { 0 };
|
|
|
e3ffab |
krb5_int16 plen;
|
|
|
e3ffab |
- void *p;
|
|
|
e3ffab |
|
|
|
e3ffab |
/* retrieve plain key */
|
|
|
e3ffab |
memcpy(&plen, keys[i].key_data_contents[0], 2);
|
|
|
e3ffab |
@@ -1521,13 +1402,12 @@ static int encode_getkeytab_reply(krb5_context krbctx,
|
|
|
e3ffab |
cipher.kvno = mkvno;
|
|
|
e3ffab |
|
|
|
e3ffab |
plain.length = le16toh(plen);
|
|
|
e3ffab |
- p = realloc(plain.data, plain.length);
|
|
|
e3ffab |
- if (!p) {
|
|
|
e3ffab |
+ plain.data = malloc(plain.length);
|
|
|
e3ffab |
+ if (!plain.data) {
|
|
|
e3ffab |
LOG_FATAL("Failed to allocate plain buffer\n");
|
|
|
e3ffab |
rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
goto done;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
- plain.data = p;
|
|
|
e3ffab |
|
|
|
e3ffab |
rc = krb5_c_decrypt(krbctx, kmkey, 0, 0, &cipher, &plain);
|
|
|
e3ffab |
if (rc) {
|
|
|
e3ffab |
@@ -1536,68 +1416,37 @@ static int encode_getkeytab_reply(krb5_context krbctx,
|
|
|
e3ffab |
goto done;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
- rc = ber_printf(ber,
|
|
|
e3ffab |
- "{t{tito}",
|
|
|
e3ffab |
- GKREP_KEY_TAG,
|
|
|
e3ffab |
- GKREP_KEYTYPE_TAG,
|
|
|
e3ffab |
- (ber_int_t)keys[i].key_data_type[0],
|
|
|
e3ffab |
- GKREP_KEYVALUE_TAG,
|
|
|
e3ffab |
- plain.data, (ber_len_t)plain.length);
|
|
|
e3ffab |
- if (rc == -1) {
|
|
|
e3ffab |
- LOG_FATAL("Failed to encode key data\n");
|
|
|
e3ffab |
- rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ ksc.ksdata[i].enctype = keys[i].key_data_type[0];
|
|
|
e3ffab |
+ ksc.ksdata[i].key.enctype = keys[i].key_data_type[0];
|
|
|
e3ffab |
+ ksc.ksdata[i].key.contents = (void *)plain.data;
|
|
|
e3ffab |
+ ksc.ksdata[i].key.length = plain.length;
|
|
|
e3ffab |
|
|
|
e3ffab |
/* if salt available, add it */
|
|
|
e3ffab |
if (keys[i].key_data_length[1] != 0) {
|
|
|
e3ffab |
- rc = ber_printf(ber,
|
|
|
e3ffab |
- "t{tito}",
|
|
|
e3ffab |
- GKREP_SALT_TAG,
|
|
|
e3ffab |
- GKREP_SALTTYPE_TAG,
|
|
|
e3ffab |
- (ber_int_t)keys[i].key_data_type[1],
|
|
|
e3ffab |
- GKREP_SALTVALUE_TAG,
|
|
|
e3ffab |
- keys[i].key_data_contents[1],
|
|
|
e3ffab |
- (ber_len_t)keys[i].key_data_length[1]);
|
|
|
e3ffab |
- if (rc == -1) {
|
|
|
e3ffab |
- LOG_FATAL("Failed to encode salt data\n");
|
|
|
e3ffab |
- rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- rc = ber_printf(ber, "}");
|
|
|
e3ffab |
- if (rc == -1) {
|
|
|
e3ffab |
- LOG_FATAL("Failed to encode data\n");
|
|
|
e3ffab |
- rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
+ ksc.ksdata[i].salttype = keys[i].key_data_type[1];
|
|
|
e3ffab |
+ ksc.ksdata[i].salt.data = (void *)keys[i].key_data_contents[1];
|
|
|
e3ffab |
+ ksc.ksdata[i].salt.length = keys[i].key_data_length[1];
|
|
|
e3ffab |
}
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
- rc = ber_printf(ber, "}}");
|
|
|
e3ffab |
- if (rc == -1) {
|
|
|
e3ffab |
- LOG_FATAL("Failed to terminate key buffer\n");
|
|
|
e3ffab |
- rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ bvp = calloc(1, sizeof(struct berval));
|
|
|
e3ffab |
+ if (!bvp) goto done;
|
|
|
e3ffab |
|
|
|
e3ffab |
- rc = ber_flatten(ber, &bvp);
|
|
|
e3ffab |
- if (rc == -1) {
|
|
|
e3ffab |
- LOG_FATAL("Failed to encode key buffer\n");
|
|
|
e3ffab |
- rc = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ ret = ipaasn1_enc_getktreply(kvno, &ksc,
|
|
|
e3ffab |
+ (void **)&bvp->bv_val, &bvp->bv_len);
|
|
|
e3ffab |
+ if (!ret) goto done;
|
|
|
e3ffab |
|
|
|
e3ffab |
rc = LDAP_SUCCESS;
|
|
|
e3ffab |
|
|
|
e3ffab |
done:
|
|
|
e3ffab |
+ for (int i = 0; i < ksc.nkeys; i ++) {
|
|
|
e3ffab |
+ free(ksc.ksdata[i].key.contents);
|
|
|
e3ffab |
+ }
|
|
|
e3ffab |
if (rc != LDAP_SUCCESS) {
|
|
|
e3ffab |
if (bvp) ber_bvfree(bvp);
|
|
|
e3ffab |
} else {
|
|
|
e3ffab |
*_bvp = bvp;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
- if (ber) ber_free(ber, 1);
|
|
|
e3ffab |
- free(plain.data);
|
|
|
e3ffab |
return rc;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
diff --git a/ipa-client/Makefile.am b/ipa-client/Makefile.am
|
|
|
e3ffab |
index 2df175e53b2a547acdad546db182b38011becd06..b9c7020f3b687b3c0030ed5166625e6ef07e2fa4 100644
|
|
|
e3ffab |
--- a/ipa-client/Makefile.am
|
|
|
e3ffab |
+++ b/ipa-client/Makefile.am
|
|
|
e3ffab |
@@ -14,11 +14,13 @@ export AM_CFLAGS
|
|
|
e3ffab |
|
|
|
e3ffab |
KRB5_UTIL_DIR=../util
|
|
|
e3ffab |
KRB5_UTIL_SRCS=$(KRB5_UTIL_DIR)/ipa_krb5.c
|
|
|
e3ffab |
+ASN1_UTIL_DIR=../asn1
|
|
|
e3ffab |
|
|
|
e3ffab |
AM_CPPFLAGS = \
|
|
|
e3ffab |
-I. \
|
|
|
e3ffab |
-I$(srcdir) \
|
|
|
e3ffab |
-I$(KRB5_UTIL_DIR) \
|
|
|
e3ffab |
+ -I$(ASN1_UTIL_DIR) \
|
|
|
e3ffab |
-DPREFIX=\""$(prefix)"\" \
|
|
|
e3ffab |
-DBINDIR=\""$(bindir)"\" \
|
|
|
e3ffab |
-DLIBDIR=\""$(libdir)"\" \
|
|
|
e3ffab |
@@ -45,6 +47,7 @@ ipa_getkeytab_SOURCES = \
|
|
|
e3ffab |
$(NULL)
|
|
|
e3ffab |
|
|
|
e3ffab |
ipa_getkeytab_LDADD = \
|
|
|
e3ffab |
+ ../asn1/libipaasn1.la \
|
|
|
e3ffab |
$(KRB5_LIBS) \
|
|
|
e3ffab |
$(OPENLDAP_LIBS) \
|
|
|
e3ffab |
$(SASL_LIBS) \
|
|
|
e3ffab |
@@ -80,6 +83,7 @@ ipa_join_LDADD = \
|
|
|
e3ffab |
$(NULL)
|
|
|
e3ffab |
|
|
|
e3ffab |
SUBDIRS = \
|
|
|
e3ffab |
+ ../asn1 \
|
|
|
e3ffab |
ipaclient \
|
|
|
e3ffab |
ipa-install \
|
|
|
e3ffab |
man \
|
|
|
e3ffab |
diff --git a/ipa-client/configure.ac b/ipa-client/configure.ac
|
|
|
e3ffab |
index 34625622d3e3bb64866b3b0b1a58d29e33f11a7d..78da8e6e413b8becbd4c75422abffb670050f446 100644
|
|
|
e3ffab |
--- a/ipa-client/configure.ac
|
|
|
e3ffab |
+++ b/ipa-client/configure.ac
|
|
|
e3ffab |
@@ -8,6 +8,7 @@ AC_PROG_LIBTOOL
|
|
|
e3ffab |
|
|
|
e3ffab |
AC_CONFIG_SRCDIR([ipaclient/__init__.py])
|
|
|
e3ffab |
AC_CONFIG_HEADERS([config.h])
|
|
|
e3ffab |
+AC_CONFIG_SUBDIRS([../asn1])
|
|
|
e3ffab |
|
|
|
e3ffab |
AM_INIT_AUTOMAKE([foreign])
|
|
|
e3ffab |
|
|
|
e3ffab |
@@ -205,6 +206,7 @@ dnl ---------------------------------------------------------------------------
|
|
|
e3ffab |
|
|
|
e3ffab |
AC_CONFIG_FILES([
|
|
|
e3ffab |
Makefile
|
|
|
e3ffab |
+ ../asn1/Makefile
|
|
|
e3ffab |
ipaclient/Makefile
|
|
|
e3ffab |
ipa-install/Makefile
|
|
|
e3ffab |
man/Makefile
|
|
|
e3ffab |
diff --git a/ipa-client/ipa-getkeytab.c b/ipa-client/ipa-getkeytab.c
|
|
|
e3ffab |
index bb43c333dca6560807a120103a1cb535fa87b76a..15255d6a33c8c298f138868ac545d4ebea415fe5 100644
|
|
|
e3ffab |
--- a/ipa-client/ipa-getkeytab.c
|
|
|
e3ffab |
+++ b/ipa-client/ipa-getkeytab.c
|
|
|
e3ffab |
@@ -40,6 +40,7 @@
|
|
|
e3ffab |
#include "config.h"
|
|
|
e3ffab |
|
|
|
e3ffab |
#include "ipa_krb5.h"
|
|
|
e3ffab |
+#include "ipa_asn1.h"
|
|
|
e3ffab |
#include "ipa-client-common.h"
|
|
|
e3ffab |
|
|
|
e3ffab |
static int ldap_sasl_interact(LDAP *ld, unsigned flags, void *priv_data, void *sit)
|
|
|
e3ffab |
@@ -295,14 +296,15 @@ done:
|
|
|
e3ffab |
return ret;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
-static BerElement *get_control_data(LDAPControl **list, const char *repoid)
|
|
|
e3ffab |
+static int find_control_data(LDAPControl **list, const char *repoid,
|
|
|
e3ffab |
+ struct berval *data)
|
|
|
e3ffab |
{
|
|
|
e3ffab |
LDAPControl *control = NULL;
|
|
|
e3ffab |
int i;
|
|
|
e3ffab |
|
|
|
e3ffab |
if (!list) {
|
|
|
e3ffab |
fprintf(stderr, _("Missing reply control list!\n"));
|
|
|
e3ffab |
- return NULL;
|
|
|
e3ffab |
+ return LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
for (i = 0; list[i]; i++) {
|
|
|
e3ffab |
@@ -312,10 +314,22 @@ static BerElement *get_control_data(LDAPControl **list, const char *repoid)
|
|
|
e3ffab |
}
|
|
|
e3ffab |
if (!control) {
|
|
|
e3ffab |
fprintf(stderr, _("Missing reply control!\n"));
|
|
|
e3ffab |
- return NULL;
|
|
|
e3ffab |
+ return LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
- return ber_init(&control->ldctl_value);
|
|
|
e3ffab |
+ *data = control->ldctl_value;
|
|
|
e3ffab |
+ return LDAP_SUCCESS;
|
|
|
e3ffab |
+}
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+static BerElement *get_control_data(LDAPControl **list, const char *repoid)
|
|
|
e3ffab |
+{
|
|
|
e3ffab |
+ struct berval data;
|
|
|
e3ffab |
+ int ret;
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ ret = find_control_data(list, repoid, &data);
|
|
|
e3ffab |
+ if (ret != LDAP_SUCCESS) return NULL;
|
|
|
e3ffab |
+
|
|
|
e3ffab |
+ return ber_init(&data);
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
static int ldap_set_keytab(krb5_context krbctx,
|
|
|
e3ffab |
@@ -435,124 +449,42 @@ error_out:
|
|
|
e3ffab |
return -1;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
-/* Format of getkeytab control
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * KeytabGetRequest ::= CHOICE {
|
|
|
e3ffab |
- * newkeys [0] Newkeys,
|
|
|
e3ffab |
- * curkeys [1] CurrentKeys,
|
|
|
e3ffab |
- * reply [2] Reply
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * NewKeys ::= SEQUENCE {
|
|
|
e3ffab |
- * serviceIdentity [0] OCTET STRING,
|
|
|
e3ffab |
- * enctypes [1] SEQUENCE OF Int16
|
|
|
e3ffab |
- * password [2] OCTET STRING OPTIONAL,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * CurrentKeys ::= SEQUENCE {
|
|
|
e3ffab |
- * serviceIdentity [0] OCTET STRING,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * Reply ::= SEQUENCE {
|
|
|
e3ffab |
- * new_kvno Int32
|
|
|
e3ffab |
- * keys SEQUENCE OF KrbKey,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * KrbKey ::= SEQUENCE {
|
|
|
e3ffab |
- * key [0] EncryptionKey,
|
|
|
e3ffab |
- * salt [1] KrbSalt OPTIONAL,
|
|
|
e3ffab |
- * s2kparams [2] OCTET STRING OPTIONAL,
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * EncryptionKey ::= SEQUENCE {
|
|
|
e3ffab |
- * keytype [0] Int32,
|
|
|
e3ffab |
- * keyvalue [1] OCTET STRING
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- *
|
|
|
e3ffab |
- * KrbSalt ::= SEQUENCE {
|
|
|
e3ffab |
- * type [0] Int32,
|
|
|
e3ffab |
- * salt [1] OCTET STRING
|
|
|
e3ffab |
- * }
|
|
|
e3ffab |
- */
|
|
|
e3ffab |
-
|
|
|
e3ffab |
-#define GK_REQUEST_NEWKEYS (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
|
|
|
e3ffab |
-#define GK_REQUEST_CURKEYS (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREQ_SVCNAME_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREQ_ENCTYPES_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
|
|
|
e3ffab |
-#define GKREQ_PASSWORD_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
|
|
|
e3ffab |
-
|
|
|
e3ffab |
+/* use asn1c generated code to fill up control */
|
|
|
e3ffab |
static struct berval *create_getkeytab_control(const char *svc_princ, bool gen,
|
|
|
e3ffab |
const char *password,
|
|
|
e3ffab |
struct krb_key_salt *encsalts,
|
|
|
e3ffab |
int num_encsalts)
|
|
|
e3ffab |
{
|
|
|
e3ffab |
- struct berval *bval = NULL;
|
|
|
e3ffab |
- BerElement *be;
|
|
|
e3ffab |
- ber_tag_t ctag;
|
|
|
e3ffab |
- ber_int_t e;
|
|
|
e3ffab |
- int ret, i;
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- be = ber_alloc_t(LBER_USE_DER);
|
|
|
e3ffab |
- if (!be) {
|
|
|
e3ffab |
- return NULL;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- if (gen) {
|
|
|
e3ffab |
- ctag = GK_REQUEST_NEWKEYS;
|
|
|
e3ffab |
- } else {
|
|
|
e3ffab |
- ctag = GK_REQUEST_CURKEYS;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- ret = ber_printf(be, "t{ts", ctag, GKREQ_SVCNAME_TAG, svc_princ);
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ struct berval *result = NULL;
|
|
|
e3ffab |
+ void *buffer = NULL;
|
|
|
e3ffab |
+ size_t buflen;
|
|
|
e3ffab |
+ long ets[num_encsalts];
|
|
|
e3ffab |
+ bool ret;
|
|
|
e3ffab |
+ int i;
|
|
|
e3ffab |
|
|
|
e3ffab |
if (gen) {
|
|
|
e3ffab |
- ret = ber_printf(be, "t{", GKREQ_ENCTYPES_TAG);
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
for (i = 0; i < num_encsalts; i++) {
|
|
|
e3ffab |
- e = encsalts[i].enctype;
|
|
|
e3ffab |
- ret = ber_printf(be, "i", e);
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- ret = ber_printf(be, "}");
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- if (password) {
|
|
|
e3ffab |
- ret = ber_printf(be, "ts", GKREQ_PASSWORD_TAG, password);
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ ets[i] = encsalts[i].enctype;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
}
|
|
|
e3ffab |
+ ret = ipaasn1_enc_getkt(gen, svc_princ,
|
|
|
e3ffab |
+ password, ets, num_encsalts,
|
|
|
e3ffab |
+ &buffer, &buflen);
|
|
|
e3ffab |
+ if (!ret) goto done;
|
|
|
e3ffab |
|
|
|
e3ffab |
- ret = ber_printf(be, "}");
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ result = malloc(sizeof(struct berval));
|
|
|
e3ffab |
+ if (!result) goto done;
|
|
|
e3ffab |
|
|
|
e3ffab |
- ret = ber_flatten(be, &bval);
|
|
|
e3ffab |
- if (ret == -1) {
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ result->bv_val = buffer;
|
|
|
e3ffab |
+ result->bv_len = buflen;
|
|
|
e3ffab |
|
|
|
e3ffab |
done:
|
|
|
e3ffab |
- ber_free(be, 1);
|
|
|
e3ffab |
- return bval;
|
|
|
e3ffab |
+ if (result == NULL) {
|
|
|
e3ffab |
+ if (buffer) {
|
|
|
e3ffab |
+ free(buffer);
|
|
|
e3ffab |
+ }
|
|
|
e3ffab |
+ }
|
|
|
e3ffab |
+ return result;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
#define GK_REPLY_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
|
|
|
e3ffab |
@@ -571,13 +503,8 @@ static int ldap_get_keytab(krb5_context krbctx, bool generate, char *password,
|
|
|
e3ffab |
struct berval *control = NULL;
|
|
|
e3ffab |
LDAP *ld = NULL;
|
|
|
e3ffab |
LDAPControl **srvctrl = NULL;
|
|
|
e3ffab |
- BerElement *ber = NULL;
|
|
|
e3ffab |
- ber_tag_t rtag;
|
|
|
e3ffab |
- ber_tag_t ctag;
|
|
|
e3ffab |
- ber_len_t tlen;
|
|
|
e3ffab |
- ber_int_t vno;
|
|
|
e3ffab |
- ber_int_t tint;
|
|
|
e3ffab |
- struct berval tbval;
|
|
|
e3ffab |
+ struct berval data;
|
|
|
e3ffab |
+ bool res;
|
|
|
e3ffab |
int ret;
|
|
|
e3ffab |
|
|
|
e3ffab |
*err_msg = NULL;
|
|
|
e3ffab |
@@ -609,98 +536,19 @@ static int ldap_get_keytab(krb5_context krbctx, bool generate, char *password,
|
|
|
e3ffab |
goto done;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
- ber = get_control_data(srvctrl, KEYTAB_GET_OID);
|
|
|
e3ffab |
- if (!ber) {
|
|
|
e3ffab |
- *err_msg = _("Failed to find or parse reply control!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- rtag = ber_scanf(ber, "t{i{", &ctag, &vno;;
|
|
|
e3ffab |
- if (rtag == LBER_ERROR || ctag != GK_REPLY_TAG) {
|
|
|
e3ffab |
- *err_msg = _("Failed to parse control head!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- keys->nkeys = 0;
|
|
|
e3ffab |
- keys->ksdata = NULL;
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- rtag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- for (int i = 0; rtag == LBER_SEQUENCE; i++) {
|
|
|
e3ffab |
- if ((i % 5) == 0) {
|
|
|
e3ffab |
- struct krb_key_salt *ksdata;
|
|
|
e3ffab |
- ksdata = realloc(keys->ksdata,
|
|
|
e3ffab |
- (i + 5) * sizeof(struct krb_key_salt));
|
|
|
e3ffab |
- if (!ksdata) {
|
|
|
e3ffab |
- *err_msg = _("Out of memory!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- keys->ksdata = ksdata;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- memset(&keys->ksdata[i], 0, sizeof(struct krb_key_salt));
|
|
|
e3ffab |
- keys->nkeys = i + 1;
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- rtag = ber_scanf(ber, "{t{io}", &ctag, &tint, &tbval);
|
|
|
e3ffab |
- if (rtag == LBER_ERROR || ctag != GKREP_KEY_TAG) {
|
|
|
e3ffab |
- *err_msg = _("Failed to parse enctype in key data!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- keys->ksdata[i].enctype = tint;
|
|
|
e3ffab |
- keys->ksdata[i].key.enctype = tint;
|
|
|
e3ffab |
- keys->ksdata[i].key.length = tbval.bv_len;
|
|
|
e3ffab |
- keys->ksdata[i].key.contents = malloc(tbval.bv_len);
|
|
|
e3ffab |
- if (!keys->ksdata[i].key.contents) {
|
|
|
e3ffab |
- *err_msg = _("Out of memory!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- memcpy(keys->ksdata[i].key.contents, tbval.bv_val, tbval.bv_len);
|
|
|
e3ffab |
- ber_memfree(tbval.bv_val);
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- rtag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- if (rtag == GKREP_SALT_TAG) {
|
|
|
e3ffab |
- rtag = ber_scanf(ber, "t{io}", &ctag, &tint, &tbval);
|
|
|
e3ffab |
- if (rtag == LBER_ERROR) {
|
|
|
e3ffab |
- *err_msg = _("Failed to parse salt in key data!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- keys->ksdata[i].salttype = tint;
|
|
|
e3ffab |
- keys->ksdata[i].salt.length = tbval.bv_len;
|
|
|
e3ffab |
- keys->ksdata[i].salt.data = malloc(tbval.bv_len);
|
|
|
e3ffab |
- if (!keys->ksdata[i].salt.data) {
|
|
|
e3ffab |
- *err_msg = _("Out of memory!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- memcpy(keys->ksdata[i].salt.data, tbval.bv_val, tbval.bv_len);
|
|
|
e3ffab |
- ber_memfree(tbval.bv_val);
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
- rtag = ber_scanf(ber, "}");
|
|
|
e3ffab |
- if (rtag == LBER_ERROR) {
|
|
|
e3ffab |
- *err_msg = _("Failed to parse ending of key data!\n");
|
|
|
e3ffab |
- ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
- goto done;
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
-
|
|
|
e3ffab |
- rtag = ber_peek_tag(ber, &tlen);
|
|
|
e3ffab |
- }
|
|
|
e3ffab |
+ ret = find_control_data(srvctrl, KEYTAB_GET_OID, &data);
|
|
|
e3ffab |
+ if (ret != LDAP_SUCCESS) goto done;
|
|
|
e3ffab |
|
|
|
e3ffab |
- rtag = ber_scanf(ber, "}}");
|
|
|
e3ffab |
- if (rtag == LBER_ERROR) {
|
|
|
e3ffab |
- *err_msg = _("Failed to parse ending of control!\n");
|
|
|
e3ffab |
+ res = ipaasn1_dec_getktreply(data.bv_val, data.bv_len, kvno, keys);
|
|
|
e3ffab |
+ if (!res) {
|
|
|
e3ffab |
+ *err_msg = _("Failed to decode control reply!\n");
|
|
|
e3ffab |
ret = LDAP_OPERATIONS_ERROR;
|
|
|
e3ffab |
goto done;
|
|
|
e3ffab |
}
|
|
|
e3ffab |
|
|
|
e3ffab |
- *kvno = vno;
|
|
|
e3ffab |
ret = LDAP_SUCCESS;
|
|
|
e3ffab |
|
|
|
e3ffab |
done:
|
|
|
e3ffab |
- if (ber) ber_free(ber, 1);
|
|
|
e3ffab |
if (ld) ldap_unbind_ext(ld, NULL, NULL);
|
|
|
e3ffab |
if (control) ber_bvfree(control);
|
|
|
e3ffab |
free(es);
|
|
|
e3ffab |
--
|
|
|
e3ffab |
2.1.0
|
|
|
e3ffab |
|