1 /* $NetBSD: acquire_cred.c,v 1.1.1.1 2011/04/13 18:14:47 elric Exp $ */ 2 3 /* 4 * Copyright (c) 2010 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * 3. Neither the name of the Institute nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include "netlogon.h" 39 #include <gssapi_spi.h> 40 41 OM_uint32 42 _netlogon_acquire_cred(OM_uint32 * min_stat, 43 const gss_name_t desired_name, 44 OM_uint32 time_req, 45 const gss_OID_set desired_mechs, 46 gss_cred_usage_t cred_usage, 47 gss_cred_id_t * output_cred_handle, 48 gss_OID_set * actual_mechs, 49 OM_uint32 * time_rec) 50 { 51 OM_uint32 ret; 52 gssnetlogon_cred cred; 53 54 /* only initiator support so far */ 55 if (cred_usage != GSS_C_INITIATE) 56 return GSS_S_FAILURE; 57 58 if (desired_name == GSS_C_NO_NAME) 59 return GSS_S_BAD_NAME; 60 61 cred = (gssnetlogon_cred)calloc(1, sizeof(*cred)); 62 if (cred == NULL) { 63 *min_stat = ENOMEM; 64 return GSS_S_FAILURE; 65 } 66 cred->SignatureAlgorithm = NL_SIGN_ALG_HMAC_MD5; 67 cred->SealAlgorithm = NL_SEAL_ALG_RC4; 68 69 ret = _netlogon_duplicate_name(min_stat, desired_name, 70 (gss_name_t *)&cred->Name); 71 if (GSS_ERROR(ret)) { 72 free(cred); 73 return ret; 74 } 75 76 *output_cred_handle = (gss_cred_id_t)cred; 77 if (actual_mechs != NULL) 78 *actual_mechs = GSS_C_NO_OID_SET; 79 if (time_rec != NULL) 80 *time_rec = GSS_C_INDEFINITE; 81 82 return GSS_S_COMPLETE; 83 } 84 85 OM_uint32 86 _netlogon_acquire_cred_ex(gss_status_id_t status, 87 const gss_name_t desired_name, 88 OM_uint32 flags, 89 OM_uint32 time_req, 90 gss_cred_usage_t cred_usage, 91 gss_auth_identity_t identity, 92 void *ctx, 93 void (*complete)(void *, OM_uint32, gss_status_id_t, gss_cred_id_t, OM_uint32)) 94 { 95 return GSS_S_UNAVAILABLE; 96 } 97 98 /* 99 * value contains 16 byte session key 100 */ 101 static OM_uint32 102 _netlogon_set_session_key(OM_uint32 *minor_status, 103 gss_cred_id_t *cred_handle, 104 const gss_buffer_t value) 105 { 106 gssnetlogon_cred cred; 107 108 if (*cred_handle == GSS_C_NO_CREDENTIAL) { 109 *minor_status = EINVAL; 110 return GSS_S_FAILURE; 111 } 112 113 cred = (gssnetlogon_cred)*cred_handle; 114 115 if (value->length != sizeof(cred->SessionKey)) { 116 *minor_status = ERANGE; 117 return GSS_S_FAILURE; 118 } 119 120 memcpy(cred->SessionKey, value->value, value->length); 121 122 *minor_status = 0; 123 return GSS_S_COMPLETE; 124 } 125 126 /* 127 * value contains 16 bit little endian encoded seal algorithm 128 */ 129 static OM_uint32 130 _netlogon_set_sign_algorithm(OM_uint32 *minor_status, 131 gss_cred_id_t *cred_handle, 132 const gss_buffer_t value) 133 { 134 gssnetlogon_cred cred; 135 uint16_t alg; 136 const uint8_t *p; 137 138 if (*cred_handle == GSS_C_NO_CREDENTIAL) { 139 *minor_status = EINVAL; 140 return GSS_S_FAILURE; 141 } 142 143 cred = (gssnetlogon_cred)*cred_handle; 144 145 if (value->length != 2) { 146 *minor_status = ERANGE; 147 return GSS_S_FAILURE; 148 } 149 150 p = (const uint8_t *)value->value; 151 alg = (p[0] << 0) | (p[1] << 8); 152 153 if (alg != NL_SIGN_ALG_HMAC_MD5 && alg != NL_SIGN_ALG_SHA256) { 154 *minor_status = EINVAL; 155 return GSS_S_FAILURE; 156 } 157 158 cred->SignatureAlgorithm = alg; 159 if (alg == NL_SIGN_ALG_SHA256) 160 cred->SealAlgorithm = NL_SEAL_ALG_AES128; 161 else 162 cred->SealAlgorithm = NL_SEAL_ALG_RC4; 163 164 *minor_status = 0; 165 return GSS_S_COMPLETE; 166 } 167 168 OM_uint32 169 _netlogon_set_cred_option 170 (OM_uint32 *minor_status, 171 gss_cred_id_t *cred_handle, 172 const gss_OID desired_object, 173 const gss_buffer_t value) 174 { 175 if (value == GSS_C_NO_BUFFER) { 176 *minor_status = EINVAL; 177 return GSS_S_FAILURE; 178 } 179 180 if (gss_oid_equal(desired_object, GSS_NETLOGON_SET_SESSION_KEY_X)) 181 return _netlogon_set_session_key(minor_status, cred_handle, value); 182 else if (gss_oid_equal(desired_object, GSS_NETLOGON_SET_SIGN_ALGORITHM_X)) 183 return _netlogon_set_sign_algorithm(minor_status, cred_handle, value); 184 185 *minor_status = EINVAL; 186 return GSS_S_FAILURE; 187 } 188 189