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