Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/plugins/preauth/pkinit/pkinit_profile.c
34923 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/*
3
* COPYRIGHT (C) 2006,2007
4
* THE REGENTS OF THE UNIVERSITY OF MICHIGAN
5
* ALL RIGHTS RESERVED
6
*
7
* Permission is granted to use, copy, create derivative works
8
* and redistribute this software and such derivative works
9
* for any purpose, so long as the name of The University of
10
* Michigan is not used in any advertising or publicity
11
* pertaining to the use of distribution of this software
12
* without specific, written prior authorization. If the
13
* above copyright notice or any other identification of the
14
* University of Michigan is included in any copy of any
15
* portion of this software, then the disclaimer below must
16
* also be included.
17
*
18
* THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
19
* FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
20
* PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
21
* MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
22
* WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
23
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
24
* REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
25
* FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
26
* CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
27
* OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
28
* IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGES.
30
*/
31
32
#include "k5-int.h"
33
#include "pkinit.h"
34
35
/*
36
* Routines for handling profile [config file] options
37
*/
38
39
/* Forward prototypes */
40
static int _krb5_conf_boolean(const char *s);
41
42
/*
43
* XXX
44
* The following is duplicated verbatim from src/lib/krb5/krb/get_in_tkt.c,
45
* which is duplicated from somewhere else. :-/
46
* XXX
47
*/
48
static const char *const conf_yes[] = {
49
"y", "yes", "true", "t", "1", "on",
50
0,
51
};
52
53
static const char *const conf_no[] = {
54
"n", "no", "false", "nil", "0", "off",
55
0,
56
};
57
58
static int
59
_krb5_conf_boolean(const char *s)
60
{
61
const char *const *p;
62
63
for(p=conf_yes; *p; p++) {
64
if (strcasecmp(*p,s) == 0)
65
return 1;
66
}
67
68
for(p=conf_no; *p; p++) {
69
if (strcasecmp(*p,s) == 0)
70
return 0;
71
}
72
73
/* Default to "no" */
74
return 0;
75
}
76
77
/*
78
* XXX
79
* End duplicated code from src/lib/krb5/krb/get_in_tkt.c
80
* XXX
81
*/
82
83
/*
84
* The following are based on krb5_libdefault_* functions in
85
* src/lib/krb5/krb/get_in_tkt.c
86
* N.B. This assumes that context->default_realm has
87
* already been established.
88
*/
89
krb5_error_code
90
pkinit_kdcdefault_strings(krb5_context context, const char *realmname,
91
const char *option, char ***ret_value)
92
{
93
profile_t profile = NULL;
94
const char *names[5];
95
char **values = NULL;
96
krb5_error_code retval;
97
98
if (context == NULL)
99
return KV5M_CONTEXT;
100
101
profile = context->profile;
102
103
if (realmname != NULL) {
104
/*
105
* Try number one:
106
*
107
* [realms]
108
* REALM = {
109
* option = <value>
110
* }
111
*/
112
113
names[0] = KRB5_CONF_REALMS;
114
names[1] = realmname;
115
names[2] = option;
116
names[3] = 0;
117
retval = profile_get_values(profile, names, &values);
118
if (retval == 0 && values != NULL)
119
goto goodbye;
120
}
121
122
/*
123
* Try number two:
124
*
125
* [kdcdefaults]
126
* option = <value>
127
*/
128
129
names[0] = KRB5_CONF_KDCDEFAULTS;
130
names[1] = option;
131
names[2] = 0;
132
retval = profile_get_values(profile, names, &values);
133
if (retval == 0 && values != NULL)
134
goto goodbye;
135
136
goodbye:
137
if (values == NULL)
138
retval = ENOENT;
139
140
*ret_value = values;
141
142
return retval;
143
144
}
145
146
krb5_error_code
147
pkinit_kdcdefault_string(krb5_context context, const char *realmname,
148
const char *option, char **ret_value)
149
{
150
krb5_error_code retval;
151
char **values = NULL;
152
153
retval = pkinit_kdcdefault_strings(context, realmname, option, &values);
154
if (retval)
155
return retval;
156
157
if (values[0] == NULL) {
158
retval = ENOENT;
159
} else {
160
*ret_value = strdup(values[0]);
161
if (*ret_value == NULL)
162
retval = ENOMEM;
163
}
164
165
profile_free_list(values);
166
return retval;
167
}
168
169
krb5_error_code
170
pkinit_kdcdefault_boolean(krb5_context context, const char *realmname,
171
const char *option, int default_value, int *ret_value)
172
{
173
char *string = NULL;
174
krb5_error_code retval;
175
176
retval = pkinit_kdcdefault_string(context, realmname, option, &string);
177
178
if (retval == 0) {
179
*ret_value = _krb5_conf_boolean(string);
180
free(string);
181
} else
182
*ret_value = default_value;
183
184
return 0;
185
}
186
187
krb5_error_code
188
pkinit_kdcdefault_integer(krb5_context context, const char *realmname,
189
const char *option, int default_value, int *ret_value)
190
{
191
char *string = NULL;
192
krb5_error_code retval;
193
194
retval = pkinit_kdcdefault_string(context, realmname, option, &string);
195
196
if (retval == 0) {
197
char *endptr;
198
long l;
199
l = strtol(string, &endptr, 0);
200
if (endptr == string)
201
*ret_value = default_value;
202
else
203
*ret_value = l;
204
free(string);
205
} else
206
*ret_value = default_value;
207
208
return 0;
209
}
210
211
212
/*
213
* krb5_libdefault_string() is defined as static in
214
* src/lib/krb5/krb/get_in_tkt.c. Create local versions of
215
* krb5_libdefault_* functions here. We need a libdefaults_strings()
216
* function which is not currently supported there anyway. Also,
217
* add the ability to supply a default value for the boolean and
218
* integer functions.
219
*/
220
221
krb5_error_code
222
pkinit_libdefault_strings(krb5_context context, const krb5_data *realm,
223
const char *option, char ***ret_value)
224
{
225
profile_t profile;
226
const char *names[5];
227
char **values = NULL;
228
krb5_error_code retval;
229
char realmstr[1024];
230
231
if (realm != NULL && realm->length > sizeof(realmstr)-1)
232
return EINVAL;
233
234
if (realm != NULL) {
235
strncpy(realmstr, realm->data, realm->length);
236
realmstr[realm->length] = '\0';
237
}
238
239
if (!context || (context->magic != KV5M_CONTEXT))
240
return KV5M_CONTEXT;
241
242
profile = context->profile;
243
244
245
if (realm != NULL) {
246
/*
247
* Try number one:
248
*
249
* [libdefaults]
250
* REALM = {
251
* option = <value>
252
* }
253
*/
254
255
names[0] = KRB5_CONF_LIBDEFAULTS;
256
names[1] = realmstr;
257
names[2] = option;
258
names[3] = 0;
259
retval = profile_get_values(profile, names, &values);
260
if (retval == 0 && values != NULL && values[0] != NULL)
261
goto goodbye;
262
263
/*
264
* Try number two:
265
*
266
* [realms]
267
* REALM = {
268
* option = <value>
269
* }
270
*/
271
272
names[0] = KRB5_CONF_REALMS;
273
names[1] = realmstr;
274
names[2] = option;
275
names[3] = 0;
276
retval = profile_get_values(profile, names, &values);
277
if (retval == 0 && values != NULL && values[0] != NULL)
278
goto goodbye;
279
}
280
281
/*
282
* Try number three:
283
*
284
* [libdefaults]
285
* option = <value>
286
*/
287
288
names[0] = KRB5_CONF_LIBDEFAULTS;
289
names[1] = option;
290
names[2] = 0;
291
retval = profile_get_values(profile, names, &values);
292
if (retval == 0 && values != NULL && values[0] != NULL)
293
goto goodbye;
294
295
goodbye:
296
if (values == NULL)
297
return ENOENT;
298
299
*ret_value = values;
300
301
return retval;
302
}
303
304
krb5_error_code
305
pkinit_libdefault_string(krb5_context context, const krb5_data *realm,
306
const char *option, char **ret_value)
307
{
308
krb5_error_code retval;
309
char **values = NULL;
310
311
retval = pkinit_libdefault_strings(context, realm, option, &values);
312
if (retval)
313
return retval;
314
315
if (values[0] == NULL) {
316
retval = ENOENT;
317
} else {
318
*ret_value = strdup(values[0]);
319
if (*ret_value == NULL)
320
retval = ENOMEM;
321
}
322
323
profile_free_list(values);
324
return retval;
325
}
326
327
krb5_error_code
328
pkinit_libdefault_boolean(krb5_context context, const krb5_data *realm,
329
const char *option, int default_value,
330
int *ret_value)
331
{
332
char *string = NULL;
333
krb5_error_code retval;
334
335
retval = pkinit_libdefault_string(context, realm, option, &string);
336
337
if (retval == 0) {
338
*ret_value = _krb5_conf_boolean(string);
339
free(string);
340
} else
341
*ret_value = default_value;
342
343
return 0;
344
}
345
346
krb5_error_code
347
pkinit_libdefault_integer(krb5_context context, const krb5_data *realm,
348
const char *option, int default_value,
349
int *ret_value)
350
{
351
char *string = NULL;
352
krb5_error_code retval;
353
354
retval = pkinit_libdefault_string(context, realm, option, &string);
355
356
if (retval == 0) {
357
char *endptr;
358
long l;
359
l = strtol(string, &endptr, 0);
360
if (endptr == string)
361
*ret_value = default_value;
362
else
363
*ret_value = l;
364
free(string);
365
}
366
367
return retval;
368
}
369
370