Update gnulib files.
[shishi.git] / lib / init.c
blob24b564ed2343d438622cde363e5c81a72d3bdda4
1 /* init.c --- Initialization functions.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
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.
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.
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
23 #include "internal.h"
25 /* Get _shishi_tls_init. */
26 #include "starttls.h"
28 /* Get _shishi_crypto_init. */
29 #include "crypto.h"
31 /* Get _shishi_asn1_init. */
32 #include "asn1.h"
34 static Shishi *
35 init_handle (int outputtype)
37 Shishi *handle;
38 int rc;
40 handle = xcalloc (1, sizeof (*handle));
42 shishi_error_set_outputtype (handle, outputtype);
44 if (!shishi_check_version (SHISHI_VERSION))
46 shishi_warn (handle, "Library and header version missmatch (%s vs %s).",
47 shishi_check_version (NULL), SHISHI_VERSION);
48 free (handle);
49 return NULL;
52 rc = _shishi_crypto_init (handle);
53 if (rc != SHISHI_OK)
55 shishi_warn (handle, "Cannot initialize crypto library");
56 free (handle);
57 return NULL;
60 #ifdef USE_STARTTLS
61 rc = _shishi_tls_init (handle);
62 if (rc != SHISHI_OK)
64 shishi_warn (handle, "Cannot initialize TLS library");
65 free (handle);
66 return NULL;
68 #endif
70 rc = _shishi_asn1_init (handle);
71 if (rc != SHISHI_OK)
73 shishi_warn (handle, "%s", shishi_strerror (SHISHI_ASN1_ERROR));
74 free (handle);
75 return NULL;
78 bindtextdomain (PACKAGE, LOCALEDIR);
79 textdomain (PACKAGE);
81 handle->kdctimeout = 5;
82 handle->kdcretries = 3;
84 handle->ticketlife = TICKETLIFE;
85 handle->renewlife = RENEWLIFE;
87 handle->nclientkdcetypes = 1;
88 handle->clientkdcetypes = xmalloc (sizeof (*handle->clientkdcetypes) *
89 handle->nclientkdcetypes);
90 handle->clientkdcetypes[0] = SHISHI_AES256_CTS_HMAC_SHA1_96;
92 handle->nauthorizationtypes = 1;
93 handle->authorizationtypes = xmalloc (sizeof (*handle->authorizationtypes) *
94 handle->nauthorizationtypes);
95 handle->authorizationtypes[0] = SHISHI_AUTHORIZATION_BASIC;
97 return handle;
101 * shishi:
103 * Initializes the Shishi library, and set up, using
104 * shishi_error_set_outputtype(), the library so that future warnings
105 * and informational messages are printed to stderr. If this function
106 * fails, it may print diagnostic errors to stderr.
108 * Return value: Returns Shishi library handle, or %NULL on error.
110 Shishi *
111 shishi (void)
113 return init_handle (SHISHI_OUTPUTTYPE_STDERR);
117 * shishi_server:
119 * Initializes the Shishi library, and set up, using
120 * shishi_error_set_outputtype(), the library so that future warnings
121 * and informational messages are printed to the syslog. If this
122 * function fails, it may print diagnostic errors to the syslog.
124 * Return value: Returns Shishi library handle, or %NULL on error.
126 Shishi *
127 shishi_server (void)
129 return init_handle (SHISHI_OUTPUTTYPE_SYSLOG);
133 * shishi_done:
134 * @handle: shishi handle as allocated by shishi_init().
136 * Deallocates the shishi library handle. The handle must not be used
137 * in any calls to shishi functions after this.
139 * If there is a default tkts, it is written to the default tkts file
140 * (call shishi_tkts_default_file_set() to change the default tkts
141 * file). If you do not wish to write the default tkts file, close the
142 * default tkts with shishi_tkts_done(handle, NULL) before calling
143 * this function.
145 void
146 shishi_done (Shishi * handle)
148 int rc;
150 if (handle->tkts)
152 shishi_tkts_to_file (handle->tkts, shishi_tkts_default_file (handle));
153 shishi_tkts_done (&handle->tkts);
156 shishi_principal_default_set (handle, NULL);
157 shishi_tkts_default_file_set (handle, NULL);
159 #ifdef USE_STARTTLS
160 rc = _shishi_tls_done (handle);
161 if (rc != SHISHI_OK)
162 shishi_warn (handle, "Cannot deinitialize TLS library");
163 #endif
165 if (handle->realminfos)
167 size_t i;
169 for (i= 0; i < handle->nrealminfos; i++)
171 size_t j;
173 if (handle->realminfos[i].kdcaddresses)
174 free (handle->realminfos[i].kdcaddresses);
176 if (handle->realminfos[i].name)
177 free (handle->realminfos[i].name);
181 if (handle->default_realm)
182 free (handle->default_realm);
183 if (handle->usercfgfile)
184 free (handle->usercfgfile);
185 if (handle->hostkeysdefaultfile)
186 free (handle->hostkeysdefaultfile);
187 if (handle->clientkdcetypes)
188 free (handle->clientkdcetypes);
189 if (handle->authorizationtypes)
190 free (handle->authorizationtypes);
191 if (handle->stringprocess)
192 free (handle->stringprocess);
193 if (handle->userdirectory)
194 free (handle->userdirectory);
196 if (handle->asn1)
197 shishi_asn1_done (handle, handle->asn1);
199 free (handle);
202 static void
203 maybe_install_usercfg (Shishi * handle)
205 const char *usercfg = shishi_cfg_default_userfile (handle);
206 const char *userdir = shishi_cfg_default_userdirectory (handle);
207 struct stat buf;
208 FILE *fh;
209 FILE *src, *dst;
210 int rc;
211 int c;
213 /* Don't create anything if non-standard home is used. */
214 if (getenv ("SHISHI_HOME"))
215 return;
217 fh = fopen (usercfg, "r");
218 if (fh)
220 fclose (fh);
221 return;
224 rc = stat (userdir, &buf);
225 if (rc == -1 && errno == ENOENT)
227 rc = mkdir (userdir, S_IRUSR | S_IWUSR | S_IXUSR);
228 if (rc != 0)
229 shishi_info (handle, "mkdir %s: %s", userdir, strerror (errno));
231 else if (rc != 0)
232 shishi_info (handle, "stat %s: %s", userdir, strerror (errno));
234 src = fopen (SKELCFGFILE, "r");
235 if (!src)
237 shishi_info (handle, "open %s: %s", SKELCFGFILE, strerror (errno));
238 return;
241 dst = fopen (usercfg, "w");
242 if (!dst)
244 fclose (src);
245 shishi_info (handle, "open %s: %s", usercfg, strerror (errno));
246 return;
249 while ((c = getc (src)) != EOF)
250 putc (c, dst);
252 fclose (dst);
253 fclose (src);
255 shishi_info (handle, "created `%s'", usercfg);
258 static int
259 init_read (Shishi * handle,
260 const char *tktsfile,
261 const char *systemcfgfile, const char *usercfgfile)
263 int rc = SHISHI_OK;
265 /* XXX Is this the correct place for this? */
266 maybe_install_usercfg (handle);
268 if (!systemcfgfile)
269 systemcfgfile = shishi_cfg_default_systemfile (handle);
271 if (*systemcfgfile)
272 rc = shishi_cfg_from_file (handle, systemcfgfile);
273 if (rc == SHISHI_FOPEN_ERROR)
274 shishi_warn (handle, "%s: %s", systemcfgfile, strerror (errno));
275 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
276 return rc;
278 if (!usercfgfile)
279 usercfgfile = shishi_cfg_default_userfile (handle);
281 if (*usercfgfile)
282 rc = shishi_cfg_from_file (handle, usercfgfile);
283 if (rc == SHISHI_FOPEN_ERROR)
284 shishi_warn (handle, "%s: %s", usercfgfile, strerror (errno));
285 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
286 return rc;
288 if (!tktsfile)
289 tktsfile = shishi_tkts_default_file (handle);
291 if (!handle->tkts)
292 rc = shishi_tkts (handle, &handle->tkts);
293 if (rc != SHISHI_OK)
294 return rc;
296 if (*tktsfile)
297 rc = shishi_tkts_from_file (handle->tkts, tktsfile);
298 if (rc == SHISHI_FOPEN_ERROR)
299 shishi_verbose (handle, "%s: %s", tktsfile, strerror (errno));
300 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
301 return rc;
303 if (VERBOSENOISE (handle))
304 shishi_cfg_print (handle, stderr);
306 return SHISHI_OK;
310 * shishi_init:
311 * @handle: pointer to handle to be created.
313 * Create a Shishi library handle, using shishi(), and read the system
314 * configuration file, user configuration file and user tickets from
315 * their default locations. The paths to the system configuration
316 * file is decided at compile time, and is $sysconfdir/shishi.conf.
317 * The user configuration file is $HOME/.shishi/config, and the user
318 * ticket file is $HOME/.shishi/ticket.
320 * The handle is allocated regardless of return values, except for
321 * SHISHI_HANDLE_ERROR which indicates a problem allocating the
322 * handle. (The other error conditions comes from reading the files.)
324 * Return value: Returns SHISHI_OK iff successful.
327 shishi_init (Shishi ** handle)
329 if (!handle || !(*handle = shishi ()))
330 return SHISHI_HANDLE_ERROR;
332 return init_read (*handle, shishi_tkts_default_file (*handle),
333 shishi_cfg_default_systemfile (*handle),
334 shishi_cfg_default_userfile (*handle));
338 * shishi_init_with_paths:
339 * @handle: pointer to handle to be created.
340 * @tktsfile: Filename of ticket file, or NULL.
341 * @systemcfgfile: Filename of system configuration, or NULL.
342 * @usercfgfile: Filename of user configuration, or NULL.
344 * Create a Shishi library handle, using shishi(), and read the system
345 * configuration file, user configuration file, and user tickets from
346 * the specified locations. If any of @usercfgfile or @systemcfgfile
347 * is NULL, the file is read from its default location, which for the
348 * system configuration file is decided at compile time, and is
349 * $sysconfdir/shishi.conf, and for the user configuration file is
350 * $HOME/.shishi/config. If the ticket file is NULL, a ticket file is
351 * not read at all.
353 * The handle is allocated regardless of return values, except for
354 * SHISHI_HANDLE_ERROR which indicates a problem allocating the
355 * handle. (The other error conditions comes from reading the files.)
357 * Return value: Returns SHISHI_OK iff successful.
360 shishi_init_with_paths (Shishi ** handle,
361 const char *tktsfile,
362 const char *systemcfgfile, const char *usercfgfile)
364 if (!handle || !(*handle = shishi ()))
365 return SHISHI_HANDLE_ERROR;
367 shishi_tkts_default_file_set (*handle, tktsfile);
369 return init_read (*handle, tktsfile, systemcfgfile, usercfgfile);
373 * shishi_init_server:
374 * @handle: pointer to handle to be created.
376 * Create a Shishi library handle, using shishi_server(), and read the
377 * system configuration file. The paths to the system configuration
378 * file is decided at compile time, and is $sysconfdir/shishi.conf.
380 * The handle is allocated regardless of return values, except for
381 * SHISHI_HANDLE_ERROR which indicates a problem allocating the
382 * handle. (The other error conditions comes from reading the file.)
384 * Return value: Returns SHISHI_OK iff successful.
387 shishi_init_server (Shishi ** handle)
389 int rc;
391 if (!handle || !(*handle = shishi_server ()))
392 return SHISHI_HANDLE_ERROR;
394 rc = shishi_cfg_from_file (*handle,
395 shishi_cfg_default_systemfile (*handle));
396 if (rc == SHISHI_FOPEN_ERROR)
397 shishi_warn (*handle, "%s: %s", shishi_cfg_default_systemfile (*handle),
398 strerror (errno));
399 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
400 return rc;
402 return SHISHI_OK;
406 * shishi_init_server_with_paths:
407 * @handle: pointer to handle to be created.
408 * @systemcfgfile: Filename of system configuration, or NULL.
410 * Create a Shishi library handle, using shishi_server(), and read the
411 * system configuration file from specified location. The paths to
412 * the system configuration file is decided at compile time, and is
413 * $sysconfdir/shishi.conf. The handle is allocated regardless of
414 * return values, except for SHISHI_HANDLE_ERROR which indicates a
415 * problem allocating the handle. (The other error conditions comes
416 * from reading the file.)
418 * Return value: Returns SHISHI_OK iff successful.
421 shishi_init_server_with_paths (Shishi ** handle, const char *systemcfgfile)
423 int rc;
425 if (!handle || !(*handle = shishi_server ()))
426 return SHISHI_HANDLE_ERROR;
428 if (!systemcfgfile)
429 systemcfgfile = shishi_cfg_default_systemfile (*handle);
431 rc = shishi_cfg_from_file (*handle, systemcfgfile);
432 if (rc == SHISHI_FOPEN_ERROR)
433 shishi_warn (*handle, "%s: %s", systemcfgfile, strerror (errno));
434 if (rc != SHISHI_OK && rc != SHISHI_FOPEN_ERROR)
435 return rc;
437 return SHISHI_OK;