gssapictx.c revision 143731
1/* 2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000, 2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: gssapictx.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ */ 19 20#include <config.h> 21 22#include <stdlib.h> 23 24#include <isc/buffer.h> 25#include <isc/dir.h> 26#include <isc/entropy.h> 27#include <isc/lex.h> 28#include <isc/mem.h> 29#include <isc/once.h> 30#include <isc/random.h> 31#include <isc/string.h> 32#include <isc/time.h> 33#include <isc/util.h> 34 35#include <dns/fixedname.h> 36#include <dns/name.h> 37#include <dns/rdata.h> 38#include <dns/rdataclass.h> 39#include <dns/result.h> 40#include <dns/types.h> 41#include <dns/keyvalues.h> 42 43#include <dst/gssapi.h> 44#include <dst/result.h> 45 46#include "dst_internal.h" 47 48#ifdef GSSAPI 49 50#include <gssapi/gssapi.h> 51 52#define RETERR(x) do { \ 53 result = (x); \ 54 if (result != ISC_R_SUCCESS) \ 55 goto out; \ 56 } while (0) 57 58#define REGION_TO_GBUFFER(r, gb) \ 59 do { \ 60 (gb).length = (r).length; \ 61 (gb).value = (r).base; \ 62 } while (0) 63 64#define GBUFFER_TO_REGION(gb, r) \ 65 do { \ 66 (r).length = (gb).length; \ 67 (r).base = (gb).value; \ 68 } while (0) 69 70static inline void 71name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer, 72 gss_buffer_desc *gbuffer) 73{ 74 dns_name_t tname, *namep; 75 isc_region_t r; 76 isc_result_t result; 77 78 if (!dns_name_isabsolute(name)) 79 namep = name; 80 else { 81 unsigned int labels; 82 dns_name_init(&tname, NULL); 83 labels = dns_name_countlabels(name); 84 dns_name_getlabelsequence(name, 0, labels - 1, &tname); 85 namep = &tname; 86 } 87 88 result = dns_name_totext(namep, ISC_FALSE, buffer); 89 isc_buffer_putuint8(buffer, 0); 90 isc_buffer_usedregion(buffer, &r); 91 REGION_TO_GBUFFER(r, *gbuffer); 92} 93 94isc_result_t 95dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) { 96 isc_buffer_t namebuf; 97 gss_name_t gname; 98 gss_buffer_desc gnamebuf; 99 unsigned char array[DNS_NAME_MAXTEXT + 1]; 100 OM_uint32 gret, minor; 101 gss_OID_set mechs; 102 OM_uint32 lifetime; 103 gss_cred_usage_t usage; 104 105 REQUIRE(cred != NULL && *cred == NULL); 106 107 if (name != NULL) { 108 isc_buffer_init(&namebuf, array, sizeof(array)); 109 name_to_gbuffer(name, &namebuf, &gnamebuf); 110 gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, 111 &gname); 112 if (gret != GSS_S_COMPLETE) 113 return (ISC_R_FAILURE); 114 } else 115 gname = NULL; 116 117 if (initiate) 118 usage = GSS_C_INITIATE; 119 else 120 usage = GSS_C_ACCEPT; 121 122 gret = gss_acquire_cred(&minor, gname, GSS_C_INDEFINITE, 123 GSS_C_NO_OID_SET, usage, 124 cred, &mechs, &lifetime); 125 if (gret != GSS_S_COMPLETE) 126 return (ISC_R_FAILURE); 127 return (ISC_R_SUCCESS); 128} 129 130isc_result_t 131dst_gssapi_initctx(dns_name_t *name, void *cred, 132 isc_region_t *intoken, isc_buffer_t *outtoken, 133 void **context) 134{ 135 isc_region_t r; 136 isc_buffer_t namebuf; 137 gss_buffer_desc gnamebuf, gintoken, *gintokenp, gouttoken; 138 OM_uint32 gret, minor, flags, ret_flags; 139 gss_OID mech_type, ret_mech_type; 140 OM_uint32 lifetime; 141 gss_name_t gname; 142 isc_result_t result; 143 unsigned char array[DNS_NAME_MAXTEXT + 1]; 144 145 isc_buffer_init(&namebuf, array, sizeof(array)); 146 name_to_gbuffer(name, &namebuf, &gnamebuf); 147 gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname); 148 if (gret != GSS_S_COMPLETE) 149 return (ISC_R_FAILURE); 150 151 if (intoken != NULL) { 152 REGION_TO_GBUFFER(*intoken, gintoken); 153 gintokenp = &gintoken; 154 } else 155 gintokenp = NULL; 156 157 if (*context == NULL) 158 *context = GSS_C_NO_CONTEXT; 159 flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG | 160 GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG; 161 mech_type = GSS_C_NO_OID; 162 163 gret = gss_init_sec_context(&minor, cred, context, gname, 164 mech_type, flags, 0, 165 GSS_C_NO_CHANNEL_BINDINGS, gintokenp, 166 &ret_mech_type, &gouttoken, &ret_flags, 167 &lifetime); 168 if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) 169 return (ISC_R_FAILURE); 170 171 GBUFFER_TO_REGION(gouttoken, r); 172 RETERR(isc_buffer_copyregion(outtoken, &r)); 173 174 if (gret == GSS_S_COMPLETE) 175 return (ISC_R_SUCCESS); 176 else 177 return (DNS_R_CONTINUE); 178 179 out: 180 return (result); 181} 182 183isc_result_t 184dst_gssapi_acceptctx(dns_name_t *name, void *cred, 185 isc_region_t *intoken, isc_buffer_t *outtoken, 186 void **context) 187{ 188 isc_region_t r; 189 isc_buffer_t namebuf; 190 gss_buffer_desc gnamebuf, gintoken, gouttoken; 191 OM_uint32 gret, minor, flags; 192 gss_OID mech_type; 193 OM_uint32 lifetime; 194 gss_cred_id_t delegated_cred; 195 gss_name_t gname; 196 isc_result_t result; 197 unsigned char array[DNS_NAME_MAXTEXT + 1]; 198 199 isc_buffer_init(&namebuf, array, sizeof(array)); 200 name_to_gbuffer(name, &namebuf, &gnamebuf); 201 gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname); 202 if (gret != GSS_S_COMPLETE) 203 return (ISC_R_FAILURE); 204 205 REGION_TO_GBUFFER(*intoken, gintoken); 206 207 if (*context == NULL) 208 *context = GSS_C_NO_CONTEXT; 209 210 gret = gss_accept_sec_context(&minor, context, cred, &gintoken, 211 GSS_C_NO_CHANNEL_BINDINGS, gname, 212 &mech_type, &gouttoken, &flags, 213 &lifetime, &delegated_cred); 214 if (gret != GSS_S_COMPLETE) 215 return (ISC_R_FAILURE); 216 217 GBUFFER_TO_REGION(gouttoken, r); 218 RETERR(isc_buffer_copyregion(outtoken, &r)); 219 220 return (ISC_R_SUCCESS); 221 222 out: 223 return (result); 224} 225 226#else 227 228isc_result_t 229dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) { 230 UNUSED(name); 231 UNUSED(initiate); 232 UNUSED(cred); 233 return (ISC_R_NOTIMPLEMENTED); 234} 235 236isc_result_t 237dst_gssapi_initctx(dns_name_t *name, void *cred, 238 isc_region_t *intoken, isc_buffer_t *outtoken, 239 void **context) 240{ 241 UNUSED(name); 242 UNUSED(cred); 243 UNUSED(intoken); 244 UNUSED(outtoken); 245 UNUSED(context); 246 return (ISC_R_NOTIMPLEMENTED); 247} 248 249isc_result_t 250dst_gssapi_acceptctx(dns_name_t *name, void *cred, 251 isc_region_t *intoken, isc_buffer_t *outtoken, 252 void **context) 253{ 254 UNUSED(name); 255 UNUSED(cred); 256 UNUSED(intoken); 257 UNUSED(outtoken); 258 UNUSED(context); 259 return (ISC_R_NOTIMPLEMENTED); 260} 261 262#endif 263