Import release 0.1.14
[secnet] / site.c
CommitLineData
2fe58dfd
SE
1/* site.c - manage communication with a remote network site */
2
469fd1d9
SE
3/* The 'site' code doesn't know anything about the structure of the
4 packets it's transmitting. In fact, under the new netlink
5 configuration scheme it doesn't need to know anything at all about
6 IP addresses, except how to contact its peer. This means it could
7 potentially be used to tunnel other protocols too (IPv6, IPX, plain
8 old Ethernet frames) if appropriate netlink code can be written
9 (and that ought not to be too hard, eg. using the TUN/TAP device to
10 pretend to be an Ethernet interface). */
11
ff05a229
SE
12/* At some point in the future the netlink code will be asked for
13 configuration information to go in the PING/PONG packets at the end
14 of the key exchange. */
15
8689b3a9 16#include "secnet.h"
2fe58dfd 17#include <stdio.h>
469fd1d9 18#include <string.h>
8689b3a9 19#include <sys/socket.h>
2fe58dfd 20
8689b3a9 21#include <sys/mman.h>
2fe58dfd 22#include "util.h"
59635212 23#include "unaligned.h"
ff05a229 24#include "magic.h"
2fe58dfd
SE
25
26#define SETUP_BUFFER_LEN 2048
27
9d3a4132
SE
28#define DEFAULT_KEY_LIFETIME 3600000 /* One hour */
29#define DEFAULT_KEY_RENEGOTIATE_GAP 300000 /* Five minutes */
2fe58dfd 30#define DEFAULT_SETUP_RETRIES 5
4f5e39ec 31#define DEFAULT_SETUP_TIMEOUT 2000
3454dce4 32#define DEFAULT_WAIT_TIME 20000
2fe58dfd
SE
33
34/* Each site can be in one of several possible states. */
35
36/* States:
37 SITE_STOP - nothing is allowed to happen; tunnel is down;
38 all session keys have been erased
39 -> SITE_RUN upon external instruction
40 SITE_RUN - site up, maybe with valid key
41 -> SITE_RESOLVE upon outgoing packet and no valid key
42 we start name resolution for the other end of the tunnel
43 -> SITE_SENTMSG2 upon valid incoming message 1 and suitable time
44 we send an appropriate message 2
45 SITE_RESOLVE - waiting for name resolution
46 -> SITE_SENTMSG1 upon successful resolution
47 we send an appropriate message 1
48 -> SITE_SENTMSG2 upon valid incoming message 1 (then abort resolution)
49 we abort resolution and
50 -> SITE_WAIT on timeout or resolution failure
51 SITE_SENTMSG1
52 -> SITE_SENTMSG2 upon valid incoming message 1 from higher priority end
53 -> SITE_SENTMSG3 upon valid incoming message 2
54 -> SITE_WAIT on timeout
55 SITE_SENTMSG2
56 -> SITE_SENTMSG4 upon valid incoming message 3
57 -> SITE_WAIT on timeout
58 SITE_SENTMSG3
59 -> SITE_SENTMSG5 upon valid incoming message 4
60 -> SITE_WAIT on timeout
61 SITE_SENTMSG4
62 -> SITE_RUN upon valid incoming message 5
63 -> SITE_WAIT on timeout
64 SITE_SENTMSG5
65 -> SITE_RUN upon valid incoming message 6
66 -> SITE_WAIT on timeout
67 SITE_WAIT - failed to establish key; do nothing for a while
68 -> SITE_RUN on timeout
69 */
70
71#define SITE_STOP 0
72#define SITE_RUN 1
73#define SITE_RESOLVE 2
74#define SITE_SENTMSG1 3
75#define SITE_SENTMSG2 4
76#define SITE_SENTMSG3 5
77#define SITE_SENTMSG4 6
78#define SITE_SENTMSG5 7
79#define SITE_WAIT 8
80
81static string_t state_name(uint32_t state)
82{
83 switch (state) {
3454dce4
SE
84 case 0: return "STOP";
85 case 1: return "RUN";
86 case 2: return "RESOLVE";
87 case 3: return "SENTMSG1";
88 case 4: return "SENTMSG2";
89 case 5: return "SENTMSG3";
90 case 6: return "SENTMSG4";
91 case 7: return "SENTMSG5";
92 case 8: return "WAIT";
2fe58dfd
SE
93 default: return "*bad state*";
94 }
95}
96
2fe58dfd
SE
97#define NONCELEN 8
98
99#define LOG_UNEXPECTED 0x00000001
100#define LOG_SETUP_INIT 0x00000002
101#define LOG_SETUP_TIMEOUT 0x00000004
102#define LOG_ACTIVATE_KEY 0x00000008
103#define LOG_TIMEOUT_KEY 0x00000010
9d3a4132 104#define LOG_SEC 0x00000020
2fe58dfd
SE
105#define LOG_STATE 0x00000040
106#define LOG_DROP 0x00000080
107#define LOG_DUMP 0x00000100
108#define LOG_ERROR 0x00000400
109
9d3a4132
SE
110static struct flagstr log_event_table[]={
111 { "unexpected", LOG_UNEXPECTED },
112 { "setup-init", LOG_SETUP_INIT },
113 { "setup-timeout", LOG_SETUP_TIMEOUT },
114 { "activate-key", LOG_ACTIVATE_KEY },
115 { "timeout-key", LOG_TIMEOUT_KEY },
116 { "security", LOG_SEC },
117 { "state-change", LOG_STATE },
118 { "packet-drop", LOG_DROP },
119 { "dump-packets", LOG_DUMP },
120 { "errors", LOG_ERROR },
ff05a229
SE
121 { "default", LOG_SETUP_INIT|LOG_SETUP_TIMEOUT|
122 LOG_ACTIVATE_KEY|LOG_TIMEOUT_KEY|LOG_SEC|LOG_ERROR },
9d3a4132
SE
123 { "all", 0xffffffff },
124 { NULL, 0 }
125};
126
2fe58dfd
SE
127struct site {
128 closure_t cl;
129 struct site_if ops;
130/* configuration information */
131 string_t localname;
132 string_t remotename;
ff05a229 133 string_t tunname; /* localname<->remotename by default, used in logs */
2fe58dfd 134 string_t address; /* DNS name for bootstrapping, optional */
ff05a229 135 int remoteport; /* Port for bootstrapping, optional */
2fe58dfd
SE
136 struct netlink_if *netlink;
137 struct comm_if *comm;
138 struct resolver_if *resolver;
139 struct log_if *log;
140 struct random_if *random;
141 struct rsaprivkey_if *privkey;
2fe58dfd
SE
142 struct rsapubkey_if *pubkey;
143 struct transform_if *transform;
144 struct dh_if *dh;
145 struct hash_if *hash;
2fe58dfd
SE
146
147 uint32_t setup_retries; /* How many times to send setup packets */
148 uint32_t setup_timeout; /* Initial timeout for setup packets */
149 uint32_t wait_timeout; /* How long to wait if setup unsuccessful */
150 uint32_t key_lifetime; /* How long a key lasts once set up */
9d3a4132
SE
151 uint32_t key_renegotiate_time; /* If we see traffic (or a keepalive)
152 after this time, initiate a new
153 key exchange */
ff05a229
SE
154 bool_t keepalive; /* Send keepalives to detect peer failure (not yet
155 implemented) */
2fe58dfd
SE
156
157 uint8_t *setupsig; /* Expected signature of incoming MSG1 packets */
158 uint32_t setupsiglen; /* Allows us to discard packets quickly if
159 they are not for us */
160 bool_t setup_priority; /* Do we have precedence if both sites emit
161 message 1 simultaneously? */
162 uint32_t log_events;
163
164/* runtime information */
165 uint32_t state;
166 uint64_t now; /* Most recently seen time */
167
ff05a229 168 /* The currently established session */
2fe58dfd
SE
169 uint32_t remote_session_id;
170 struct transform_inst_if *current_transform;
171 bool_t current_valid;
172 uint64_t current_key_timeout; /* End of life of current key */
ff05a229 173 uint64_t renegotiate_key_time; /* When we can negotiate a new key */
2fe58dfd
SE
174 struct sockaddr_in peer; /* Current address of peer */
175 bool_t peer_valid; /* Peer address becomes invalid when key times out,
176 but only if we have a DNS name for our peer */
177
ff05a229
SE
178 /* The current key setup protocol exchange. We can only be
179 involved in one of these at a time. There's a potential for
180 denial of service here (the attacker keeps sending a setup
181 packet; we keep trying to continue the exchange, and have to
182 timeout before we can listen for another setup packet); perhaps
183 we should keep a list of 'bad' sources for setup packets. */
2fe58dfd
SE
184 uint32_t setup_session_id;
185 struct sockaddr_in setup_peer;
186 uint8_t localN[NONCELEN]; /* Nonces for key exchange */
187 uint8_t remoteN[NONCELEN];
188 struct buffer_if buffer; /* Current outgoing key exchange packet */
189 uint32_t retries; /* Number of retries remaining */
190 uint64_t timeout; /* Timeout for current state */
191 uint8_t *dhsecret;
192 uint8_t *sharedsecret;
2fe58dfd
SE
193 struct transform_inst_if *new_transform; /* For key setup/verify */
194};
195
196static void slog(struct site *st, uint32_t event, string_t msg, ...)
197{
198 va_list ap;
199 uint8_t buf[240];
b2a56f7c 200 uint32_t class;
2fe58dfd
SE
201
202 va_start(ap,msg);
203
204 if (event&st->log_events) {
b2a56f7c
SE
205 switch(event) {
206 case LOG_UNEXPECTED: class=M_INFO; break;
207 case LOG_SETUP_INIT: class=M_INFO; break;
208 case LOG_SETUP_TIMEOUT: class=M_NOTICE; break;
209 case LOG_ACTIVATE_KEY: class=M_INFO; break;
210 case LOG_TIMEOUT_KEY: class=M_INFO; break;
211 case LOG_SEC: class=M_SECURITY; break;
212 case LOG_STATE: class=M_DEBUG; break;
213 case LOG_DROP: class=M_DEBUG; break;
214 case LOG_DUMP: class=M_DEBUG; break;
469fd1d9
SE
215 case LOG_ERROR: class=M_ERR; break;
216 default: class=M_ERR; break;
b2a56f7c
SE
217 }
218
2fe58dfd 219 vsnprintf(buf,240,msg,ap);
b2a56f7c 220 st->log->log(st->log->st,class,"%s: %s",st->tunname,buf);
2fe58dfd
SE
221 }
222 va_end(ap);
223}
224
9d3a4132 225static void set_link_quality(struct site *st);
794f2398
SE
226static void delete_key(struct site *st, string_t reason, uint32_t loglevel);
227static bool_t initiate_key_setup(struct site *st, string_t reason);
2fe58dfd
SE
228static void enter_state_run(struct site *st);
229static bool_t enter_state_resolve(struct site *st);
ff05a229 230static bool_t enter_new_state(struct site *st,uint32_t next);
2fe58dfd
SE
231static void enter_state_wait(struct site *st);
232
233#define CHECK_AVAIL(b,l) do { if ((b)->size<(l)) return False; } while(0)
234#define CHECK_EMPTY(b) do { if ((b)->size!=0) return False; } while(0)
235#define CHECK_TYPE(b,t) do { uint32_t type; \
236 CHECK_AVAIL((b),4); \
59635212 237 type=buf_unprepend_uint32((b)); \
2fe58dfd
SE
238 if (type!=(t)) return False; } while(0)
239
240struct msg {
241 uint8_t *hashstart;
242 uint32_t dest;
243 uint32_t source;
244 uint32_t remlen;
245 uint8_t *remote;
246 uint32_t loclen;
247 uint8_t *local;
248 uint8_t *nR;
249 uint8_t *nL;
250 uint32_t pklen;
251 uint8_t *pk;
252 uint32_t hashlen;
253 uint32_t siglen;
254 uint8_t *sig;
255};
256
ff05a229
SE
257/* Build any of msg1 to msg4. msg5 and msg6 are built from the inside
258 out using a transform of config data supplied by netlink */
2fe58dfd
SE
259static bool_t generate_msg(struct site *st, uint32_t type, string_t what)
260{
261 void *hst;
262 uint8_t *hash=alloca(st->hash->len);
263 string_t dhpub, sig;
264
265 st->retries=st->setup_retries;
266 BUF_ALLOC(&st->buffer,what);
267 buffer_init(&st->buffer,0);
59635212
SE
268 buf_append_uint32(&st->buffer,
269 (type==LABEL_MSG1?0:st->setup_session_id));
270 buf_append_uint32(&st->buffer,(uint32_t)st);
271 buf_append_uint32(&st->buffer,type);
2fe58dfd
SE
272 buf_append_string(&st->buffer,st->localname);
273 buf_append_string(&st->buffer,st->remotename);
274 memcpy(buf_append(&st->buffer,NONCELEN),st->localN,NONCELEN);
275 if (type==LABEL_MSG1) return True;
276 memcpy(buf_append(&st->buffer,NONCELEN),st->remoteN,NONCELEN);
277 if (type==LABEL_MSG2) return True;
278 dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
279 buf_append_string(&st->buffer,dhpub);
280 free(dhpub);
281 hst=st->hash->init();
282 st->hash->update(hst,st->buffer.start,st->buffer.size);
283 st->hash->final(hst,hash);
284 sig=st->privkey->sign(st->privkey->st,hash,st->hash->len);
285 buf_append_string(&st->buffer,sig);
286 free(sig);
287 return True;
288}
289
290static bool_t unpick_msg(struct site *st, uint32_t type,
291 struct buffer_if *msg, struct msg *m)
292{
293 m->hashstart=msg->start;
294 CHECK_AVAIL(msg,4);
59635212 295 m->dest=buf_unprepend_uint32(msg);
2fe58dfd 296 CHECK_AVAIL(msg,4);
59635212 297 m->source=buf_unprepend_uint32(msg);
2fe58dfd
SE
298 CHECK_TYPE(msg,type);
299 CHECK_AVAIL(msg,2);
59635212 300 m->remlen=buf_unprepend_uint16(msg);
2fe58dfd
SE
301 CHECK_AVAIL(msg,m->remlen);
302 m->remote=buf_unprepend(msg,m->remlen);
303 CHECK_AVAIL(msg,2);
59635212 304 m->loclen=buf_unprepend_uint16(msg);
2fe58dfd
SE
305 CHECK_AVAIL(msg,m->loclen);
306 m->local=buf_unprepend(msg,m->loclen);
307 CHECK_AVAIL(msg,NONCELEN);
308 m->nR=buf_unprepend(msg,NONCELEN);
309 if (type==LABEL_MSG1) {
310 CHECK_EMPTY(msg);
311 return True;
312 }
313 CHECK_AVAIL(msg,NONCELEN);
314 m->nL=buf_unprepend(msg,NONCELEN);
315 if (type==LABEL_MSG2) {
316 CHECK_EMPTY(msg);
317 return True;
318 }
319 CHECK_AVAIL(msg,2);
59635212 320 m->pklen=buf_unprepend_uint16(msg);
2fe58dfd
SE
321 CHECK_AVAIL(msg,m->pklen);
322 m->pk=buf_unprepend(msg,m->pklen);
323 m->hashlen=msg->start-m->hashstart;
324 CHECK_AVAIL(msg,2);
59635212 325 m->siglen=buf_unprepend_uint16(msg);
2fe58dfd
SE
326 CHECK_AVAIL(msg,m->siglen);
327 m->sig=buf_unprepend(msg,m->siglen);
328 CHECK_EMPTY(msg);
329 return True;
330}
331
ff05a229
SE
332static bool_t check_msg(struct site *st, uint32_t type, struct msg *m,
333 string_t *error)
334{
335 if (type==LABEL_MSG1) return True;
336
337 /* Check that the site names and our nonce have been sent
338 back correctly, and then store our peer's nonce. */
339 if (memcmp(m->remote,st->remotename,strlen(st->remotename)!=0)) {
340 *error="wrong remote site name";
341 return False;
342 }
343 if (memcmp(m->local,st->localname,strlen(st->localname)!=0)) {
344 *error="wrong local site name";
345 return False;
346 }
347 if (memcmp(m->nL,st->localN,NONCELEN)!=0) {
348 *error="wrong locally-generated nonce";
349 return False;
350 }
351 if (type==LABEL_MSG2) return True;
352 if (memcmp(m->nR,st->remoteN,NONCELEN)!=0) {
353 *error="wrong remotely-generated nonce";
354 return False;
355 }
356 if (type==LABEL_MSG3) return True;
357 if (type==LABEL_MSG4) return True;
358 *error="unknown message type";
359 return False;
360}
361
2fe58dfd
SE
362static bool_t generate_msg1(struct site *st)
363{
364 st->random->generate(st->random->st,NONCELEN,st->localN);
365 return generate_msg(st,LABEL_MSG1,"site:MSG1");
366}
367
368static bool_t process_msg1(struct site *st, struct buffer_if *msg1,
369 struct sockaddr_in *src)
370{
371 struct msg m;
372
373 /* We've already determined we're in an appropriate state to
374 process an incoming MSG1, and that the MSG1 has correct values
375 of A and B. */
376
377 if (!unpick_msg(st,LABEL_MSG1,msg1,&m)) return False;
378
2fe58dfd 379 st->setup_peer=*src;
2fe58dfd
SE
380 st->setup_session_id=m.source;
381 memcpy(st->remoteN,m.nR,NONCELEN);
382 return True;
383}
384
385static bool_t generate_msg2(struct site *st)
386{
387 st->random->generate(st->random->st,NONCELEN,st->localN);
388 return generate_msg(st,LABEL_MSG2,"site:MSG2");
389}
390
391static bool_t process_msg2(struct site *st, struct buffer_if *msg2,
392 struct sockaddr_in *src)
393{
394 struct msg m;
ff05a229 395 string_t err;
2fe58dfd
SE
396
397 if (!unpick_msg(st,LABEL_MSG2,msg2,&m)) return False;
ff05a229
SE
398 if (!check_msg(st,LABEL_MSG2,&m,&err)) {
399 slog(st,LOG_SEC,"msg2: %s",err);
2fe58dfd
SE
400 return False;
401 }
402 st->setup_session_id=m.source;
403 memcpy(st->remoteN,m.nR,NONCELEN);
404 return True;
405}
406
407static bool_t generate_msg3(struct site *st)
408{
409 /* Now we have our nonce and their nonce. Think of a secret key,
410 and create message number 3. */
411 st->random->generate(st->random->st,st->dh->len,st->dhsecret);
412 return generate_msg(st,LABEL_MSG3,"site:MSG3");
413}
414
415static bool_t process_msg3(struct site *st, struct buffer_if *msg3,
416 struct sockaddr_in *src)
417{
418 struct msg m;
419 uint8_t *hash=alloca(st->hash->len);
420 void *hst;
ff05a229 421 string_t err;
2fe58dfd
SE
422
423 if (!unpick_msg(st,LABEL_MSG3,msg3,&m)) return False;
ff05a229
SE
424 if (!check_msg(st,LABEL_MSG3,&m,&err)) {
425 slog(st,LOG_SEC,"msg3: %s",err);
2fe58dfd
SE
426 return False;
427 }
ff05a229 428
2fe58dfd
SE
429 /* Check signature and store g^x mod m */
430 hst=st->hash->init();
431 st->hash->update(hst,m.hashstart,m.hashlen);
432 st->hash->final(hst,hash);
433 /* Terminate signature with a '0' - cheating, but should be ok */
434 m.sig[m.siglen]=0;
435 if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
59635212 436 slog(st,LOG_SEC,"msg3 signature failed check!");
2fe58dfd
SE
437 return False;
438 }
439
440 /* Terminate their DH public key with a '0' */
441 m.pk[m.pklen]=0;
442 /* Invent our DH secret key */
443 st->random->generate(st->random->st,st->dh->len,st->dhsecret);
444
445 /* Generate the shared key */
446 st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,m.pk,
447 st->sharedsecret,st->transform->keylen);
448
449 /* Set up the transform */
450 st->new_transform->setkey(st->new_transform->st,st->sharedsecret,
451 st->transform->keylen);
452
453 return True;
454}
455
456static bool_t generate_msg4(struct site *st)
457{
458 /* We have both nonces, their public key and our private key. Generate
459 our public key, sign it and send it to them. */
460 return generate_msg(st,LABEL_MSG4,"site:MSG4");
461}
462
463static bool_t process_msg4(struct site *st, struct buffer_if *msg4,
464 struct sockaddr_in *src)
465{
466 struct msg m;
467 uint8_t *hash=alloca(st->hash->len);
468 void *hst;
ff05a229 469 string_t err;
2fe58dfd
SE
470
471 if (!unpick_msg(st,LABEL_MSG4,msg4,&m)) return False;
ff05a229
SE
472 if (!check_msg(st,LABEL_MSG4,&m,&err)) {
473 slog(st,LOG_SEC,"msg4: %s",err);
2fe58dfd
SE
474 return False;
475 }
476
477 /* Check signature and store g^x mod m */
478 hst=st->hash->init();
479 st->hash->update(hst,m.hashstart,m.hashlen);
480 st->hash->final(hst,hash);
481 /* Terminate signature with a '0' - cheating, but should be ok */
482 m.sig[m.siglen]=0;
483 if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
59635212 484 slog(st,LOG_SEC,"msg4 signature failed check!");
2fe58dfd
SE
485 return False;
486 }
487
488 /* Terminate their DH public key with a '0' */
489 m.pk[m.pklen]=0;
490 /* Generate the shared key */
491 st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,m.pk,
492 st->sharedsecret,st->transform->keylen);
493 /* Set up the transform */
494 st->new_transform->setkey(st->new_transform->st,st->sharedsecret,
495 st->transform->keylen);
496
497 return True;
498}
499
2fe58dfd
SE
500struct msg0 {
501 uint32_t dest;
502 uint32_t source;
503 uint32_t type;
504};
505
506static bool_t unpick_msg0(struct site *st, struct buffer_if *msg0,
507 struct msg0 *m)
508{
509 CHECK_AVAIL(msg0,4);
59635212 510 m->dest=buf_unprepend_uint32(msg0);
2fe58dfd 511 CHECK_AVAIL(msg0,4);
59635212 512 m->source=buf_unprepend_uint32(msg0);
2fe58dfd 513 CHECK_AVAIL(msg0,4);
59635212 514 m->type=buf_unprepend_uint32(msg0);
2fe58dfd
SE
515 return True;
516 /* Leaves transformed part of buffer untouched */
517}
518
ff05a229
SE
519static bool_t generate_msg5(struct site *st)
520{
521 string_t transform_err;
522
523 BUF_ALLOC(&st->buffer,"site:MSG5");
524 /* We are going to add four words to the message */
525 buffer_init(&st->buffer,st->transform->max_start_pad+(4*4));
526 /* Give the netlink code an opportunity to put its own stuff in the
527 message (configuration information, etc.) */
528 st->netlink->output_config(st->netlink->st,&st->buffer);
529 buf_prepend_uint32(&st->buffer,LABEL_MSG5);
530 st->new_transform->forwards(st->new_transform->st,&st->buffer,
531 &transform_err);
532 buf_prepend_uint32(&st->buffer,LABEL_MSG5);
533 buf_prepend_uint32(&st->buffer,(uint32_t)st);
534 buf_prepend_uint32(&st->buffer,st->setup_session_id);
535
536 st->retries=st->setup_retries;
537 return True;
538}
539
2fe58dfd
SE
540static bool_t process_msg5(struct site *st, struct buffer_if *msg5,
541 struct sockaddr_in *src)
542{
543 struct msg0 m;
544 string_t transform_err;
545
546 if (!unpick_msg0(st,msg5,&m)) return False;
547
548 if (st->new_transform->reverse(st->new_transform->st,
549 msg5,&transform_err)) {
550 /* There's a problem */
59635212 551 slog(st,LOG_SEC,"process_msg5: transform: %s",transform_err);
2fe58dfd
SE
552 return False;
553 }
554 /* Buffer should now contain untransformed PING packet data */
555 CHECK_AVAIL(msg5,4);
59635212 556 if (buf_unprepend_uint32(msg5)!=LABEL_MSG5) {
ff05a229 557 slog(st,LOG_SEC,"MSG5/PING packet contained wrong label");
2fe58dfd
SE
558 return False;
559 }
794f2398
SE
560 if (!st->netlink->check_config(st->netlink->st,msg5)) {
561 slog(st,LOG_SEC,"MSG5/PING packet contained bad netlink config");
562 return False;
563 }
2fe58dfd
SE
564 CHECK_EMPTY(msg5);
565 return True;
566}
567
568static bool_t generate_msg6(struct site *st)
569{
570 string_t transform_err;
571
572 BUF_ALLOC(&st->buffer,"site:MSG6");
ff05a229
SE
573 /* We are going to add four words to the message */
574 buffer_init(&st->buffer,st->transform->max_start_pad+(4*4));
794f2398
SE
575 /* Give the netlink code an opportunity to put its own stuff in the
576 message (configuration information, etc.) */
577 st->netlink->output_config(st->netlink->st,&st->buffer);
ff05a229 578 buf_prepend_uint32(&st->buffer,LABEL_MSG6);
2fe58dfd
SE
579 st->new_transform->forwards(st->new_transform->st,&st->buffer,
580 &transform_err);
59635212
SE
581 buf_prepend_uint32(&st->buffer,LABEL_MSG6);
582 buf_prepend_uint32(&st->buffer,(uint32_t)st);
583 buf_prepend_uint32(&st->buffer,st->setup_session_id);
2fe58dfd 584
ff05a229 585 st->retries=1; /* Peer will retransmit MSG5 if this packet gets lost */
2fe58dfd
SE
586 return True;
587}
588
589static bool_t process_msg6(struct site *st, struct buffer_if *msg6,
590 struct sockaddr_in *src)
591{
592 struct msg0 m;
593 string_t transform_err;
594
595 if (!unpick_msg0(st,msg6,&m)) return False;
596
597 if (st->new_transform->reverse(st->new_transform->st,
598 msg6,&transform_err)) {
599 /* There's a problem */
59635212 600 slog(st,LOG_SEC,"process_msg6: transform: %s",transform_err);
2fe58dfd
SE
601 return False;
602 }
603 /* Buffer should now contain untransformed PING packet data */
604 CHECK_AVAIL(msg6,4);
59635212
SE
605 if (buf_unprepend_uint32(msg6)!=LABEL_MSG6) {
606 slog(st,LOG_SEC,"MSG6/PONG packet contained invalid data");
2fe58dfd
SE
607 return False;
608 }
794f2398
SE
609 if (!st->netlink->check_config(st->netlink->st,msg6)) {
610 slog(st,LOG_SEC,"MSG6/PONG packet contained bad netlink config");
611 return False;
612 }
2fe58dfd
SE
613 CHECK_EMPTY(msg6);
614 return True;
615}
616
617static bool_t process_msg0(struct site *st, struct buffer_if *msg0,
618 struct sockaddr_in *src)
619{
620 struct msg0 m;
621 string_t transform_err;
622 uint32_t type;
623
624 if (!st->current_valid) {
625 slog(st,LOG_DROP,"incoming message but no current key -> dropping");
794f2398 626 return initiate_key_setup(st,"incoming message but no current key");
2fe58dfd
SE
627 }
628
629 if (!unpick_msg0(st,msg0,&m)) return False;
630
631 if (st->current_transform->reverse(st->current_transform->st,
632 msg0,&transform_err)) {
633 /* There's a problem */
59635212 634 slog(st,LOG_SEC,"transform: %s",transform_err);
794f2398 635 return initiate_key_setup(st,"incoming message would not decrypt");
2fe58dfd
SE
636 }
637 CHECK_AVAIL(msg0,4);
59635212 638 type=buf_unprepend_uint32(msg0);
2fe58dfd 639 switch(type) {
794f2398
SE
640 case LABEL_MSG7:
641 /* We must forget about the current session. */
642 delete_key(st,"request from peer",LOG_SEC);
643 return True;
644 break;
2fe58dfd
SE
645 case LABEL_MSG9:
646 /* Deliver to netlink layer */
469fd1d9 647 st->netlink->deliver(st->netlink->st,msg0);
2fe58dfd
SE
648 return True;
649 break;
650 default:
ff05a229
SE
651 slog(st,LOG_SEC,"incoming encrypted message of type %08x "
652 "(unknown)",type);
2fe58dfd
SE
653 break;
654 }
655 return False;
656}
657
658static void dump_packet(struct site *st, struct buffer_if *buf,
659 struct sockaddr_in *addr, bool_t incoming)
660{
59635212
SE
661 uint32_t dest=ntohl(*(uint32_t *)buf->start);
662 uint32_t source=ntohl(*(uint32_t *)(buf->start+4));
663 uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
2fe58dfd
SE
664
665 if (st->log_events & LOG_DUMP)
b2a56f7c 666 log(st->log,M_DEBUG,"%s: %s: %08x<-%08x: %08x:",
9d3a4132 667 st->tunname,incoming?"incoming":"outgoing",
2fe58dfd
SE
668 dest,source,msgtype);
669}
670
671static uint32_t site_status(void *st)
672{
673 return 0;
674}
675
676static bool_t send_msg(struct site *st)
677{
678 if (st->retries>0) {
679 dump_packet(st,&st->buffer,&st->setup_peer,False);
680 st->comm->sendmsg(st->comm->st,&st->buffer,&st->setup_peer);
681 st->timeout=st->now+st->setup_timeout;
682 st->retries--;
683 return True;
684 } else {
3454dce4
SE
685 slog(st,LOG_SETUP_TIMEOUT,"timed out sending key setup packet "
686 "(in state %s)",state_name(st->state));
2fe58dfd
SE
687 enter_state_wait(st);
688 return False;
689 }
690}
691
692static void site_resolve_callback(void *sst, struct in_addr *address)
693{
694 struct site *st=sst;
695
696 if (st->state!=SITE_RESOLVE) {
697 slog(st,LOG_UNEXPECTED,"site_resolve_callback called unexpectedly");
698 return;
699 }
700 if (address) {
701 memset(&st->setup_peer,0,sizeof(st->setup_peer));
702 st->setup_peer.sin_family=AF_INET;
703 st->setup_peer.sin_port=htons(st->remoteport);
704 st->setup_peer.sin_addr=*address;
ff05a229 705 enter_new_state(st,SITE_SENTMSG1);
2fe58dfd
SE
706 } else {
707 /* Resolution failed */
708 slog(st,LOG_ERROR,"resolution of %s failed",st->address);
709 enter_state_run(st);
710 }
711}
712
794f2398 713static bool_t initiate_key_setup(struct site *st,string_t reason)
9d3a4132
SE
714{
715 if (st->state!=SITE_RUN) return False;
794f2398 716 slog(st,LOG_SETUP_INIT,"initiating key exchange (%s)",reason);
9d3a4132 717 if (st->address) {
794f2398 718 slog(st,LOG_SETUP_INIT,"resolving peer address");
9d3a4132
SE
719 return enter_state_resolve(st);
720 } else if (st->peer_valid) {
794f2398 721 slog(st,LOG_SETUP_INIT,"using old peer address");
9d3a4132 722 st->setup_peer=st->peer;
ff05a229 723 return enter_new_state(st,SITE_SENTMSG1);
9d3a4132 724 }
ff05a229 725 slog(st,LOG_SETUP_INIT,"key exchange failed: no address for peer");
9d3a4132
SE
726 return False;
727}
728
2fe58dfd
SE
729static void activate_new_key(struct site *st)
730{
731 struct transform_inst_if *t;
732
ff05a229
SE
733 /* We have two transform instances, which we swap between active
734 and setup */
2fe58dfd
SE
735 t=st->current_transform;
736 st->current_transform=st->new_transform;
737 st->new_transform=t;
738
739 t->delkey(t->st);
2fe58dfd
SE
740 st->timeout=0;
741 st->current_valid=True;
742 st->current_key_timeout=st->now+st->key_lifetime;
ff05a229 743 st->renegotiate_key_time=st->now+st->key_renegotiate_time;
2fe58dfd
SE
744 st->peer=st->setup_peer;
745 st->peer_valid=True;
746 st->remote_session_id=st->setup_session_id;
747
748 slog(st,LOG_ACTIVATE_KEY,"new key activated");
9d3a4132 749 enter_state_run(st);
2fe58dfd
SE
750}
751
794f2398
SE
752static void delete_key(struct site *st, string_t reason, uint32_t loglevel)
753{
754 if (st->current_valid) {
755 slog(st,loglevel,"session closed (%s)",reason);
756
757 st->current_valid=False;
758 st->current_transform->delkey(st->current_transform->st);
759 st->current_key_timeout=0;
760 set_link_quality(st);
761 }
762}
763
2fe58dfd
SE
764static void state_assert(struct site *st, bool_t ok)
765{
4f5e39ec 766 if (!ok) fatal("site:state_assert");
2fe58dfd
SE
767}
768
769static void enter_state_stop(struct site *st)
770{
771 st->state=SITE_STOP;
772 st->timeout=0;
794f2398 773 delete_key(st,"entering state STOP",LOG_TIMEOUT_KEY);
2fe58dfd
SE
774 st->new_transform->delkey(st->new_transform->st);
775}
776
9d3a4132
SE
777static void set_link_quality(struct site *st)
778{
779 uint32_t quality;
780 if (st->current_valid)
781 quality=LINK_QUALITY_UP;
782 else if (st->state==SITE_WAIT || st->state==SITE_STOP)
783 quality=LINK_QUALITY_DOWN;
784 else if (st->address)
785 quality=LINK_QUALITY_DOWN_CURRENT_ADDRESS;
786 else if (st->peer_valid)
787 quality=LINK_QUALITY_DOWN_STALE_ADDRESS;
788 else
789 quality=LINK_QUALITY_DOWN;
790
469fd1d9 791 st->netlink->set_quality(st->netlink->st,quality);
9d3a4132
SE
792}
793
2fe58dfd
SE
794static void enter_state_run(struct site *st)
795{
796 slog(st,LOG_STATE,"entering state RUN");
797 st->state=SITE_RUN;
798 st->timeout=0;
9d3a4132 799
ff05a229
SE
800 st->setup_session_id=0;
801 memset(&st->setup_peer,0,sizeof(st->setup_peer));
802 memset(st->localN,0,NONCELEN);
803 memset(st->remoteN,0,NONCELEN);
804 st->new_transform->delkey(st->new_transform->st);
805 memset(st->dhsecret,0,st->dh->len);
806 memset(st->sharedsecret,0,st->transform->keylen);
9d3a4132 807 set_link_quality(st);
2fe58dfd
SE
808}
809
810static bool_t enter_state_resolve(struct site *st)
811{
812 state_assert(st,st->state==SITE_RUN);
813 slog(st,LOG_STATE,"entering state RESOLVE");
814 st->state=SITE_RESOLVE;
815 st->resolver->request(st->resolver->st,st->address,
816 site_resolve_callback,st);
817 return True;
818}
819
ff05a229 820static bool_t enter_new_state(struct site *st, uint32_t next)
2fe58dfd 821{
ff05a229
SE
822 bool_t (*gen)(struct site *st);
823 slog(st,LOG_STATE,"entering state %s",state_name(next));
824 switch(next) {
825 case SITE_SENTMSG1:
826 state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE);
827 gen=generate_msg1;
828 break;
829 case SITE_SENTMSG2:
830 state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE ||
831 st->state==SITE_SENTMSG1 || st->state==SITE_WAIT);
832 gen=generate_msg2;
833 break;
834 case SITE_SENTMSG3:
835 state_assert(st,st->state==SITE_SENTMSG1);
836 BUF_FREE(&st->buffer);
837 gen=generate_msg3;
838 break;
839 case SITE_SENTMSG4:
840 state_assert(st,st->state==SITE_SENTMSG2);
841 BUF_FREE(&st->buffer);
842 gen=generate_msg4;
843 break;
844 case SITE_SENTMSG5:
845 state_assert(st,st->state==SITE_SENTMSG3);
846 BUF_FREE(&st->buffer);
847 gen=generate_msg5;
848 break;
849 case SITE_RUN:
850 state_assert(st,st->state==SITE_SENTMSG4);
851 BUF_FREE(&st->buffer);
852 gen=generate_msg6;
853 break;
854 default:
855 gen=NULL;
4f5e39ec 856 fatal("enter_new_state(%s): invalid new state",state_name(next));
ff05a229 857 break;
2fe58dfd 858 }
2fe58dfd 859
ff05a229
SE
860 if (gen(st) && send_msg(st)) {
861 st->state=next;
862 if (next==SITE_RUN) {
863 BUF_FREE(&st->buffer); /* Never reused */
864 st->timeout=0; /* Never retransmit */
865 activate_new_key(st);
866 }
2fe58dfd
SE
867 return True;
868 }
ff05a229
SE
869 slog(st,LOG_ERROR,"error entering state %s",state_name(next));
870 st->buffer.free=False; /* Unconditionally use the buffer; it may be
871 in either state, and enter_state_wait() will
872 do a BUF_FREE() */
2fe58dfd
SE
873 enter_state_wait(st);
874 return False;
875}
876
ff05a229 877/* msg7 tells our peer that we're about to forget our key */
794f2398
SE
878static bool_t send_msg7(struct site *st,string_t reason)
879{
880 string_t transform_err;
881
882 if (st->current_valid && st->peer_valid && st->buffer.free) {
883 BUF_ALLOC(&st->buffer,"site:MSG7");
884 buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
885 buf_append_uint32(&st->buffer,LABEL_MSG7);
886 buf_append_string(&st->buffer,reason);
887 st->current_transform->forwards(st->current_transform->st,
888 &st->buffer, &transform_err);
889 buf_prepend_uint32(&st->buffer,LABEL_MSG0);
890 buf_prepend_uint32(&st->buffer,(uint32_t)st);
891 buf_prepend_uint32(&st->buffer,st->remote_session_id);
892 st->comm->sendmsg(st->comm->st,&st->buffer,&st->peer);
893 BUF_FREE(&st->buffer);
894 return True;
895 }
896 return False;
897}
898
2fe58dfd
SE
899/* We go into this state if our peer becomes uncommunicative. Similar to
900 the "stop" state, we forget all session keys for a while, before
901 re-entering the "run" state. */
902static void enter_state_wait(struct site *st)
903{
904 slog(st,LOG_STATE,"entering state WAIT");
905 st->timeout=st->now+st->wait_timeout;
906 st->state=SITE_WAIT;
907 st->peer_valid=False;
9d3a4132 908 set_link_quality(st);
2fe58dfd
SE
909 BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
910 /* XXX Erase keys etc. */
911}
912
913static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
914 int *timeout_io, const struct timeval *tv_now,
915 uint64_t *now)
916{
917 struct site *st=sst;
918
919 *nfds_io=0; /* We don't use any file descriptors */
920 st->now=*now;
921
922 /* Work out when our next timeout is. The earlier of 'timeout' or
923 'current_key_timeout'. A stored value of '0' indicates no timeout
924 active. */
925 if (st->timeout && st->timeout-*now < *timeout_io) {
926 *timeout_io=st->timeout-*now;
927 }
928
929 if (st->current_key_timeout && st->current_key_timeout-*now < *timeout_io)
930 *timeout_io=st->current_key_timeout-*now;
931
932 return 0; /* success */
933}
934
935/* NB site_afterpoll will be called before site_beforepoll is ever called */
936static void site_afterpoll(void *sst, struct pollfd *fds, int nfds,
937 const struct timeval *tv_now, uint64_t *now)
938{
939 struct site *st=sst;
940
941 st->now=*now;
942 if (st->timeout && *now>st->timeout) {
2fe58dfd
SE
943 st->timeout=0;
944 if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5)
945 send_msg(st);
946 else if (st->state==SITE_WAIT) {
947 enter_state_run(st);
948 } else {
949 slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
950 st->state);
951 }
952 }
953 if (st->current_key_timeout && *now>st->current_key_timeout) {
794f2398 954 delete_key(st,"maximum key life exceeded",LOG_TIMEOUT_KEY);
2fe58dfd
SE
955 }
956}
957
958/* This function is called by the netlink device to deliver packets
959 intended for the remote network. The packet is in "raw" wire
960 format, but is guaranteed to be word-aligned. */
469fd1d9 961static void site_outgoing(void *sst, struct buffer_if *buf)
2fe58dfd
SE
962{
963 struct site *st=sst;
964 string_t transform_err;
965
966 if (st->state==SITE_STOP) {
967 BUF_FREE(buf);
968 return;
969 }
970
971 /* In all other states we consider delivering the packet if we have
972 a valid key and a valid address to send it to. */
973 if (st->current_valid && st->peer_valid) {
974 /* Transform it and send it */
70dc107b
SE
975 if (buf->size>0) {
976 buf_prepend_uint32(buf,LABEL_MSG9);
977 st->current_transform->forwards(st->current_transform->st,
978 buf, &transform_err);
979 buf_prepend_uint32(buf,LABEL_MSG0);
980 buf_prepend_uint32(buf,(uint32_t)st);
981 buf_prepend_uint32(buf,st->remote_session_id);
982 st->comm->sendmsg(st->comm->st,buf,&st->peer);
983 }
2fe58dfd 984 BUF_FREE(buf);
ff05a229
SE
985 /* See whether we should start negotiating a new key */
986 if (st->now > st->renegotiate_key_time)
987 initiate_key_setup(st,"outgoing packet in renegotiation window");
2fe58dfd
SE
988 return;
989 }
990
70dc107b 991 slog(st,LOG_DROP,"discarding outgoing packet of size %d",buf->size);
2fe58dfd 992 BUF_FREE(buf);
794f2398 993 initiate_key_setup(st,"outgoing packet");
2fe58dfd
SE
994}
995
996/* This function is called by the communication device to deliver
997 packets from our peers. */
998static bool_t site_incoming(void *sst, struct buffer_if *buf,
999 struct sockaddr_in *source)
1000{
1001 struct site *st=sst;
59635212 1002 uint32_t dest=ntohl(*(uint32_t *)buf->start);
2fe58dfd
SE
1003
1004 if (dest==0) {
2fe58dfd
SE
1005 /* It could be for any site - it should have LABEL_MSG1 and
1006 might have our name and our peer's name in it */
ff05a229 1007 if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
2fe58dfd 1008 if (memcmp(buf->start+8,st->setupsig,st->setupsiglen)==0) {
2fe58dfd 1009 /* It's addressed to us. Decide what to do about it. */
ff05a229 1010 dump_packet(st,buf,source,True);
2fe58dfd
SE
1011 if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
1012 st->state==SITE_WAIT) {
1013 /* We should definitely process it */
1014 if (process_msg1(st,buf,source)) {
1015 slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
ff05a229 1016 enter_new_state(st,SITE_SENTMSG2);
2fe58dfd
SE
1017 } else {
1018 slog(st,LOG_ERROR,"failed to process incoming msg1");
1019 }
1020 BUF_FREE(buf);
1021 return True;
ff05a229 1022 } else if (st->state==SITE_SENTMSG1) {
2fe58dfd
SE
1023 /* We've just sent a message 1! They may have crossed on
1024 the wire. If we have priority then we ignore the
1025 incoming one, otherwise we process it as usual. */
1026 if (st->setup_priority) {
1027 BUF_FREE(buf);
1028 slog(st,LOG_DUMP,"crossed msg1s; we are higher "
1029 "priority => ignore incoming msg1");
1030 return True;
1031 } else {
1032 slog(st,LOG_DUMP,"crossed msg1s; we are lower "
1033 "priority => use incoming msg1");
1034 if (process_msg1(st,buf,source)) {
1035 BUF_FREE(&st->buffer); /* Free our old message 1 */
ff05a229 1036 enter_new_state(st,SITE_SENTMSG2);
2fe58dfd
SE
1037 } else {
1038 slog(st,LOG_ERROR,"failed to process an incoming "
1039 "crossed msg1 (we have low priority)");
1040 }
1041 BUF_FREE(buf);
1042 return True;
1043 }
1044 }
1045 /* The message 1 was received at an unexpected stage of the
1046 key setup. XXX POLICY - what do we do? */
1047 slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
1048 BUF_FREE(buf);
1049 return True;
1050 }
1051 return False; /* Not for us. */
1052 }
1053 if (dest==(uint32_t)st) {
2fe58dfd 1054 /* Explicitly addressed to us */
ff05a229 1055 uint32_t msgtype=ntohl(get_uint32(buf->start+8));
2fe58dfd
SE
1056 if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
1057 switch (msgtype) {
794f2398
SE
1058 case 0: /* NAK */
1059 /* If the source is our current peer then initiate a key setup,
1060 because our peer's forgotten the key */
1061 if (get_uint32(buf->start+4)==st->remote_session_id) {
1062 initiate_key_setup(st,"received a NAK");
1063 } else {
1064 slog(st,LOG_SEC,"bad incoming NAK");
1065 }
1066 break;
2fe58dfd
SE
1067 case LABEL_MSG0:
1068 process_msg0(st,buf,source);
1069 break;
1070 case LABEL_MSG1:
1071 /* Setup packet: should not have been explicitly addressed
1072 to us */
59635212 1073 slog(st,LOG_SEC,"incoming explicitly addressed msg1");
2fe58dfd
SE
1074 break;
1075 case LABEL_MSG2:
1076 /* Setup packet: expected only in state SENTMSG1 */
1077 if (st->state!=SITE_SENTMSG1) {
1078 slog(st,LOG_UNEXPECTED,"unexpected MSG2");
1079 } else if (process_msg2(st,buf,source))
ff05a229 1080 enter_new_state(st,SITE_SENTMSG3);
2fe58dfd 1081 else {
59635212 1082 slog(st,LOG_SEC,"invalid MSG2");
2fe58dfd
SE
1083 }
1084 break;
1085 case LABEL_MSG3:
1086 /* Setup packet: expected only in state SENTMSG2 */
1087 if (st->state!=SITE_SENTMSG2) {
1088 slog(st,LOG_UNEXPECTED,"unexpected MSG3");
1089 } else if (process_msg3(st,buf,source))
ff05a229 1090 enter_new_state(st,SITE_SENTMSG4);
2fe58dfd 1091 else {
59635212 1092 slog(st,LOG_SEC,"invalid MSG3");
2fe58dfd
SE
1093 }
1094 break;
1095 case LABEL_MSG4:
1096 /* Setup packet: expected only in state SENTMSG3 */
1097 if (st->state!=SITE_SENTMSG3) {
1098 slog(st,LOG_UNEXPECTED,"unexpected MSG4");
1099 } else if (process_msg4(st,buf,source))
ff05a229 1100 enter_new_state(st,SITE_SENTMSG5);
2fe58dfd 1101 else {
59635212 1102 slog(st,LOG_SEC,"invalid MSG4");
2fe58dfd
SE
1103 }
1104 break;
1105 case LABEL_MSG5:
4efd681a
SE
1106 /* Setup packet: expected only in state SENTMSG4 */
1107 /* (may turn up in state RUN if our return MSG6 was lost
1108 and the new key has already been activated. In that
1109 case we should treat it as an ordinary PING packet. We
1110 can't pass it to process_msg5() because the
ff05a229 1111 new_transform will now be unkeyed. XXX) */
4efd681a 1112 if (st->state!=SITE_SENTMSG4) {
2fe58dfd
SE
1113 slog(st,LOG_UNEXPECTED,"unexpected MSG5");
1114 } else if (process_msg5(st,buf,source)) {
ff05a229 1115 enter_new_state(st,SITE_RUN);
2fe58dfd 1116 } else {
59635212 1117 slog(st,LOG_SEC,"invalid MSG5");
2fe58dfd
SE
1118 }
1119 break;
1120 case LABEL_MSG6:
1121 /* Setup packet: expected only in state SENTMSG5 */
1122 if (st->state!=SITE_SENTMSG5) {
1123 slog(st,LOG_UNEXPECTED,"unexpected MSG6");
1124 } else if (process_msg6(st,buf,source)) {
1125 BUF_FREE(&st->buffer); /* Free message 5 */
1126 activate_new_key(st);
1127 } else {
59635212 1128 slog(st,LOG_SEC,"invalid MSG6");
2fe58dfd
SE
1129 }
1130 break;
2fe58dfd 1131 default:
59635212 1132 slog(st,LOG_SEC,"received message of unknown type 0x%08x",
2fe58dfd
SE
1133 msgtype);
1134 break;
1135 }
1136 BUF_FREE(buf);
1137 return True;
1138 }
1139
1140 return False;
1141}
1142
1143static void site_control(void *vst, bool_t run)
1144{
1145 struct site *st=vst;
1146 if (run) enter_state_run(st);
1147 else enter_state_stop(st);
1148}
1149
794f2398
SE
1150static void site_phase_hook(void *sst, uint32_t newphase)
1151{
1152 struct site *st=sst;
1153
1154 /* The program is shutting down; tell our peer */
1155 send_msg7(st,"shutting down");
1156}
1157
2fe58dfd
SE
1158static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
1159 list_t *args)
1160{
1161 struct site *st;
1162 item_t *item;
1163 dict_t *dict;
1164
1165 st=safe_malloc(sizeof(*st),"site_apply");
1166
1167 st->cl.description="site";
1168 st->cl.type=CL_SITE;
1169 st->cl.apply=NULL;
1170 st->cl.interface=&st->ops;
1171 st->ops.st=st;
1172 st->ops.control=site_control;
1173 st->ops.status=site_status;
1174
1175 /* First parameter must be a dict */
1176 item=list_elem(args,0);
1177 if (!item || item->type!=t_dict)
1178 cfgfatal(loc,"site","parameter must be a dictionary\n");
1179
1180 dict=item->data.dict;
558fa3fb
SE
1181 st->localname=dict_read_string(dict, "local-name", True, "site", loc);
1182 st->remotename=dict_read_string(dict, "name", True, "site", loc);
1183 /* Sanity check (which also allows the 'sites' file to include
1184 site() closures for all sites including our own): refuse to
1185 talk to ourselves */
1186 if (strcmp(st->localname,st->remotename)==0) {
b2a56f7c 1187 Message(M_DEBUG,"site %s: local-name==name -> ignoring this site\n",
baa06aeb 1188 st->localname);
558fa3fb
SE
1189 free(st);
1190 return NULL;
1191 }
469fd1d9 1192 st->netlink=find_cl_if(dict,"link",CL_NETLINK,True,"site",loc);
2fe58dfd
SE
1193 st->comm=find_cl_if(dict,"comm",CL_COMM,True,"site",loc);
1194 st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
1195 st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
1196 st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
1197
2fe58dfd 1198 st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
2fe58dfd 1199 st->address=dict_read_string(dict, "address", False, "site", loc);
3454dce4
SE
1200 if (st->address)
1201 st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
1202 else st->remoteport=0;
2fe58dfd
SE
1203 st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
1204
1205 st->transform=
1206 find_cl_if(dict,"transform",CL_TRANSFORM,True,"site",loc);
1207
1208 st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc);
1209 st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
1210
9d3a4132
SE
1211 st->key_lifetime=dict_read_number(
1212 dict,"key-lifetime",False,"site",loc,DEFAULT_KEY_LIFETIME);
1213 if (st->key_lifetime < DEFAULT_KEY_RENEGOTIATE_GAP)
1214 st->key_renegotiate_time=st->key_lifetime/2;
1215 else
1216 st->key_renegotiate_time=st->key_lifetime-DEFAULT_KEY_RENEGOTIATE_GAP;
1217 st->setup_retries=dict_read_number(
1218 dict,"setup-retries",False,"site",loc,DEFAULT_SETUP_RETRIES);
1219 st->setup_timeout=dict_read_number(
1220 dict,"setup-timeout",False,"site",loc,DEFAULT_SETUP_TIMEOUT);
1221 st->wait_timeout=dict_read_number(
1222 dict,"wait-time",False,"site",loc,DEFAULT_WAIT_TIME);
1223 st->key_renegotiate_time=dict_read_number(
1224 dict,"renegotiate-time",False,"site",loc,st->key_lifetime);
1225 if (st->key_renegotiate_time > st->key_lifetime) {
1226 cfgfatal(loc,"site",
1227 "renegotiate-time must be less than key-lifetime\n");
1228 }
9d3a4132
SE
1229 st->keepalive=dict_read_bool(dict,"keepalive",False,"site",loc,False);
1230
1231 st->log_events=string_list_to_word(dict_lookup(dict,"log-events"),
1232 log_event_table,"site");
2fe58dfd 1233
4efd681a
SE
1234 st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
1235 "site_apply");
1236 sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
1237
2fe58dfd
SE
1238 /* The information we expect to see in incoming messages of type 1 */
1239 st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
1240 st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
8689b3a9
SE
1241 put_uint32(st->setupsig+0,LABEL_MSG1);
1242 put_uint16(st->setupsig+4,strlen(st->remotename));
2fe58dfd 1243 memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
8689b3a9 1244 put_uint16(st->setupsig+(6+strlen(st->remotename)),strlen(st->localname));
2fe58dfd
SE
1245 memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
1246 strlen(st->localname));
1247 st->setup_priority=(strcmp(st->localname,st->remotename)>0);
1248
1249 buffer_new(&st->buffer,SETUP_BUFFER_LEN);
1250
1251 /* We are interested in poll(), but only for timeouts. We don't have
1252 any fds of our own. */
1253 register_for_poll(st, site_beforepoll, site_afterpoll, 0, "site");
1254 st->timeout=0;
1255
1256 st->current_valid=False;
1257 st->current_key_timeout=0;
1258 st->peer_valid=False;
1259 /* XXX mlock these */
1260 st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
1261 st->sharedsecret=safe_malloc(st->transform->keylen,"site:sharedsecret");
1262
1263 /* We need to register the remote networks with the netlink device */
469fd1d9 1264 st->netlink->reg(st->netlink->st, site_outgoing, st,
ff05a229
SE
1265 st->transform->max_start_pad+(4*4)+
1266 st->comm->min_start_pad,
1267 st->transform->max_end_pad+st->comm->min_end_pad);
1268
2fe58dfd
SE
1269 st->comm->request_notify(st->comm->st, st, site_incoming);
1270
1271 st->current_transform=st->transform->create(st->transform->st);
1272 st->new_transform=st->transform->create(st->transform->st);
1273
1274 enter_state_stop(st);
1275
794f2398
SE
1276 add_hook(PHASE_SHUTDOWN,site_phase_hook,st);
1277
2fe58dfd
SE
1278 return new_closure(&st->cl);
1279}
1280
1281init_module site_module;
1282void site_module(dict_t *dict)
1283{
1284 add_closure(dict,"site",site_apply);
1285}