5496aa33582c990cc13d2f0343c8b2e45efd4a61
[platform/upstream/krb5.git] / src / lib / gssapi / generic / gssapi_generic.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright 1993 by OpenVision Technologies, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software
6  * and its documentation for any purpose is hereby granted without fee,
7  * provided that the above copyright notice appears in all copies and
8  * that both that copyright notice and this permission notice appear in
9  * supporting documentation, and that the name of OpenVision not be used
10  * in advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission. OpenVision makes no
12  * representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21  * PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 /*
25  * $Id$
26  */
27
28 #include "gssapiP_generic.h"
29
30 /*
31  * See krb5/gssapi_krb5.c for a description of the algorithm for
32  * encoding an object identifier.
33  */
34
35 /* Reserved static storage for GSS_oids.  Comments are quotes from RFC 2744. */
36
37 #define oids ((gss_OID_desc *)const_oids)
38 static const gss_OID_desc const_oids[] = {
39     /*
40      * The implementation must reserve static storage for a
41      * gss_OID_desc object containing the value */
42     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
43     /* corresponding to an object-identifier value of
44      * {iso(1) member-body(2) United States(840) mit(113554)
45      * infosys(1) gssapi(2) generic(1) user_name(1)}.  The constant
46      * GSS_C_NT_USER_NAME should be initialized to point
47      * to that gss_OID_desc.
48      */
49
50     /*
51      * The implementation must reserve static storage for a
52      * gss_OID_desc object containing the value */
53     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
54     /* corresponding to an object-identifier value of
55      * {iso(1) member-body(2) United States(840) mit(113554)
56      * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
57      * The constant GSS_C_NT_MACHINE_UID_NAME should be
58      * initialized to point to that gss_OID_desc.
59      */
60
61     /*
62      * The implementation must reserve static storage for a
63      * gss_OID_desc object containing the value */
64     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
65     /* corresponding to an object-identifier value of
66      * {iso(1) member-body(2) United States(840) mit(113554)
67      * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
68      * The constant GSS_C_NT_STRING_UID_NAME should be
69      * initialized to point to that gss_OID_desc.
70      */
71
72     /*
73      * The implementation must reserve static storage for a
74      * gss_OID_desc object containing the value */
75     {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
76     /* corresponding to an object-identifier value of
77      * {iso(1) org(3) dod(6) internet(1) security(5)
78      * nametypes(6) gss-host-based-services(2)).  The constant
79      * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
80      * to that gss_OID_desc.  This is a deprecated OID value, and
81      * implementations wishing to support hostbased-service names
82      * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
83      * defined below, to identify such names;
84      * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
85      * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
86      * parameter, but should not be emitted by GSS-API
87      * implementations
88      */
89
90     /*
91      * The implementation must reserve static storage for a
92      * gss_OID_desc object containing the value */
93     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"},
94     /* corresponding to an object-identifier value of
95      * {iso(1) member-body(2) Unites States(840) mit(113554)
96      * infosys(1) gssapi(2) generic(1) service_name(4)}.
97      * The constant GSS_C_NT_HOSTBASED_SERVICE should be
98      * initialized to point to that gss_OID_desc.
99      */
100
101     /*
102      * The implementation must reserve static storage for a
103      * gss_OID_desc object containing the value */
104     {6, (void *)"\x2b\x06\01\x05\x06\x03"},
105     /* corresponding to an object identifier value of
106      * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
107      * 6(nametypes), 3(gss-anonymous-name)}.  The constant
108      * and GSS_C_NT_ANONYMOUS should be initialized to point
109      * to that gss_OID_desc.
110      */
111
112     /*
113      * The implementation must reserve static storage for a
114      * gss_OID_desc object containing the value */
115     {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
116     /* corresponding to an object-identifier value of
117      * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
118      * 6(nametypes), 4(gss-api-exported-name)}.  The constant
119      * GSS_C_NT_EXPORT_NAME should be initialized to point
120      * to that gss_OID_desc.
121      */
122     {6, (void *)"\x2b\x06\x01\x05\x06\x06"},
123     /* corresponding to an object-identifier value of
124      * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
125      * 6(nametypes), 6(gss-composite-export)}.  The constant
126      * GSS_C_NT_COMPOSITE_EXPORT should be initialized to point
127      * to that gss_OID_desc.
128      */
129     /* GSS_C_INQ_SSPI_SESSION_KEY 1.2.840.113554.1.2.2.5.5 */
130     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"},
131
132     /* RFC 5587 attributes, see below */
133     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x01"},
134     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x02"},
135     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x03"},
136     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x04"},
137     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x05"},
138     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x06"},
139     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x07"},
140     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x08"},
141     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x09"},
142     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0a"},
143     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0b"},
144     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0c"},
145     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0d"},
146     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0e"},
147     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0f"},
148     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x10"},
149     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x11"},
150     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x12"},
151     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x13"},
152     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x14"},
153     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x15"},
154     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x16"},
155     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x17"},
156     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x18"},
157     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"},
158     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"},
159     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"},
160 };
161
162 /* Here are the constants which point to the static structure above.
163  *
164  * Constants of the form GSS_C_NT_* are specified by rfc 2744.
165  *
166  * Constants of the form gss_nt_* are the original MIT krb5 names
167  * found in gssapi_generic.h.  They are provided for compatibility. */
168
169 GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME           = oids+0;
170 GSS_DLLIMP gss_OID gss_nt_user_name             = oids+0;
171
172 GSS_DLLIMP gss_OID GSS_C_NT_MACHINE_UID_NAME    = oids+1;
173 GSS_DLLIMP gss_OID gss_nt_machine_uid_name      = oids+1;
174
175 GSS_DLLIMP gss_OID GSS_C_NT_STRING_UID_NAME     = oids+2;
176 GSS_DLLIMP gss_OID gss_nt_string_uid_name       = oids+2;
177
178 GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = oids+3;
179 gss_OID gss_nt_service_name_v2                  = oids+3;
180
181 GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE   = oids+4;
182 GSS_DLLIMP gss_OID gss_nt_service_name          = oids+4;
183
184 GSS_DLLIMP gss_OID GSS_C_NT_ANONYMOUS           = oids+5;
185
186 GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME         = oids+6;
187 gss_OID gss_nt_exported_name                    = oids+6;
188
189 GSS_DLLIMP gss_OID GSS_C_NT_COMPOSITE_EXPORT    = oids+7;
190
191 GSS_DLLIMP gss_OID GSS_C_INQ_SSPI_SESSION_KEY   = oids+8;
192
193 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_CONCRETE     = oids+9;
194 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_PSEUDO       = oids+10;
195 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_COMPOSITE    = oids+11;
196 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_NEGO         = oids+12;
197 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_GLUE         = oids+13;
198 GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_MECH          = oids+14;
199 GSS_DLLIMP gss_const_OID GSS_C_MA_DEPRECATED        = oids+15;
200 GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_DFLT_MECH     = oids+16;
201 GSS_DLLIMP gss_const_OID GSS_C_MA_ITOK_FRAMED       = oids+17;
202 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT         = oids+18;
203 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG         = oids+19;
204 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_INIT    = oids+20;
205 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_INIT    = oids+21;
206 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_ANON    = oids+22;
207 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_ANON    = oids+23;
208 GSS_DLLIMP gss_const_OID GSS_C_MA_DELEG_CRED        = oids+24;
209 GSS_DLLIMP gss_const_OID GSS_C_MA_INTEG_PROT        = oids+25;
210 GSS_DLLIMP gss_const_OID GSS_C_MA_CONF_PROT         = oids+26;
211 GSS_DLLIMP gss_const_OID GSS_C_MA_MIC               = oids+27;
212 GSS_DLLIMP gss_const_OID GSS_C_MA_WRAP              = oids+28;
213 GSS_DLLIMP gss_const_OID GSS_C_MA_PROT_READY        = oids+29;
214 GSS_DLLIMP gss_const_OID GSS_C_MA_REPLAY_DET        = oids+30;
215 GSS_DLLIMP gss_const_OID GSS_C_MA_OOS_DET           = oids+31;
216 GSS_DLLIMP gss_const_OID GSS_C_MA_CBINDINGS         = oids+32;
217 GSS_DLLIMP gss_const_OID GSS_C_MA_PFS               = oids+33;
218 GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS          = oids+34;
219 GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS         = oids+35;
220
221 static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 };
222 gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc;
223
224 static struct mech_attr_info_desc {
225     gss_OID mech_attr;
226     const char *name;
227     const char *short_desc;
228     const char *long_desc;
229 } mech_attr_info[] = {
230     {
231         oids+9,
232         "GSS_C_MA_MECH_CONCRETE",
233         "concrete-mech",
234         "Mechanism is neither a pseudo-mechanism nor a composite mechanism.",
235     },
236     {
237         oids+10,
238         "GSS_C_MA_MECH_PSEUDO",
239         "pseudo-mech",
240         "Mechanism is a pseudo-mechanism.",
241     },
242     {
243         oids+11,
244         "GSS_C_MA_MECH_COMPOSITE",
245         "composite-mech",
246         "Mechanism is a composite of other mechanisms.",
247     },
248     {
249         oids+12,
250         "GSS_C_MA_MECH_NEGO",
251         "mech-negotiation-mech",
252         "Mechanism negotiates other mechanisms.",
253     },
254     {
255         oids+13,
256         "GSS_C_MA_MECH_GLUE",
257         "mech-glue",
258         "OID is not a mechanism but the GSS-API itself.",
259     },
260     {
261         oids+14,
262         "GSS_C_MA_NOT_MECH",
263         "not-mech",
264         "Known OID but not a mechanism OID.",
265     },
266     {
267         oids+15,
268         "GSS_C_MA_DEPRECATED",
269         "mech-deprecated",
270         "Mechanism is deprecated.",
271     },
272     {
273         oids+16,
274         "GSS_C_MA_NOT_DFLT_MECH",
275         "mech-not-default",
276         "Mechanism must not be used as a default mechanism.",
277     },
278     {
279         oids+17,
280         "GSS_C_MA_ITOK_FRAMED",
281         "initial-is-framed",
282         "Mechanism's initial contexts are properly framed.",
283     },
284     {
285         oids+18,
286         "GSS_C_MA_AUTH_INIT",
287         "auth-init-princ",
288         "Mechanism supports authentication of initiator to acceptor.",
289     },
290     {
291         oids+19,
292         "GSS_C_MA_AUTH_TARG",
293         "auth-targ-princ",
294         "Mechanism supports authentication of acceptor to initiator.",
295     },
296     {
297         oids+20,
298         "GSS_C_MA_AUTH_INIT_INIT",
299         "auth-init-princ-initial",
300         "Mechanism supports authentication of initiator using "
301         "initial credentials.",
302     },
303     {
304         oids+21,
305         "GSS_C_MA_AUTH_TARG_INIT",
306         "auth-target-princ-initial",
307         "Mechanism supports authentication of acceptor using "
308         "initial credentials.",
309     },
310     {
311         oids+22,
312         "GSS_C_MA_AUTH_INIT_ANON",
313         "auth-init-princ-anon",
314         "Mechanism supports GSS_C_NT_ANONYMOUS as an initiator name.",
315     },
316     {
317         oids+23,
318         "GSS_C_MA_AUTH_TARG_ANON",
319         "auth-targ-princ-anon",
320         "Mechanism supports GSS_C_NT_ANONYMOUS as an acceptor name.",
321     },
322     {
323         oids+24,
324         "GSS_C_MA_DELEG_CRED",
325         "deleg-cred",
326         "Mechanism supports credential delegation.",
327     },
328     {
329         oids+25,
330         "GSS_C_MA_INTEG_PROT",
331         "integ-prot",
332         "Mechanism supports per-message integrity protection.",
333     },
334     {
335         oids+26,
336         "GSS_C_MA_CONF_PROT",
337         "conf-prot",
338         "Mechanism supports per-message confidentiality protection.",
339     },
340     {
341         oids+27,
342         "GSS_C_MA_MIC",
343         "mic",
344         "Mechanism supports Message Integrity Code (MIC) tokens.",
345     },
346     {
347         oids+28,
348         "GSS_C_MA_WRAP",
349         "wrap",
350         "Mechanism supports wrap tokens.",
351     },
352     {
353         oids+29,
354         "GSS_C_MA_PROT_READY",
355         "prot-ready",
356         "Mechanism supports per-message proteciton prior to "
357         "full context establishment.",
358     },
359     {
360         oids+30,
361         "GSS_C_MA_REPLAY_DET",
362         "replay-detection",
363         "Mechanism supports replay detection.",
364     },
365     {
366         oids+31,
367         "GSS_C_MA_OOS_DET",
368         "oos-detection",
369         "Mechanism supports out-of-sequence detection.",
370     },
371     {
372         oids+32,
373         "GSS_C_MA_CBINDINGS",
374         "channel-bindings",
375         "Mechanism supports channel bindings.",
376     },
377     {
378         oids+33,
379         "GSS_C_MA_PFS",
380         "pfs",
381         "Mechanism supports Perfect Forward Security.",
382     },
383     {
384         oids+34,
385         "GSS_C_MA_COMPRESS",
386         "compress",
387         "Mechanism supports compression of data inputs to gss_wrap().",
388     },
389     {
390         oids+35,
391         "GSS_C_MA_CTX_TRANS",
392         "context-transfer",
393         "Mechanism supports security context export/import.",
394     },
395 };
396
397 OM_uint32
398 generic_gss_display_mech_attr(
399     OM_uint32         *minor_status,
400     gss_const_OID      mech_attr,
401     gss_buffer_t       name,
402     gss_buffer_t       short_desc,
403     gss_buffer_t       long_desc)
404 {
405     size_t i;
406
407     if (name != GSS_C_NO_BUFFER) {
408         name->length = 0;
409         name->value = NULL;
410     }
411     if (short_desc != GSS_C_NO_BUFFER) {
412         short_desc->length = 0;
413         short_desc->value = NULL;
414     }
415     if (long_desc != GSS_C_NO_BUFFER) {
416         long_desc->length = 0;
417         long_desc->value = NULL;
418     }
419     for (i = 0; i < sizeof(mech_attr_info)/sizeof(mech_attr_info[0]); i++) {
420         struct mech_attr_info_desc *mai = &mech_attr_info[i];
421
422         if (g_OID_equal(mech_attr, mai->mech_attr)) {
423             if (name != GSS_C_NO_BUFFER &&
424                 !g_make_string_buffer(mai->name, name)) {
425                 *minor_status = ENOMEM;
426                 return GSS_S_FAILURE;
427             }
428             if (short_desc != GSS_C_NO_BUFFER &&
429                 !g_make_string_buffer(mai->short_desc, short_desc)) {
430                 *minor_status = ENOMEM;
431                 return GSS_S_FAILURE;
432             }
433             if (long_desc != GSS_C_NO_BUFFER &&
434                 !g_make_string_buffer(mai->long_desc, long_desc)) {
435                 *minor_status = ENOMEM;
436                 return GSS_S_FAILURE;
437             }
438             return GSS_S_COMPLETE;
439         }
440     }
441
442     return GSS_S_BAD_MECH_ATTR;
443 }
444
445 static gss_buffer_desc const_attrs[] = {
446     { sizeof("local-login-user") - 1,
447       "local-login-user" },
448 };
449
450 GSS_DLLIMP gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER = &const_attrs[0];