aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2022-02-24 01:24:23 -0500
committerGreg Hudson <ghudson@mit.edu>2022-05-18 17:10:42 -0400
commitf81fda346f07c8d67e549cb90bcbdc3c24e5dd5d (patch)
treeadce5a14ee6db275e7d30125584c91909a704fa8
parent151004b6364e232e8195d19b189f9a682589a094 (diff)
downloadkrb5-f81fda346f07c8d67e549cb90bcbdc3c24e5dd5d.zip
krb5-f81fda346f07c8d67e549cb90bcbdc3c24e5dd5d.tar.gz
krb5-f81fda346f07c8d67e549cb90bcbdc3c24e5dd5d.tar.bz2
Refactor and move CCAPI utility functions
Move the CCAPI credential transiation functions up a layer and refactor them to current practices.
-rw-r--r--src/lib/krb5/ccache/Makefile.in7
-rw-r--r--src/lib/krb5/ccache/ccapi/Makefile.in5
-rw-r--r--src/lib/krb5/ccache/ccapi/deps6
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc.c11
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.c528
-rw-r--r--src/lib/krb5/ccache/ccapi/stdcc_util.h31
-rw-r--r--src/lib/krb5/ccache/ccapi_util.c425
-rw-r--r--src/lib/krb5/ccache/ccapi_util.h50
-rw-r--r--src/lib/krb5/ccache/deps12
9 files changed, 500 insertions, 575 deletions
diff --git a/src/lib/krb5/ccache/Makefile.in b/src/lib/krb5/ccache/Makefile.in
index eaff6d2..9d29ec5 100644
--- a/src/lib/krb5/ccache/Makefile.in
+++ b/src/lib/krb5/ccache/Makefile.in
@@ -25,6 +25,7 @@ KCMRPC_OBJ = $(KCMRPC_OBJ-@OSX@)
STLIBOBJS= \
+ ccapi_util.o \
ccbase.o \
cccopy.o \
cccursor.o \
@@ -44,7 +45,8 @@ STLIBOBJS= \
ccfns.o \
$(KCMRPC_OBJ)
-OBJS= $(OUTPRE)ccbase.$(OBJEXT) \
+OBJS= $(OUTPRE)ccapi_util.$(OBJEXT) \
+ $(OUTPRE)ccbase.$(OBJEXT) \
$(OUTPRE)cccopy.$(OBJEXT) \
$(OUTPRE)cccursor.$(OBJEXT) \
$(OUTPRE)ccdefault.$(OBJEXT) \
@@ -63,7 +65,8 @@ OBJS= $(OUTPRE)ccbase.$(OBJEXT) \
$(OUTPRE)ccfns.$(OBJEXT) \
$(MSLSA_OBJ)
-SRCS= $(srcdir)/ccbase.c \
+SRCS= $(srcdir)/ccapi_util.c \
+ $(srcdir)/ccbase.c \
$(srcdir)/cccopy.c \
$(srcdir)/cccursor.c \
$(srcdir)/ccdefault.c \
diff --git a/src/lib/krb5/ccache/ccapi/Makefile.in b/src/lib/krb5/ccache/ccapi/Makefile.in
index c842b49..2e379e4 100644
--- a/src/lib/krb5/ccache/ccapi/Makefile.in
+++ b/src/lib/krb5/ccache/ccapi/Makefile.in
@@ -11,12 +11,11 @@ DEFINES= -DUSE_CCAPI
STLIBOBJS = \
stdcc.o \
- stdcc_util.o \
winccld.o
-OBJS = $(OUTPRE)stdcc.$(OBJEXT) $(OUTPRE)stdcc_util.$(OBJEXT) $(OUTPRE)winccld.$(OBJEXT)
+OBJS = $(OUTPRE)stdcc.$(OBJEXT) $(OUTPRE)winccld.$(OBJEXT)
-SRCS = $(srcdir)/stdcc.c $(srcdir)/stdcc_util.c $(srcdir)/winccld.c
+SRCS = $(srcdir)/stdcc.c $(srcdir)/winccld.c
##DOS##LIBOBJS = $(OBJS)
diff --git a/src/lib/krb5/ccache/ccapi/deps b/src/lib/krb5/ccache/ccapi/deps
index 7df6d68..c3ef7d0 100644
--- a/src/lib/krb5/ccache/ccapi/deps
+++ b/src/lib/krb5/ccache/ccapi/deps
@@ -10,9 +10,5 @@ stdcc.so stdcc.po $(OUTPRE)stdcc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
$(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/locate_plugin.h \
$(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h stdcc.c stdcc.h stdcc_util.h
-stdcc_util.so stdcc_util.po $(OUTPRE)stdcc_util.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
- $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
- $(top_srcdir)/include/krb5.h stdcc_util.c stdcc_util.h
+ $(top_srcdir)/include/socket-utils.h stdcc.c stdcc.h
winccld.so winccld.po $(OUTPRE)winccld.$(OBJEXT): winccld.c
diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c
index bb13eb5..427b329 100644
--- a/src/lib/krb5/ccache/ccapi/stdcc.c
+++ b/src/lib/krb5/ccache/ccapi/stdcc.c
@@ -33,8 +33,8 @@
#include "k5-int.h"
#include "../cc-int.h"
+#include "../ccapi_util.h"
#include "stdcc.h"
-#include "stdcc_util.h"
#include "string.h"
#include <stdio.h>
@@ -464,7 +464,7 @@ krb5_stdccv3_store (krb5_context context, krb5_ccache id, krb5_creds *creds )
if (!err) {
/* copy the fields from the almost identical structures */
- err = copy_krb5_creds_to_cc_cred_union (context, creds, &cred_union);
+ err = k5_krb5_to_ccapi_creds (context, creds, &cred_union);
}
if (!err) {
@@ -475,7 +475,7 @@ krb5_stdccv3_store (krb5_context context, krb5_ccache id, krb5_creds *creds )
cache_changed();
}
- if (cred_union) { cred_union_release (cred_union); }
+ if (cred_union) { k5_release_ccapi_cred (cred_union); }
return cc_err_xlate (err);
}
@@ -537,7 +537,7 @@ krb5_stdccv3_next_cred (krb5_context context,
err = cc_credentials_iterator_next (iterator, &credentials);
if (!err && (credentials->data->version == cc_credentials_v5)) {
- copy_cc_cred_union_to_krb5_creds(context, credentials->data, creds);
+ err = k5_ccapi_to_krb5_creds (context, credentials->data, creds);
break;
}
}
@@ -787,8 +787,7 @@ krb5_stdccv3_remove (krb5_context context,
if (!err && (credentials->data->version == cc_credentials_v5)) {
krb5_creds creds;
- err = copy_cc_cred_union_to_krb5_creds(context,
- credentials->data, &creds);
+ err = k5_ccapi_to_krb5_creds (context, credentials->data, &creds);
if (!err) {
found = krb5int_cc_creds_match_request(context,
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c
deleted file mode 100644
index 91f2bd5..0000000
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * stdcc_util.c
- * utility functions used in implementing the ccache api for krb5
- * not publicly exported
- * Frank Dabek, July 1998
- */
-
-#if defined(_WIN32) || defined(USE_CCAPI)
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#if defined(_WIN32)
-#include <malloc.h>
-#endif
-
-#include "k5-int.h"
-#include "stdcc_util.h"
-#ifdef _WIN32 /* it's part of krb5.h everywhere else */
-#include "kv5m_err.h"
-#endif
-
-#define fieldSize 255
-
-static void
-free_cc_array (cc_data **io_cc_array)
-{
- if (io_cc_array) {
- unsigned int i;
-
- for (i = 0; io_cc_array[i]; i++) {
- if (io_cc_array[i]->data) { free (io_cc_array[i]->data); }
- free (io_cc_array[i]);
- }
- free (io_cc_array);
- }
-}
-
-static krb5_error_code
-copy_cc_array_to_addresses (krb5_context in_context,
- cc_data **in_cc_array,
- krb5_address ***out_addresses)
-{
- krb5_error_code err = 0;
-
- if (in_cc_array == NULL) {
- *out_addresses = NULL;
-
- } else {
- unsigned int count, i;
- krb5_address **addresses = NULL;
-
- /* get length of array */
- for (count = 0; in_cc_array[count]; count++);
- addresses = (krb5_address **) malloc (sizeof (*addresses) * (count + 1));
- if (!addresses) { err = KRB5_CC_NOMEM; }
-
- for (i = 0; !err && i < count; i++) {
- addresses[i] = (krb5_address *) malloc (sizeof (krb5_address));
- if (!addresses[i]) { err = KRB5_CC_NOMEM; }
-
- if (!err) {
- addresses[i]->contents = (krb5_octet *) malloc (sizeof (krb5_octet) *
- in_cc_array[i]->length);
- if (!addresses[i]->contents) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- addresses[i]->magic = KV5M_ADDRESS;
- addresses[i]->addrtype = in_cc_array[i]->type;
- addresses[i]->length = in_cc_array[i]->length;
- memcpy (addresses[i]->contents,
- in_cc_array[i]->data, in_cc_array[i]->length);
- }
- }
-
- if (!err) {
- addresses[i] = NULL; /* terminator */
- *out_addresses = addresses;
- addresses = NULL;
- }
-
- if (addresses) { krb5_free_addresses (in_context, addresses); }
- }
-
- return err;
-}
-
-static krb5_error_code
-copy_cc_array_to_authdata (krb5_context in_context,
- cc_data **in_cc_array,
- krb5_authdata ***out_authdata)
-{
- krb5_error_code err = 0;
-
- if (in_cc_array == NULL) {
- *out_authdata = NULL;
-
- } else {
- unsigned int count, i;
- krb5_authdata **authdata = NULL;
-
- /* get length of array */
- for (count = 0; in_cc_array[count]; count++);
- authdata = (krb5_authdata **) malloc (sizeof (*authdata) * (count + 1));
- if (!authdata) { err = KRB5_CC_NOMEM; }
-
- for (i = 0; !err && i < count; i++) {
- authdata[i] = (krb5_authdata *) malloc (sizeof (krb5_authdata));
- if (!authdata[i]) { err = KRB5_CC_NOMEM; }
-
- if (!err) {
- authdata[i]->contents = (krb5_octet *) malloc (sizeof (krb5_octet) *
- in_cc_array[i]->length);
- if (!authdata[i]->contents) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- authdata[i]->magic = KV5M_AUTHDATA;
- authdata[i]->ad_type = in_cc_array[i]->type;
- authdata[i]->length = in_cc_array[i]->length;
- memcpy (authdata[i]->contents,
- in_cc_array[i]->data, in_cc_array[i]->length);
- }
- }
-
- if (!err) {
- authdata[i] = NULL; /* terminator */
- *out_authdata = authdata;
- authdata = NULL;
- }
-
- if (authdata) { krb5_free_authdata (in_context, authdata); }
- }
-
- return err;
-}
-
-static krb5_error_code
-copy_addresses_to_cc_array (krb5_context in_context,
- krb5_address **in_addresses,
- cc_data ***out_cc_array)
-{
- krb5_error_code err = 0;
-
- if (in_addresses == NULL) {
- *out_cc_array = NULL;
-
- } else {
- unsigned int count, i;
- cc_data **cc_array = NULL;
-
- /* get length of array */
- for (count = 0; in_addresses[count]; count++);
- cc_array = (cc_data **) malloc (sizeof (*cc_array) * (count + 1));
- if (!cc_array) { err = KRB5_CC_NOMEM; }
-
- for (i = 0; !err && i < count; i++) {
- cc_array[i] = (cc_data *) malloc (sizeof (cc_data));
- if (!cc_array[i]) { err = KRB5_CC_NOMEM; }
-
- if (!err) {
- cc_array[i]->data = malloc (in_addresses[i]->length);
- if (!cc_array[i]->data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- cc_array[i]->type = in_addresses[i]->addrtype;
- cc_array[i]->length = in_addresses[i]->length;
- memcpy (cc_array[i]->data, in_addresses[i]->contents, in_addresses[i]->length);
- }
- }
-
- if (!err) {
- cc_array[i] = NULL; /* terminator */
- *out_cc_array = cc_array;
- cc_array = NULL;
- }
-
- if (cc_array) { free_cc_array (cc_array); }
- }
-
-
- return err;
-}
-
-static krb5_error_code
-copy_authdata_to_cc_array (krb5_context in_context,
- krb5_authdata **in_authdata,
- cc_data ***out_cc_array)
-{
- krb5_error_code err = 0;
-
- if (in_authdata == NULL) {
- *out_cc_array = NULL;
-
- } else {
- unsigned int count, i;
- cc_data **cc_array = NULL;
-
- /* get length of array */
- for (count = 0; in_authdata[count]; count++);
- cc_array = (cc_data **) malloc (sizeof (*cc_array) * (count + 1));
- if (!cc_array) { err = KRB5_CC_NOMEM; }
-
- for (i = 0; !err && i < count; i++) {
- cc_array[i] = (cc_data *) malloc (sizeof (cc_data));
- if (!cc_array[i]) { err = KRB5_CC_NOMEM; }
-
- if (!err) {
- cc_array[i]->data = malloc (in_authdata[i]->length);
- if (!cc_array[i]->data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- cc_array[i]->type = in_authdata[i]->ad_type;
- cc_array[i]->length = in_authdata[i]->length;
- memcpy (cc_array[i]->data, in_authdata[i]->contents, in_authdata[i]->length);
- }
- }
-
- if (!err) {
- cc_array[i] = NULL; /* terminator */
- *out_cc_array = cc_array;
- cc_array = NULL;
- }
-
- if (cc_array) { free_cc_array (cc_array); }
- }
-
-
- return err;
-}
-
-
-/*
- * copy_cc_credentials_to_krb5_creds
- * - allocate an empty k5 style ticket and copy info from the cc_creds ticket
- */
-
-krb5_error_code
-copy_cc_cred_union_to_krb5_creds (krb5_context in_context,
- const cc_credentials_union *in_cred_union,
- krb5_creds *out_creds)
-{
- krb5_error_code err = 0;
- cc_credentials_v5_t *cv5 = NULL;
- krb5_int32 offset_seconds = 0, offset_microseconds = 0;
- krb5_principal client = NULL;
- krb5_principal server = NULL;
- char *ticket_data = NULL;
- char *second_ticket_data = NULL;
- unsigned char *keyblock_contents = NULL;
- krb5_address **addresses = NULL;
- krb5_authdata **authdata = NULL;
-
- if (in_cred_union->version != cc_credentials_v5) {
- err = KRB5_CC_NOT_KTYPE;
- } else {
- cv5 = in_cred_union->credentials.credentials_v5;
- }
-
-#if TARGET_OS_MAC
- if (!err) {
- err = krb5_get_time_offsets (in_context, &offset_seconds, &offset_microseconds);
- }
-#endif
-
- if (!err) {
- err = krb5_parse_name (in_context, cv5->client, &client);
- }
-
- if (!err) {
- err = krb5_parse_name (in_context, cv5->server, &server);
- }
-
- if (!err && cv5->keyblock.data) {
- keyblock_contents = (unsigned char *) malloc (cv5->keyblock.length);
- if (!keyblock_contents) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err && cv5->ticket.data) {
- ticket_data = (char *) malloc (cv5->ticket.length);
- if (!ticket_data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err && cv5->second_ticket.data) {
- second_ticket_data = (char *) malloc (cv5->second_ticket.length);
- if (!second_ticket_data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- /* addresses */
- err = copy_cc_array_to_addresses (in_context, cv5->addresses, &addresses);
- }
-
- if (!err) {
- /* authdata */
- err = copy_cc_array_to_authdata (in_context, cv5->authdata, &authdata);
- }
-
- if (!err) {
- /* principals */
- out_creds->client = client;
- client = NULL;
- out_creds->server = server;
- server = NULL;
-
- /* copy keyblock */
- if (cv5->keyblock.data) {
- memcpy (keyblock_contents, cv5->keyblock.data, cv5->keyblock.length);
- }
- out_creds->keyblock.enctype = cv5->keyblock.type;
- out_creds->keyblock.length = cv5->keyblock.length;
- out_creds->keyblock.contents = keyblock_contents;
- keyblock_contents = NULL;
-
- /* copy times */
- out_creds->times.authtime = ts_incr(cv5->authtime, offset_seconds);
- out_creds->times.starttime = ts_incr(cv5->starttime, offset_seconds);
- out_creds->times.endtime = ts_incr(cv5->endtime, offset_seconds);
- out_creds->times.renew_till = ts_incr(cv5->renew_till, offset_seconds);
- out_creds->is_skey = cv5->is_skey;
- out_creds->ticket_flags = cv5->ticket_flags;
-
- /* first ticket */
- if (cv5->ticket.data) {
- memcpy(ticket_data, cv5->ticket.data, cv5->ticket.length);
- }
- out_creds->ticket.length = cv5->ticket.length;
- out_creds->ticket.data = ticket_data;
- ticket_data = NULL;
-
- /* second ticket */
- if (cv5->second_ticket.data) {
- memcpy(second_ticket_data, cv5->second_ticket.data, cv5->second_ticket.length);
- }
- out_creds->second_ticket.length = cv5->second_ticket.length;
- out_creds->second_ticket.data = second_ticket_data;
- second_ticket_data = NULL;
-
- out_creds->addresses = addresses;
- addresses = NULL;
-
- out_creds->authdata = authdata;
- authdata = NULL;
-
- /* zero out magic number */
- out_creds->magic = 0;
- }
-
- if (addresses) { krb5_free_addresses (in_context, addresses); }
- if (authdata) { krb5_free_authdata (in_context, authdata); }
- if (keyblock_contents) { free (keyblock_contents); }
- if (ticket_data) { free (ticket_data); }
- if (second_ticket_data) { free (second_ticket_data); }
- if (client) { krb5_free_principal (in_context, client); }
- if (server) { krb5_free_principal (in_context, server); }
-
- return err;
-}
-
-/*
- * copy_krb5_creds_to_cc_credentials
- * - analogous to above but in the reverse direction
- */
-krb5_error_code
-copy_krb5_creds_to_cc_cred_union (krb5_context in_context,
- krb5_creds *in_creds,
- cc_credentials_union **out_cred_union)
-{
- krb5_error_code err = 0;
- cc_credentials_union *cred_union = NULL;
- cc_credentials_v5_t *cv5 = NULL;
- char *client = NULL;
- char *server = NULL;
- unsigned char *ticket_data = NULL;
- unsigned char *second_ticket_data = NULL;
- unsigned char *keyblock_data = NULL;
- krb5_int32 offset_seconds = 0, offset_microseconds = 0;
- cc_data **cc_address_array = NULL;
- cc_data **cc_authdata_array = NULL;
-
- if (out_cred_union == NULL) { err = KRB5_CC_NOMEM; }
-
-#if TARGET_OS_MAC
- if (!err) {
- err = krb5_get_time_offsets (in_context, &offset_seconds, &offset_microseconds);
- }
-#endif
-
- if (!err) {
- cred_union = (cc_credentials_union *) malloc (sizeof (*cred_union));
- if (!cred_union) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- cv5 = (cc_credentials_v5_t *) malloc (sizeof (*cv5));
- if (!cv5) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- err = krb5_unparse_name (in_context, in_creds->client, &client);
- }
-
- if (!err) {
- err = krb5_unparse_name (in_context, in_creds->server, &server);
- }
-
- if (!err && in_creds->keyblock.contents) {
- keyblock_data = (unsigned char *) malloc (in_creds->keyblock.length);
- if (!keyblock_data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err && in_creds->ticket.data) {
- ticket_data = (unsigned char *) malloc (in_creds->ticket.length);
- if (!ticket_data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err && in_creds->second_ticket.data) {
- second_ticket_data = (unsigned char *) malloc (in_creds->second_ticket.length);
- if (!second_ticket_data) { err = KRB5_CC_NOMEM; }
- }
-
- if (!err) {
- err = copy_addresses_to_cc_array (in_context, in_creds->addresses, &cc_address_array);
- }
-
- if (!err) {
- err = copy_authdata_to_cc_array (in_context, in_creds->authdata, &cc_authdata_array);
- }
-
- if (!err) {
- /* principals */
- cv5->client = client;
- client = NULL;
- cv5->server = server;
- server = NULL;
-
- /* copy more fields */
- if (in_creds->keyblock.contents) {
- memcpy(keyblock_data, in_creds->keyblock.contents, in_creds->keyblock.length);
- }
- cv5->keyblock.type = in_creds->keyblock.enctype;
- cv5->keyblock.length = in_creds->keyblock.length;
- cv5->keyblock.data = keyblock_data;
- keyblock_data = NULL;
-
- cv5->authtime = ts_incr(in_creds->times.authtime, -offset_seconds);
- cv5->starttime = ts_incr(in_creds->times.starttime, -offset_seconds);
- cv5->endtime = ts_incr(in_creds->times.endtime, -offset_seconds);
- cv5->renew_till = ts_incr(in_creds->times.renew_till, -offset_seconds);
- cv5->is_skey = in_creds->is_skey;
- cv5->ticket_flags = in_creds->ticket_flags;
-
- if (in_creds->ticket.data) {
- memcpy (ticket_data, in_creds->ticket.data, in_creds->ticket.length);
- }
- cv5->ticket.length = in_creds->ticket.length;
- cv5->ticket.data = ticket_data;
- ticket_data = NULL;
-
- if (in_creds->second_ticket.data) {
- memcpy (second_ticket_data, in_creds->second_ticket.data, in_creds->second_ticket.length);
- }
- cv5->second_ticket.length = in_creds->second_ticket.length;
- cv5->second_ticket.data = second_ticket_data;
- second_ticket_data = NULL;
-
- cv5->addresses = cc_address_array;
- cc_address_array = NULL;
-
- cv5->authdata = cc_authdata_array;
- cc_authdata_array = NULL;
-
- /* Set up the structures to return to the caller */
- cred_union->version = cc_credentials_v5;
- cred_union->credentials.credentials_v5 = cv5;
- cv5 = NULL;
-
- *out_cred_union = cred_union;
- cred_union = NULL;
- }
-
- if (cc_address_array) { free_cc_array (cc_address_array); }
- if (cc_authdata_array) { free_cc_array (cc_authdata_array); }
- if (keyblock_data) { free (keyblock_data); }
- if (ticket_data) { free (ticket_data); }
- if (second_ticket_data) { free (second_ticket_data); }
- if (client) { krb5_free_unparsed_name (in_context, client); }
- if (server) { krb5_free_unparsed_name (in_context, server); }
- if (cv5) { free (cv5); }
- if (cred_union) { free (cred_union); }
-
- return err;
-}
-
-krb5_error_code
-cred_union_release (cc_credentials_union *in_cred_union)
-{
- if (in_cred_union) {
- if (in_cred_union->version == cc_credentials_v5 &&
- in_cred_union->credentials.credentials_v5) {
- cc_credentials_v5_t *cv5 = in_cred_union->credentials.credentials_v5;
-
- /* should use krb5_free_unparsed_name but we have no context */
- if (cv5->client) { free (cv5->client); }
- if (cv5->server) { free (cv5->server); }
-
- if (cv5->keyblock.data) { free (cv5->keyblock.data); }
- if (cv5->ticket.data) { free (cv5->ticket.data); }
- if (cv5->second_ticket.data) { free (cv5->second_ticket.data); }
-
- free_cc_array (cv5->addresses);
- free_cc_array (cv5->authdata);
-
- free (cv5);
-
- }
- free ((cc_credentials_union *) in_cred_union);
- }
-
- return 0;
-}
-
-#endif /* defined(_WIN32) || defined(USE_CCAPI) */
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h
deleted file mode 100644
index 34e438d..0000000
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* stdcc_util.h
- *
- * Frank Dabek, July 1998
- */
-
-#if defined(_WIN32) || defined(USE_CCAPI)
-
-#include "autoconf.h"
-
-#include <CredentialsCache.h>
-
-#include "krb5.h"
-
-/* prototypes for private functions declared in stdcc_util.c */
-krb5_error_code
-copy_cc_cred_union_to_krb5_creds (krb5_context in_context,
- const cc_credentials_union *in_cred_union,
- krb5_creds *out_creds);
-krb5_error_code
-copy_krb5_creds_to_cc_cred_union (krb5_context in_context,
- krb5_creds *in_creds,
- cc_credentials_union **out_cred_union);
-
-krb5_error_code
-cred_union_release (cc_credentials_union *in_cred_union);
-
-#define kAddressArray 4
-#define kAuthDataArray 5
-
-#endif /* defined(_WIN32) || defined(USE_CCAPI) */
diff --git a/src/lib/krb5/ccache/ccapi_util.c b/src/lib/krb5/ccache/ccapi_util.c
new file mode 100644
index 0000000..76f686c
--- /dev/null
+++ b/src/lib/krb5/ccache/ccapi_util.c
@@ -0,0 +1,425 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/krb5/ccache/ccapi_util.c - conversion functions for CCAPI creds */
+/*
+ * Copyright (C) 2022 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cc-int.h"
+#include "ccapi_util.h"
+
+#if defined(USE_CCAPI)
+
+static void
+free_cc_data_list(cc_data **list)
+{
+ size_t i;
+
+ for (i = 0; list != NULL && list[i] != NULL; i++) {
+ free(list[i]->data);
+ free(list[i]);
+ }
+ free(list);
+}
+
+static krb5_error_code
+cc_data_list_to_addresses(krb5_context context, cc_data **list,
+ krb5_address ***addrs_out)
+{
+ krb5_error_code ret;
+ size_t count, i;
+ krb5_address **addrs = NULL;
+
+ *addrs_out = NULL;
+ if (list == NULL)
+ return 0;
+
+ for (count = 0; list[count]; count++);
+ addrs = k5calloc(count + 1, sizeof(*addrs), &ret);
+ if (addrs == NULL)
+ return ret;
+
+ for (i = 0; i < count; i++) {
+ addrs[i] = k5alloc(sizeof(*addrs[i]), &ret);
+ if (addrs[i] == NULL)
+ goto cleanup;
+
+ addrs[i]->contents = k5memdup(list[i]->data, list[i]->length, &ret);
+ if (addrs[i]->contents == NULL)
+ goto cleanup;
+ addrs[i]->length = list[i]->length;
+ addrs[i]->addrtype = list[i]->type;
+ addrs[i]->magic = KV5M_ADDRESS;
+ }
+
+ *addrs_out = addrs;
+ addrs = NULL;
+
+cleanup:
+ krb5_free_addresses(context, addrs);
+ return ret;
+}
+
+static krb5_error_code
+cc_data_list_to_authdata(krb5_context context, cc_data **list,
+ krb5_authdata ***authdata_out)
+{
+ krb5_error_code ret;
+ size_t count, i;
+ krb5_authdata **authdata = NULL;
+
+ *authdata_out = NULL;
+ if (list == NULL)
+ return 0;
+
+ for (count = 0; list[count]; count++);
+ authdata = k5calloc(count + 1, sizeof(*authdata), &ret);
+ if (authdata == NULL)
+ return ret;
+
+ for (i = 0; i < count; i++) {
+ authdata[i] = k5alloc(sizeof(*authdata[i]), &ret);
+ if (authdata[i] == NULL)
+ goto cleanup;
+
+ authdata[i]->contents = k5memdup(list[i]->data, list[i]->length, &ret);
+ if (authdata[i]->contents == NULL)
+ goto cleanup;
+ authdata[i]->length = list[i]->length;
+ authdata[i]->ad_type = list[i]->type;
+ authdata[i]->magic = KV5M_AUTHDATA;
+ }
+
+ *authdata_out = authdata;
+ authdata = NULL;
+
+cleanup:
+ krb5_free_authdata(context, authdata);
+ return ret;
+}
+
+static krb5_error_code
+addresses_to_cc_data_list(krb5_context context, krb5_address **addrs,
+ cc_data ***list_out)
+{
+ krb5_error_code ret;
+ size_t count, i;
+ cc_data **list = NULL;
+
+ *list_out = NULL;
+ if (addrs == NULL)
+ return 0;
+
+ for (count = 0; addrs[count]; count++);
+ list = k5calloc(count + 1, sizeof(*list), &ret);
+ if (list == NULL)
+ return ret;
+
+ for (i = 0; i < count; i++) {
+ list[i] = k5alloc(sizeof(*list[i]), &ret);
+ if (list[i] == NULL)
+ goto cleanup;
+
+ list[i]->data = k5memdup(addrs[i]->contents, addrs[i]->length, &ret);
+ if (list[i]->data == NULL)
+ goto cleanup;
+ list[i]->length = addrs[i]->length;
+ list[i]->type = addrs[i]->addrtype;
+ }
+
+ *list_out = list;
+ list = NULL;
+
+cleanup:
+ free_cc_data_list(list);
+ return ret;
+}
+
+static krb5_error_code
+authdata_to_cc_data_list(krb5_context context, krb5_authdata **authdata,
+ cc_data ***list_out)
+{
+ krb5_error_code ret;
+ size_t count, i;
+ cc_data **list = NULL;
+
+ *list_out = NULL;
+ if (authdata == NULL)
+ return 0;
+
+ for (count = 0; authdata[count]; count++);
+ list = k5calloc(count + 1, sizeof(*list), &ret);
+ if (list == NULL)
+ return ret;
+
+ for (i = 0; i < count; i++) {
+ list[i] = k5alloc(sizeof(*list[i]), &ret);
+ if (list[i] == NULL)
+ goto cleanup;
+
+ list[i]->data = k5memdup(authdata[i]->contents, authdata[i]->length,
+ &ret);
+ if (list[i]->data == NULL)
+ goto cleanup;
+ list[i]->length = authdata[i]->length;
+ list[i]->type = authdata[i]->ad_type;
+ }
+
+ *list_out = list;
+ list = NULL;
+
+cleanup:
+ free_cc_data_list(list);
+ return ret;
+}
+
+krb5_error_code
+k5_ccapi_to_krb5_creds(krb5_context context,
+ const cc_credentials_union *ccapi_cred,
+ krb5_creds *cred_out)
+{
+ krb5_error_code ret;
+ cc_credentials_v5_t *cv5 = NULL;
+ krb5_principal client = NULL;
+ krb5_principal server = NULL;
+ char *ticket_data = NULL;
+ char *second_ticket_data = NULL;
+ uint8_t *keyblock_contents = NULL;
+ krb5_address **addresses = NULL;
+ krb5_authdata **authdata = NULL;
+
+ if (ccapi_cred->version != cc_credentials_v5)
+ return KRB5_CC_NOT_KTYPE;
+
+ cv5 = ccapi_cred->credentials.credentials_v5;
+
+ ret = krb5_parse_name(context, cv5->client, &client);
+ if (ret)
+ goto cleanup;
+ ret = krb5_parse_name(context, cv5->server, &server);
+ if (ret)
+ goto cleanup;
+
+ if (cv5->keyblock.length > 0) {
+ keyblock_contents = k5memdup(cv5->keyblock.data, cv5->keyblock.length,
+ &ret);
+ if (keyblock_contents == NULL)
+ goto cleanup;
+ }
+
+ if (cv5->ticket.length > 0) {
+ ticket_data = k5memdup(cv5->ticket.data, cv5->ticket.length, &ret);
+ if (ticket_data == NULL)
+ goto cleanup;
+ }
+
+ if (cv5->second_ticket.length > 0) {
+ second_ticket_data = k5memdup(cv5->second_ticket.data,
+ cv5->second_ticket.length, &ret);
+ if (second_ticket_data == NULL)
+ goto cleanup;
+ }
+
+ ret = cc_data_list_to_addresses(context, cv5->addresses, &addresses);
+ if (ret)
+ goto cleanup;
+
+ ret = cc_data_list_to_authdata(context, cv5->authdata, &authdata);
+ if (ret)
+ goto cleanup;
+
+ cred_out->client = client;
+ cred_out->server = server;
+ client = server = NULL;
+
+ cred_out->keyblock.magic = KV5M_KEYBLOCK;
+ cred_out->keyblock.enctype = cv5->keyblock.type;
+ cred_out->keyblock.length = cv5->keyblock.length;
+ cred_out->keyblock.contents = keyblock_contents;
+ keyblock_contents = NULL;
+
+ cred_out->times.authtime = cv5->authtime;
+ cred_out->times.starttime = cv5->starttime;
+ cred_out->times.endtime = cv5->endtime;
+ cred_out->times.renew_till = cv5->renew_till;
+ cred_out->is_skey = cv5->is_skey;
+ cred_out->ticket_flags = cv5->ticket_flags;
+
+ cred_out->ticket = make_data(ticket_data, cv5->ticket.length);
+ cred_out->second_ticket = make_data(second_ticket_data,
+ cv5->second_ticket.length);
+ ticket_data = second_ticket_data = NULL;
+
+ cred_out->addresses = addresses;
+ addresses = NULL;
+
+ cred_out->authdata = authdata;
+ authdata = NULL;
+
+ cred_out->magic = KV5M_CREDS;
+
+cleanup:
+ krb5_free_principal(context, client);
+ krb5_free_principal(context, server);
+ krb5_free_addresses(context, addresses);
+ krb5_free_authdata(context, authdata);
+ free(keyblock_contents);
+ free(ticket_data);
+ free(second_ticket_data);
+ return ret;
+}
+
+krb5_error_code
+k5_krb5_to_ccapi_creds(krb5_context context, krb5_creds *cred,
+ cc_credentials_union **ccapi_cred_out)
+{
+ krb5_error_code ret;
+ cc_credentials_union *cred_union = NULL;
+ cc_credentials_v5_t *cv5 = NULL;
+ char *client = NULL, *server = NULL;
+ uint8_t *ticket_data = NULL, *second_ticket_data = NULL;
+ uint8_t *keyblock_data = NULL;
+ cc_data **addr_list = NULL, **authdata_list = NULL;
+
+ cred_union = k5alloc(sizeof(*cred_union), &ret);
+ if (cred_union == NULL)
+ goto cleanup;
+
+ cv5 = k5alloc(sizeof(*cv5), &ret);
+ if (cv5 == NULL)
+ goto cleanup;
+
+ ret = krb5_unparse_name(context, cred->client, &client);
+ if (ret)
+ goto cleanup;
+ ret = krb5_unparse_name(context, cred->server, &server);
+ if (ret)
+ goto cleanup;
+
+ if (cred->keyblock.length > 0) {
+ keyblock_data = k5memdup(cred->keyblock.contents,
+ cred->keyblock.length, &ret);
+ if (keyblock_data == NULL)
+ goto cleanup;
+ }
+
+ if (cred->ticket.length > 0) {
+ ticket_data = k5memdup0(cred->ticket.data, cred->ticket.length, &ret);
+ if (ticket_data == NULL)
+ goto cleanup;
+ }
+
+ if (cred->second_ticket.length > 0) {
+ second_ticket_data = k5memdup0(cred->second_ticket.data,
+ cred->second_ticket.length, &ret);
+ if (second_ticket_data == NULL)
+ goto cleanup;
+ }
+
+ ret = addresses_to_cc_data_list(context, cred->addresses, &addr_list);
+ if (ret)
+ goto cleanup;
+
+ ret = authdata_to_cc_data_list(context, cred->authdata, &authdata_list);
+ if (ret)
+ goto cleanup;
+
+ cv5->client = client;
+ cv5->server = server;
+ client = server = NULL;
+
+ cv5->keyblock.type = cred->keyblock.enctype;
+ cv5->keyblock.length = cred->keyblock.length;
+ cv5->keyblock.data = keyblock_data;
+ keyblock_data = NULL;
+
+ cv5->authtime = cred->times.authtime;
+ cv5->starttime = cred->times.starttime;
+ cv5->endtime = cred->times.endtime;
+ cv5->renew_till = cred->times.renew_till;
+ cv5->is_skey = cred->is_skey;
+ cv5->ticket_flags = cred->ticket_flags;
+
+ cv5->ticket.length = cred->ticket.length;
+ cv5->ticket.data = ticket_data;
+ cv5->second_ticket.length = cred->second_ticket.length;
+ cv5->second_ticket.data = second_ticket_data;
+ ticket_data = second_ticket_data = NULL;
+
+ cv5->addresses = addr_list;
+ addr_list = NULL;
+
+ cv5->authdata = authdata_list;
+ authdata_list = NULL;
+
+ cred_union->version = cc_credentials_v5;
+ cred_union->credentials.credentials_v5 = cv5;
+ cv5 = NULL;
+
+ *ccapi_cred_out = cred_union;
+ cred_union = NULL;
+
+cleanup:
+ free_cc_data_list(addr_list);
+ free_cc_data_list(authdata_list);
+ free(keyblock_data);
+ free(ticket_data);
+ free(second_ticket_data);
+ krb5_free_unparsed_name(context, client);
+ krb5_free_unparsed_name(context, server);
+ free(cv5);
+ free(cred_union);
+ return ret;
+}
+
+void
+k5_release_ccapi_cred(cc_credentials_union *ccapi_cred)
+{
+ cc_credentials_v5_t *cv5;
+
+ if (ccapi_cred == NULL)
+ return;
+ if (ccapi_cred->version != cc_credentials_v5)
+ return;
+ if (ccapi_cred->credentials.credentials_v5 == NULL)
+ return;
+
+ cv5 = ccapi_cred->credentials.credentials_v5;
+
+ free(cv5->client);
+ free(cv5->server);
+ free(cv5->keyblock.data);
+ free(cv5->ticket.data);
+ free(cv5->second_ticket.data);
+ free_cc_data_list(cv5->addresses);
+ free_cc_data_list(cv5->authdata);
+ free(cv5);
+ free(ccapi_cred);
+}
+
+#endif /* defined(USE_CCAPI) */
diff --git a/src/lib/krb5/ccache/ccapi_util.h b/src/lib/krb5/ccache/ccapi_util.h
new file mode 100644
index 0000000..6a86608
--- /dev/null
+++ b/src/lib/krb5/ccache/ccapi_util.h
@@ -0,0 +1,50 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/krb5/ccache/ccapi_util.c - conversion declarations for CCAPI creds */
+/*
+ * Copyright (C) 2021 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CCAPI_UTIL_H
+#define CCAPI_UTIL_H
+
+#include <CredentialsCache.h>
+
+krb5_error_code
+k5_ccapi_to_krb5_creds(krb5_context context,
+ const cc_credentials_union *ccapi_cred,
+ krb5_creds *cred_out);
+
+krb5_error_code
+k5_krb5_to_ccapi_creds(krb5_context context, krb5_creds *cred,
+ cc_credentials_union **ccapi_cred_out);
+
+void
+k5_release_ccapi_cred(cc_credentials_union *ccapi_cred);
+
+#endif /* CCAPI_UTIL_H */
diff --git a/src/lib/krb5/ccache/deps b/src/lib/krb5/ccache/deps
index 919e475..1f69e0f 100644
--- a/src/lib/krb5/ccache/deps
+++ b/src/lib/krb5/ccache/deps
@@ -1,6 +1,18 @@
#
# Generated makefile dependencies follow.
#
+ccapi_util.so ccapi_util.po $(OUTPRE)ccapi_util.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ cc-int.h ccapi_util.c ccapi_util.h
ccbase.so ccbase.po $(OUTPRE)ccbase.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \