gss_init_sec_context.c revision 170734
1193323Sed/*- 2193323Sed * Copyright (c) 2005 Doug Rabson 3193323Sed * All rights reserved. 4193323Sed * 5193323Sed * Redistribution and use in source and binary forms, with or without 6193323Sed * modification, are permitted provided that the following conditions 7193323Sed * are met: 8193323Sed * 1. Redistributions of source code must retain the above copyright 9193323Sed * notice, this list of conditions and the following disclaimer. 10193323Sed * 2. Redistributions in binary form must reproduce the above copyright 11193323Sed * notice, this list of conditions and the following disclaimer in the 12193323Sed * documentation and/or other materials provided with the distribution. 13193323Sed * 14193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17193323Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18193323Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20198090Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21198090Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22193323Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23193323Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24193323Sed * SUCH DAMAGE. 25193323Sed * 26198090Srdivacky * $FreeBSD: head/lib/libgssapi/gss_init_sec_context.c 170734 2007-06-14 19:58:24Z harti $ 27198090Srdivacky */ 28198090Srdivacky 29198090Srdivacky#include <gssapi/gssapi.h> 30198090Srdivacky#include <stdlib.h> 31193323Sed#include <string.h> 32193323Sed#include <errno.h> 33193323Sed 34193323Sed#include "mech_switch.h" 35193323Sed#include "name.h" 36193323Sed#include "cred.h" 37193323Sed#include "context.h" 38193323Sed 39193323SedOM_uint32 40193323Sedgss_init_sec_context(OM_uint32 * minor_status, 41198090Srdivacky const gss_cred_id_t initiator_cred_handle, 42198090Srdivacky gss_ctx_id_t * context_handle, 43198090Srdivacky const gss_name_t target_name, 44198090Srdivacky const gss_OID imech_type, 45193323Sed OM_uint32 req_flags, 46193323Sed OM_uint32 time_req, 47193323Sed const gss_channel_bindings_t input_chan_bindings, 48193323Sed const gss_buffer_t input_token, 49193323Sed gss_OID * actual_mech_type, 50193323Sed gss_buffer_t output_token, 51193323Sed OM_uint32 * ret_flags, 52193323Sed OM_uint32 * time_rec) 53198090Srdivacky{ 54198090Srdivacky OM_uint32 major_status; 55207618Srdivacky gss_OID mech_type; 56193323Sed struct _gss_mech_switch *m; 57193323Sed struct _gss_name *name = (struct _gss_name *) target_name; 58193323Sed struct _gss_mechanism_name *mn; 59193323Sed struct _gss_context *ctx = (struct _gss_context *) *context_handle; 60193323Sed struct _gss_cred *cred = (struct _gss_cred *) initiator_cred_handle; 61193323Sed struct _gss_mechanism_cred *mc; 62193323Sed gss_cred_id_t cred_handle; 63193323Sed int allocated_ctx; 64193323Sed 65193323Sed *minor_status = 0; 66193323Sed 67198090Srdivacky if ((mech_type = imech_type) == GSS_C_NO_OID) { 68198090Srdivacky _gss_load_mech(); 69198090Srdivacky mech_type = &SLIST_FIRST(&_gss_mechs)->gm_mech_oid; 70198090Srdivacky if (mech_type == NULL) 71193323Sed return (GSS_S_BAD_MECH); 72198090Srdivacky } 73198090Srdivacky 74193323Sed /* 75198090Srdivacky * If we haven't allocated a context yet, do so now and lookup 76193323Sed * the mechanism switch table. If we have one already, make 77193323Sed * sure we use the same mechanism switch as before. 78193323Sed */ 79193323Sed if (!ctx) { 80193323Sed ctx = malloc(sizeof(struct _gss_context)); 81193323Sed if (!ctx) { 82198090Srdivacky *minor_status = ENOMEM; 83198090Srdivacky return (GSS_S_FAILURE); 84198090Srdivacky } 85198090Srdivacky memset(ctx, 0, sizeof(struct _gss_context)); 86198090Srdivacky m = ctx->gc_mech = _gss_find_mech_switch(mech_type); 87207618Srdivacky if (!m) { 88198090Srdivacky free(ctx); 89198090Srdivacky return (GSS_S_BAD_MECH); 90198090Srdivacky } 91198090Srdivacky allocated_ctx = 1; 92198090Srdivacky } else { 93198090Srdivacky m = ctx->gc_mech; 94198090Srdivacky allocated_ctx = 0; 95198090Srdivacky } 96198090Srdivacky 97198090Srdivacky /* 98198090Srdivacky * Find the MN for this mechanism. 99193323Sed */ 100198090Srdivacky mn = _gss_find_mn(name, mech_type); 101198090Srdivacky 102198090Srdivacky /* 103198090Srdivacky * If we have a cred, find the cred for this mechanism. 104198090Srdivacky */ 105198090Srdivacky cred_handle = GSS_C_NO_CREDENTIAL; 106198090Srdivacky if (cred) { 107198090Srdivacky SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { 108193323Sed if (_gss_oid_equal(mech_type, mc->gmc_mech_oid)) { 109198090Srdivacky cred_handle = mc->gmc_cred; 110198090Srdivacky break; 111198090Srdivacky } 112198090Srdivacky } 113198090Srdivacky } 114198090Srdivacky 115198090Srdivacky major_status = m->gm_init_sec_context(minor_status, 116198090Srdivacky cred_handle, 117198090Srdivacky &ctx->gc_ctx, 118198090Srdivacky mn->gmn_name, 119198090Srdivacky mech_type, 120198090Srdivacky req_flags, 121198090Srdivacky time_req, 122198090Srdivacky input_chan_bindings, 123198090Srdivacky input_token, 124198090Srdivacky actual_mech_type, 125198090Srdivacky output_token, 126198090Srdivacky ret_flags, 127198090Srdivacky time_rec); 128198090Srdivacky 129198090Srdivacky if (major_status != GSS_S_COMPLETE 130207618Srdivacky && major_status != GSS_S_CONTINUE_NEEDED) { 131198090Srdivacky if (allocated_ctx) 132198090Srdivacky free(ctx); 133198090Srdivacky } else { 134198090Srdivacky *context_handle = (gss_ctx_id_t) ctx; 135198090Srdivacky } 136207618Srdivacky 137193323Sed return (major_status); 138193323Sed} 139193323Sed