Use FORMAT everywhere, and fix up the errors it finds
[secnet] / secnet.h
CommitLineData
2fe58dfd
SE
1/* Core interface of secnet, to be used by all modules */
2
3#ifndef secnet_h
4#define secnet_h
5
59635212 6#include "config.h"
2fe58dfd 7#include <stdlib.h>
2fe58dfd 8#include <stdarg.h>
4f5e39ec 9#include <stdio.h>
b02b720a
IJ
10#include <string.h>
11#include <assert.h>
2fe58dfd 12#include <sys/poll.h>
8689b3a9
SE
13#include <sys/types.h>
14#include <sys/time.h>
2fe58dfd 15#include <netinet/in.h>
2fe58dfd 16
2fe58dfd 17typedef char *string_t;
fe5e9cc4 18typedef const char *cstring_t;
2fe58dfd
SE
19typedef enum {False,True} bool_t;
20
794f2398 21#define ASSERT(x) do { if (!(x)) { fatal("assertion failed line %d file " \
4f5e39ec 22 __FILE__,__LINE__); } } while(0)
2fe58dfd 23
fcbc5905
IJ
24/* from version.c */
25
26extern char version[];
27
08ee90a2
IJ
28/* from logmsg.c */
29extern uint32_t message_level;
30extern bool_t secnet_is_daemon;
31extern struct log_if *system_log;
32
33/* from process.c */
34extern void start_signal_handling(void);
35
2fe58dfd
SE
36/***** CONFIGURATION support *****/
37
baa06aeb
SE
38extern bool_t just_check_config; /* If True then we're going to exit after
39 reading the configuration file */
b2a56f7c 40extern bool_t background; /* If True then we'll eventually run as a daemon */
baa06aeb 41
2fe58dfd
SE
42typedef struct dict dict_t; /* Configuration dictionary */
43typedef struct closure closure_t;
44typedef struct item item_t;
45typedef struct list list_t; /* A list of items */
46
47/* Configuration file location, for error-reporting */
48struct cloc {
fe5e9cc4 49 cstring_t file;
1caa23ff 50 int line;
2fe58dfd
SE
51};
52
53/* Modules export closures, which can be invoked from the configuration file.
54 "Invoking" a closure usually returns another closure (of a different
55 type), but can actually return any configuration object. */
56typedef list_t *(apply_fn)(closure_t *self, struct cloc loc,
57 dict_t *context, list_t *data);
58struct closure {
fe5e9cc4 59 cstring_t description; /* For debugging */
2fe58dfd
SE
60 uint32_t type; /* Central registry... */
61 apply_fn *apply;
62 void *interface; /* Interface for use inside secnet; depends on type */
63};
64
65enum types { t_null, t_bool, t_string, t_number, t_dict, t_closure };
66struct item {
67 enum types type;
68 union {
69 bool_t bool;
70 string_t string;
71 uint32_t number;
72 dict_t *dict;
73 closure_t *closure;
74 } data;
75 struct cloc loc;
76};
77
ff05a229
SE
78/* Note that it is unwise to use this structure directly; use the list
79 manipulation functions instead. */
2fe58dfd
SE
80struct list {
81 item_t *item;
82 struct list *next;
83};
84
85/* In the following two lookup functions, NULL means 'not found' */
86/* Lookup a value in the specified dictionary, or its parents */
fe5e9cc4 87extern list_t *dict_lookup(dict_t *dict, cstring_t key);
2fe58dfd 88/* Lookup a value in just the specified dictionary */
fe5e9cc4 89extern list_t *dict_lookup_primitive(dict_t *dict, cstring_t key);
2fe58dfd 90/* Add a value to the specified dictionary */
fe5e9cc4 91extern void dict_add(dict_t *dict, cstring_t key, list_t *val);
2fe58dfd 92/* Obtain an array of keys in the dictionary. malloced; caller frees */
fe5e9cc4 93extern cstring_t *dict_keys(dict_t *dict);
2fe58dfd
SE
94
95/* List-manipulation functions */
96extern list_t *list_new(void);
1caa23ff 97extern int32_t list_length(list_t *a);
2fe58dfd
SE
98extern list_t *list_append(list_t *a, item_t *i);
99extern list_t *list_append_list(list_t *a, list_t *b);
100/* Returns an item from the list (index starts at 0), or NULL */
1caa23ff 101extern item_t *list_elem(list_t *l, int32_t index);
2fe58dfd
SE
102
103/* Convenience functions */
104extern list_t *new_closure(closure_t *cl);
fe5e9cc4
SE
105extern void add_closure(dict_t *dict, cstring_t name, apply_fn apply);
106extern void *find_cl_if(dict_t *dict, cstring_t name, uint32_t type,
107 bool_t fail_if_invalid, cstring_t desc,
2fe58dfd 108 struct cloc loc);
fe5e9cc4
SE
109extern item_t *dict_find_item(dict_t *dict, cstring_t key, bool_t required,
110 cstring_t desc, struct cloc loc);
111extern string_t dict_read_string(dict_t *dict, cstring_t key, bool_t required,
112 cstring_t desc, struct cloc loc);
113extern uint32_t dict_read_number(dict_t *dict, cstring_t key, bool_t required,
114 cstring_t desc, struct cloc loc,
115 uint32_t def);
59230b9b 116 /* return value can safely be assigned to int32_t */
fe5e9cc4
SE
117extern bool_t dict_read_bool(dict_t *dict, cstring_t key, bool_t required,
118 cstring_t desc, struct cloc loc, bool_t def);
9d3a4132 119struct flagstr {
fe5e9cc4 120 cstring_t name;
9d3a4132
SE
121 uint32_t value;
122};
fe5e9cc4
SE
123extern uint32_t string_to_word(cstring_t s, struct cloc loc,
124 struct flagstr *f, cstring_t desc);
9d3a4132 125extern uint32_t string_list_to_word(list_t *l, struct flagstr *f,
fe5e9cc4 126 cstring_t desc);
2fe58dfd
SE
127
128/***** END of configuration support *****/
129
7138d0c5
SE
130/***** UTILITY functions *****/
131
fe5e9cc4
SE
132extern char *safe_strdup(const char *string, const char *message);
133extern void *safe_malloc(size_t size, const char *message);
bb9d0561 134extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
2fe58dfd 135
fe5e9cc4 136extern int sys_cmd(const char *file, const char *argc, ...);
4efd681a 137
698280de
IJ
138extern uint64_t now_global;
139extern struct timeval tv_now_global;
140
141static const uint64_t *const now = &now_global;
142static const struct timeval *const tv_now = &tv_now_global;
143
144/* "now" is current program time, in milliseconds. It is derived
145 from tv_now. Both are provided by the event loop. */
146
2fe58dfd
SE
147/***** END of utility functions *****/
148
149/***** SCHEDULING support */
150
90a39563
IJ
151/* If nfds_io is insufficient for your needs, set it to the required
152 number and return ERANGE. timeout is in milliseconds; if it is too
153 high then lower it. It starts at -1 (==infinite) */
2fe58dfd 154typedef int beforepoll_fn(void *st, struct pollfd *fds, int *nfds_io,
90a39563
IJ
155 int *timeout_io);
156typedef void afterpoll_fn(void *st, struct pollfd *fds, int nfds);
2fe58dfd
SE
157
158/* Register interest in the main loop of the program. Before a call
159 to poll() your supplied beforepoll function will be called. After
160 the call to poll() the supplied afterpoll function will be called.
161 max_nfds is a _hint_ about the maximum number of struct pollfd
162 structures you may require - you can always ask for more in
163 *nfds_io. */
164extern void register_for_poll(void *st, beforepoll_fn *before,
1caa23ff 165 afterpoll_fn *after, int32_t max_nfds,
fe5e9cc4 166 cstring_t desc);
2fe58dfd
SE
167
168/***** END of scheduling support */
169
170/***** PROGRAM LIFETIME support */
171
172/* The secnet program goes through a number of phases in its lifetime.
173 Module code may arrange to be called just as various phases are
7b1a9fb7
RK
174 entered.
175
176 Remember to update the table in util.c if changing the set of
177 phases. */
2fe58dfd 178
42394c37
RK
179enum phase {
180 PHASE_INIT,
181 PHASE_GETOPTS, /* Process command-line arguments */
182 PHASE_READCONFIG, /* Parse and process configuration file */
183 PHASE_SETUP, /* Process information in configuration */
7b1a9fb7 184 PHASE_DAEMONIZE, /* Become a daemon (if necessary) */
42394c37
RK
185 PHASE_GETRESOURCES, /* Obtain all external resources */
186 PHASE_DROPPRIV, /* Last chance for privileged operations */
187 PHASE_RUN,
188 PHASE_SHUTDOWN, /* About to die; delete key material, etc. */
189 /* Keep this last: */
190 NR_PHASES,
191};
2fe58dfd
SE
192
193typedef void hook_fn(void *self, uint32_t newphase);
194bool_t add_hook(uint32_t phase, hook_fn *f, void *state);
195bool_t remove_hook(uint32_t phase, hook_fn *f, void *state);
196
7138d0c5
SE
197extern uint32_t current_phase;
198extern void enter_phase(uint32_t new_phase);
199
ff05a229
SE
200/* Some features (like netlink 'soft' routes) require that secnet
201 retain root privileges. They should indicate that here when
202 appropriate. */
203extern bool_t require_root_privileges;
fe5e9cc4 204extern cstring_t require_root_privileges_explanation;
9d3a4132 205
2fe58dfd
SE
206/***** END of program lifetime support *****/
207
208/***** MODULE support *****/
209
210/* Module initialisation function type - modules export one function of
211 this type which is called to initialise them. For dynamically loaded
212 modules it's called "secnet_module". */
469fd1d9 213typedef void init_module(dict_t *dict);
2fe58dfd 214
08ee90a2
IJ
215extern void init_builtin_modules(dict_t *dict);
216
217extern init_module resolver_module;
218extern init_module random_module;
219extern init_module udp_module;
220extern init_module util_module;
221extern init_module site_module;
b02b720a 222extern init_module transform_eax_module;
92a7d254 223extern init_module transform_cbcmac_module;
08ee90a2
IJ
224extern init_module netlink_module;
225extern init_module rsa_module;
226extern init_module dh_module;
227extern init_module md5_module;
228extern init_module slip_module;
229extern init_module tun_module;
230extern init_module sha1_module;
231extern init_module log_module;
232
2fe58dfd
SE
233/***** END of module support *****/
234
235/***** CLOSURE TYPES and interface definitions *****/
236
469fd1d9
SE
237#define CL_PURE 0
238#define CL_RESOLVER 1
239#define CL_RANDOMSRC 2
240#define CL_RSAPUBKEY 3
241#define CL_RSAPRIVKEY 4
242#define CL_COMM 5
243#define CL_IPIF 6
244#define CL_LOG 7
245#define CL_SITE 8
246#define CL_TRANSFORM 9
247#define CL_DH 11
248#define CL_HASH 12
249#define CL_BUFFER 13
250#define CL_NETLINK 14
2fe58dfd
SE
251
252struct buffer_if;
253
254/* PURE closure requires no interface */
255
256/* RESOLVER interface */
257
258/* Answers to queries are delivered to a function of this
259 type. 'address' will be NULL if there was a problem with the query. It
260 will be freed once resolve_answer_fn returns. It is in network byte
261 order. */
ff05a229 262/* XXX extend to be able to provide multiple answers */
2fe58dfd 263typedef void resolve_answer_fn(void *st, struct in_addr *addr);
fe5e9cc4 264typedef bool_t resolve_request_fn(void *st, cstring_t name,
2fe58dfd
SE
265 resolve_answer_fn *cb, void *cst);
266struct resolver_if {
267 void *st;
268 resolve_request_fn *request;
269};
270
271/* RANDOMSRC interface */
272
273/* Return some random data. Returns TRUE for success. */
1caa23ff 274typedef bool_t random_fn(void *st, int32_t bytes, uint8_t *buff);
2fe58dfd
SE
275
276struct random_if {
277 void *st;
278 bool_t blocking;
279 random_fn *generate;
280};
281
282/* RSAPUBKEY interface */
283
1caa23ff 284typedef bool_t rsa_checksig_fn(void *st, uint8_t *data, int32_t datalen,
fe5e9cc4 285 cstring_t signature);
2fe58dfd
SE
286struct rsapubkey_if {
287 void *st;
288 rsa_checksig_fn *check;
289};
290
291/* RSAPRIVKEY interface */
292
1caa23ff 293typedef string_t rsa_makesig_fn(void *st, uint8_t *data, int32_t datalen);
2fe58dfd
SE
294struct rsaprivkey_if {
295 void *st;
296 rsa_makesig_fn *sign;
297};
298
299/* COMM interface */
300
a15faeb2
IJ
301struct comm_addr {
302 /* This struct is pure data; in particular comm's clients may
303 freely copy it. */
304 /* Everyone is also guaranteed that all padding is set to zero, ie
305 that comm_addrs referring to semantically identical peers will
306 compare equal with memcmp. Anyone who constructs a comm_addr
307 must start by memsetting it with FILLZERO, or some
308 equivalent. */
309 struct comm_if *comm;
310 struct sockaddr_in sin;
311};
312
2fe58dfd
SE
313/* Return True if the packet was processed, and shouldn't be passed to
314 any other potential receivers. */
315typedef bool_t comm_notify_fn(void *state, struct buffer_if *buf,
a15faeb2 316 const struct comm_addr *source);
2fe58dfd
SE
317typedef void comm_request_notify_fn(void *commst, void *nst,
318 comm_notify_fn *fn);
319typedef void comm_release_notify_fn(void *commst, void *nst,
320 comm_notify_fn *fn);
321typedef bool_t comm_sendmsg_fn(void *commst, struct buffer_if *buf,
a15faeb2 322 const struct comm_addr *dest);
5edf478f
IJ
323typedef const char *comm_addr_to_string_fn(void *commst,
324 const struct comm_addr *ca);
325 /* Returned string is in a static buffer. */
2fe58dfd
SE
326struct comm_if {
327 void *st;
1caa23ff 328 int32_t min_start_pad;
2fe58dfd
SE
329 comm_request_notify_fn *request_notify;
330 comm_release_notify_fn *release_notify;
331 comm_sendmsg_fn *sendmsg;
5edf478f 332 comm_addr_to_string_fn *addr_to_string;
2fe58dfd
SE
333};
334
335/* LOG interface */
336
fe5e9cc4
SE
337typedef void log_msg_fn(void *st, int class, const char *message, ...);
338typedef void log_vmsg_fn(void *st, int class, const char *message,
339 va_list args);
2fe58dfd
SE
340struct log_if {
341 void *st;
779837e1
IJ
342 log_msg_fn *logfn; /* Do not call these directly - you don't get */
343 log_vmsg_fn *vlogfn; /* printf format checking. Use [v]slilog instead */
2fe58dfd 344};
59938e0e 345/* (convenience functions, defined in util.c) */
040ee979 346extern void slilog(struct log_if *lf, int class, const char *message, ...)
4f5e39ec 347FORMAT(printf,3,4);
59938e0e
IJ
348extern void vslilog(struct log_if *lf, int class, const char *message, va_list)
349FORMAT(printf,3,0);
2fe58dfd
SE
350
351/* SITE interface */
352
353/* Pretty much a placeholder; allows starting and stopping of processing,
354 key expiry, etc. */
355typedef void site_control_fn(void *st, bool_t run);
356typedef uint32_t site_status_fn(void *st);
357struct site_if {
358 void *st;
359 site_control_fn *control;
360 site_status_fn *status;
361};
362
363/* TRANSFORM interface */
364
365/* A reversable transformation. Transforms buffer in-place; may add
45a11706
IJ
366 data to start or end. Maximum amount of data to be added before
367 the packet specified in max_start_pad. (Reverse transformations decrease
2fe58dfd
SE
368 length, of course.) Transformations may be key-dependent, in which
369 case key material is passed in at initialisation time. They may
370 also depend on internal factors (eg. time) and keep internal
371 state. A struct transform_if only represents a particular type of
372 transformation; instances of the transformation (eg. with
0118121a
IJ
373 particular key material) have a different C type. The same
374 secret key will be used in opposite directions between a pair of
375 secnets; one of these pairs will get direction==False, the other True. */
2fe58dfd
SE
376
377typedef struct transform_inst_if *transform_createinstance_fn(void *st);
0118121a
IJ
378typedef bool_t transform_setkey_fn(void *st, uint8_t *key, int32_t keylen,
379 bool_t direction);
b67dab18 380typedef bool_t transform_valid_fn(void *st); /* 0: no key; 1: ok */
2fe58dfd
SE
381typedef void transform_delkey_fn(void *st);
382typedef void transform_destroyinstance_fn(void *st);
07e4774c
IJ
383/* Returns:
384 * 0: all is well
385 * 1: for any other problem
386 * 2: message decrypted but sequence number was out of range
387 */
2fe58dfd 388typedef uint32_t transform_apply_fn(void *st, struct buffer_if *buf,
fe5e9cc4 389 const char **errmsg);
2fe58dfd
SE
390
391struct transform_inst_if {
392 void *st;
393 transform_setkey_fn *setkey;
b67dab18 394 transform_valid_fn *valid;
2fe58dfd
SE
395 transform_delkey_fn *delkey;
396 transform_apply_fn *forwards;
397 transform_apply_fn *reverse;
398 transform_destroyinstance_fn *destroy;
1ce2f8bc 399 int32_t max_start_pad; /* same as from transform_if */
2fe58dfd
SE
400};
401
402struct transform_if {
403 void *st;
45a11706 404 int32_t max_start_pad; /* these two are both <<< INT_MAX */
7c9ca4bd 405 int32_t keylen; /* 0 means give the transform exactly as much as there is */
5b5f297f 406 int capab_transformnum;
2fe58dfd
SE
407 transform_createinstance_fn *create;
408};
409
410/* NETLINK interface */
411
70dc107b
SE
412/* Used by netlink to deliver to site, and by site to deliver to
413 netlink. cid is the client identifier returned by
414 netlink_regnets_fn. If buf has size 0 then the function is just
415 being called for its site-effects (eg. making the site code attempt
416 to bring up a network link) */
469fd1d9 417typedef void netlink_deliver_fn(void *st, struct buffer_if *buf);
4efd681a 418/* site code can tell netlink when outgoing packets will be dropped,
70dc107b 419 so netlink can generate appropriate ICMP and make routing decisions */
f208b9a9
IJ
420#define LINK_QUALITY_UNUSED 0 /* This link is unused, do not make this netlink */
421#define LINK_QUALITY_DOWN 1 /* No chance of a packet being delivered right away*/
422#define LINK_QUALITY_DOWN_STALE_ADDRESS 2 /* Link down, old address information */
423#define LINK_QUALITY_DOWN_CURRENT_ADDRESS 3 /* Link down, current address information */
424#define LINK_QUALITY_UP 4 /* Link active */
70dc107b 425#define MAXIMUM_LINK_QUALITY 3
469fd1d9
SE
426typedef void netlink_link_quality_fn(void *st, uint32_t quality);
427typedef void netlink_register_fn(void *st, netlink_deliver_fn *deliver,
45a11706 428 void *dst, int32_t max_start_pad);
794f2398
SE
429typedef void netlink_output_config_fn(void *st, struct buffer_if *buf);
430typedef bool_t netlink_check_config_fn(void *st, struct buffer_if *buf);
1caa23ff 431typedef void netlink_set_mtu_fn(void *st, int32_t new_mtu);
2fe58dfd
SE
432struct netlink_if {
433 void *st;
469fd1d9 434 netlink_register_fn *reg;
2fe58dfd 435 netlink_deliver_fn *deliver;
70dc107b 436 netlink_link_quality_fn *set_quality;
d3fe100d 437 netlink_set_mtu_fn *set_mtu;
2fe58dfd
SE
438};
439
440/* DH interface */
441
442/* Returns public key as a malloced hex string */
443typedef string_t dh_makepublic_fn(void *st, uint8_t *secret,
1caa23ff 444 int32_t secretlen);
2fe58dfd
SE
445/* Fills buffer (up to buflen) with shared secret */
446typedef void dh_makeshared_fn(void *st, uint8_t *secret,
1caa23ff
IJ
447 int32_t secretlen, cstring_t rempublic,
448 uint8_t *sharedsecret, int32_t buflen);
2fe58dfd
SE
449struct dh_if {
450 void *st;
1caa23ff 451 int32_t len; /* Approximate size of modulus in bytes */
7c9ca4bd 452 int32_t ceil_len; /* Number of bytes just sufficient to contain modulus */
2fe58dfd
SE
453 dh_makepublic_fn *makepublic;
454 dh_makeshared_fn *makeshared;
455};
456
457/* HASH interface */
458
459typedef void *hash_init_fn(void);
babd74ec 460typedef void hash_update_fn(void *st, const void *buf, int32_t len);
2fe58dfd
SE
461typedef void hash_final_fn(void *st, uint8_t *digest);
462struct hash_if {
1caa23ff 463 int32_t len; /* Hash output length in bytes */
2fe58dfd
SE
464 hash_init_fn *init;
465 hash_update_fn *update;
466 hash_final_fn *final;
467};
468
469/* BUFFER interface */
470
471struct buffer_if {
472 bool_t free;
fe5e9cc4 473 cstring_t owner; /* Set to constant string */
2fe58dfd
SE
474 uint32_t flags; /* How paranoid should we be? */
475 struct cloc loc; /* Where we were defined */
476 uint8_t *base;
477 uint8_t *start;
1caa23ff
IJ
478 int32_t size; /* Size of buffer contents */
479 int32_t len; /* Total length allocated at base */
2fe58dfd
SE
480};
481
4f5e39ec
SE
482/***** LOG functions *****/
483
484#define M_DEBUG_CONFIG 0x001
485#define M_DEBUG_PHASE 0x002
486#define M_DEBUG 0x004
487#define M_INFO 0x008
488#define M_NOTICE 0x010
489#define M_WARNING 0x020
490#define M_ERR 0x040
491#define M_SECURITY 0x080
492#define M_FATAL 0x100
493
494/* The fatal() family of functions require messages that do not end in '\n' */
779837e1
IJ
495extern NORETURN(fatal(const char *message, ...)) FORMAT(printf,1,2);
496extern NORETURN(fatal_perror(const char *message, ...)) FORMAT(printf,1,2);
497extern NORETURN(fatal_status(int status, const char *message, ...))
498 FORMAT(printf,2,3);
499extern NORETURN(fatal_perror_status(int status, const char *message, ...))
500 FORMAT(printf,2,3);
4f5e39ec
SE
501
502/* The cfgfatal() family of functions require messages that end in '\n' */
fe5e9cc4 503extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
779837e1 504 const char *message, ...)) FORMAT(printf,3,4);
4f5e39ec
SE
505extern void cfgfile_postreadcheck(struct cloc loc, FILE *f);
506extern NORETURN(vcfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
fe5e9cc4 507 cstring_t facility, const char *message,
779837e1
IJ
508 va_list))
509 FORMAT(printf,4,0);
4f5e39ec 510extern NORETURN(cfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
fe5e9cc4 511 cstring_t facility,
779837e1
IJ
512 const char *message, ...))
513 FORMAT(printf,4,5);
4f5e39ec 514
fe5e9cc4
SE
515extern void Message(uint32_t class, const char *message, ...)
516 FORMAT(printf,2,3);
517extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log);
4f5e39ec
SE
518
519/***** END of log functions *****/
520
45cfab8c
IJ
521#define STRING2(x) #x
522#define STRING(x) STRING2(x)
523
076bb54e
IJ
524#define FILLZERO(obj) (memset(&(obj),0,sizeof((obj))))
525
2fe58dfd 526#endif /* secnet_h */