Line data Source code
1 : /*
2 : * Copyright (c) 2009 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "gsskrb5_locl.h"
35 :
36 : OM_uint32 GSSAPI_CALLCONV
37 788 : _gsskrb5_export_cred(OM_uint32 *minor_status,
38 : gss_cred_id_t cred_handle,
39 : gss_buffer_t cred_token)
40 : {
41 0 : OM_uint32 major_status;
42 788 : gsskrb5_cred handle = (gsskrb5_cred)cred_handle;
43 0 : krb5_context context;
44 0 : krb5_error_code ret;
45 0 : krb5_storage *sp;
46 0 : krb5_data data;
47 0 : const char *type;
48 0 : char *str;
49 :
50 788 : GSSAPI_KRB5_INIT (&context);
51 :
52 788 : if (handle->usage != GSS_C_INITIATE && handle->usage != GSS_C_BOTH) {
53 0 : *minor_status = GSS_KRB5_S_G_BAD_USAGE;
54 0 : return GSS_S_FAILURE;
55 : }
56 :
57 788 : sp = krb5_storage_emem();
58 788 : if (sp == NULL) {
59 0 : *minor_status = ENOMEM;
60 0 : return GSS_S_FAILURE;
61 : }
62 :
63 788 : type = krb5_cc_get_type(context, handle->ccache);
64 788 : if (strcmp(type, "MEMORY") == 0) {
65 0 : krb5_creds *creds;
66 0 : krb5_data config_start_realm;
67 0 : char *start_realm;
68 :
69 788 : ret = krb5_store_uint32(sp, 0);
70 788 : if (ret) {
71 0 : krb5_storage_free(sp);
72 0 : *minor_status = ret;
73 0 : return GSS_S_FAILURE;
74 : }
75 :
76 788 : ret = krb5_cc_get_config(context, handle->ccache, NULL, "start_realm",
77 : &config_start_realm);
78 788 : if (ret == 0) {
79 788 : start_realm = strndup(config_start_realm.data,
80 : config_start_realm.length);
81 788 : krb5_data_free(&config_start_realm);
82 : } else {
83 0 : start_realm = strdup(krb5_principal_get_realm(context,
84 0 : handle->principal));
85 : }
86 788 : if (start_realm == NULL) {
87 0 : *minor_status = krb5_enomem(context);
88 0 : krb5_storage_free(sp);
89 0 : return GSS_S_FAILURE;
90 : }
91 :
92 788 : ret = _krb5_get_krbtgt(context, handle->ccache, start_realm, &creds);
93 788 : free(start_realm);
94 788 : start_realm = NULL;
95 788 : if (ret) {
96 0 : krb5_storage_free(sp);
97 0 : *minor_status = ret;
98 0 : return GSS_S_FAILURE;
99 : }
100 :
101 788 : ret = krb5_store_creds(sp, creds);
102 788 : krb5_free_creds(context, creds);
103 788 : if (ret) {
104 0 : krb5_storage_free(sp);
105 0 : *minor_status = ret;
106 0 : return GSS_S_FAILURE;
107 : }
108 :
109 : } else {
110 0 : ret = krb5_store_uint32(sp, 1);
111 0 : if (ret) {
112 0 : krb5_storage_free(sp);
113 0 : *minor_status = ret;
114 0 : return GSS_S_FAILURE;
115 : }
116 :
117 0 : ret = krb5_cc_get_full_name(context, handle->ccache, &str);
118 0 : if (ret) {
119 0 : krb5_storage_free(sp);
120 0 : *minor_status = ret;
121 0 : return GSS_S_FAILURE;
122 : }
123 :
124 0 : ret = krb5_store_string(sp, str);
125 0 : free(str);
126 0 : if (ret) {
127 0 : krb5_storage_free(sp);
128 0 : *minor_status = ret;
129 0 : return GSS_S_FAILURE;
130 : }
131 : }
132 788 : ret = krb5_storage_to_data(sp, &data);
133 788 : krb5_storage_free(sp);
134 788 : if (ret) {
135 0 : *minor_status = ret;
136 0 : return GSS_S_FAILURE;
137 : }
138 788 : sp = krb5_storage_emem();
139 788 : if (sp == NULL) {
140 0 : krb5_data_free(&data);
141 0 : *minor_status = ENOMEM;
142 0 : return GSS_S_FAILURE;
143 : }
144 :
145 788 : major_status = _gss_mg_store_oid(minor_status, sp, GSS_KRB5_MECHANISM);
146 788 : if (major_status != GSS_S_COMPLETE) {
147 0 : krb5_data_free(&data);
148 0 : krb5_storage_free(sp);
149 0 : return major_status;
150 : }
151 :
152 788 : ret = krb5_store_data(sp, data);
153 788 : krb5_data_free(&data);
154 788 : if (ret) {
155 0 : krb5_storage_free(sp);
156 0 : *minor_status = ret;
157 0 : return GSS_S_FAILURE;
158 : }
159 :
160 788 : ret = krb5_storage_to_data(sp, &data);
161 788 : krb5_storage_free(sp);
162 788 : if (ret) {
163 0 : *minor_status = ret;
164 0 : return GSS_S_FAILURE;
165 : }
166 :
167 788 : cred_token->value = data.data;
168 788 : cred_token->length = data.length;
169 :
170 788 : return GSS_S_COMPLETE;
171 : }
172 :
173 : OM_uint32 GSSAPI_CALLCONV
174 23107 : _gsskrb5_import_cred(OM_uint32 * minor_status,
175 : gss_buffer_t cred_token,
176 : gss_cred_id_t * cred_handle)
177 : {
178 0 : krb5_context context;
179 0 : krb5_error_code ret;
180 0 : gsskrb5_cred handle;
181 0 : krb5_ccache id;
182 0 : krb5_storage *sp;
183 0 : char *str;
184 0 : uint32_t type;
185 23107 : int flags = 0;
186 :
187 23107 : *cred_handle = GSS_C_NO_CREDENTIAL;
188 :
189 23107 : GSSAPI_KRB5_INIT (&context);
190 :
191 23107 : sp = krb5_storage_from_mem(cred_token->value, cred_token->length);
192 23107 : if (sp == NULL) {
193 0 : *minor_status = ENOMEM;
194 0 : return GSS_S_FAILURE;
195 : }
196 :
197 23107 : ret = krb5_ret_uint32(sp, &type);
198 23107 : if (ret) {
199 0 : krb5_storage_free(sp);
200 0 : *minor_status = ret;
201 0 : return GSS_S_FAILURE;
202 : }
203 23107 : switch (type) {
204 23107 : case 0: {
205 0 : krb5_creds creds;
206 :
207 23107 : ret = krb5_ret_creds(sp, &creds);
208 23107 : krb5_storage_free(sp);
209 23107 : if (ret) {
210 0 : *minor_status = ret;
211 0 : return GSS_S_FAILURE;
212 : }
213 :
214 23107 : ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id);
215 23107 : if (ret) {
216 0 : *minor_status = ret;
217 0 : return GSS_S_FAILURE;
218 : }
219 :
220 23107 : ret = krb5_cc_initialize(context, id, creds.client);
221 23107 : if (ret) {
222 0 : krb5_cc_destroy(context, id);
223 0 : *minor_status = ret;
224 0 : return GSS_S_FAILURE;
225 : }
226 :
227 23107 : ret = krb5_cc_store_cred(context, id, &creds);
228 23107 : krb5_free_cred_contents(context, &creds);
229 23107 : if (ret) {
230 0 : *minor_status = ret;
231 0 : return GSS_S_FAILURE;
232 : }
233 :
234 23107 : flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
235 :
236 23107 : break;
237 : }
238 0 : case 1:
239 0 : ret = krb5_ret_string(sp, &str);
240 0 : krb5_storage_free(sp);
241 0 : if (ret) {
242 0 : *minor_status = ret;
243 0 : return GSS_S_FAILURE;
244 : }
245 :
246 0 : ret = krb5_cc_resolve(context, str, &id);
247 0 : krb5_xfree(str);
248 0 : if (ret) {
249 0 : *minor_status = ret;
250 0 : return GSS_S_FAILURE;
251 : }
252 0 : break;
253 :
254 0 : default:
255 0 : krb5_storage_free(sp);
256 0 : *minor_status = 0;
257 0 : return GSS_S_NO_CRED;
258 : }
259 :
260 23107 : handle = calloc(1, sizeof(*handle));
261 23107 : if (handle == NULL) {
262 0 : krb5_cc_close(context, id);
263 0 : *minor_status = ENOMEM;
264 0 : return GSS_S_FAILURE;
265 : }
266 23107 : *minor_status = krb5_cc_get_principal(context, id, &handle->principal);
267 23107 : if (*minor_status) {
268 0 : free(handle);
269 0 : krb5_cc_close(context, id);
270 0 : return GSS_S_FAILURE;
271 : }
272 :
273 23107 : handle->usage = GSS_C_INITIATE;
274 23107 : handle->destination_realm = NULL;
275 23107 : handle->ccache = id;
276 23107 : handle->cred_flags = flags;
277 :
278 23107 : *cred_handle = (gss_cred_id_t)handle;
279 :
280 23107 : return GSS_S_COMPLETE;
281 : }
|