Add.
[shishi.git] / lib / init.c
blob7b9c43647b61cc573be07e230f0aa9668e71711a
1 /* init.c --- Initialization functions.
2 * Copyright (C) 2002, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "internal.h"
24 /* Get _shishi_tls_init. */
25 #include "starttls.h"
27 /* Get _shishi_crypto_init. */
28 #include "crypto.h"
30 /* Get _shishi_asn1_init. */
31 #include "asn1.h"
33 static Shishi *
34 init_handle (int outputtype)
36 Shishi *handle;
37 int rc;
39 handle = xcalloc (1, sizeof (*handle));
41 shishi_error_set_outputtype (handle, outputtype);
43 if (!shishi_check_version (SHISHI_VERSION))
45 shishi_warn (handle, "Library and header version missmatch (%s vs %s).",
46 shishi_check_version (NULL), SHISHI_VERSION);
47 free (handle);
48 return NULL;
51 rc = _shishi_crypto_init (handle);
52 if (rc != SHISHI_OK)
54 shishi_warn (handle, "Cannot initialize crypto library");
55 free (handle);
56 return NULL;
59 #ifdef USE_STARTTLS
60 rc = _shishi_tls_init (handle);
61 if (rc != SHISHI_OK)
63 shishi_warn (handle, "Cannot initialize TLS library");
64 free (handle);
65 return NULL;
67 #endif
69 rc = _shishi_asn1_init (handle);
70 if (rc != SHISHI_OK)
72 shishi_warn (handle, "%s", shishi_strerror (SHISHI_ASN1_ERROR));
73 free (handle);
74 return NULL;
77 bindtextdomain (PACKAGE, LOCALEDIR);
78 textdomain (PACKAGE);
80 handle->kdctimeout = 5;
81 handle->kdcretries = 3;
83 handle->ticketlife = TICKETLIFE;
84 handle->renewlife = RENEWLIFE;
86 handle->nclientkdcetypes = 1;
87 handle->clientkdcetypes = xmalloc (sizeof (*handle->clientkdcetypes) *
88 handle->nclientkdcetypes);
89 handle->clientkdcetypes[0] = SHISHI_AES256_CTS_HMAC_SHA1_96;
91 handle->nauthorizationtypes = 1;
92 handle->authorizationtypes = xmalloc (sizeof (*handle->authorizationtypes) *
93 handle->nauthorizationtypes);
94 handle->authorizationtypes[0] = SHISHI_AUTHORIZATION_BASIC;
96 return handle;
99 /**
100 * shishi:
102 * Initializes the Shishi library, and set up, using
103 * shishi_error_set_outputtype(), the library so that future warnings
104 * and informational messages are printed to stderr. If this function
105 * fails, it may print diagnostic errors to stderr.
107 * Return value: Returns Shishi library handle, or %NULL on error.
109 Shishi *
110 shishi (void)
112 return init_handle (SHISHI_OUTPUTTYPE_STDERR);
116 * shishi_server:
118 * Initializes the Shishi library, and set up, using
119 * shishi_error_set_outputtype(), the library so that future warnings
120 * and informational messages are printed to the syslog. If this
121 * function fails, it may print diagnostic errors to the syslog.
123 * Return value: Returns Shishi library handle, or %NULL on error.
125 Shishi *
126 shishi_server (void)
128 return init_handle (SHISHI_OUTPUTTYPE_SYSLOG);
132 * shishi_done:
133 * @handle: shishi handle as allocated by shishi_init().
135 * Deallocates the shishi library handle. The handle must not be used
136 * in any calls to shishi functions after this.
138 * If there is a default tkts, it is written to the default tkts file
139 * (call shishi_tkts_default_file_set() to change the default tkts
140 * file). If you do not wish to write the default tkts file, close the
141 * default tkts with shishi_tkts_done(handle, NULL) before calling
142 * this function.
144 void
145 shishi_done (Shishi * handle)
147 int rc;
149 if (handle->tkts)
151 shishi_tkts_to_file (handle->tkts, shishi_tkts_default_file (handle));
152 shishi_tkts_done (&handle->tkts);
155 shishi_principal_default_set (handle, NULL);
156 shishi_tkts_default_file_set (handle, NULL);
158 #ifdef USE_STARTTLS
159 rc = _shishi_tls_done (handle);
160 if (rc != SHISHI_OK)
161 shishi_warn (handle, "Cannot deinitialize TLS library");
162 #endif
164 if (handle->realminfos)
166 size_t i;
168 for (i= 0; i < handle->nrealminfos; i++)
170 size_t j;
172 if (handle->realminfos[i].kdcaddresses)
173 free (handle->realminfos[i].kdcaddresses);
175 if (handle->realminfos[i].name)
176 free (handle->realminfos[i].name);
180 if (handle->default_realm)
181 free (handle->default_realm);
182 if (handle->usercfgfile)
183 free (handle->usercfgfile);
184 if (handle->hostkeysdefaultfile)
185 free (handle->hostkeysdefaultfile);
186 if (handle->clientkdcetypes)
187 free (handle->clientkdcetypes);
188 if (handle->authorizationtypes)
189 free (handle->authorizationtypes);
190 if (handle->stringprocess)
191 free (handle->stringprocess);
192 if (handle->userdirectory)
193 free (handle->userdirectory);
195 if (handle->asn1)
196 shishi_asn1_done (handle, handle->asn1);
198 free (handle);
201 static void
202 maybe_install_usercfg (Shishi * handle)
204 const char *usercfg = shishi_cfg_default_userfile (handle);
205 const char *userdir = shishi_cfg_default_userdirectory (handle);
206 struct stat buf;
207 FILE *fh;
208 FILE *src, *dst;
209 int rc;
210 int c;
212 /* Don't create anything if non-standard home is used. */
213 if (getenv ("SHISHI_HOME"))
214 return;
216 fh = fopen (usercfg, "r");
217 if (fh)
219 fclose (fh);
220 return;
223 rc = stat (userdir, &buf);
224 if (rc == -1 && errno == ENOENT)
226 rc = mkdir (userdir, S_IRUSR | S_IWUSR | S_IXUSR);
227 if (rc != 0)
228 shishi_info (handle, "mkdir %s: %s", userdir, strerror (errno));
230 else if (rc != 0)
231 shishi_info (handle, "stat %s: %s", userdir, strerror (errno));
233 src = fopen (SKELCFGFILE, "r");
234 if (!src)
236 shishi_info (handle, "open %s: %s", SKELCFGFILE, strerror (errno));
237 return;
240 dst = fopen (usercfg, "w");
241 if (!dst)
243 fclose (src);
244 shishi_info (handle, "open %s: %s", usercfg, strerror (errno));
245 return;
248 while ((c = getc (src)) != EOF)
249 putc (c, dst);
251 fclose (dst);
252 fclose (src);
254 shishi_info (handle, "created `%s'", usercfg);
257 static int
258 init_read (Shishi * handle,
259 const char *tktsfile,
260 const char *systemcfgfile, const char *usercfgfile)
262 int rc = SHISHI_OK;
264 /* XXX Is this the correct place for this? */
265 maybe_install_usercfg (handle);
267 if (!tktsfile)
268 tktsfile = shishi_tkts_default_file (handle);
270 if (!systemcfgfile)
271 systemcfgfile = shishi_cfg_default_systemfile (handle);
273 if (!usercfgfile)
274 usercfgfile = shishi_cfg_default_userfile (handle);
276 if (!handle->tkts)
277 rc = shishi_tkts (handle, &handle->tkts);
278 if (rc != SHISHI_OK)
279 return rc;
281 if (*tktsfile)
282 rc = shishi_tkts_from_file (handle->tkts, tktsfile);
283 if (rc == SHISHI_FOPEN_ERROR)
284 shishi_warn (handle, "%s: %s", tktsfile, strerror (errno));
285 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
286 return rc;
288 if (*systemcfgfile)
289 rc = shishi_cfg_from_file (handle, systemcfgfile);
290 if (rc == SHISHI_FOPEN_ERROR)
291 shishi_warn (handle, "%s: %s", systemcfgfile, strerror (errno));
292 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
293 return rc;
295 if (*usercfgfile)
296 rc = shishi_cfg_from_file (handle, usercfgfile);
297 if (rc == SHISHI_FOPEN_ERROR)
298 shishi_warn (handle, "%s: %s", usercfgfile, strerror (errno));
299 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
300 return rc;
302 if (VERBOSENOISE (handle))
303 shishi_cfg_print (handle, stderr);
305 return SHISHI_OK;
309 * shishi_init:
310 * @handle: pointer to handle to be created.
312 * Create a Shishi library handle, using shishi(), and read the system
313 * configuration file, user configuration file and user tickets from
314 * their default locations. The paths to the system configuration
315 * file is decided at compile time, and is $sysconfdir/shishi.conf.
316 * The user configuration file is $HOME/.shishi/config, and the user
317 * ticket file is $HOME/.shishi/ticket.
319 * The handle is allocated regardless of return values, except for
320 * SHISHI_HANDLE_ERROR which indicates a problem allocating the
321 * handle. (The other error conditions comes from reading the files.)
323 * Return value: Returns SHISHI_OK iff successful.
326 shishi_init (Shishi ** handle)
328 if (!handle || !(*handle = shishi ()))
329 return SHISHI_HANDLE_ERROR;
331 return init_read (*handle, shishi_tkts_default_file (*handle),
332 shishi_cfg_default_systemfile (*handle),
333 shishi_cfg_default_userfile (*handle));
337 * shishi_init_with_paths:
338 * @handle: pointer to handle to be created.
339 * @tktsfile: Filename of ticket file, or NULL.
340 * @systemcfgfile: Filename of system configuration, or NULL.
341 * @usercfgfile: Filename of user configuration, or NULL.
343 * Create a Shishi library handle, using shishi(), and read the system
344 * configuration file, user configuration file, and user tickets from
345 * the specified locations. If any of @usercfgfile or @systemcfgfile
346 * is NULL, the file is read from its default location, which for the
347 * system configuration file is decided at compile time, and is
348 * $sysconfdir/shishi.conf, and for the user configuration file is
349 * $HOME/.shishi/config. If the ticket file is NULL, a ticket file is
350 * not read at all.
352 * The handle is allocated regardless of return values, except for
353 * SHISHI_HANDLE_ERROR which indicates a problem allocating the
354 * handle. (The other error conditions comes from reading the files.)
356 * Return value: Returns SHISHI_OK iff successful.
359 shishi_init_with_paths (Shishi ** handle,
360 const char *tktsfile,
361 const char *systemcfgfile, const char *usercfgfile)
363 if (!handle || !(*handle = shishi ()))
364 return SHISHI_HANDLE_ERROR;
366 shishi_tkts_default_file_set (*handle, tktsfile);
368 return init_read (*handle, tktsfile, systemcfgfile, usercfgfile);
372 * shishi_init_server:
373 * @handle: pointer to handle to be created.
375 * Create a Shishi library handle, using shishi_server(), and read the
376 * system configuration file. The paths to the system configuration
377 * file is decided at compile time, and is $sysconfdir/shishi.conf.
379 * The handle is allocated regardless of return values, except for
380 * SHISHI_HANDLE_ERROR which indicates a problem allocating the
381 * handle. (The other error conditions comes from reading the file.)
383 * Return value: Returns SHISHI_OK iff successful.
386 shishi_init_server (Shishi ** handle)
388 int rc;
390 if (!handle || !(*handle = shishi_server ()))
391 return SHISHI_HANDLE_ERROR;
393 rc = shishi_cfg_from_file (*handle,
394 shishi_cfg_default_systemfile (*handle));
395 if (rc == SHISHI_FOPEN_ERROR)
396 shishi_warn (*handle, "%s: %s", shishi_cfg_default_systemfile (*handle),
397 strerror (errno));
398 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
399 return rc;
401 return SHISHI_OK;
405 * shishi_init_server_with_paths:
406 * @handle: pointer to handle to be created.
407 * @systemcfgfile: Filename of system configuration, or NULL.
409 * Create a Shishi library handle, using shishi_server(), and read the
410 * system configuration file from specified location. The paths to
411 * the system configuration file is decided at compile time, and is
412 * $sysconfdir/shishi.conf. The handle is allocated regardless of
413 * return values, except for SHISHI_HANDLE_ERROR which indicates a
414 * problem allocating the handle. (The other error conditions comes
415 * from reading the file.)
417 * Return value: Returns SHISHI_OK iff successful.
420 shishi_init_server_with_paths (Shishi ** handle, const char *systemcfgfile)
422 int rc;
424 if (!handle || !(*handle = shishi_server ()))
425 return SHISHI_HANDLE_ERROR;
427 if (!systemcfgfile)
428 systemcfgfile = shishi_cfg_default_systemfile (*handle);
430 rc = shishi_cfg_from_file (*handle, systemcfgfile);
431 if (rc == SHISHI_FOPEN_ERROR)
432 shishi_warn (*handle, "%s: %s", systemcfgfile, strerror (errno));
433 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
434 return rc;
436 return SHISHI_OK;