1178825Sdfr/* 2178825Sdfr * Copyright (c) 2004, PADL Software Pty Ltd. 3178825Sdfr * All rights reserved. 4178825Sdfr * 5178825Sdfr * Redistribution and use in source and binary forms, with or without 6178825Sdfr * modification, are permitted provided that the following conditions 7178825Sdfr * are met: 8178825Sdfr * 9178825Sdfr * 1. Redistributions of source code must retain the above copyright 10178825Sdfr * notice, this list of conditions and the following disclaimer. 11178825Sdfr * 12178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 13178825Sdfr * notice, this list of conditions and the following disclaimer in the 14178825Sdfr * documentation and/or other materials provided with the distribution. 15178825Sdfr * 16178825Sdfr * 3. Neither the name of PADL Software nor the names of its contributors 17178825Sdfr * may be used to endorse or promote products derived from this software 18178825Sdfr * without specific prior written permission. 19178825Sdfr * 20178825Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30178825Sdfr * SUCH DAMAGE. 31178825Sdfr */ 32178825Sdfr 33233294Sstas#include "spnego_locl.h" 34178825Sdfr 35233294SstasOM_uint32 GSSAPI_CALLCONV 36178825Sdfr_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) 37178825Sdfr{ 38178825Sdfr OM_uint32 ret; 39233294Sstas 40178825Sdfr *minor_status = 0; 41178825Sdfr 42233294Sstas if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) 43178825Sdfr return GSS_S_COMPLETE; 44178825Sdfr 45233294Sstas ret = gss_release_cred(minor_status, cred_handle); 46178825Sdfr 47178825Sdfr *cred_handle = GSS_C_NO_CREDENTIAL; 48178825Sdfr 49178825Sdfr return ret; 50178825Sdfr} 51178825Sdfr 52178825Sdfr/* 53178825Sdfr * For now, just a simple wrapper that avoids recursion. When 54178825Sdfr * we support gss_{get,set}_neg_mechs() we will need to expose 55178825Sdfr * more functionality. 56178825Sdfr */ 57233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_acquire_cred 58178825Sdfr(OM_uint32 *minor_status, 59178825Sdfr const gss_name_t desired_name, 60178825Sdfr OM_uint32 time_req, 61178825Sdfr const gss_OID_set desired_mechs, 62178825Sdfr gss_cred_usage_t cred_usage, 63178825Sdfr gss_cred_id_t * output_cred_handle, 64178825Sdfr gss_OID_set * actual_mechs, 65178825Sdfr OM_uint32 * time_rec 66178825Sdfr ) 67178825Sdfr{ 68178825Sdfr const spnego_name dname = (const spnego_name)desired_name; 69178825Sdfr gss_name_t name = GSS_C_NO_NAME; 70178825Sdfr OM_uint32 ret, tmp; 71178825Sdfr gss_OID_set_desc actual_desired_mechs; 72178825Sdfr gss_OID_set mechs; 73233294Sstas size_t i, j; 74178825Sdfr 75178825Sdfr *output_cred_handle = GSS_C_NO_CREDENTIAL; 76178825Sdfr 77178825Sdfr if (dname) { 78178825Sdfr ret = gss_import_name(minor_status, &dname->value, &dname->type, &name); 79178825Sdfr if (ret) { 80178825Sdfr return ret; 81178825Sdfr } 82178825Sdfr } 83233294Sstas 84178825Sdfr ret = gss_indicate_mechs(minor_status, &mechs); 85178825Sdfr if (ret != GSS_S_COMPLETE) { 86178825Sdfr gss_release_name(minor_status, &name); 87178825Sdfr return ret; 88178825Sdfr } 89178825Sdfr 90178825Sdfr /* Remove ourselves from this list */ 91178825Sdfr actual_desired_mechs.count = mechs->count; 92178825Sdfr actual_desired_mechs.elements = malloc(actual_desired_mechs.count * 93178825Sdfr sizeof(gss_OID_desc)); 94178825Sdfr if (actual_desired_mechs.elements == NULL) { 95178825Sdfr *minor_status = ENOMEM; 96178825Sdfr ret = GSS_S_FAILURE; 97178825Sdfr goto out; 98178825Sdfr } 99178825Sdfr 100178825Sdfr for (i = 0, j = 0; i < mechs->count; i++) { 101178825Sdfr if (gss_oid_equal(&mechs->elements[i], GSS_SPNEGO_MECHANISM)) 102178825Sdfr continue; 103178825Sdfr 104178825Sdfr actual_desired_mechs.elements[j] = mechs->elements[i]; 105178825Sdfr j++; 106178825Sdfr } 107178825Sdfr actual_desired_mechs.count = j; 108178825Sdfr 109178825Sdfr ret = gss_acquire_cred(minor_status, name, 110178825Sdfr time_req, &actual_desired_mechs, 111178825Sdfr cred_usage, 112233294Sstas output_cred_handle, 113178825Sdfr actual_mechs, time_rec); 114178825Sdfr if (ret != GSS_S_COMPLETE) 115178825Sdfr goto out; 116178825Sdfr 117178825Sdfrout: 118178825Sdfr gss_release_name(minor_status, &name); 119178825Sdfr gss_release_oid_set(&tmp, &mechs); 120178825Sdfr if (actual_desired_mechs.elements != NULL) { 121178825Sdfr free(actual_desired_mechs.elements); 122178825Sdfr } 123178825Sdfr if (ret != GSS_S_COMPLETE) { 124233294Sstas _gss_spnego_release_cred(&tmp, output_cred_handle); 125178825Sdfr } 126178825Sdfr 127178825Sdfr return ret; 128178825Sdfr} 129178825Sdfr 130233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred 131178825Sdfr (OM_uint32 * minor_status, 132178825Sdfr const gss_cred_id_t cred_handle, 133178825Sdfr gss_name_t * name, 134178825Sdfr OM_uint32 * lifetime, 135178825Sdfr gss_cred_usage_t * cred_usage, 136178825Sdfr gss_OID_set * mechanisms 137178825Sdfr ) 138178825Sdfr{ 139178825Sdfr spnego_name sname = NULL; 140178825Sdfr OM_uint32 ret; 141178825Sdfr 142178825Sdfr if (cred_handle == GSS_C_NO_CREDENTIAL) { 143178825Sdfr *minor_status = 0; 144178825Sdfr return GSS_S_NO_CRED; 145178825Sdfr } 146178825Sdfr 147178825Sdfr if (name) { 148178825Sdfr sname = calloc(1, sizeof(*sname)); 149178825Sdfr if (sname == NULL) { 150178825Sdfr *minor_status = ENOMEM; 151178825Sdfr return GSS_S_FAILURE; 152178825Sdfr } 153178825Sdfr } 154178825Sdfr 155178825Sdfr ret = gss_inquire_cred(minor_status, 156233294Sstas cred_handle, 157178825Sdfr sname ? &sname->mech : NULL, 158178825Sdfr lifetime, 159178825Sdfr cred_usage, 160178825Sdfr mechanisms); 161178825Sdfr if (ret) { 162178825Sdfr if (sname) 163178825Sdfr free(sname); 164178825Sdfr return ret; 165178825Sdfr } 166178825Sdfr if (name) 167178825Sdfr *name = (gss_name_t)sname; 168178825Sdfr 169178825Sdfr return ret; 170178825Sdfr} 171178825Sdfr 172233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_mech ( 173178825Sdfr OM_uint32 * minor_status, 174178825Sdfr const gss_cred_id_t cred_handle, 175178825Sdfr const gss_OID mech_type, 176178825Sdfr gss_name_t * name, 177178825Sdfr OM_uint32 * initiator_lifetime, 178178825Sdfr OM_uint32 * acceptor_lifetime, 179178825Sdfr gss_cred_usage_t * cred_usage 180178825Sdfr ) 181178825Sdfr{ 182178825Sdfr spnego_name sname = NULL; 183178825Sdfr OM_uint32 ret; 184178825Sdfr 185178825Sdfr if (cred_handle == GSS_C_NO_CREDENTIAL) { 186178825Sdfr *minor_status = 0; 187178825Sdfr return GSS_S_NO_CRED; 188178825Sdfr } 189178825Sdfr 190178825Sdfr if (name) { 191178825Sdfr sname = calloc(1, sizeof(*sname)); 192178825Sdfr if (sname == NULL) { 193178825Sdfr *minor_status = ENOMEM; 194178825Sdfr return GSS_S_FAILURE; 195178825Sdfr } 196178825Sdfr } 197178825Sdfr 198178825Sdfr ret = gss_inquire_cred_by_mech(minor_status, 199233294Sstas cred_handle, 200178825Sdfr mech_type, 201178825Sdfr sname ? &sname->mech : NULL, 202178825Sdfr initiator_lifetime, 203178825Sdfr acceptor_lifetime, 204178825Sdfr cred_usage); 205178825Sdfr 206178825Sdfr if (ret) { 207178825Sdfr if (sname) 208178825Sdfr free(sname); 209178825Sdfr return ret; 210178825Sdfr } 211178825Sdfr if (name) 212178825Sdfr *name = (gss_name_t)sname; 213178825Sdfr 214178825Sdfr return GSS_S_COMPLETE; 215178825Sdfr} 216178825Sdfr 217233294SstasOM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_oid 218178825Sdfr (OM_uint32 * minor_status, 219178825Sdfr const gss_cred_id_t cred_handle, 220178825Sdfr const gss_OID desired_object, 221178825Sdfr gss_buffer_set_t *data_set) 222178825Sdfr{ 223178825Sdfr OM_uint32 ret; 224178825Sdfr 225178825Sdfr if (cred_handle == GSS_C_NO_CREDENTIAL) { 226178825Sdfr *minor_status = 0; 227178825Sdfr return GSS_S_NO_CRED; 228178825Sdfr } 229178825Sdfr 230178825Sdfr ret = gss_inquire_cred_by_oid(minor_status, 231233294Sstas cred_handle, 232178825Sdfr desired_object, 233178825Sdfr data_set); 234178825Sdfr 235178825Sdfr return ret; 236178825Sdfr} 237178825Sdfr 238233294SstasOM_uint32 GSSAPI_CALLCONV 239233294Sstas_gss_spnego_set_cred_option (OM_uint32 *minor_status, 240233294Sstas gss_cred_id_t *cred_handle, 241233294Sstas const gss_OID object, 242233294Sstas const gss_buffer_t value) 243233294Sstas{ 244233294Sstas if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { 245233294Sstas *minor_status = 0; 246233294Sstas return GSS_S_NO_CRED; 247233294Sstas } 248233294Sstas 249233294Sstas return gss_set_cred_option(minor_status, 250233294Sstas cred_handle, 251233294Sstas object, 252233294Sstas value); 253233294Sstas} 254233294Sstas 255233294Sstas#if 0 256233294Sstas 257233294SstasOM_uint32 GSSAPI_CALLCONV 258233294Sstas_gss_spnego_export_cred (OM_uint32 *minor_status, 259233294Sstas gss_cred_id_t cred_handle, 260233294Sstas gss_buffer_t value) 261233294Sstas{ 262233294Sstas return gss_export_cred(minor_status, cred_handle, value); 263233294Sstas} 264233294Sstas 265233294SstasOM_uint32 GSSAPI_CALLCONV 266233294Sstas_gss_spnego_import_cred (OM_uint32 *minor_status, 267233294Sstas gss_buffer_t value, 268233294Sstas gss_cred_id_t *cred_handle) 269233294Sstas{ 270233294Sstas return gss_import_cred(minor_status, value, cred_handle); 271233294Sstas} 272233294Sstas 273233294Sstas#endif 274