1/*- 2 * Copyright (c) 2005 Doug Rabson 3 * All rights reserved. 4 * 5 * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include "mech_locl.h" 30#include <heim_threads.h> 31 32#ifdef __BLOCKS__ 33#include <Block.h> 34#endif 35 36#ifdef __BLOCKS__ 37 38static void 39complete_block(void *ctx, OM_uint32 maj_stat, 40 gss_status_id_t status, gss_cred_id_t cred, 41 gss_OID_set set, OM_uint32 min_time) 42{ 43 gss_acquire_cred_complete complete = ctx; 44 45 complete(status, cred, set, min_time); 46 Block_release(complete); 47} 48 49OM_uint32 GSSAPI_LIB_FUNCTION 50gss_acquire_cred_ex(const gss_name_t desired_name, 51 OM_uint32 flags, 52 OM_uint32 time_req, 53 gss_const_OID desired_mech, 54 gss_cred_usage_t cred_usage, 55 gss_auth_identity_t identity, 56 gss_acquire_cred_complete complete) 57{ 58 OM_uint32 ret; 59 60 complete = (gss_acquire_cred_complete)Block_copy(complete); 61 62 ret = gss_acquire_cred_ex_f(NULL, 63 desired_name, 64 flags, 65 time_req, 66 desired_mech, 67 cred_usage, 68 identity, 69 complete, 70 complete_block); 71 if (ret != GSS_S_COMPLETE) 72 Block_release(complete); 73 return ret; 74} 75#endif 76 77 78OM_uint32 GSSAPI_LIB_FUNCTION 79gss_acquire_cred_ex_f(gss_status_id_t status, 80 gss_name_t desired_name, 81 OM_uint32 flags, 82 OM_uint32 time_req, 83 gss_const_OID desired_mech, 84 gss_cred_usage_t cred_usage, 85 gss_auth_identity_t identity, 86 void * userctx, 87 void (*usercomplete)(void *, OM_uint32, gss_status_id_t, gss_cred_id_t, gss_OID_set, OM_uint32)) 88{ 89 OM_uint32 major_status, minor_status; 90 gss_name_t name = GSS_C_NO_NAME; 91 gss_cred_id_t cred; 92 OM_uint32 junk; 93 gss_buffer_desc buffer; 94 95 if (usercomplete == NULL) 96 return GSS_S_CALL_INACCESSIBLE_READ; 97 98 /* 99 * If no desired_name, make one up from the identity 100 */ 101 if (desired_name == GSS_C_NO_NAME) { 102 char *str; 103 if (identity->username == NULL) 104 return GSS_S_FAILURE; 105 if (identity->realm) 106 asprintf(&str, "%s@%s", identity->username, identity->realm); 107 else 108 str = strdup(identity->username); 109 buffer.value = str; 110 buffer.length = strlen(str); 111 112 major_status = gss_import_name(&minor_status, &buffer, GSS_C_NT_USER_NAME, &name); 113 free(str); 114 if (major_status) 115 return major_status; 116 117 desired_name = name; 118 } 119 120 /* 121 * First make sure that at least one of the requested 122 * mechanisms is one that we support. 123 */ 124 if (desired_mech) { 125 int t; 126 gss_test_oid_set_member(&junk, desired_mech, _gss_mech_oids, &t); 127 if (!t) { 128 if (name) 129 gss_release_name(&junk, &name); 130 return (GSS_S_BAD_MECH); 131 } 132 } 133 134 buffer.value = identity->password; 135 buffer.length = strlen(identity->password); 136 137 cred = GSS_C_NO_CREDENTIAL; 138 139 major_status = gss_acquire_cred_ext(&minor_status, 140 desired_name, 141 GSS_C_CRED_PASSWORD, 142 &buffer, 143 time_req, 144 desired_mech, 145 cred_usage, 146 &cred); 147 if (name) 148 gss_release_name(&junk, &name); 149 if (major_status) 150 return major_status; 151 152 usercomplete(userctx, major_status, status, 153 cred, GSS_C_NO_OID_SET, GSS_C_INDEFINITE); 154 155 return GSS_S_COMPLETE; 156} 157