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