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