Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_import_name.c
34907 views
1
/*-
2
* Copyright (c) 2005 Doug Rabson
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*
26
* $FreeBSD: src/lib/libgssapi/gss_import_name.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
27
*/
28
29
#include "mech_locl.h"
30
31
static OM_uint32
32
_gss_import_export_name(OM_uint32 *minor_status,
33
const gss_buffer_t input_name_buffer,
34
gss_name_t *output_name)
35
{
36
OM_uint32 major_status;
37
unsigned char *p = input_name_buffer->value;
38
size_t len = input_name_buffer->length;
39
size_t t;
40
gss_OID_desc mech_oid;
41
gssapi_mech_interface m;
42
struct _gss_name *name;
43
gss_name_t new_canonical_name;
44
int composite = 0;
45
46
*minor_status = 0;
47
*output_name = 0;
48
49
/*
50
* Make sure that TOK_ID is {4, 1}.
51
*/
52
if (len < 2)
53
return (GSS_S_BAD_NAME);
54
if (p[0] != 4)
55
return (GSS_S_BAD_NAME);
56
switch (p[1]) {
57
case 1: /* non-composite name */
58
break;
59
case 2: /* composite name */
60
composite = 1;
61
break;
62
default:
63
return (GSS_S_BAD_NAME);
64
}
65
p += 2;
66
len -= 2;
67
68
/*
69
* Get the mech length and the name length and sanity
70
* check the size of of the buffer.
71
*/
72
if (len < 2)
73
return (GSS_S_BAD_NAME);
74
t = (p[0] << 8) + p[1];
75
p += 2;
76
len -= 2;
77
78
/*
79
* Check the DER encoded OID to make sure it agrees with the
80
* length we just decoded.
81
*/
82
if (p[0] != 6) /* 6=OID */
83
return (GSS_S_BAD_NAME);
84
p++;
85
len--;
86
t--;
87
if (p[0] & 0x80) {
88
int digits = p[0];
89
p++;
90
len--;
91
t--;
92
mech_oid.length = 0;
93
while (digits--) {
94
mech_oid.length = (mech_oid.length << 8) | p[0];
95
p++;
96
len--;
97
t--;
98
}
99
} else {
100
mech_oid.length = p[0];
101
p++;
102
len--;
103
t--;
104
}
105
if (mech_oid.length != t)
106
return (GSS_S_BAD_NAME);
107
108
mech_oid.elements = p;
109
110
if (len < t + 4)
111
return (GSS_S_BAD_NAME);
112
p += t;
113
len -= t;
114
115
t = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
116
/* p += 4; */
117
len -= 4;
118
119
if (!composite && len != t)
120
return (GSS_S_BAD_NAME);
121
122
m = __gss_get_mechanism(&mech_oid);
123
if (!m)
124
return (GSS_S_BAD_MECH);
125
126
/*
127
* Ask the mechanism to import the name.
128
*/
129
major_status = m->gm_import_name(minor_status,
130
input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name);
131
if (major_status != GSS_S_COMPLETE) {
132
_gss_mg_error(m, major_status, *minor_status);
133
return major_status;
134
}
135
136
/*
137
* Now we make a new name and mark it as an MN.
138
*/
139
name = _gss_make_name(m, new_canonical_name);
140
if (!name) {
141
m->gm_release_name(minor_status, &new_canonical_name);
142
return (GSS_S_FAILURE);
143
}
144
145
*output_name = (gss_name_t) name;
146
147
*minor_status = 0;
148
return (GSS_S_COMPLETE);
149
}
150
151
/**
152
* Import a name internal or mechanism name
153
*
154
* Type of name and their format:
155
* - GSS_C_NO_OID
156
* - GSS_C_NT_USER_NAME
157
* - GSS_C_NT_HOSTBASED_SERVICE
158
* - GSS_C_NT_EXPORT_NAME
159
* - GSS_C_NT_ANONYMOUS
160
* - GSS_KRB5_NT_PRINCIPAL_NAME
161
*
162
* For more information about @ref internalVSmechname.
163
*
164
* @param minor_status minor status code
165
* @param input_name_buffer import name buffer
166
* @param input_name_type type of the import name buffer
167
* @param output_name the resulting type, release with
168
* gss_release_name(), independent of input_name
169
*
170
* @returns a gss_error code, see gss_display_status() about printing
171
* the error code.
172
*
173
* @ingroup gssapi
174
*/
175
176
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
177
gss_import_name(OM_uint32 *minor_status,
178
const gss_buffer_t input_name_buffer,
179
const gss_OID input_name_type,
180
gss_name_t *output_name)
181
{
182
struct _gss_mechanism_name *mn;
183
gss_OID name_type = input_name_type;
184
OM_uint32 major_status, ms;
185
struct _gss_name *name;
186
struct _gss_mech_switch *m;
187
gss_name_t rname;
188
189
*output_name = GSS_C_NO_NAME;
190
191
if (input_name_buffer->length == 0) {
192
*minor_status = 0;
193
return (GSS_S_BAD_NAME);
194
}
195
196
_gss_load_mech();
197
198
/*
199
* Use GSS_NT_USER_NAME as default name type.
200
*/
201
if (name_type == GSS_C_NO_OID)
202
name_type = GSS_C_NT_USER_NAME;
203
204
/*
205
* If this is an exported name, we need to parse it to find
206
* the mechanism and then import it as an MN. See RFC 2743
207
* section 3.2 for a description of the format.
208
*/
209
if (gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME)) {
210
return _gss_import_export_name(minor_status,
211
input_name_buffer, output_name);
212
}
213
214
215
*minor_status = 0;
216
name = calloc(1, sizeof(struct _gss_name));
217
if (!name) {
218
*minor_status = ENOMEM;
219
return (GSS_S_FAILURE);
220
}
221
222
HEIM_SLIST_INIT(&name->gn_mn);
223
224
major_status = _gss_copy_oid(minor_status,
225
name_type, &name->gn_type);
226
if (major_status) {
227
free(name);
228
return (GSS_S_FAILURE);
229
}
230
231
major_status = _gss_copy_buffer(minor_status,
232
input_name_buffer, &name->gn_value);
233
if (major_status)
234
goto out;
235
236
/*
237
* Walk over the mechs and import the name into a mech name
238
* for those supported this nametype.
239
*/
240
241
HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) {
242
int present = 0;
243
244
major_status = gss_test_oid_set_member(minor_status,
245
name_type, m->gm_name_types, &present);
246
247
if (major_status || present == 0)
248
continue;
249
250
mn = malloc(sizeof(struct _gss_mechanism_name));
251
if (!mn) {
252
*minor_status = ENOMEM;
253
major_status = GSS_S_FAILURE;
254
goto out;
255
}
256
257
major_status = (*m->gm_mech.gm_import_name)(minor_status,
258
&name->gn_value,
259
(name->gn_type.elements
260
? &name->gn_type : GSS_C_NO_OID),
261
&mn->gmn_name);
262
if (major_status != GSS_S_COMPLETE) {
263
_gss_mg_error(&m->gm_mech, major_status, *minor_status);
264
free(mn);
265
goto out;
266
}
267
268
mn->gmn_mech = &m->gm_mech;
269
mn->gmn_mech_oid = &m->gm_mech_oid;
270
HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
271
}
272
273
/*
274
* If we can't find a mn for the name, bail out already here.
275
*/
276
277
mn = HEIM_SLIST_FIRST(&name->gn_mn);
278
if (!mn) {
279
*minor_status = 0;
280
major_status = GSS_S_NAME_NOT_MN;
281
goto out;
282
}
283
284
*output_name = (gss_name_t) name;
285
return (GSS_S_COMPLETE);
286
287
out:
288
rname = (gss_name_t)name;
289
gss_release_name(&ms, &rname);
290
return major_status;
291
}
292
293