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