site: fix site name checking leaving room for expansion
[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
IJ
328 int32_t min_start_pad;
329 int32_t min_end_pad;
2fe58dfd
SE
330 comm_request_notify_fn *request_notify;
331 comm_release_notify_fn *release_notify;
332 comm_sendmsg_fn *sendmsg;
5edf478f 333 comm_addr_to_string_fn *addr_to_string;
2fe58dfd
SE
334};
335
336/* LOG interface */
337
fe5e9cc4
SE
338typedef void log_msg_fn(void *st, int class, const char *message, ...);
339typedef void log_vmsg_fn(void *st, int class, const char *message,
340 va_list args);
2fe58dfd
SE
341struct log_if {
342 void *st;
343 log_msg_fn *log;
344 log_vmsg_fn *vlog;
345};
59938e0e 346/* (convenience functions, defined in util.c) */
040ee979 347extern void slilog(struct log_if *lf, int class, const char *message, ...)
4f5e39ec 348FORMAT(printf,3,4);
59938e0e
IJ
349extern void vslilog(struct log_if *lf, int class, const char *message, va_list)
350FORMAT(printf,3,0);
2fe58dfd
SE
351
352/* SITE interface */
353
354/* Pretty much a placeholder; allows starting and stopping of processing,
355 key expiry, etc. */
356typedef void site_control_fn(void *st, bool_t run);
357typedef uint32_t site_status_fn(void *st);
358struct site_if {
359 void *st;
360 site_control_fn *control;
361 site_status_fn *status;
362};
363
364/* TRANSFORM interface */
365
366/* A reversable transformation. Transforms buffer in-place; may add
367 data to start or end. Maximum amount of data to be added specified
368 in max_start_pad and max_end_pad. (Reverse transformations decrease
369 length, of course.) Transformations may be key-dependent, in which
370 case key material is passed in at initialisation time. They may
371 also depend on internal factors (eg. time) and keep internal
372 state. A struct transform_if only represents a particular type of
373 transformation; instances of the transformation (eg. with
0118121a
IJ
374 particular key material) have a different C type. The same
375 secret key will be used in opposite directions between a pair of
376 secnets; one of these pairs will get direction==False, the other True. */
2fe58dfd
SE
377
378typedef struct transform_inst_if *transform_createinstance_fn(void *st);
0118121a
IJ
379typedef bool_t transform_setkey_fn(void *st, uint8_t *key, int32_t keylen,
380 bool_t direction);
b67dab18 381typedef bool_t transform_valid_fn(void *st); /* 0: no key; 1: ok */
2fe58dfd
SE
382typedef void transform_delkey_fn(void *st);
383typedef void transform_destroyinstance_fn(void *st);
07e4774c
IJ
384/* Returns:
385 * 0: all is well
386 * 1: for any other problem
387 * 2: message decrypted but sequence number was out of range
388 */
2fe58dfd 389typedef uint32_t transform_apply_fn(void *st, struct buffer_if *buf,
fe5e9cc4 390 const char **errmsg);
2fe58dfd
SE
391
392struct transform_inst_if {
393 void *st;
394 transform_setkey_fn *setkey;
b67dab18 395 transform_valid_fn *valid;
2fe58dfd
SE
396 transform_delkey_fn *delkey;
397 transform_apply_fn *forwards;
398 transform_apply_fn *reverse;
399 transform_destroyinstance_fn *destroy;
400};
401
402struct transform_if {
403 void *st;
1caa23ff
IJ
404 int32_t max_start_pad; /* these three are all <<< INT_MAX */
405 int32_t max_end_pad;
7c9ca4bd 406 int32_t keylen; /* 0 means give the transform exactly as much as there is */
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,
1caa23ff
IJ
428 void *dst, int32_t max_start_pad,
429 int32_t max_end_pad);
794f2398
SE
430typedef void netlink_output_config_fn(void *st, struct buffer_if *buf);
431typedef bool_t netlink_check_config_fn(void *st, struct buffer_if *buf);
1caa23ff 432typedef void netlink_set_mtu_fn(void *st, int32_t new_mtu);
2fe58dfd
SE
433struct netlink_if {
434 void *st;
469fd1d9 435 netlink_register_fn *reg;
2fe58dfd 436 netlink_deliver_fn *deliver;
70dc107b 437 netlink_link_quality_fn *set_quality;
d3fe100d 438 netlink_set_mtu_fn *set_mtu;
2fe58dfd
SE
439};
440
441/* DH interface */
442
443/* Returns public key as a malloced hex string */
444typedef string_t dh_makepublic_fn(void *st, uint8_t *secret,
1caa23ff 445 int32_t secretlen);
2fe58dfd
SE
446/* Fills buffer (up to buflen) with shared secret */
447typedef void dh_makeshared_fn(void *st, uint8_t *secret,
1caa23ff
IJ
448 int32_t secretlen, cstring_t rempublic,
449 uint8_t *sharedsecret, int32_t buflen);
2fe58dfd
SE
450struct dh_if {
451 void *st;
1caa23ff 452 int32_t len; /* Approximate size of modulus in bytes */
7c9ca4bd 453 int32_t ceil_len; /* Number of bytes just sufficient to contain modulus */
2fe58dfd
SE
454 dh_makepublic_fn *makepublic;
455 dh_makeshared_fn *makeshared;
456};
457
458/* HASH interface */
459
460typedef void *hash_init_fn(void);
babd74ec 461typedef void hash_update_fn(void *st, const void *buf, int32_t len);
2fe58dfd
SE
462typedef void hash_final_fn(void *st, uint8_t *digest);
463struct hash_if {
1caa23ff 464 int32_t len; /* Hash output length in bytes */
2fe58dfd
SE
465 hash_init_fn *init;
466 hash_update_fn *update;
467 hash_final_fn *final;
468};
469
470/* BUFFER interface */
471
472struct buffer_if {
473 bool_t free;
fe5e9cc4 474 cstring_t owner; /* Set to constant string */
2fe58dfd
SE
475 uint32_t flags; /* How paranoid should we be? */
476 struct cloc loc; /* Where we were defined */
477 uint8_t *base;
478 uint8_t *start;
1caa23ff
IJ
479 int32_t size; /* Size of buffer contents */
480 int32_t len; /* Total length allocated at base */
2fe58dfd
SE
481};
482
4f5e39ec
SE
483/***** LOG functions *****/
484
485#define M_DEBUG_CONFIG 0x001
486#define M_DEBUG_PHASE 0x002
487#define M_DEBUG 0x004
488#define M_INFO 0x008
489#define M_NOTICE 0x010
490#define M_WARNING 0x020
491#define M_ERR 0x040
492#define M_SECURITY 0x080
493#define M_FATAL 0x100
494
495/* The fatal() family of functions require messages that do not end in '\n' */
fe5e9cc4
SE
496extern NORETURN(fatal(const char *message, ...));
497extern NORETURN(fatal_perror(const char *message, ...));
498extern NORETURN(fatal_status(int status, const char *message, ...));
499extern NORETURN(fatal_perror_status(int status, const char *message, ...));
4f5e39ec
SE
500
501/* The cfgfatal() family of functions require messages that end in '\n' */
fe5e9cc4
SE
502extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
503 const char *message, ...));
4f5e39ec
SE
504extern void cfgfile_postreadcheck(struct cloc loc, FILE *f);
505extern NORETURN(vcfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
fe5e9cc4 506 cstring_t facility, const char *message,
4f5e39ec
SE
507 va_list));
508extern NORETURN(cfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
fe5e9cc4
SE
509 cstring_t facility,
510 const char *message, ...));
4f5e39ec 511
fe5e9cc4
SE
512extern void Message(uint32_t class, const char *message, ...)
513 FORMAT(printf,2,3);
514extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log);
4f5e39ec
SE
515
516/***** END of log functions *****/
517
45cfab8c
IJ
518#define STRING2(x) #x
519#define STRING(x) STRING2(x)
520
076bb54e
IJ
521#define FILLZERO(obj) (memset(&(obj),0,sizeof((obj))))
522
2fe58dfd 523#endif /* secnet_h */