2 * Copyright (c) 2011, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include "gssapiP_eap.h"
34 #include "authdata_plugin.h"
37 * This rubbish is necessary because MIT doesn't provide another way
38 * to access verified AD-KDCIssued elements. We can't verify them
39 * ourselves because they're signed in the ticket session key, which
40 * is destroyed immediately after the AP-REQ is processed.
43 struct radius_ad_context {
45 krb5_boolean verified;
48 static krb5_data radius_ad_attr = {
49 KV5M_DATA, sizeof("urn:authdata-radius-avp") - 1, "urn:authdata-radius-avp" };
51 static krb5_error_code
52 radius_ad_init(krb5_context kcontext GSSEAP_UNUSED,
53 void **plugin_context)
60 radius_ad_flags(krb5_context kcontext GSSEAP_UNUSED,
61 void *plugin_context GSSEAP_UNUSED,
62 krb5_authdatatype ad_type GSSEAP_UNUSED,
65 *flags = AD_USAGE_KDC_ISSUED | AD_INFORMATIONAL;
69 radius_ad_fini(krb5_context kcontext GSSEAP_UNUSED,
70 void *plugin_context GSSEAP_UNUSED)
75 static krb5_error_code
76 radius_ad_request_init(krb5_context kcontext GSSEAP_UNUSED,
77 struct _krb5_authdata_context *context GSSEAP_UNUSED,
78 void *plugin_context GSSEAP_UNUSED,
79 void **request_context)
81 struct radius_ad_context *ctx;
83 ctx = GSSEAP_CALLOC(1, sizeof(*ctx));
87 *request_context = ctx;
92 static krb5_error_code
93 radius_ad_export_authdata(krb5_context kcontext,
94 struct _krb5_authdata_context *context GSSEAP_UNUSED,
95 void *plugin_context GSSEAP_UNUSED,
96 void *request_context,
97 krb5_flags usage GSSEAP_UNUSED,
98 krb5_authdata ***out_authdata)
100 struct radius_ad_context *radius_ad = (struct radius_ad_context *)request_context;
101 krb5_authdata *data[2];
104 datum.ad_type = KRB5_AUTHDATA_RADIUS_AVP;
105 datum.length = radius_ad->avpdata.length;
106 datum.contents = (krb5_octet *)radius_ad->avpdata.data;
111 return krb5_copy_authdata(kcontext, data, out_authdata);
114 static krb5_error_code
115 radius_ad_import_authdata(krb5_context kcontext,
116 struct _krb5_authdata_context *context GSSEAP_UNUSED,
117 void *plugin_context GSSEAP_UNUSED,
118 void *request_context,
119 krb5_authdata **authdata,
120 krb5_boolean kdc_issued_flag,
121 krb5_const_principal issuer GSSEAP_UNUSED)
123 struct radius_ad_context *radius_ad = (struct radius_ad_context *)request_context;
125 krb5_free_data_contents(kcontext, &radius_ad->avpdata);
126 radius_ad->verified = FALSE;
128 assert(authdata[0] != NULL);
130 radius_ad->avpdata.data = GSSEAP_MALLOC(authdata[0]->length);
131 if (radius_ad->avpdata.data == NULL)
134 memcpy(radius_ad->avpdata.data, authdata[0]->contents,
135 authdata[0]->length);
136 radius_ad->avpdata.length = authdata[0]->length;
138 radius_ad->verified = kdc_issued_flag;
144 radius_ad_request_fini(krb5_context kcontext,
145 struct _krb5_authdata_context *context GSSEAP_UNUSED,
146 void *plugin_context GSSEAP_UNUSED,
147 void *request_context)
149 struct radius_ad_context *radius_ad = (struct radius_ad_context *)request_context;
151 if (radius_ad != NULL) {
152 krb5_free_data_contents(kcontext, &radius_ad->avpdata);
153 GSSEAP_FREE(radius_ad);
157 static krb5_error_code
158 radius_ad_get_attribute(krb5_context kcontext GSSEAP_UNUSED,
159 struct _krb5_authdata_context *context GSSEAP_UNUSED,
160 void *plugin_context GSSEAP_UNUSED,
161 void *request_context,
162 const krb5_data *attribute,
163 krb5_boolean *authenticated,
164 krb5_boolean *complete,
166 krb5_data *display_value GSSEAP_UNUSED,
169 struct radius_ad_context *radius_ad = (struct radius_ad_context *)request_context;
171 if (attribute->length != radius_ad_attr.length ||
172 memcmp(attribute->data, radius_ad_attr.data,
173 radius_ad_attr.length) != 0)
176 if (radius_ad->avpdata.length == 0)
179 *authenticated = radius_ad->verified;
183 value->data = GSSEAP_MALLOC(radius_ad->avpdata.length);
184 if (value->data == NULL)
187 memcpy(value->data, radius_ad->avpdata.data, radius_ad->avpdata.length);
188 value->length = radius_ad->avpdata.length;
193 static krb5_error_code
194 radius_ad_copy(krb5_context kcontext GSSEAP_UNUSED,
195 struct _krb5_authdata_context *context GSSEAP_UNUSED,
196 void *plugin_context GSSEAP_UNUSED,
197 void *request_context,
198 void *dst_plugin_context GSSEAP_UNUSED,
199 void *dst_request_context)
201 struct radius_ad_context *radius_ad_src =
202 (struct radius_ad_context *)request_context;
203 struct radius_ad_context *radius_ad_dst =
204 (struct radius_ad_context *)dst_request_context;
206 radius_ad_dst->avpdata.data = GSSEAP_MALLOC(radius_ad_src->avpdata.length);
207 if (radius_ad_dst->avpdata.data == NULL)
210 memcpy(radius_ad_dst->avpdata.data, radius_ad_src->avpdata.data,
211 radius_ad_src->avpdata.length);
212 radius_ad_dst->avpdata.length = radius_ad_src->avpdata.length;
213 radius_ad_dst->verified = radius_ad_src->verified;
218 static krb5_authdatatype radius_ad_ad_types[] =
219 { KRB5_AUTHDATA_RADIUS_AVP, 0 };
221 krb5plugin_authdata_client_ftable_v0 authdata_client_0 = {
227 radius_ad_request_init,
228 radius_ad_request_fini,
230 radius_ad_get_attribute,
233 radius_ad_export_authdata,
234 radius_ad_import_authdata,