chiark / gitweb /
Import release 0.04
[secnet.git] / site.c
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
63 static 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
103 struct site {
104     closure_t cl;
105     struct site_if ops;
106 /* configuration information */
107     string_t localname;
108     string_t remotename;
109     string_t tunname; /* localname<->remotename by default */
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
162 static 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);
171         st->log->log(st->log->st,0,"%s: %s",st->tunname,buf);
172     }
173     va_end(ap);
174 }
175
176 static void enter_state_run(struct site *st);
177 static bool_t enter_state_resolve(struct site *st);
178 static bool_t enter_state_sentmsg1(struct site *st);
179 static bool_t enter_state_sentmsg2(struct site *st);
180 static bool_t enter_state_sentmsg3(struct site *st);
181 static bool_t enter_state_sentmsg4(struct site *st);
182 static bool_t enter_state_sentmsg5(struct site *st);
183 static 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
192 struct 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. */
211 static 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
242 static 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
284 static 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
290 static 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
309 static 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
315 static 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
341 static 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
349 static 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
404 static 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
411 static 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
462 static 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
480 struct msg0 {
481     uint32_t dest;
482     uint32_t source;
483     uint32_t type;
484 };
485
486 static 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
499 static 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
523 static 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
541 static 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
565 static 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
605 static 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
618 static uint32_t site_status(void *st)
619 {
620     return 0;
621 }
622
623 static 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
638 static 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
659 static 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
679 static void state_assert(struct site *st, bool_t ok)
680 {
681     if (!ok) fatal("state_assert\n");
682 }
683
684 static 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
697 static 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;
702     st->netlink->set_delivery(st->netlink->st,st->netlink_cid,True);
703     /* XXX get rid of key setup data */
704 }
705
706 static 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
716 static 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
731 static 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
746 static 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
761 static 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
776 static 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
793 static 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. */
813 static 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;
819     st->netlink->set_delivery(st->netlink->st,st->netlink_cid,False);
820     BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
821     /* XXX Erase keys etc. */
822 }
823
824 static 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 */
847 static 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. */
876 static 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. */
917 static 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:
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) {
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
1058 static 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
1065 static 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
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
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),
1156                                          st->transform->max_end_pad,
1157                                          st->tunname);
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
1169 init_module site_module;
1170 void site_module(dict_t *dict)
1171 {
1172     add_closure(dict,"site",site_apply);
1173 }