Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_cred.c
34914 views
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 KTH nor the names of its contributors may be
18
* used to endorse or promote products derived from this software without
19
* specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*/
33
34
#include "mech_locl.h"
35
#include <krb5.h>
36
37
/*
38
* format: any number of:
39
* mech-len: int32
40
* mech-data: char * (not alligned)
41
* cred-len: int32
42
* cred-data char * (not alligned)
43
*/
44
45
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
46
gss_export_cred(OM_uint32 * minor_status,
47
gss_cred_id_t cred_handle,
48
gss_buffer_t token)
49
{
50
struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
51
struct _gss_mechanism_cred *mc;
52
gss_buffer_desc buffer;
53
krb5_error_code ret;
54
krb5_storage *sp;
55
OM_uint32 major;
56
krb5_data data;
57
58
_mg_buffer_zero(token);
59
60
if (cred == NULL) {
61
*minor_status = 0;
62
return GSS_S_NO_CRED;
63
}
64
65
HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
66
if (mc->gmc_mech->gm_export_cred == NULL) {
67
*minor_status = 0;
68
return GSS_S_NO_CRED;
69
}
70
}
71
72
sp = krb5_storage_emem();
73
if (sp == NULL) {
74
*minor_status = ENOMEM;
75
return GSS_S_FAILURE;
76
}
77
78
HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
79
80
major = mc->gmc_mech->gm_export_cred(minor_status,
81
mc->gmc_cred, &buffer);
82
if (major) {
83
krb5_storage_free(sp);
84
return major;
85
}
86
87
ret = krb5_storage_write(sp, buffer.value, buffer.length);
88
if (ret < 0 || (size_t)ret != buffer.length) {
89
gss_release_buffer(minor_status, &buffer);
90
krb5_storage_free(sp);
91
*minor_status = EINVAL;
92
return GSS_S_FAILURE;
93
}
94
gss_release_buffer(minor_status, &buffer);
95
}
96
97
ret = krb5_storage_to_data(sp, &data);
98
krb5_storage_free(sp);
99
if (ret) {
100
*minor_status = ret;
101
return GSS_S_FAILURE;
102
}
103
104
token->value = data.data;
105
token->length = data.length;
106
107
return GSS_S_COMPLETE;
108
}
109
110
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
111
gss_import_cred(OM_uint32 * minor_status,
112
gss_buffer_t token,
113
gss_cred_id_t * cred_handle)
114
{
115
gssapi_mech_interface m;
116
krb5_error_code ret;
117
struct _gss_cred *cred;
118
krb5_storage *sp = NULL;
119
OM_uint32 major, junk;
120
krb5_data data;
121
122
*cred_handle = GSS_C_NO_CREDENTIAL;
123
124
if (token->length == 0) {
125
*minor_status = ENOMEM;
126
return GSS_S_FAILURE;
127
}
128
129
sp = krb5_storage_from_readonly_mem(token->value, token->length);
130
if (sp == NULL) {
131
*minor_status = ENOMEM;
132
return GSS_S_FAILURE;
133
}
134
135
cred = calloc(1, sizeof(struct _gss_cred));
136
if (cred == NULL) {
137
krb5_storage_free(sp);
138
*minor_status = ENOMEM;
139
return GSS_S_FAILURE;
140
}
141
HEIM_SLIST_INIT(&cred->gc_mc);
142
143
*cred_handle = (gss_cred_id_t)cred;
144
145
while(1) {
146
struct _gss_mechanism_cred *mc;
147
gss_buffer_desc buffer;
148
gss_cred_id_t mcred;
149
gss_OID_desc oid;
150
151
ret = krb5_ret_data(sp, &data);
152
if (ret == HEIM_ERR_EOF) {
153
break;
154
} else if (ret) {
155
*minor_status = ret;
156
major = GSS_S_FAILURE;
157
goto out;
158
}
159
oid.elements = data.data;
160
oid.length = data.length;
161
162
m = __gss_get_mechanism(&oid);
163
krb5_data_free(&data);
164
if (!m) {
165
*minor_status = 0;
166
major = GSS_S_BAD_MECH;
167
goto out;
168
}
169
170
if (m->gm_import_cred == NULL) {
171
*minor_status = 0;
172
major = GSS_S_BAD_MECH;
173
goto out;
174
}
175
176
ret = krb5_ret_data(sp, &data);
177
if (ret) {
178
*minor_status = ret;
179
major = GSS_S_FAILURE;
180
goto out;
181
}
182
183
buffer.value = data.data;
184
buffer.length = data.length;
185
186
major = m->gm_import_cred(minor_status,
187
&buffer, &mcred);
188
krb5_data_free(&data);
189
if (major) {
190
goto out;
191
}
192
193
mc = malloc(sizeof(struct _gss_mechanism_cred));
194
if (mc == NULL) {
195
*minor_status = EINVAL;
196
major = GSS_S_FAILURE;
197
goto out;
198
}
199
200
mc->gmc_mech = m;
201
mc->gmc_mech_oid = &m->gm_mech_oid;
202
mc->gmc_cred = mcred;
203
204
HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
205
}
206
krb5_storage_free(sp);
207
sp = NULL;
208
209
if (HEIM_SLIST_EMPTY(&cred->gc_mc)) {
210
major = GSS_S_NO_CRED;
211
goto out;
212
}
213
214
return GSS_S_COMPLETE;
215
216
out:
217
if (sp)
218
krb5_storage_free(sp);
219
220
gss_release_cred(&junk, cred_handle);
221
222
return major;
223
224
}
225
226