Commit | Line | Data |
---|---|---|
d03ab969 | 1 | /* -*-c-*- |
2 | * | |
d03ab969 | 3 | * Simple key management |
4 | * | |
d11a0bf7 | 5 | * (c) 1999 Straylight/Edgeware |
d03ab969 | 6 | */ |
7 | ||
45c0fd36 | 8 | /*----- Licensing notice --------------------------------------------------* |
d03ab969 | 9 | * |
10 | * This file is part of Catacomb. | |
11 | * | |
12 | * Catacomb is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU Library General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
45c0fd36 | 16 | * |
d03ab969 | 17 | * Catacomb is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU Library General Public License for more details. | |
45c0fd36 | 21 | * |
d03ab969 | 22 | * You should have received a copy of the GNU Library General Public |
23 | * License along with Catacomb; if not, write to the Free | |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
b3f05084 | 28 | #ifndef CATACOMB_KEY_H |
29 | #define CATACOMB_KEY_H | |
d03ab969 | 30 | |
31 | #ifdef __cplusplus | |
32 | extern "C" { | |
33 | #endif | |
34 | ||
35 | /*----- Header files ------------------------------------------------------*/ | |
36 | ||
37 | #include <stdio.h> | |
38 | #include <time.h> | |
39 | ||
40 | #include <mLib/bits.h> | |
d11a0bf7 | 41 | #include <mLib/dstr.h> |
d03ab969 | 42 | #include <mLib/hash.h> |
43 | #include <mLib/sym.h> | |
44 | ||
1dda051b | 45 | #ifndef CATACOMB_KEY_ERROR_H |
46 | # include "key-error.h" | |
47 | #endif | |
48 | ||
052b36d0 | 49 | #ifndef CATACOMB_KEY_DATA_H |
50 | # include "key-data.h" | |
51 | #endif | |
52 | ||
981bf127 | 53 | #ifndef CATACOMB_GHASH_H |
54 | # include "ghash.h" | |
55 | #endif | |
56 | ||
d11a0bf7 | 57 | #ifndef CATACOMB_MP_H |
58 | # include "mp.h" | |
59 | #endif | |
60 | ||
d03ab969 | 61 | /*----- Data structures ---------------------------------------------------*/ |
62 | ||
63 | /* --- Key attributes --- * | |
64 | * | |
65 | * Each attribute is stored as a symbol in a symbol table. The value is | |
66 | * the plain (not url-encoded) text to be written to the the file. If the | |
67 | * value is binary data, then by this point it's base-64 encoded. | |
68 | */ | |
69 | ||
70 | typedef struct key_attr { | |
71 | sym_base _b; /* Symbol table data */ | |
72 | char *p; /* Pointer to attribute value */ | |
73 | } key_attr; | |
74 | ||
75 | /* --- Main key structure --- * | |
76 | * | |
77 | * Each key is stored in two symbol tables, one indexed by keyid, and the | |
78 | * other indexed by type. Because many keys can have the same type, the type | |
79 | * table contains a list of keys, sorted in descending order of expiry. | |
80 | */ | |
81 | ||
82 | typedef struct key { | |
d11a0bf7 | 83 | |
84 | /* --- Hashtable management --- */ | |
45c0fd36 | 85 | |
d03ab969 | 86 | hash_base _b; /* Symbol table data */ |
87 | struct key *next; /* Next key of the same type */ | |
d11a0bf7 | 88 | |
89 | /* --- Basic key attributes --- */ | |
90 | ||
d03ab969 | 91 | uint32 id; /* Key id used to name it */ |
d11a0bf7 | 92 | char *tag; /* Textual tag name */ |
d03ab969 | 93 | char *type; /* Textual key type */ |
d03ab969 | 94 | time_t exp, del; /* Expiry times for keys */ |
d11a0bf7 | 95 | |
96 | /* --- The key data itself --- */ | |
97 | ||
ef13e9a4 | 98 | key_data *k; /* The actual key data */ |
d11a0bf7 | 99 | |
100 | /* --- Other attributes and commentary --- */ | |
101 | ||
d03ab969 | 102 | sym_table a; /* Hashtable of key attributes */ |
103 | char *c; /* Any additional comments */ | |
104 | } key; | |
105 | ||
106 | /* --- The keys-by-type entries --- */ | |
107 | ||
d11a0bf7 | 108 | typedef struct key_ref { |
d03ab969 | 109 | sym_base _b; /* Symbol table data */ |
110 | key *k; /* Pointer to first key in list */ | |
d11a0bf7 | 111 | } key_ref; |
d03ab969 | 112 | |
113 | /* --- A key file --- */ | |
114 | ||
115 | typedef struct key_file { | |
116 | FILE *fp; /* File pointer open on file */ | |
d03ab969 | 117 | char *name; /* Filename used to create it */ |
118 | unsigned f; /* Various useful flags */ | |
119 | hash_table byid; /* Table of keys by keyid */ | |
120 | sym_table bytype; /* Table of keys by type */ | |
d11a0bf7 | 121 | sym_table bytag; /* Table of keys by tag */ |
d03ab969 | 122 | size_t idload; /* Loading on id table */ |
123 | } key_file; | |
124 | ||
125 | /* --- Key file flags --- */ | |
126 | ||
16efd15b | 127 | #define KF_WRITE 1u /* File opened for writing */ |
128 | #define KF_MODIFIED 2u /* File has been modified */ | |
d03ab969 | 129 | |
130 | /* --- Iterating over keys --- * | |
131 | * | |
132 | * Both of these are simple symbol table iterators, but they're made distinct | |
133 | * types for the dubious benefits that type safety brings. | |
134 | */ | |
135 | ||
136 | typedef struct { hash_iter i; time_t t; } key_iter; | |
137 | typedef struct { sym_iter i; } key_attriter; | |
138 | ||
cae5cb8e | 139 | /* --- Key fetching --- */ |
140 | ||
141 | typedef struct key_fetchdef { | |
142 | char *name; /* Name of item */ | |
143 | size_t off; /* Offset into target structure */ | |
144 | unsigned e; /* Flags for the item */ | |
145 | const struct key_fetchdef *kf; /* Substructure pointer */ | |
146 | } key_fetchdef; | |
147 | ||
d03ab969 | 148 | /* --- File opening options --- */ |
149 | ||
9f1b58fe | 150 | #define KOPEN_READ 0u |
151 | #define KOPEN_WRITE 1u | |
152 | #define KOPEN_MASK 0xff | |
153 | #define KOPEN_NOFILE 0x100 | |
d03ab969 | 154 | |
155 | /* --- Various other magic numbers --- */ | |
156 | ||
d03ab969 | 157 | #define KEXP_FOREVER ((time_t)-1) /* Never expire this key */ |
158 | #define KEXP_EXPIRE ((time_t)-2) /* Expire this key when unused */ | |
159 | ||
d11a0bf7 | 160 | /* --- Write error codes --- */ |
d03ab969 | 161 | |
162 | enum { | |
163 | KWRITE_OK, /* Everything went fine */ | |
164 | KWRITE_FAIL = -1, /* Close attempt failed */ | |
165 | KWRITE_BROKEN = -2 /* Key ring needs manual fixing */ | |
166 | }; | |
167 | ||
d11a0bf7 | 168 | /* --- Error reporting functions for @key_merge@ and @key_open@ --- */ |
169 | ||
170 | typedef void key_reporter(const char */*file*/, int /*line*/, | |
171 | const char */*err*/, void */*p*/); | |
172 | ||
d03ab969 | 173 | /* --- Macros for testing expiry --- */ |
174 | ||
175 | #define KEY_EXPIRED(now, exp) \ | |
176 | ((exp) == KEXP_EXPIRE || ((exp) != KEXP_FOREVER && (exp) < (now))) | |
177 | ||
d11a0bf7 | 178 | /*----- Reading and writing keys and files --------------------------------*/ |
d03ab969 | 179 | |
8f2287ef | 180 | /* --- @key_merge@, @key_mergeline@ --- * |
d03ab969 | 181 | * |
182 | * Arguments: @key_file *f@ = pointer to file structure | |
183 | * @const char *file@ = name of file (for error messages) | |
8f2287ef MW |
184 | * @int lno@ = line number (for error messages, @key_mergeline@) |
185 | * @FILE *fp@ = file handle to read from (@key_merge@) | |
186 | * @const char *line@ = line from the input (@key_mergeline@) | |
d11a0bf7 | 187 | * @key_reporter *rep@ = error reporting function |
188 | * @void *arg@ = argument for function | |
d03ab969 | 189 | * |
d11a0bf7 | 190 | * Returns: Error code (one of the @KERR@ constants). |
d03ab969 | 191 | * |
8f2287ef MW |
192 | * Use: The @key_merge@ function reads keys from a file, and inserts |
193 | * them into the keyring. | |
194 | * | |
195 | * The @key_mergeline@ function reads a key from a single input | |
196 | * line (which may, but need not, have a final newline), and | |
197 | * adds it to the keyring. | |
198 | * | |
199 | * The @key_mergeline@ function is intended to help with | |
200 | * interfacing Catacomb to runtimes which don't use C's @stdio@ | |
201 | * streams, rather than as a general-purpose service, though if | |
202 | * it turns out to be useful in other ways then so much the | |
203 | * better. | |
d03ab969 | 204 | */ |
205 | ||
d11a0bf7 | 206 | extern int key_merge(key_file */*f*/, const char */*file*/, FILE */*fp*/, |
207 | key_reporter */*rep*/, void */*arg*/); | |
8f2287ef MW |
208 | extern int key_mergeline(key_file */*f*/, const char */*file*/, int /*lno*/, |
209 | const char */*line*/, | |
210 | key_reporter */*rep*/, void */*arg*/); | |
d03ab969 | 211 | |
8f2287ef | 212 | /* --- @key_extract@, @key_extractline@ --- * |
d03ab969 | 213 | * |
214 | * Arguments: @key_file *f@ = pointer to file structure | |
215 | * @key *k@ = key to extract | |
8f2287ef MW |
216 | * @FILE *fp@ = file to write on (@key_extract@) |
217 | * @dstr *d@ = string to write on (@key_extractline@) | |
d11a0bf7 | 218 | * @const key_filter *kf@ = pointer to key selection block |
d03ab969 | 219 | * |
8f2287ef MW |
220 | * Returns: @key_extract@ returns zero if OK, EOF on error. |
221 | * @key_extractline@ does not return a value. | |
222 | * | |
223 | * Use: Extracts a key to an ouptut file or buffer. | |
224 | * | |
225 | * The @key_extractline@ includes a final newline in its output. | |
d03ab969 | 226 | * |
8f2287ef MW |
227 | * The @key_extractline@ function is intended to help with |
228 | * interfacing Catacomb to runtimes which don't use C's @stdio@ | |
229 | * streams, rather than as a general-purpose service, though if | |
230 | * it turns out to be useful in other ways then so much the | |
231 | * better. | |
d03ab969 | 232 | */ |
233 | ||
d11a0bf7 | 234 | extern int key_extract(key_file */*f*/, key */*k*/, FILE */*fp*/, |
235 | const key_filter */*kf*/); | |
8f2287ef MW |
236 | extern void key_extractline(key_file */*f*/, key */*k*/, |
237 | dstr */*d*/, const key_filter */*kf*/); | |
d03ab969 | 238 | |
239 | /* --- @key_open@ --- * | |
240 | * | |
241 | * Arguments: @key_file *f@ = pointer to file structure to initialize | |
242 | * @const char *file@ = pointer to the file name | |
9f1b58fe | 243 | * @unsigned how@ = opening options (@KOPEN_*@). |
d11a0bf7 | 244 | * @key_reporter *rep@ = error reporting function |
245 | * @void *arg@ = argument for function | |
d03ab969 | 246 | * |
247 | * Returns: Zero if it worked, nonzero otherwise. | |
248 | * | |
249 | * Use: Opens a key file, reads its contents, and stores them in a | |
250 | * structure. The file is locked appropriately until closed | |
251 | * using @key_close@. On an error, everything is cleared away | |
252 | * tidily. If the file is opened with @KOPEN_WRITE@, it's | |
253 | * created if necessary, with read and write permissions for its | |
254 | * owner only. | |
255 | */ | |
256 | ||
9f1b58fe | 257 | extern int key_open(key_file */*f*/, const char */*file*/, unsigned /*how*/, |
d11a0bf7 | 258 | key_reporter */*rep*/, void */*arg*/); |
d03ab969 | 259 | |
d901c888 | 260 | /* --- @key_discard@ --- * |
261 | * | |
262 | * Arguments: @key_file *f@ = pointer to key file block | |
263 | * | |
264 | * Returns: --- | |
265 | * | |
266 | * Use: Frees all the key data, without writing changes. | |
267 | */ | |
268 | ||
01e60364 | 269 | extern void key_discard(key_file */*f*/); |
d901c888 | 270 | |
d03ab969 | 271 | /* --- @key_close@ --- * |
272 | * | |
273 | * Arguments: @key_file *f@ = pointer to key file block | |
274 | * | |
275 | * Returns: A @KWRITE_@ code indicating how it went. | |
276 | * | |
277 | * Use: Frees all the key data, writes any changes. Make sure that | |
278 | * all hell breaks loose if this returns @KWRITE_BROKEN@. | |
279 | */ | |
280 | ||
281 | extern int key_close(key_file */*f*/); | |
282 | ||
d11a0bf7 | 283 | /* --- @key_save@ --- * |
284 | * | |
285 | * Arguments: @key_file *f@ = pointer to key file block | |
286 | * | |
287 | * Returns: A @KWRITE_@ code indicating how well it worked. | |
288 | * | |
289 | * Use: Writes a key file's data back to the actual file. This code | |
290 | * is extremely careful about error handling. It should usually | |
291 | * be able to back out somewhere sensible, but it can tell when | |
292 | * it's got itself into a real pickle and starts leaving well | |
293 | * alone. | |
294 | * | |
295 | * Callers, please make sure that you ring alarm bells when this | |
296 | * function returns @KWRITE_BROKEN@. | |
297 | */ | |
298 | ||
299 | extern int key_save(key_file */*f*/); | |
300 | ||
301 | /* --- @key_lockfile@ --- * | |
302 | * | |
303 | * Arguments: @key_file *f@ = pointer to file structure to initialize | |
304 | * @const char *file@ = pointer to the file name | |
9f1b58fe | 305 | * @unsigned how@ = opening options (@KOPEN_*@). |
d11a0bf7 | 306 | * |
307 | * Returns: Zero if it worked, nonzero otherwise. | |
308 | * | |
309 | * Use: Opens a keyfile and stores the information needed for | |
310 | * continued access in the structure. | |
311 | * | |
312 | * If the file is opened with @KOPEN_WRITE@, it's created if | |
313 | * necessary with read and write permissions for owner only, and | |
314 | * locked for update while it's open. | |
315 | * | |
316 | * This is a system-dependent routine, and only really intended | |
317 | * for the private use of @key_open@. | |
318 | */ | |
319 | ||
9f1b58fe | 320 | extern int key_lockfile(key_file */*f*/, const char */*file*/, |
321 | unsigned /*how*/); | |
d11a0bf7 | 322 | |
323 | /*----- Creating and manipulating keys ------------------------------------*/ | |
324 | ||
d03ab969 | 325 | /* --- @key_new@ --- |
326 | * | |
327 | * Arguments: @key_file *f@ = pointer to key file | |
d11a0bf7 | 328 | * @uint32 id@ = keyid to set |
d03ab969 | 329 | * @const char *type@ = the type of this key |
d03ab969 | 330 | * @time_t exp@ = when the key expires |
ef13e9a4 | 331 | * @key *kk@ = where to put the key pointer |
d03ab969 | 332 | * |
ef13e9a4 | 333 | * Returns: Error code (one of the @KERR@ constants). |
d03ab969 | 334 | * |
335 | * Use: Attaches a new key to a key file. You must have a writable | |
336 | * key file for this to work. | |
337 | * | |
338 | * The type is a key type string. This interface doesn't care | |
339 | * about how type strings are formatted: it just treats them as | |
340 | * opaque gobs of text. Clients are advised to choose some | |
341 | * standard for representing key types, though. | |
342 | * | |
d03ab969 | 343 | * The expiry time should either be a time in the future, or the |
344 | * magic value @KEXP_FOREVER@ which means `never expire this | |
345 | * key'. Be careful with `forever' keys. If I were you, I'd | |
346 | * use a more sophisticated key management system than this for | |
347 | * them. | |
348 | * | |
d11a0bf7 | 349 | * You have to set the actual key yourself. |
d03ab969 | 350 | */ |
351 | ||
ef13e9a4 | 352 | extern int key_new(key_file */*f*/, uint32 /*id*/, const char */*type*/, |
353 | time_t /*exp*/, key **/*kk*/); | |
d03ab969 | 354 | |
355 | /* --- @key_delete@ --- * | |
356 | * | |
357 | * Arguments: @key_file *f@ = pointer to file block | |
358 | * @key *k@ = key to delete | |
359 | * | |
d11a0bf7 | 360 | * Returns: Error code (one of the @KERR@ constants). |
d03ab969 | 361 | * |
362 | * Use: Removes the given key from the list. The key file must be | |
363 | * writable. (Due to the horridness of the data structures, | |
364 | * deleted keys aren't actually removed, just marked so that | |
365 | * they can't be looked up or iterated over. One upshot of | |
366 | * this is that they don't get written back to the file when | |
367 | * it's closed.) | |
368 | */ | |
369 | ||
d11a0bf7 | 370 | extern int key_delete(key_file */*f*/, key */*k*/); |
d03ab969 | 371 | |
9313a3d5 | 372 | /* --- @key_expired@ --- * |
373 | * | |
374 | * Arguments: @key *k@ = pointer to key block | |
375 | * | |
376 | * Returns: Zero if the key is OK, nonzero if it's expired. | |
377 | */ | |
378 | ||
379 | int key_expired(key */*k*/); | |
380 | ||
d03ab969 | 381 | /* --- @key_expire@ --- * |
382 | * | |
383 | * Arguments: @key_file *f@ = pointer to file block | |
384 | * @key *k@ = pointer to key block | |
385 | * | |
d11a0bf7 | 386 | * Returns: Error code (one of the @KERR@ constants). |
d03ab969 | 387 | * |
388 | * Use: Immediately marks the key as expired. It may be removed | |
389 | * immediately, if it is no longer required, and will be removed | |
390 | * by a tidy operation when it is no longer required. The key | |
391 | * file must be writable. | |
392 | */ | |
393 | ||
d11a0bf7 | 394 | extern int key_expire(key_file */*f*/, key */*k*/); |
d03ab969 | 395 | |
396 | /* --- @key_used@ --- * | |
397 | * | |
398 | * Arguments: @key_file *f@ = pointer to key file | |
399 | * @key *k@ = pointer to key block | |
400 | * @time_t t@ = when key can be removed | |
401 | * | |
402 | * Returns: Zero if OK, nonzero on failure. | |
403 | * | |
404 | * Use: Marks a key as being required until a given time. Even | |
405 | * though the key may expire before then (and won't be returned | |
406 | * by type after that time), it will still be available when | |
407 | * requested explicitly by id. The key file must be writable. | |
408 | * | |
409 | * The only (current) reason for failure is attempting to use | |
410 | * a key which can expire for something which can't. | |
411 | */ | |
412 | ||
413 | extern int key_used(key_file */*f*/, key */*k*/, time_t /*t*/); | |
414 | ||
981bf127 | 415 | /* --- @key_fingerprint@ --- * |
416 | * | |
417 | * Arguments: @key *k@ = the key to fingerprint | |
418 | * @ghash *h@ = the hash to use | |
419 | * @const key_filter *kf@ = filter to apply | |
420 | * | |
421 | * Returns: Nonzero if the key slightly matched the filter. | |
422 | * | |
423 | * Use: Updates the hash context with the key contents. | |
424 | */ | |
425 | ||
426 | extern int key_fingerprint(key */*k*/, ghash */*h*/, | |
427 | const key_filter */*kf*/); | |
428 | ||
d11a0bf7 | 429 | /*----- Setting and reading attributes ------------------------------------*/ |
430 | ||
431 | /* --- @key_chkident@ --- * | |
432 | * | |
433 | * Arguments: @const char *p@ = pointer to a type string | |
434 | * | |
435 | * Returns: Zero if OK, -1 on error. | |
436 | * | |
437 | * Use: Checks whether an identification component string is OK. | |
438 | */ | |
439 | ||
440 | extern int key_chkident(const char */*p*/); | |
441 | ||
442 | /* --- @key_chkcomment@ --- * | |
443 | * | |
444 | * Arguments: @const char *p@ = pointer to a comment string | |
445 | * | |
446 | * Returns: Zero if OK, -1 on error. | |
447 | * | |
448 | * Use: Checks whether a comment string is OK. | |
449 | */ | |
450 | ||
451 | extern int key_chkcomment(const char */*p*/); | |
452 | ||
453 | /* --- @key_setcomment@ --- * | |
454 | * | |
455 | * Arguments: @key_file *f@ = pointer to key file block | |
456 | * @key *k@ = pointer to key block | |
457 | * @const char *c@ = pointer to comment to set, or zero | |
458 | * | |
459 | * Returns: Error code (one of the @KERR@ constants). | |
460 | * | |
461 | * Use: Replaces the key's current comment with a new one. | |
462 | */ | |
463 | ||
464 | extern int key_setcomment(key_file */*f*/, key */*k*/, const char */*c*/); | |
465 | ||
466 | /* --- @key_settag@ --- * | |
467 | * | |
468 | * Arguments: @key_file *f@ = pointer to key file block | |
469 | * @key *k@ = pointer to key block | |
470 | * @const char *tag@ = pointer to comment to set, or zero | |
471 | * | |
472 | * Returns: Error code (one of the @KERR@ constants). | |
473 | * | |
474 | * Use: Replaces the key's current tag with a new one. | |
475 | */ | |
476 | ||
477 | extern int key_settag(key_file */*f*/, key */*k*/, const char */*tag*/); | |
478 | ||
ef13e9a4 | 479 | /* --- @key_setkeydata@ --- * |
480 | * | |
481 | * Arguments: @key_file *kf@ = pointer to key file | |
482 | * @key *k@ = pointer to key | |
483 | * @key_data *kd@ = new key data | |
484 | * | |
485 | * Returns: Zero on success, or a @KERR_@ error code on failure. | |
486 | * | |
487 | * Use: Sets the key data for a key. | |
488 | */ | |
489 | ||
490 | extern int key_setkeydata(key_file */*kf*/, key */*k*/, key_data */*kd*/); | |
491 | ||
d11a0bf7 | 492 | /* --- @key_fulltag@ --- * |
493 | * | |
494 | * Arguments: @key *k@ = pointer to key | |
495 | * @dstr *d@ = pointer to destination string | |
496 | * | |
497 | * Returns: --- | |
498 | * | |
499 | * Use: Emits the key's full tag, which has the form | |
500 | * `ID:TYPE[:TAG]'. This is used in the textual file format, | |
501 | * and to identify passphrases for locked keys. | |
502 | */ | |
503 | ||
504 | extern void key_fulltag(key */*k*/, dstr */*d*/); | |
505 | ||
506 | /* --- @key_qtag@ --- * | |
507 | * | |
508 | * Arguments: @key_file *f@ = key file to find a key from | |
509 | * @const char *tag@ = pointer to tag string | |
510 | * @dstr *d@ = pointer to string for full tag name | |
511 | * @key **k@ = where to store the key pointer | |
ef13e9a4 | 512 | * @key_data ***kd@ = where to store the key data pointer |
d11a0bf7 | 513 | * |
514 | * Returns: Zero if OK, nonzero if it failed. | |
515 | * | |
516 | * Use: Performs a full lookup on a qualified tag name. The tag is | |
517 | * qualified by the names of subkeys, separated by dots. Hence, | |
518 | * a qualified tag is ID|TAG[.TAG...]. The various result | |
519 | * pointers can be null to indicate that the result isn't | |
45c0fd36 | 520 | * interesting. |
d11a0bf7 | 521 | */ |
522 | ||
523 | extern int key_qtag(key_file */*f*/, const char */*tag*/, | |
ef13e9a4 | 524 | dstr */*d*/, key **/*k*/, key_data ***/*kd*/); |
d11a0bf7 | 525 | |
526 | /* --- @key_getattr@ --- * | |
527 | * | |
528 | * Arguments: @key_file *f@ = pointer to file | |
529 | * @key *k@ = pointer to key | |
530 | * @const char *n@ = pointer to attribute name | |
531 | * | |
532 | * Returns: Pointer to attribute value, or null if not found. | |
533 | * | |
534 | * Use: Returns the value of a key attribute. | |
535 | */ | |
536 | ||
537 | extern const char *key_getattr(key_file */*f*/, key */*k*/, | |
538 | const char */*n*/); | |
539 | ||
540 | /* --- @key_putattr@ --- * | |
541 | * | |
542 | * Arguments: @key_file *f@ = pointer to file | |
543 | * @key *k@ = pointer to key | |
544 | * @const char *n@ = pointer to attribute name | |
545 | * @const char *v@ = pointer to attribute value or null | |
546 | * | |
547 | * Returns: Error code (one of the @KERR@ constants). | |
548 | * | |
549 | * Use: Inserts an attribute on a key. If an attribute with the same | |
550 | * name already exists, it is deleted. Setting a null value | |
551 | * removes the attribute. | |
552 | */ | |
553 | ||
554 | extern int key_putattr(key_file */*f*/, key */*k*/, | |
555 | const char */*n*/, const char */*v*/); | |
556 | ||
557 | /* --- @key_mkattriter@ --- * | |
558 | * | |
559 | * Arguments: @key_attriter *i@ = pointer to attribute iterator | |
560 | * @key *k@ = pointer to key | |
561 | * | |
562 | * Returns: --- | |
563 | * | |
564 | * Use: Initializes an attribute iterator. The attributes are | |
565 | * returned by @key_nextattr@. | |
566 | */ | |
567 | ||
568 | extern void key_mkattriter(key_attriter */*i*/, key */*k*/); | |
569 | ||
570 | /* --- @key_nextattr@ --- * | |
571 | * | |
572 | * Arguments: @key_attriter *i@ = pointer to attribute iterator | |
573 | * @const char **n, **v@ = pointers to name and value | |
574 | * | |
575 | * Returns: Zero if no attribute available, or nonzero if returned OK. | |
576 | * | |
577 | * Use: Returns the next attribute. | |
578 | */ | |
579 | ||
580 | extern int key_nextattr(key_attriter */*i*/, | |
581 | const char **/*n*/, const char **/*v*/); | |
582 | ||
583 | /*----- Searching and iterating -------------------------------------------*/ | |
584 | ||
585 | /* --- @key_bytype@ --- * | |
586 | * | |
587 | * Arguments: @key_file *f@ = key file we want a key from | |
588 | * @const char *type@ = type string for desired key | |
589 | * | |
590 | * Returns: Pointer to the best key to use, or null. | |
591 | * | |
592 | * Use: Looks up a key by its type. Returns the key with the latest | |
593 | * expiry time. This function will not return an expired key. | |
594 | */ | |
595 | ||
596 | extern key *key_bytype(key_file */*f*/, const char */*type*/); | |
597 | ||
598 | /* --- @key_byid@ --- * | |
599 | * | |
600 | * Arguments: @key_file *f@ = key file to find a key from | |
601 | * @uint32 id@ = id to look for | |
602 | * | |
603 | * Returns: Key with matching id. | |
604 | * | |
605 | * Use: Returns a key given its id. This function will return an | |
606 | * expired key, but not a deleted one. | |
607 | */ | |
608 | ||
609 | extern key *key_byid(key_file */*f*/, uint32 /*id*/); | |
610 | ||
611 | /* --- @key_bytag@ --- * | |
612 | * | |
613 | * Arguments: @key_file *f@ = key file to find a key from | |
614 | * @const char *tag@ = pointer to tag string | |
615 | * | |
616 | * Returns: Key with matching id or tag. | |
617 | * | |
618 | * Use: Returns a key given its tag or id. This function will return | |
619 | * an expired key, but not a deleted one. | |
620 | */ | |
621 | ||
622 | extern key *key_bytag(key_file */*f*/, const char */*tag*/); | |
623 | ||
624 | /* --- @key_mkiter@ --- * | |
625 | * | |
626 | * Arguments: @key_iter *i@ = pointer to iterator object | |
627 | * @key_file *f@ = pointer to file structure | |
628 | * | |
629 | * Returns: --- | |
630 | * | |
631 | * Use: Initializes a key iterator. The keys are returned by | |
632 | * @key_next@. | |
633 | */ | |
634 | ||
635 | extern void key_mkiter(key_iter */*i*/, key_file */*f*/); | |
636 | ||
637 | /* --- @key_next@ --- * | |
638 | * | |
639 | * Arguments: @key_iter *i@ = pointer to iterator object | |
640 | * | |
641 | * Returns: Pointer to next key, or null. | |
642 | * | |
643 | * Use: Returns the next key in some arbitrary sequence. | |
644 | */ | |
645 | ||
646 | extern key *key_next(key_iter */*i*/); | |
647 | ||
cae5cb8e | 648 | /*----- Fetching key data conveniently ------------------------------------*/ |
649 | ||
650 | /* --- @key_fetchinit@ --- * | |
651 | * | |
652 | * Arguments: @const key_fetchdef *kf@ = pointer to base definition | |
653 | * @key_packstruct *kps@ = pointer to destination packing def | |
654 | * @void *p@ = pointer to destination block | |
655 | * | |
656 | * Returns: Pointer to packing definition. | |
657 | * | |
658 | * Use: Initializes a packing definition (@key_packdef@ structure). | |
659 | * If @kps@ is null on entry, an appropriately sized block is | |
660 | * allocated automatically. Otherwise it must be large enough. | |
661 | */ | |
662 | ||
663 | extern key_packdef *key_fetchinit(const key_fetchdef */*kf*/, | |
664 | key_packstruct */*kp*/, void */*p*/); | |
665 | ||
666 | /* --- @key_fetch@ --- * | |
667 | * | |
668 | * Arguments: @key_packdef *kp@ = pointer to packing structure | |
669 | * @key *k@ = key file containing desired key | |
670 | * | |
671 | * Returns: Error code, or zero. | |
672 | * | |
673 | * Use: Fetches an unpacked key from a packed one. | |
674 | */ | |
675 | ||
676 | extern int key_fetch(key_packdef */*kp*/, key */*k*/); | |
677 | ||
678 | /* --- @key_fetchbyname@ --- * | |
679 | * | |
680 | * Arguments: @key_packdef *kp@ = pointer to packing structure | |
681 | * @key_file *kf@ = key file containing desired key | |
682 | * @const char *tag@ = user's tag describing the key | |
683 | * | |
684 | * Returns: Error code, or zero. | |
685 | * | |
686 | * Use: Fetches a named key from a key file and unpacks it | |
687 | * conveniently. | |
688 | */ | |
689 | ||
690 | extern int key_fetchbyname(key_packdef */*kp*/, | |
691 | key_file */*kf*/, const char */*tag*/); | |
692 | ||
693 | /* --- @key_fetchdone@ --- * | |
694 | * | |
695 | * Arguments: @key_packdef *kp@ = pointer to packing structure | |
696 | * | |
697 | * Returns: --- | |
698 | * | |
699 | * Use: Frees a packing structure. If the structure was allocated by | |
700 | * @key_fetchinit@ then it is freed. | |
701 | */ | |
702 | ||
703 | extern void key_fetchdone(key_packdef */*kp*/); | |
704 | ||
d11a0bf7 | 705 | /*----- Other functions ---------------------------------------------------*/ |
706 | ||
707 | /* --- @key_moan@ --- * | |
708 | * | |
709 | * Arguments: @const char *file@ = name of the file | |
710 | * @int line@ = line number in file | |
711 | * @const char *msg@ = error message | |
712 | * @void *p@ = argument pointer | |
713 | * | |
714 | * Returns: --- | |
715 | * | |
716 | * Use: Reports an error message about loading a key file. | |
717 | */ | |
718 | ||
719 | extern void key_moan(const char */*file*/, int /*line*/, | |
720 | const char */*msg*/, void */*p*/); | |
721 | ||
d03ab969 | 722 | /*----- That's all, folks -------------------------------------------------*/ |
723 | ||
724 | #ifdef __cplusplus | |
725 | } | |
726 | #endif | |
727 | ||
728 | #endif |