2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 Internet Software Consortium.
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.
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.
18 /* $Id: gssapictx.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ */
24 #include <isc/buffer.h>
26 #include <isc/entropy.h>
30 #include <isc/random.h>
31 #include <isc/string.h>
35 #include <dns/fixedname.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>
43 #include <dst/gssapi.h>
44 #include <dst/result.h>
46 #include "dst_internal.h"
50 #include <gssapi/gssapi.h>
52 #define RETERR(x) do { \
54 if (result != ISC_R_SUCCESS) \
58 #define REGION_TO_GBUFFER(r, gb) \
60 (gb).length = (r).length; \
61 (gb).value = (r).base; \
64 #define GBUFFER_TO_REGION(gb, r) \
66 (r).length = (gb).length; \
67 (r).base = (gb).value; \
71 name_to_gbuffer(dns_name_t *name, isc_buffer_t *buffer,
72 gss_buffer_desc *gbuffer)
74 dns_name_t tname, *namep;
78 if (!dns_name_isabsolute(name))
82 dns_name_init(&tname, NULL);
83 labels = dns_name_countlabels(name);
84 dns_name_getlabelsequence(name, 0, labels - 1, &tname);
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);
95 dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) {
98 gss_buffer_desc gnamebuf;
99 unsigned char array[DNS_NAME_MAXTEXT + 1];
100 OM_uint32 gret, minor;
103 gss_cred_usage_t usage;
105 REQUIRE(cred != NULL && *cred == 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,
112 if (gret != GSS_S_COMPLETE)
113 return (ISC_R_FAILURE);
118 usage = GSS_C_INITIATE;
120 usage = GSS_C_ACCEPT;
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);
131 dst_gssapi_initctx(dns_name_t *name, void *cred,
132 isc_region_t *intoken, isc_buffer_t *outtoken,
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;
143 unsigned char array[DNS_NAME_MAXTEXT + 1];
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);
151 if (intoken != NULL) {
152 REGION_TO_GBUFFER(*intoken, gintoken);
153 gintokenp = &gintoken;
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;
163 gret = gss_init_sec_context(&minor, cred, context, gname,
165 GSS_C_NO_CHANNEL_BINDINGS, gintokenp,
166 &ret_mech_type, &gouttoken, &ret_flags,
168 if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED)
169 return (ISC_R_FAILURE);
171 GBUFFER_TO_REGION(gouttoken, r);
172 RETERR(isc_buffer_copyregion(outtoken, &r));
174 if (gret == GSS_S_COMPLETE)
175 return (ISC_R_SUCCESS);
177 return (DNS_R_CONTINUE);
184 dst_gssapi_acceptctx(dns_name_t *name, void *cred,
185 isc_region_t *intoken, isc_buffer_t *outtoken,
189 isc_buffer_t namebuf;
190 gss_buffer_desc gnamebuf, gintoken, gouttoken;
191 OM_uint32 gret, minor, flags;
194 gss_cred_id_t delegated_cred;
197 unsigned char array[DNS_NAME_MAXTEXT + 1];
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);
205 REGION_TO_GBUFFER(*intoken, gintoken);
207 if (*context == NULL)
208 *context = GSS_C_NO_CONTEXT;
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);
217 GBUFFER_TO_REGION(gouttoken, r);
218 RETERR(isc_buffer_copyregion(outtoken, &r));
220 return (ISC_R_SUCCESS);
229 dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate, void **cred) {
233 return (ISC_R_NOTIMPLEMENTED);
237 dst_gssapi_initctx(dns_name_t *name, void *cred,
238 isc_region_t *intoken, isc_buffer_t *outtoken,
246 return (ISC_R_NOTIMPLEMENTED);
250 dst_gssapi_acceptctx(dns_name_t *name, void *cred,
251 isc_region_t *intoken, isc_buffer_t *outtoken,
259 return (ISC_R_NOTIMPLEMENTED);