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 "mit-krb5.h" 38#include <string.h> 39#include <errno.h> 40 41static krb5_flags 42mshim_mit_ap_req_flags(mit_krb5_flags ap_req_options) 43{ 44 krb5_flags flags = 0; 45 46 if (ap_req_options & MIT_AP_OPTS_USE_SUBKEY) 47 flags |= AP_OPTS_USE_SUBKEY; 48 if (ap_req_options & MIT_AP_OPTS_USE_SESSION_KEY) 49 flags |= AP_OPTS_USE_SESSION_KEY; 50 if (ap_req_options & MIT_AP_OPTS_MUTUAL_REQUIRED) 51 flags |= AP_OPTS_MUTUAL_REQUIRED; 52 53 return flags; 54} 55 56 57 58mit_krb5_error_code KRB5_CALLCONV 59krb5_mk_req(mit_krb5_context context, 60 mit_krb5_auth_context *ac, 61 mit_krb5_flags ap_req_options, 62 char *service, 63 char *hostname, 64 mit_krb5_data *inbuf, 65 mit_krb5_ccache ccache, 66 mit_krb5_data *outbuf) 67{ 68 krb5_data idata, *d = NULL; 69 krb5_data odata; 70 krb5_flags flags = mshim_mit_ap_req_flags(ap_req_options); 71 krb5_error_code ret; 72 73 LOG_ENTRY(); 74 75 memset(outbuf, 0, sizeof(*outbuf)); 76 77 if (inbuf) { 78 d = &idata; 79 idata.data = inbuf->data; 80 idata.length = inbuf->length; 81 } 82 83 ret = heim_krb5_mk_req(HC(context), (krb5_auth_context *)ac, 84 flags, service, hostname, d, 85 (krb5_ccache)ccache, &odata); 86 if (ret == 0) 87 mshim_hdata2mdata(&odata, outbuf); 88 89 return ret; 90} 91 92 93mit_krb5_error_code KRB5_CALLCONV 94krb5_mk_req_extended(mit_krb5_context context, 95 mit_krb5_auth_context *ac, 96 mit_krb5_flags ap_req_options, 97 mit_krb5_data *inbuf, 98 mit_krb5_creds *cred, 99 mit_krb5_data *outbuf) 100 { 101 krb5_data idata, *d = NULL; 102 krb5_data odata; 103 krb5_flags flags = mshim_mit_ap_req_flags(ap_req_options); 104 krb5_error_code ret; 105 krb5_creds hcreds; 106 107 LOG_ENTRY(); 108 109 memset(outbuf, 0, sizeof(*outbuf)); 110 111 mshim_mcred2hcred(HC(context), cred, &hcreds); 112 113 if (inbuf) { 114 d = &idata; 115 idata.data = inbuf->data; 116 idata.length = inbuf->length; 117 } 118 119 ret = heim_krb5_mk_req_extended(HC(context), (krb5_auth_context *)ac, 120 flags, d, &hcreds, &odata); 121 heim_krb5_free_cred_contents(HC(context), &hcreds); 122 if (ret == 0) 123 mshim_hdata2mdata(&odata, outbuf); 124 125 return ret; 126} 127 128mit_krb5_error_code KRB5_CALLCONV 129krb5_sendauth(mit_krb5_context context, 130 mit_krb5_auth_context *auth_context, 131 mit_krb5_pointer fd, 132 char *appl_version, 133 mit_krb5_principal client, 134 mit_krb5_principal server, 135 mit_krb5_flags ap_req_options, 136 mit_krb5_data *in_data, 137 mit_krb5_creds *in_creds, 138 mit_krb5_ccache ccache, 139 mit_krb5_error **error, 140 mit_krb5_ap_rep_enc_part **rep_result, 141 mit_krb5_creds **out_creds) 142{ 143 mit_krb5_error_code ret; 144 struct comb_principal *c = (struct comb_principal *)client; 145 struct comb_principal *s = (struct comb_principal *)server; 146 krb5_flags flags = mshim_mit_ap_req_flags(ap_req_options); 147 krb5_ap_rep_enc_part *hrep_result = NULL; 148 krb5_error *herror = NULL; 149 krb5_data hin_data; 150 krb5_creds hin_creds, *hout_creds = NULL; 151 152 memset(&hin_creds, 0, sizeof(hin_creds)); 153 heim_krb5_data_zero(&hin_data); 154 155 if (in_data) 156 mshim_mdata2hdata(in_data, &hin_data); 157 if (in_creds) 158 mshim_mcred2hcred(HC(context), in_creds, &hin_creds); 159 160 ret = heim_krb5_sendauth(HC(context), 161 (krb5_auth_context *)auth_context, 162 fd, 163 appl_version, 164 c->heim, 165 s->heim, 166 flags, 167 in_data ? &hin_data : NULL, 168 in_creds ? &hin_creds : NULL, 169 (krb5_ccache)ccache, 170 &herror, 171 &hrep_result, 172 &hout_creds); 173 if (in_data) 174 free(hin_data.data); 175 if (in_creds) 176 heim_krb5_free_cred_contents(HC(context), &hin_creds); 177 178 if (herror && error) { 179 *error = mshim_malloc(sizeof(**error)); 180 mshim_herror2merror(HC(context), herror, *error); 181 } 182 if (hrep_result && rep_result) { 183 *rep_result = mshim_malloc(sizeof(**rep_result)); 184 mshim_haprepencpart2maprepencpart(hrep_result, *rep_result); 185 } 186 if (hout_creds && out_creds) { 187 *out_creds = mshim_malloc(sizeof(**out_creds)); 188 mshim_hcred2mcred(HC(context), hout_creds, *out_creds); 189 } 190 if (hrep_result) 191 heim_krb5_free_ap_rep_enc_part(HC(context), hrep_result); 192 if (herror) 193 heim_krb5_free_error(HC(context), herror); 194 if (hout_creds) 195 heim_krb5_free_creds(HC(context), hout_creds); 196 197 return ret; 198} 199 200mit_krb5_error_code KRB5_CALLCONV 201krb5_mk_priv(mit_krb5_context context, 202 mit_krb5_auth_context auth_context, 203 const mit_krb5_data *inbuf, 204 mit_krb5_data *outbuf, 205 mit_krb5_replay_data *replay) 206{ 207 krb5_replay_data outdata; 208 mit_krb5_error_code ret; 209 krb5_data in, out; 210 211 LOG_ENTRY(); 212 213 memset(outbuf, 0, sizeof(*outbuf)); 214 memset(&outdata, 0, sizeof(outdata)); 215 216 in.data = inbuf->data; 217 in.length = inbuf->length; 218 219 ret = heim_krb5_mk_priv(HC(context), 220 (krb5_auth_context)auth_context, 221 &in, 222 &out, 223 &outdata); 224 if (ret) 225 return ret; 226 227 mshim_hdata2mdata(&out, outbuf); 228 heim_krb5_data_free(&out); 229 230 if (replay) { 231 memset(replay, 0, sizeof(*replay)); 232 mshim_hreplay2mreplay(&outdata, replay); 233 } 234 235 return 0; 236} 237 238mit_krb5_error_code KRB5_CALLCONV 239krb5_mk_safe(mit_krb5_context context, 240 mit_krb5_auth_context auth_context, 241 const mit_krb5_data *inbuf, 242 mit_krb5_data *outbuf, 243 mit_krb5_replay_data *replay) 244{ 245 krb5_replay_data outdata; 246 mit_krb5_error_code ret; 247 krb5_data in, out; 248 249 LOG_ENTRY(); 250 251 memset(outbuf, 0, sizeof(*outbuf)); 252 memset(&outdata, 0, sizeof(outdata)); 253 254 in.data = inbuf->data; 255 in.length = inbuf->length; 256 257 ret = heim_krb5_mk_safe(HC(context), 258 (krb5_auth_context)auth_context, 259 &in, 260 &out, 261 &outdata); 262 if (ret) 263 return ret; 264 265 mshim_hdata2mdata(&out, outbuf); 266 heim_krb5_data_free(&out); 267 268 if (replay) { 269 memset(replay, 0, sizeof(*replay)); 270 mshim_hreplay2mreplay(&outdata, replay); 271 } 272 273 return 0; 274} 275 276