2 * Copyright (c) 2009 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
34 #include "gsskrb5_locl.h"
36 OM_uint32 GSSAPI_CALLCONV
37 _gsskrb5_export_cred(OM_uint32
*minor_status
,
38 gss_cred_id_t cred_handle
,
39 gss_buffer_t cred_token
)
41 OM_uint32 major_status
;
42 gsskrb5_cred handle
= (gsskrb5_cred
)cred_handle
;
50 GSSAPI_KRB5_INIT (&context
);
52 if (handle
->usage
!= GSS_C_INITIATE
&& handle
->usage
!= GSS_C_BOTH
) {
53 *minor_status
= GSS_KRB5_S_G_BAD_USAGE
;
57 sp
= krb5_storage_emem();
59 *minor_status
= ENOMEM
;
63 type
= krb5_cc_get_type(context
, handle
->ccache
);
64 if (strcmp(type
, "MEMORY") == 0) {
66 krb5_data config_start_realm
;
69 ret
= krb5_store_uint32(sp
, 0);
71 krb5_storage_free(sp
);
76 ret
= krb5_cc_get_config(context
, handle
->ccache
, NULL
, "start_realm",
79 start_realm
= strndup(config_start_realm
.data
,
80 config_start_realm
.length
);
81 krb5_data_free(&config_start_realm
);
83 start_realm
= strdup(krb5_principal_get_realm(context
,
86 if (start_realm
== NULL
) {
87 *minor_status
= krb5_enomem(context
);
88 krb5_storage_free(sp
);
92 ret
= _krb5_get_krbtgt(context
, handle
->ccache
, start_realm
, &creds
);
96 krb5_storage_free(sp
);
101 ret
= krb5_store_creds(sp
, creds
);
102 krb5_free_creds(context
, creds
);
104 krb5_storage_free(sp
);
106 return GSS_S_FAILURE
;
110 ret
= krb5_store_uint32(sp
, 1);
112 krb5_storage_free(sp
);
114 return GSS_S_FAILURE
;
117 ret
= krb5_cc_get_full_name(context
, handle
->ccache
, &str
);
119 krb5_storage_free(sp
);
121 return GSS_S_FAILURE
;
124 ret
= krb5_store_string(sp
, str
);
127 krb5_storage_free(sp
);
129 return GSS_S_FAILURE
;
132 ret
= krb5_storage_to_data(sp
, &data
);
133 krb5_storage_free(sp
);
136 return GSS_S_FAILURE
;
138 sp
= krb5_storage_emem();
140 krb5_data_free(&data
);
141 *minor_status
= ENOMEM
;
142 return GSS_S_FAILURE
;
145 major_status
= _gss_mg_store_oid(minor_status
, sp
, GSS_KRB5_MECHANISM
);
146 if (major_status
!= GSS_S_COMPLETE
) {
147 krb5_data_free(&data
);
148 krb5_storage_free(sp
);
152 ret
= krb5_store_data(sp
, data
);
153 krb5_data_free(&data
);
155 krb5_storage_free(sp
);
157 return GSS_S_FAILURE
;
160 ret
= krb5_storage_to_data(sp
, &data
);
161 krb5_storage_free(sp
);
164 return GSS_S_FAILURE
;
167 cred_token
->value
= data
.data
;
168 cred_token
->length
= data
.length
;
170 return GSS_S_COMPLETE
;
173 OM_uint32 GSSAPI_CALLCONV
174 _gsskrb5_import_cred(OM_uint32
* minor_status
,
175 gss_buffer_t cred_token
,
176 gss_cred_id_t
* cred_handle
)
178 krb5_context context
;
187 *cred_handle
= GSS_C_NO_CREDENTIAL
;
189 GSSAPI_KRB5_INIT (&context
);
191 sp
= krb5_storage_from_mem(cred_token
->value
, cred_token
->length
);
193 *minor_status
= ENOMEM
;
194 return GSS_S_FAILURE
;
197 ret
= krb5_ret_uint32(sp
, &type
);
199 krb5_storage_free(sp
);
201 return GSS_S_FAILURE
;
207 ret
= krb5_ret_creds(sp
, &creds
);
208 krb5_storage_free(sp
);
211 return GSS_S_FAILURE
;
214 ret
= krb5_cc_new_unique(context
, "MEMORY", NULL
, &id
);
217 return GSS_S_FAILURE
;
220 ret
= krb5_cc_initialize(context
, id
, creds
.client
);
222 krb5_cc_destroy(context
, id
);
224 return GSS_S_FAILURE
;
227 ret
= krb5_cc_store_cred(context
, id
, &creds
);
228 krb5_free_cred_contents(context
, &creds
);
231 return GSS_S_FAILURE
;
234 flags
|= GSS_CF_DESTROY_CRED_ON_RELEASE
;
239 ret
= krb5_ret_string(sp
, &str
);
240 krb5_storage_free(sp
);
243 return GSS_S_FAILURE
;
246 ret
= krb5_cc_resolve(context
, str
, &id
);
250 return GSS_S_FAILURE
;
255 krb5_storage_free(sp
);
257 return GSS_S_NO_CRED
;
260 handle
= calloc(1, sizeof(*handle
));
261 if (handle
== NULL
) {
262 krb5_cc_close(context
, id
);
263 *minor_status
= ENOMEM
;
264 return GSS_S_FAILURE
;
267 handle
->usage
= GSS_C_INITIATE
;
268 handle
->destination_realm
= NULL
;
269 krb5_cc_get_principal(context
, id
, &handle
->principal
);
271 handle
->cred_flags
= flags
;
273 *cred_handle
= (gss_cred_id_t
)handle
;
275 return GSS_S_COMPLETE
;