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