chiark / gitweb /
Import release 0.03
[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 address; /* DNS name for bootstrapping, optional */
110     int remoteport;
111     struct netlink_if *netlink;
112     struct comm_if *comm;
113     struct resolver_if *resolver;
114     struct log_if *log;
115     struct random_if *random;
116     struct rsaprivkey_if *privkey;
117     struct subnet_list remotenets;
118     struct rsapubkey_if *pubkey;
119     struct transform_if *transform;
120     struct dh_if *dh;
121     struct hash_if *hash;
122     void *netlink_cid;
123
124     uint32_t setup_retries; /* How many times to send setup packets */
125     uint32_t setup_timeout; /* Initial timeout for setup packets */
126     uint32_t wait_timeout; /* How long to wait if setup unsuccessful */
127     uint32_t key_lifetime; /* How long a key lasts once set up */
128
129     uint8_t *setupsig; /* Expected signature of incoming MSG1 packets */
130     uint32_t setupsiglen; /* Allows us to discard packets quickly if
131                              they are not for us */
132     bool_t setup_priority; /* Do we have precedence if both sites emit
133                               message 1 simultaneously? */
134     uint32_t log_events;
135
136 /* runtime information */
137     uint32_t state;
138     uint64_t now; /* Most recently seen time */
139
140     uint32_t remote_session_id;
141     struct transform_inst_if *current_transform;
142     bool_t current_valid;
143     uint64_t current_key_timeout; /* End of life of current key */
144     struct sockaddr_in peer; /* Current address of peer */
145     bool_t peer_valid; /* Peer address becomes invalid when key times out,
146                           but only if we have a DNS name for our peer */
147
148     uint32_t setup_session_id;
149     struct sockaddr_in setup_peer;
150     uint8_t localN[NONCELEN]; /* Nonces for key exchange */
151     uint8_t remoteN[NONCELEN];
152     struct buffer_if buffer; /* Current outgoing key exchange packet */
153     uint32_t retries; /* Number of retries remaining */
154     uint64_t timeout; /* Timeout for current state */
155     uint8_t *dhsecret;
156     uint8_t *sharedsecret;
157
158     struct transform_inst_if *new_transform; /* For key setup/verify */
159 };
160
161 static void slog(struct site *st, uint32_t event, string_t msg, ...)
162 {
163     va_list ap;
164     uint8_t buf[240];
165
166     va_start(ap,msg);
167
168     if (event&st->log_events) {
169         vsnprintf(buf,240,msg,ap);
170         st->log->log(st->log->st,0,"%s<->%s: %s",st->localname,st->remotename,
171                      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     /* XXX get rid of key setup data */
703 }
704
705 static bool_t enter_state_resolve(struct site *st)
706 {
707     state_assert(st,st->state==SITE_RUN);
708     slog(st,LOG_STATE,"entering state RESOLVE");
709     st->state=SITE_RESOLVE;
710     st->resolver->request(st->resolver->st,st->address,
711                           site_resolve_callback,st);
712     return True;
713 }
714
715 static bool_t enter_state_sentmsg1(struct site *st)
716 {
717     state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE);
718     slog(st,LOG_STATE,"entering state SENTMSG1");
719     if (generate_msg1(st) && send_msg(st)) {
720         st->state=SITE_SENTMSG1;
721         return True;
722     }
723     slog(st,LOG_ERROR,"error entering state SENTMSG1");
724     st->buffer.free=False; /* Can't tell which it was, but enter_state_wait()
725                               will do a BUF_FREE() */
726     enter_state_wait(st);
727     return False;
728 }
729
730 static bool_t enter_state_sentmsg2(struct site *st)
731 {
732     state_assert(st,st->state==SITE_RUN || st->state==SITE_RESOLVE ||
733                  st->state==SITE_SENTMSG1 || st->state==SITE_WAIT);
734     slog(st,LOG_STATE,"entering state SENTMSG2");
735     if (generate_msg2(st) && send_msg(st)) {
736         st->state=SITE_SENTMSG2;
737         return True;
738     }
739     slog(st,LOG_ERROR,"error entering state SENTMSG2");
740     st->buffer.free=False;
741     enter_state_wait(st);
742     return False;
743 }
744
745 static bool_t enter_state_sentmsg3(struct site *st)
746 {
747     state_assert(st,st->state==SITE_SENTMSG1);
748     slog(st,LOG_STATE,"entering state SENTMSG3");
749     BUF_FREE(&st->buffer); /* Free message 1 */
750     if (generate_msg3(st) && send_msg(st)) {
751         st->state=SITE_SENTMSG3;
752         return True;
753     }
754     slog(st,LOG_ERROR,"error entering state SENTMSG3");
755     st->buffer.free=False;
756     enter_state_wait(st);
757     return False;
758 }
759
760 static bool_t enter_state_sentmsg4(struct site *st)
761 {
762     state_assert(st,st->state==SITE_SENTMSG2);
763     slog(st,LOG_STATE,"entering state SENTMSG4");
764     BUF_FREE(&st->buffer); /* Free message 2 */
765     if (generate_msg4(st) && send_msg(st)) {
766         st->state=SITE_SENTMSG4;
767         return True;
768     }
769     slog(st,LOG_ERROR,"error entering state SENTMSG4");
770     st->buffer.free=False;
771     enter_state_wait(st);
772     return False;
773 }
774
775 static bool_t enter_state_sentmsg5(struct site *st)
776 {
777     state_assert(st,st->state==SITE_SENTMSG3);
778     slog(st,LOG_STATE,"entering state SENTMSG5");
779     BUF_FREE(&st->buffer); /* Free message 3 */
780
781     if (generate_msg5(st) && send_msg(st)) {
782         st->state=SITE_SENTMSG5;
783         return True;
784     }
785     slog(st,LOG_ERROR,"error entering state SENTMSG5");
786     st->buffer.free=False;
787     enter_state_wait(st);
788     
789     return False;
790 }
791
792 static bool_t send_msg6(struct site *st)
793 {
794     state_assert(st,st->state==SITE_SENTMSG4);
795     slog(st,LOG_STATE,"entering state RUN after sending msg6");
796     BUF_FREE(&st->buffer); /* Free message 4 */
797     if (generate_msg6(st) && send_msg(st)) {
798         BUF_FREE(&st->buffer); /* Never reused */
799         st->timeout=0; /* Never retransmit */
800         activate_new_key(st);
801         return True;
802     }
803     slog(st,LOG_ERROR,"error entering state RUN after sending msg6");
804     st->buffer.free=False;
805     enter_state_wait(st);
806     return False;
807 }
808
809 /* We go into this state if our peer becomes uncommunicative. Similar to
810    the "stop" state, we forget all session keys for a while, before
811    re-entering the "run" state. */
812 static void enter_state_wait(struct site *st)
813 {
814     slog(st,LOG_STATE,"entering state WAIT");
815     st->timeout=st->now+st->wait_timeout;
816     st->state=SITE_WAIT;
817     st->peer_valid=False;
818     BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
819     /* XXX Erase keys etc. */
820 }
821
822 static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
823                            int *timeout_io, const struct timeval *tv_now,
824                            uint64_t *now)
825 {
826     struct site *st=sst;
827
828     *nfds_io=0; /* We don't use any file descriptors */
829     st->now=*now;
830
831     /* Work out when our next timeout is. The earlier of 'timeout' or
832        'current_key_timeout'. A stored value of '0' indicates no timeout
833        active. */
834     if (st->timeout && st->timeout-*now < *timeout_io) {
835         *timeout_io=st->timeout-*now;
836     }
837
838     if (st->current_key_timeout && st->current_key_timeout-*now < *timeout_io)
839         *timeout_io=st->current_key_timeout-*now;
840
841     return 0; /* success */
842 }
843
844 /* NB site_afterpoll will be called before site_beforepoll is ever called */
845 static void site_afterpoll(void *sst, struct pollfd *fds, int nfds,
846                            const struct timeval *tv_now, uint64_t *now)
847 {
848     struct site *st=sst;
849
850     st->now=*now;
851     if (st->timeout && *now>st->timeout) {
852         /* Do stuff */
853         st->timeout=0;
854         if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5)
855             send_msg(st);
856         else if (st->state==SITE_WAIT) {
857             enter_state_run(st);
858         } else {
859             slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
860                  st->state);
861         }
862     }
863     if (st->current_key_timeout && *now>st->current_key_timeout) {
864         slog(st,LOG_TIMEOUT_KEY,"maximum key life exceeded; session closed");
865         st->current_valid=False;
866         st->current_transform->delkey(st->current_transform->st);
867         st->current_key_timeout=0;
868     }
869 }
870
871 /* This function is called by the netlink device to deliver packets
872    intended for the remote network. The packet is in "raw" wire
873    format, but is guaranteed to be word-aligned. */
874 static void site_outgoing(void *sst, void *cid, struct buffer_if *buf)
875 {
876     struct site *st=sst;
877     string_t transform_err;
878     
879     if (st->state==SITE_STOP) {
880         BUF_FREE(buf);
881         return;
882     }
883
884     /* In all other states we consider delivering the packet if we have
885        a valid key and a valid address to send it to. */
886     if (st->current_valid && st->peer_valid) {
887         /* Transform it and send it */
888         *(uint32_t *)buf_prepend(buf,4)=LABEL_MSG9;
889         st->current_transform->forwards(st->current_transform->st,
890                                         buf, &transform_err);
891         *(uint32_t *)buf_prepend(buf,4)=LABEL_MSG0;
892         *(uint32_t *)buf_prepend(buf,4)=(uint32_t)st;
893         *(uint32_t *)buf_prepend(buf,4)=st->remote_session_id;
894         st->comm->sendmsg(st->comm->st,buf,&st->peer);
895         BUF_FREE(buf);
896         return;
897     }
898
899     if (st->state==SITE_RUN) {
900         BUF_FREE(buf); /* We throw the outgoing packet away */
901         slog(st,LOG_SETUP_INIT,"initiating key exchange");
902         enter_state_resolve(st);
903         return;
904     }
905
906     /* Otherwise we're in the middle of key setup or a wait - just
907        throw the outgoing packet away */
908     slog(st,LOG_DROP,"discarding outgoing packet");
909     BUF_FREE(buf);
910     return;
911 }
912
913 /* This function is called by the communication device to deliver
914    packets from our peers. */
915 static bool_t site_incoming(void *sst, struct buffer_if *buf,
916                             struct sockaddr_in *source)
917 {
918     struct site *st=sst;
919     uint32_t dest=*(uint32_t *)buf->start;
920
921     if (dest==0) {
922         if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
923         /* It could be for any site - it should have LABEL_MSG1 and
924            might have our name and our peer's name in it */
925         if (memcmp(buf->start+8,st->setupsig,st->setupsiglen)==0) {
926             dump_packet(st,buf,source,True);
927             /* It's addressed to us. Decide what to do about it. */
928             if (st->state==SITE_RUN || st->state==SITE_RESOLVE ||
929                 st->state==SITE_WAIT) {
930                 /* We should definitely process it */
931                 if (process_msg1(st,buf,source)) {
932                     slog(st,LOG_SETUP_INIT,"key setup initiated by peer");
933                     enter_state_sentmsg2(st);
934                 } else {
935                     slog(st,LOG_ERROR,"failed to process incoming msg1");
936                 }
937                 BUF_FREE(buf);
938                 return True;
939             }
940             if (st->state==SITE_SENTMSG1) {
941                 /* We've just sent a message 1! They may have crossed on
942                    the wire. If we have priority then we ignore the
943                    incoming one, otherwise we process it as usual. */
944                 if (st->setup_priority) {
945                     BUF_FREE(buf);
946                     slog(st,LOG_DUMP,"crossed msg1s; we are higher "
947                          "priority => ignore incoming msg1");
948                     return True;
949                 } else {
950                     slog(st,LOG_DUMP,"crossed msg1s; we are lower "
951                          "priority => use incoming msg1");
952                     if (process_msg1(st,buf,source)) {
953                         BUF_FREE(&st->buffer); /* Free our old message 1 */
954                         enter_state_sentmsg2(st);
955                     } else {
956                         slog(st,LOG_ERROR,"failed to process an incoming "
957                              "crossed msg1 (we have low priority)");
958                     }
959                     BUF_FREE(buf);
960                     return True;
961                 }
962             }
963             /* The message 1 was received at an unexpected stage of the
964                key setup. XXX POLICY - what do we do? */
965             slog(st,LOG_UNEXPECTED,"unexpected incoming message 1");
966             BUF_FREE(buf);
967             return True;
968         }
969         return False; /* Not for us. */
970     }
971     if (dest==(uint32_t)st) {
972         uint32_t msgtype=*(uint32_t *)(buf->start+8);
973         /* Explicitly addressed to us */
974         if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
975         switch (msgtype) {
976         case LABEL_MSG0:
977             process_msg0(st,buf,source);
978             break;
979         case LABEL_MSG1:
980             /* Setup packet: should not have been explicitly addressed
981                to us */
982             slog(st,LOG_SECURITY,"incoming explicitly addressed msg1");
983             break;
984         case LABEL_MSG2:
985             /* Setup packet: expected only in state SENTMSG1 */
986             if (st->state!=SITE_SENTMSG1) {
987                 slog(st,LOG_UNEXPECTED,"unexpected MSG2");
988             } else if (process_msg2(st,buf,source))
989                 enter_state_sentmsg3(st);
990             else {
991                 slog(st,LOG_SECURITY,"invalid MSG2");
992             }
993             break;
994         case LABEL_MSG3:
995             /* Setup packet: expected only in state SENTMSG2 */
996             if (st->state!=SITE_SENTMSG2) {
997                 slog(st,LOG_UNEXPECTED,"unexpected MSG3");
998             } else if (process_msg3(st,buf,source))
999                 enter_state_sentmsg4(st);
1000             else {
1001                 slog(st,LOG_SECURITY,"invalid MSG3");
1002             }
1003             break;
1004         case LABEL_MSG4:
1005             /* Setup packet: expected only in state SENTMSG3 */
1006             if (st->state!=SITE_SENTMSG3) {
1007                 slog(st,LOG_UNEXPECTED,"unexpected MSG4");
1008             } else if (process_msg4(st,buf,source))
1009                 enter_state_sentmsg5(st);
1010             else {
1011                 slog(st,LOG_SECURITY,"invalid MSG4");
1012             }
1013             break;
1014         case LABEL_MSG5:
1015             /* Setup packet: expected only in state SENTMSG4 or RUN */
1016             if (st->state!=SITE_SENTMSG4 && st->state!=SITE_RUN) {
1017                 slog(st,LOG_UNEXPECTED,"unexpected MSG5");
1018             } else if (process_msg5(st,buf,source)) {
1019                 send_msg6(st);
1020             } else {
1021                 slog(st,LOG_SECURITY,"invalid MSG5");
1022             }
1023             break;
1024         case LABEL_MSG6:
1025             /* Setup packet: expected only in state SENTMSG5 */
1026             if (st->state!=SITE_SENTMSG5) {
1027                 slog(st,LOG_UNEXPECTED,"unexpected MSG6");
1028             } else if (process_msg6(st,buf,source)) {
1029                 BUF_FREE(&st->buffer); /* Free message 5 */
1030                 activate_new_key(st);
1031             } else {
1032                 slog(st,LOG_SECURITY,"invalid MSG6");
1033             }
1034             break;
1035         case LABEL_MSG8:
1036             /* NAK packet: enter state where we ping and check for response */
1037             slog(st,LOG_ERROR,"received a NAK");
1038             break;
1039         default:
1040             slog(st,LOG_SECURITY,"received message of unknown type 0x%08x",
1041                  msgtype);
1042             break;
1043         }
1044         BUF_FREE(buf);
1045         return True;
1046     }
1047
1048     return False;
1049 }
1050
1051 static void site_control(void *vst, bool_t run)
1052 {
1053     struct site *st=vst;
1054     if (run) enter_state_run(st);
1055     else enter_state_stop(st);
1056 }
1057
1058 static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
1059                           list_t *args)
1060 {
1061     struct site *st;
1062     item_t *item;
1063     dict_t *dict;
1064
1065     st=safe_malloc(sizeof(*st),"site_apply");
1066
1067     st->cl.description="site";
1068     st->cl.type=CL_SITE;
1069     st->cl.apply=NULL;
1070     st->cl.interface=&st->ops;
1071     st->ops.st=st;
1072     st->ops.control=site_control;
1073     st->ops.status=site_status;
1074
1075     /* First parameter must be a dict */
1076     item=list_elem(args,0);
1077     if (!item || item->type!=t_dict)
1078         cfgfatal(loc,"site","parameter must be a dictionary\n");
1079     
1080     dict=item->data.dict;
1081     st->netlink=find_cl_if(dict,"netlink",CL_NETLINK,True,"site",loc);
1082     st->comm=find_cl_if(dict,"comm",CL_COMM,True,"site",loc);
1083     st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
1084     st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
1085     st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
1086
1087     st->localname=dict_read_string(dict, "local-name", True, "site", loc);
1088     st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
1089     st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
1090
1091     st->remotename=dict_read_string(dict, "name", True, "site", loc);
1092     st->address=dict_read_string(dict, "address", False, "site", loc);
1093     dict_read_subnet_list(dict, "networks", True, "site", loc,
1094                           &st->remotenets);
1095     st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
1096
1097     st->transform=
1098         find_cl_if(dict,"transform",CL_TRANSFORM,True,"site",loc);
1099
1100     st->dh=find_cl_if(dict,"dh",CL_DH,True,"site",loc);
1101     st->hash=find_cl_if(dict,"hash",CL_HASH,True,"site",loc);
1102
1103     st->key_lifetime=dict_read_number(dict,"key-lifetime",
1104                                       False,"site",loc,DEFAULT_KEY_LIFETIME);
1105     st->setup_retries=dict_read_number(dict,"setup-retries",
1106                                        False,"site",loc,DEFAULT_SETUP_RETRIES);
1107     st->setup_timeout=dict_read_number(dict,"setup-timeout",
1108                                        False,"site",loc,DEFAULT_SETUP_TIMEOUT);
1109     st->wait_timeout=dict_read_number(dict,"wait-time",
1110                                       False,"site",loc,DEFAULT_WAIT_TIME);
1111     /* XXX should be configurable */
1112     st->log_events=LOG_SECURITY|LOG_ERROR|
1113         LOG_ACTIVATE_KEY|LOG_TIMEOUT_KEY|LOG_SETUP_INIT|LOG_SETUP_TIMEOUT;
1114
1115     /* The information we expect to see in incoming messages of type 1 */
1116     st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
1117     st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
1118     *(uint32_t *)&(st->setupsig[0])=LABEL_MSG1;
1119     *(uint16_t *)&(st->setupsig[4])=htons(strlen(st->remotename));
1120     memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
1121     *(uint16_t *)&(st->setupsig[6+strlen(st->remotename)])=
1122         htons(strlen(st->localname));
1123     memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
1124            strlen(st->localname));
1125     st->setup_priority=(strcmp(st->localname,st->remotename)>0);
1126
1127     buffer_new(&st->buffer,SETUP_BUFFER_LEN);
1128
1129     /* We are interested in poll(), but only for timeouts. We don't have
1130        any fds of our own. */
1131     register_for_poll(st, site_beforepoll, site_afterpoll, 0, "site");
1132     st->timeout=0;
1133
1134     st->current_valid=False;
1135     st->current_key_timeout=0;
1136     st->peer_valid=False;
1137     /* XXX mlock these */
1138     st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
1139     st->sharedsecret=safe_malloc(st->transform->keylen,"site:sharedsecret");
1140
1141     /* We need to register the remote networks with the netlink device */
1142     st->netlink_cid=st->netlink->regnets(st->netlink->st, &st->remotenets,
1143                                          site_outgoing, st,
1144                                          st->transform->max_start_pad+(4*4),
1145                                          st->transform->max_end_pad);
1146
1147     st->comm->request_notify(st->comm->st, st, site_incoming);
1148
1149     st->current_transform=st->transform->create(st->transform->st);
1150     st->new_transform=st->transform->create(st->transform->st);
1151
1152     enter_state_stop(st);
1153
1154     return new_closure(&st->cl);
1155 }
1156
1157 init_module site_module;
1158 void site_module(dict_t *dict)
1159 {
1160     add_closure(dict,"site",site_apply);
1161 }