Import release 0.08
[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;
4efd681a 707 st->netlink->set_delivery(st->netlink->st,st->netlink_cid,True);
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;
4efd681a 824 st->netlink->set_delivery(st->netlink->st,st->netlink_cid,False);
2fe58dfd
SE
825 BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
826 /* XXX Erase keys etc. */
827}
828
829static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
830 int *timeout_io, const struct timeval *tv_now,
831 uint64_t *now)
832{
833 struct site *st=sst;
834
835 *nfds_io=0; /* We don't use any file descriptors */
836 st->now=*now;
837
838 /* Work out when our next timeout is. The earlier of 'timeout' or
839 'current_key_timeout'. A stored value of '0' indicates no timeout
840 active. */
841 if (st->timeout && st->timeout-*now < *timeout_io) {
842 *timeout_io=st->timeout-*now;
843 }
844
845 if (st->current_key_timeout && st->current_key_timeout-*now < *timeout_io)
846 *timeout_io=st->current_key_timeout-*now;
847
848 return 0; /* success */
849}
850
851/* NB site_afterpoll will be called before site_beforepoll is ever called */
852static void site_afterpoll(void *sst, struct pollfd *fds, int nfds,
853 const struct timeval *tv_now, uint64_t *now)
854{
855 struct site *st=sst;
856
857 st->now=*now;
858 if (st->timeout && *now>st->timeout) {
859 /* Do stuff */
860 st->timeout=0;
861 if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5)
862 send_msg(st);
863 else if (st->state==SITE_WAIT) {
864 enter_state_run(st);
865 } else {
866 slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
867 st->state);
868 }
869 }
870 if (st->current_key_timeout && *now>st->current_key_timeout) {
871 slog(st,LOG_TIMEOUT_KEY,"maximum key life exceeded; session closed");
872 st->current_valid=False;
873 st->current_transform->delkey(st->current_transform->st);
874 st->current_key_timeout=0;
875 }
876}
877
878/* This function is called by the netlink device to deliver packets
879 intended for the remote network. The packet is in "raw" wire
880 format, but is guaranteed to be word-aligned. */
881static void site_outgoing(void *sst, void *cid, struct buffer_if *buf)
882{
883 struct site *st=sst;
884 string_t transform_err;
885
886 if (st->state==SITE_STOP) {
887 BUF_FREE(buf);
888 return;
889 }
890
891 /* In all other states we consider delivering the packet if we have
892 a valid key and a valid address to send it to. */
893 if (st->current_valid && st->peer_valid) {
894 /* Transform it and send it */
59635212 895 buf_prepend_uint32(buf,LABEL_MSG9);
2fe58dfd
SE
896 st->current_transform->forwards(st->current_transform->st,
897 buf, &transform_err);
59635212
SE
898 buf_prepend_uint32(buf,LABEL_MSG0);
899 buf_prepend_uint32(buf,(uint32_t)st);
900 buf_prepend_uint32(buf,st->remote_session_id);
2fe58dfd
SE
901 st->comm->sendmsg(st->comm->st,buf,&st->peer);
902 BUF_FREE(buf);
903 return;
904 }
905
906 if (st->state==SITE_RUN) {
907 BUF_FREE(buf); /* We throw the outgoing packet away */
908 slog(st,LOG_SETUP_INIT,"initiating key exchange");
909 enter_state_resolve(st);
910 return;
911 }
912
913 /* Otherwise we're in the middle of key setup or a wait - just
914 throw the outgoing packet away */
915 slog(st,LOG_DROP,"discarding outgoing packet");
916 BUF_FREE(buf);
917 return;
918}
919
920/* This function is called by the communication device to deliver
921 packets from our peers. */
922static bool_t site_incoming(void *sst, struct buffer_if *buf,
923 struct sockaddr_in *source)
924{
925 struct site *st=sst;
59635212 926 uint32_t dest=ntohl(*(uint32_t *)buf->start);
2fe58dfd
SE
927
928 if (dest==0) {
929 if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
930 /* It could be for any site - it should have LABEL_MSG1 and
931 might have our name and our peer's name in it */
932 if (memcmp(buf->start+8,st->setupsig,st->setupsiglen)==0) {
933 dump_packet(st,buf,source,True);
934 /* It's addressed to us. Decide what to do about it. */
935 if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
936 st->state==SITE_WAIT) {
937 /* We should definitely process it */
938 if (process_msg1(st,buf,source)) {
939 slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
940 enter_state_sentmsg2(st);
941 } else {
942 slog(st,LOG_ERROR,"failed to process incoming msg1");
943 }
944 BUF_FREE(buf);
945 return True;
946 }
947 if (st->state==SITE_SENTMSG1) {
948 /* We've just sent a message 1! They may have crossed on
949 the wire. If we have priority then we ignore the
950 incoming one, otherwise we process it as usual. */
951 if (st->setup_priority) {
952 BUF_FREE(buf);
953 slog(st,LOG_DUMP,"crossed msg1s; we are higher "
954 "priority => ignore incoming msg1");
955 return True;
956 } else {
957 slog(st,LOG_DUMP,"crossed msg1s; we are lower "
958 "priority => use incoming msg1");
959 if (process_msg1(st,buf,source)) {
960 BUF_FREE(&st->buffer); /* Free our old message 1 */
961 enter_state_sentmsg2(st);
962 } else {
963 slog(st,LOG_ERROR,"failed to process an incoming "
964 "crossed msg1 (we have low priority)");
965 }
966 BUF_FREE(buf);
967 return True;
968 }
969 }
970 /* The message 1 was received at an unexpected stage of the
971 key setup. XXX POLICY - what do we do? */
972 slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
973 BUF_FREE(buf);
974 return True;
975 }
976 return False; /* Not for us. */
977 }
978 if (dest==(uint32_t)st) {
59635212 979 uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
2fe58dfd
SE
980 /* Explicitly addressed to us */
981 if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
982 switch (msgtype) {
983 case LABEL_MSG0:
984 process_msg0(st,buf,source);
985 break;
986 case LABEL_MSG1:
987 /* Setup packet: should not have been explicitly addressed
988 to us */
59635212 989 slog(st,LOG_SEC,"incoming explicitly addressed msg1");
2fe58dfd
SE
990 break;
991 case LABEL_MSG2:
992 /* Setup packet: expected only in state SENTMSG1 */
993 if (st->state!=SITE_SENTMSG1) {
994 slog(st,LOG_UNEXPECTED,"unexpected MSG2");
995 } else if (process_msg2(st,buf,source))
996 enter_state_sentmsg3(st);
997 else {
59635212 998 slog(st,LOG_SEC,"invalid MSG2");
2fe58dfd
SE
999 }
1000 break;
1001 case LABEL_MSG3:
1002 /* Setup packet: expected only in state SENTMSG2 */
1003 if (st->state!=SITE_SENTMSG2) {
1004 slog(st,LOG_UNEXPECTED,"unexpected MSG3");
1005 } else if (process_msg3(st,buf,source))
1006 enter_state_sentmsg4(st);
1007 else {
59635212 1008 slog(st,LOG_SEC,"invalid MSG3");
2fe58dfd
SE
1009 }
1010 break;
1011 case LABEL_MSG4:
1012 /* Setup packet: expected only in state SENTMSG3 */
1013 if (st->state!=SITE_SENTMSG3) {
1014 slog(st,LOG_UNEXPECTED,"unexpected MSG4");
1015 } else if (process_msg4(st,buf,source))
1016 enter_state_sentmsg5(st);
1017 else {
59635212 1018 slog(st,LOG_SEC,"invalid MSG4");
2fe58dfd
SE
1019 }
1020 break;
1021 case LABEL_MSG5:
4efd681a
SE
1022 /* Setup packet: expected only in state SENTMSG4 */
1023 /* (may turn up in state RUN if our return MSG6 was lost
1024 and the new key has already been activated. In that
1025 case we should treat it as an ordinary PING packet. We
1026 can't pass it to process_msg5() because the
1027 new_transform will now be null. XXX) */
1028 if (st->state!=SITE_SENTMSG4) {
2fe58dfd
SE
1029 slog(st,LOG_UNEXPECTED,"unexpected MSG5");
1030 } else if (process_msg5(st,buf,source)) {
1031 send_msg6(st);
1032 } else {
59635212 1033 slog(st,LOG_SEC,"invalid MSG5");
2fe58dfd
SE
1034 }
1035 break;
1036 case LABEL_MSG6:
1037 /* Setup packet: expected only in state SENTMSG5 */
1038 if (st->state!=SITE_SENTMSG5) {
1039 slog(st,LOG_UNEXPECTED,"unexpected MSG6");
1040 } else if (process_msg6(st,buf,source)) {
1041 BUF_FREE(&st->buffer); /* Free message 5 */
1042 activate_new_key(st);
1043 } else {
59635212 1044 slog(st,LOG_SEC,"invalid MSG6");
2fe58dfd
SE
1045 }
1046 break;
1047 case LABEL_MSG8:
1048 /* NAK packet: enter state where we ping and check for response */
1049 slog(st,LOG_ERROR,"received a NAK");
1050 break;
1051 default:
59635212 1052 slog(st,LOG_SEC,"received message of unknown type 0x%08x",
2fe58dfd
SE
1053 msgtype);
1054 break;
1055 }
1056 BUF_FREE(buf);
1057 return True;
1058 }
1059
1060 return False;
1061}
1062
1063static void site_control(void *vst, bool_t run)
1064{
1065 struct site *st=vst;
1066 if (run) enter_state_run(st);
1067 else enter_state_stop(st);
1068}
1069
1070static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
1071 list_t *args)
1072{
1073 struct site *st;
1074 item_t *item;
1075 dict_t *dict;
1076
1077 st=safe_malloc(sizeof(*st),"site_apply");
1078
1079 st->cl.description="site";
1080 st->cl.type=CL_SITE;
1081 st->cl.apply=NULL;
1082 st->cl.interface=&st->ops;
1083 st->ops.st=st;
1084 st->ops.control=site_control;
1085 st->ops.status=site_status;
1086
1087 /* First parameter must be a dict */
1088 item=list_elem(args,0);
1089 if (!item || item->type!=t_dict)
1090 cfgfatal(loc,"site","parameter must be a dictionary\n");
1091
1092 dict=item->data.dict;
1093 st->netlink=find_cl_if(dict,"netlink",CL_NETLINK,True,"site",loc);
1094 st->comm=find_cl_if(dict,"comm",CL_COMM,True,"site",loc);
1095 st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
1096 st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
1097 st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
1098
1099 st->localname=dict_read_string(dict, "local-name", True, "site", loc);
1100 st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
1101 st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
1102
1103 st->remotename=dict_read_string(dict, "name", True, "site", loc);
1104 st->address=dict_read_string(dict, "address", False, "site", loc);
1105 dict_read_subnet_list(dict, "networks", True, "site", loc,
1106 &st->remotenets);
1107 st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
1108
1109 st->transform=
1110 find_cl_if(dict,"transform",CL_TRANSFORM,True,"site",loc);
1111
1112 st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc);
1113 st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
1114
1115 st->key_lifetime=dict_read_number(dict,"key-lifetime",
1116 False,"site",loc,DEFAULT_KEY_LIFETIME);
1117 st->setup_retries=dict_read_number(dict,"setup-retries",
1118 False,"site",loc,DEFAULT_SETUP_RETRIES);
1119 st->setup_timeout=dict_read_number(dict,"setup-timeout",
1120 False,"site",loc,DEFAULT_SETUP_TIMEOUT);
1121 st->wait_timeout=dict_read_number(dict,"wait-time",
1122 False,"site",loc,DEFAULT_WAIT_TIME);
1123 /* XXX should be configurable */
59635212 1124 st->log_events=LOG_SEC|LOG_ERROR|
2fe58dfd
SE
1125 LOG_ACTIVATE_KEY|LOG_TIMEOUT_KEY|LOG_SETUP_INIT|LOG_SETUP_TIMEOUT;
1126
4efd681a
SE
1127 st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
1128 "site_apply");
1129 sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
1130
2fe58dfd 1131 /* The information we expect to see in incoming messages of type 1 */
59635212 1132 /* XXX fix this bit for unaligned access */
2fe58dfd
SE
1133 st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
1134 st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
8689b3a9
SE
1135 put_uint32(st->setupsig+0,LABEL_MSG1);
1136 put_uint16(st->setupsig+4,strlen(st->remotename));
2fe58dfd 1137 memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
8689b3a9 1138 put_uint16(st->setupsig+(6+strlen(st->remotename)),strlen(st->localname));
2fe58dfd
SE
1139 memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
1140 strlen(st->localname));
1141 st->setup_priority=(strcmp(st->localname,st->remotename)>0);
1142
1143 buffer_new(&st->buffer,SETUP_BUFFER_LEN);
1144
1145 /* We are interested in poll(), but only for timeouts. We don't have
1146 any fds of our own. */
1147 register_for_poll(st, site_beforepoll, site_afterpoll, 0, "site");
1148 st->timeout=0;
1149
1150 st->current_valid=False;
1151 st->current_key_timeout=0;
1152 st->peer_valid=False;
1153 /* XXX mlock these */
1154 st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
1155 st->sharedsecret=safe_malloc(st->transform->keylen,"site:sharedsecret");
1156
1157 /* We need to register the remote networks with the netlink device */
1158 st->netlink_cid=st->netlink->regnets(st->netlink->st, &st->remotenets,
1159 site_outgoing, st,
1160 st->transform->max_start_pad+(4*4),
4efd681a
SE
1161 st->transform->max_end_pad,
1162 st->tunname);
2fe58dfd
SE
1163
1164 st->comm->request_notify(st->comm->st, st, site_incoming);
1165
1166 st->current_transform=st->transform->create(st->transform->st);
1167 st->new_transform=st->transform->create(st->transform->st);
1168
1169 enter_state_stop(st);
1170
1171 return new_closure(&st->cl);
1172}
1173
1174init_module site_module;
1175void site_module(dict_t *dict)
1176{
1177 add_closure(dict,"site",site_apply);
1178}