1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
/*
* Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup bus bus
* @{ @ingroup libcharon
*/
#ifndef BUS_H_
#define BUS_H_
typedef enum alert_t alert_t;
typedef enum narrow_hook_t narrow_hook_t;
typedef struct bus_t bus_t;
#include <stdarg.h>
#include <debug.h>
#include <sa/ike_sa.h>
#include <sa/child_sa.h>
#include <processing/jobs/job.h>
#include <bus/listeners/listener.h>
/* undefine the definitions from libstrongswan */
#undef DBG0
#undef DBG1
#undef DBG2
#undef DBG3
#undef DBG4
#ifndef DEBUG_LEVEL
# define DEBUG_LEVEL 4
#endif /* DEBUG_LEVEL */
#if DEBUG_LEVEL >= 0
#define DBG0(group, format, ...) charon->bus->log(charon->bus, group, 0, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 0 */
#if DEBUG_LEVEL >= 1
#define DBG1(group, format, ...) charon->bus->log(charon->bus, group, 1, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 1 */
#if DEBUG_LEVEL >= 2
#define DBG2(group, format, ...) charon->bus->log(charon->bus, group, 2, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 2 */
#if DEBUG_LEVEL >= 3
#define DBG3(group, format, ...) charon->bus->log(charon->bus, group, 3, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 3 */
#if DEBUG_LEVEL >= 4
#define DBG4(group, format, ...) charon->bus->log(charon->bus, group, 4, format, ##__VA_ARGS__)
#endif /* DEBUG_LEVEL >= 4 */
#ifndef DBG0
# define DBG0(...) {}
#endif /* DBG0 */
#ifndef DBG1
# define DBG1(...) {}
#endif /* DBG1 */
#ifndef DBG2
# define DBG2(...) {}
#endif /* DBG2 */
#ifndef DBG3
# define DBG3(...) {}
#endif /* DBG3 */
#ifndef DBG4
# define DBG4(...) {}
#endif /* DBG4 */
/**
* Kind of alerts to raise.
*/
enum alert_t {
/** a RADIUS server did not respond, no additional arguments */
ALERT_RADIUS_NOT_RESPONDING,
/** a shutdown signal has been received, argument is the signal (int) */
ALERT_SHUTDOWN_SIGNAL,
/** peer authentication failed, no arguments */
ALERT_PEER_AUTH_FAILED,
/** failed to resolve peer address, no arguments */
ALERT_PEER_ADDR_FAILED,
};
/**
* Kind of narrow hook.
*
* There is a non-authenticated (IKE_AUTH) and a authenticated
* (CREATE_CHILD_SA) narrowing hook for the initiator. Only one of these
* hooks is invoked before the exchange.
* To verify the traffic selectors negotiated, each PRE hook has a POST
* counterpart that follows. POST hooks are invoked with an authenticated peer.
* It is usually not a good idea to narrow in the POST hooks,
* as the resulting traffic selector is not negotiated and results
* in non-matching policies.
*/
enum narrow_hook_t {
/** invoked as initiator before exchange, peer is not yet authenticated */
NARROW_INITIATOR_PRE_NOAUTH,
/** invoked as initiator before exchange, peer is authenticated */
NARROW_INITIATOR_PRE_AUTH,
/** invoked as responder during exchange, peer is authenticated */
NARROW_RESPONDER,
/** invoked as initiator after exchange, follows a INITIATOR_PRE_NOAUTH */
NARROW_INITIATOR_POST_NOAUTH,
/** invoked as initiator after exchange, follows a INITIATOR_PRE_AUTH */
NARROW_INITIATOR_POST_AUTH,
};
/**
* The bus receives events and sends them to all registered listeners.
*
* Any events sent to are delivered to all registered listeners. Threads
* may wait actively to events using the blocking listen() call.
*/
struct bus_t {
/**
* Register a listener to the bus.
*
* A registered listener receives all events which are sent to the bus.
* The listener is passive; the thread which emitted the event
* processes the listener routine.
*
* @param listener listener to register.
*/
void (*add_listener) (bus_t *this, listener_t *listener);
/**
* Unregister a listener from the bus.
*
* @param listener listener to unregister.
*/
void (*remove_listener) (bus_t *this, listener_t *listener);
/**
* Register a listener and block the calling thread.
*
* This call registers a listener and blocks the calling thread until
* its listeners function returns FALSE. This allows to wait for certain
* events. The associated job is executed after the listener has been
* registered: This allows to listen on events we initiate with the job,
* without missing any events to job may fire.
*
* @param listener listener to register
* @param job job to execute asynchronously when registered, or NULL
* @param timeout max timeout in ms to listen for events, 0 to disable
* @return TRUE if timed out
*/
bool (*listen)(bus_t *this, listener_t *listener, job_t *job, u_int timeout);
/**
* Set the IKE_SA the calling thread is using.
*
* To associate an received log message to an IKE_SA without passing it as
* parameter each time, the thread registers the currenlty used IKE_SA
* during check-out. Before check-in, the thread unregisters the IKE_SA.
* This IKE_SA is stored per-thread, so each thread has its own IKE_SA
* registered.
*
* @param ike_sa ike_sa to register, or NULL to unregister
*/
void (*set_sa) (bus_t *this, ike_sa_t *ike_sa);
/**
* Get the IKE_SA the calling thread is currently using.
*
* If a thread currently does not know what IKE_SA it is processing,
* it can call get_sa() to look up the SA set during checkout via set_sa().
*
* @return registered ike_sa, NULL if none registered
*/
ike_sa_t* (*get_sa)(bus_t *this);
/**
* Send a log message to the bus.
*
* The signal specifies the type of the event occurred. The format string
* specifies an additional informational or error message with a
* printf() like variable argument list.
* Use the DBG() macros.
*
* @param group debugging group
* @param level verbosity level of the signal
* @param format printf() style format string
* @param ... printf() style argument list
*/
void (*log)(bus_t *this, debug_t group, level_t level, char* format, ...);
/**
* Send a log message to the bus using va_list arguments.
*
* Same as bus_t.signal(), but uses va_list argument list.
*
* @param group kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
* @param format printf() style format string
* @param args va_list arguments
*/
void (*vlog)(bus_t *this, debug_t group, level_t level,
char* format, va_list args);
/**
* Raise an alert over the bus.
*
* @param alert kind of alert
* @param ... alert specific attributes
*/
void (*alert)(bus_t *this, alert_t alert, ...);
/**
* Send a IKE_SA state change event to the bus.
*
* @param ike_sa IKE_SA which changes its state
* @param state new state IKE_SA changes to
*/
void (*ike_state_change)(bus_t *this, ike_sa_t *ike_sa,
ike_sa_state_t state);
/**
* Send a CHILD_SA state change event to the bus.
*
* @param child_sa CHILD_SA which changes its state
* @param state new state CHILD_SA changes to
*/
void (*child_state_change)(bus_t *this, child_sa_t *child_sa,
child_sa_state_t state);
/**
* Message send/receive hook.
*
* The hook is invoked twice for each message: Once with plain, parsed data
* and once encoded and encrypted.
*
* @param message message to send/receive
* @param incoming TRUE for incoming messages, FALSE for outgoing
* @param plain TRUE if message is parsed and decrypted, FALSE it not
* @param
*/
void (*message)(bus_t *this, message_t *message, bool incoming, bool plain);
/**
* IKE_SA authorization hook.
*
* @param final TRUE if this is the final invocation
* @return TRUE to establish IKE_SA, FALSE to send AUTH_FAILED
*/
bool (*authorize)(bus_t *this, bool final);
/**
* CHILD_SA traffic selector narrowing hook.
*
* @param child_sa CHILD_SA set up with these traffic selectors
* @param type type of hook getting invoked
* @param local list of local traffic selectors to narrow
* @param remote list of remote traffic selectors to narrow
*/
void (*narrow)(bus_t *this, child_sa_t *child_sa, narrow_hook_t type,
linked_list_t *local, linked_list_t *remote);
/**
* IKE_SA keymat hook.
*
* @param ike_sa IKE_SA this keymat belongs to
* @param dh diffie hellman shared secret
* @param dh_other others DH public value (IKEv1 only)
* @param nonce_i initiators nonce
* @param nonce_r responders nonce
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
* @param shared shared key used for key derivation (IKEv1-PSK only)
*/
void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
ike_sa_t *rekey, shared_key_t *shared);
/**
* CHILD_SA keymat hook.
*
* @param child_sa CHILD_SA this keymat is used for
* @param initiator initiator of the CREATE_CHILD_SA exchange
* @param dh diffie hellman shared secret
* @param nonce_i initiators nonce
* @param nonce_r responders nonce
*/
void (*child_keys)(bus_t *this, child_sa_t *child_sa, bool initiator,
diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
/**
* IKE_SA up/down hook.
*
* @param ike_sa IKE_SA coming up/going down
* @param up TRUE for an up event, FALSE for a down event
*/
void (*ike_updown)(bus_t *this, ike_sa_t *ike_sa, bool up);
/**
* IKE_SA rekeying hook.
*
* @param old rekeyed and obsolete IKE_SA
* @param new new IKE_SA replacing old
*/
void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new);
/**
* CHILD_SA up/down hook.
*
* @param child_sa CHILD_SA coming up/going down
* @param up TRUE for an up event, FALSE for a down event
*/
void (*child_updown)(bus_t *this, child_sa_t *child_sa, bool up);
/**
* CHILD_SA rekeying hook.
*
* @param old rekeyed and obsolete CHILD_SA
* @param new new CHILD_SA replacing old
*/
void (*child_rekey)(bus_t *this, child_sa_t *old, child_sa_t *new);
/**
* Destroy the event bus.
*/
void (*destroy) (bus_t *this);
};
/**
* Create the event bus which forwards events to its listeners.
*
* @return event bus instance
*/
bus_t *bus_create();
#endif /** BUS_H_ @}*/
|