1/* 2 * Copyright (c) 2008-2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2008-2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "heim.h" 37#include <string.h> 38#include <errno.h> 39 40void KRB5_CALLCONV 41krb5_get_init_creds_opt_init(mit_krb5_get_init_creds_opt *opt) 42{ 43 LOG_ENTRY(); 44 memset(opt, 0, sizeof(*opt)); 45} 46 47mit_krb5_error_code KRB5_CALLCONV 48krb5_get_init_creds_opt_set_process_last_req(mit_krb5_context context, 49 mit_krb5_get_init_creds_opt *opt, 50 mit_krb5_gic_process_last_req req, 51 void *ctx) 52{ 53 LOG_ENTRY(); 54 /* XXX need to implement this, its will be require for Lion 55 some time later */ 56 return 0; 57} 58 59mit_krb5_error_code KRB5_CALLCONV 60krb5_get_init_creds_opt_alloc(mit_krb5_context context, 61 mit_krb5_get_init_creds_opt **opt) 62{ 63 mit_krb5_get_init_creds_opt *c; 64 LOG_ENTRY(); 65 c = calloc(1, sizeof(*c)); 66 if (c == NULL) 67 return ENOMEM; 68 *opt = c; 69 return 0; 70} 71 72void KRB5_CALLCONV 73krb5_get_init_creds_opt_free(mit_krb5_context context, 74 mit_krb5_get_init_creds_opt *opt) 75{ 76 LOG_ENTRY(); 77 free(opt); 78} 79 80 81void KRB5_CALLCONV 82krb5_get_init_creds_opt_set_tkt_life(mit_krb5_get_init_creds_opt *opt, 83 mit_krb5_deltat tkt_life) 84{ 85 LOG_ENTRY(); 86 opt->flags |= MIT_KRB5_GET_INIT_CREDS_OPT_TKT_LIFE; 87 opt->tkt_life = tkt_life; 88} 89 90void KRB5_CALLCONV 91krb5_get_init_creds_opt_set_renew_life(mit_krb5_get_init_creds_opt *opt, 92 mit_krb5_deltat renew_life) 93{ 94 LOG_ENTRY(); 95 opt->flags |= MIT_KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE; 96 opt->renew_life = renew_life; 97} 98 99void KRB5_CALLCONV 100krb5_get_init_creds_opt_set_forwardable(mit_krb5_get_init_creds_opt *opt, 101 int forwardable) 102{ 103 LOG_ENTRY(); 104 opt->flags |= MIT_KRB5_GET_INIT_CREDS_OPT_FORWARDABLE; 105 opt->forwardable = forwardable; 106} 107 108void KRB5_CALLCONV 109krb5_get_init_creds_opt_set_proxiable(mit_krb5_get_init_creds_opt *opt, 110 int proxiable) 111{ 112 LOG_ENTRY(); 113 opt->flags |= MIT_KRB5_GET_INIT_CREDS_OPT_PROXIABLE; 114 opt->proxiable = proxiable; 115} 116 117void KRB5_CALLCONV 118krb5_get_init_creds_opt_set_canonicalize(mit_krb5_get_init_creds_opt *opt, 119 int canonicalize) 120{ 121 LOG_ENTRY(); 122 opt->flags |= MIT_KRB5_GET_INIT_CREDS_OPT_CANONICALIZE; 123} 124 125void KRB5_CALLCONV 126krb5_get_init_creds_opt_set_etype_list(mit_krb5_get_init_creds_opt *opt, 127 mit_krb5_enctype *etype_list, 128 int etype_list_length) 129{ 130 LOG_ENTRY(); 131 opt->flags |= KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST; 132 opt->etype_list = etype_list; 133 opt->etype_list_length = etype_list_length; 134} 135 136void KRB5_CALLCONV 137krb5_get_init_creds_opt_set_address_list(mit_krb5_get_init_creds_opt *opt, 138 mit_krb5_address **addresses) 139{ 140 LOG_UNIMPLEMENTED(); 141} 142 143void KRB5_CALLCONV 144krb5_get_init_creds_opt_set_preauth_list(mit_krb5_get_init_creds_opt *opt, 145 mit_krb5_preauthtype *preauth_list, 146 int preauth_list_length) 147{ 148 LOG_ENTRY(); 149} 150 151static krb5_get_init_creds_opt * 152mshim_gic_opt(krb5_context context, mit_krb5_get_init_creds_opt *mopt) 153{ 154 krb5_get_init_creds_opt *opt = NULL; 155 if (mopt) { 156 heim_krb5_get_init_creds_opt_alloc(context, &opt); 157 if (mopt->flags & MIT_KRB5_GET_INIT_CREDS_OPT_FORWARDABLE) 158 heim_krb5_get_init_creds_opt_set_forwardable(opt, mopt->forwardable); 159 if (mopt->flags & MIT_KRB5_GET_INIT_CREDS_OPT_PROXIABLE) 160 heim_krb5_get_init_creds_opt_set_proxiable(opt, mopt->proxiable); 161 if (mopt->flags & MIT_KRB5_GET_INIT_CREDS_OPT_CANONICALIZE) 162 heim_krb5_get_init_creds_opt_set_canonicalize(HC(context), opt, TRUE); 163 if (mopt->flags & MIT_KRB5_GET_INIT_CREDS_OPT_TKT_LIFE) 164 heim_krb5_get_init_creds_opt_set_tkt_life(opt, mopt->tkt_life); 165 if (mopt->flags & MIT_KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) 166 heim_krb5_get_init_creds_opt_set_renew_life(opt, mopt->renew_life); 167 /* XXX */ 168 } 169 return opt; 170} 171 172mit_krb5_error_code KRB5_CALLCONV 173krb5_get_init_creds_password(mit_krb5_context context, 174 mit_krb5_creds *creds, 175 mit_krb5_principal client, 176 char *password, 177 mit_krb5_prompter_fct prompter, 178 void *data, 179 mit_krb5_deltat start_time, 180 char *in_tkt_service, 181 mit_krb5_get_init_creds_opt *mopt) 182{ 183 struct comb_principal *p = (struct comb_principal *)client; 184 krb5_get_init_creds_opt *opt = NULL; 185 krb5_error_code ret; 186 krb5_creds hcreds; 187 krb5_prompter_fct pfct = NULL; 188 189 LOG_ENTRY(); 190 191 opt = mshim_gic_opt(HC(context), mopt); 192 193 memset(creds, 0, sizeof(*creds)); 194 memset(&hcreds, 0, sizeof(hcreds)); 195 196 if (prompter == krb5_prompter_posix) 197 pfct = heim_krb5_prompter_posix; 198 else if (prompter == NULL) 199 pfct = NULL; 200 else { 201 if (opt) 202 heim_krb5_get_init_creds_opt_free(HC(context), opt); 203 return EINVAL; 204 } 205 206 ret = heim_krb5_get_init_creds_password(HC(context), &hcreds, p->heim, password, 207 pfct, NULL, start_time, in_tkt_service, opt); 208 if (opt) 209 heim_krb5_get_init_creds_opt_free(HC(context), opt); 210 if (ret) 211 return ret; 212 213 mshim_hcred2mcred(HC(context), &hcreds, creds); 214 215 heim_krb5_free_cred_contents(HC(context), &hcreds); 216 217 return ret; 218} 219 220mit_krb5_error_code KRB5_CALLCONV 221krb5_get_init_creds_keytab(mit_krb5_context context, 222 mit_krb5_creds *creds, 223 mit_krb5_principal client, 224 mit_krb5_keytab arg_keytab, 225 mit_krb5_deltat start_time, 226 char *in_tkt_service, 227 mit_krb5_get_init_creds_opt *mopt) 228{ 229 struct comb_principal *p = (struct comb_principal *)client; 230 krb5_get_init_creds_opt *opt = NULL; 231 krb5_error_code ret; 232 krb5_creds hcreds; 233 234 LOG_ENTRY(); 235 236 opt = mshim_gic_opt(HC(context), mopt); 237 238 memset(creds, 0, sizeof(*creds)); 239 memset(&hcreds, 0, sizeof(hcreds)); 240 241 ret = heim_krb5_get_init_creds_keytab(HC(context), &hcreds, p->heim, 242 (krb5_keytab)arg_keytab, 243 start_time, in_tkt_service, opt); 244 if (opt) 245 heim_krb5_get_init_creds_opt_free(HC(context), opt); 246 if (ret) 247 return ret; 248 249 mshim_hcred2mcred(HC(context), &hcreds, creds); 250 251 heim_krb5_free_cred_contents(HC(context), &hcreds); 252 253 return ret; 254} 255 256mit_krb5_error_code KRB5_CALLCONV 257krb5_get_in_tkt_with_password(mit_krb5_context context, 258 mit_krb5_flags flags, 259 mit_krb5_address * const *addr, 260 mit_krb5_enctype *enctype, 261 mit_krb5_preauthtype *preauth, 262 const char *password, 263 mit_krb5_ccache cache, 264 mit_krb5_creds *cred, 265 mit_krb5_kdc_rep **rep) 266{ 267 struct comb_principal *p; 268 krb5_error_code ret; 269 krb5_creds hcreds; 270 271 LOG_ENTRY(); 272 273 if (rep) 274 *rep = NULL; 275 276 if (cred->client) 277 p = (struct comb_principal *)cred->client; 278 else 279 return KRB5_PRINC_NOMATCH; 280 281 memset(&hcreds, 0, sizeof(hcreds)); 282 283 ret = heim_krb5_get_init_creds_password(HC(context), &hcreds, p->heim, password, 284 NULL, NULL, 0, NULL, NULL); 285 if (ret) 286 return ret; 287 288 if (cache) 289 heim_krb5_cc_store_cred(HC(context), (krb5_ccache)cache, &hcreds); 290 291 heim_krb5_free_cred_contents(HC(context), &hcreds); 292 293 return 0; 294} 295 296void KRB5_CALLCONV 297krb5_verify_init_creds_opt_init(mit_krb5_verify_init_creds_opt *options) 298{ 299 memset(options, 0, sizeof(*options)); 300} 301 302void KRB5_CALLCONV 303krb5_verify_init_creds_opt_set_ap_req_nofail(mit_krb5_verify_init_creds_opt *options, 304 int ap_req_nofail) 305{ 306 if (ap_req_nofail) { 307 options->flags |= MIT_KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL; 308 } else { 309 options->flags &= ~MIT_KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL; 310 } 311 options->ap_req_nofail = ap_req_nofail; 312} 313 314mit_krb5_error_code KRB5_CALLCONV 315krb5_verify_init_creds(mit_krb5_context context, 316 mit_krb5_creds *creds, 317 mit_krb5_principal ap_req_server, 318 mit_krb5_keytab ap_req_keytab, 319 mit_krb5_ccache *ccache, 320 mit_krb5_verify_init_creds_opt *options) 321{ 322 struct comb_principal *p = (struct comb_principal *)ap_req_server; 323 krb5_error_code ret; 324 krb5_creds hcreds; 325 krb5_verify_init_creds_opt hopts; 326 327 memset(&hcreds, 0, sizeof(hcreds)); 328 heim_krb5_verify_init_creds_opt_init(&hopts); 329 330 if (options->ap_req_nofail) 331 heim_krb5_verify_init_creds_opt_set_ap_req_nofail(&hopts, options->ap_req_nofail); 332 333 mshim_mcred2hcred(HC(context), creds, &hcreds); 334 335 ret = heim_krb5_verify_init_creds(HC(context), 336 &hcreds, p->heim, 337 (krb5_keytab)ap_req_keytab, 338 (krb5_ccache *)ccache, 339 &hopts); 340 heim_krb5_free_cred_contents(HC(context), &hcreds); 341 342 return ret; 343} 344 345 346