chiark / gitweb /
Initial import.
[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