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