Path: blob/main/crypto/heimdal/lib/gssapi/krb5/import_name.c
34923 views
/*1* Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "gsskrb5_locl.h"3435static OM_uint3236parse_krb5_name (OM_uint32 *minor_status,37krb5_context context,38const char *name,39gss_name_t *output_name)40{41krb5_principal princ;42krb5_error_code kerr;4344kerr = krb5_parse_name (context, name, &princ);4546if (kerr == 0) {47*output_name = (gss_name_t)princ;48return GSS_S_COMPLETE;49}50*minor_status = kerr;5152if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)53return GSS_S_BAD_NAME;5455return GSS_S_FAILURE;56}5758static OM_uint3259import_krb5_name (OM_uint32 *minor_status,60krb5_context context,61const gss_buffer_t input_name_buffer,62gss_name_t *output_name)63{64OM_uint32 ret;65char *tmp;6667tmp = malloc (input_name_buffer->length + 1);68if (tmp == NULL) {69*minor_status = ENOMEM;70return GSS_S_FAILURE;71}72memcpy (tmp,73input_name_buffer->value,74input_name_buffer->length);75tmp[input_name_buffer->length] = '\0';7677ret = parse_krb5_name(minor_status, context, tmp, output_name);78free(tmp);7980return ret;81}8283OM_uint3284_gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,85int use_dns, krb5_const_principal sourcename, gss_name_t targetname,86krb5_principal *out)87{88krb5_principal p = (krb5_principal)targetname;89krb5_error_code ret;90char *hostname = NULL, *service;9192*minor_status = 0;9394/* If its not a hostname */95if (krb5_principal_get_type(context, p) != MAGIC_HOSTBASED_NAME_TYPE) {96ret = krb5_copy_principal(context, p, out);97} else if (!use_dns) {98ret = krb5_copy_principal(context, p, out);99if (ret)100goto out;101krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);102if (sourcename)103ret = krb5_principal_set_realm(context, *out, sourcename->realm);104} else {105if (p->name.name_string.len == 0)106return GSS_S_BAD_NAME;107else if (p->name.name_string.len > 1)108hostname = p->name.name_string.val[1];109110service = p->name.name_string.val[0];111112ret = krb5_sname_to_principal(context,113hostname,114service,115KRB5_NT_SRV_HST,116out);117}118119out:120if (ret) {121*minor_status = ret;122return GSS_S_FAILURE;123}124125return 0;126}127128129static OM_uint32130import_hostbased_name (OM_uint32 *minor_status,131krb5_context context,132const gss_buffer_t input_name_buffer,133gss_name_t *output_name)134{135krb5_principal princ = NULL;136krb5_error_code kerr;137char *tmp, *p, *host = NULL;138139tmp = malloc (input_name_buffer->length + 1);140if (tmp == NULL) {141*minor_status = ENOMEM;142return GSS_S_FAILURE;143}144memcpy (tmp,145input_name_buffer->value,146input_name_buffer->length);147tmp[input_name_buffer->length] = '\0';148149p = strchr (tmp, '@');150if (p != NULL) {151*p = '\0';152host = p + 1;153}154155kerr = krb5_make_principal(context, &princ, NULL, tmp, host, NULL);156free (tmp);157*minor_status = kerr;158if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)159return GSS_S_BAD_NAME;160else if (kerr)161return GSS_S_FAILURE;162163krb5_principal_set_type(context, princ, MAGIC_HOSTBASED_NAME_TYPE);164*output_name = (gss_name_t)princ;165166return 0;167}168169static OM_uint32170import_export_name (OM_uint32 *minor_status,171krb5_context context,172const gss_buffer_t input_name_buffer,173gss_name_t *output_name)174{175unsigned char *p;176uint32_t length;177OM_uint32 ret;178char *name;179180if (input_name_buffer->length < 10 + GSS_KRB5_MECHANISM->length)181return GSS_S_BAD_NAME;182183/* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */184185p = input_name_buffer->value;186187if (memcmp(&p[0], "\x04\x01\x00", 3) != 0 ||188p[3] != GSS_KRB5_MECHANISM->length + 2 ||189p[4] != 0x06 ||190p[5] != GSS_KRB5_MECHANISM->length ||191memcmp(&p[6], GSS_KRB5_MECHANISM->elements,192GSS_KRB5_MECHANISM->length) != 0)193return GSS_S_BAD_NAME;194195p += 6 + GSS_KRB5_MECHANISM->length;196197length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];198p += 4;199200if (length > input_name_buffer->length - 10 - GSS_KRB5_MECHANISM->length)201return GSS_S_BAD_NAME;202203name = malloc(length + 1);204if (name == NULL) {205*minor_status = ENOMEM;206return GSS_S_FAILURE;207}208memcpy(name, p, length);209name[length] = '\0';210211ret = parse_krb5_name(minor_status, context, name, output_name);212free(name);213214return ret;215}216217OM_uint32 GSSAPI_CALLCONV _gsskrb5_import_name218(OM_uint32 * minor_status,219const gss_buffer_t input_name_buffer,220const gss_OID input_name_type,221gss_name_t * output_name222)223{224krb5_context context;225226*minor_status = 0;227*output_name = GSS_C_NO_NAME;228229GSSAPI_KRB5_INIT (&context);230231if (gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) ||232gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE_X))233return import_hostbased_name (minor_status,234context,235input_name_buffer,236output_name);237else if (input_name_type == GSS_C_NO_OID238|| gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)239|| gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))240/* default printable syntax */241return import_krb5_name (minor_status,242context,243input_name_buffer,244output_name);245else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) {246return import_export_name(minor_status,247context,248input_name_buffer,249output_name);250} else {251*minor_status = 0;252return GSS_S_BAD_NAMETYPE;253}254}255256257