Update gnulib files.
[shishi.git] / lib / keys.c
bloba946cfaf2747ce464dc5a835a5c90a495bc3a276
1 /* keys.c --- Functions for managing keys sets, and keys stored in files.
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 struct Shishi_keys
27 Shishi *handle;
28 Shishi_key **keys;
29 int nkeys;
32 /**
33 * shishi_keys:
34 * @handle: shishi handle as allocated by shishi_init().
35 * @keys: output pointer to newly allocated keys handle.
37 * Get a new key set handle.
39 * Return value: Returns %SHISHI_OK iff successful.
40 **/
41 int
42 shishi_keys (Shishi * handle, Shishi_keys ** keys)
44 *keys = xmalloc (sizeof (**keys));
46 (*keys)->handle = handle;
47 (*keys)->keys = NULL;
48 (*keys)->nkeys = 0;
50 return SHISHI_OK;
53 /**
54 * shishi_keys_done:
55 * @keys: key set handle as allocated by shishi_keys().
57 * Deallocates all resources associated with key set. The key set
58 * handle must not be used in calls to other shishi_keys_*() functions
59 * after this.
60 **/
61 void
62 shishi_keys_done (Shishi_keys ** keys)
64 size_t i;
66 if (!keys || !*keys)
67 return;
69 if ((*keys)->nkeys > 0)
70 for (i = (*keys)->nkeys; i > 0; i--)
71 shishi_key_done ((*keys)->keys[i - 1]);
73 if ((*keys)->keys)
74 free ((*keys)->keys);
76 free (*keys);
78 *keys = NULL;
80 return;
83 /**
84 * shishi_keys_size:
85 * @keys: key set handle as allocated by shishi_keys().
87 * Get size of key set.
89 * Return value: Returns number of keys stored in key set.
90 **/
91 int
92 shishi_keys_size (Shishi_keys * keys)
94 return keys->nkeys;
97 /**
98 * shishi_keys_nth:
99 * @keys: key set handle as allocated by shishi_keys().
100 * @keyno: integer indicating requested key in key set.
102 * Get the n:th ticket in key set.
104 * Return value: Returns a key handle to the keyno:th key in the key
105 * set, or NULL if @keys is invalid or @keyno is out of bounds. The
106 * first key is @keyno 0, the second key @keyno 1, and so on.
108 const Shishi_key *
109 shishi_keys_nth (Shishi_keys * keys, int keyno)
111 if (keys == NULL || keyno >= keys->nkeys)
112 return NULL;
114 return keys->keys[keyno];
118 * shishi_keys_remove:
119 * @keys: key set handle as allocated by shishi_keys().
120 * @keyno: key number of key in the set to remove. The first
121 * key is key number 0.
123 * Remove a key, indexed by @keyno, in given key set.
125 void
126 shishi_keys_remove (Shishi_keys * keys, int keyno)
128 shishi_key_done (keys->keys[keyno]);
130 if (keyno < keys->nkeys)
131 memmove (&keys->keys[keyno], &keys->keys[keyno + 1],
132 sizeof (*keys->keys) * (keys->nkeys - keyno - 1));
134 --keys->nkeys;
136 keys->keys = xrealloc (keys->keys, sizeof (*keys->keys) * keys->nkeys);
140 * shishi_keys_add:
141 * @keys: key set handle as allocated by shishi_keys().
142 * @key: key to be added to key set.
144 * Add a key to the key set. A deep copy of the key is stored, so
145 * changing @key, or deallocating it, will not modify the value stored
146 * in the key set.
148 * Return value: Returns SHISHI_OK iff succesful.
151 shishi_keys_add (Shishi_keys * keys, Shishi_key * key)
153 int rc;
155 if (!key)
156 return SHISHI_INVALID_KEY;
158 keys->nkeys++;
160 keys->keys = xrealloc (keys->keys, sizeof (*keys->keys) * keys->nkeys);
162 rc = shishi_key (keys->handle, &(keys->keys[keys->nkeys - 1]));
163 if (rc != SHISHI_OK)
164 return rc;
166 shishi_key_copy (keys->keys[keys->nkeys - 1], key);
168 return SHISHI_OK;
172 * shishi_keys_print:
173 * @keys: key set to print.
174 * @fh: file handle, open for writing, to print keys to.
176 * Print all keys in set using shishi_key_print.
178 * Returns: Returns %SHISHI_OK on success.
181 shishi_keys_print (Shishi_keys * keys, FILE *fh)
183 int rc;
184 size_t i;
186 for (i = 0; i < keys->nkeys; i++)
188 rc = shishi_key_print (keys->handle, fh, shishi_keys_nth (keys, i));
189 if (rc != SHISHI_OK)
190 return rc;
192 fprintf (fh, "\n");
195 return SHISHI_OK;
199 * shishi_keys_to_file:
200 * @handle: shishi handle as allocated by shishi_init().
201 * @filename: filename to append key to.
202 * @keys: set of keys to print.
204 * Print an ASCII representation of a key structure to a file, for
205 * each key in the key set. The file is appended to if it exists.
206 * See shishi_key_print() for the format of the output.
208 * Return value: Returns %SHISHI_OK iff successful.
211 shishi_keys_to_file (Shishi * handle,
212 const char *filename,
213 Shishi_keys * keys)
215 FILE *fh;
216 int res;
218 if (VERBOSE (handle))
219 printf (_("Writing KEYS to %s...\n"), filename);
221 fh = fopen (filename, "a");
222 if (fh == NULL)
223 return SHISHI_FOPEN_ERROR;
225 res = shishi_keys_print (keys, fh);
226 if (res != SHISHI_OK)
227 return res;
229 res = fclose (fh);
230 if (res != 0)
231 return SHISHI_IO_ERROR;
233 if (VERBOSE (handle))
234 printf (_("Writing KEYS to %s...done\n"), filename);
236 return SHISHI_OK;
240 * shishi_keys_for_serverrealm_in_file
241 * @handle: Shishi library handle create by shishi_init().
242 * @filename: file to read keys from.
243 * @server: server name to get key for.
244 * @realm: realm of server to get key for.
246 * Get keys that match specified @server and @realm from the key set
247 * file @filename.
249 * Return value: Returns the key for specific server and realm, read
250 * from the indicated file, or NULL if no key could be found or an
251 * error encountered.
253 Shishi_key *
254 shishi_keys_for_serverrealm_in_file (Shishi * handle,
255 const char *filename,
256 const char *server, const char *realm)
258 Shishi_key *key = NULL;
259 FILE *fh;
260 int res;
262 fh = fopen (filename, "r");
263 if (fh == NULL)
264 return NULL;
266 res = SHISHI_OK;
267 while (!feof (fh))
269 res = shishi_key_parse (handle, fh, &key);
270 if (res != SHISHI_OK || key == NULL)
271 break;
273 if (VERBOSENOISE (handle))
275 printf ("Read key:\n");
276 shishi_key_print (handle, stdout, key);
279 if ((!server ||
280 (shishi_key_principal (key) &&
281 strcmp (server, shishi_key_principal (key)) == 0)) &&
282 (!realm ||
283 (shishi_key_realm (key) &&
284 strcmp (realm, shishi_key_realm (key)) == 0)))
285 break;
287 shishi_key_done (key);
288 key = NULL;
291 res = fclose (fh);
292 if (res != 0)
293 return NULL;
295 return key;
299 * shishi_keys_for_server_in_file
300 * @handle: Shishi library handle create by shishi_init().
301 * @filename: file to read keys from.
302 * @server: server name to get key for.
304 * Get key for specified @server from @filename.
306 * Return value: Returns the key for specific server, read from the
307 * indicated file, or NULL if no key could be found or an error
308 * encountered.
310 Shishi_key *
311 shishi_keys_for_server_in_file (Shishi * handle,
312 const char *filename, const char *server)
314 return shishi_keys_for_serverrealm_in_file (handle, filename, server, NULL);
318 * shishi_keys_for_localservicerealm_in_file:
319 * @handle: Shishi library handle create by shishi_init().
320 * @filename: file to read keys from.
321 * @service: service to get key for.
322 * @realm: realm of server to get key for, or NULL for default realm.
324 * Get key for specified @service and @realm from @filename.
326 * Return value: Returns the key for the server
327 * "SERVICE/HOSTNAME@REALM" (where HOSTNAME is the current system's
328 * hostname), read from the default host keys file (see
329 * shishi_hostkeys_default_file()), or NULL if no key could be found
330 * or an error encountered.
332 Shishi_key *
333 shishi_keys_for_localservicerealm_in_file (Shishi * handle,
334 const char *filename,
335 const char *service,
336 const char *realm)
338 char *hostname;
339 char *server;
340 Shishi_key *key;
342 hostname = xgethostname ();
344 asprintf (&server, "%s/%s", service, hostname);
346 key = shishi_keys_for_serverrealm_in_file (handle, filename, server, realm);
348 free (server);
349 free (hostname);
351 return key;