Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/gssapi/mechglue/g_mechattr.c
39586 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* lib/gssapi/mechglue/g_mechattr.c */
3
/*
4
* Copyright (C) 2010 by the Massachusetts Institute of Technology.
5
* All rights reserved.
6
*
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
11
*
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
25
*/
26
27
#include "mglueP.h"
28
29
static int
30
testMechAttr(gss_const_OID attr,
31
gss_const_OID_set against)
32
{
33
int present = 0;
34
OM_uint32 minor;
35
36
if (GSS_ERROR(generic_gss_test_oid_set_member(&minor, attr,
37
(gss_OID_set)against,
38
&present)))
39
return 0;
40
41
return present;
42
}
43
44
/*
45
* Return TRUE iff all the elements of desired and none of the elements
46
* of except exist in available.
47
*/
48
static int
49
testMechAttrsOffered(gss_const_OID_set desired,
50
gss_const_OID_set except,
51
gss_const_OID_set available)
52
{
53
size_t i;
54
55
if (desired != GSS_C_NO_OID_SET) {
56
for (i = 0; i < desired->count; i++) {
57
if (!testMechAttr(&desired->elements[i], available))
58
return 0;
59
}
60
}
61
62
if (except != GSS_C_NO_OID_SET) {
63
for (i = 0; i < except->count; i++) {
64
if (testMechAttr(&except->elements[i], available))
65
return 0;
66
}
67
}
68
69
return 1;
70
}
71
72
/*
73
* Return TRUE iff all the elements of critical exist in known.
74
*/
75
static int
76
testMechAttrsKnown(gss_const_OID_set critical,
77
gss_const_OID_set known)
78
{
79
size_t i;
80
81
if (critical != GSS_C_NO_OID_SET) {
82
for (i = 0; i < critical->count; i++) {
83
if (!testMechAttr(&critical->elements[i], known))
84
return 0;
85
}
86
}
87
88
return 1;
89
}
90
91
OM_uint32 KRB5_CALLCONV
92
gss_indicate_mechs_by_attrs(
93
OM_uint32 *minor,
94
gss_const_OID_set desired_mech_attrs,
95
gss_const_OID_set except_mech_attrs,
96
gss_const_OID_set critical_mech_attrs,
97
gss_OID_set *mechs)
98
{
99
OM_uint32 status, tmpMinor;
100
gss_OID_set allMechs = GSS_C_NO_OID_SET;
101
size_t i;
102
103
if (minor != NULL)
104
*minor = 0;
105
106
if (mechs != NULL)
107
*mechs = GSS_C_NO_OID_SET;
108
109
if (minor == NULL || mechs == NULL)
110
return GSS_S_CALL_INACCESSIBLE_WRITE;
111
112
status = gss_indicate_mechs(minor, &allMechs);
113
if (GSS_ERROR(status))
114
goto cleanup;
115
116
status = generic_gss_create_empty_oid_set(minor, mechs);
117
if (GSS_ERROR(status))
118
goto cleanup;
119
120
for (i = 0; i < allMechs->count; i++) {
121
gss_OID_set supportedAttrs = GSS_C_NO_OID_SET;
122
gss_OID_set knownAttrs = GSS_C_NO_OID_SET;
123
124
status = gss_inquire_attrs_for_mech(minor, &allMechs->elements[i],
125
&supportedAttrs, &knownAttrs);
126
if (GSS_ERROR(status))
127
continue;
128
129
if (testMechAttrsOffered(desired_mech_attrs,
130
except_mech_attrs, supportedAttrs) &&
131
testMechAttrsKnown(critical_mech_attrs, knownAttrs)) {
132
status = gss_add_oid_set_member(minor, &allMechs->elements[i],
133
mechs);
134
if (GSS_ERROR(status)) {
135
gss_release_oid_set(&tmpMinor, &supportedAttrs);
136
gss_release_oid_set(&tmpMinor, &knownAttrs);
137
goto cleanup;
138
}
139
}
140
141
gss_release_oid_set(&tmpMinor, &supportedAttrs);
142
gss_release_oid_set(&tmpMinor, &knownAttrs);
143
}
144
145
*minor = 0;
146
status = GSS_S_COMPLETE;
147
148
cleanup:
149
gss_release_oid_set(&tmpMinor, &allMechs);
150
151
return status;
152
}
153
154
OM_uint32 KRB5_CALLCONV
155
gss_inquire_attrs_for_mech(
156
OM_uint32 *minor,
157
gss_const_OID mech_oid,
158
gss_OID_set *mech_attrs,
159
gss_OID_set *known_mech_attrs)
160
{
161
OM_uint32 status, tmpMinor;
162
gss_OID selected_mech, public_mech;
163
gss_mechanism mech;
164
165
if (minor != NULL)
166
*minor = 0;
167
168
if (mech_attrs != NULL)
169
*mech_attrs = GSS_C_NO_OID_SET;
170
171
if (known_mech_attrs != NULL)
172
*known_mech_attrs = GSS_C_NO_OID_SET;
173
174
if (minor == NULL)
175
return GSS_S_CALL_INACCESSIBLE_WRITE;
176
177
status = gssint_select_mech_type(minor, mech_oid, &selected_mech);
178
if (status != GSS_S_COMPLETE)
179
return status;
180
181
mech = gssint_get_mechanism(selected_mech);
182
if (mech == NULL)
183
return GSS_S_BAD_MECH;
184
185
if (mech->gss_inquire_attrs_for_mech != NULL) {
186
public_mech = gssint_get_public_oid(selected_mech);
187
status = mech->gss_inquire_attrs_for_mech(minor, public_mech,
188
mech_attrs,
189
known_mech_attrs);
190
if (GSS_ERROR(status)) {
191
map_error(minor, mech);
192
return status;
193
}
194
}
195
196
/* Make sure *mech_attrs is a proper OID set, as GSS_C_NO_OID_SET is not
197
* accepted by gss_test_oid_set_member(). */
198
if (mech_attrs != NULL && *mech_attrs == GSS_C_NO_OID_SET) {
199
status = generic_gss_create_empty_oid_set(minor, mech_attrs);
200
if (status != GSS_S_COMPLETE) {
201
if (known_mech_attrs != NULL)
202
gss_release_oid_set(&tmpMinor, known_mech_attrs);
203
return status;
204
}
205
}
206
207
if (known_mech_attrs != NULL && *known_mech_attrs == GSS_C_NO_OID_SET) {
208
if (mech->gss_inquire_attrs_for_mech != NULL) {
209
/* A mech can leave *known_mech_attrs alone as shorthand for
210
* understanding the RFC 5587 attribute set. */
211
status = generic_gss_copy_oid_set(minor,
212
gss_ma_known_attrs,
213
known_mech_attrs);
214
} else {
215
/* The mech does not implement RFC 5587. Indicate that it doesn't
216
* know about any attributes. */
217
status = generic_gss_create_empty_oid_set(minor, known_mech_attrs);
218
}
219
if (GSS_ERROR(status)) {
220
gss_release_oid_set(&tmpMinor, mech_attrs);
221
if (mech_attrs != NULL)
222
*mech_attrs = GSS_C_NO_OID_SET;
223
}
224
}
225
226
return GSS_S_COMPLETE;
227
}
228
229
OM_uint32 KRB5_CALLCONV
230
gss_display_mech_attr(
231
OM_uint32 *minor,
232
gss_const_OID mech_attr,
233
gss_buffer_t name,
234
gss_buffer_t short_desc,
235
gss_buffer_t long_desc)
236
{
237
return generic_gss_display_mech_attr(minor, mech_attr,
238
name, short_desc, long_desc);
239
}
240
241