creds.c revision 233294
143809Sjkh/* 243809Sjkh * Copyright (c) 2009 Kungliga Tekniska H��gskolan 387047Sru * (Royal Institute of Technology, Stockholm, Sweden). 443809Sjkh * All rights reserved. 543809Sjkh * 643809Sjkh * Redistribution and use in source and binary forms, with or without 743809Sjkh * modification, are permitted provided that the following conditions 843809Sjkh * are met: 959674Ssheldonh * 1059674Ssheldonh * 1. Redistributions of source code must retain the above copyright 1159674Ssheldonh * notice, this list of conditions and the following disclaimer. 1254949Ssheldonh * 1343809Sjkh * 2. Redistributions in binary form must reproduce the above copyright 1443809Sjkh * notice, this list of conditions and the following disclaimer in the 15140769Skeramida * documentation and/or other materials provided with the distribution. 16140769Skeramida * 17140769Skeramida * 3. Neither the name of the Institute nor the names of its contributors 1850472Speter * may be used to endorse or promote products derived from this software 1943809Sjkh * without specific prior written permission. 2043809Sjkh * 2148290Sjseger * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2243809Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2343809Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24109233Smtm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25119170Smtm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26197619Sdougb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2798188Sgordon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28168358Sache * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29153298Sdougb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30153298Sdougb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31153298Sdougb * SUCH DAMAGE. 32153298Sdougb */ 3343809Sjkh 3448785Siwasaki#include "gsskrb5_locl.h" 3548785Siwasaki 3648785SiwasakiOM_uint32 GSSAPI_CALLCONV 37178450Sbrooks_gsskrb5_export_cred(OM_uint32 *minor_status, 38176835Sbrooks gss_cred_id_t cred_handle, 39131338Simp gss_buffer_t cred_token) 40152770Sjkoshy{ 41112354Scjc gsskrb5_cred handle = (gsskrb5_cred)cred_handle; 42112354Scjc krb5_context context; 43112354Scjc krb5_error_code ret; 44142580Snjl krb5_storage *sp; 45142580Snjl krb5_data data, mech; 46127345Sbrooks const char *type; 47127345Sbrooks char *str; 48167268Syar 49127345Sbrooks GSSAPI_KRB5_INIT (&context); 50127345Sbrooks 51167268Syar if (handle->usage != GSS_C_INITIATE && handle->usage != GSS_C_BOTH) { 52127345Sbrooks *minor_status = GSS_KRB5_S_G_BAD_USAGE; 53153537Sdougb return GSS_S_FAILURE; 54170085Sdougb } 5579825Sroam 5643809Sjkh sp = krb5_storage_emem(); 57120195Sdougb if (sp == NULL) { 58168410Spjd *minor_status = ENOMEM; 59168410Spjd return GSS_S_FAILURE; 60168410Spjd } 61120195Sdougb 62120195Sdougb type = krb5_cc_get_type(context, handle->ccache); 63120195Sdougb if (strcmp(type, "MEMORY") == 0) { 64132356Ssimon krb5_creds *creds; 65132356Ssimon ret = krb5_store_uint32(sp, 0); 66120195Sdougb if (ret) { 67149050Spjd krb5_storage_free(sp); 68149050Spjd *minor_status = ret; 69149050Spjd return GSS_S_FAILURE; 70149050Spjd } 71149050Spjd 72149050Spjd ret = _krb5_get_krbtgt(context, handle->ccache, 73149050Spjd handle->principal->realm, 74149050Spjd &creds); 75149050Spjd if (ret) { 76149050Spjd krb5_storage_free(sp); 77149050Spjd *minor_status = ret; 78149050Spjd return GSS_S_FAILURE; 79149050Spjd } 80149050Spjd 81148765Spjd ret = krb5_store_creds(sp, creds); 82159377Sbrueffer krb5_free_creds(context, creds); 83149050Spjd if (ret) { 84149050Spjd krb5_storage_free(sp); 85136730Skeramida *minor_status = ret; 8687047Sru return GSS_S_FAILURE; 87193944Savg } 8876946Sdd 89108018Smckusick } else { 90138286Srees ret = krb5_store_uint32(sp, 1); 9188676Ssheldonh if (ret) { 9288676Ssheldonh krb5_storage_free(sp); 9343809Sjkh *minor_status = ret; 9443809Sjkh return GSS_S_FAILURE; 9543809Sjkh } 9643809Sjkh 9743809Sjkh ret = krb5_cc_get_full_name(context, handle->ccache, &str); 9864749Sjhb if (ret) { 9948880Sjkh krb5_storage_free(sp); 100168546Spjd *minor_status = ret; 101168546Spjd return GSS_S_FAILURE; 10243809Sjkh } 103115950Smtm 104168034Sache ret = krb5_store_string(sp, str); 105168034Sache free(str); 106190031Sdes if (ret) { 107168033Sache krb5_storage_free(sp); 108179003Sbrooks *minor_status = ret; 109157706Sbrooks return GSS_S_FAILURE; 110188710Smtm } 111178022Ssam } 112178022Ssam ret = krb5_storage_to_data(sp, &data); 113178022Ssam krb5_storage_free(sp); 114178022Ssam if (ret) { 11543809Sjkh *minor_status = ret; 11645542Sdes return GSS_S_FAILURE; 11743809Sjkh } 11843809Sjkh sp = krb5_storage_emem(); 11987047Sru if (sp == NULL) { 12057014Spaul krb5_data_free(&data); 121200028Sume *minor_status = ENOMEM; 122200028Sume return GSS_S_FAILURE; 123200028Sume } 124200028Sume 125181762Sjhb mech.data = GSS_KRB5_MECHANISM->elements; 126181762Sjhb mech.length = GSS_KRB5_MECHANISM->length; 127181762Sjhb 128181762Sjhb ret = krb5_store_data(sp, mech); 129181762Sjhb if (ret) { 130181762Sjhb krb5_data_free(&data); 131181762Sjhb krb5_storage_free(sp); 132181762Sjhb *minor_status = ret; 133200028Sume return GSS_S_FAILURE; 134200028Sume } 135200028Sume 136200028Sume ret = krb5_store_data(sp, data); 137200028Sume krb5_data_free(&data); 138200028Sume if (ret) { 139200028Sume krb5_storage_free(sp); 140200028Sume *minor_status = ret; 141163749Sphk return GSS_S_FAILURE; 142181759Sjhb } 143181759Sjhb 144181759Sjhb ret = krb5_storage_to_data(sp, &data); 145181759Sjhb krb5_storage_free(sp); 146202460Sume if (ret) { 147181759Sjhb *minor_status = ret; 148163749Sphk return GSS_S_FAILURE; 149181759Sjhb } 150163749Sphk 151181759Sjhb cred_token->value = data.data; 152181759Sjhb cred_token->length = data.length; 153175522Srafan 154175522Srafan return GSS_S_COMPLETE; 155175522Srafan} 156175722Smtm 15761961SdillonOM_uint32 GSSAPI_CALLCONV 15861961Sdillon_gsskrb5_import_cred(OM_uint32 * minor_status, 159123029Sbms gss_buffer_t cred_token, 160123029Sbms gss_cred_id_t * cred_handle) 161123029Sbms{ 16261961Sdillon krb5_context context; 16361961Sdillon krb5_error_code ret; 16444990Sbrian gsskrb5_cred handle; 16587047Sru krb5_ccache id; 16690957Scjc krb5_storage *sp; 16787047Sru char *str; 16866745Sdarrenr uint32_t type; 16986856Sdarrenr int flags = 0; 17066745Sdarrenr 17166745Sdarrenr *cred_handle = GSS_C_NO_CREDENTIAL; 17286856Sdarrenr 17386856Sdarrenr GSSAPI_KRB5_INIT (&context); 17486856Sdarrenr 17566745Sdarrenr sp = krb5_storage_from_mem(cred_token->value, cred_token->length); 17666745Sdarrenr if (sp == NULL) { 17786856Sdarrenr *minor_status = ENOMEM; 17886856Sdarrenr return GSS_S_FAILURE; 17986856Sdarrenr } 18087047Sru 18185219Sdarrenr ret = krb5_ret_uint32(sp, &type); 18286856Sdarrenr if (ret) { 18385219Sdarrenr krb5_storage_free(sp); 184127342Smlaier *minor_status = ret; 185127342Smlaier return GSS_S_FAILURE; 186127342Smlaier } 187127342Smlaier switch (type) { 188127759Smlaier case 0: { 189132678Smlaier krb5_creds creds; 190127759Smlaier 191127759Smlaier ret = krb5_ret_creds(sp, &creds); 192172070Smlaier krb5_storage_free(sp); 193172070Smlaier if (ret) { 194150835Syar *minor_status = ret; 195150835Syar return GSS_S_FAILURE; 196168593Skeramida } 197150835Syar 19877154Sobrien ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id); 19989808Scjc if (ret) { 20049704Sobrien *minor_status = ret; 20151209Sdes return GSS_S_FAILURE; 20260685Swollman } 20395547Sdougb 20449603Sdes ret = krb5_cc_initialize(context, id, creds.client); 20548687Speter if (ret) { 20683677Sbrooks krb5_cc_destroy(context, id); 20783677Sbrooks *minor_status = ret; 20843809Sjkh return GSS_S_FAILURE; 20943809Sjkh } 21064677Ssheldonh 211197145Shrs ret = krb5_cc_store_cred(context, id, &creds); 212197145Shrs krb5_free_cred_contents(context, &creds); 213137070Spjd 214201215Sjhb flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; 215201215Sjhb 216178738Sbrooks break; 217189759Sbrooks } 218152441Sbrooks case 1: 21943809Sjkh ret = krb5_ret_string(sp, &str); 220159138Sthompsa krb5_storage_free(sp); 221159138Sthompsa if (ret) { 222159138Sthompsa *minor_status = ret; 22343809Sjkh return GSS_S_FAILURE; 22443809Sjkh } 22543809Sjkh 226179315Sbz ret = krb5_cc_resolve(context, str, &id); 227179315Sbz krb5_xfree(str); 228166583Sflz if (ret) { 22977651Sbrian *minor_status = ret; 23077651Sbrian return GSS_S_FAILURE; 23177651Sbrian } 23277651Sbrian break; 233166583Sflz 234166583Sflz default: 235166583Sflz krb5_storage_free(sp); 236166583Sflz *minor_status = 0; 23743809Sjkh return GSS_S_NO_CRED; 23853665Salfred } 23949110Sbrian 240138889Sbrian handle = calloc(1, sizeof(*handle)); 24149110Sbrian if (handle == NULL) { 24249110Sbrian krb5_cc_close(context, id); 24350193Sbrian *minor_status = ENOMEM; 24449110Sbrian return GSS_S_FAILURE; 24564471Sbrian } 24649110Sbrian 247172586Semax handle->usage = GSS_C_INITIATE; 248172586Semax krb5_cc_get_principal(context, id, &handle->principal); 249172586Semax handle->ccache = id; 250172586Semax handle->cred_flags = flags; 251172586Semax 252172586Semax *cred_handle = (gss_cred_id_t)handle; 25374462Salfred 254155236Sflz return GSS_S_COMPLETE; 25543809Sjkh} 25678905Sdd