diff options
Diffstat (limited to 'contrib/bind9/lib/dns/gssapi_link.c')
-rw-r--r-- | contrib/bind9/lib/dns/gssapi_link.c | 394 |
1 files changed, 0 insertions, 394 deletions
diff --git a/contrib/bind9/lib/dns/gssapi_link.c b/contrib/bind9/lib/dns/gssapi_link.c deleted file mode 100644 index 5ad81cd..0000000 --- a/contrib/bind9/lib/dns/gssapi_link.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * $Id: gssapi_link.c,v 1.17 2011/03/28 05:32:16 marka Exp $ - */ - -#include <config.h> - -#ifdef GSSAPI - -#include <isc/base64.h> -#include <isc/buffer.h> -#include <isc/mem.h> -#include <isc/string.h> -#include <isc/util.h> - -#include <dst/result.h> - -#include "dst_internal.h" -#include "dst_parse.h" - -#include <dst/gssapi.h> - -#define INITIAL_BUFFER_SIZE 1024 -#define BUFFER_EXTRA 1024 - -#define REGION_TO_GBUFFER(r, gb) \ - do { \ - (gb).length = (r).length; \ - (gb).value = (r).base; \ - } while (0) - -#define GBUFFER_TO_REGION(gb, r) \ - do { \ - (r).length = (gb).length; \ - (r).base = (gb).value; \ - } while (0) - - -struct dst_gssapi_signverifyctx { - isc_buffer_t *buffer; -}; - -/*% - * Allocate a temporary "context" for use in gathering data for signing - * or verifying. - */ -static isc_result_t -gssapi_create_signverify_ctx(dst_key_t *key, dst_context_t *dctx) { - dst_gssapi_signverifyctx_t *ctx; - isc_result_t result; - - UNUSED(key); - - ctx = isc_mem_get(dctx->mctx, sizeof(dst_gssapi_signverifyctx_t)); - if (ctx == NULL) - return (ISC_R_NOMEMORY); - ctx->buffer = NULL; - result = isc_buffer_allocate(dctx->mctx, &ctx->buffer, - INITIAL_BUFFER_SIZE); - if (result != ISC_R_SUCCESS) { - isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t)); - return (result); - } - - dctx->ctxdata.gssctx = ctx; - - return (ISC_R_SUCCESS); -} - -/*% - * Destroy the temporary sign/verify context. - */ -static void -gssapi_destroy_signverify_ctx(dst_context_t *dctx) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - - if (ctx != NULL) { - if (ctx->buffer != NULL) - isc_buffer_free(&ctx->buffer); - isc_mem_put(dctx->mctx, ctx, sizeof(dst_gssapi_signverifyctx_t)); - dctx->ctxdata.gssctx = NULL; - } -} - -/*% - * Add data to our running buffer of data we will be signing or verifying. - * This code will see if the new data will fit in our existing buffer, and - * copy it in if it will. If not, it will attempt to allocate a larger - * buffer and copy old+new into it, and free the old buffer. - */ -static isc_result_t -gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - isc_buffer_t *newbuffer = NULL; - isc_region_t r; - unsigned int length; - isc_result_t result; - - result = isc_buffer_copyregion(ctx->buffer, data); - if (result == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - length = isc_buffer_length(ctx->buffer) + data->length + BUFFER_EXTRA; - - result = isc_buffer_allocate(dctx->mctx, &newbuffer, length); - if (result != ISC_R_SUCCESS) - return (result); - - isc_buffer_usedregion(ctx->buffer, &r); - (void)isc_buffer_copyregion(newbuffer, &r); - (void)isc_buffer_copyregion(newbuffer, data); - - isc_buffer_free(&ctx->buffer); - ctx->buffer = newbuffer; - - return (ISC_R_SUCCESS); -} - -/*% - * Sign. - */ -static isc_result_t -gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - isc_region_t message; - gss_buffer_desc gmessage, gsig; - OM_uint32 minor, gret; - gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; - char buf[1024]; - - /* - * Convert the data we wish to sign into a structure gssapi can - * understand. - */ - isc_buffer_usedregion(ctx->buffer, &message); - REGION_TO_GBUFFER(message, gmessage); - - /* - * Generate the signature. - */ - gret = gss_get_mic(&minor, gssctx, GSS_C_QOP_DEFAULT, &gmessage, - &gsig); - - /* - * If it did not complete, we log the result and return a generic - * failure code. - */ - if (gret != GSS_S_COMPLETE) { - gss_log(3, "GSS sign error: %s", - gss_error_tostring(gret, minor, buf, sizeof(buf))); - return (ISC_R_FAILURE); - } - - /* - * If it will not fit in our allocated buffer, return that we need - * more space. - */ - if (gsig.length > isc_buffer_availablelength(sig)) { - gss_release_buffer(&minor, &gsig); - return (ISC_R_NOSPACE); - } - - /* - * Copy the output into our buffer space, and release the gssapi - * allocated space. - */ - isc_buffer_putmem(sig, gsig.value, gsig.length); - if (gsig.length != 0U) - gss_release_buffer(&minor, &gsig); - - return (ISC_R_SUCCESS); -} - -/*% - * Verify. - */ -static isc_result_t -gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) { - dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx; - isc_region_t message, r; - gss_buffer_desc gmessage, gsig; - OM_uint32 minor, gret; - gss_ctx_id_t gssctx = dctx->key->keydata.gssctx; - unsigned char *buf; - char err[1024]; - - /* - * Convert the data we wish to sign into a structure gssapi can - * understand. - */ - isc_buffer_usedregion(ctx->buffer, &message); - REGION_TO_GBUFFER(message, gmessage); - - /* - * XXXMLG - * It seem that gss_verify_mic() modifies the signature buffer, - * at least on Heimdal's implementation. Copy it here to an allocated - * buffer. - */ - buf = isc_mem_allocate(dst__memory_pool, sig->length); - if (buf == NULL) - return (ISC_R_FAILURE); - memcpy(buf, sig->base, sig->length); - r.base = buf; - r.length = sig->length; - REGION_TO_GBUFFER(r, gsig); - - /* - * Verify the data. - */ - gret = gss_verify_mic(&minor, gssctx, &gmessage, &gsig, NULL); - - isc_mem_free(dst__memory_pool, buf); - - /* - * Convert return codes into something useful to us. - */ - if (gret != GSS_S_COMPLETE) { - gss_log(3, "GSS verify error: %s", - gss_error_tostring(gret, minor, err, sizeof(err))); - if (gret == GSS_S_DEFECTIVE_TOKEN || - gret == GSS_S_BAD_SIG || - gret == GSS_S_DUPLICATE_TOKEN || - gret == GSS_S_OLD_TOKEN || - gret == GSS_S_UNSEQ_TOKEN || - gret == GSS_S_GAP_TOKEN || - gret == GSS_S_CONTEXT_EXPIRED || - gret == GSS_S_NO_CONTEXT || - gret == GSS_S_FAILURE) - return(DST_R_VERIFYFAILURE); - else - return (ISC_R_FAILURE); - } - - return (ISC_R_SUCCESS); -} - -static isc_boolean_t -gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) { - gss_ctx_id_t gsskey1 = key1->keydata.gssctx; - gss_ctx_id_t gsskey2 = key2->keydata.gssctx; - - /* No idea */ - return (ISC_TF(gsskey1 == gsskey2)); -} - -static isc_result_t -gssapi_generate(dst_key_t *key, int unused, void (*callback)(int)) { - UNUSED(key); - UNUSED(unused); - UNUSED(callback); - - /* No idea */ - return (ISC_R_FAILURE); -} - -static isc_boolean_t -gssapi_isprivate(const dst_key_t *key) { - UNUSED(key); - return (ISC_TRUE); -} - -static void -gssapi_destroy(dst_key_t *key) { - REQUIRE(key != NULL); - dst_gssapi_deletectx(key->mctx, &key->keydata.gssctx); - key->keydata.gssctx = NULL; -} - -static isc_result_t -gssapi_restore(dst_key_t *key, const char *keystr) { - OM_uint32 major, minor; - size_t len; - isc_buffer_t *b = NULL; - isc_region_t r; - gss_buffer_desc gssbuffer; - isc_result_t result; - - len = strlen(keystr); - if ((len % 4) != 0U) - return (ISC_R_BADBASE64); - - len = (len / 4) * 3; - - result = isc_buffer_allocate(key->mctx, &b, len); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_base64_decodestring(keystr, b); - if (result != ISC_R_SUCCESS) { - isc_buffer_free(&b); - return (result); - } - - isc_buffer_remainingregion(b, &r); - REGION_TO_GBUFFER(r, gssbuffer); - major = gss_import_sec_context(&minor, &gssbuffer, - &key->keydata.gssctx); - if (major != GSS_S_COMPLETE) { - isc_buffer_free(&b); - return (ISC_R_FAILURE); - } - - isc_buffer_free(&b); - return (ISC_R_SUCCESS); -} - -static isc_result_t -gssapi_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { - OM_uint32 major, minor; - gss_buffer_desc gssbuffer; - size_t len; - char *buf; - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - major = gss_export_sec_context(&minor, &key->keydata.gssctx, - &gssbuffer); - if (major != GSS_S_COMPLETE) { - fprintf(stderr, "gss_export_sec_context -> %d, %d\n", - major, minor); - return (ISC_R_FAILURE); - } - if (gssbuffer.length == 0U) - return (ISC_R_FAILURE); - len = ((gssbuffer.length + 2)/3) * 4; - buf = isc_mem_get(mctx, len); - if (buf == NULL) { - gss_release_buffer(&minor, &gssbuffer); - return (ISC_R_NOMEMORY); - } - isc_buffer_init(&b, buf, len); - GBUFFER_TO_REGION(gssbuffer, r); - result = isc_base64_totext(&r, 0, "", &b); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - gss_release_buffer(&minor, &gssbuffer); - *buffer = buf; - *length = len; - return (ISC_R_SUCCESS); -} - -static dst_func_t gssapi_functions = { - gssapi_create_signverify_ctx, - gssapi_destroy_signverify_ctx, - gssapi_adddata, - gssapi_sign, - gssapi_verify, - NULL, /*%< verify2 */ - NULL, /*%< computesecret */ - gssapi_compare, - NULL, /*%< paramcompare */ - gssapi_generate, - gssapi_isprivate, - gssapi_destroy, - NULL, /*%< todns */ - NULL, /*%< fromdns */ - NULL, /*%< tofile */ - NULL, /*%< parse */ - NULL, /*%< cleanup */ - NULL, /*%< fromlabel */ - gssapi_dump, - gssapi_restore, -}; - -isc_result_t -dst__gssapi_init(dst_func_t **funcp) { - REQUIRE(funcp != NULL); - if (*funcp == NULL) - *funcp = &gssapi_functions; - return (ISC_R_SUCCESS); -} - -#else -int gssapi_link_unneeded = 1; -#endif - -/*! \file */ |