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