Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_import_name.c
34907 views
/*-1* Copyright (c) 2005 Doug Rabson2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25* $FreeBSD: src/lib/libgssapi/gss_import_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $26*/2728#include "mech_locl.h"2930static OM_uint3231_gss_import_export_name(OM_uint32 *minor_status,32const gss_buffer_t input_name_buffer,33gss_name_t *output_name)34{35OM_uint32 major_status;36unsigned char *p = input_name_buffer->value;37size_t len = input_name_buffer->length;38size_t t;39gss_OID_desc mech_oid;40gssapi_mech_interface m;41struct _gss_name *name;42gss_name_t new_canonical_name;43int composite = 0;4445*minor_status = 0;46*output_name = 0;4748/*49* Make sure that TOK_ID is {4, 1}.50*/51if (len < 2)52return (GSS_S_BAD_NAME);53if (p[0] != 4)54return (GSS_S_BAD_NAME);55switch (p[1]) {56case 1: /* non-composite name */57break;58case 2: /* composite name */59composite = 1;60break;61default:62return (GSS_S_BAD_NAME);63}64p += 2;65len -= 2;6667/*68* Get the mech length and the name length and sanity69* check the size of of the buffer.70*/71if (len < 2)72return (GSS_S_BAD_NAME);73t = (p[0] << 8) + p[1];74p += 2;75len -= 2;7677/*78* Check the DER encoded OID to make sure it agrees with the79* length we just decoded.80*/81if (p[0] != 6) /* 6=OID */82return (GSS_S_BAD_NAME);83p++;84len--;85t--;86if (p[0] & 0x80) {87int digits = p[0];88p++;89len--;90t--;91mech_oid.length = 0;92while (digits--) {93mech_oid.length = (mech_oid.length << 8) | p[0];94p++;95len--;96t--;97}98} else {99mech_oid.length = p[0];100p++;101len--;102t--;103}104if (mech_oid.length != t)105return (GSS_S_BAD_NAME);106107mech_oid.elements = p;108109if (len < t + 4)110return (GSS_S_BAD_NAME);111p += t;112len -= t;113114t = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];115/* p += 4; */116len -= 4;117118if (!composite && len != t)119return (GSS_S_BAD_NAME);120121m = __gss_get_mechanism(&mech_oid);122if (!m)123return (GSS_S_BAD_MECH);124125/*126* Ask the mechanism to import the name.127*/128major_status = m->gm_import_name(minor_status,129input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name);130if (major_status != GSS_S_COMPLETE) {131_gss_mg_error(m, major_status, *minor_status);132return major_status;133}134135/*136* Now we make a new name and mark it as an MN.137*/138name = _gss_make_name(m, new_canonical_name);139if (!name) {140m->gm_release_name(minor_status, &new_canonical_name);141return (GSS_S_FAILURE);142}143144*output_name = (gss_name_t) name;145146*minor_status = 0;147return (GSS_S_COMPLETE);148}149150/**151* Import a name internal or mechanism name152*153* Type of name and their format:154* - GSS_C_NO_OID155* - GSS_C_NT_USER_NAME156* - GSS_C_NT_HOSTBASED_SERVICE157* - GSS_C_NT_EXPORT_NAME158* - GSS_C_NT_ANONYMOUS159* - GSS_KRB5_NT_PRINCIPAL_NAME160*161* For more information about @ref internalVSmechname.162*163* @param minor_status minor status code164* @param input_name_buffer import name buffer165* @param input_name_type type of the import name buffer166* @param output_name the resulting type, release with167* gss_release_name(), independent of input_name168*169* @returns a gss_error code, see gss_display_status() about printing170* the error code.171*172* @ingroup gssapi173*/174175GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL176gss_import_name(OM_uint32 *minor_status,177const gss_buffer_t input_name_buffer,178const gss_OID input_name_type,179gss_name_t *output_name)180{181struct _gss_mechanism_name *mn;182gss_OID name_type = input_name_type;183OM_uint32 major_status, ms;184struct _gss_name *name;185struct _gss_mech_switch *m;186gss_name_t rname;187188*output_name = GSS_C_NO_NAME;189190if (input_name_buffer->length == 0) {191*minor_status = 0;192return (GSS_S_BAD_NAME);193}194195_gss_load_mech();196197/*198* Use GSS_NT_USER_NAME as default name type.199*/200if (name_type == GSS_C_NO_OID)201name_type = GSS_C_NT_USER_NAME;202203/*204* If this is an exported name, we need to parse it to find205* the mechanism and then import it as an MN. See RFC 2743206* section 3.2 for a description of the format.207*/208if (gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME)) {209return _gss_import_export_name(minor_status,210input_name_buffer, output_name);211}212213214*minor_status = 0;215name = calloc(1, sizeof(struct _gss_name));216if (!name) {217*minor_status = ENOMEM;218return (GSS_S_FAILURE);219}220221HEIM_SLIST_INIT(&name->gn_mn);222223major_status = _gss_copy_oid(minor_status,224name_type, &name->gn_type);225if (major_status) {226free(name);227return (GSS_S_FAILURE);228}229230major_status = _gss_copy_buffer(minor_status,231input_name_buffer, &name->gn_value);232if (major_status)233goto out;234235/*236* Walk over the mechs and import the name into a mech name237* for those supported this nametype.238*/239240HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {241int present = 0;242243major_status = gss_test_oid_set_member(minor_status,244name_type, m->gm_name_types, &present);245246if (major_status || present == 0)247continue;248249mn = malloc(sizeof(struct _gss_mechanism_name));250if (!mn) {251*minor_status = ENOMEM;252major_status = GSS_S_FAILURE;253goto out;254}255256major_status = (*m->gm_mech.gm_import_name)(minor_status,257&name->gn_value,258(name->gn_type.elements259? &name->gn_type : GSS_C_NO_OID),260&mn->gmn_name);261if (major_status != GSS_S_COMPLETE) {262_gss_mg_error(&m->gm_mech, major_status, *minor_status);263free(mn);264goto out;265}266267mn->gmn_mech = &m->gm_mech;268mn->gmn_mech_oid = &m->gm_mech_oid;269HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);270}271272/*273* If we can't find a mn for the name, bail out already here.274*/275276mn = HEIM_SLIST_FIRST(&name->gn_mn);277if (!mn) {278*minor_status = 0;279major_status = GSS_S_NAME_NOT_MN;280goto out;281}282283*output_name = (gss_name_t) name;284return (GSS_S_COMPLETE);285286out:287rname = (gss_name_t)name;288gss_release_name(&ms, &rname);289return major_status;290}291292293