Branch data Line data Source code
1 : : /* init.c --- Initialization functions.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010 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 gl_sockets_startup. */
26 : : #include "sockets.h"
27 : :
28 : : /* Get _shishi_tls_init. */
29 : : #include "starttls.h"
30 : :
31 : : /* Get _shishi_crypto_init. */
32 : : #include "low-crypto.h"
33 : :
34 : : /* Get _shishi_asn1_init. */
35 : : #include "asn1.h"
36 : :
37 : : static Shishi *
38 : 14 : init_handle (int outputtype)
39 : : {
40 : : Shishi *handle;
41 : : int rc;
42 : :
43 : 14 : handle = xcalloc (1, sizeof (*handle));
44 : :
45 : 14 : shishi_error_set_outputtype (handle, outputtype);
46 : :
47 [ - + ]: 14 : if (!shishi_check_version (SHISHI_VERSION))
48 : : {
49 : 0 : shishi_warn (handle, "Library and header version missmatch (%s vs %s).",
50 : : shishi_check_version (NULL), SHISHI_VERSION);
51 : 0 : free (handle);
52 : 0 : return NULL;
53 : : }
54 : :
55 : 14 : rc = gl_sockets_startup (SOCKETS_2_1);
56 [ - + ]: 14 : if (rc)
57 : : {
58 : 0 : shishi_warn (handle, "Failed to initialized Windows sockets (%d)", rc);
59 : 0 : free (handle);
60 : 0 : return NULL;
61 : : }
62 : :
63 : 14 : rc = _shishi_crypto_init (handle);
64 [ - + ]: 14 : if (rc != SHISHI_OK)
65 : : {
66 : 0 : shishi_warn (handle, "Cannot initialize crypto library");
67 : 0 : free (handle);
68 : 0 : return NULL;
69 : : }
70 : :
71 : : #ifdef USE_STARTTLS
72 : 14 : rc = _shishi_tls_init (handle);
73 [ - + ]: 14 : if (rc != SHISHI_OK)
74 : : {
75 : 0 : shishi_warn (handle, "Cannot initialize TLS library");
76 : 0 : free (handle);
77 : 0 : return NULL;
78 : : }
79 : : #endif
80 : :
81 : 14 : rc = _shishi_asn1_init (handle);
82 [ - + ]: 14 : if (rc != SHISHI_OK)
83 : : {
84 : 0 : shishi_warn (handle, "%s", shishi_strerror (SHISHI_ASN1_ERROR));
85 : 0 : free (handle);
86 : 0 : return NULL;
87 : : }
88 : :
89 : 14 : bindtextdomain (PACKAGE, LOCALEDIR);
90 : 14 : textdomain (PACKAGE);
91 : :
92 : 14 : handle->kdctimeout = 5;
93 : 14 : handle->kdcretries = 3;
94 : :
95 : 14 : handle->ticketlife = TICKETLIFE;
96 : 14 : handle->renewlife = RENEWLIFE;
97 : :
98 : 14 : handle->nclientkdcetypes = 1;
99 : 14 : handle->clientkdcetypes = xmalloc (sizeof (*handle->clientkdcetypes) *
100 : : handle->nclientkdcetypes);
101 : 14 : handle->clientkdcetypes[0] = SHISHI_AES256_CTS_HMAC_SHA1_96;
102 : :
103 : 14 : handle->nauthorizationtypes = 1;
104 : 14 : handle->authorizationtypes = xmalloc (sizeof (*handle->authorizationtypes) *
105 : : handle->nauthorizationtypes);
106 : 14 : handle->authorizationtypes[0] = SHISHI_AUTHORIZATION_BASIC;
107 : :
108 : 14 : return handle;
109 : : }
110 : :
111 : : /**
112 : : * shishi:
113 : : *
114 : : * Initializes the Shishi library, and set up, using
115 : : * shishi_error_set_outputtype(), the library so that future warnings
116 : : * and informational messages are printed to stderr. If this function
117 : : * fails, it may print diagnostic errors to stderr.
118 : : *
119 : : * Return value: Returns Shishi library handle, or %NULL on error.
120 : : **/
121 : : Shishi *
122 : 14 : shishi (void)
123 : : {
124 : 14 : return init_handle (SHISHI_OUTPUTTYPE_STDERR);
125 : : }
126 : :
127 : : /**
128 : : * shishi_server:
129 : : *
130 : : * Initializes the Shishi library, and set up, using
131 : : * shishi_error_set_outputtype(), the library so that future warnings
132 : : * and informational messages are printed to the syslog. If this
133 : : * function fails, it may print diagnostic errors to the syslog.
134 : : *
135 : : * Return value: Returns Shishi library handle, or %NULL on error.
136 : : **/
137 : : Shishi *
138 : 0 : shishi_server (void)
139 : : {
140 : 0 : return init_handle (SHISHI_OUTPUTTYPE_SYSLOG);
141 : : }
142 : :
143 : : /**
144 : : * shishi_done:
145 : : * @handle: shishi handle as allocated by shishi_init().
146 : : *
147 : : * Deallocates the shishi library handle. The handle must not be used
148 : : * in any calls to shishi functions after this.
149 : : *
150 : : * If there is a default tkts, it is written to the default tkts file
151 : : * (call shishi_tkts_default_file_set() to change the default tkts
152 : : * file). If you do not wish to write the default tkts file, close the
153 : : * default tkts with shishi_tkts_done(handle, NULL) before calling
154 : : * this function.
155 : : **/
156 : : void
157 : 14 : shishi_done (Shishi * handle)
158 : : {
159 : : int rc;
160 : :
161 [ - + ]: 14 : if (handle->tkts)
162 : : {
163 : 0 : shishi_tkts_to_file (handle->tkts, shishi_tkts_default_file (handle));
164 : 0 : shishi_tkts_done (&handle->tkts);
165 : : }
166 : :
167 : 14 : shishi_principal_default_set (handle, NULL);
168 : 14 : shishi_tkts_default_file_set (handle, NULL);
169 : :
170 : : #ifdef USE_STARTTLS
171 : 14 : rc = _shishi_tls_done (handle);
172 [ - + ]: 14 : if (rc != SHISHI_OK)
173 : 0 : shishi_warn (handle, "Cannot deinitialize TLS library");
174 : : #endif
175 : :
176 [ - + ]: 14 : if (handle->realminfos)
177 : : {
178 : : size_t i;
179 : :
180 [ # # ]: 0 : for (i = 0; i < handle->nrealminfos; i++)
181 : : {
182 : : /* XXX free each address */
183 : :
184 : 0 : free (handle->realminfos[i].kdcaddresses);
185 : 0 : free (handle->realminfos[i].name);
186 : : }
187 : : }
188 : :
189 : 14 : free (handle->default_realm);
190 : 14 : free (handle->usercfgfile);
191 : 14 : free (handle->hostkeysdefaultfile);
192 : 14 : free (handle->clientkdcetypes);
193 : 14 : free (handle->authorizationtypes);
194 : 14 : free (handle->stringprocess);
195 : 14 : free (handle->userdirectory);
196 : :
197 [ + - ]: 14 : if (handle->asn1)
198 : 14 : shishi_asn1_done (handle, handle->asn1);
199 : :
200 : 14 : free (handle);
201 : 14 : }
202 : :
203 : : static void
204 : 0 : maybe_install_usercfg (Shishi * handle)
205 : : {
206 : 0 : const char *usercfg = shishi_cfg_default_userfile (handle);
207 : 0 : const char *userdir = shishi_cfg_default_userdirectory (handle);
208 : : struct stat buf;
209 : : FILE *fh;
210 : : FILE *src, *dst;
211 : : int rc;
212 : : int c;
213 : :
214 : : /* Don't create anything if non-standard home is used. */
215 [ # # ]: 0 : if (getenv ("SHISHI_HOME"))
216 : 0 : return;
217 : :
218 : 0 : fh = fopen (usercfg, "r");
219 [ # # ]: 0 : if (fh)
220 : : {
221 : 0 : fclose (fh);
222 : 0 : return;
223 : : }
224 : :
225 : 0 : rc = stat (userdir, &buf);
226 [ # # # # ]: 0 : if (rc == -1 && errno == ENOENT)
227 : : {
228 : 0 : rc = mkdir (userdir, S_IRUSR | S_IWUSR | S_IXUSR);
229 [ # # ]: 0 : if (rc != 0)
230 : 0 : shishi_warn (handle, "`%s': %s", userdir, strerror (errno));
231 : : }
232 [ # # ]: 0 : else if (rc != 0)
233 : 0 : shishi_warn (handle, "`%s': %s", userdir, strerror (errno));
234 : :
235 : 0 : src = fopen (SKELCFGFILE, "r");
236 [ # # ]: 0 : if (!src)
237 : : {
238 : 0 : shishi_warn (handle, "`%s': %s", SKELCFGFILE, strerror (errno));
239 : 0 : return;
240 : : }
241 : :
242 : 0 : dst = fopen (usercfg, "w");
243 [ # # ]: 0 : if (!dst)
244 : : {
245 : 0 : fclose (src);
246 : 0 : shishi_warn (handle, "`%s': %s", usercfg, strerror (errno));
247 : 0 : return;
248 : : }
249 : :
250 [ # # ]: 0 : while ((c = getc (src)) != EOF)
251 : 0 : putc (c, dst);
252 : :
253 : 0 : fclose (dst);
254 : 0 : fclose (src);
255 : :
256 : 0 : shishi_info (handle, "created `%s'", usercfg);
257 : : }
258 : :
259 : : static int
260 : 0 : init_read (Shishi * handle,
261 : : const char *tktsfile,
262 : : const char *systemcfgfile, const char *usercfgfile)
263 : : {
264 : 0 : int rc = SHISHI_OK;
265 : :
266 : : /* XXX Is this the correct place for this? */
267 : 0 : maybe_install_usercfg (handle);
268 : :
269 [ # # ]: 0 : if (!systemcfgfile)
270 : 0 : systemcfgfile = shishi_cfg_default_systemfile (handle);
271 : :
272 [ # # ]: 0 : if (*systemcfgfile)
273 : 0 : rc = shishi_cfg_from_file (handle, systemcfgfile);
274 [ # # ]: 0 : if (rc == SHISHI_FOPEN_ERROR)
275 : 0 : shishi_warn (handle, "%s: %s", systemcfgfile, strerror (errno));
276 [ # # ][ # # ]: 0 : if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
277 : 0 : return rc;
278 : :
279 [ # # ]: 0 : if (!usercfgfile)
280 : 0 : usercfgfile = shishi_cfg_default_userfile (handle);
281 : :
282 [ # # ]: 0 : if (*usercfgfile)
283 : 0 : rc = shishi_cfg_from_file (handle, usercfgfile);
284 [ # # ]: 0 : if (rc == SHISHI_FOPEN_ERROR)
285 : 0 : shishi_warn (handle, "%s: %s", usercfgfile, strerror (errno));
286 [ # # ][ # # ]: 0 : if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
287 : 0 : return rc;
288 : :
289 [ # # ]: 0 : if (!tktsfile)
290 : 0 : tktsfile = shishi_tkts_default_file (handle);
291 : :
292 [ # # ]: 0 : if (!handle->tkts)
293 : 0 : rc = shishi_tkts (handle, &handle->tkts);
294 [ # # ]: 0 : if (rc != SHISHI_OK)
295 : 0 : return rc;
296 : :
297 [ # # ]: 0 : if (*tktsfile)
298 : 0 : rc = shishi_tkts_from_file (handle->tkts, tktsfile);
299 [ # # ]: 0 : if (rc == SHISHI_FOPEN_ERROR)
300 : 0 : shishi_verbose (handle, "%s: %s", tktsfile, strerror (errno));
301 [ # # ][ # # ]: 0 : if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
302 : 0 : return rc;
303 : :
304 [ # # ]: 0 : if (VERBOSENOISE (handle))
305 : 0 : shishi_cfg_print (handle, stderr);
306 : :
307 : 0 : return SHISHI_OK;
308 : : }
309 : :
310 : : /**
311 : : * shishi_init:
312 : : * @handle: pointer to handle to be created.
313 : : *
314 : : * Create a Shishi library handle, using shishi(), and read the system
315 : : * configuration file, user configuration file and user tickets from
316 : : * their default locations. The paths to the system configuration
317 : : * file is decided at compile time, and is $sysconfdir/shishi.conf.
318 : : * The user configuration file is $HOME/.shishi/config, and the user
319 : : * ticket file is $HOME/.shishi/ticket.
320 : : *
321 : : * The handle is allocated regardless of return values, except for
322 : : * SHISHI_HANDLE_ERROR which indicates a problem allocating the
323 : : * handle. (The other error conditions comes from reading the files.)
324 : : *
325 : : * Return value: Returns SHISHI_OK iff successful.
326 : : **/
327 : : int
328 : 0 : shishi_init (Shishi ** handle)
329 : : {
330 [ # # ][ # # ]: 0 : if (!handle || !(*handle = shishi ()))
331 : 0 : return SHISHI_HANDLE_ERROR;
332 : :
333 : 0 : return init_read (*handle, shishi_tkts_default_file (*handle),
334 : : shishi_cfg_default_systemfile (*handle),
335 : : shishi_cfg_default_userfile (*handle));
336 : : }
337 : :
338 : : /**
339 : : * shishi_init_with_paths:
340 : : * @handle: pointer to handle to be created.
341 : : * @tktsfile: Filename of ticket file, or NULL.
342 : : * @systemcfgfile: Filename of system configuration, or NULL.
343 : : * @usercfgfile: Filename of user configuration, or NULL.
344 : : *
345 : : * Create a Shishi library handle, using shishi(), and read the system
346 : : * configuration file, user configuration file, and user tickets from
347 : : * the specified locations. If any of @usercfgfile or @systemcfgfile
348 : : * is NULL, the file is read from its default location, which for the
349 : : * system configuration file is decided at compile time, and is
350 : : * $sysconfdir/shishi.conf, and for the user configuration file is
351 : : * $HOME/.shishi/config. If the ticket file is NULL, a ticket file is
352 : : * not read at all.
353 : : *
354 : : * The handle is allocated regardless of return values, except for
355 : : * SHISHI_HANDLE_ERROR which indicates a problem allocating the
356 : : * handle. (The other error conditions comes from reading the files.)
357 : : *
358 : : * Return value: Returns SHISHI_OK iff successful.
359 : : **/
360 : : int
361 : 0 : shishi_init_with_paths (Shishi ** handle,
362 : : const char *tktsfile,
363 : : const char *systemcfgfile, const char *usercfgfile)
364 : : {
365 [ # # ][ # # ]: 0 : if (!handle || !(*handle = shishi ()))
366 : 0 : return SHISHI_HANDLE_ERROR;
367 : :
368 : 0 : shishi_tkts_default_file_set (*handle, tktsfile);
369 : :
370 : 0 : return init_read (*handle, tktsfile, systemcfgfile, usercfgfile);
371 : : }
372 : :
373 : : /**
374 : : * shishi_init_server:
375 : : * @handle: pointer to handle to be created.
376 : : *
377 : : * Create a Shishi library handle, using shishi_server(), and read the
378 : : * system configuration file. The paths to the system configuration
379 : : * file is decided at compile time, and is $sysconfdir/shishi.conf.
380 : : *
381 : : * The handle is allocated regardless of return values, except for
382 : : * SHISHI_HANDLE_ERROR which indicates a problem allocating the
383 : : * handle. (The other error conditions comes from reading the file.)
384 : : *
385 : : * Return value: Returns SHISHI_OK iff successful.
386 : : **/
387 : : int
388 : 0 : shishi_init_server (Shishi ** handle)
389 : : {
390 : : int rc;
391 : :
392 [ # # ][ # # ]: 0 : if (!handle || !(*handle = shishi_server ()))
393 : 0 : return SHISHI_HANDLE_ERROR;
394 : :
395 : 0 : rc = shishi_cfg_from_file (*handle,
396 : : shishi_cfg_default_systemfile (*handle));
397 [ # # ]: 0 : if (rc == SHISHI_FOPEN_ERROR)
398 : 0 : shishi_warn (*handle, "%s: %s", shishi_cfg_default_systemfile (*handle),
399 : : strerror (errno));
400 [ # # ][ # # ]: 0 : if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
401 : 0 : return rc;
402 : :
403 : 0 : return SHISHI_OK;
404 : : }
405 : :
406 : : /**
407 : : * shishi_init_server_with_paths:
408 : : * @handle: pointer to handle to be created.
409 : : * @systemcfgfile: Filename of system configuration, or NULL.
410 : : *
411 : : * Create a Shishi library handle, using shishi_server(), and read the
412 : : * system configuration file from specified location. The paths to
413 : : * the system configuration file is decided at compile time, and is
414 : : * $sysconfdir/shishi.conf. The handle is allocated regardless of
415 : : * return values, except for SHISHI_HANDLE_ERROR which indicates a
416 : : * problem allocating the handle. (The other error conditions comes
417 : : * from reading the file.)
418 : : *
419 : : * Return value: Returns SHISHI_OK iff successful.
420 : : **/
421 : : int
422 : 0 : shishi_init_server_with_paths (Shishi ** handle, const char *systemcfgfile)
423 : : {
424 : : int rc;
425 : :
426 [ # # ][ # # ]: 0 : if (!handle || !(*handle = shishi_server ()))
427 : 0 : return SHISHI_HANDLE_ERROR;
428 : :
429 [ # # ]: 0 : if (!systemcfgfile)
430 : 0 : systemcfgfile = shishi_cfg_default_systemfile (*handle);
431 : :
432 : 0 : rc = shishi_cfg_from_file (*handle, systemcfgfile);
433 [ # # ]: 0 : if (rc == SHISHI_FOPEN_ERROR)
434 : 0 : shishi_warn (*handle, "%s: %s", systemcfgfile, strerror (errno));
435 [ # # ][ # # ]: 0 : if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
436 : 0 : return rc;
437 : :
438 : 0 : return SHISHI_OK;
439 : : }
|