Bug Summary

File:lib/cfg.c
Warning:line 265, column 13
Although the value stored to 'subopts' is used in the enclosing expression, the value is never actually read from 'subopts'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cfg.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/builds/gsasl/shishi/lib -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I ./gl -I ./gl -D LOCALEDIR="/usr/local/share/locale" -D SYSTEMCFGFILE="/usr/local/etc/shishi/shishi.conf" -D SKELCFGFILE="/usr/local/etc/shishi/shishi.skel" -D HOSTKEYSFILE="/usr/local/etc/shishi/shishi.keys" -D PIC -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/builds/gsasl/shishi/lib -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/gsasl/shishi/clang-analyzer/2022-08-08-065803-50050-1 -x c cfg.c
1/* cfg.h --- Configuration file functions.
2 * Copyright (C) 2002-2022 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23#include "internal.h"
24
25/* Get prototypes. */
26#include "cfg.h"
27
28#include "low-crypto.h"
29
30enum
31{
32 DEFAULT_REALM_OPTION = 0,
33 DEFAULT_PRINCIPAL_OPTION,
34 CLIENT_KDC_ETYPES_OPTION,
35 REALM_KDC_OPTION,
36 SERVER_REALM_OPTION,
37 KDC_TIMEOUT_OPTION,
38 KDC_RETRIES_OPTION,
39 TICKET_LIFE_OPTION,
40 RENEW_LIFE_OPTION,
41 AUTHORIZATION_TYPES_OPTION,
42 VERBOSE_CRYPTO_NOISE_OPTION,
43 VERBOSE_CRYPTO_OPTION,
44 VERBOSE_ASN1_OPTION,
45 VERBOSE_NOISE_OPTION,
46 VERBOSE_OPTION,
47 STRINGPROCESS_OPTION,
48 QUICK_RANDOM,
49 THE_END
50};
51
52static const char *const _shishi_opts[] = {
53 /* [DEFAULT_REALM_OPTION] = */ "default-realm",
54 /* [DEFAULT_PRINCIPAL_OPTION] = */ "default-principal",
55 /* [CLIENT_KDC_ETYPES_OPTION] = */ "client-kdc-etypes",
56 /* [REALM_KDC_OPTION] = */ "realm-kdc",
57 /* [SERVER_REALM_OPTION] = */ "server-realm",
58 /* [KDC_TIMEOUT_OPTION] = */ "kdc-timeout",
59 /* [KDC_RETRIES_OPTION] = */ "kdc-retries",
60 /* [TICKET_LIFE_OPTION] = */ "ticket-life",
61 /* [RENEW_LIFE_OPTION] = */ "renew-life",
62 /* [AUTHORIZATION_TYPES_OPTION] = */ "authorization-types",
63 /* [VERBOSE_CRYPTO_NOISE_OPTION] = */ "verbose-crypto-noise",
64 /* [VERBOSE_CRYPTO_OPTION] = */ "verbose-crypto",
65 /* [VERBOSE_ASN1_OPTION] = */ "verbose-asn1",
66 /* [VERBOSE_NOISE_OPTION] = */ "verbose-noise",
67 /* [VERBOSE_OPTION] = */ "verbose",
68 /* [STRINGPROCESS_OPTION] = */ "stringprocess",
69 /* [QUICK_RANDOM] = */ "quick-random",
70 /* [THE_END] = */ NULL((void*)0)
71};
72
73struct Shishi_realminfo *
74_shishi_realminfo (Shishi * handle, const char *realm)
75{
76 size_t i;
77
78 for (i = 0; i < handle->nrealminfos; i++)
79 if (strcmp (realm, handle->realminfos[i].name) == 0)
80 return &handle->realminfos[i];
81
82 return NULL((void*)0);
83}
84
85struct Shishi_realminfo *
86_shishi_realminfo_new (Shishi * handle, char *realm)
87{
88 struct Shishi_realminfo *ri;
89
90 ri = _shishi_realminfo (handle, realm);
91 if (ri)
92 return ri;
93
94 handle->realminfos = xrealloc (handle->realminfos,
95 (++handle->nrealminfos) *
96 sizeof (*handle->realminfos));
97
98 ri = &handle->realminfos[handle->nrealminfos - 1];
99 memset (ri, 0, sizeof (*ri));
100 ri->name = realm;
101
102 return ri;
103}
104
105/**
106 * shishi_cfg:
107 * @handle: Shishi library handle created by shishi_init().
108 * @option: String containing shishi library options.
109 *
110 * Configures the shishi library according to the options
111 * given in @option.
112 *
113 * Return value: Returns %SHISHI_OK if @option is valid
114 * and configuration was successful.
115 **/
116int
117shishi_cfg (Shishi * handle, const char *option)
118{
119 char *opt = option ? xstrdup (option) : NULL((void*)0);
120 char *p = opt;
121 char *value;
122 int res;
123 size_t i;
124
125 while (p != NULL((void*)0) && *p != '\0')
126 {
127 switch (getsubopt (&p, (char *const *) _shishi_opts, &value))
128 {
129 case KDC_TIMEOUT_OPTION:
130 if (value && atoi (value) > 0)
131 handle->kdctimeout = atoi (value);
132 else if (value)
133 shishi_warn (handle, "Invalid KDC timeout value: `%s'", value);
134 else
135 shishi_warn (handle, "Missing KDC timeout value");
136 break;
137
138 case KDC_RETRIES_OPTION:
139 if (value && atoi (value) > 0)
140 handle->kdcretries = atoi (value);
141 else if (value)
142 shishi_warn (handle, "Invalid KDC retries value: `%s'", value);
143 else
144 shishi_warn (handle, "Missing KDC retries value");
145 break;
146
147 case TICKET_LIFE_OPTION:
148 {
149 time_t now = time (NULL((void*)0));
150 time_t then = shishi_get_date (value, &now);
151 int diff = difftime (then, now);
152
153 if (value && then != -1 && diff > 0)
154 handle->ticketlife = diff;
155 else if (diff <= 0 && diff + 60 * 60 * 24 > 0)
156 /* Hack to support "17:00" as always meaning the next 17:00. */
157 handle->ticketlife = 60 * 60 * 24 + diff;
158 else if (diff <= 0)
159 shishi_warn (handle, "Negative ticket life date: `%s'", value);
160 else if (then == -1)
161 shishi_warn (handle, "Invalid ticket life date: `%s'", value);
162 else
163 shishi_warn (handle, "Missing ticket life value");
164 }
165 break;
166
167 case RENEW_LIFE_OPTION:
168 {
169 time_t now = time (NULL((void*)0));
170 time_t then = shishi_get_date (value, &now);
171 int diff = difftime (then, now);
172
173 if (value && then != -1 && diff > 0)
174 handle->renewlife = diff;
175 else if (diff <= 0)
176 shishi_warn (handle, "Negative renew life date: `%s'", value);
177 else if (then == -1)
178 shishi_warn (handle, "Invalid renew life date: `%s'", value);
179 else
180 shishi_warn (handle, "Missing renew life value");
181 }
182 break;
183
184 case REALM_KDC_OPTION:
185 {
186 struct Shishi_realminfo *ri;
187 char *realm = NULL((void*)0);
188 char *protstr;
189 int transport = UDP;
190 int add_realm = 1;
191
192 realm = xstrdup (value);
193 for (i = 0; i < handle->nrealminfos; i++)
194 if (strcmp (realm, handle->realminfos[i].name) == 0)
195 {
196 if (handle->realminfos[i].nkdcaddresses > 0 ||
197 handle->realminfos[i].kdcaddresses)
198 {
199 free (handle->realminfos[i].kdcaddresses);
200 handle->realminfos[i].kdcaddresses = NULL((void*)0);
201 handle->realminfos[i].nkdcaddresses = 0;
202 ri = &handle->realminfos[i];
203 add_realm = 0;
204 }
205 break;
206 }
207 if (add_realm)
208 {
209 handle->realminfos = xrealloc (handle->realminfos,
210 (handle->nrealminfos + 1) *
211 sizeof (*handle->realminfos));
212 memset (&handle->realminfos[handle->nrealminfos], 0,
213 sizeof (handle->realminfos[handle->nrealminfos]));
214 handle->realminfos[handle->nrealminfos].name = realm;
215 ri = &handle->realminfos[handle->nrealminfos];
216 handle->nrealminfos++;
217 }
218 if ((protstr = strchr (p, '/')))
219 {
220 *protstr = '\0';
221 protstr++;
222 if (strcasecmp (protstr, "udp") == 0)
223 transport = UDP;
224 else if (strcasecmp (protstr, "tcp") == 0)
225 transport = TCP;
226 else if (strcasecmp (protstr, "tls") == 0)
227 transport = TLS;
228 else
229 shishi_warn (handle,
230 "Ignoring unknown KDC transport: %s", protstr);
231 }
232
233 ri->kdcaddresses = xrealloc (ri->kdcaddresses,
234 (ri->nkdcaddresses + 1) *
235 sizeof (*ri->kdcaddresses));
236 ri->kdcaddresses[ri->nkdcaddresses].transport = transport;
237 ri->kdcaddresses[ri->nkdcaddresses].hostname = xstrdup (p);
238 if ((protstr = strchr (value, ':')))
239 {
240 *protstr = '\0';
241 protstr++;
242 ri->kdcaddresses[ri->nkdcaddresses].port = protstr;
243 }
244 else
245 ri->kdcaddresses[ri->nkdcaddresses].port = NULL((void*)0);
246 ri->nkdcaddresses++;
247
248 p = NULL((void*)0); /* Done with suboptions. */
249 }
250 break;
251
252 case SERVER_REALM_OPTION:
253 {
254 struct Shishi_realminfo *ri;
255 char *subopts, *part, *next;
256
257 if (!p || (*p == 0))
258 {
259 shishi_warn (handle, "Empty server-realm for '%s'.", value);
260 break;
261 }
262
263 ri = _shishi_realminfo_new (handle, xstrdup (value));
264
265 part = subopts = xstrdup (p); /* List of patterns. */
Although the value stored to 'subopts' is used in the enclosing expression, the value is never actually read from 'subopts'
266 while (part && *part)
267 {
268 next = strchr (part, ',');
269 if (next)
270 *(next++) = '\0';
271
272 ri->serverwildcards = xrealloc (ri->serverwildcards,
273 ++ri->nserverwildcards *
274 sizeof
275 (*ri->serverwildcards));
276 ri->serverwildcards[ri->nserverwildcards - 1] =
277 xstrdup (part);
278 part = next;
279 }
280 p = NULL((void*)0); /* Done with suboptions. */
281 }
282 break;
283
284 case DEFAULT_REALM_OPTION:
285 handle->default_realm = xstrdup (value);
286 break;
287
288 case DEFAULT_PRINCIPAL_OPTION:
289 handle->default_principal = xstrdup (value);
290 break;
291
292 case CLIENT_KDC_ETYPES_OPTION:
293 res = shishi_cfg_clientkdcetype_set (handle, value);
294 if (res != SHISHI_OK)
295 goto out;
296 break;
297
298 case AUTHORIZATION_TYPES_OPTION:
299 res = shishi_cfg_authorizationtype_set (handle, value);
300 if (res != SHISHI_OK)
301 goto out;
302 break;
303
304 case STRINGPROCESS_OPTION:
305 free (handle->stringprocess);
306 handle->stringprocess = xstrdup (value);
307 break;
308
309 case QUICK_RANDOM:
310 _shishi_quick_random ();
311 break;
312
313 case VERBOSE_OPTION:
314 handle->verbose = value && atoi (value) ? atoi (value) :
315 ~0 & ~VERBOSES((1<<2) | (1<<3) | (1<<1) | (1<<4));
316 break;
317
318 case VERBOSE_CRYPTO_NOISE_OPTION:
319 handle->verbose |= SHISHI_VERBOSE_CRYPTO_NOISE(1<<4);
320 break;
321
322 case VERBOSE_CRYPTO_OPTION:
323 handle->verbose |= SHISHI_VERBOSE_CRYPTO(1<<3);
324 break;
325
326 case VERBOSE_ASN1_OPTION:
327 handle->verbose |= SHISHI_VERBOSE_ASN1(1<<2);
328 break;
329
330 case VERBOSE_NOISE_OPTION:
331 handle->verbose |= SHISHI_VERBOSE_NOISE(1<<1);
332 break;
333
334 case -1:
335 if (!value)
336 break;
337 /* fall through */
338
339 default:
340 shishi_warn (handle, "Unknown option: `%s'", value);
341 break;
342 }
343 }
344
345 res = SHISHI_OK;
346
347out:
348 free (opt);
349 return res;
350}
351
352/**
353 * shishi_cfg_from_file:
354 * @handle: Shishi library handle created by shishi_init().
355 * @cfg: Name of configuration file.
356 *
357 * Configures the shishi library using a configuration file
358 * located at @cfg.
359 *
360 * Return value: Returns %SHISHI_OK if successful.
361 **/
362int
363shishi_cfg_from_file (Shishi * handle, const char *cfg)
364{
365 char *line = NULL((void*)0);
366 size_t len = 0;
367 FILE *fh;
368
369 if (cfg == NULL((void*)0))
370 return SHISHI_OK;
371
372 fh = fopen (cfg, "r");
373 if (fh == NULL((void*)0))
374 return SHISHI_FOPEN_ERROR;
375
376 while (!feof (fh))
377 {
378 ssize_t n = getline (&line, &len, fh);
379 char *p = line;
380 char *q;
381
382 if (n <= 0)
383 /* End of file or error. */
384 break;
385
386 while (strlen (p) > 0 && (p[strlen (p) - 1] == '\n' ||
387 p[strlen (p) - 1] == '\r'))
388 p[strlen (p) - 1] = '\0';
389
390 while (*p && strchr (" \t\r\n", *p))
391 p++;
392
393 if (*p == '\0' || *p == '#')
394 continue;
395
396 q = strchr (p, ' ');
397 if (q && (strchr (p, '=') == NULL((void*)0) || q < strchr (p, '=')))
398 *q = '=';
399
400 shishi_cfg (handle, p);
401 }
402
403 free (line);
404
405 if (ferror (fh))
406 shishi_error_printf (handle, "Error reading configuration file");
407
408 if (fclose (fh) != 0)
409 return SHISHI_IO_ERROR;
410
411 return SHISHI_OK;
412}
413
414const char *
415_shishi_transport2string (int transport)
416{
417 if (transport == UDP)
418 return "UDP";
419 else if (transport == TCP)
420 return "TCP";
421 else if (transport == TLS)
422 return "TLS";
423 else
424 return "UNKNOWN";
425}
426
427/**
428 * shishi_cfg_print:
429 * @handle: Shishi library handle created by shishi_init().
430 * @fh: File stream handle opened for writing.
431 *
432 * Prints library configuration status to @fh. This function is
433 * mostly intended for debugging purposes.
434 *
435 * Return value: Always returns %SHISHI_OK.
436 **/
437int
438shishi_cfg_print (Shishi * handle, FILE * fh)
439{
440 size_t i, j;
441 time_t tmp, now = time (NULL((void*)0));
442
443 fprintf (fh, "Shishi initial library configuration:\n");
444 fprintf (fh, "\tDefault realm: %s\n",
445 handle->default_realm ? handle->default_realm : "(NULL)");
446 fprintf (fh, "\tDefault principal: %s\n",
447 handle->default_principal ? handle->default_principal : "(NULL)");
448 fprintf (fh, "\tClient KDC etypes:");
449 for (i = 0; i < handle->nclientkdcetypes; i++)
450 fprintf (fh, " %s", shishi_cipher_name (handle->clientkdcetypes[i]));
451 fprintf (fh, "\n");
452 fprintf (fh, "\tVerbose: %d\n", handle->verbose);
453 tmp = now + handle->ticketlife;
454 fprintf (fh, "\tTicket life: %d seconds. %s",
455 handle->ticketlife, ctime (&tmp));
456 tmp = now + handle->renewlife;
457 fprintf (fh, "\tRenew life: %d seconds. %s",
458 handle->renewlife, ctime (&tmp));
459 for (i = 0; i < handle->nrealminfos; i++)
460 {
461 fprintf (fh, "\tKDCs for realm %s:\n", handle->realminfos[i].name);
462 for (j = 0; j < handle->realminfos[i].nkdcaddresses; j++)
463 fprintf (fh, "\t\tTransport %s host %s port %s\n",
464 _shishi_transport2string (handle->realminfos[i].
465 kdcaddresses[j].transport),
466 handle->realminfos[i].kdcaddresses[j].hostname,
467 handle->realminfos[i].kdcaddresses[j].port);
468 }
469
470 return SHISHI_OK;
471}
472
473/**
474 * shishi_cfg_default_systemfile:
475 * @handle: Shishi library handle created by shishi_init().
476 *
477 * The system configuration file name is decided at compile
478 * time, but is replaced by assigning another file name to
479 * the environment variable $SHISHI_CONFIG. This call offers
480 * a single interface for determining the file name, to which
481 * the library turns for its settings.
482 *
483 * Return value: Returns file name of present system configuration.
484 **/
485const char *
486shishi_cfg_default_systemfile (Shishi * handle)
487{
488 char *file;
489
490 file = getenv ("SHISHI_CONFIG");
491 if (file)
492 return file;
493
494 return SYSTEMCFGFILE"/usr/local/etc/shishi/shishi.conf";
495}
496
497#define BASE_DIR"/.shishi" "/.shishi"
498
499/**
500 * shishi_cfg_default_userdirectory:
501 * @handle: Shishi library handle created by shishi_init().
502 *
503 * The default user directory, referred to for Shishi ticket cache
504 * and other purposes, is normally computed by appending the fixed
505 * string "/.shishi" to the content of the environment variable $HOME.
506 *
507 * This hard coded directory, i.e., "$HOME/.shishi/", can be replaced
508 * by whatever complete path is stored in the environment variable
509 * $SHISHI_HOME.
510 *
511 * Return value: Returns the user's directory name where the Shishi
512 * library will search for configuration files, ticket caches,
513 * etcetera.
514 **/
515const char *
516shishi_cfg_default_userdirectory (Shishi * handle)
517{
518 char *home;
519 char *envdir;
520
521 envdir = getenv ("SHISHI_HOME");
522 if (envdir)
523 return envdir;
524
525 if (!handle->userdirectory)
526 {
527 home = getenv ("HOME");
528
529 asprintf (&handle->userdirectory, "%s%s", home ? home : "", BASE_DIR"/.shishi");
530 }
531
532 return handle->userdirectory;
533}
534
535/**
536 * shishi_cfg_userdirectory_file:
537 * @handle: Shishi library handle created by shishi_init().
538 * @file: Basename of file to use for the user's configuration
539 * settings of the library.
540 *
541 * Reports the full path to the file where the Shishi library
542 * expects to find the user's library configuration, given that
543 * the file itself is named by the parameter @file.
544 *
545 * The answer is composed from the value of @file and the directory
546 * returned by shishi_cfg_default_userdirectory(). Typically, the
547 * returned string would be expanded from "$HOME/.shishi/@file".
548 *
549 * Return value: Returns the absolute filename to the argument @file,
550 * relative to the user specific Shishi configuration directory.
551 **/
552char *
553shishi_cfg_userdirectory_file (Shishi * handle, const char *file)
554{
555 char *out;
556
557 asprintf (&out, "%s/%s", shishi_cfg_default_userdirectory (handle), file);
558
559 return out;
560}
561
562#define USERCFG_FILE"shishi.conf" "shishi.conf"
563
564/**
565 * shishi_cfg_default_userfile:
566 * @handle: Shishi library handle created by shishi_init().
567 *
568 * Reports the absolute filename of the default user configuration
569 * file. This is typically "$HOME/.shishi/shishi.conf".
570 *
571 * The value of $SHISHI_HOME will change the directory part,
572 * as stated regarding shishi_cfg_default_userdirectory().
573 *
574 * Return value: Returns the user's configuration filename.
575 **/
576const char *
577shishi_cfg_default_userfile (Shishi * handle)
578{
579 if (!handle->usercfgfile)
580 handle->usercfgfile =
581 shishi_cfg_userdirectory_file (handle, USERCFG_FILE"shishi.conf");
582
583 return handle->usercfgfile;
584}
585
586/**
587 * shishi_cfg_clientkdcetype:
588 * @handle: Shishi library handle created by shishi_init().
589 * @etypes: Pointer to an array of encryption types.
590 *
591 * Sets the variable @etypes to a static array of preferred encryption
592 * types applicable to clients.
593 *
594 * Return value: Returns the number of encryption types referred to
595 * by the updated array pointer, or zero, should no type exist.
596 **/
597int
598shishi_cfg_clientkdcetype (Shishi * handle, int32_t ** etypes)
599{
600 *etypes = handle->clientkdcetypes;
601 return handle->nclientkdcetypes;
602}
603
604/**
605 * shishi_cfg_clientkdcetype_fast:
606 * @handle: Shishi library handle created by shishi_init().
607 *
608 * Extracts the default encryption type from the list of preferred
609 * encryption types acceptable to the client.
610 *
611 * When the preferred list is empty, %SHISHI_AES256_CTS_HMAC_SHA1_96
612 * is returned as a sensible default type.
613 *
614 * Return value: Returns the default encryption type.
615 **/
616int32_t
617shishi_cfg_clientkdcetype_fast (Shishi * handle)
618{
619 if (handle->nclientkdcetypes > 0)
620 return handle->clientkdcetypes[0];
621 else
622 return SHISHI_AES256_CTS_HMAC_SHA1_96;
623}
624
625/**
626 * shishi_cfg_clientkdcetype_set:
627 * @handle: Shishi library handle created by shishi_init().
628 * @value: String naming acceptable encryption types.
629 *
630 * Sets the configuration option "client-kdc-etypes" from @value.
631 * The string contains encryption types, integers or names,
632 * separated by comma or by whitespace. An example naming three
633 * encryption types could be:
634 *
635 * aes256-cts-hmac-sha1-96 des3-cbc-sha1-kd des-cbc-md5
636 *
637 * Return value: Returns %SHISHI_OK if successful, and
638 * %SHISHI_INVALID_ARGUMENT otherwise.
639 **/
640int
641shishi_cfg_clientkdcetype_set (Shishi * handle, char *value)
642{
643 char *ptrptr;
644 char *val, *tmpvalue;
645 int i;
646 int tot = 0;
647 int rc = SHISHI_INVALID_ARGUMENT;
648
649 if (value == NULL((void*)0) || *value == '\0')
650 return SHISHI_OK;
651
652 tmpvalue = xstrdup (value);
653
654 for (i = 0; (val = strtok_r (i == 0 ? tmpvalue : NULL((void*)0), ", \t", &ptrptr));
655 i++)
656 {
657 int etype = shishi_cipher_parse (val);
658
659 if (etype == -1)
660 shishi_warn (handle, "Ignoring unknown encryption type: `%s'", val);
661 else
662 {
663 int *new;
664
665 tot++;
666 new = xrealloc (handle->clientkdcetypes,
667 tot * sizeof (*handle->clientkdcetypes));
668 handle->clientkdcetypes = new;
669 handle->clientkdcetypes[tot - 1] = etype;
670 handle->nclientkdcetypes = tot;
671 rc = SHISHI_OK; /* At least one valid type. */
672 }
673 }
674
675 free (tmpvalue);
676
677 return rc;
678}
679
680/**
681 * shishi_cfg_authorizationtype_set:
682 * @handle: Shishi library handle created by shishi_init().
683 * @value: String listing acceptable authorization types.
684 *
685 * Sets the configuration option "authorization-types" from @value.
686 * The string contains authorization types, integers or names,
687 * separated by comma or whitespace.
688 *
689 * As an example, "k5login basic" would first check Kerberos5
690 * authentication based on preset principals, and then fall back
691 * to the basic test of identical principal names.
692 *
693 * Return value: Returns %SHISHI_OK if successful, and
694 * %SHISHI_INVALID_ARGUMENT otherwise.
695 **/
696int
697shishi_cfg_authorizationtype_set (Shishi * handle, char *value)
698{
699 char *ptrptr;
700 char *val, *tmpvalue;
701 int i;
702 int tot = 0;
703 int rc = SHISHI_INVALID_ARGUMENT;
704
705 if (value == NULL((void*)0) || *value == '\0')
706 return SHISHI_OK;
707
708 tmpvalue = xstrdup (value);
709
710 for (i = 0; (val = strtok_r (i == 0 ? tmpvalue : NULL((void*)0), ", \t", &ptrptr));
711 i++)
712 {
713 int atype = shishi_authorization_parse (val);
714
715 if (atype == -1)
716 shishi_warn (handle, "Ignoring unknown authorization type: `%s'",
717 val);
718 else
719 {
720 int *new;
721
722 tot++;
723 new = xrealloc (handle->authorizationtypes,
724 tot * sizeof (*handle->authorizationtypes));
725 handle->authorizationtypes = new;
726 handle->authorizationtypes[tot - 1] = atype;
727 handle->nauthorizationtypes = tot;
728 rc = SHISHI_OK; /* At least one valid type. */
729 }
730 }
731
732 free (tmpvalue);
733
734 return rc;
735}