Add old stuff.
[shishi.git] / lib / keys.c
blob96a6c5ecd60e632f0b104943fc00e0113a614621
1 /* keys.c --- Functions for managing keys sets, and keys stored in files.
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 struct Shishi_keys
26 Shishi *handle;
27 Shishi_key **keys;
28 int nkeys;
31 /**
32 * shishi_keys:
33 * @handle: shishi handle as allocated by shishi_init().
34 * @keys: output pointer to newly allocated keys handle.
36 * Get a new key set handle.
38 * Return value: Returns %SHISHI_OK iff successful.
39 **/
40 int
41 shishi_keys (Shishi * handle, Shishi_keys ** keys)
43 *keys = xmalloc (sizeof (**keys));
45 (*keys)->handle = handle;
46 (*keys)->keys = NULL;
47 (*keys)->nkeys = 0;
49 return SHISHI_OK;
52 /**
53 * shishi_keys_done:
54 * @keys: key set handle as allocated by shishi_keys().
56 * Deallocates all resources associated with key set. The key set
57 * handle must not be used in calls to other shishi_keys_*() functions
58 * after this.
59 **/
60 void
61 shishi_keys_done (Shishi_keys ** keys)
63 size_t i;
65 if (!keys || !*keys)
66 return;
68 if ((*keys)->nkeys > 0)
69 for (i = (*keys)->nkeys; i > 0; i--)
70 shishi_key_done ((*keys)->keys[i - 1]);
72 if ((*keys)->keys)
73 free ((*keys)->keys);
75 free (*keys);
77 *keys = NULL;
79 return;
82 /**
83 * shishi_keys_size:
84 * @keys: key set handle as allocated by shishi_keys().
86 * Get size of key set.
88 * Return value: Returns number of keys stored in key set.
89 **/
90 int
91 shishi_keys_size (Shishi_keys * keys)
93 return keys->nkeys;
96 /**
97 * shishi_keys_nth:
98 * @keys: key set handle as allocated by shishi_keys().
99 * @keyno: integer indicating requested key in key set.
101 * Get the n:th ticket in key set.
103 * Return value: Returns a key handle to the keyno:th key in the key
104 * set, or NULL if @keys is invalid or @keyno is out of bounds. The
105 * first key is @keyno 0, the second key @keyno 1, and so on.
107 const Shishi_key *
108 shishi_keys_nth (Shishi_keys * keys, int keyno)
110 if (keys == NULL || keyno >= keys->nkeys)
111 return NULL;
113 return keys->keys[keyno];
117 * shishi_keys_remove:
118 * @keys: key set handle as allocated by shishi_keys().
119 * @keyno: key number of key in the set to remove. The first
120 * key is key number 0.
122 * Remove a key, indexed by @keyno, in given key set.
124 void
125 shishi_keys_remove (Shishi_keys * keys, int keyno)
127 shishi_key_done (keys->keys[keyno]);
129 if (keyno < keys->nkeys)
130 memmove (&keys->keys[keyno], &keys->keys[keyno + 1],
131 sizeof (*keys->keys) * (keys->nkeys - keyno - 1));
133 --keys->nkeys;
135 keys->keys = xrealloc (keys->keys, sizeof (*keys->keys) * keys->nkeys);
139 * shishi_keys_add:
140 * @keys: key set handle as allocated by shishi_keys().
141 * @key: key to be added to key set.
143 * Add a key to the key set. A deep copy of the key is stored, so
144 * changing @key, or deallocating it, will not modify the value stored
145 * in the key set.
147 * Return value: Returns SHISHI_OK iff succesful.
150 shishi_keys_add (Shishi_keys * keys, Shishi_key * key)
152 int rc;
154 if (!key)
155 return SHISHI_INVALID_KEY;
157 keys->nkeys++;
159 keys->keys = xrealloc (keys->keys, sizeof (*keys->keys) * keys->nkeys);
161 rc = shishi_key (keys->handle, &(keys->keys[keys->nkeys - 1]));
162 if (rc != SHISHI_OK)
163 return rc;
165 shishi_key_copy (keys->keys[keys->nkeys - 1], key);
167 return SHISHI_OK;
171 * shishi_keys_print:
172 * @keys: key set to print.
173 * @fh: file handle, open for writing, to print keys to.
175 * Print all keys in set using shishi_key_print.
177 * Returns: Returns %SHISHI_OK on success.
180 shishi_keys_print (Shishi_keys * keys, FILE *fh)
182 int rc;
183 size_t i;
185 for (i = 0; i < keys->nkeys; i++)
187 rc = shishi_key_print (keys->handle, fh, shishi_keys_nth (keys, i));
188 if (rc != SHISHI_OK)
189 return rc;
191 fprintf (fh, "\n");
194 return SHISHI_OK;
198 * shishi_keys_to_file:
199 * @handle: shishi handle as allocated by shishi_init().
200 * @filename: filename to append key to.
201 * @keys: set of keys to print.
203 * Print an ASCII representation of a key structure to a file, for
204 * each key in the key set. The file is appended to if it exists.
205 * See shishi_key_print() for the format of the output.
207 * Return value: Returns %SHISHI_OK iff successful.
210 shishi_keys_to_file (Shishi * handle,
211 const char *filename,
212 Shishi_keys * keys)
214 FILE *fh;
215 int res;
217 if (VERBOSE (handle))
218 printf (_("Writing KEYS to %s...\n"), filename);
220 fh = fopen (filename, "a");
221 if (fh == NULL)
222 return SHISHI_FOPEN_ERROR;
224 res = shishi_keys_print (keys, fh);
225 if (res != SHISHI_OK)
226 return res;
228 res = fclose (fh);
229 if (res != 0)
230 return SHISHI_IO_ERROR;
232 if (VERBOSE (handle))
233 printf (_("Writing KEYS to %s...done\n"), filename);
235 return SHISHI_OK;
239 * shishi_keys_for_serverrealm_in_file
240 * @handle: Shishi library handle create by shishi_init().
241 * @filename: file to read keys from.
242 * @server: server name to get key for.
243 * @realm: realm of server to get key for.
245 * Get keys that match specified @server and @realm from the key set
246 * file @filename.
248 * Return value: Returns the key for specific server and realm, read
249 * from the indicated file, or NULL if no key could be found or an
250 * error encountered.
252 Shishi_key *
253 shishi_keys_for_serverrealm_in_file (Shishi * handle,
254 const char *filename,
255 const char *server, const char *realm)
257 Shishi_key *key = NULL;
258 FILE *fh;
259 int res;
261 fh = fopen (filename, "r");
262 if (fh == NULL)
263 return NULL;
265 res = SHISHI_OK;
266 while (!feof (fh))
268 res = shishi_key_parse (handle, fh, &key);
269 if (res != SHISHI_OK || key == NULL)
270 break;
272 if (VERBOSENOISE (handle))
274 printf ("Read key:\n");
275 shishi_key_print (handle, stdout, key);
278 if ((!server ||
279 (shishi_key_principal (key) &&
280 strcmp (server, shishi_key_principal (key)) == 0)) &&
281 (!realm ||
282 (shishi_key_realm (key) &&
283 strcmp (realm, shishi_key_realm (key)) == 0)))
284 break;
286 shishi_key_done (key);
287 key = NULL;
290 res = fclose (fh);
291 if (res != 0)
292 return NULL;
294 return key;
298 * shishi_keys_for_server_in_file
299 * @handle: Shishi library handle create by shishi_init().
300 * @filename: file to read keys from.
301 * @server: server name to get key for.
303 * Get key for specified @server from @filename.
305 * Return value: Returns the key for specific server, read from the
306 * indicated file, or NULL if no key could be found or an error
307 * encountered.
309 Shishi_key *
310 shishi_keys_for_server_in_file (Shishi * handle,
311 const char *filename, const char *server)
313 return shishi_keys_for_serverrealm_in_file (handle, filename, server, NULL);
317 * shishi_keys_for_localservicerealm_in_file:
318 * @handle: Shishi library handle create by shishi_init().
319 * @filename: file to read keys from.
320 * @service: service to get key for.
321 * @realm: realm of server to get key for, or NULL for default realm.
323 * Get key for specified @service and @realm from @filename.
325 * Return value: Returns the key for the server
326 * "SERVICE/HOSTNAME@REALM" (where HOSTNAME is the current system's
327 * hostname), read from the default host keys file (see
328 * shishi_hostkeys_default_file()), or NULL if no key could be found
329 * or an error encountered.
331 Shishi_key *
332 shishi_keys_for_localservicerealm_in_file (Shishi * handle,
333 const char *filename,
334 const char *service,
335 const char *realm)
337 char *hostname;
338 char *server;
339 Shishi_key *key;
341 hostname = xgethostname ();
343 asprintf (&server, "%s/%s", service, hostname);
345 key = shishi_keys_for_serverrealm_in_file (handle, filename, server, realm);
347 free (server);
348 free (hostname);
350 return key;