Path: blob/main/crypto/krb5/src/tests/gssapi/common.c
34889 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* tests/gssapi/common.c - Common utility functions for GSSAPI test programs */2/*3* Copyright (C) 2012 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9*10* * Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in15* the documentation and/or other materials provided with the16* distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS21* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE22* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,23* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES24* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR25* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,27* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED29* OF THE POSSIBILITY OF SUCH DAMAGE.30*/3132#include <stdio.h>33#include <string.h>34#include "common.h"3536gss_OID_desc mech_krb5 = { 9, "\052\206\110\206\367\022\001\002\002" };37gss_OID_desc mech_spnego = { 6, "\053\006\001\005\005\002" };38gss_OID_desc mech_iakerb = { 6, "\053\006\001\005\002\005" };39gss_OID_set_desc mechset_krb5 = { 1, &mech_krb5 };40gss_OID_set_desc mechset_spnego = { 1, &mech_spnego };41gss_OID_set_desc mechset_iakerb = { 1, &mech_iakerb };4243static void44display_status(const char *msg, OM_uint32 code, int type)45{46OM_uint32 min_stat, msg_ctx = 0;47gss_buffer_desc buf;4849do {50(void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID,51&msg_ctx, &buf);52fprintf(stderr, "%s: %.*s\n", msg, (int)buf.length, (char *)buf.value);53(void)gss_release_buffer(&min_stat, &buf);54} while (msg_ctx != 0);55}5657void58check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor)59{60if (GSS_ERROR(major)) {61display_status(msg, major, GSS_C_GSS_CODE);62display_status(msg, minor, GSS_C_MECH_CODE);63exit(1);64}65}6667void68check_k5err(krb5_context context, const char *msg, krb5_error_code code)69{70const char *errmsg;7172if (code) {73errmsg = krb5_get_error_message(context, code);74printf("%s: %s\n", msg, errmsg);75krb5_free_error_message(context, errmsg);76exit(1);77}78}7980void81errout(const char *msg)82{83fprintf(stderr, "%s\n", msg);84exit(1);85}8687gss_name_t88import_name(const char *str)89{90OM_uint32 major, minor;91gss_name_t name;92gss_buffer_desc buf;93gss_OID nametype = NULL;9495if (*str == 'u')96nametype = GSS_C_NT_USER_NAME;97else if (*str == 'p')98nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;99else if (*str == 'e')100nametype = (gss_OID)GSS_KRB5_NT_ENTERPRISE_NAME;101else if (*str == 'c')102nametype = (gss_OID)GSS_KRB5_NT_X509_CERT;103else if (*str == 'h')104nametype = GSS_C_NT_HOSTBASED_SERVICE;105if (nametype == NULL || str[1] != ':')106errout("names must begin with u: or p: or e: or c: or h:");107buf.value = (char *)str + 2;108buf.length = strlen(str) - 2;109major = gss_import_name(&minor, &buf, nametype, &name);110check_gsserr("gss_import_name", major, minor);111return name;112}113114void115establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,116gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,117gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech,118gss_cred_id_t *deleg_cred)119{120establish_contexts_ex(imech, icred, acred, tname, flags, ictx, actx,121GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_CHANNEL_BINDINGS,122NULL, src_name, amech, deleg_cred);123}124125void126establish_contexts_ex(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,127gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,128gss_ctx_id_t *actx, gss_channel_bindings_t icb,129gss_channel_bindings_t acb, OM_uint32 *aret_flags,130gss_name_t *src_name, gss_OID *amech,131gss_cred_id_t *deleg_cred)132{133OM_uint32 minor, imaj, amaj;134gss_buffer_desc itok, atok;135136*ictx = *actx = GSS_C_NO_CONTEXT;137imaj = amaj = GSS_S_CONTINUE_NEEDED;138itok.value = atok.value = NULL;139itok.length = atok.length = 0;140for (;;) {141(void)gss_release_buffer(&minor, &itok);142imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags,143GSS_C_INDEFINITE, icb, &atok, NULL, &itok,144NULL, NULL);145check_gsserr("gss_init_sec_context", imaj, minor);146if (amaj == GSS_S_COMPLETE)147break;148149(void)gss_release_buffer(&minor, &atok);150amaj = gss_accept_sec_context(&minor, actx, acred, &itok, acb,151src_name, amech, &atok, aret_flags, NULL,152deleg_cred);153check_gsserr("gss_accept_sec_context", amaj, minor);154(void)gss_release_buffer(&minor, &itok);155if (imaj == GSS_S_COMPLETE)156break;157}158159if (imaj != GSS_S_COMPLETE || amaj != GSS_S_COMPLETE)160errout("One side wants to continue after the other is done");161162(void)gss_release_buffer(&minor, &itok);163(void)gss_release_buffer(&minor, &atok);164}165166void167export_import_cred(gss_cred_id_t *cred)168{169OM_uint32 major, minor;170gss_buffer_desc buf;171172major = gss_export_cred(&minor, *cred, &buf);173check_gsserr("gss_export_cred", major, minor);174(void)gss_release_cred(&minor, cred);175major = gss_import_cred(&minor, &buf, cred);176check_gsserr("gss_import_cred", major, minor);177(void)gss_release_buffer(&minor, &buf);178}179180void181display_canon_name(const char *tag, gss_name_t name, gss_OID mech)182{183gss_name_t canon;184OM_uint32 major, minor;185gss_buffer_desc buf;186187major = gss_canonicalize_name(&minor, name, mech, &canon);188check_gsserr("gss_canonicalize_name", major, minor);189190major = gss_display_name(&minor, canon, &buf, NULL);191check_gsserr("gss_display_name", major, minor);192193printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value);194195(void)gss_release_name(&minor, &canon);196(void)gss_release_buffer(&minor, &buf);197}198199void200display_oid(const char *tag, gss_OID oid)201{202OM_uint32 major, minor;203gss_buffer_desc buf;204205major = gss_oid_to_str(&minor, oid, &buf);206check_gsserr("gss_oid_to_str", major, minor);207if (tag != NULL)208printf("%s:\t", tag);209printf("%.*s\n", (int)buf.length, (char *)buf.value);210(void)gss_release_buffer(&minor, &buf);211}212213static void214dump_attribute(gss_name_t name, gss_buffer_t attribute, int noisy)215{216OM_uint32 major, minor;217gss_buffer_desc value;218gss_buffer_desc display_value;219int authenticated = 0;220int complete = 0;221int more = -1;222unsigned int i;223224while (more != 0) {225value.value = NULL;226display_value.value = NULL;227228major = gss_get_name_attribute(&minor, name, attribute, &authenticated,229&complete, &value, &display_value,230&more);231check_gsserr("gss_get_name_attribute", major, minor);232233printf("Attribute %.*s %s %s\n\n%.*s\n",234(int)attribute->length, (char *)attribute->value,235authenticated ? "Authenticated" : "",236complete ? "Complete" : "",237(int)display_value.length, (char *)display_value.value);238239if (noisy) {240for (i = 0; i < value.length; i++) {241if ((i % 32) == 0)242printf("\n");243printf("%02x", ((char *)value.value)[i] & 0xFF);244}245printf("\n\n");246}247248(void)gss_release_buffer(&minor, &value);249(void)gss_release_buffer(&minor, &display_value);250}251}252253void254enumerate_attributes(gss_name_t name, int noisy)255{256OM_uint32 major, minor;257int is_mechname;258gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;259size_t i;260261major = gss_inquire_name(&minor, name, &is_mechname, NULL, &attrs);262check_gsserr("gss_inquire_name", major, minor);263264if (attrs != GSS_C_NO_BUFFER_SET) {265for (i = 0; i < attrs->count; i++)266dump_attribute(name, &attrs->elements[i], noisy);267}268269(void)gss_release_buffer_set(&minor, &attrs);270}271272void273print_hex(FILE *fp, gss_buffer_t buf)274{275size_t i;276const unsigned char *bytes = buf->value;277278for (i = 0; i < buf->length; i++)279printf("%02X", bytes[i]);280printf("\n");281}282283284