New multiprecision integer arithmetic suite.
[u/mdw/catacomb] / key.h
1 /* -*-c-*-
2 *
3 * $Id: key.h,v 1.1 1999/09/03 08:41:12 mdw Exp $
4 *
5 * Simple key management
6 *
7 * (c) 1999 Mark Wooding
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: key.h,v $
33 * Revision 1.1 1999/09/03 08:41:12 mdw
34 * Initial import.
35 *
36 */
37
38 #ifndef KEY_H
39 #define KEY_H
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /*----- Header files ------------------------------------------------------*/
46
47 #include <stdio.h>
48 #include <time.h>
49
50 #include <mLib/bits.h>
51 #include <mLib/hash.h>
52 #include <mLib/sym.h>
53
54 /*----- Data structures ---------------------------------------------------*/
55
56 /* --- Key attributes --- *
57 *
58 * Each attribute is stored as a symbol in a symbol table. The value is
59 * the plain (not url-encoded) text to be written to the the file. If the
60 * value is binary data, then by this point it's base-64 encoded.
61 */
62
63 typedef struct key_attr {
64 sym_base _b; /* Symbol table data */
65 char *p; /* Pointer to attribute value */
66 } key_attr;
67
68 /* --- Main key structure --- *
69 *
70 * Each key is stored in two symbol tables, one indexed by keyid, and the
71 * other indexed by type. Because many keys can have the same type, the type
72 * table contains a list of keys, sorted in descending order of expiry.
73 */
74
75 typedef struct key {
76 hash_base _b; /* Symbol table data */
77 struct key *next; /* Next key of the same type */
78 uint32 id; /* Key id used to name it */
79 char *type; /* Textual key type */
80 void *k; /* Actual key data */
81 size_t ksz; /* Size of the key data */
82 time_t exp, del; /* Expiry times for keys */
83 sym_table a; /* Hashtable of key attributes */
84 char *c; /* Any additional comments */
85 } key;
86
87 /* --- The keys-by-type entries --- */
88
89 typedef struct key_type {
90 sym_base _b; /* Symbol table data */
91 key *k; /* Pointer to first key in list */
92 } key_type;
93
94 /* --- A key file --- */
95
96 typedef struct key_file {
97 FILE *fp; /* File pointer open on file */
98 int fd; /* File descriptor open on file */
99 char *name; /* Filename used to create it */
100 unsigned f; /* Various useful flags */
101 hash_table byid; /* Table of keys by keyid */
102 sym_table bytype; /* Table of keys by type */
103 size_t idload; /* Loading on id table */
104 } key_file;
105
106 /* --- Key file flags --- */
107
108 enum {
109 KF_WRITE = 1, /* File opened for writing */
110 KF_MODIFIED = 2 /* File has been modified */
111 };
112
113 /* --- Iterating over keys --- *
114 *
115 * Both of these are simple symbol table iterators, but they're made distinct
116 * types for the dubious benefits that type safety brings.
117 */
118
119 typedef struct { hash_iter i; time_t t; } key_iter;
120 typedef struct { sym_iter i; } key_attriter;
121
122 /* --- File opening options --- */
123
124 enum {
125 KOPEN_READ,
126 KOPEN_WRITE
127 };
128
129 /* --- Various other magic numbers --- */
130
131 #define KEXP_UNUSED ((time_t)0) /* Key has never been used */
132 #define KEXP_FOREVER ((time_t)-1) /* Never expire this key */
133 #define KEXP_EXPIRE ((time_t)-2) /* Expire this key when unused */
134
135 /* --- Write attempt codes --- */
136
137 enum {
138 KWRITE_OK, /* Everything went fine */
139 KWRITE_FAIL = -1, /* Close attempt failed */
140 KWRITE_BROKEN = -2 /* Key ring needs manual fixing */
141 };
142
143 /* --- Macros for testing expiry --- */
144
145 #define KEY_EXPIRED(now, exp) \
146 ((exp) == KEXP_EXPIRE || ((exp) != KEXP_FOREVER && (exp) < (now)))
147
148 #define KEY_DELETED(now, del) ((del) == KEXP_FOREVER || (del) < (now))
149
150 /*----- Functions provided ------------------------------------------------*/
151
152 /* --- @key_chktype@ --- *
153 *
154 * Arguments: @const char *type@ = pointer to a type string
155 *
156 * Returns: Zero if OK, -1 on error.
157 *
158 * Use: Checks whether a type string is OK.
159 */
160
161 extern int key_chktype(const char */*type*/);
162
163 /* --- @key_chkcomment@ --- *
164 *
165 * Arguments: @const char *comment@ = pointer to a comment string
166 *
167 * Returns: Zero if OK, -1 on error.
168 *
169 * Use: Checks whether a comment string is OK.
170 */
171
172 extern int key_chkcomment(const char */*c*/);
173
174 /* --- @key_mkiter@ --- *
175 *
176 * Arguments: @key_iter *i@ = pointer to iterator object
177 * @key_file *f@ = pointer to file structure
178 *
179 * Returns: ---
180 *
181 * Use: Initializes a key iterator. The keys are returned by
182 * @key_next@.
183 */
184
185 extern void key_mkiter(key_iter */*i*/, key_file */*f*/);
186
187 /* --- @key_next@ --- *
188 *
189 * Arguments: @key_iter *i@ = pointer to iterator object
190 *
191 * Returns: Pointer to next key, or null.
192 *
193 * Use: Returns the next key in some arbitrary sequence.
194 */
195
196 extern key *key_next(key_iter */*i*/);
197
198 /* --- @key_mkattriter@ --- *
199 *
200 * Arguments: @key_attriter *i@ = pointer to attribute iterator
201 * @key_file *f@ = pointer to key file
202 * @key *k@ = pointer to key
203 *
204 * Returns: ---
205 *
206 * Use: Initializes an attribute iterator. The attributes are
207 * returned by @key_nextattr@.
208 */
209
210 extern void key_mkattriter(key_attriter */*i*/, key_file */*f*/, key */*k*/);
211
212 /* --- @key_nextattr@ --- *
213 *
214 * Arguments: @key_attriter *i@ = pointer to attribute iterator
215 * @const char **n, **v@ = pointers to name and value
216 *
217 * Returns: Zero if no attribute available, or nonzero if returned OK.
218 *
219 * Use: Returns the next attribute.
220 */
221
222 extern int key_nextattr(key_attriter */*i*/,
223 const char **/*n*/, const char **/*v*/);
224
225 /* --- @key_bytype@ --- *
226 *
227 * Arguments: @key_file *f@ = key file we want a key from
228 * @const char *type@ = type string for desired key
229 *
230 * Returns: Pointer to the best key to use, or null.
231 *
232 * Use: Looks up a key by its type. Returns the key with the latest
233 * expiry time. This function will not return an expired key.
234 */
235
236 extern key *key_bytype(key_file */*f*/, const char */*type*/);
237
238 /* --- @key_byid@ --- *
239 *
240 * Arguments: @key_file *f@ = key file to find a key from
241 * @uint32 id@ = id to look for
242 *
243 * Returns: Key with matching id.
244 *
245 * Use: Returns a key given its id. This function will return an
246 * expired key, but not a deleted one.
247 */
248
249 extern key *key_byid(key_file */*f*/, uint32 /*id*/);
250
251 /* --- @key_getattr@ --- *
252 *
253 * Arguments: @key_file *f@ = pointer to file
254 * @key *k@ = pointer to key
255 * @const char *n@ = pointer to attribute name
256 *
257 * Returns: Pointer to attribute value, or null if not found.
258 *
259 * Use: Returns the value of a key attribute.
260 */
261
262 extern const char *key_getattr(key_file */*f*/, key */*k*/,
263 const char */*n*/);
264
265 /* --- @key_putattr@ --- *
266 *
267 * Arguments: @key_file *f@ = pointer to file
268 * @key *k@ = pointer to key
269 * @const char *n@ = pointer to attribute name
270 * @const char *v@ = pointer to attribute value
271 *
272 * Returns: ---
273 *
274 * Use: Inserts an attribute on a key. If an attribute with the same
275 * name already exists, it is deleted.
276 */
277
278 extern void key_putattr(key_file */*f*/, key */*k*/,
279 const char */*n*/, const char */*v*/);
280
281 /* --- @key_setcomment@ --- *
282 *
283 * Arguments: @key_file *f@ = pointer to key file block
284 * @key *k@ = pointer to key block
285 * @const char *c@ = pointer to comment to set, or zero
286 *
287 * Returns: ---
288 *
289 * Use: Replaces the key's current comment with a new one.
290 */
291
292 extern void key_setcomment(key_file */*f*/, key */*k*/, const char */*c*/);
293
294 /* --- @key_merge@ --- *
295 *
296 * Arguments: @key_file *f@ = pointer to file structure
297 * @const char *file@ = name of file (for error messages)
298 * @FILE *fp@ = file handle to read from
299 *
300 * Returns: ---
301 *
302 * Use: Reads keys from a file, and inserts them into the file.
303 */
304
305 extern void key_merge(key_file */*f*/, const char */*file*/, FILE */*fp*/);
306
307 /* --- @key_extract@ --- *
308 *
309 * Arguments: @key_file *f@ = pointer to file structure
310 * @key *k@ = key to extract
311 * @FILE *fp@ = file to write on
312 *
313 * Returns: Zero if OK, EOF on error.
314 *
315 * Use: Extracts a key to an ouptut file.
316 */
317
318 extern int key_extract(key_file */*f*/, key */*k*/, FILE */*fp*/);
319
320 /* --- @key_write@ --- *
321 *
322 * Arguments: @key_file *f@ = pointer to key file block
323 *
324 * Returns: A @KWRITE_@ code indicating how well it worked.
325 *
326 * Use: Writes a key file's data back to the actual file. This code
327 * is extremely careful about error handling. It should usually
328 * be able to back out somewhere sensible, but it can tell when
329 * it's got itself into a real pickle and starts leaving well
330 * alone.
331 *
332 * Callers, please make sure that you ring alarm bells when this
333 * function returns @KWRITE_BROKEN@.
334 */
335
336 extern int key_write(key_file */*f*/);
337
338 /* --- @key_open@ --- *
339 *
340 * Arguments: @key_file *f@ = pointer to file structure to initialize
341 * @const char *file@ = pointer to the file name
342 * @int how@ = opening options (@KOPEN_*@).
343 *
344 * Returns: Zero if it worked, nonzero otherwise.
345 *
346 * Use: Opens a key file, reads its contents, and stores them in a
347 * structure. The file is locked appropriately until closed
348 * using @key_close@. On an error, everything is cleared away
349 * tidily. If the file is opened with @KOPEN_WRITE@, it's
350 * created if necessary, with read and write permissions for its
351 * owner only.
352 */
353
354 extern int key_open(key_file */*f*/, const char */*file*/, int /*how*/);
355
356 /* --- @key_close@ --- *
357 *
358 * Arguments: @key_file *f@ = pointer to key file block
359 *
360 * Returns: A @KWRITE_@ code indicating how it went.
361 *
362 * Use: Frees all the key data, writes any changes. Make sure that
363 * all hell breaks loose if this returns @KWRITE_BROKEN@.
364 */
365
366 extern int key_close(key_file */*f*/);
367
368 /* --- @key_new@ ---
369 *
370 * Arguments: @key_file *f@ = pointer to key file
371 * @const char *type@ = the type of this key
372 * @const void *k@ = pointer to key data
373 * @size_t ksz@ = size of key data
374 * @time_t exp@ = when the key expires
375 * @const char *c@ = textual comment to attach
376 *
377 * Returns: Key block containing new data, or null if it couldn't be
378 * done.
379 *
380 * Use: Attaches a new key to a key file. You must have a writable
381 * key file for this to work.
382 *
383 * The type is a key type string. This interface doesn't care
384 * about how type strings are formatted: it just treats them as
385 * opaque gobs of text. Clients are advised to choose some
386 * standard for representing key types, though.
387 *
388 * The key can be any old binary mess.
389 *
390 * The expiry time should either be a time in the future, or the
391 * magic value @KEXP_FOREVER@ which means `never expire this
392 * key'. Be careful with `forever' keys. If I were you, I'd
393 * use a more sophisticated key management system than this for
394 * them.
395 *
396 * The comment can be any old text not containing newlines or
397 * nulls. This interface doesn't impose any length restrictions
398 * on comment lengths.
399 */
400
401 extern key *key_new(key_file */*f*/, const char */*type*/,
402 const void */*k*/, size_t /*ksz*/,
403 time_t /*exp*/, const char */*c*/);
404
405 /* --- @key_delete@ --- *
406 *
407 * Arguments: @key_file *f@ = pointer to file block
408 * @key *k@ = key to delete
409 *
410 * Returns: ---
411 *
412 * Use: Removes the given key from the list. The key file must be
413 * writable. (Due to the horridness of the data structures,
414 * deleted keys aren't actually removed, just marked so that
415 * they can't be looked up or iterated over. One upshot of
416 * this is that they don't get written back to the file when
417 * it's closed.)
418 */
419
420 extern void key_delete(key_file */*f*/, key */*k*/);
421
422 /* --- @key_expire@ --- *
423 *
424 * Arguments: @key_file *f@ = pointer to file block
425 * @key *k@ = pointer to key block
426 *
427 * Returns: ---
428 *
429 * Use: Immediately marks the key as expired. It may be removed
430 * immediately, if it is no longer required, and will be removed
431 * by a tidy operation when it is no longer required. The key
432 * file must be writable.
433 */
434
435 extern void key_expire(key_file */*f*/, key */*k*/);
436
437 /* --- @key_used@ --- *
438 *
439 * Arguments: @key_file *f@ = pointer to key file
440 * @key *k@ = pointer to key block
441 * @time_t t@ = when key can be removed
442 *
443 * Returns: Zero if OK, nonzero on failure.
444 *
445 * Use: Marks a key as being required until a given time. Even
446 * though the key may expire before then (and won't be returned
447 * by type after that time), it will still be available when
448 * requested explicitly by id. The key file must be writable.
449 *
450 * The only (current) reason for failure is attempting to use
451 * a key which can expire for something which can't.
452 */
453
454 extern int key_used(key_file */*f*/, key */*k*/, time_t /*t*/);
455
456 /*----- That's all, folks -------------------------------------------------*/
457
458 #ifdef __cplusplus
459 }
460 #endif
461
462 #endif