|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
/* tests/gssapi/common.c - Common utility functions for GSSAPI test programs */
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Copyright (C) 2012 by the Massachusetts Institute of Technology.
|
|
Packit |
fd8b60 |
* All rights reserved.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
fd8b60 |
* modification, are permitted provided that the following conditions
|
|
Packit |
fd8b60 |
* are met:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* * Redistributions of source code must retain the above copyright
|
|
Packit |
fd8b60 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* * Redistributions in binary form must reproduce the above copyright
|
|
Packit |
fd8b60 |
* notice, this list of conditions and the following disclaimer in
|
|
Packit |
fd8b60 |
* the documentation and/or other materials provided with the
|
|
Packit |
fd8b60 |
* distribution.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
fd8b60 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
fd8b60 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
Packit |
fd8b60 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
Packit |
fd8b60 |
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
Packit |
fd8b60 |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
Packit |
fd8b60 |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit |
fd8b60 |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
Packit |
fd8b60 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
Packit |
fd8b60 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
fd8b60 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
Packit |
fd8b60 |
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include <stdio.h>
|
|
Packit |
fd8b60 |
#include <string.h>
|
|
Packit |
fd8b60 |
#include "common.h"
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
gss_OID_desc mech_krb5 = { 9, "\052\206\110\206\367\022\001\002\002" };
|
|
Packit |
fd8b60 |
gss_OID_desc mech_spnego = { 6, "\053\006\001\005\005\002" };
|
|
Packit |
fd8b60 |
gss_OID_desc mech_iakerb = { 6, "\053\006\001\005\002\005" };
|
|
Packit |
fd8b60 |
gss_OID_set_desc mechset_krb5 = { 1, &mech_krb5 };
|
|
Packit |
fd8b60 |
gss_OID_set_desc mechset_spnego = { 1, &mech_spnego };
|
|
Packit |
fd8b60 |
gss_OID_set_desc mechset_iakerb = { 1, &mech_iakerb };
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
display_status(const char *msg, OM_uint32 code, int type)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 min_stat, msg_ctx = 0;
|
|
Packit |
fd8b60 |
gss_buffer_desc buf;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
do {
|
|
Packit |
fd8b60 |
(void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID,
|
|
Packit |
fd8b60 |
&msg_ctx, &buf;;
|
|
Packit |
fd8b60 |
fprintf(stderr, "%s: %.*s\n", msg, (int)buf.length, (char *)buf.value);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&min_stat, &buf;;
|
|
Packit |
fd8b60 |
} while (msg_ctx != 0);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
if (GSS_ERROR(major)) {
|
|
Packit |
fd8b60 |
display_status(msg, major, GSS_C_GSS_CODE);
|
|
Packit |
fd8b60 |
display_status(msg, minor, GSS_C_MECH_CODE);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
check_k5err(krb5_context context, const char *msg, krb5_error_code code)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
const char *errmsg;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (code) {
|
|
Packit |
fd8b60 |
errmsg = krb5_get_error_message(context, code);
|
|
Packit |
fd8b60 |
printf("%s: %s\n", msg, errmsg);
|
|
Packit |
fd8b60 |
krb5_free_error_message(context, errmsg);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
errout(const char *msg)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
fprintf(stderr, "%s\n", msg);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
gss_name_t
|
|
Packit |
fd8b60 |
import_name(const char *str)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_name_t name;
|
|
Packit |
fd8b60 |
gss_buffer_desc buf;
|
|
Packit |
fd8b60 |
gss_OID nametype = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (*str == 'u')
|
|
Packit |
fd8b60 |
nametype = GSS_C_NT_USER_NAME;
|
|
Packit |
fd8b60 |
else if (*str == 'p')
|
|
Packit |
fd8b60 |
nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
|
|
Packit |
fd8b60 |
else if (*str == 'e')
|
|
Packit |
fd8b60 |
nametype = (gss_OID)GSS_KRB5_NT_ENTERPRISE_NAME;
|
|
Packit |
fd8b60 |
else if (*str == 'h')
|
|
Packit |
fd8b60 |
nametype = GSS_C_NT_HOSTBASED_SERVICE;
|
|
Packit |
fd8b60 |
if (nametype == NULL || str[1] != ':')
|
|
Packit |
fd8b60 |
errout("names must begin with u: or p: or e: or h:");
|
|
Packit |
fd8b60 |
buf.value = (char *)str + 2;
|
|
Packit |
fd8b60 |
buf.length = strlen(str) - 2;
|
|
Packit |
fd8b60 |
major = gss_import_name(&minor, &buf, nametype, &name);
|
|
Packit |
fd8b60 |
check_gsserr("gss_import_name", major, minor);
|
|
Packit |
fd8b60 |
return name;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
|
|
Packit |
fd8b60 |
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
|
|
Packit |
fd8b60 |
gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech,
|
|
Packit |
fd8b60 |
gss_cred_id_t *deleg_cred)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 minor, imaj, amaj;
|
|
Packit |
fd8b60 |
gss_buffer_desc itok, atok;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*ictx = *actx = GSS_C_NO_CONTEXT;
|
|
Packit |
fd8b60 |
imaj = amaj = GSS_S_CONTINUE_NEEDED;
|
|
Packit |
fd8b60 |
itok.value = atok.value = NULL;
|
|
Packit |
fd8b60 |
itok.length = atok.length = 0;
|
|
Packit |
fd8b60 |
for (;;) {
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &itok);
|
|
Packit |
fd8b60 |
imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags,
|
|
Packit |
fd8b60 |
GSS_C_INDEFINITE,
|
|
Packit |
fd8b60 |
GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL,
|
|
Packit |
fd8b60 |
&itok, NULL, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_init_sec_context", imaj, minor);
|
|
Packit |
fd8b60 |
if (amaj == GSS_S_COMPLETE)
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &atok);
|
|
Packit |
fd8b60 |
amaj = gss_accept_sec_context(&minor, actx, acred, &itok,
|
|
Packit |
fd8b60 |
GSS_C_NO_CHANNEL_BINDINGS, src_name,
|
|
Packit |
fd8b60 |
amech, &atok, NULL, NULL, deleg_cred);
|
|
Packit |
fd8b60 |
check_gsserr("gss_accept_sec_context", amaj, minor);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &itok);
|
|
Packit |
fd8b60 |
if (imaj == GSS_S_COMPLETE)
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (imaj != GSS_S_COMPLETE || amaj != GSS_S_COMPLETE)
|
|
Packit |
fd8b60 |
errout("One side wants to continue after the other is done");
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &itok);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &atok);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
export_import_cred(gss_cred_id_t *cred)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_buffer_desc buf;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_export_cred(&minor, *cred, &buf;;
|
|
Packit |
fd8b60 |
check_gsserr("gss_export_cred", major, minor);
|
|
Packit |
fd8b60 |
(void)gss_release_cred(&minor, cred);
|
|
Packit |
fd8b60 |
major = gss_import_cred(&minor, &buf, cred);
|
|
Packit |
fd8b60 |
check_gsserr("gss_import_cred", major, minor);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &buf;;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
display_canon_name(const char *tag, gss_name_t name, gss_OID mech)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
gss_name_t canon;
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_buffer_desc buf;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_canonicalize_name(&minor, name, mech, &canon);
|
|
Packit |
fd8b60 |
check_gsserr("gss_canonicalize_name", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_display_name(&minor, canon, &buf, NULL);
|
|
Packit |
fd8b60 |
check_gsserr("gss_display_name", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_name(&minor, &canon);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &buf;;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
display_oid(const char *tag, gss_OID oid)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_buffer_desc buf;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_oid_to_str(&minor, oid, &buf;;
|
|
Packit |
fd8b60 |
check_gsserr("gss_oid_to_str", major, minor);
|
|
Packit |
fd8b60 |
if (tag != NULL)
|
|
Packit |
fd8b60 |
printf("%s:\t", tag);
|
|
Packit |
fd8b60 |
printf("%.*s\n", (int)buf.length, (char *)buf.value);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &buf;;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static void
|
|
Packit |
fd8b60 |
dump_attribute(gss_name_t name, gss_buffer_t attribute, int noisy)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
gss_buffer_desc value;
|
|
Packit |
fd8b60 |
gss_buffer_desc display_value;
|
|
Packit |
fd8b60 |
int authenticated = 0;
|
|
Packit |
fd8b60 |
int complete = 0;
|
|
Packit |
fd8b60 |
int more = -1;
|
|
Packit |
fd8b60 |
unsigned int i;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
while (more != 0) {
|
|
Packit |
fd8b60 |
value.value = NULL;
|
|
Packit |
fd8b60 |
display_value.value = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_get_name_attribute(&minor, name, attribute, &authenticated,
|
|
Packit |
fd8b60 |
&complete, &value, &display_value,
|
|
Packit |
fd8b60 |
&more);
|
|
Packit |
fd8b60 |
check_gsserr("gss_get_name_attribute", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
printf("Attribute %.*s %s %s\n\n%.*s\n",
|
|
Packit |
fd8b60 |
(int)attribute->length, (char *)attribute->value,
|
|
Packit |
fd8b60 |
authenticated ? "Authenticated" : "",
|
|
Packit |
fd8b60 |
complete ? "Complete" : "",
|
|
Packit |
fd8b60 |
(int)display_value.length, (char *)display_value.value);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (noisy) {
|
|
Packit |
fd8b60 |
for (i = 0; i < value.length; i++) {
|
|
Packit |
fd8b60 |
if ((i % 32) == 0)
|
|
Packit |
fd8b60 |
printf("\n");
|
|
Packit |
fd8b60 |
printf("%02x", ((char *)value.value)[i] & 0xFF);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
printf("\n\n");
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &value);
|
|
Packit |
fd8b60 |
(void)gss_release_buffer(&minor, &display_value);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
enumerate_attributes(gss_name_t name, int noisy)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
OM_uint32 major, minor;
|
|
Packit |
fd8b60 |
int is_mechname;
|
|
Packit |
fd8b60 |
gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;
|
|
Packit |
fd8b60 |
size_t i;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
major = gss_inquire_name(&minor, name, &is_mechname, NULL, &attrs);
|
|
Packit |
fd8b60 |
check_gsserr("gss_inquire_name", major, minor);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (attrs != GSS_C_NO_BUFFER_SET) {
|
|
Packit |
fd8b60 |
for (i = 0; i < attrs->count; i++)
|
|
Packit |
fd8b60 |
dump_attribute(name, &attrs->elements[i], noisy);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
(void)gss_release_buffer_set(&minor, &attrs);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
void
|
|
Packit |
fd8b60 |
print_hex(FILE *fp, gss_buffer_t buf)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
size_t i;
|
|
Packit |
fd8b60 |
const unsigned char *bytes = buf->value;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < buf->length; i++)
|
|
Packit |
fd8b60 |
printf("%02X", bytes[i]);
|
|
Packit |
fd8b60 |
printf("\n");
|
|
Packit |
fd8b60 |
}
|