1226031Sstas/* 2226031Sstas * Copyright (c) 2009 Kungliga Tekniska H��gskolan 3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4226031Sstas * All rights reserved. 5226031Sstas * 6226031Sstas * Redistribution and use in source and binary forms, with or without 7226031Sstas * modification, are permitted provided that the following conditions 8226031Sstas * are met: 9226031Sstas * 10226031Sstas * 1. Redistributions of source code must retain the above copyright 11226031Sstas * notice, this list of conditions and the following disclaimer. 12226031Sstas * 13226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 14226031Sstas * notice, this list of conditions and the following disclaimer in the 15226031Sstas * documentation and/or other materials provided with the distribution. 16226031Sstas * 17226031Sstas * 3. Neither the name of KTH nor the names of its contributors may be 18226031Sstas * used to endorse or promote products derived from this software without 19226031Sstas * specific prior written permission. 20226031Sstas * 21226031Sstas * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22226031Sstas * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24226031Sstas * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25226031Sstas * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26226031Sstas * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27226031Sstas * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28226031Sstas * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29226031Sstas * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30226031Sstas * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31226031Sstas * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32226031Sstas */ 33226031Sstas 34226031Sstas#include "mech_locl.h" 35226031Sstas#include <krb5.h> 36226031Sstas 37226031Sstas/* 38226031Sstas * format: any number of: 39226031Sstas * mech-len: int32 40226031Sstas * mech-data: char * (not alligned) 41226031Sstas * cred-len: int32 42226031Sstas * cred-data char * (not alligned) 43226031Sstas*/ 44226031Sstas 45226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 46226031Sstasgss_export_cred(OM_uint32 * minor_status, 47226031Sstas gss_cred_id_t cred_handle, 48226031Sstas gss_buffer_t token) 49226031Sstas{ 50226031Sstas struct _gss_cred *cred = (struct _gss_cred *)cred_handle; 51226031Sstas struct _gss_mechanism_cred *mc; 52226031Sstas gss_buffer_desc buffer; 53226031Sstas krb5_error_code ret; 54226031Sstas krb5_storage *sp; 55226031Sstas OM_uint32 major; 56226031Sstas krb5_data data; 57226031Sstas 58226031Sstas _mg_buffer_zero(token); 59226031Sstas 60226031Sstas if (cred == NULL) { 61226031Sstas *minor_status = 0; 62226031Sstas return GSS_S_NO_CRED; 63226031Sstas } 64226031Sstas 65226031Sstas HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { 66226031Sstas if (mc->gmc_mech->gm_export_cred == NULL) { 67226031Sstas *minor_status = 0; 68226031Sstas return GSS_S_NO_CRED; 69226031Sstas } 70226031Sstas } 71226031Sstas 72226031Sstas sp = krb5_storage_emem(); 73226031Sstas if (sp == NULL) { 74226031Sstas *minor_status = ENOMEM; 75226031Sstas return GSS_S_FAILURE; 76226031Sstas } 77226031Sstas 78226031Sstas HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { 79226031Sstas 80226031Sstas major = mc->gmc_mech->gm_export_cred(minor_status, 81226031Sstas mc->gmc_cred, &buffer); 82226031Sstas if (major) { 83226031Sstas krb5_storage_free(sp); 84226031Sstas return major; 85226031Sstas } 86226031Sstas 87226031Sstas ret = krb5_storage_write(sp, buffer.value, buffer.length); 88226031Sstas if (ret < 0 || (size_t)ret != buffer.length) { 89226031Sstas gss_release_buffer(minor_status, &buffer); 90226031Sstas krb5_storage_free(sp); 91226031Sstas *minor_status = EINVAL; 92226031Sstas return GSS_S_FAILURE; 93226031Sstas } 94226031Sstas gss_release_buffer(minor_status, &buffer); 95226031Sstas } 96226031Sstas 97226031Sstas ret = krb5_storage_to_data(sp, &data); 98226031Sstas krb5_storage_free(sp); 99226031Sstas if (ret) { 100226031Sstas *minor_status = ret; 101226031Sstas return GSS_S_FAILURE; 102226031Sstas } 103226031Sstas 104226031Sstas token->value = data.data; 105226031Sstas token->length = data.length; 106226031Sstas 107226031Sstas return GSS_S_COMPLETE; 108226031Sstas} 109226031Sstas 110226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 111226031Sstasgss_import_cred(OM_uint32 * minor_status, 112226031Sstas gss_buffer_t token, 113226031Sstas gss_cred_id_t * cred_handle) 114226031Sstas{ 115226031Sstas gssapi_mech_interface m; 116226031Sstas krb5_error_code ret; 117226031Sstas struct _gss_cred *cred; 118226031Sstas krb5_storage *sp = NULL; 119226031Sstas OM_uint32 major, junk; 120226031Sstas krb5_data data; 121226031Sstas 122226031Sstas *cred_handle = GSS_C_NO_CREDENTIAL; 123226031Sstas 124226031Sstas if (token->length == 0) { 125226031Sstas *minor_status = ENOMEM; 126226031Sstas return GSS_S_FAILURE; 127226031Sstas } 128226031Sstas 129226031Sstas sp = krb5_storage_from_readonly_mem(token->value, token->length); 130226031Sstas if (sp == NULL) { 131226031Sstas *minor_status = ENOMEM; 132226031Sstas return GSS_S_FAILURE; 133226031Sstas } 134226031Sstas 135226031Sstas cred = calloc(1, sizeof(struct _gss_cred)); 136226031Sstas if (cred == NULL) { 137226031Sstas krb5_storage_free(sp); 138226031Sstas *minor_status = ENOMEM; 139226031Sstas return GSS_S_FAILURE; 140226031Sstas } 141226031Sstas HEIM_SLIST_INIT(&cred->gc_mc); 142226031Sstas 143226031Sstas *cred_handle = (gss_cred_id_t)cred; 144226031Sstas 145226031Sstas while(1) { 146226031Sstas struct _gss_mechanism_cred *mc; 147226031Sstas gss_buffer_desc buffer; 148226031Sstas gss_cred_id_t mcred; 149226031Sstas gss_OID_desc oid; 150226031Sstas 151226031Sstas ret = krb5_ret_data(sp, &data); 152226031Sstas if (ret == HEIM_ERR_EOF) { 153226031Sstas break; 154226031Sstas } else if (ret) { 155226031Sstas *minor_status = ret; 156226031Sstas major = GSS_S_FAILURE; 157226031Sstas goto out; 158226031Sstas } 159226031Sstas oid.elements = data.data; 160226031Sstas oid.length = data.length; 161226031Sstas 162226031Sstas m = __gss_get_mechanism(&oid); 163226031Sstas krb5_data_free(&data); 164226031Sstas if (!m) { 165226031Sstas *minor_status = 0; 166226031Sstas major = GSS_S_BAD_MECH; 167226031Sstas goto out; 168226031Sstas } 169226031Sstas 170226031Sstas if (m->gm_import_cred == NULL) { 171226031Sstas *minor_status = 0; 172226031Sstas major = GSS_S_BAD_MECH; 173226031Sstas goto out; 174226031Sstas } 175226031Sstas 176226031Sstas ret = krb5_ret_data(sp, &data); 177226031Sstas if (ret) { 178226031Sstas *minor_status = ret; 179226031Sstas major = GSS_S_FAILURE; 180226031Sstas goto out; 181226031Sstas } 182226031Sstas 183226031Sstas buffer.value = data.data; 184226031Sstas buffer.length = data.length; 185226031Sstas 186226031Sstas major = m->gm_import_cred(minor_status, 187226031Sstas &buffer, &mcred); 188226031Sstas krb5_data_free(&data); 189226031Sstas if (major) { 190226031Sstas goto out; 191226031Sstas } 192226031Sstas 193226031Sstas mc = malloc(sizeof(struct _gss_mechanism_cred)); 194226031Sstas if (mc == NULL) { 195226031Sstas *minor_status = EINVAL; 196226031Sstas major = GSS_S_FAILURE; 197226031Sstas goto out; 198226031Sstas } 199226031Sstas 200226031Sstas mc->gmc_mech = m; 201226031Sstas mc->gmc_mech_oid = &m->gm_mech_oid; 202226031Sstas mc->gmc_cred = mcred; 203226031Sstas 204226031Sstas HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); 205226031Sstas } 206226031Sstas krb5_storage_free(sp); 207226031Sstas sp = NULL; 208226031Sstas 209226031Sstas if (HEIM_SLIST_EMPTY(&cred->gc_mc)) { 210226031Sstas major = GSS_S_NO_CRED; 211226031Sstas goto out; 212226031Sstas } 213226031Sstas 214226031Sstas return GSS_S_COMPLETE; 215226031Sstas 216226031Sstas out: 217226031Sstas if (sp) 218226031Sstas krb5_storage_free(sp); 219226031Sstas 220226031Sstas gss_release_cred(&junk, cred_handle); 221226031Sstas 222226031Sstas return major; 223226031Sstas 224226031Sstas} 225