1 /* cfg.c configuration file functions.
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but 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.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 DEFAULT_REALM_OPTION
= 0,
27 DEFAULT_PRINCIPAL_OPTION
,
28 CLIENT_KDC_ETYPES_OPTION
,
33 VERBOSE_CRYPTO_OPTION
,
41 static char *const _shishi_opts
[] = {
42 /* [DEFAULT_REALM_OPTION] = */ "default-realm",
43 /* [DEFAULT_PRINCIPAL_OPTION] = */ "default-principal",
44 /* [CLIENT_KDC_ETYPES_OPTION] = */ "client-kdc-etypes",
45 /* [REALM_KDC_OPTION] = */ "realm-kdc",
46 /* [KDC_OPTION] = */ "kdc",
47 /* [KDC_TIMEOUT_OPTION] = */ "kdc-timeout",
48 /* [KDC_RETRIES_OPTION] = */ "kdc-retries",
49 /* [VERBOSE_CRYPTO_OPTION] = */ "verbose-crypto",
50 /* [VERBOSE_ASN1_OPTION] = */ "verbose-asn1",
51 /* [VERBOSE_NOICE_OPTION] = */ "verbose-noice",
52 /* [VERBOSE_OPTION] = */ "verbose",
53 /* [STRINGPROCESS_OPTION] = */ "stringprocess",
54 /* [THE_END] = */ NULL
57 int getsubopt (char **optionp
, char *const *tokens
, char **valuep
);
61 * @option: string with shishi library option.
63 * Configure shishi library with given option.
65 * Return Value: Returns SHISHI_OK if option was valid.
68 shishi_cfg (Shishi
* handle
, char *option
)
75 while (option
!= NULL
&& *option
!= '\0')
77 switch (getsubopt (&option
, _shishi_opts
, &value
))
79 case KDC_TIMEOUT_OPTION
:
80 if (value
&& atoi (value
) > 0)
81 handle
->kdctimeout
= atoi (value
);
83 shishi_warn (handle
, "Invalid KDC timeout value: `%s'\n", value
);
85 shishi_warn (handle
, "Missing KDC timeout value.\n");
88 case KDC_RETRIES_OPTION
:
89 if (value
&& atoi (value
) > 0)
90 handle
->kdcretries
= atoi (value
);
92 shishi_warn (handle
, "Invalid KDC retries value: `%s'\n", value
);
94 shishi_warn (handle
, "Missing KDC retries value.\n");
97 case REALM_KDC_OPTION
:
98 realm
= strdup (value
);
99 for (i
= 0; i
< handle
->nrealminfos
; i
++)
100 if (strcmp (realm
, handle
->realminfos
[i
].name
) == 0)
102 if (handle
->realminfos
[i
].nkdcaddresses
> 0 ||
103 handle
->realminfos
[i
].kdcaddresses
)
105 if (handle
->realminfos
[i
].kdcaddresses
)
106 free (handle
->realminfos
[i
].kdcaddresses
);
107 handle
->realminfos
[i
].kdcaddresses
= NULL
;
108 handle
->realminfos
[i
].nkdcaddresses
= 0;
112 handle
->realminfos
= realloc (handle
->realminfos
,
113 (handle
->nrealminfos
+ 1) *
114 sizeof (*handle
->realminfos
));
115 if (handle
->realminfos
== NULL
)
116 return SHISHI_MALLOC_ERROR
;
117 handle
->realminfos
[handle
->nrealminfos
].name
= realm
;
118 handle
->realminfos
[handle
->nrealminfos
].kdcaddresses
= NULL
;
119 handle
->realminfos
[handle
->nrealminfos
].nkdcaddresses
= 0;
120 handle
->nrealminfos
++;
122 case DEFAULT_REALM_OPTION
:
123 handle
->default_realm
= strdup (value
);
125 case DEFAULT_PRINCIPAL_OPTION
:
126 handle
->default_principal
= strdup (value
);
128 case CLIENT_KDC_ETYPES_OPTION
:
129 res
= shishi_cfg_clientkdcetype_set (handle
, value
);
130 if (res
!= SHISHI_OK
)
134 handle
->kdc
= strdup (value
);
136 case STRINGPROCESS_OPTION
:
137 handle
->stringprocess
= strdup (value
);
140 handle
->verbose
= value
&& atoi (value
) ? atoi (value
) :
143 case VERBOSE_CRYPTO_OPTION
:
144 handle
->verbose
|= SHISHI_VERBOSE_CRYPTO
;
146 case VERBOSE_ASN1_OPTION
:
147 handle
->verbose
|= SHISHI_VERBOSE_ASN1
;
149 case VERBOSE_NOICE_OPTION
:
150 handle
->verbose
|= SHISHI_VERBOSE_NOICE
;
155 for (i
= 0; i
< handle
->nrealminfos
; i
++)
156 if (realm
&& handle
->realminfos
[i
].name
== realm
)
158 struct Shishi_realminfo
*ri
= &handle
->realminfos
[i
];
159 struct sockaddr_in
*sinaddr
;
163 he
= gethostbyname (value
); /* XXX move to netio.c */
165 he
->h_addr_list
[0] == NULL
|| he
->h_addrtype
!= AF_INET
)
168 "Unknown KDC host `%s' (h_errno %d)\n",
173 ri
->kdcaddresses
= realloc (ri
->kdcaddresses
,
174 (ri
->nkdcaddresses
+ 1) *
175 sizeof (*ri
->kdcaddresses
));
176 if (ri
->kdcaddresses
== NULL
)
177 return SHISHI_MALLOC_ERROR
;
178 ri
->kdcaddresses
[ri
->nkdcaddresses
].name
= strdup (value
);
179 sinaddr
= (struct sockaddr_in
*)
180 &ri
->kdcaddresses
[ri
->nkdcaddresses
].sockaddress
;
181 memset (sinaddr
, 0, sizeof (struct sockaddr
));
184 sinaddr
->sin_family
= he
->h_addrtype
;
185 memcpy (&sinaddr
->sin_addr
, he
->h_addr_list
[0], he
->h_length
);
186 se
= getservbyname ("kerberos", NULL
);
188 sinaddr
->sin_port
= se
->s_port
;
190 sinaddr
->sin_port
= htons (88);
197 shishi_warn (handle
, "Unknown option: `%s'\n", value
);
206 * shishi_cfg_from_file:
207 * @cfg: filename to read configuration from.
209 * Configure shishi library using configuration file.
211 * Return Value: Returns SHISHI_OK iff succesful.
214 shishi_cfg_from_file (Shishi
* handle
, const char *cfg
)
222 fh
= fopen (cfg
, "r");
225 shishi_warn (handle
, "`%s': %s", cfg
, strerror (errno
));
226 return SHISHI_FOPEN_ERROR
;
229 while (!feof (fh
) && !ferror (fh
))
231 if (!fgets (line
, sizeof (line
), fh
))
234 line
[strlen (line
) - 1] = '\0';
236 while (line
[0] && strchr (" \t\r\n", line
[0]))
237 memmove (line
, line
+ 1, strlen (line
));
239 if (line
[0] == '#' || line
[0] == '\0')
242 if (strchr (line
, ' ') && (strchr (line
, '=') == NULL
||
243 strchr (line
, ' ') < strchr (line
, '=')))
245 char *p
= strchr (line
, ' ');
246 while (*(p
+ 1) == ' ' || *(p
+ 1) == '=')
247 memmove (p
, p
+ 1, strlen (p
+ 1) + 1);
251 shishi_cfg (handle
, line
);
254 if (fclose (fh
) != 0)
255 return SHISHI_FCLOSE_ERROR
;
257 if (VERBOSE (handle
))
258 shishi_cfg_print (handle
, stdout
);
265 * @handle: Shishi library handle create by shishi_init().
266 * @fh: file descriptor opened for writing.
268 * Print library configuration status, mostly for debugging purposes.
270 * Return Value: Returns SHISHI_OK.
273 shishi_cfg_print (Shishi
* handle
, FILE * fh
)
277 fprintf (fh
, "Shishi initial library configuration:\n");
278 fprintf (fh
, "\tDefault realm: %s\n",
279 handle
->default_realm
? handle
->default_realm
: "(NULL)");
280 fprintf (fh
, "\tDefault principal: %s\n",
281 handle
->default_principal
? handle
->default_principal
: "(NULL)");
282 fprintf (fh
, "\tClient KDC etypes:");
283 for (i
= 0; i
< handle
->nclientkdcetypes
; i
++)
284 fprintf (fh
, " %s", shishi_cipher_name (handle
->clientkdcetypes
[i
]));
286 fprintf (fh
, "\tKDC: %s\n", handle
->kdc
? handle
->kdc
: "(NULL)");
287 fprintf (fh
, "\tVerbose: %d\n", handle
->verbose
);
288 for (i
= 0; i
< handle
->nrealminfos
; i
++)
290 fprintf (fh
, "\tRealm %s's KDCs:", handle
->realminfos
[i
].name
);
291 for (j
= 0; j
< handle
->realminfos
[i
].nkdcaddresses
; j
++)
292 fprintf (fh
, " %s (%s)", handle
->realminfos
[i
].kdcaddresses
[j
].name
,
293 inet_ntoa (((struct sockaddr_in
*) &handle
->realminfos
[i
].
294 kdcaddresses
[j
].sockaddress
)->sin_addr
));
302 * shishi_cfg_default_systemfile:
303 * @handle: Shishi library handle create by shishi_init().
305 * Return value: Return system configuration filename.
308 shishi_cfg_default_systemfile (Shishi
* handle
)
310 return SYSTEMCFGFILE
;
314 * shishi_cfg_default_userfile:
315 * @handle: Shishi library handle create by shishi_init().
317 * Return value: Return user configuration filename.
320 shishi_cfg_default_userfile (Shishi
* handle
)
324 if (!handle
->usercfgfile
)
326 home
= getenv ("HOME");
331 asprintf (&handle
->usercfgfile
, "%s%s", home
, USERCFG_FILE
);
334 return handle
->usercfgfile
;
338 * shishi_cfg_clientkdcetype:
339 * @handle: Shishi library handle create by shishi_init().
340 * @etypes: output array with encryption types.
342 * Set the etypes variable to the array of preferred client etypes.
344 * Return value: Return the number of encryption types in the array,
348 shishi_cfg_clientkdcetype (Shishi
* handle
, int **etypes
)
350 *etypes
= handle
->clientkdcetypes
;
351 return handle
->nclientkdcetypes
;
355 * shishi_cfg_clientkdcetype_set:
356 * @handle: Shishi library handle create by shishi_init().
357 * @value: string with encryption types.
359 * Set the "client-kdc-etypes" configuration option from given string.
360 * The string contains encryption types (integer or names) separated
361 * by comma or whitespace, e.g. "aes256-cts-hmac-sha1-96
362 * des3-cbc-sha1-kd des-cbc-md5".
364 * Return value: Return SHISHI_OK iff successful.
367 shishi_cfg_clientkdcetype_set (Shishi
* handle
, char *value
)
374 if (value
== NULL
|| *value
== '\0')
377 for (i
= 0; (val
= strtok_r (i
== 0 ? value
: NULL
, ", \t", &ptrptr
)); i
++)
379 int etype
= shishi_cipher_parse (val
);
382 shishi_warn (handle
, "Ignoring unknown encryption type: `%s'\n", val
);
388 new = realloc (handle
->clientkdcetypes
,
389 tot
* sizeof (*handle
->clientkdcetypes
));
390 if (handle
->clientkdcetypes
== NULL
)
391 return SHISHI_MALLOC_ERROR
;
392 handle
->clientkdcetypes
= new;
393 handle
->clientkdcetypes
[tot
- 1] = etype
;
394 handle
->nclientkdcetypes
= tot
;