]>
Commit | Line | Data |
---|---|---|
997358a6 MW |
1 | /* information about connections between hosts and clients |
2 | * Copyright (C) 1998-2002 D. Hugh Redelmeier. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms of the GNU General Public License as published by the | |
6 | * Free Software Foundation; either version 2 of the License, or (at your | |
7 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, but | |
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 | * for more details. | |
13 | * | |
9820c0e2 | 14 | * RCSID $Id: connections.c,v 1.43 2006/04/29 18:16:02 as Exp $ |
997358a6 MW |
15 | */ |
16 | ||
17 | #include <string.h> | |
18 | #include <stdio.h> | |
19 | #include <stddef.h> | |
20 | #include <stdlib.h> | |
21 | #include <unistd.h> | |
22 | #include <netinet/in.h> | |
23 | #include <sys/socket.h> | |
24 | #include <sys/stat.h> | |
25 | #include <netinet/in.h> | |
26 | #include <arpa/inet.h> | |
27 | #include <resolv.h> | |
28 | #include <arpa/nameser.h> /* missing from <resolv.h> on old systems */ | |
29 | #include <sys/queue.h> | |
30 | ||
31 | #include <freeswan.h> | |
32 | #include <freeswan/ipsec_policy.h> | |
33 | #include "kameipsec.h" | |
34 | ||
35 | #include "constants.h" | |
36 | #include "defs.h" | |
37 | #include "id.h" | |
38 | #include "x509.h" | |
39 | #include "ca.h" | |
40 | #include "crl.h" | |
41 | #include "pgp.h" | |
42 | #include "certs.h" | |
43 | #include "ac.h" | |
44 | #include "smartcard.h" | |
45 | #include "fetch.h" | |
46 | #include "connections.h" | |
47 | #include "foodgroups.h" | |
48 | #include "demux.h" | |
49 | #include "state.h" | |
50 | #include "timer.h" | |
51 | #include "ipsec_doi.h" /* needs demux.h and state.h */ | |
52 | #include "server.h" | |
53 | #include "kernel.h" | |
54 | #include "log.h" | |
55 | #include "keys.h" | |
56 | #include "adns.h" /* needs <resolv.h> */ | |
57 | #include "dnskey.h" /* needs keys.h and adns.h */ | |
58 | #include "whack.h" | |
59 | #include "alg_info.h" | |
60 | #include "ike_alg.h" | |
61 | #include "kernel_alg.h" | |
62 | #ifdef NAT_TRAVERSAL | |
63 | #include "nat_traversal.h" | |
64 | #endif | |
65 | ||
66 | #ifdef VIRTUAL_IP | |
67 | #include "virtual.h" | |
68 | #endif | |
69 | ||
70 | static void flush_pending_by_connection(struct connection *c); /* forward */ | |
71 | ||
72 | static struct connection *connections = NULL; | |
73 | ||
74 | /* struct host_pair: a nexus of information about a pair of hosts. | |
75 | * A host is an IP address, UDP port pair. This is a debatable choice: | |
76 | * - should port be considered (no choice of port in standard)? | |
77 | * - should ID be considered (hard because not always known)? | |
78 | * - should IP address matter on our end (we don't know our end)? | |
79 | * Only oriented connections are registered. | |
80 | * Unoriented connections are kept on the unoriented_connections | |
81 | * linked list (using hp_next). For them, host_pair is NULL. | |
82 | */ | |
83 | ||
84 | struct host_pair { | |
85 | struct { | |
86 | ip_address addr; | |
87 | u_int16_t port; /* host order */ | |
88 | } me, him; | |
89 | bool initial_connection_sent; | |
90 | struct connection *connections; /* connections with this pair */ | |
91 | struct pending *pending; /* awaiting Keying Channel */ | |
92 | struct host_pair *next; | |
93 | }; | |
94 | ||
95 | static struct host_pair *host_pairs = NULL; | |
96 | ||
97 | static struct connection *unoriented_connections = NULL; | |
98 | ||
99 | /* check to see that Ids of peers match */ | |
100 | bool | |
101 | same_peer_ids(const struct connection *c, const struct connection *d | |
102 | , const struct id *his_id) | |
103 | { | |
104 | return same_id(&c->spd.this.id, &d->spd.this.id) | |
105 | && same_id(his_id == NULL? &c->spd.that.id : his_id, &d->spd.that.id); | |
106 | } | |
107 | ||
108 | static struct host_pair * | |
109 | find_host_pair(const ip_address *myaddr, u_int16_t myport | |
110 | , const ip_address *hisaddr, u_int16_t hisport) | |
111 | { | |
112 | struct host_pair *p, *prev; | |
113 | ||
114 | /* default hisaddr to an appropriate any */ | |
115 | if (hisaddr == NULL) | |
116 | hisaddr = aftoinfo(addrtypeof(myaddr))->any; | |
117 | ||
118 | #ifdef NAT_TRAVERSAL | |
119 | if (nat_traversal_enabled) { | |
120 | /** | |
121 | * port is not relevant in host_pair. with nat_traversal we | |
122 | * always use pluto_port (500) | |
123 | */ | |
124 | myport = pluto_port; | |
125 | hisport = pluto_port; | |
126 | } | |
127 | #endif | |
128 | ||
129 | for (prev = NULL, p = host_pairs; p != NULL; prev = p, p = p->next) | |
130 | { | |
131 | if (sameaddr(&p->me.addr, myaddr) && p->me.port == myport | |
132 | && sameaddr(&p->him.addr, hisaddr) && p->him.port == hisport) | |
133 | { | |
134 | if (prev != NULL) | |
135 | { | |
136 | prev->next = p->next; /* remove p from list */ | |
137 | p->next = host_pairs; /* and stick it on front */ | |
138 | host_pairs = p; | |
139 | } | |
140 | break; | |
141 | } | |
142 | } | |
143 | return p; | |
144 | } | |
145 | ||
146 | /* find head of list of connections with this pair of hosts */ | |
147 | static struct connection * | |
148 | find_host_pair_connections(const ip_address *myaddr, u_int16_t myport | |
149 | , const ip_address *hisaddr, u_int16_t hisport) | |
150 | { | |
151 | struct host_pair *hp = find_host_pair(myaddr, myport, hisaddr, hisport); | |
152 | ||
153 | #ifdef NAT_TRAVERSAL | |
154 | if (nat_traversal_enabled && hp && hisaddr) { | |
155 | struct connection *c; | |
156 | for (c = hp->connections; c != NULL; c = c->hp_next) { | |
157 | if ((c->spd.this.host_port==myport) && (c->spd.that.host_port==hisport)) | |
158 | return c; | |
159 | } | |
160 | return NULL; | |
161 | } | |
162 | #endif | |
163 | ||
164 | return hp == NULL? NULL : hp->connections; | |
165 | } | |
166 | ||
167 | static void | |
168 | connect_to_host_pair(struct connection *c) | |
169 | { | |
170 | if (oriented(*c)) | |
171 | { | |
172 | struct host_pair *hp = find_host_pair(&c->spd.this.host_addr, c->spd.this.host_port | |
173 | , &c->spd.that.host_addr, c->spd.that.host_port); | |
174 | ||
175 | if (hp == NULL) | |
176 | { | |
177 | /* no suitable host_pair -- build one */ | |
178 | hp = alloc_thing(struct host_pair, "host_pair"); | |
179 | hp->me.addr = c->spd.this.host_addr; | |
180 | hp->him.addr = c->spd.that.host_addr; | |
181 | #ifdef NAT_TRAVERSAL | |
182 | hp->me.port = nat_traversal_enabled ? pluto_port : c->spd.this.host_port; | |
183 | hp->him.port = nat_traversal_enabled ? pluto_port : c->spd.that.host_port; | |
184 | #else | |
185 | hp->me.port = c->spd.this.host_port; | |
186 | hp->him.port = c->spd.that.host_port; | |
187 | #endif | |
188 | hp->initial_connection_sent = FALSE; | |
189 | hp->connections = NULL; | |
190 | hp->pending = NULL; | |
191 | hp->next = host_pairs; | |
192 | host_pairs = hp; | |
193 | } | |
194 | c->host_pair = hp; | |
195 | c->hp_next = hp->connections; | |
196 | hp->connections = c; | |
197 | } | |
198 | else | |
199 | { | |
200 | /* since this connection isn't oriented, we place it | |
201 | * in the unoriented_connections list instead. | |
202 | */ | |
203 | c->host_pair = NULL; | |
204 | c->hp_next = unoriented_connections; | |
205 | unoriented_connections = c; | |
206 | } | |
207 | } | |
208 | ||
209 | /* find a connection by name. | |
210 | * If strict, don't accept a CK_INSTANCE. | |
211 | * Move the winner (if any) to the front. | |
212 | * If none is found, and strict, a diagnostic is logged to whack. | |
213 | */ | |
214 | struct connection * | |
215 | con_by_name(const char *nm, bool strict) | |
216 | { | |
217 | struct connection *p, *prev; | |
218 | ||
219 | for (prev = NULL, p = connections; ; prev = p, p = p->ac_next) | |
220 | { | |
221 | if (p == NULL) | |
222 | { | |
223 | if (strict) | |
224 | whack_log(RC_UNKNOWN_NAME | |
225 | , "no connection named \"%s\"", nm); | |
226 | break; | |
227 | } | |
228 | if (streq(p->name, nm) | |
229 | && (!strict || p->kind != CK_INSTANCE)) | |
230 | { | |
231 | if (prev != NULL) | |
232 | { | |
233 | prev->ac_next = p->ac_next; /* remove p from list */ | |
234 | p->ac_next = connections; /* and stick it on front */ | |
235 | connections = p; | |
236 | } | |
237 | break; | |
238 | } | |
239 | } | |
240 | return p; | |
241 | } | |
242 | ||
243 | void | |
244 | release_connection(struct connection *c, bool relations) | |
245 | { | |
246 | if (c->kind == CK_INSTANCE) | |
247 | { | |
248 | /* This does everything we need. | |
249 | * Note that we will be called recursively by delete_connection, | |
250 | * but kind will be CK_GOING_AWAY. | |
251 | */ | |
252 | delete_connection(c, relations); | |
253 | } | |
254 | else | |
255 | { | |
256 | flush_pending_by_connection(c); | |
257 | delete_states_by_connection(c, relations); | |
258 | unroute_connection(c); | |
259 | } | |
260 | } | |
261 | ||
262 | /* Delete a connection */ | |
263 | ||
264 | #define list_rm(etype, enext, e, ehead) { \ | |
265 | etype **ep; \ | |
266 | for (ep = &(ehead); *ep != (e); ep = &(*ep)->enext) \ | |
267 | passert(*ep != NULL); /* we must not come up empty-handed */ \ | |
268 | *ep = (e)->enext; \ | |
269 | } | |
270 | ||
271 | ||
272 | void | |
273 | delete_connection(struct connection *c, bool relations) | |
274 | { | |
275 | struct connection *old_cur_connection | |
276 | = cur_connection == c? NULL : cur_connection; | |
277 | #ifdef DEBUG | |
278 | lset_t old_cur_debugging = cur_debugging; | |
279 | #endif | |
280 | ||
281 | set_cur_connection(c); | |
282 | ||
283 | /* Must be careful to avoid circularity: | |
284 | * we mark c as going away so it won't get deleted recursively. | |
285 | */ | |
286 | passert(c->kind != CK_GOING_AWAY); | |
287 | if (c->kind == CK_INSTANCE) | |
288 | { | |
289 | plog("deleting connection \"%s\" instance with peer %s {isakmp=#%lu/ipsec=#%lu}" | |
290 | , c->name | |
291 | , ip_str(&c->spd.that.host_addr) | |
292 | , c->newest_isakmp_sa, c->newest_ipsec_sa); | |
293 | c->kind = CK_GOING_AWAY; | |
294 | } | |
295 | else | |
296 | { | |
297 | plog("deleting connection"); | |
298 | } | |
299 | release_connection(c, relations); /* won't delete c */ | |
300 | ||
301 | if (c->kind == CK_GROUP) | |
302 | delete_group(c); | |
303 | ||
304 | /* free up any logging resources */ | |
305 | perpeer_logfree(c); | |
306 | ||
307 | /* find and delete c from connections list */ | |
308 | list_rm(struct connection, ac_next, c, connections); | |
309 | cur_connection = old_cur_connection; | |
310 | ||
311 | /* find and delete c from the host pair list */ | |
312 | if (c->host_pair == NULL) | |
313 | { | |
314 | list_rm(struct connection, hp_next, c, unoriented_connections); | |
315 | } | |
316 | else | |
317 | { | |
318 | struct host_pair *hp = c->host_pair; | |
319 | ||
320 | list_rm(struct connection, hp_next, c, hp->connections); | |
321 | c->host_pair = NULL; /* redundant, but safe */ | |
322 | ||
323 | /* if there are no more connections with this host_pair | |
324 | * and we haven't even made an initial contact, let's delete | |
325 | * this guy in case we were created by an attempted DOS attack. | |
326 | */ | |
327 | if (hp->connections == NULL | |
328 | && !hp->initial_connection_sent) | |
329 | { | |
330 | passert(hp->pending == NULL); /* ??? must deal with this! */ | |
331 | list_rm(struct host_pair, next, hp, host_pairs); | |
332 | pfree(hp); | |
333 | } | |
334 | } | |
335 | ||
336 | #ifdef VIRTUAL_IP | |
337 | if (c->kind != CK_GOING_AWAY) pfreeany(c->spd.that.virt); | |
338 | #endif | |
339 | ||
340 | #ifdef DEBUG | |
341 | cur_debugging = old_cur_debugging; | |
342 | #endif | |
343 | pfreeany(c->name); | |
344 | free_id_content(&c->spd.this.id); | |
345 | pfreeany(c->spd.this.updown); | |
346 | freeanychunk(c->spd.this.ca); | |
347 | free_ietfAttrList(c->spd.this.groups); | |
348 | free_id_content(&c->spd.that.id); | |
349 | pfreeany(c->spd.that.updown); | |
350 | freeanychunk(c->spd.that.ca); | |
351 | free_ietfAttrList(c->spd.that.groups); | |
352 | free_generalNames(c->requested_ca, TRUE); | |
353 | gw_delref(&c->gw_info); | |
354 | ||
355 | lock_certs_and_keys("delete_connection"); | |
356 | release_cert(c->spd.this.cert); | |
357 | scx_release(c->spd.this.sc); | |
358 | release_cert(c->spd.that.cert); | |
359 | scx_release(c->spd.that.sc); | |
360 | unlock_certs_and_keys("delete_connection"); | |
361 | ||
362 | alg_info_delref((struct alg_info **)&c->alg_info_esp); | |
363 | alg_info_delref((struct alg_info **)&c->alg_info_ike); | |
364 | ||
365 | pfree(c); | |
366 | } | |
367 | ||
368 | /* Delete connections with the specified name */ | |
369 | void | |
370 | delete_connections_by_name(const char *name, bool strict) | |
371 | { | |
372 | struct connection *c = con_by_name(name, strict); | |
373 | ||
374 | for (; c != NULL; c = con_by_name(name, FALSE)) | |
375 | delete_connection(c, FALSE); | |
376 | } | |
377 | ||
378 | void | |
379 | delete_every_connection(void) | |
380 | { | |
381 | while (connections != NULL) | |
382 | delete_connection(connections, TRUE); | |
383 | } | |
384 | ||
385 | void | |
386 | release_dead_interfaces(void) | |
387 | { | |
388 | struct host_pair *hp; | |
389 | ||
390 | for (hp = host_pairs; hp != NULL; hp = hp->next) | |
391 | { | |
392 | struct connection **pp | |
393 | , *p; | |
394 | ||
395 | for (pp = &hp->connections; (p = *pp) != NULL; ) | |
396 | { | |
397 | if (p->interface->change == IFN_DELETE) | |
398 | { | |
399 | /* this connection's interface is going away */ | |
400 | enum connection_kind k = p->kind; | |
401 | ||
402 | release_connection(p, TRUE); | |
403 | ||
404 | if (k <= CK_PERMANENT) | |
405 | { | |
406 | /* The connection should have survived release: | |
407 | * move it to the unoriented_connections list. | |
408 | */ | |
409 | passert(p == *pp); | |
410 | ||
411 | p->interface = NULL; | |
412 | ||
413 | *pp = p->hp_next; /* advance *pp */ | |
414 | p->host_pair = NULL; | |
415 | p->hp_next = unoriented_connections; | |
416 | unoriented_connections = p; | |
417 | } | |
418 | else | |
419 | { | |
420 | /* The connection should have vanished, | |
421 | * but the previous connection remains. | |
422 | */ | |
423 | passert(p != *pp); | |
424 | } | |
425 | } | |
426 | else | |
427 | { | |
428 | pp = &p->hp_next; /* advance pp */ | |
429 | } | |
430 | } | |
431 | } | |
432 | } | |
433 | ||
434 | /* adjust orientations of connections to reflect newly added interfaces */ | |
435 | void | |
436 | check_orientations(void) | |
437 | { | |
438 | /* try to orient all the unoriented connections */ | |
439 | { | |
440 | struct connection *c = unoriented_connections; | |
441 | ||
442 | unoriented_connections = NULL; | |
443 | ||
444 | while (c != NULL) | |
445 | { | |
446 | struct connection *nxt = c->hp_next; | |
447 | ||
448 | (void)orient(c); | |
449 | connect_to_host_pair(c); | |
450 | c = nxt; | |
451 | } | |
452 | } | |
453 | ||
454 | /* Check that no oriented connection has become double-oriented. | |
455 | * In other words, the far side must not match one of our new interfaces. | |
456 | */ | |
457 | { | |
458 | struct iface *i; | |
459 | ||
460 | for (i = interfaces; i != NULL; i = i->next) | |
461 | { | |
462 | if (i->change == IFN_ADD) | |
463 | { | |
464 | struct host_pair *hp; | |
465 | ||
466 | for (hp = host_pairs; hp != NULL; hp = hp->next) | |
467 | { | |
468 | if (sameaddr(&hp->him.addr, &i->addr) | |
469 | && (!no_klips || hp->him.port == pluto_port)) | |
470 | { | |
471 | /* bad news: the whole chain of connections | |
472 | * hanging off this host pair has both sides | |
473 | * matching an interface. | |
474 | * We'll get rid of them, using orient and | |
475 | * connect_to_host_pair. But we'll be lazy | |
476 | * and not ditch the host_pair itself (the | |
477 | * cost of leaving it is slight and cannot | |
478 | * be induced by a foe). | |
479 | */ | |
480 | struct connection *c = hp->connections; | |
481 | ||
482 | hp->connections = NULL; | |
483 | while (c != NULL) | |
484 | { | |
485 | struct connection *nxt = c->hp_next; | |
486 | ||
487 | c->interface = NULL; | |
488 | (void)orient(c); | |
489 | connect_to_host_pair(c); | |
490 | c = nxt; | |
491 | } | |
492 | } | |
493 | } | |
494 | } | |
495 | } | |
496 | } | |
497 | } | |
498 | ||
499 | static err_t | |
500 | default_end(struct end *e, ip_address *dflt_nexthop) | |
501 | { | |
502 | err_t ugh = NULL; | |
503 | const struct af_info *afi = aftoinfo(addrtypeof(&e->host_addr)); | |
504 | ||
505 | if (afi == NULL) | |
506 | return "unknown address family in default_end"; | |
507 | ||
508 | /* default ID to IP (but only if not NO_IP -- WildCard) */ | |
509 | if (e->id.kind == ID_NONE && !isanyaddr(&e->host_addr)) | |
510 | { | |
511 | e->id.kind = afi->id_addr; | |
512 | e->id.ip_addr = e->host_addr; | |
513 | e->has_id_wildcards = FALSE; | |
514 | } | |
515 | ||
516 | /* default nexthop to other side */ | |
517 | if (isanyaddr(&e->host_nexthop)) | |
518 | e->host_nexthop = *dflt_nexthop; | |
519 | ||
520 | /* default client to subnet containing only self | |
521 | * XXX This may mean that the client's address family doesn't match | |
522 | * tunnel_addr_family. | |
523 | */ | |
524 | if (!e->has_client) | |
525 | ugh = addrtosubnet(&e->host_addr, &e->client); | |
526 | ||
527 | return ugh; | |
528 | } | |
529 | ||
530 | /* Format the topology of a connection end, leaving out defaults. | |
531 | * Largest left end looks like: client === host : port [ host_id ] --- hop | |
532 | * Note: if that==NULL, skip nexthop | |
533 | * Returns strlen of formated result (length excludes NUL at end). | |
534 | */ | |
535 | size_t | |
536 | format_end(char *buf | |
537 | , size_t buf_len | |
538 | , const struct end *this | |
539 | , const struct end *that | |
540 | , bool is_left | |
541 | , lset_t policy) | |
542 | { | |
543 | char client[SUBNETTOT_BUF]; | |
544 | const char *client_sep = ""; | |
545 | char protoport[sizeof(":255/65535")]; | |
546 | const char *host = NULL; | |
547 | char host_space[ADDRTOT_BUF]; | |
548 | char host_port[sizeof(":65535")]; | |
549 | char host_id[BUF_LEN + 2]; | |
550 | char hop[ADDRTOT_BUF]; | |
551 | const char *hop_sep = ""; | |
552 | const char *open_brackets = ""; | |
553 | const char *close_brackets = ""; | |
554 | ||
555 | if (isanyaddr(&this->host_addr)) | |
556 | { | |
557 | switch (policy & (POLICY_GROUP | POLICY_OPPO)) | |
558 | { | |
559 | case POLICY_GROUP: | |
560 | host = "%group"; | |
561 | break; | |
562 | case POLICY_OPPO: | |
563 | host = "%opportunistic"; | |
564 | break; | |
565 | case POLICY_GROUP | POLICY_OPPO: | |
566 | host = "%opportunisticgroup"; | |
567 | break; | |
568 | default: | |
569 | host = "%any"; | |
570 | break; | |
571 | } | |
572 | } | |
573 | ||
574 | client[0] = '\0'; | |
575 | ||
576 | #ifdef VIRTUAL_IP | |
577 | if (is_virtual_end(this) && isanyaddr(&this->host_addr)) | |
578 | { | |
579 | host = "%virtual"; | |
580 | } | |
581 | #endif | |
582 | ||
583 | /* [client===] */ | |
584 | if (this->has_client) | |
585 | { | |
586 | ip_address client_net, client_mask; | |
587 | ||
588 | networkof(&this->client, &client_net); | |
589 | maskof(&this->client, &client_mask); | |
590 | client_sep = "==="; | |
591 | ||
592 | /* {client_subnet_wildcard} */ | |
593 | if (this->has_client_wildcard) | |
594 | { | |
595 | open_brackets = "{"; | |
596 | close_brackets = "}"; | |
597 | } | |
598 | ||
599 | if (isanyaddr(&client_net) && isanyaddr(&client_mask) | |
600 | && (policy & (POLICY_GROUP | POLICY_OPPO))) | |
601 | client_sep = ""; /* boring case */ | |
602 | else if (subnetisnone(&this->client)) | |
603 | strcpy(client, "?"); | |
604 | else | |
605 | subnettot(&this->client, 0, client, sizeof(client)); | |
606 | } | |
607 | else if (this->modecfg && isanyaddr(&this->host_srcip)) | |
608 | { | |
609 | /* we are mode config client */ | |
610 | client_sep = "==="; | |
611 | strcpy(client, "%modecfg"); | |
612 | } | |
613 | ||
614 | /* host */ | |
615 | if (host == NULL) | |
616 | { | |
617 | addrtot(&this->host_addr, 0, host_space, sizeof(host_space)); | |
618 | host = host_space; | |
619 | } | |
620 | ||
621 | host_port[0] = '\0'; | |
622 | if (this->host_port != IKE_UDP_PORT) | |
623 | snprintf(host_port, sizeof(host_port), ":%u" | |
624 | , this->host_port); | |
625 | ||
626 | /* payload portocol and port */ | |
627 | protoport[0] = '\0'; | |
628 | if (this->has_port_wildcard) | |
629 | snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol); | |
630 | else if (this->port || this->protocol) | |
631 | snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol | |
632 | , this->port); | |
633 | ||
634 | /* id, if different from host */ | |
635 | host_id[0] = '\0'; | |
636 | if (this->id.kind == ID_MYID) | |
637 | { | |
638 | strcpy(host_id, "[%myid]"); | |
639 | } | |
640 | else if (!(this->id.kind == ID_NONE | |
641 | || (id_is_ipaddr(&this->id) && sameaddr(&this->id.ip_addr, &this->host_addr)))) | |
642 | { | |
643 | int len = idtoa(&this->id, host_id+1, sizeof(host_id)-2); | |
644 | ||
645 | host_id[0] = '['; | |
646 | strcpy(&host_id[len < 0? (ptrdiff_t)sizeof(host_id)-2 : 1 + len], "]"); | |
647 | } | |
648 | ||
649 | /* [---hop] */ | |
650 | hop[0] = '\0'; | |
651 | hop_sep = ""; | |
652 | if (that != NULL && !sameaddr(&this->host_nexthop, &that->host_addr)) | |
653 | { | |
654 | addrtot(&this->host_nexthop, 0, hop, sizeof(hop)); | |
655 | hop_sep = "---"; | |
656 | } | |
657 | ||
658 | if (is_left) | |
659 | snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s" | |
660 | , open_brackets, client, close_brackets | |
661 | , client_sep, host, host_port, host_id | |
662 | , protoport, hop_sep, hop); | |
663 | else | |
664 | snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s" | |
665 | , hop, hop_sep, host, host_port, host_id | |
666 | , protoport, client_sep | |
667 | , open_brackets, client, close_brackets); | |
668 | return strlen(buf); | |
669 | } | |
670 | ||
671 | /* format topology of a connection. | |
672 | * Two symmetric ends separated by ... | |
673 | */ | |
674 | #define CONNECTION_BUF (2 * (END_BUF - 1) + 4) | |
675 | ||
676 | static size_t | |
677 | format_connection(char *buf, size_t buf_len | |
678 | , const struct connection *c | |
679 | , struct spd_route *sr) | |
680 | { | |
681 | size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY); | |
682 | ||
683 | w += snprintf(buf + w, buf_len - w, "..."); | |
684 | return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy); | |
685 | } | |
686 | ||
687 | static void | |
688 | unshare_connection_strings(struct connection *c) | |
689 | { | |
690 | c->name = clone_str(c->name, "connection name"); | |
691 | ||
692 | unshare_id_content(&c->spd.this.id); | |
693 | c->spd.this.updown = clone_str(c->spd.this.updown, "updown"); | |
694 | scx_share(c->spd.this.sc); | |
695 | share_cert(c->spd.this.cert); | |
696 | if (c->spd.this.ca.ptr != NULL) | |
697 | clonetochunk(c->spd.this.ca, c->spd.this.ca.ptr, c->spd.this.ca.len, "ca string"); | |
698 | ||
699 | unshare_id_content(&c->spd.that.id); | |
700 | c->spd.that.updown = clone_str(c->spd.that.updown, "updown"); | |
701 | scx_share(c->spd.that.sc); | |
702 | share_cert(c->spd.that.cert); | |
703 | if (c->spd.that.ca.ptr != NULL) | |
704 | clonetochunk(c->spd.that.ca, c->spd.that.ca.ptr, c->spd.that.ca.len, "ca string"); | |
705 | ||
706 | /* increment references to algo's */ | |
707 | alg_info_addref((struct alg_info *)c->alg_info_esp); | |
708 | alg_info_addref((struct alg_info *)c->alg_info_ike); | |
709 | } | |
710 | ||
711 | static void | |
712 | load_end_certificate(const char *filename, struct end *dst) | |
713 | { | |
714 | time_t valid_until; | |
715 | cert_t cert; | |
716 | bool valid_cert = FALSE; | |
717 | bool cached_cert = FALSE; | |
718 | ||
719 | /* initialize end certificate */ | |
720 | dst->cert.type = CERT_NONE; | |
721 | dst->cert.u.x509 = NULL; | |
722 | ||
723 | /* initialize smartcard info record */ | |
724 | dst->sc = NULL; | |
725 | ||
726 | if (filename != NULL) | |
727 | { | |
728 | if (scx_on_smartcard(filename)) | |
729 | { | |
730 | /* load cert from smartcard */ | |
731 | valid_cert = scx_load_cert(filename, &dst->sc, &cert, &cached_cert); | |
732 | } | |
733 | else | |
734 | { | |
735 | /* load cert from file */ | |
736 | valid_cert = load_host_cert(filename, &cert); | |
737 | } | |
738 | } | |
739 | ||
740 | if (valid_cert) | |
741 | { | |
742 | err_t ugh = NULL; | |
743 | ||
744 | switch (cert.type) | |
745 | { | |
746 | case CERT_PGP: | |
747 | select_pgpcert_id(cert.u.pgp, &dst->id); | |
748 | ||
749 | if (cached_cert) | |
750 | dst->cert = cert; | |
751 | else | |
752 | { | |
753 | valid_until = cert.u.pgp->until; | |
754 | add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL); | |
755 | dst->cert.type = cert.type; | |
756 | dst->cert.u.pgp = add_pgpcert(cert.u.pgp); | |
757 | } | |
758 | break; | |
759 | case CERT_X509_SIGNATURE: | |
760 | select_x509cert_id(cert.u.x509, &dst->id); | |
761 | ||
762 | if (cached_cert) | |
763 | dst->cert = cert; | |
764 | else | |
765 | { | |
766 | /* check validity of cert */ | |
767 | valid_until = cert.u.x509->notAfter; | |
768 | ugh = check_validity(cert.u.x509, &valid_until); | |
769 | if (ugh != NULL) | |
770 | { | |
771 | plog(" %s", ugh); | |
772 | free_x509cert(cert.u.x509); | |
773 | break; | |
774 | } | |
775 | ||
776 | DBG(DBG_CONTROL, | |
777 | DBG_log("certificate is valid") | |
778 | ) | |
779 | add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL); | |
780 | dst->cert.type = cert.type; | |
781 | dst->cert.u.x509 = add_x509cert(cert.u.x509); | |
782 | } | |
783 | /* if no CA is defined, use issuer as default */ | |
784 | if (dst->ca.ptr == NULL) | |
785 | dst->ca = dst->cert.u.x509->issuer; | |
786 | break; | |
787 | default: | |
788 | break; | |
789 | } | |
790 | ||
791 | /* cache the certificate that was last retrieved from the smartcard */ | |
792 | if (dst->sc != NULL) | |
793 | { | |
794 | if (!same_cert(&dst->sc->last_cert, &dst->cert)) | |
795 | { | |
796 | lock_certs_and_keys("load_end_certificates"); | |
797 | release_cert(dst->sc->last_cert); | |
798 | dst->sc->last_cert = dst->cert; | |
799 | share_cert(dst->cert); | |
800 | unlock_certs_and_keys("load_end_certificates"); | |
801 | } | |
802 | time(&dst->sc->last_load); | |
803 | } | |
804 | } | |
805 | } | |
806 | ||
807 | static bool | |
808 | extract_end(struct end *dst, const whack_end_t *src, const char *which) | |
809 | { | |
810 | bool same_ca = FALSE; | |
811 | ||
812 | /* decode id, if any */ | |
813 | if (src->id == NULL) | |
814 | { | |
815 | dst->id.kind = ID_NONE; | |
816 | } | |
817 | else | |
818 | { | |
819 | err_t ugh = atoid(src->id, &dst->id, TRUE); | |
820 | ||
821 | if (ugh != NULL) | |
822 | { | |
823 | loglog(RC_BADID, "bad %s --id: %s (ignored)", which, ugh); | |
824 | dst->id = empty_id; /* ignore bad one */ | |
825 | } | |
826 | } | |
827 | ||
828 | dst->ca = empty_chunk; | |
829 | ||
830 | /* decode CA distinguished name, if any */ | |
831 | if (src->ca != NULL) | |
832 | { | |
833 | if streq(src->ca, "%same") | |
834 | same_ca = TRUE; | |
835 | else if (!streq(src->ca, "%any")) | |
836 | { | |
837 | err_t ugh; | |
838 | ||
839 | dst->ca.ptr = temporary_cyclic_buffer(); | |
840 | ugh = atodn(src->ca, &dst->ca); | |
841 | if (ugh != NULL) | |
842 | { | |
843 | plog("bad CA string '%s': %s (ignored)", src->ca, ugh); | |
844 | dst->ca = empty_chunk; | |
845 | } | |
846 | } | |
847 | } | |
848 | ||
849 | /* load local end certificate and extract ID, if any */ | |
850 | load_end_certificate(src->cert, dst); | |
851 | ||
852 | /* does id has wildcards? */ | |
853 | dst->has_id_wildcards = id_count_wildcards(&dst->id) > 0; | |
854 | ||
855 | /* decode group attributes, if any */ | |
856 | decode_groups(src->groups, &dst->groups); | |
857 | ||
858 | /* the rest is simple copying of corresponding fields */ | |
859 | dst->host_addr = src->host_addr; | |
860 | dst->host_nexthop = src->host_nexthop; | |
861 | dst->host_srcip = src->host_srcip; | |
862 | dst->client = src->client; | |
863 | dst->protocol = src->protocol; | |
864 | dst->port = src->port; | |
865 | dst->has_port_wildcard = src->has_port_wildcard; | |
866 | dst->key_from_DNS_on_demand = src->key_from_DNS_on_demand; | |
867 | dst->has_client = src->has_client; | |
868 | dst->has_client_wildcard = src->has_client_wildcard; | |
869 | dst->modecfg = src->modecfg; | |
870 | dst->hostaccess = src->hostaccess; | |
871 | dst->sendcert = src->sendcert; | |
872 | dst->updown = src->updown; | |
873 | dst->host_port = src->host_port; | |
874 | ||
875 | /* if host sourceip is defined but no client is present | |
876 | * behind the host then set client to sourceip/32 | |
877 | */ | |
878 | if (addrbytesptr(&dst->host_srcip, NULL) | |
879 | && !isanyaddr(&dst->host_srcip) | |
880 | && !dst->has_client) | |
881 | { | |
882 | err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client); | |
883 | ||
884 | if (ugh != NULL) | |
885 | plog("could not assign host sourceip to client subnet"); | |
886 | else | |
887 | dst->has_client = TRUE; | |
888 | } | |
889 | return same_ca; | |
890 | } | |
891 | ||
892 | static bool | |
893 | check_connection_end(const whack_end_t *this, const whack_end_t *that | |
894 | , const whack_message_t *wm) | |
895 | { | |
896 | if (wm->addr_family != addrtypeof(&this->host_addr) | |
897 | || wm->addr_family != addrtypeof(&this->host_nexthop) | |
898 | || (this->has_client? wm->tunnel_addr_family : wm->addr_family) | |
899 | != subnettypeof(&this->client) | |
900 | || subnettypeof(&this->client) != subnettypeof(&that->client)) | |
901 | { | |
902 | /* this should have been diagnosed by whack, so we need not be clear | |
903 | * !!! overloaded use of RC_CLASH | |
904 | */ | |
905 | loglog(RC_CLASH, "address family inconsistency in connection"); | |
906 | return FALSE; | |
907 | } | |
908 | ||
909 | if (isanyaddr(&that->host_addr)) | |
910 | { | |
911 | /* other side is wildcard: we must check if other conditions met */ | |
912 | if (isanyaddr(&this->host_addr)) | |
913 | { | |
914 | loglog(RC_ORIENT, "connection must specify host IP address for our side"); | |
915 | return FALSE; | |
916 | } | |
917 | } | |
918 | #ifdef VIRTUAL_IP | |
919 | if (this->virt && (!isanyaddr(&this->host_addr) || this->has_client)) | |
920 | { | |
921 | loglog(RC_CLASH, | |
922 | "virtual IP must only be used with %%any and without client"); | |
923 | return FALSE; | |
924 | } | |
925 | #endif | |
926 | return TRUE; /* happy */ | |
927 | } | |
928 | ||
929 | struct connection * | |
930 | find_connection_by_reqid(uint32_t reqid) | |
931 | { | |
932 | struct connection *c; | |
933 | ||
934 | reqid &= ~3; | |
935 | for (c = connections; c != NULL; c = c->ac_next) | |
936 | { | |
937 | if (c->spd.reqid == reqid) | |
938 | return c; | |
939 | } | |
940 | ||
941 | return NULL; | |
942 | } | |
943 | ||
944 | static uint32_t | |
945 | gen_reqid(void) | |
946 | { | |
947 | uint32_t start; | |
948 | static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3; | |
949 | ||
950 | start = reqid; | |
951 | do { | |
952 | reqid += 4; | |
953 | if (reqid == 0) | |
954 | reqid = (IPSEC_MANUAL_REQID_MAX & ~3) + 4; | |
955 | if (!find_connection_by_reqid(reqid)) | |
956 | return reqid; | |
957 | } while (reqid != start); | |
958 | ||
959 | exit_log("unable to allocate reqid"); | |
960 | } | |
961 | ||
962 | void | |
963 | add_connection(const whack_message_t *wm) | |
964 | { | |
965 | if (con_by_name(wm->name, FALSE) != NULL) | |
966 | { | |
967 | loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name); | |
968 | } | |
969 | else if (wm->right.protocol != wm->left.protocol) | |
970 | { | |
971 | /* this should haven been diagnosed by whack | |
972 | * !!! overloaded use of RC_CLASH | |
973 | */ | |
974 | loglog(RC_CLASH, "the protocol must be the same for leftport and rightport"); | |
975 | } | |
976 | else if (check_connection_end(&wm->right, &wm->left, wm) | |
977 | && check_connection_end(&wm->left, &wm->right, wm)) | |
978 | { | |
979 | bool same_rightca, same_leftca; | |
980 | struct connection *c = alloc_thing(struct connection, "struct connection"); | |
981 | ||
982 | c->name = wm->name; | |
983 | ||
984 | c->policy = wm->policy; | |
985 | ||
986 | if ((c->policy & POLICY_COMPRESS) && !can_do_IPcomp) | |
987 | loglog(RC_COMMENT | |
988 | , "ignoring --compress in \"%s\" because KLIPS is not configured to do IPCOMP" | |
989 | , c->name); | |
990 | ||
991 | if (wm->esp) | |
992 | { | |
993 | const char *ugh; | |
994 | ||
995 | DBG(DBG_CONTROL, | |
996 | DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL") | |
997 | ) | |
998 | c->alg_info_esp= alg_info_esp_create_from_str(wm->esp? wm->esp : "", &ugh); | |
999 | ||
1000 | DBG(DBG_CRYPT|DBG_CONTROL, | |
1001 | static char buf[256]="<NULL>"; | |
1002 | ||
1003 | if (c->alg_info_esp) | |
1004 | alg_info_snprint(buf, sizeof(buf) | |
1005 | ,(struct alg_info *)c->alg_info_esp); | |
1006 | DBG_log("esp string values: %s", buf); | |
1007 | ) | |
1008 | if (c->alg_info_esp) | |
1009 | { | |
1010 | if (c->alg_info_esp->alg_info_cnt==0) | |
1011 | loglog(RC_LOG_SERIOUS | |
1012 | , "got 0 transforms for esp=\"%s\"", wm->esp); | |
1013 | } | |
1014 | else | |
1015 | { | |
1016 | loglog(RC_LOG_SERIOUS | |
1017 | , "esp string error: %s", ugh? ugh : "Unknown"); | |
1018 | } | |
1019 | } | |
1020 | ||
1021 | if (wm->ike) | |
1022 | { | |
1023 | const char *ugh; | |
1024 | ||
1025 | DBG(DBG_CONTROL, | |
1026 | DBG_log("from whack: got --ike=%s", wm->ike ? wm->ike: "NULL") | |
1027 | ) | |
1028 | c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : "", &ugh); | |
1029 | ||
1030 | DBG(DBG_CRYPT|DBG_CONTROL, | |
1031 | static char buf[256]="<NULL>"; | |
1032 | ||
1033 | if (c->alg_info_ike) | |
1034 | alg_info_snprint(buf, sizeof(buf) | |
1035 | , (struct alg_info *)c->alg_info_ike); | |
1036 | DBG_log("ike string values: %s", buf); | |
1037 | ) | |
1038 | if (c->alg_info_ike) | |
1039 | { | |
1040 | if (c->alg_info_ike->alg_info_cnt==0) | |
1041 | loglog(RC_LOG_SERIOUS | |
1042 | , "got 0 transforms for ike=\"%s\"", wm->ike); | |
1043 | } | |
1044 | else | |
1045 | { | |
1046 | loglog(RC_LOG_SERIOUS | |
1047 | , "ike string error: %s", ugh? ugh : "Unknown"); | |
1048 | } | |
1049 | } | |
1050 | ||
1051 | c->sa_ike_life_seconds = wm->sa_ike_life_seconds; | |
1052 | c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds; | |
1053 | c->sa_rekey_margin = wm->sa_rekey_margin; | |
1054 | c->sa_rekey_fuzz = wm->sa_rekey_fuzz; | |
1055 | c->sa_keying_tries = wm->sa_keying_tries; | |
1056 | ||
1057 | /* RFC 3706 DPD */ | |
1058 | c->dpd_delay = wm->dpd_delay; | |
1059 | c->dpd_timeout = wm->dpd_timeout; | |
1060 | c->dpd_action = wm->dpd_action; | |
1061 | ||
1062 | c->addr_family = wm->addr_family; | |
1063 | c->tunnel_addr_family = wm->tunnel_addr_family; | |
1064 | ||
1065 | c->requested_ca = NULL; | |
1066 | ||
1067 | same_leftca = extract_end(&c->spd.this, &wm->left, "left"); | |
1068 | same_rightca = extract_end(&c->spd.that, &wm->right, "right"); | |
1069 | ||
1070 | if (same_rightca) | |
1071 | c->spd.that.ca = c->spd.this.ca; | |
1072 | else if (same_leftca) | |
1073 | c->spd.this.ca = c->spd.that.ca; | |
1074 | ||
1075 | default_end(&c->spd.this, &c->spd.that.host_addr); | |
1076 | default_end(&c->spd.that, &c->spd.this.host_addr); | |
1077 | ||
1078 | /* force any wildcard host IP address, any wildcard subnet | |
1079 | * or any wildcard ID to that end | |
1080 | */ | |
1081 | if (isanyaddr(&c->spd.this.host_addr) || c->spd.this.has_client_wildcard | |
1082 | || c->spd.this.has_port_wildcard || c->spd.this.has_id_wildcards) | |
1083 | { | |
1084 | struct end t = c->spd.this; | |
1085 | ||
1086 | c->spd.this = c->spd.that; | |
1087 | c->spd.that = t; | |
1088 | } | |
1089 | ||
1090 | c->spd.next = NULL; | |
1091 | c->spd.reqid = gen_reqid(); | |
1092 | ||
1093 | /* set internal fields */ | |
1094 | c->instance_serial = 0; | |
1095 | c->ac_next = connections; | |
1096 | connections = c; | |
1097 | c->interface = NULL; | |
1098 | c->spd.routing = RT_UNROUTED; | |
1099 | c->newest_isakmp_sa = SOS_NOBODY; | |
1100 | c->newest_ipsec_sa = SOS_NOBODY; | |
1101 | c->spd.eroute_owner = SOS_NOBODY; | |
1102 | ||
1103 | if (c->policy & POLICY_GROUP) | |
1104 | { | |
1105 | c->kind = CK_GROUP; | |
1106 | add_group(c); | |
1107 | } | |
1108 | else if ((isanyaddr(&c->spd.that.host_addr) && !NEVER_NEGOTIATE(c->policy)) | |
1109 | || c->spd.that.has_client_wildcard || c->spd.that.has_port_wildcard | |
1110 | || c->spd.that.has_id_wildcards) | |
1111 | { | |
1112 | /* Opportunistic or Road Warrior or wildcard client subnet | |
1113 | * or wildcard ID */ | |
1114 | c->kind = CK_TEMPLATE; | |
1115 | } | |
1116 | else | |
1117 | { | |
1118 | c->kind = CK_PERMANENT; | |
1119 | } | |
1120 | set_policy_prio(c); /* must be after kind is set */ | |
1121 | ||
1122 | #ifdef DEBUG | |
1123 | c->extra_debugging = wm->debugging; | |
1124 | #endif | |
1125 | ||
1126 | c->gw_info = NULL; | |
1127 | ||
1128 | #ifdef VIRTUAL_IP | |
1129 | passert(!(wm->left.virt && wm->right.virt)); | |
1130 | if (wm->left.virt || wm->right.virt) | |
1131 | { | |
1132 | passert(isanyaddr(&c->spd.that.host_addr)); | |
1133 | c->spd.that.virt = create_virtual(c, | |
1134 | wm->left.virt ? wm->left.virt : wm->right.virt); | |
1135 | if (c->spd.that.virt) | |
1136 | c->spd.that.has_client = TRUE; | |
1137 | } | |
1138 | #endif | |
1139 | ||
1140 | unshare_connection_strings(c); | |
1141 | (void)orient(c); | |
1142 | connect_to_host_pair(c); | |
1143 | ||
1144 | /* log all about this connection */ | |
1145 | plog("added connection description \"%s\"", c->name); | |
1146 | DBG(DBG_CONTROL, | |
1147 | char topo[CONNECTION_BUF]; | |
1148 | ||
1149 | (void) format_connection(topo, sizeof(topo), c, &c->spd); | |
1150 | ||
1151 | DBG_log("%s", topo); | |
1152 | ||
1153 | /* Make sure that address families can be correctly inferred | |
1154 | * from printed ends. | |
1155 | */ | |
1156 | passert(c->addr_family == addrtypeof(&c->spd.this.host_addr) | |
1157 | && c->addr_family == addrtypeof(&c->spd.this.host_nexthop) | |
1158 | && (c->spd.this.has_client? c->tunnel_addr_family : c->addr_family) | |
1159 | == subnettypeof(&c->spd.this.client) | |
1160 | ||
1161 | && c->addr_family == addrtypeof(&c->spd.that.host_addr) | |
1162 | && c->addr_family == addrtypeof(&c->spd.that.host_nexthop) | |
1163 | && (c->spd.that.has_client? c->tunnel_addr_family : c->addr_family) | |
1164 | == subnettypeof(&c->spd.that.client)); | |
1165 | ||
1166 | DBG_log("ike_life: %lus; ipsec_life: %lus; rekey_margin: %lus;" | |
1167 | " rekey_fuzz: %lu%%; keyingtries: %lu; policy: %s" | |
1168 | , (unsigned long) c->sa_ike_life_seconds | |
1169 | , (unsigned long) c->sa_ipsec_life_seconds | |
1170 | , (unsigned long) c->sa_rekey_margin | |
1171 | , (unsigned long) c->sa_rekey_fuzz | |
1172 | , (unsigned long) c->sa_keying_tries | |
1173 | , prettypolicy(c->policy)); | |
1174 | ); | |
1175 | } | |
1176 | } | |
1177 | ||
1178 | /* Derive a template connection from a group connection and target. | |
1179 | * Similar to instantiate(). Happens at whack --listen. | |
1180 | * Returns name of new connection. May be NULL. | |
1181 | * Caller is responsible for pfreeing. | |
1182 | */ | |
1183 | char * | |
1184 | add_group_instance(struct connection *group, const ip_subnet *target) | |
1185 | { | |
1186 | char namebuf[100] | |
1187 | , targetbuf[SUBNETTOT_BUF]; | |
1188 | struct connection *t; | |
1189 | char *name = NULL; | |
1190 | ||
1191 | passert(group->kind == CK_GROUP); | |
1192 | passert(oriented(*group)); | |
1193 | ||
1194 | /* manufacture a unique name for this template */ | |
1195 | subnettot(target, 0, targetbuf, sizeof(targetbuf)); | |
1196 | snprintf(namebuf, sizeof(namebuf), "%s#%s", group->name, targetbuf); | |
1197 | ||
1198 | if (con_by_name(namebuf, FALSE) != NULL) | |
1199 | { | |
1200 | loglog(RC_DUPNAME, "group name + target yields duplicate name \"%s\"" | |
1201 | , namebuf); | |
1202 | } | |
1203 | else | |
1204 | { | |
1205 | t = clone_thing(*group, "group instance"); | |
1206 | t->name = namebuf; | |
1207 | unshare_connection_strings(t); | |
1208 | name = clone_str(t->name, "group instance name"); | |
1209 | t->spd.that.client = *target; | |
1210 | t->policy &= ~(POLICY_GROUP | POLICY_GROUTED); | |
1211 | t->kind = isanyaddr(&t->spd.that.host_addr) && !NEVER_NEGOTIATE(t->policy) | |
1212 | ? CK_TEMPLATE : CK_INSTANCE; | |
1213 | ||
1214 | /* reset log file info */ | |
1215 | t->log_file_name = NULL; | |
1216 | t->log_file = NULL; | |
1217 | t->log_file_err = FALSE; | |
1218 | ||
1219 | t->spd.reqid = gen_reqid(); | |
1220 | ||
1221 | #ifdef VIRTUAL_IP | |
1222 | if (t->spd.that.virt) | |
1223 | { | |
1224 | DBG_log("virtual_ip not supported in group instance"); | |
1225 | t->spd.that.virt = NULL; | |
1226 | } | |
1227 | #endif | |
1228 | ||
1229 | /* add to connections list */ | |
1230 | t->ac_next = connections; | |
1231 | connections = t; | |
1232 | ||
1233 | /* same host_pair as parent: stick after parent on list */ | |
1234 | group->hp_next = t; | |
1235 | ||
1236 | /* route if group is routed */ | |
1237 | if (group->policy & POLICY_GROUTED) | |
1238 | { | |
1239 | if (!trap_connection(t)) | |
1240 | whack_log(RC_ROUTE, "could not route"); | |
1241 | } | |
1242 | } | |
1243 | return name; | |
1244 | } | |
1245 | ||
1246 | /* an old target has disappeared for a group: delete instance */ | |
1247 | void | |
1248 | remove_group_instance(const struct connection *group USED_BY_DEBUG | |
1249 | , const char *name) | |
1250 | { | |
1251 | passert(group->kind == CK_GROUP); | |
1252 | passert(oriented(*group)); | |
1253 | ||
1254 | delete_connections_by_name(name, FALSE); | |
1255 | } | |
1256 | ||
1257 | /* Common part of instantiating a Road Warrior or Opportunistic connection. | |
1258 | * his_id can be used to carry over an ID discovered in Phase 1. | |
1259 | * It must not disagree with the one in c, but if that is unspecified, | |
1260 | * the new connection will use his_id. | |
1261 | * If his_id is NULL, and c.that.id is uninstantiated (ID_NONE), the | |
1262 | * new connection will continue to have an uninstantiated that.id. | |
1263 | * Note: instantiation does not affect port numbers. | |
1264 | * | |
1265 | * Note that instantiate can only deal with a single SPD/eroute. | |
1266 | */ | |
1267 | static struct connection * | |
1268 | instantiate(struct connection *c, const ip_address *him | |
1269 | #ifdef NAT_TRAVERSAL | |
1270 | , u_int16_t his_port | |
1271 | #endif | |
1272 | , const struct id *his_id) | |
1273 | { | |
1274 | struct connection *d; | |
1275 | int wildcards; | |
1276 | ||
1277 | passert(c->kind == CK_TEMPLATE); | |
1278 | passert(c->spd.next == NULL); | |
1279 | ||
1280 | c->instance_serial++; | |
1281 | d = clone_thing(*c, "temporary connection"); | |
1282 | if (his_id != NULL) | |
1283 | { | |
1284 | passert(match_id(his_id, &d->spd.that.id, &wildcards)); | |
1285 | d->spd.that.id = *his_id; | |
1286 | d->spd.that.has_id_wildcards = FALSE; | |
1287 | } | |
1288 | unshare_connection_strings(d); | |
1289 | unshare_ietfAttrList(&d->spd.this.groups); | |
1290 | unshare_ietfAttrList(&d->spd.that.groups); | |
1291 | d->kind = CK_INSTANCE; | |
1292 | ||
1293 | passert(oriented(*d)); | |
1294 | d->spd.that.host_addr = *him; | |
1295 | setportof(htons(c->spd.that.port), &d->spd.that.host_addr); | |
1296 | #ifdef NAT_TRAVERSAL | |
1297 | if (his_port) d->spd.that.host_port = his_port; | |
1298 | #endif | |
1299 | default_end(&d->spd.that, &d->spd.this.host_addr); | |
1300 | ||
1301 | /* We cannot guess what our next_hop should be, but if it was | |
1302 | * explicitly specified as 0.0.0.0, we set it to be him. | |
1303 | * (whack will not allow nexthop to be elided in RW case.) | |
1304 | */ | |
1305 | default_end(&d->spd.this, &d->spd.that.host_addr); | |
1306 | d->spd.next = NULL; | |
1307 | d->spd.reqid = gen_reqid(); | |
1308 | ||
1309 | /* set internal fields */ | |
1310 | d->ac_next = connections; | |
1311 | connections = d; | |
1312 | d->spd.routing = RT_UNROUTED; | |
1313 | d->newest_isakmp_sa = SOS_NOBODY; | |
1314 | d->newest_ipsec_sa = SOS_NOBODY; | |
1315 | d->spd.eroute_owner = SOS_NOBODY; | |
1316 | ||
1317 | /* reset log file info */ | |
1318 | d->log_file_name = NULL; | |
1319 | d->log_file = NULL; | |
1320 | d->log_file_err = FALSE; | |
1321 | ||
1322 | connect_to_host_pair(d); | |
1323 | ||
1324 | return d; | |
1325 | } | |
1326 | ||
1327 | struct connection * | |
1328 | rw_instantiate(struct connection *c | |
1329 | , const ip_address *him | |
1330 | #ifdef NAT_TRAVERSAL | |
1331 | , u_int16_t his_port | |
1332 | #endif | |
1333 | #ifdef VIRTUAL_IP | |
1334 | , const ip_subnet *his_net | |
1335 | #endif | |
1336 | , const struct id *his_id) | |
1337 | { | |
1338 | #ifdef NAT_TRAVERSAL | |
1339 | struct connection *d = instantiate(c, him, his_port, his_id); | |
1340 | #else | |
1341 | struct connection *d = instantiate(c, him, his_id); | |
1342 | #endif | |
1343 | ||
1344 | #ifdef VIRTUAL_IP | |
1345 | if (d && his_net && is_virtual_connection(c)) | |
1346 | { | |
1347 | d->spd.that.client = *his_net; | |
1348 | d->spd.that.virt = NULL; | |
1349 | if (subnetishost(his_net) && addrinsubnet(him, his_net)) | |
1350 | d->spd.that.has_client = FALSE; | |
1351 | } | |
1352 | #endif | |
1353 | ||
1354 | if (d->policy & POLICY_OPPO) | |
1355 | { | |
1356 | /* This must be before we know the client addresses. | |
1357 | * Fill in one that is impossible. This prevents anyone else from | |
1358 | * trying to use this connection to get to a particular client | |
1359 | */ | |
1360 | d->spd.that.client = *aftoinfo(subnettypeof(&d->spd.that.client))->none; | |
1361 | } | |
1362 | DBG(DBG_CONTROL | |
1363 | , DBG_log("instantiated \"%s\" for %s" , d->name, ip_str(him))); | |
1364 | return d; | |
1365 | } | |
1366 | ||
1367 | struct connection * | |
1368 | oppo_instantiate(struct connection *c | |
1369 | , const ip_address *him | |
1370 | , const struct id *his_id | |
1371 | , struct gw_info *gw | |
1372 | , const ip_address *our_client USED_BY_DEBUG | |
1373 | , const ip_address *peer_client) | |
1374 | { | |
1375 | #ifdef NAT_TRAVERSAL | |
1376 | struct connection *d = instantiate(c, him, 0, his_id); | |
1377 | #else | |
1378 | struct connection *d = instantiate(c, him, his_id); | |
1379 | #endif | |
1380 | ||
1381 | passert(d->spd.next == NULL); | |
1382 | ||
1383 | /* fill in our client side */ | |
1384 | if (d->spd.this.has_client) | |
1385 | { | |
1386 | /* there was a client in the abstract connection | |
1387 | * so we demand that the required client is within that subnet. | |
1388 | */ | |
1389 | passert(addrinsubnet(our_client, &d->spd.this.client)); | |
1390 | happy(addrtosubnet(our_client, &d->spd.this.client)); | |
1391 | /* opportunistic connections do not use port selectors */ | |
1392 | setportof(0, &d->spd.this.client.addr); | |
1393 | } | |
1394 | else | |
1395 | { | |
1396 | /* there was no client in the abstract connection | |
1397 | * so we demand that the required client be the host | |
1398 | */ | |
1399 | passert(sameaddr(our_client, &d->spd.this.host_addr)); | |
1400 | } | |
1401 | ||
1402 | /* fill in peer's client side. | |
1403 | * If the client is the peer, excise the client from the connection. | |
1404 | */ | |
1405 | passert((d->policy & POLICY_OPPO) | |
1406 | && addrinsubnet(peer_client, &d->spd.that.client)); | |
1407 | happy(addrtosubnet(peer_client, &d->spd.that.client)); | |
1408 | /* opportunistic connections do not use port selectors */ | |
1409 | setportof(0, &d->spd.that.client.addr); | |
1410 | ||
1411 | if (sameaddr(peer_client, &d->spd.that.host_addr)) | |
1412 | d->spd.that.has_client = FALSE; | |
1413 | ||
1414 | passert(d->gw_info == NULL); | |
1415 | gw_addref(gw); | |
1416 | d->gw_info = gw; | |
1417 | ||
1418 | /* Adjust routing if something is eclipsing c. | |
1419 | * It must be a %hold for us (hard to passert this). | |
1420 | * If there was another instance eclipsing, we'd be using it. | |
1421 | */ | |
1422 | if (c->spd.routing == RT_ROUTED_ECLIPSED) | |
1423 | d->spd.routing = RT_ROUTED_PROSPECTIVE; | |
1424 | ||
1425 | /* Remember if the template is routed: | |
1426 | * if so, this instance applies for initiation | |
1427 | * even if it is created for responding. | |
1428 | */ | |
1429 | if (routed(c->spd.routing)) | |
1430 | d->instance_initiation_ok = TRUE; | |
1431 | ||
1432 | DBG(DBG_CONTROL, | |
1433 | char topo[CONNECTION_BUF]; | |
1434 | ||
1435 | (void) format_connection(topo, sizeof(topo), d, &d->spd); | |
1436 | DBG_log("instantiated \"%s\": %s", d->name, topo); | |
1437 | ); | |
1438 | return d; | |
1439 | } | |
1440 | ||
1441 | /* priority formatting */ | |
1442 | void | |
1443 | fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]) | |
1444 | { | |
1445 | if (pp == BOTTOM_PRIO) | |
1446 | snprintf(buf, POLICY_PRIO_BUF, "0"); | |
1447 | else | |
1448 | snprintf(buf, POLICY_PRIO_BUF, "%lu,%lu" | |
1449 | , pp>>16, (pp & ~(~(policy_prio_t)0 << 16)) >> 8); | |
1450 | } | |
1451 | ||
1452 | /* Format any information needed to identify an instance of a connection. | |
1453 | * Fills any needed information into buf which MUST be big enough. | |
1454 | * Road Warrior: peer's IP address | |
1455 | * Opportunistic: [" " myclient "==="] " ..." peer ["===" hisclient] '\0' | |
1456 | */ | |
1457 | static size_t | |
1458 | fmt_client(const ip_subnet *client, const ip_address *gw, const char *prefix, char buf[ADDRTOT_BUF]) | |
1459 | { | |
1460 | if (subnetisaddr(client, gw)) | |
1461 | { | |
1462 | buf[0] = '\0'; /* compact denotation for "self" */ | |
1463 | } | |
1464 | else | |
1465 | { | |
1466 | char *ap; | |
1467 | ||
1468 | strcpy(buf, prefix); | |
1469 | ap = buf + strlen(prefix); | |
1470 | if (subnetisnone(client)) | |
1471 | strcpy(ap, "?"); /* unknown */ | |
1472 | else | |
1473 | subnettot(client, 0, ap, SUBNETTOT_BUF); | |
1474 | } | |
1475 | return strlen(buf); | |
1476 | } | |
1477 | ||
1478 | void | |
1479 | fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF]) | |
1480 | { | |
1481 | char *p = buf; | |
1482 | ||
1483 | *p = '\0'; | |
1484 | ||
1485 | if (c->kind == CK_INSTANCE) | |
1486 | { | |
1487 | if (c->instance_serial != 0) | |
1488 | { | |
1489 | snprintf(p, CONN_INST_BUF, "[%lu]", c->instance_serial); | |
1490 | p += strlen(p); | |
1491 | } | |
1492 | ||
1493 | if (c->policy & POLICY_OPPO) | |
1494 | { | |
1495 | size_t w = fmt_client(&c->spd.this.client, &c->spd.this.host_addr, " ", p); | |
1496 | ||
1497 | p += w; | |
1498 | ||
1499 | strcpy(p, w == 0? " ..." : "=== ..."); | |
1500 | p += strlen(p); | |
1501 | ||
1502 | addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF); | |
1503 | p += strlen(p); | |
1504 | ||
1505 | (void) fmt_client(&c->spd.that.client, &c->spd.that.host_addr, "===", p); | |
1506 | } | |
1507 | else | |
1508 | { | |
1509 | *p++ = ' '; | |
1510 | addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF); | |
1511 | #ifdef NAT_TRAVERSAL | |
1512 | if (c->spd.that.host_port != pluto_port) | |
1513 | { | |
1514 | p += strlen(p); | |
1515 | sprintf(p, ":%d", c->spd.that.host_port); | |
1516 | } | |
1517 | #endif | |
1518 | } | |
1519 | } | |
1520 | } | |
1521 | ||
1522 | /* Find an existing connection for a trapped outbound packet. | |
1523 | * This is attempted before we bother with gateway discovery. | |
1524 | * + this connection is routed or instance_of_routed_template | |
1525 | * (i.e. approved for on-demand) | |
1526 | * + this subnet contains our_client (or we are our_client) | |
1527 | * + that subnet contains peer_client (or peer is peer_client) | |
1528 | * + don't care about Phase 1 IDs (we don't know) | |
1529 | * Note: result may still need to be instantiated. | |
1530 | * The winner has the highest policy priority. | |
1531 | * | |
1532 | * If there are several with that priority, we give preference to | |
1533 | * the first one that is an instance. | |
1534 | * | |
1535 | * See also build_outgoing_opportunistic_connection. | |
1536 | */ | |
1537 | struct connection * | |
1538 | find_connection_for_clients(struct spd_route **srp, | |
1539 | const ip_address *our_client, | |
1540 | const ip_address *peer_client, | |
1541 | int transport_proto) | |
1542 | { | |
1543 | struct connection *c = connections, *best = NULL; | |
1544 | policy_prio_t best_prio = BOTTOM_PRIO; | |
1545 | struct spd_route *sr; | |
1546 | struct spd_route *best_sr = NULL; | |
1547 | int our_port = ntohs(portof(our_client)); | |
1548 | int peer_port = ntohs(portof(peer_client)); | |
1549 | ||
1550 | passert(!isanyaddr(our_client) && !isanyaddr(peer_client)); | |
1551 | #ifdef DEBUG | |
1552 | if (DBGP(DBG_CONTROL)) | |
1553 | { | |
1554 | char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF]; | |
1555 | ||
1556 | addrtot(our_client, 0, ocb, sizeof(ocb)); | |
1557 | addrtot(peer_client, 0, pcb, sizeof(pcb)); | |
1558 | DBG_log("find_connection: " | |
1559 | "looking for policy for connection: %s:%d/%d -> %s:%d/%d" | |
1560 | , ocb, transport_proto, our_port, pcb, transport_proto, peer_port); | |
1561 | } | |
1562 | #endif /* DEBUG */ | |
1563 | ||
1564 | for (c = connections; c != NULL; c = c->ac_next) | |
1565 | { | |
1566 | if (c->kind == CK_GROUP) | |
1567 | continue; | |
1568 | ||
1569 | for (sr = &c->spd; best!=c && sr; sr = sr->next) | |
1570 | { | |
1571 | if ((routed(sr->routing) || c->instance_initiation_ok) | |
1572 | && addrinsubnet(our_client, &sr->this.client) | |
1573 | && addrinsubnet(peer_client, &sr->that.client) | |
1574 | && addrinsubnet(peer_client, &sr->that.client) | |
1575 | && (!sr->this.protocol || transport_proto == sr->this.protocol) | |
1576 | && (!sr->this.port || our_port == sr->this.port) | |
1577 | && (!sr->that.port || peer_port == sr->that.port)) | |
1578 | { | |
1579 | char cib[CONN_INST_BUF]; | |
1580 | char cib2[CONN_INST_BUF]; | |
1581 | ||
1582 | policy_prio_t prio = 8 * (c->prio + (c->kind == CK_INSTANCE)) | |
1583 | + 2 * (sr->this.port == our_port) | |
1584 | + 2 * (sr->that.port == peer_port) | |
1585 | + (sr->this.protocol == transport_proto); | |
1586 | ||
1587 | #ifdef DEBUG | |
1588 | if (DBGP(DBG_CONTROL|DBG_CONTROLMORE)) | |
1589 | { | |
1590 | char c_ocb[SUBNETTOT_BUF], c_pcb[SUBNETTOT_BUF]; | |
1591 | ||
1592 | subnettot(&c->spd.this.client, 0, c_ocb, sizeof(c_ocb)); | |
1593 | subnettot(&c->spd.that.client, 0, c_pcb, sizeof(c_pcb)); | |
1594 | DBG_log("find_connection: conn \"%s\"%s has compatible peers: %s->%s [pri: %ld]" | |
1595 | , c->name | |
1596 | , (fmt_conn_instance(c, cib), cib) | |
1597 | , c_ocb, c_pcb, prio); | |
1598 | } | |
1599 | #endif /* DEBUG */ | |
1600 | ||
1601 | if (best == NULL) | |
1602 | { | |
1603 | best = c; | |
1604 | best_sr = sr; | |
1605 | best_prio = prio; | |
1606 | } | |
1607 | ||
1608 | DBG(DBG_CONTROLMORE, | |
1609 | DBG_log("find_connection: " | |
1610 | "comparing best \"%s\"%s [pri:%ld]{%p} (child %s) to \"%s\"%s [pri:%ld]{%p} (child %s)" | |
1611 | , best->name | |
1612 | , (fmt_conn_instance(best, cib), cib) | |
1613 | , best_prio | |
1614 | , best | |
1615 | , (best->policy_next ? best->policy_next->name : "none") | |
1616 | , c->name | |
1617 | , (fmt_conn_instance(c, cib2), cib2) | |
1618 | , prio | |
1619 | , c | |
1620 | , (c->policy_next ? c->policy_next->name : "none"))); | |
1621 | ||
1622 | if (prio > best_prio) | |
1623 | { | |
1624 | best = c; | |
1625 | best_sr = sr; | |
1626 | best_prio = prio; | |
1627 | } | |
1628 | } | |
1629 | } | |
1630 | } | |
1631 | ||
1632 | if (best!= NULL && NEVER_NEGOTIATE(best->policy)) | |
1633 | best = NULL; | |
1634 | ||
1635 | if (srp != NULL && best != NULL) | |
1636 | *srp = best_sr; | |
1637 | ||
1638 | #ifdef DEBUG | |
1639 | if (DBGP(DBG_CONTROL)) | |
1640 | { | |
1641 | if (best) | |
1642 | { | |
1643 | char cib[CONN_INST_BUF]; | |
1644 | DBG_log("find_connection: concluding with \"%s\"%s [pri:%ld]{%p} kind=%s" | |
1645 | , best->name | |
1646 | , (fmt_conn_instance(best, cib), cib) | |
1647 | , best_prio | |
1648 | , best | |
1649 | , enum_name(&connection_kind_names, best->kind)); | |
1650 | } else { | |
1651 | DBG_log("find_connection: concluding with empty"); | |
1652 | } | |
1653 | } | |
1654 | #endif /* DEBUG */ | |
1655 | ||
1656 | return best; | |
1657 | } | |
1658 | ||
1659 | /* Find and instantiate a connection for an outgoing Opportunistic connection. | |
1660 | * We've already discovered its gateway. | |
1661 | * We look for a the connection such that: | |
1662 | * + this is one of our interfaces | |
1663 | * + this subnet contains our_client (or we are our_client) | |
1664 | * (we will specialize the client). We prefer the smallest such subnet. | |
1665 | * + that subnet contains peer_clent (we will specialize the client). | |
1666 | * We prefer the smallest such subnet. | |
1667 | * + is opportunistic | |
1668 | * + that peer is NO_IP | |
1669 | * + don't care about Phase 1 IDs (probably should be default) | |
1670 | * We could look for a connection that already had the desired peer | |
1671 | * (rather than NO_IP) specified, but it doesn't seem worth the | |
1672 | * bother. | |
1673 | * | |
1674 | * We look for the routed policy applying to the narrowest subnets. | |
1675 | * We only succeed if we find such a policy AND it is satisfactory. | |
1676 | * | |
1677 | * The body of the inner loop is a lot like that in | |
1678 | * find_connection_for_clients. In this case, we know the gateways | |
1679 | * that we need to instantiate an opportunistic connection. | |
1680 | */ | |
1681 | struct connection * | |
1682 | build_outgoing_opportunistic_connection(struct gw_info *gw | |
1683 | ,const ip_address *our_client | |
1684 | ,const ip_address *peer_client) | |
1685 | { | |
1686 | struct iface *p; | |
1687 | struct connection *best = NULL; | |
1688 | struct spd_route *sr, *bestsr; | |
1689 | char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF]; | |
1690 | ||
1691 | addrtot(our_client, 0, ocb, sizeof(ocb)); | |
1692 | addrtot(peer_client, 0, pcb, sizeof(pcb)); | |
1693 | ||
1694 | passert(!isanyaddr(our_client) && !isanyaddr(peer_client)); | |
1695 | ||
1696 | /* We don't know his ID yet, so gw id must be an ipaddr */ | |
1697 | passert(gw->key != NULL); | |
1698 | passert(id_is_ipaddr(&gw->gw_id)); | |
1699 | ||
1700 | /* for each of our addresses... */ | |
1701 | for (p = interfaces; p != NULL; p = p->next) | |
1702 | { | |
1703 | /* go through those connections with our address and NO_IP as hosts | |
1704 | * We cannot know what port the peer would use, so we assume | |
1705 | * that it is pluto_port (makes debugging easier). | |
1706 | */ | |
1707 | struct connection *c = find_host_pair_connections(&p->addr | |
1708 | , pluto_port, (ip_address *)NULL, pluto_port); | |
1709 | ||
1710 | for (; c != NULL; c = c->hp_next) | |
1711 | { | |
1712 | DBG(DBG_OPPO, | |
1713 | DBG_log("checking %s", c->name)); | |
1714 | if (c->kind == CK_GROUP) | |
1715 | { | |
1716 | continue; | |
1717 | } | |
1718 | ||
1719 | for (sr = &c->spd; best!=c && sr; sr = sr->next) | |
1720 | { | |
1721 | if (routed(sr->routing) | |
1722 | && addrinsubnet(our_client, &sr->this.client) | |
1723 | && addrinsubnet(peer_client, &sr->that.client)) | |
1724 | { | |
1725 | if (best == NULL) | |
1726 | { | |
1727 | best = c; | |
1728 | break; | |
1729 | } | |
1730 | ||
1731 | DBG(DBG_OPPO, | |
1732 | DBG_log("comparing best %s to %s" | |
1733 | , best->name, c->name)); | |
1734 | ||
1735 | for (bestsr = &best->spd; best!=c && bestsr; bestsr=bestsr->next) | |
1736 | { | |
1737 | if (!subnetinsubnet(&bestsr->this.client, &sr->this.client) | |
1738 | || (samesubnet(&bestsr->this.client, &sr->this.client) | |
1739 | && !subnetinsubnet(&bestsr->that.client | |
1740 | , &sr->that.client))) | |
1741 | { | |
1742 | best = c; | |
1743 | } | |
1744 | } | |
1745 | } | |
1746 | } | |
1747 | } | |
1748 | } | |
1749 | ||
1750 | if (best == NULL | |
1751 | || NEVER_NEGOTIATE(best->policy) | |
1752 | || (best->policy & POLICY_OPPO) == LEMPTY | |
1753 | || best->kind != CK_TEMPLATE) | |
1754 | return NULL; | |
1755 | else | |
1756 | return oppo_instantiate(best, &gw->gw_id.ip_addr, NULL, gw | |
1757 | , our_client, peer_client); | |
1758 | } | |
1759 | ||
1760 | bool | |
1761 | orient(struct connection *c) | |
1762 | { | |
1763 | struct spd_route *sr; | |
1764 | ||
1765 | if (!oriented(*c)) | |
1766 | { | |
1767 | struct iface *p; | |
1768 | ||
1769 | for (sr = &c->spd; sr; sr = sr->next) | |
1770 | { | |
1771 | /* Note: this loop does not stop when it finds a match: | |
1772 | * it continues checking to catch any ambiguity. | |
1773 | */ | |
1774 | for (p = interfaces; p != NULL; p = p->next) | |
1775 | { | |
1776 | #ifdef NAT_TRAVERSAL | |
1777 | if (p->ike_float) continue; | |
1778 | #endif | |
1779 | for (;;) | |
1780 | { | |
1781 | /* check if this interface matches this end */ | |
1782 | if (sameaddr(&sr->this.host_addr, &p->addr) | |
1783 | && (!no_klips || sr->this.host_port == pluto_port)) | |
1784 | { | |
1785 | if (oriented(*c)) | |
1786 | { | |
1787 | if (c->interface == p) | |
1788 | loglog(RC_LOG_SERIOUS | |
1789 | , "both sides of \"%s\" are our interface %s!" | |
1790 | , c->name, p->rname); | |
1791 | else | |
1792 | loglog(RC_LOG_SERIOUS, "two interfaces match \"%s\" (%s, %s)" | |
1793 | , c->name, c->interface->rname, p->rname); | |
1794 | c->interface = NULL; /* withdraw orientation */ | |
1795 | return FALSE; | |
1796 | } | |
1797 | c->interface = p; | |
1798 | } | |
1799 | ||
1800 | /* done with this interface if it doesn't match that end */ | |
1801 | if (!(sameaddr(&sr->that.host_addr, &p->addr) | |
1802 | && (!no_klips || sr->that.host_port == pluto_port))) | |
1803 | break; | |
1804 | ||
1805 | /* swap ends and try again. | |
1806 | * It is a little tricky to see that this loop will stop. | |
1807 | * Only continue if the far side matches. | |
1808 | * If both sides match, there is an error-out. | |
1809 | */ | |
1810 | { | |
1811 | struct end t = sr->this; | |
1812 | ||
1813 | sr->this = sr->that; | |
1814 | sr->that = t; | |
1815 | } | |
1816 | } | |
1817 | } | |
1818 | } | |
1819 | } | |
1820 | return oriented(*c); | |
1821 | } | |
1822 | ||
1823 | void | |
1824 | initiate_connection(const char *name, int whackfd) | |
1825 | { | |
1826 | struct connection *c = con_by_name(name, TRUE); | |
1827 | ||
1828 | if (c != NULL) | |
1829 | { | |
1830 | set_cur_connection(c); | |
1831 | if (!oriented(*c)) | |
1832 | { | |
1833 | loglog(RC_ORIENT, "we have no ipsecN interface for either end of this connection"); | |
1834 | } | |
1835 | else if (NEVER_NEGOTIATE(c->policy)) | |
1836 | { | |
1837 | loglog(RC_INITSHUNT | |
1838 | , "cannot initiate an authby=never connection"); | |
1839 | } | |
1840 | else if (c->kind != CK_PERMANENT) | |
1841 | { | |
1842 | if (isanyaddr(&c->spd.that.host_addr)) | |
1843 | loglog(RC_NOPEERIP, "cannot initiate connection without knowing peer IP address"); | |
1844 | else | |
1845 | loglog(RC_WILDCARD, "cannot initiate connection with ID wildcards"); | |
1846 | } | |
1847 | else | |
1848 | { | |
1849 | /* We will only request an IPsec SA if policy isn't empty | |
1850 | * (ignoring Main Mode items). | |
1851 | * This is a fudge, but not yet important. | |
1852 | * If we are to proceed asynchronously, whackfd will be NULL_FD. | |
1853 | */ | |
1854 | c->policy |= POLICY_UP; | |
1855 | /* do we have to prompt for a PIN code? */ | |
1856 | if (c->spd.this.sc != NULL && !c->spd.this.sc->valid && whackfd != NULL_FD) | |
1857 | scx_get_pin(c->spd.this.sc, whackfd); | |
1858 | ||
1859 | if (c->spd.this.sc != NULL && !c->spd.this.sc->valid) | |
1860 | { | |
1861 | loglog(RC_NOVALIDPIN, "cannot initiate connection without valid PIN"); | |
1862 | } | |
1863 | else | |
1864 | { | |
1865 | ipsecdoi_initiate(whackfd, c, c->policy, 1, SOS_NOBODY); | |
1866 | whackfd = NULL_FD; /* protect from close */ | |
1867 | } | |
1868 | } | |
1869 | reset_cur_connection(); | |
1870 | } | |
1871 | close_any(whackfd); | |
1872 | } | |
1873 | ||
1874 | /* (Possibly) Opportunistic Initiation: | |
1875 | * Knowing clients (single IP addresses), try to build an tunnel. | |
1876 | * This may involve discovering a gateway and instantiating an | |
1877 | * Opportunistic connection. Called when a packet is caught by | |
1878 | * a %trap, or when whack --oppohere --oppothere is used. | |
1879 | * It may turn out that an existing or non-opporunistic connnection | |
1880 | * can handle the traffic. | |
1881 | * | |
1882 | * Most of the code will be restarted if an ADNS request is made | |
1883 | * to discover the gateway. The only difference between the first | |
1884 | * and second entry is whether gateways_from_dns is NULL or not. | |
1885 | * initiate_opportunistic: initial entrypoint | |
1886 | * continue_oppo: where we pickup when ADNS result arrives | |
1887 | * initiate_opportunistic_body: main body shared by above routines | |
1888 | * cannot_oppo: a helper function to log a diagnostic | |
1889 | * This structure repeats a lot of code when the ADNS result arrives. | |
1890 | * This seems like a waste, but anything learned the first time through | |
1891 | * may no longer be true! | |
1892 | * | |
1893 | * After the first IKE message is sent, the regular state machinery | |
1894 | * carries negotiation forward. | |
1895 | */ | |
1896 | ||
1897 | enum find_oppo_step { | |
1898 | fos_start, | |
1899 | fos_myid_ip_txt, | |
1900 | fos_myid_hostname_txt, | |
1901 | fos_myid_ip_key, | |
1902 | fos_myid_hostname_key, | |
1903 | fos_our_client, | |
1904 | fos_our_txt, | |
1905 | #ifdef USE_KEYRR | |
1906 | fos_our_key, | |
1907 | #endif /* USE_KEYRR */ | |
1908 | fos_his_client, | |
1909 | fos_done | |
1910 | }; | |
1911 | ||
1912 | #ifdef DEBUG | |
1913 | static const char *const oppo_step_name[] = { | |
1914 | "fos_start", | |
1915 | "fos_myid_ip_txt", | |
1916 | "fos_myid_hostname_txt", | |
1917 | "fos_myid_ip_key", | |
1918 | "fos_myid_hostname_key", | |
1919 | "fos_our_client", | |
1920 | "fos_our_txt", | |
1921 | #ifdef USE_KEYRR | |
1922 | "fos_our_key", | |
1923 | #endif /* USE_KEYRR */ | |
1924 | "fos_his_client", | |
1925 | "fos_done" | |
1926 | }; | |
1927 | #endif /* DEBUG */ | |
1928 | ||
1929 | struct find_oppo_bundle { | |
1930 | enum find_oppo_step step; | |
1931 | err_t want; | |
1932 | bool failure_ok; /* if true, continue_oppo should not die on DNS failure */ | |
1933 | ip_address our_client; /* not pointer! */ | |
1934 | ip_address peer_client; | |
1935 | int transport_proto; | |
1936 | bool held; | |
1937 | policy_prio_t policy_prio; | |
1938 | ipsec_spi_t failure_shunt; /* in host order! 0 for delete. */ | |
1939 | int whackfd; | |
1940 | }; | |
1941 | ||
1942 | struct find_oppo_continuation { | |
1943 | struct adns_continuation ac; /* common prefix */ | |
1944 | struct find_oppo_bundle b; | |
1945 | }; | |
1946 | ||
1947 | static void | |
1948 | cannot_oppo(struct connection *c | |
1949 | , struct find_oppo_bundle *b | |
1950 | , err_t ugh) | |
1951 | { | |
1952 | char pcb[ADDRTOT_BUF]; | |
1953 | char ocb[ADDRTOT_BUF]; | |
1954 | ||
1955 | addrtot(&b->peer_client, 0, pcb, sizeof(pcb)); | |
1956 | addrtot(&b->our_client, 0, ocb, sizeof(ocb)); | |
1957 | ||
1958 | DBG(DBG_DNS | DBG_OPPO, DBG_log("Can't Opportunistically initiate for %s to %s: %s" | |
1959 | , ocb, pcb, ugh)); | |
1960 | ||
1961 | whack_log(RC_OPPOFAILURE | |
1962 | , "Can't Opportunistically initiate for %s to %s: %s" | |
1963 | , ocb, pcb, ugh); | |
1964 | ||
1965 | if (c != NULL && c->policy_next != NULL) | |
1966 | { | |
1967 | /* there is some policy that comes afterwards */ | |
1968 | struct spd_route *shunt_spd; | |
1969 | struct connection *nc = c->policy_next; | |
1970 | struct state *st; | |
1971 | ||
1972 | passert(c->kind == CK_TEMPLATE); | |
1973 | passert(c->policy_next->kind == CK_PERMANENT); | |
1974 | ||
1975 | DBG(DBG_OPPO, DBG_log("OE failed for %s to %s, but %s overrides shunt" | |
1976 | , ocb, pcb, c->policy_next->name)); | |
1977 | ||
1978 | /* | |
1979 | * okay, here we need add to the "next" policy, which is ought | |
1980 | * to be an instance. | |
1981 | * We will add another entry to the spd_route list for the specific | |
1982 | * situation that we have. | |
1983 | */ | |
1984 | ||
1985 | shunt_spd = clone_thing(nc->spd, "shunt eroute policy"); | |
1986 | ||
1987 | shunt_spd->next = nc->spd.next; | |
1988 | nc->spd.next = shunt_spd; | |
1989 | ||
1990 | happy(addrtosubnet(&b->peer_client, &shunt_spd->that.client)); | |
1991 | ||
1992 | if (sameaddr(&b->peer_client, &shunt_spd->that.host_addr)) | |
1993 | shunt_spd->that.has_client = FALSE; | |
1994 | ||
1995 | /* | |
1996 | * override the tunnel destination with the one from the secondaried | |
1997 | * policy | |
1998 | */ | |
1999 | shunt_spd->that.host_addr = nc->spd.that.host_addr; | |
2000 | ||
2001 | /* now, lookup the state, and poke it up. | |
2002 | */ | |
2003 | ||
2004 | st = state_with_serialno(nc->newest_ipsec_sa); | |
2005 | ||
2006 | /* XXX what to do if the IPSEC SA has died? */ | |
2007 | passert(st != NULL); | |
2008 | ||
2009 | /* link the new connection instance to the state's list of | |
2010 | * connections | |
2011 | */ | |
2012 | ||
2013 | DBG(DBG_OPPO, DBG_log("installing state: %ld for %s to %s" | |
2014 | , nc->newest_ipsec_sa | |
2015 | , ocb, pcb)); | |
2016 | ||
2017 | #ifdef DEBUG | |
2018 | if (DBGP(DBG_OPPO | DBG_CONTROLMORE)) | |
2019 | { | |
2020 | char state_buf[LOG_WIDTH]; | |
2021 | char state_buf2[LOG_WIDTH]; | |
2022 | time_t n = now(); | |
2023 | ||
2024 | fmt_state(st, n, state_buf, sizeof(state_buf) | |
2025 | , state_buf2, sizeof(state_buf2)); | |
2026 | DBG_log("cannot_oppo, failure SA1: %s", state_buf); | |
2027 | DBG_log("cannot_oppo, failure SA2: %s", state_buf2); | |
2028 | } | |
2029 | #endif /* DEBUG */ | |
2030 | ||
2031 | if (!route_and_eroute(c, shunt_spd, st)) | |
2032 | { | |
2033 | whack_log(RC_OPPOFAILURE | |
2034 | , "failed to instantiate shunt policy %s for %s to %s" | |
2035 | , c->name | |
2036 | , ocb, pcb); | |
2037 | } | |
2038 | return; | |
2039 | } | |
2040 | ||
2041 | #ifdef KLIPS | |
2042 | if (b->held) | |
2043 | { | |
2044 | /* Replace HOLD with b->failure_shunt. | |
2045 | * If no b->failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE. | |
2046 | */ | |
2047 | if (b->failure_shunt == 0) | |
2048 | { | |
2049 | DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; installing %%pass" | |
2050 | , ocb, pcb)); | |
2051 | } | |
2052 | ||
2053 | (void) replace_bare_shunt(&b->our_client, &b->peer_client | |
2054 | , b->policy_prio | |
2055 | , b->failure_shunt | |
2056 | , b->failure_shunt != 0 | |
2057 | , b->transport_proto | |
2058 | , ugh); | |
2059 | } | |
2060 | #endif | |
2061 | } | |
2062 | ||
2063 | static void initiate_opportunistic_body(struct find_oppo_bundle *b | |
2064 | , struct adns_continuation *ac, err_t ac_ugh); /* forward */ | |
2065 | ||
2066 | void | |
2067 | initiate_opportunistic(const ip_address *our_client | |
2068 | , const ip_address *peer_client | |
2069 | , int transport_proto | |
2070 | , bool held | |
2071 | , int whackfd) | |
2072 | { | |
2073 | struct find_oppo_bundle b; | |
2074 | ||
2075 | b.want = (whackfd == NULL_FD ? "whack" : "acquire"); | |
2076 | b.failure_ok = FALSE; | |
2077 | b.our_client = *our_client; | |
2078 | b.peer_client = *peer_client; | |
2079 | b.transport_proto = transport_proto; | |
2080 | b.held = held; | |
2081 | b.policy_prio = BOTTOM_PRIO; | |
2082 | b.failure_shunt = 0; | |
2083 | b.whackfd = whackfd; | |
2084 | b.step = fos_start; | |
2085 | initiate_opportunistic_body(&b, NULL, NULL); | |
2086 | } | |
2087 | ||
2088 | static void | |
2089 | continue_oppo(struct adns_continuation *acr, err_t ugh) | |
2090 | { | |
2091 | struct find_oppo_continuation *cr = (void *)acr; /* inherit, damn you! */ | |
2092 | struct connection *c; | |
2093 | bool was_held = cr->b.held; | |
2094 | int whackfd = cr->b.whackfd; | |
2095 | ||
2096 | /* note: cr->id has no resources; cr->sgw_id is id_none: | |
2097 | * neither need freeing. | |
2098 | */ | |
2099 | whack_log_fd = whackfd; | |
2100 | ||
2101 | #ifdef KLIPS | |
2102 | /* Discover and record whether %hold has gone away. | |
2103 | * This could have happened while we were awaiting DNS. | |
2104 | * We must check BEFORE any call to cannot_oppo. | |
2105 | */ | |
2106 | if (was_held) | |
2107 | cr->b.held = has_bare_hold(&cr->b.our_client, &cr->b.peer_client | |
2108 | , cr->b.transport_proto); | |
2109 | #endif | |
2110 | ||
2111 | #ifdef DEBUG | |
2112 | /* if we're going to ignore the error, at least note it in debugging log */ | |
2113 | if (cr->b.failure_ok && ugh != NULL) | |
2114 | { | |
2115 | DBG(DBG_CONTROL | DBG_DNS, | |
2116 | { | |
2117 | char ocb[ADDRTOT_BUF]; | |
2118 | char pcb[ADDRTOT_BUF]; | |
2119 | ||
2120 | addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb)); | |
2121 | addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb)); | |
2122 | DBG_log("continuing from failed DNS lookup for %s, %s to %s: %s" | |
2123 | , cr->b.want, ocb, pcb, ugh); | |
2124 | }); | |
2125 | } | |
2126 | #endif | |
2127 | ||
2128 | if (!cr->b.failure_ok && ugh != NULL) | |
2129 | { | |
2130 | c = find_connection_for_clients(NULL, &cr->b.our_client, &cr->b.peer_client | |
2131 | , cr->b.transport_proto); | |
2132 | cannot_oppo(c, &cr->b | |
2133 | , builddiag("%s: %s", cr->b.want, ugh)); | |
2134 | } | |
2135 | else if (was_held && !cr->b.held) | |
2136 | { | |
2137 | /* was_held indicates we were started due to a %trap firing | |
2138 | * (as opposed to a "whack --oppohere --oppothere"). | |
2139 | * Since the %hold has gone, we can assume that somebody else | |
2140 | * has beaten us to the punch. We can go home. But lets log it. | |
2141 | */ | |
2142 | char ocb[ADDRTOT_BUF]; | |
2143 | char pcb[ADDRTOT_BUF]; | |
2144 | ||
2145 | addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb)); | |
2146 | addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb)); | |
2147 | ||
2148 | loglog(RC_COMMENT | |
2149 | , "%%hold otherwise handled during DNS lookup for Opportunistic Initiation for %s to %s" | |
2150 | , ocb, pcb); | |
2151 | } | |
2152 | else | |
2153 | { | |
2154 | initiate_opportunistic_body(&cr->b, &cr->ac, ugh); | |
2155 | whackfd = NULL_FD; /* was handed off */ | |
2156 | } | |
2157 | ||
2158 | whack_log_fd = NULL_FD; | |
2159 | close_any(whackfd); | |
2160 | } | |
2161 | ||
2162 | #ifdef USE_KEYRR | |
2163 | static err_t | |
2164 | check_key_recs(enum myid_state try_state | |
2165 | , const struct connection *c | |
2166 | , struct adns_continuation *ac) | |
2167 | { | |
2168 | /* Check if KEY lookup yielded good results. | |
2169 | * Looking up based on our ID. Used if | |
2170 | * client is ourself, or if TXT had no public key. | |
2171 | * Note: if c is different this time, there is | |
2172 | * a chance that we did the wrong query. | |
2173 | * If so, treat as a kind of failure. | |
2174 | */ | |
2175 | enum myid_state old_myid_state = myid_state; | |
2176 | const struct RSA_private_key *our_RSA_pri; | |
2177 | err_t ugh = NULL; | |
2178 | ||
2179 | myid_state = try_state; | |
2180 | ||
2181 | if (old_myid_state != myid_state | |
2182 | && old_myid_state == MYID_SPECIFIED) | |
2183 | { | |
2184 | ugh = "%myid was specified while we were guessing"; | |
2185 | } | |
2186 | else if ((our_RSA_pri = get_RSA_private_key(c)) == NULL) | |
2187 | { | |
2188 | ugh = "we don't know our own RSA key"; | |
2189 | } | |
2190 | else if (!same_id(&ac->id, &c->spd.this.id)) | |
2191 | { | |
2192 | ugh = "our ID changed underfoot"; | |
2193 | } | |
2194 | else | |
2195 | { | |
2196 | /* Similar to code in RSA_check_signature | |
2197 | * for checking the other side. | |
2198 | */ | |
2199 | pubkey_list_t *kr; | |
2200 | ||
2201 | ugh = "no KEY RR found for us"; | |
2202 | for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next) | |
2203 | { | |
2204 | ugh = "all our KEY RRs have the wrong public key"; | |
2205 | if (kr->key->alg == PUBKEY_ALG_RSA | |
2206 | && same_RSA_public_key(&our_RSA_pri->pub, &kr->key->u.rsa)) | |
2207 | { | |
2208 | ugh = NULL; /* good! */ | |
2209 | break; | |
2210 | } | |
2211 | } | |
2212 | } | |
2213 | if (ugh != NULL) | |
2214 | myid_state = old_myid_state; | |
2215 | return ugh; | |
2216 | } | |
2217 | #endif /* USE_KEYRR */ | |
2218 | ||
2219 | static err_t | |
2220 | check_txt_recs(enum myid_state try_state | |
2221 | , const struct connection *c | |
2222 | , struct adns_continuation *ac) | |
2223 | { | |
2224 | /* Check if TXT lookup yielded good results. | |
2225 | * Looking up based on our ID. Used if | |
2226 | * client is ourself, or if TXT had no public key. | |
2227 | * Note: if c is different this time, there is | |
2228 | * a chance that we did the wrong query. | |
2229 | * If so, treat as a kind of failure. | |
2230 | */ | |
2231 | enum myid_state old_myid_state = myid_state; | |
2232 | const struct RSA_private_key *our_RSA_pri; | |
2233 | err_t ugh = NULL; | |
2234 | ||
2235 | myid_state = try_state; | |
2236 | ||
2237 | if (old_myid_state != myid_state | |
2238 | && old_myid_state == MYID_SPECIFIED) | |
2239 | { | |
2240 | ugh = "%myid was specified while we were guessing"; | |
2241 | } | |
2242 | else if ((our_RSA_pri = get_RSA_private_key(c)) == NULL) | |
2243 | { | |
2244 | ugh = "we don't know our own RSA key"; | |
2245 | } | |
2246 | else if (!same_id(&ac->id, &c->spd.this.id)) | |
2247 | { | |
2248 | ugh = "our ID changed underfoot"; | |
2249 | } | |
2250 | else | |
2251 | { | |
2252 | /* Similar to code in RSA_check_signature | |
2253 | * for checking the other side. | |
2254 | */ | |
2255 | struct gw_info *gwp; | |
2256 | ||
2257 | ugh = "no TXT RR found for us"; | |
2258 | for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next) | |
2259 | { | |
2260 | ugh = "all our TXT RRs have the wrong public key"; | |
2261 | if (gwp->key->alg == PUBKEY_ALG_RSA | |
2262 | && same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa)) | |
2263 | { | |
2264 | ugh = NULL; /* good! */ | |
2265 | break; | |
2266 | } | |
2267 | } | |
2268 | } | |
2269 | if (ugh != NULL) | |
2270 | myid_state = old_myid_state; | |
2271 | return ugh; | |
2272 | } | |
2273 | ||
2274 | ||
2275 | /* note: gateways_from_dns must be NULL iff this is the first call */ | |
2276 | static void | |
2277 | initiate_opportunistic_body(struct find_oppo_bundle *b | |
2278 | , struct adns_continuation *ac | |
2279 | , err_t ac_ugh) | |
2280 | { | |
2281 | struct connection *c; | |
2282 | struct spd_route *sr; | |
2283 | ||
2284 | /* What connection shall we use? | |
2285 | * First try for one that explicitly handles the clients. | |
2286 | */ | |
2287 | DBG(DBG_CONTROL, | |
2288 | { | |
2289 | char ours[ADDRTOT_BUF]; | |
2290 | char his[ADDRTOT_BUF]; | |
2291 | int ourport; | |
2292 | int hisport; | |
2293 | ||
2294 | addrtot(&b->our_client, 0, ours, sizeof(ours)); | |
2295 | addrtot(&b->peer_client, 0, his, sizeof(his)); | |
2296 | ourport = ntohs(portof(&b->our_client)); | |
2297 | hisport = ntohs(portof(&b->peer_client)); | |
2298 | DBG_log("initiate on demand from %s:%d to %s:%d proto=%d state: %s because: %s" | |
2299 | , ours, ourport, his, hisport, b->transport_proto | |
2300 | , oppo_step_name[b->step], b->want); | |
2301 | }); | |
2302 | if (isanyaddr(&b->our_client) || isanyaddr(&b->peer_client)) | |
2303 | { | |
2304 | cannot_oppo(NULL, b, "impossible IP address"); | |
2305 | } | |
2306 | else if ((c = find_connection_for_clients(&sr | |
2307 | , &b->our_client | |
2308 | , &b->peer_client | |
2309 | , b->transport_proto)) == NULL) | |
2310 | { | |
2311 | /* No connection explicitly handles the clients and there | |
2312 | * are no Opportunistic connections -- whine and give up. | |
2313 | * The failure policy cannot be gotten from a connection; we pick %pass. | |
2314 | */ | |
2315 | cannot_oppo(NULL, b, "no routed Opportunistic template covers this pair"); | |
2316 | } | |
2317 | else if (c->kind != CK_TEMPLATE) | |
2318 | { | |
2319 | /* We've found a connection that can serve. | |
2320 | * Do we have to initiate it? | |
2321 | * Not if there is currently an IPSEC SA. | |
2322 | * But if there is an IPSEC SA, then KLIPS would not | |
2323 | * have generated the acquire. So we assume that there isn't one. | |
2324 | * This may be redundant if a non-opportunistic | |
2325 | * negotiation is already being attempted. | |
2326 | */ | |
2327 | ||
2328 | /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */ | |
2329 | ||
2330 | if(c->kind == CK_INSTANCE) | |
2331 | { | |
2332 | char cib[CONN_INST_BUF]; | |
2333 | /* there is already an instance being negotiated, no nothing */ | |
2334 | DBG(DBG_CONTROL, DBG_log("found existing instance \"%s\"%s, rekeying it" | |
2335 | , c->name | |
2336 | , (fmt_conn_instance(c, cib), cib))); | |
2337 | /* XXX-mcr - return; */ | |
2338 | } | |
2339 | ||
2340 | /* otherwise, there is some kind of static conn that can handle | |
2341 | * this connection, so we initiate it */ | |
2342 | ||
2343 | #ifdef KLIPS | |
2344 | if (b->held) | |
2345 | { | |
2346 | /* what should we do on failure? */ | |
2347 | (void) assign_hold(c, sr, b->transport_proto, &b->our_client, &b->peer_client); | |
2348 | } | |
2349 | #endif | |
2350 | ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY); | |
2351 | b->whackfd = NULL_FD; /* protect from close */ | |
2352 | } | |
2353 | else | |
2354 | { | |
2355 | /* We are handling an opportunistic situation. | |
2356 | * This involves several DNS lookup steps that require suspension. | |
2357 | * Note: many facts might change while we're suspended. | |
2358 | * Here be dragons. | |
2359 | * | |
2360 | * The first chunk of code handles the result of the previous | |
2361 | * DNS query (if any). It also selects the kind of the next step. | |
2362 | * The second chunk initiates the next DNS query (if any). | |
2363 | */ | |
2364 | enum find_oppo_step next_step; | |
2365 | err_t ugh = ac_ugh; | |
2366 | char mycredentialstr[BUF_LEN]; | |
2367 | char cib[CONN_INST_BUF]; | |
2368 | ||
2369 | DBG(DBG_CONTROL, DBG_log("creating new instance from \"%s\"%s" | |
2370 | , c->name | |
2371 | , (fmt_conn_instance(c, cib), cib))); | |
2372 | ||
2373 | ||
2374 | idtoa(&sr->this.id, mycredentialstr, sizeof(mycredentialstr)); | |
2375 | ||
2376 | passert(c->policy & POLICY_OPPO); /* can't initiate Road Warrior connections */ | |
2377 | ||
2378 | /* handle any DNS answer; select next step */ | |
2379 | ||
2380 | switch (b->step) | |
2381 | { | |
2382 | case fos_start: | |
2383 | /* just starting out: select first query step */ | |
2384 | next_step = fos_myid_ip_txt; | |
2385 | break; | |
2386 | ||
2387 | case fos_myid_ip_txt: /* TXT for our default IP address as %myid */ | |
2388 | ugh = check_txt_recs(MYID_IP, c, ac); | |
2389 | if (ugh != NULL) | |
2390 | { | |
2391 | /* cannot use our IP as OE identitiy for initiation */ | |
2392 | DBG(DBG_OPPO, DBG_log("can not use our IP (%s:TXT) as identity: %s" | |
2393 | , myid_str[MYID_IP] | |
2394 | , ugh)); | |
2395 | if (!logged_myid_ip_txt_warning) | |
2396 | { | |
2397 | loglog(RC_LOG_SERIOUS | |
2398 | , "can not use our IP (%s:TXT) as identity: %s" | |
2399 | , myid_str[MYID_IP] | |
2400 | , ugh); | |
2401 | logged_myid_ip_txt_warning = TRUE; | |
2402 | } | |
2403 | ||
2404 | next_step = fos_myid_hostname_txt; | |
2405 | ugh = NULL; /* failure can be recovered from */ | |
2406 | } | |
2407 | else | |
2408 | { | |
2409 | /* we can use our IP as OE identity for initiation */ | |
2410 | if (!logged_myid_ip_txt_warning) | |
2411 | { | |
2412 | loglog(RC_LOG_SERIOUS | |
2413 | , "using our IP (%s:TXT) as identity!" | |
2414 | , myid_str[MYID_IP]); | |
2415 | logged_myid_ip_txt_warning = TRUE; | |
2416 | } | |
2417 | ||
2418 | next_step = fos_our_client; | |
2419 | } | |
2420 | break; | |
2421 | ||
2422 | case fos_myid_hostname_txt: /* TXT for our hostname as %myid */ | |
2423 | ugh = check_txt_recs(MYID_HOSTNAME, c, ac); | |
2424 | if (ugh != NULL) | |
2425 | { | |
2426 | /* cannot use our hostname as OE identitiy for initiation */ | |
2427 | DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:TXT) as identity: %s" | |
2428 | , myid_str[MYID_HOSTNAME] | |
2429 | , ugh)); | |
2430 | if (!logged_myid_fqdn_txt_warning) | |
2431 | { | |
2432 | loglog(RC_LOG_SERIOUS | |
2433 | , "can not use our hostname (%s:TXT) as identity: %s" | |
2434 | , myid_str[MYID_HOSTNAME] | |
2435 | , ugh); | |
2436 | logged_myid_fqdn_txt_warning = TRUE; | |
2437 | } | |
2438 | #ifdef USE_KEYRR | |
2439 | next_step = fos_myid_ip_key; | |
2440 | ugh = NULL; /* failure can be recovered from */ | |
2441 | #endif | |
2442 | } | |
2443 | else | |
2444 | { | |
2445 | /* we can use our hostname as OE identity for initiation */ | |
2446 | if (!logged_myid_fqdn_txt_warning) | |
2447 | { | |
2448 | loglog(RC_LOG_SERIOUS | |
2449 | , "using our hostname (%s:TXT) as identity!" | |
2450 | , myid_str[MYID_HOSTNAME]); | |
2451 | logged_myid_fqdn_txt_warning = TRUE; | |
2452 | } | |
2453 | next_step = fos_our_client; | |
2454 | } | |
2455 | break; | |
2456 | ||
2457 | #ifdef USE_KEYRR | |
2458 | case fos_myid_ip_key: /* KEY for our default IP address as %myid */ | |
2459 | ugh = check_key_recs(MYID_IP, c, ac); | |
2460 | if (ugh != NULL) | |
2461 | { | |
2462 | /* cannot use our IP as OE identitiy for initiation */ | |
2463 | DBG(DBG_OPPO, DBG_log("can not use our IP (%s:KEY) as identity: %s" | |
2464 | , myid_str[MYID_IP] | |
2465 | , ugh)); | |
2466 | if (!logged_myid_ip_key_warning) | |
2467 | { | |
2468 | loglog(RC_LOG_SERIOUS | |
2469 | , "can not use our IP (%s:KEY) as identity: %s" | |
2470 | , myid_str[MYID_IP] | |
2471 | , ugh); | |
2472 | logged_myid_ip_key_warning = TRUE; | |
2473 | } | |
2474 | ||
2475 | next_step = fos_myid_hostname_key; | |
2476 | ugh = NULL; /* failure can be recovered from */ | |
2477 | } | |
2478 | else | |
2479 | { | |
2480 | /* we can use our IP as OE identity for initiation */ | |
2481 | if (!logged_myid_ip_key_warning) | |
2482 | { | |
2483 | loglog(RC_LOG_SERIOUS | |
2484 | , "using our IP (%s:KEY) as identity!" | |
2485 | , myid_str[MYID_IP]); | |
2486 | logged_myid_ip_key_warning = TRUE; | |
2487 | } | |
2488 | next_step = fos_our_client; | |
2489 | } | |
2490 | break; | |
2491 | ||
2492 | case fos_myid_hostname_key: /* KEY for our hostname as %myid */ | |
2493 | ugh = check_key_recs(MYID_HOSTNAME, c, ac); | |
2494 | if (ugh != NULL) | |
2495 | { | |
2496 | /* cannot use our IP as OE identitiy for initiation */ | |
2497 | DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:KEY) as identity: %s" | |
2498 | , myid_str[MYID_HOSTNAME] | |
2499 | , ugh)); | |
2500 | if (!logged_myid_fqdn_key_warning) | |
2501 | { | |
2502 | loglog(RC_LOG_SERIOUS | |
2503 | , "can not use our hostname (%s:KEY) as identity: %s" | |
2504 | , myid_str[MYID_HOSTNAME] | |
2505 | , ugh); | |
2506 | logged_myid_fqdn_key_warning = TRUE; | |
2507 | } | |
2508 | ||
2509 | next_step = fos_myid_hostname_key; | |
2510 | ugh = NULL; /* failure can be recovered from */ | |
2511 | } | |
2512 | else | |
2513 | { | |
2514 | /* we can use our IP as OE identity for initiation */ | |
2515 | if (!logged_myid_fqdn_key_warning) | |
2516 | { | |
2517 | loglog(RC_LOG_SERIOUS | |
2518 | , "using our hostname (%s:KEY) as identity!" | |
2519 | , myid_str[MYID_HOSTNAME]); | |
2520 | logged_myid_fqdn_key_warning = TRUE; | |
2521 | } | |
2522 | next_step = fos_our_client; | |
2523 | } | |
2524 | break; | |
2525 | #endif | |
2526 | ||
2527 | case fos_our_client: /* TXT for our client */ | |
2528 | { | |
2529 | /* Our client is not us: we must check the TXT records. | |
2530 | * Note: if c is different this time, there is | |
2531 | * a chance that we did the wrong query. | |
2532 | * If so, treat as a kind of failure. | |
2533 | */ | |
2534 | const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c); | |
2535 | ||
2536 | next_step = fos_his_client; /* normal situation */ | |
2537 | ||
2538 | passert(sr != NULL); | |
2539 | ||
2540 | if (our_RSA_pri == NULL) | |
2541 | { | |
2542 | ugh = "we don't know our own RSA key"; | |
2543 | } | |
2544 | else if (sameaddr(&sr->this.host_addr, &b->our_client)) | |
2545 | { | |
2546 | /* this wasn't true when we started -- bail */ | |
2547 | ugh = "our IP address changed underfoot"; | |
2548 | } | |
2549 | else if (!same_id(&ac->sgw_id, &sr->this.id)) | |
2550 | { | |
2551 | /* this wasn't true when we started -- bail */ | |
2552 | ugh = "our ID changed underfoot"; | |
2553 | } | |
2554 | else | |
2555 | { | |
2556 | /* Similar to code in quick_inI1_outR1_tail | |
2557 | * for checking the other side. | |
2558 | */ | |
2559 | struct gw_info *gwp; | |
2560 | ||
2561 | ugh = "no TXT RR for our client delegates us"; | |
2562 | for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next) | |
2563 | { | |
2564 | passert(same_id(&gwp->gw_id, &sr->this.id)); | |
2565 | ||
2566 | ugh = "TXT RR for our client has wrong key"; | |
2567 | /* If there is a key from the TXT record, | |
2568 | * we count it as a win if we match the key. | |
2569 | * If there was no key, we have a tentative win: | |
2570 | * we need to check our KEY record to be sure. | |
2571 | */ | |
2572 | if (!gwp->gw_key_present) | |
2573 | { | |
2574 | /* Success, but the TXT had no key | |
2575 | * so we must check our our own KEY records. | |
2576 | */ | |
2577 | next_step = fos_our_txt; | |
2578 | ugh = NULL; /* good! */ | |
2579 | break; | |
2580 | } | |
2581 | if (same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa)) | |
2582 | { | |
2583 | ugh = NULL; /* good! */ | |
2584 | break; | |
2585 | } | |
2586 | } | |
2587 | } | |
2588 | } | |
2589 | break; | |
2590 | ||
2591 | case fos_our_txt: /* TXT for us */ | |
2592 | { | |
2593 | /* Check if TXT lookup yielded good results. | |
2594 | * Looking up based on our ID. Used if | |
2595 | * client is ourself, or if TXT had no public key. | |
2596 | * Note: if c is different this time, there is | |
2597 | * a chance that we did the wrong query. | |
2598 | * If so, treat as a kind of failure. | |
2599 | */ | |
2600 | const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c); | |
2601 | ||
2602 | next_step = fos_his_client; /* unless we decide to look for KEY RR */ | |
2603 | ||
2604 | if (our_RSA_pri == NULL) | |
2605 | { | |
2606 | ugh = "we don't know our own RSA key"; | |
2607 | } | |
2608 | else if (!same_id(&ac->id, &c->spd.this.id)) | |
2609 | { | |
2610 | ugh = "our ID changed underfoot"; | |
2611 | } | |
2612 | else | |
2613 | { | |
2614 | /* Similar to code in RSA_check_signature | |
2615 | * for checking the other side. | |
2616 | */ | |
2617 | struct gw_info *gwp; | |
2618 | ||
2619 | ugh = "no TXT RR for us"; | |
2620 | for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next) | |
2621 | { | |
2622 | passert(same_id(&gwp->gw_id, &sr->this.id)); | |
2623 | ||
2624 | ugh = "TXT RR for us has wrong key"; | |
2625 | if (gwp->gw_key_present | |
2626 | && same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa)) | |
2627 | { | |
2628 | DBG(DBG_CONTROL, | |
2629 | DBG_log("initiate on demand found TXT with right public key at: %s" | |
2630 | , mycredentialstr)); | |
2631 | ugh = NULL; | |
2632 | break; | |
2633 | } | |
2634 | } | |
2635 | #ifdef USE_KEYRR | |
2636 | if (ugh != NULL) | |
2637 | { | |
2638 | /* if no TXT with right key, try KEY */ | |
2639 | DBG(DBG_CONTROL, | |
2640 | DBG_log("will try for KEY RR since initiate on demand found %s: %s" | |
2641 | , ugh, mycredentialstr)); | |
2642 | next_step = fos_our_key; | |
2643 | ugh = NULL; | |
2644 | } | |
2645 | #endif | |
2646 | } | |
2647 | } | |
2648 | break; | |
2649 | ||
2650 | #ifdef USE_KEYRR | |
2651 | case fos_our_key: /* KEY for us */ | |
2652 | { | |
2653 | /* Check if KEY lookup yielded good results. | |
2654 | * Looking up based on our ID. Used if | |
2655 | * client is ourself, or if TXT had no public key. | |
2656 | * Note: if c is different this time, there is | |
2657 | * a chance that we did the wrong query. | |
2658 | * If so, treat as a kind of failure. | |
2659 | */ | |
2660 | const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c); | |
2661 | ||
2662 | next_step = fos_his_client; /* always */ | |
2663 | ||
2664 | if (our_RSA_pri == NULL) | |
2665 | { | |
2666 | ugh = "we don't know our own RSA key"; | |
2667 | } | |
2668 | else if (!same_id(&ac->id, &c->spd.this.id)) | |
2669 | { | |
2670 | ugh = "our ID changed underfoot"; | |
2671 | } | |
2672 | else | |
2673 | { | |
2674 | /* Similar to code in RSA_check_signature | |
2675 | * for checking the other side. | |
2676 | */ | |
2677 | pubkey_list_t *kr; | |
2678 | ||
2679 | ugh = "no KEY RR found for us (and no good TXT RR)"; | |
2680 | for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next) | |
2681 | { | |
2682 | ugh = "all our KEY RRs have the wrong public key (and no good TXT RR)"; | |
2683 | if (kr->key->alg == PUBKEY_ALG_RSA | |
2684 | && same_RSA_public_key(&our_RSA_pri->pub, &kr->key->u.rsa)) | |
2685 | { | |
2686 | /* do this only once a day */ | |
2687 | if (!logged_txt_warning) | |
2688 | { | |
2689 | loglog(RC_LOG_SERIOUS | |
2690 | , "found KEY RR but not TXT RR for %s. See http://www.freeswan.org/err/txt-change.html." | |
2691 | , mycredentialstr); | |
2692 | logged_txt_warning = TRUE; | |
2693 | } | |
2694 | ugh = NULL; /* good! */ | |
2695 | break; | |
2696 | } | |
2697 | } | |
2698 | } | |
2699 | } | |
2700 | break; | |
2701 | #endif /* USE_KEYRR */ | |
2702 | ||
2703 | case fos_his_client: /* TXT for his client */ | |
2704 | { | |
2705 | /* We've finished last DNS queries: TXT for his client. | |
2706 | * Using the information, try to instantiate a connection | |
2707 | * and start negotiating. | |
2708 | * We now know the peer. The chosing of "c" ignored this, | |
2709 | * so we will disregard its current value. | |
2710 | * !!! We need to randomize the entry in gw that we choose. | |
2711 | */ | |
2712 | next_step = fos_done; /* no more queries */ | |
2713 | ||
2714 | c = build_outgoing_opportunistic_connection(ac->gateways_from_dns | |
2715 | , &b->our_client | |
2716 | , &b->peer_client); | |
2717 | ||
2718 | if (c == NULL) | |
2719 | { | |
2720 | /* We cannot seem to instantiate a suitable connection: | |
2721 | * complain clearly. | |
2722 | */ | |
2723 | char ocb[ADDRTOT_BUF] | |
2724 | , pcb[ADDRTOT_BUF] | |
2725 | , pb[ADDRTOT_BUF]; | |
2726 | ||
2727 | addrtot(&b->our_client, 0, ocb, sizeof(ocb)); | |
2728 | addrtot(&b->peer_client, 0, pcb, sizeof(pcb)); | |
2729 | passert(id_is_ipaddr(&ac->gateways_from_dns->gw_id)); | |
2730 | addrtot(&ac->gateways_from_dns->gw_id.ip_addr, 0, pb, sizeof(pb)); | |
2731 | loglog(RC_OPPOFAILURE | |
2732 | , "no suitable connection for opportunism" | |
2733 | " between %s and %s with %s as peer" | |
2734 | , ocb, pcb, pb); | |
2735 | ||
2736 | #ifdef KLIPS | |
2737 | if (b->held) | |
2738 | { | |
2739 | /* Replace HOLD with PASS. | |
2740 | * The type of replacement *ought* to be | |
2741 | * specified by policy. | |
2742 | */ | |
2743 | (void) replace_bare_shunt(&b->our_client, &b->peer_client | |
2744 | , BOTTOM_PRIO | |
2745 | , SPI_PASS /* fail into PASS */ | |
2746 | , TRUE, b->transport_proto | |
2747 | , "no suitable connection"); | |
2748 | } | |
2749 | #endif | |
2750 | } | |
2751 | else | |
2752 | { | |
2753 | /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */ | |
2754 | passert(c->kind == CK_INSTANCE); | |
2755 | passert(c->gw_info != NULL); | |
2756 | passert(HAS_IPSEC_POLICY(c->policy)); | |
2757 | passert(LHAS(LELEM(RT_UNROUTED) | LELEM(RT_ROUTED_PROSPECTIVE), c->spd.routing)); | |
2758 | #ifdef KLIPS | |
2759 | if (b->held) | |
2760 | { | |
2761 | /* what should we do on failure? */ | |
2762 | (void) assign_hold(c, &c->spd | |
2763 | , b->transport_proto | |
2764 | , &b->our_client, &b->peer_client); | |
2765 | } | |
2766 | #endif | |
2767 | c->gw_info->key->last_tried_time = now(); | |
2768 | ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY); | |
2769 | b->whackfd = NULL_FD; /* protect from close */ | |
2770 | } | |
2771 | } | |
2772 | break; | |
2773 | ||
2774 | default: | |
2775 | bad_case(b->step); | |
2776 | } | |
2777 | ||
2778 | /* the second chunk: initiate the next DNS query (if any) */ | |
2779 | DBG(DBG_CONTROL, | |
2780 | { | |
2781 | char ours[ADDRTOT_BUF]; | |
2782 | char his[ADDRTOT_BUF]; | |
2783 | ||
2784 | addrtot(&b->our_client, 0, ours, sizeof(ours)); | |
2785 | addrtot(&b->peer_client, 0, his, sizeof(his)); | |
2786 | DBG_log("initiate on demand from %s to %s new state: %s with ugh: %s" | |
2787 | , ours, his, oppo_step_name[b->step], ugh ? ugh : "ok"); | |
2788 | }); | |
2789 | ||
2790 | if (ugh != NULL) | |
2791 | { | |
2792 | b->policy_prio = c->prio; | |
2793 | b->failure_shunt = shunt_policy_spi(c, FALSE); | |
2794 | cannot_oppo(c, b, ugh); | |
2795 | } | |
2796 | else if (next_step == fos_done) | |
2797 | { | |
2798 | /* nothing to do */ | |
2799 | } | |
2800 | else | |
2801 | { | |
2802 | /* set up the next query */ | |
2803 | struct find_oppo_continuation *cr = alloc_thing(struct find_oppo_continuation | |
2804 | , "opportunistic continuation"); | |
2805 | struct id id; | |
2806 | ||
2807 | b->policy_prio = c->prio; | |
2808 | b->failure_shunt = shunt_policy_spi(c, FALSE); | |
2809 | cr->b = *b; /* copy; start hand off of whackfd */ | |
2810 | cr->b.failure_ok = FALSE; | |
2811 | cr->b.step = next_step; | |
2812 | ||
2813 | for (sr = &c->spd | |
2814 | ; sr!=NULL && !sameaddr(&sr->this.host_addr, &b->our_client) | |
2815 | ; sr = sr->next) | |
2816 | ; | |
2817 | ||
2818 | if (sr == NULL) | |
2819 | sr = &c->spd; | |
2820 | ||
2821 | /* If a %hold shunt has replaced the eroute for this template, | |
2822 | * record this fact. | |
2823 | */ | |
2824 | if (b->held | |
2825 | && sr->routing == RT_ROUTED_PROSPECTIVE && eclipsable(sr)) | |
2826 | { | |
2827 | sr->routing = RT_ROUTED_ECLIPSED; | |
2828 | eclipse_count++; | |
2829 | } | |
2830 | ||
2831 | /* Switch to issue next query. | |
2832 | * A case may turn out to be unnecessary. If so, it falls | |
2833 | * through to the next case. | |
2834 | * Figuring out what %myid can stand for must be done before | |
2835 | * our client credentials are looked up: we must know what | |
2836 | * the client credentials may use to identify us. | |
2837 | * On the other hand, our own credentials should be looked | |
2838 | * up after our clients in case our credentials are not | |
2839 | * needed at all. | |
2840 | * XXX this is a wasted effort if we don't have credentials | |
2841 | * BUT they are not needed. | |
2842 | */ | |
2843 | switch (next_step) | |
2844 | { | |
2845 | case fos_myid_ip_txt: | |
2846 | if (c->spd.this.id.kind == ID_MYID | |
2847 | && myid_state != MYID_SPECIFIED) | |
2848 | { | |
2849 | cr->b.failure_ok = TRUE; | |
2850 | cr->b.want = b->want = "TXT record for IP address as %myid"; | |
2851 | ugh = start_adns_query(&myids[MYID_IP] | |
2852 | , &myids[MYID_IP] | |
2853 | , T_TXT | |
2854 | , continue_oppo | |
2855 | , &cr->ac); | |
2856 | break; | |
2857 | } | |
2858 | cr->b.step = fos_myid_hostname_txt; | |
2859 | /* fall through */ | |
2860 | ||
2861 | case fos_myid_hostname_txt: | |
2862 | if (c->spd.this.id.kind == ID_MYID | |
2863 | && myid_state != MYID_SPECIFIED) | |
2864 | { | |
2865 | #ifdef USE_KEYRR | |
2866 | cr->b.failure_ok = TRUE; | |
2867 | #else | |
2868 | cr->b.failure_ok = FALSE; | |
2869 | #endif | |
2870 | cr->b.want = b->want = "TXT record for hostname as %myid"; | |
2871 | ugh = start_adns_query(&myids[MYID_HOSTNAME] | |
2872 | , &myids[MYID_HOSTNAME] | |
2873 | , T_TXT | |
2874 | , continue_oppo | |
2875 | , &cr->ac); | |
2876 | break; | |
2877 | } | |
2878 | ||
2879 | #ifdef USE_KEYRR | |
2880 | cr->b.step = fos_myid_ip_key; | |
2881 | /* fall through */ | |
2882 | ||
2883 | case fos_myid_ip_key: | |
2884 | if (c->spd.this.id.kind == ID_MYID | |
2885 | && myid_state != MYID_SPECIFIED) | |
2886 | { | |
2887 | cr->b.failure_ok = TRUE; | |
2888 | cr->b.want = b->want = "KEY record for IP address as %myid (no good TXT)"; | |
2889 | ugh = start_adns_query(&myids[MYID_IP] | |
2890 | , (const struct id *) NULL /* security gateway meaningless */ | |
2891 | , T_KEY | |
2892 | , continue_oppo | |
2893 | , &cr->ac); | |
2894 | break; | |
2895 | } | |
2896 | cr->b.step = fos_myid_hostname_key; | |
2897 | /* fall through */ | |
2898 | ||
2899 | case fos_myid_hostname_key: | |
2900 | if (c->spd.this.id.kind == ID_MYID | |
2901 | && myid_state != MYID_SPECIFIED) | |
2902 | { | |
2903 | cr->b.failure_ok = FALSE; /* last attempt! */ | |
2904 | cr->b.want = b->want = "KEY record for hostname as %myid (no good TXT)"; | |
2905 | ugh = start_adns_query(&myids[MYID_HOSTNAME] | |
2906 | , (const struct id *) NULL /* security gateway meaningless */ | |
2907 | , T_KEY | |
2908 | , continue_oppo | |
2909 | , &cr->ac); | |
2910 | break; | |
2911 | } | |
2912 | #endif | |
2913 | cr->b.step = fos_our_client; | |
2914 | /* fall through */ | |
2915 | ||
2916 | case fos_our_client: /* TXT for our client */ | |
2917 | if (!sameaddr(&c->spd.this.host_addr, &b->our_client)) | |
2918 | { | |
2919 | /* Check that at least one TXT(reverse(b->our_client)) is workable. | |
2920 | * Note: {unshare|free}_id_content not needed for id: ephemeral. | |
2921 | */ | |
2922 | cr->b.want = b->want = "our client's TXT record"; | |
2923 | iptoid(&b->our_client, &id); | |
2924 | ugh = start_adns_query(&id | |
2925 | , &c->spd.this.id /* we are the security gateway */ | |
2926 | , T_TXT | |
2927 | , continue_oppo | |
2928 | , &cr->ac); | |
2929 | break; | |
2930 | } | |
2931 | cr->b.step = fos_our_txt; | |
2932 | /* fall through */ | |
2933 | ||
2934 | case fos_our_txt: /* TXT for us */ | |
2935 | cr->b.failure_ok = b->failure_ok = TRUE; | |
2936 | cr->b.want = b->want = "our TXT record"; | |
2937 | ugh = start_adns_query(&sr->this.id | |
2938 | , &sr->this.id /* we are the security gateway XXX - maybe ignore? mcr */ | |
2939 | , T_TXT | |
2940 | , continue_oppo | |
2941 | , &cr->ac); | |
2942 | break; | |
2943 | ||
2944 | #ifdef USE_KEYRR | |
2945 | case fos_our_key: /* KEY for us */ | |
2946 | cr->b.want = b->want = "our KEY record"; | |
2947 | cr->b.failure_ok = b->failure_ok = FALSE; | |
2948 | ugh = start_adns_query(&sr->this.id | |
2949 | , (const struct id *) NULL /* security gateway meaningless */ | |
2950 | , T_KEY | |
2951 | , continue_oppo | |
2952 | , &cr->ac); | |
2953 | break; | |
2954 | #endif /* USE_KEYRR */ | |
2955 | ||
2956 | case fos_his_client: /* TXT for his client */ | |
2957 | /* note: {unshare|free}_id_content not needed for id: ephemeral */ | |
2958 | cr->b.want = b->want = "target's TXT record"; | |
2959 | cr->b.failure_ok = b->failure_ok = FALSE; | |
2960 | iptoid(&b->peer_client, &id); | |
2961 | ugh = start_adns_query(&id | |
2962 | , (const struct id *) NULL /* security gateway unconstrained */ | |
2963 | , T_TXT | |
2964 | , continue_oppo | |
2965 | , &cr->ac); | |
2966 | break; | |
2967 | ||
2968 | default: | |
2969 | bad_case(next_step); | |
2970 | } | |
2971 | ||
2972 | if (ugh == NULL) | |
2973 | b->whackfd = NULL_FD; /* complete hand-off */ | |
2974 | else | |
2975 | cannot_oppo(c, b, ugh); | |
2976 | } | |
2977 | } | |
2978 | close_any(b->whackfd); | |
2979 | } | |
2980 | ||
2981 | void | |
2982 | terminate_connection(const char *nm) | |
2983 | { | |
2984 | /* Loop because more than one may match (master and instances) | |
2985 | * But at least one is required (enforced by con_by_name). | |
2986 | */ | |
2987 | struct connection *c, *n; | |
2988 | ||
2989 | for (c = con_by_name(nm, TRUE); c != NULL; c = n) | |
2990 | { | |
2991 | n = c->ac_next; /* grab this before c might disappear */ | |
2992 | if (streq(c->name, nm) | |
2993 | && c->kind >= CK_PERMANENT | |
2994 | && !NEVER_NEGOTIATE(c->policy)) | |
2995 | { | |
2996 | set_cur_connection(c); | |
2997 | plog("terminating SAs using this connection"); | |
2998 | c->policy &= ~POLICY_UP; | |
2999 | flush_pending_by_connection(c); | |
3000 | delete_states_by_connection(c, FALSE); | |
3001 | reset_cur_connection(); | |
3002 | } | |
3003 | } | |
3004 | } | |
3005 | ||
3006 | /* check nexthop safety | |
3007 | * Our nexthop must not be within a routed client subnet, and vice versa. | |
3008 | * Note: we don't think this is true. We think that KLIPS will | |
3009 | * not process a packet output by an eroute. | |
3010 | */ | |
3011 | #ifdef NEVER | |
3012 | //bool | |
3013 | //check_nexthop(const struct connection *c) | |
3014 | //{ | |
3015 | // struct connection *d; | |
3016 | // | |
3017 | // if (addrinsubnet(&c->spd.this.host_nexthop, &c->spd.that.client)) | |
3018 | // { | |
3019 | // loglog(RC_LOG_SERIOUS, "cannot perform routing for connection \"%s\"" | |
3020 | // " because nexthop is within peer's client network", | |
3021 | // c->name); | |
3022 | // return FALSE; | |
3023 | // } | |
3024 | // | |
3025 | // for (d = connections; d != NULL; d = d->next) | |
3026 | // { | |
3027 | // if (d->routing != RT_UNROUTED) | |
3028 | // { | |
3029 | // if (addrinsubnet(&c->spd.this.host_nexthop, &d->spd.that.client)) | |
3030 | // { | |
3031 | // loglog(RC_LOG_SERIOUS, "cannot do routing for connection \"%s\" | |
3032 | // " because nexthop is contained in" | |
3033 | // " existing routing for connection \"%s\"", | |
3034 | // c->name, d->name); | |
3035 | // return FALSE; | |
3036 | // } | |
3037 | // if (addrinsubnet(&d->spd.this.host_nexthop, &c->spd.that.client)) | |
3038 | // { | |
3039 | // loglog(RC_LOG_SERIOUS, "cannot do routing for connection \"%s\" | |
3040 | // " because it contains nexthop of" | |
3041 | // " existing routing for connection \"%s\"", | |
3042 | // c->name, d->name); | |
3043 | // return FALSE; | |
3044 | // } | |
3045 | // } | |
3046 | // } | |
3047 | // return TRUE; | |
3048 | //} | |
3049 | #endif /* NEVER */ | |
3050 | ||
3051 | /* an ISAKMP SA has been established. | |
3052 | * Note the serial number, and release any connections with | |
3053 | * the same peer ID but different peer IP address. | |
3054 | */ | |
3055 | bool uniqueIDs = FALSE; /* --uniqueids? */ | |
3056 | ||
3057 | void | |
3058 | ISAKMP_SA_established(struct connection *c, so_serial_t serial) | |
3059 | { | |
3060 | c->newest_isakmp_sa = serial; | |
3061 | ||
3062 | /* the connection is now oriented so that we are able to determine | |
3063 | * whether we are a mode config server with a virtual IP to send. | |
3064 | */ | |
3065 | if (!isanyaddr(&c->spd.that.host_srcip)) | |
3066 | c->spd.that.modecfg = TRUE; | |
3067 | ||
3068 | if (uniqueIDs) | |
3069 | { | |
3070 | /* for all connections: if the same Phase 1 IDs are used | |
3071 | * for a different IP address, unorient that connection. | |
3072 | */ | |
3073 | struct connection *d; | |
3074 | ||
3075 | for (d = connections; d != NULL; ) | |
3076 | { | |
3077 | struct connection *next = d->ac_next; /* might move underneath us */ | |
3078 | ||
3079 | #ifdef NAT_TRAVERSAL | |
3080 | if (d->kind >= CK_PERMANENT | |
3081 | && same_id(&c->spd.this.id, &d->spd.this.id) | |
3082 | && same_id(&c->spd.that.id, &d->spd.that.id) | |
3083 | && (!sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr) || | |
3084 | (c->spd.that.host_port != d->spd.that.host_port))) | |
3085 | #else | |
3086 | if (d->kind >= CK_PERMANENT | |
3087 | && same_id(&c->spd.this.id, &d->spd.this.id) | |
3088 | && same_id(&c->spd.that.id, &d->spd.that.id) | |
3089 | && !sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr)) | |
3090 | #endif | |
3091 | { | |
3092 | release_connection(d, FALSE); | |
3093 | } | |
3094 | d = next; | |
3095 | } | |
3096 | } | |
3097 | } | |
3098 | ||
3099 | /* Find the connection to connection c's peer's client with the | |
3100 | * largest value of .routing. All other things being equal, | |
3101 | * preference is given to c. If none is routed, return NULL. | |
3102 | * | |
3103 | * If erop is non-null, set *erop to a connection sharing both | |
3104 | * our client subnet and peer's client subnet with the largest value | |
3105 | * of .routing. If none is erouted, set *erop to NULL. | |
3106 | * | |
3107 | * The return value is used to find other connections sharing a route. | |
3108 | * *erop is used to find other connections sharing an eroute. | |
3109 | */ | |
3110 | struct connection * | |
3111 | route_owner(struct connection *c | |
3112 | , struct spd_route **srp | |
3113 | , struct connection **erop | |
3114 | , struct spd_route **esrp) | |
3115 | { | |
3116 | struct connection *d | |
3117 | , *best_ro = c | |
3118 | , *best_ero = c; | |
3119 | struct spd_route *srd, *src; | |
3120 | struct spd_route *best_sr, *best_esr; | |
3121 | enum routing_t best_routing, best_erouting; | |
3122 | ||
3123 | passert(oriented(*c)); | |
3124 | best_sr = NULL; | |
3125 | best_esr = NULL; | |
3126 | best_routing = c->spd.routing; | |
3127 | best_erouting = best_routing; | |
3128 | ||
3129 | for (d = connections; d != NULL; d = d->ac_next) | |
3130 | { | |
3131 | for (srd = &d->spd; srd; srd = srd->next) | |
3132 | { | |
3133 | if (srd->routing == RT_UNROUTED) | |
3134 | continue; | |
3135 | ||
3136 | for (src = &c->spd; src; src=src->next) | |
3137 | { | |
3138 | if (!samesubnet(&src->that.client, &srd->that.client)) | |
3139 | continue; | |
3140 | if (src->that.protocol != srd->that.protocol) | |
3141 | continue; | |
3142 | if (src->that.port != srd->that.port) | |
3143 | continue; | |
3144 | passert(oriented(*d)); | |
3145 | if (srd->routing > best_routing) | |
3146 | { | |
3147 | best_ro = d; | |
3148 | best_sr = srd; | |
3149 | best_routing = srd->routing; | |
3150 | } | |
3151 | ||
3152 | if (!samesubnet(&src->this.client, &srd->this.client)) | |
3153 | continue; | |
3154 | if (src->this.protocol != srd->this.protocol) | |
3155 | continue; | |
3156 | if (src->this.port != srd->this.port) | |
3157 | continue; | |
3158 | if (srd->routing > best_erouting) | |
3159 | { | |
3160 | best_ero = d; | |
3161 | best_esr = srd; | |
3162 | best_erouting = srd->routing; | |
3163 | } | |
3164 | } | |
3165 | } | |
3166 | } | |
3167 | ||
3168 | DBG(DBG_CONTROL, | |
3169 | { | |
3170 | char cib[CONN_INST_BUF]; | |
3171 | err_t m = builddiag("route owner of \"%s\"%s %s:" | |
3172 | , c->name | |
3173 | , (fmt_conn_instance(c, cib), cib) | |
3174 | , enum_name(&routing_story, c->spd.routing)); | |
3175 | ||
3176 | if (!routed(best_ro->spd.routing)) | |
3177 | m = builddiag("%s NULL", m); | |
3178 | else if (best_ro == c) | |
3179 | m = builddiag("%s self", m); | |
3180 | else | |
3181 | m = builddiag("%s \"%s\"%s %s", m | |
3182 | , best_ro->name | |
3183 | , (fmt_conn_instance(best_ro, cib), cib) | |
3184 | , enum_name(&routing_story, best_ro->spd.routing)); | |
3185 | ||
3186 | if (erop != NULL) | |
3187 | { | |
3188 | m = builddiag("%s; eroute owner:", m); | |
3189 | if (!erouted(best_ero->spd.routing)) | |
3190 | m = builddiag("%s NULL", m); | |
3191 | else if (best_ero == c) | |
3192 | m = builddiag("%s self", m); | |
3193 | else | |
3194 | m = builddiag("%s \"%s\"%s %s", m | |
3195 | , best_ero->name | |
3196 | , (fmt_conn_instance(best_ero, cib), cib) | |
3197 | , enum_name(&routing_story, best_ero->spd.routing)); | |
3198 | } | |
3199 | ||
3200 | DBG_log("%s", m); | |
3201 | }); | |
3202 | ||
3203 | if (erop != NULL) | |
3204 | *erop = erouted(best_erouting)? best_ero : NULL; | |
3205 | ||
3206 | if (srp != NULL ) | |
3207 | { | |
3208 | *srp = best_sr; | |
3209 | if (esrp != NULL ) | |
3210 | *esrp = best_esr; | |
3211 | } | |
3212 | ||
3213 | return routed(best_routing)? best_ro : NULL; | |
3214 | } | |
3215 | ||
3216 | /* Find a connection that owns the shunt eroute between subnets. | |
3217 | * There ought to be only one. | |
3218 | * This might get to be a bottleneck -- try hashing if it does. | |
3219 | */ | |
3220 | struct connection * | |
3221 | shunt_owner(const ip_subnet *ours, const ip_subnet *his) | |
3222 | { | |
3223 | struct connection *c; | |
3224 | struct spd_route *sr; | |
3225 | ||
3226 | for (c = connections; c != NULL; c = c->ac_next) | |
3227 | { | |
3228 | for (sr = &c->spd; sr; sr = sr->next) | |
3229 | { | |
3230 | if (shunt_erouted(sr->routing) | |
3231 | && samesubnet(ours, &sr->this.client) | |
3232 | && samesubnet(his, &sr->that.client)) | |
3233 | return c; | |
3234 | } | |
3235 | } | |
3236 | return NULL; | |
3237 | } | |
3238 | ||
3239 | /* Find some connection with this pair of hosts. | |
3240 | * We don't know enough to chose amongst those available. | |
3241 | * ??? no longer usefully different from find_host_pair_connections | |
3242 | */ | |
3243 | struct connection * | |
3244 | find_host_connection(const ip_address *me, u_int16_t my_port | |
3245 | , const ip_address *him, u_int16_t his_port, lset_t policy) | |
3246 | { | |
3247 | struct connection *c = find_host_pair_connections(me, my_port, him, his_port); | |
3248 | ||
3249 | if (policy != LEMPTY) | |
3250 | { | |
3251 | /* if we have requirements for the policy, | |
3252 | * choose the first matching connection. | |
3253 | */ | |
3254 | while (c != NULL) | |
3255 | { | |
3256 | if ((c->policy & policy) == policy) | |
3257 | break; | |
3258 | c = c->hp_next; | |
3259 | } | |
3260 | } | |
3261 | return c; | |
3262 | } | |
3263 | ||
3264 | /* given an up-until-now satisfactory connection, find the best connection | |
3265 | * now that we just got the Phase 1 Id Payload from the peer. | |
3266 | * | |
3267 | * Comments in the code describe the (tricky!) matching criteria. | |
3268 | * Although this routine could handle the initiator case, | |
3269 | * it isn't currently called in this case. | |
3270 | * If it were, it could "upgrade" an Opportunistic Connection | |
3271 | * to a Road Warrior Connection if a suitable Peer ID were found. | |
3272 | * | |
3273 | * In RFC 2409 "The Internet Key Exchange (IKE)", | |
3274 | * in 5.1 "IKE Phase 1 Authenticated With Signatures", describing Main | |
3275 | * Mode: | |
3276 | * | |
3277 | * Initiator Responder | |
3278 | * ----------- ----------- | |
3279 | * HDR, SA --> | |
3280 | * <-- HDR, SA | |
3281 | * HDR, KE, Ni --> | |
3282 | * <-- HDR, KE, Nr | |
3283 | * HDR*, IDii, [ CERT, ] SIG_I --> | |
3284 | * <-- HDR*, IDir, [ CERT, ] SIG_R | |
3285 | * | |
3286 | * In 5.4 "Phase 1 Authenticated With a Pre-Shared Key": | |
3287 | * | |
3288 | * HDR, SA --> | |
3289 | * <-- HDR, SA | |
3290 | * HDR, KE, Ni --> | |
3291 | * <-- HDR, KE, Nr | |
3292 | * HDR*, IDii, HASH_I --> | |
3293 | * <-- HDR*, IDir, HASH_R | |
3294 | * | |
3295 | * refine_host_connection could be called in two case: | |
3296 | * | |
3297 | * - the Responder receives the IDii payload: | |
3298 | * + [PSK] after using PSK to decode this message | |
3299 | * + before sending its IDir payload | |
3300 | * + before using its ID in HASH_R computation | |
3301 | * + [DSig] before using its private key to sign SIG_R | |
3302 | * + before using the Initiator's ID in HASH_I calculation | |
3303 | * + [DSig] before using the Initiator's public key to check SIG_I | |
3304 | * | |
3305 | * - the Initiator receives the IDir payload: | |
3306 | * + [PSK] after using PSK to encode previous message and decode this message | |
3307 | * + after sending its IDii payload | |
3308 | * + after using its ID in HASH_I computation | |
3309 | * + [DSig] after using its private key to sign SIG_I | |
3310 | * + before using the Responder's ID to compute HASH_R | |
3311 | * + [DSig] before using Responder's public key to check SIG_R | |
3312 | * | |
3313 | * refine_host_connection can choose a different connection, as long as | |
3314 | * nothing already used is changed. | |
3315 | * | |
3316 | * In the Initiator case, the particular connection might have been | |
3317 | * specified by whatever provoked Pluto to initiate. For example: | |
3318 | * whack --initiate connection-name | |
3319 | * The advantages of switching connections when we're the Initiator seem | |
3320 | * less important than the disadvantages, so after FreeS/WAN 1.9, we | |
3321 | * don't do this. | |
3322 | */ | |
3323 | struct connection * | |
3324 | refine_host_connection(const struct state *st, const struct id *peer_id | |
3325 | , chunk_t peer_ca) | |
3326 | { | |
3327 | struct connection *c = st->st_connection; | |
3328 | u_int16_t auth = st->st_oakley.auth; | |
3329 | struct connection *d; | |
3330 | struct connection *best_found = NULL; | |
3331 | lset_t auth_policy; | |
3332 | const chunk_t *psk = NULL; | |
3333 | bool wcpip; /* wildcard Peer IP? */ | |
3334 | ||
3335 | int wildcards, our_pathlen, peer_pathlen; | |
3336 | int best_wildcards = MAX_WILDCARDS; | |
3337 | int best_our_pathlen = MAX_CA_PATH_LEN; | |
3338 | int best_peer_pathlen = MAX_CA_PATH_LEN; | |
3339 | ||
3340 | if (same_id(&c->spd.that.id, peer_id) | |
3341 | && trusted_ca(peer_ca, c->spd.that.ca, &peer_pathlen) | |
3342 | && peer_pathlen == 0 | |
3343 | && match_requested_ca(c->requested_ca, c->spd.this.ca, &our_pathlen) | |
3344 | && our_pathlen == 0) | |
3345 | { | |
3346 | DBG(DBG_CONTROL, | |
3347 | DBG_log("current connection is a full match" | |
3348 | " -- no need to look further"); | |
3349 | ) | |
3350 | return c; | |
3351 | } | |
3352 | ||
3353 | switch (auth) | |
3354 | { | |
3355 | case OAKLEY_PRESHARED_KEY: | |
3356 | auth_policy = POLICY_PSK; | |
3357 | psk = get_preshared_secret(c); | |
3358 | /* It should be virtually impossible to fail to find PSK: | |
3359 | * we just used it to decode the current message! | |
3360 | */ | |
3361 | if (psk == NULL) | |
3362 | return NULL; /* cannot determine PSK! */ | |
3363 | break; | |
3364 | ||
3365 | case OAKLEY_RSA_SIG: | |
3366 | auth_policy = POLICY_RSASIG; | |
3367 | break; | |
3368 | ||
3369 | default: | |
3370 | bad_case(auth); | |
3371 | } | |
3372 | ||
3373 | /* The current connection won't do: search for one that will. | |
3374 | * First search for one with the same pair of hosts. | |
3375 | * If that fails, search for a suitable Road Warrior or Opportunistic | |
3376 | * connection (i.e. wildcard peer IP). | |
3377 | * We need to match: | |
3378 | * - peer_id (slightly complicated by instantiation) | |
3379 | * - if PSK auth, the key must not change (we used it to decode message) | |
3380 | * - policy-as-used must be acceptable to new connection | |
3381 | */ | |
3382 | d = c->host_pair->connections; | |
3383 | for (wcpip = FALSE; ; wcpip = TRUE) | |
3384 | { | |
3385 | for (; d != NULL; d = d->hp_next) | |
3386 | { | |
3387 | const char *match_name[] = {"no", "ok"}; | |
3388 | ||
3389 | bool matching_id = match_id(peer_id | |
3390 | , &d->spd.that.id, &wildcards); | |
3391 | bool matching_trust = trusted_ca(peer_ca | |
3392 | , d->spd.that.ca, &peer_pathlen); | |
3393 | bool matching_request = match_requested_ca(c->requested_ca | |
3394 | , d->spd.this.ca, &our_pathlen); | |
3395 | bool match = matching_id && matching_trust && matching_request; | |
3396 | ||
3397 | DBG(DBG_CONTROLMORE, | |
3398 | DBG_log("%s: %s match (id: %s, trust: %s, request: %s)" | |
3399 | , d->name | |
3400 | , match ? "full":" no" | |
3401 | , match_name[matching_id] | |
3402 | , match_name[matching_trust] | |
3403 | , match_name[matching_request]) | |
3404 | ) | |
3405 | ||
3406 | /* do we have a match? */ | |
3407 | if (!match) | |
3408 | continue; | |
3409 | ||
3410 | /* ignore group connections */ | |
3411 | if (d->policy & POLICY_GROUP) | |
3412 | continue; | |
3413 | ||
3414 | #ifdef NAT_TRAVERSAL | |
3415 | if (c->spd.that.host_port != d->spd.that.host_port | |
3416 | && d->kind == CK_INSTANCE) | |
3417 | continue; | |
3418 | #endif | |
3419 | ||
3420 | /* authentication used must fit policy of this connection */ | |
3421 | if ((d->policy & auth_policy) == LEMPTY) | |
3422 | continue; /* our auth isn't OK for this connection */ | |
3423 | ||
3424 | switch (auth) | |
3425 | { | |
3426 | case OAKLEY_PRESHARED_KEY: | |
3427 | /* secret must match the one we already used */ | |
3428 | { | |
3429 | const chunk_t *dpsk = get_preshared_secret(d); | |
3430 | ||
3431 | if (dpsk == NULL) | |
3432 | continue; /* no secret */ | |
3433 | ||
3434 | if (psk != dpsk) | |
3435 | if (psk->len != dpsk->len | |
3436 | || memcmp(psk->ptr, dpsk->ptr, psk->len) != 0) | |
3437 | continue; /* different secret */ | |
3438 | } | |
3439 | break; | |
3440 | ||
3441 | case OAKLEY_RSA_SIG: | |
3442 | /* | |
3443 | * We must at least be able to find our private key | |
3444 | .*/ | |
3445 | if (d->spd.this.sc == NULL /* no smartcard */ | |
3446 | && get_RSA_private_key(d) == NULL) /* no private key */ | |
3447 | continue; | |
3448 | break; | |
3449 | ||
3450 | default: | |
3451 | bad_case(auth); | |
3452 | } | |
3453 | ||
3454 | /* d has passed all the tests. | |
3455 | * We'll go with it if the Peer ID was an exact match. | |
3456 | */ | |
3457 | if (match && wildcards == 0 && peer_pathlen == 0 && our_pathlen == 0) | |
3458 | return d; | |
3459 | ||
3460 | /* We'll remember it as best_found in case an exact | |
3461 | * match doesn't come along. | |
3462 | */ | |
3463 | if (best_found == NULL || wildcards < best_wildcards | |
3464 | || ((wildcards == best_wildcards && peer_pathlen < best_peer_pathlen) | |
3465 | || (peer_pathlen == best_peer_pathlen && our_pathlen < best_our_pathlen))) | |
3466 | { | |
3467 | best_found = d; | |
3468 | best_wildcards = wildcards; | |
3469 | best_peer_pathlen = peer_pathlen; | |
3470 | best_our_pathlen = our_pathlen; | |
3471 | } | |
3472 | } | |
3473 | if (wcpip) | |
3474 | return best_found; /* been around twice already */ | |
3475 | ||
3476 | /* Starting second time around. | |
3477 | * We're willing to settle for a connection that needs Peer IP | |
3478 | * instantiated: Road Warrior or Opportunistic. | |
3479 | * Look on list of connections for host pair with wildcard Peer IP | |
3480 | */ | |
3481 | d = find_host_pair_connections(&c->spd.this.host_addr, c->spd.this.host_port | |
3482 | , (ip_address *)NULL, c->spd.that.host_port); | |
3483 | } | |
3484 | } | |
3485 | ||
3486 | #ifdef VIRTUAL_IP | |
3487 | /** | |
3488 | * With virtual addressing, we must not allow someone to use an already | |
3489 | * used (by another id) addr/net. | |
3490 | */ | |
3491 | static bool | |
3492 | is_virtual_net_used(const ip_subnet *peer_net, const struct id *peer_id) | |
3493 | { | |
3494 | struct connection *d; | |
3495 | ||
3496 | for (d = connections; d != NULL; d = d->ac_next) | |
3497 | { | |
3498 | switch (d->kind) | |
3499 | { | |
3500 | case CK_PERMANENT: | |
3501 | case CK_INSTANCE: | |
3502 | if ((subnetinsubnet(peer_net,&d->spd.that.client) || | |
3503 | subnetinsubnet(&d->spd.that.client,peer_net)) | |
3504 | && !same_id(&d->spd.that.id, peer_id)) | |
3505 | { | |
3506 | char buf[BUF_LEN]; | |
3507 | char client[SUBNETTOT_BUF]; | |
3508 | ||
3509 | subnettot(peer_net, 0, client, sizeof(client)); | |
3510 | idtoa(&d->spd.that.id, buf, sizeof(buf)); | |
3511 | plog("Virtual IP %s is already used by '%s'", client, buf); | |
3512 | idtoa(peer_id, buf, sizeof(buf)); | |
3513 | plog("Your ID is '%s'", buf); | |
3514 | return TRUE; /* already used by another one */ | |
3515 | } | |
3516 | break; | |
3517 | case CK_GOING_AWAY: | |
3518 | default: | |
3519 | break; | |
3520 | } | |
3521 | } | |
3522 | return FALSE; /* you can safely use it */ | |
3523 | } | |
3524 | #endif | |
3525 | ||
3526 | /* find_client_connection: given a connection suitable for ISAKMP | |
3527 | * (i.e. the hosts match), find a one suitable for IPSEC | |
3528 | * (i.e. with matching clients). | |
3529 | * | |
3530 | * If we don't find an exact match (not even our current connection), | |
3531 | * we try for one that still needs instantiation. Try Road Warrior | |
3532 | * abstract connections and the Opportunistic abstract connections. | |
3533 | * This requires inverse instantiation: abstraction. | |
3534 | * | |
3535 | * After failing to find an exact match, we abstract the peer | |
3536 | * to be NO_IP (the wildcard value). This enables matches with | |
3537 | * Road Warrior and Opportunistic abstract connections. | |
3538 | * | |
3539 | * After failing that search, we also abstract the Phase 1 peer ID | |
3540 | * if possible. If the peer's ID was the peer's IP address, we make | |
3541 | * it NO_ID; instantiation will make it the peer's IP address again. | |
3542 | * | |
3543 | * If searching for a Road Warrior abstract connection fails, | |
3544 | * and conditions are suitable, we search for the best Opportunistic | |
3545 | * abstract connection. | |
3546 | * | |
3547 | * Note: in the end, both Phase 1 IDs must be preserved, after any | |
3548 | * instantiation. They are the IDs that have been authenticated. | |
3549 | */ | |
3550 | ||
3551 | #define PATH_WEIGHT 1 | |
3552 | #define WILD_WEIGHT (MAX_CA_PATH_LEN+1) | |
3553 | #define PRIO_WEIGHT (MAX_WILDCARDS+1)*WILD_WEIGHT | |
3554 | ||
3555 | /* fc_try: a helper function for find_client_connection */ | |
3556 | static struct connection * | |
3557 | fc_try(const struct connection *c | |
3558 | , struct host_pair *hp | |
3559 | , const struct id *peer_id | |
3560 | , const ip_subnet *our_net | |
3561 | , const ip_subnet *peer_net | |
3562 | , const u_int8_t our_protocol | |
3563 | , const u_int16_t our_port | |
3564 | , const u_int8_t peer_protocol | |
3565 | , const u_int16_t peer_port | |
3566 | , chunk_t peer_ca | |
3567 | , const ietfAttrList_t *peer_list) | |
3568 | { | |
3569 | struct connection *d; | |
3570 | struct connection *best = NULL; | |
3571 | policy_prio_t best_prio = BOTTOM_PRIO; | |
3572 | int wildcards, pathlen; | |
3573 | ||
3574 | const bool peer_net_is_host = subnetisaddr(peer_net, &c->spd.that.host_addr); | |
3575 | ||
3576 | for (d = hp->connections; d != NULL; d = d->hp_next) | |
3577 | { | |
3578 | struct spd_route *sr; | |
3579 | ||
3580 | if (d->policy & POLICY_GROUP) | |
3581 | continue; | |
3582 | ||
3583 | if (!(same_id(&c->spd.this.id, &d->spd.this.id) | |
3584 | && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards) | |
3585 | && trusted_ca(peer_ca, d->spd.that.ca, &pathlen) | |
3586 | && group_membership(peer_list, d->name, d->spd.that.groups))) | |
3587 | continue; | |
3588 | ||
3589 | /* compare protocol and ports */ | |
3590 | if (d->spd.this.protocol != our_protocol | |
3591 | || d->spd.this.port != our_port | |
3592 | || d->spd.that.protocol != peer_protocol | |
3593 | || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard)) | |
3594 | continue; | |
3595 | ||
3596 | /* non-Opportunistic case: | |
3597 | * our_client must match. | |
3598 | * | |
3599 | * So must peer_client, but the testing is complicated | |
3600 | * by the fact that the peer might be a wildcard | |
3601 | * and if so, the default value of that.client | |
3602 | * won't match the default peer_net. The appropriate test: | |
3603 | * | |
3604 | * If d has a peer client, it must match peer_net. | |
3605 | * If d has no peer client, peer_net must just have peer itself. | |
3606 | */ | |
3607 | ||
3608 | for (sr = &d->spd; best != d && sr != NULL; sr = sr->next) | |
3609 | { | |
3610 | policy_prio_t prio; | |
3611 | #ifdef DEBUG | |
3612 | if (DBGP(DBG_CONTROLMORE)) | |
3613 | { | |
3614 | char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF]; | |
3615 | char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF]; | |
3616 | ||
3617 | subnettot(our_net, 0, s1, sizeof(s1)); | |
3618 | subnettot(peer_net, 0, d1, sizeof(d1)); | |
3619 | subnettot(&sr->this.client, 0, s3, sizeof(s3)); | |
3620 | subnettot(&sr->that.client, 0, d3, sizeof(d3)); | |
3621 | DBG_log(" fc_try trying " | |
3622 | "%s:%s:%d/%d -> %s:%d/%d vs %s:%s:%d/%d -> %s:%d/%d" | |
3623 | , c->name, s1, c->spd.this.protocol, c->spd.this.port | |
3624 | , d1, c->spd.that.protocol, c->spd.that.port | |
3625 | , d->name, s3, sr->this.protocol, sr->this.port | |
3626 | , d3, sr->that.protocol, sr->that.port); | |
3627 | } | |
3628 | #endif /* DEBUG */ | |
3629 | ||
3630 | if (!samesubnet(&sr->this.client, our_net)) | |
3631 | continue; | |
3632 | ||
3633 | if (sr->that.has_client) | |
3634 | { | |
3635 | if (sr->that.has_client_wildcard) | |
3636 | { | |
3637 | if (!subnetinsubnet(peer_net, &sr->that.client)) | |
3638 | continue; | |
3639 | } | |
3640 | else | |
3641 | { | |
3642 | #ifdef VIRTUAL_IP | |
3643 | if ((!samesubnet(&sr->that.client, peer_net)) && (!is_virtual_connection(d))) | |
3644 | #else | |
3645 | if (!samesubnet(&sr->that.client, peer_net)) | |
3646 | #endif | |
3647 | continue; | |
3648 | #ifdef VIRTUAL_IP | |
3649 | if (is_virtual_connection(d) | |
3650 | && ( (!is_virtual_net_allowed(d, peer_net, &c->spd.that.host_addr)) | |
3651 | || is_virtual_net_used(peer_net, peer_id?peer_id:&c->spd.that.id))) | |
3652 | continue; | |
3653 | #endif | |
3654 | } | |
3655 | } | |
3656 | else | |
3657 | { | |
3658 | if (!peer_net_is_host) | |
3659 | continue; | |
3660 | } | |
3661 | ||
3662 | /* We've run the gauntlet -- success: | |
3663 | * We've got an exact match of subnets. | |
3664 | * The connection is feasible, but we continue looking for the best. | |
3665 | * The highest priority wins, implementing eroute-like rule. | |
3666 | * - a routed connection is preferrred | |
3667 | * - given that, the smallest number of ID wildcards are preferred | |
3668 | * - given that, the shortest CA pathlength is preferred | |
3669 | */ | |
3670 | prio = PRIO_WEIGHT * routed(sr->routing) | |
3671 | + WILD_WEIGHT * (MAX_WILDCARDS - wildcards) | |
3672 | + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen) | |
3673 | + 1; | |
3674 | if (prio > best_prio) | |
3675 | { | |
3676 | best = d; | |
3677 | best_prio = prio; | |
3678 | } | |
3679 | } | |
3680 | } | |
3681 | ||
3682 | if (best != NULL && NEVER_NEGOTIATE(best->policy)) | |
3683 | best = NULL; | |
3684 | ||
3685 | DBG(DBG_CONTROLMORE, | |
3686 | DBG_log(" fc_try concluding with %s [%ld]" | |
3687 | , (best ? best->name : "none"), best_prio) | |
3688 | ) | |
3689 | return best; | |
3690 | } | |
3691 | ||
3692 | static struct connection * | |
3693 | fc_try_oppo(const struct connection *c | |
3694 | , struct host_pair *hp | |
3695 | , const ip_subnet *our_net | |
3696 | , const ip_subnet *peer_net | |
3697 | , const u_int8_t our_protocol | |
3698 | , const u_int16_t our_port | |
3699 | , const u_int8_t peer_protocol | |
3700 | , const u_int16_t peer_port | |
3701 | , chunk_t peer_ca | |
3702 | , const ietfAttrList_t *peer_list) | |
3703 | { | |
3704 | struct connection *d; | |
3705 | struct connection *best = NULL; | |
3706 | policy_prio_t best_prio = BOTTOM_PRIO; | |
3707 | int wildcards, pathlen; | |
3708 | ||
3709 | for (d = hp->connections; d != NULL; d = d->hp_next) | |
3710 | { | |
3711 | struct spd_route *sr; | |
3712 | policy_prio_t prio; | |
3713 | ||
3714 | if (d->policy & POLICY_GROUP) | |
3715 | continue; | |
3716 | ||
3717 | if (!(same_id(&c->spd.this.id, &d->spd.this.id) | |
3718 | && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards) | |
3719 | && trusted_ca(peer_ca, d->spd.that.ca, &pathlen) | |
3720 | && group_membership(peer_list, d->name, d->spd.that.groups))) | |
3721 | continue; | |
3722 | ||
3723 | /* compare protocol and ports */ | |
3724 | if (d->spd.this.protocol != our_protocol | |
3725 | || d->spd.this.port != our_port | |
3726 | || d->spd.that.protocol != peer_protocol | |
3727 | || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard)) | |
3728 | continue; | |
3729 | ||
3730 | /* Opportunistic case: | |
3731 | * our_net must be inside d->spd.this.client | |
3732 | * and peer_net must be inside d->spd.that.client | |
3733 | * Note: this host_pair chain also has shunt | |
3734 | * eroute conns (clear, drop), but they won't | |
3735 | * be marked as opportunistic. | |
3736 | */ | |
3737 | for (sr = &d->spd; sr != NULL; sr = sr->next) | |
3738 | { | |
3739 | #ifdef DEBUG | |
3740 | if (DBGP(DBG_CONTROLMORE)) | |
3741 | { | |
3742 | char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF]; | |
3743 | char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF]; | |
3744 | ||
3745 | subnettot(our_net, 0, s1, sizeof(s1)); | |
3746 | subnettot(peer_net, 0, d1, sizeof(d1)); | |
3747 | subnettot(&sr->this.client, 0, s3, sizeof(s3)); | |
3748 | subnettot(&sr->that.client, 0, d3, sizeof(d3)); | |
3749 | DBG_log(" fc_try_oppo trying %s:%s -> %s vs %s:%s -> %s" | |
3750 | , c->name, s1, d1, d->name, s3, d3); | |
3751 | } | |
3752 | #endif /* DEBUG */ | |
3753 | ||
3754 | if (!subnetinsubnet(our_net, &sr->this.client) | |
3755 | || !subnetinsubnet(peer_net, &sr->that.client)) | |
3756 | continue; | |
3757 | ||
3758 | /* The connection is feasible, but we continue looking for the best. | |
3759 | * The highest priority wins, implementing eroute-like rule. | |
3760 | * - our smallest client subnet is preferred (longest mask) | |
3761 | * - given that, his smallest client subnet is preferred | |
3762 | * - given that, a routed connection is preferrred | |
3763 | * - given that, the smallest number of ID wildcards are preferred | |
3764 | * - given that, the shortest CA pathlength is preferred | |
3765 | */ | |
3766 | prio = PRIO_WEIGHT * (d->prio + routed(sr->routing)) | |
3767 | + WILD_WEIGHT * (MAX_WILDCARDS - wildcards) | |
3768 | + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen); | |
3769 | if (prio > best_prio) | |
3770 | { | |
3771 | best = d; | |
3772 | best_prio = prio; | |
3773 | } | |
3774 | } | |
3775 | } | |
3776 | ||
3777 | /* if the best wasn't opportunistic, we fail: it must be a shunt */ | |
3778 | if (best != NULL | |
3779 | && (NEVER_NEGOTIATE(best->policy) | |
3780 | || (best->policy & POLICY_OPPO) == LEMPTY)) | |
3781 | { | |
3782 | best = NULL; | |
3783 | } | |
3784 | ||
3785 | DBG(DBG_CONTROLMORE, | |
3786 | DBG_log(" fc_try_oppo concluding with %s [%ld]" | |
3787 | , (best ? best->name : "none"), best_prio) | |
3788 | ) | |
3789 | return best; | |
3790 | ||
3791 | } | |
3792 | ||
3793 | /* | |
3794 | * get the peer's CA and group attributes | |
3795 | */ | |
3796 | chunk_t | |
3797 | get_peer_ca_and_groups(struct connection *c, const ietfAttrList_t **peer_list) | |
3798 | { | |
3799 | struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES); | |
3800 | ||
3801 | *peer_list = NULL; | |
3802 | ||
3803 | if (p1st != NULL | |
3804 | && p1st->st_peer_pubkey != NULL | |
3805 | && p1st->st_peer_pubkey->issuer.ptr != NULL) | |
3806 | { | |
3807 | x509acert_t *ac = get_x509acert(p1st->st_peer_pubkey->issuer | |
3808 | , p1st->st_peer_pubkey->serial);; | |
3809 | ||
3810 | if (ac != NULL && verify_x509acert(ac, strict_crl_policy)) | |
3811 | *peer_list = ac->groups; | |
3812 | else | |
3813 | { | |
3814 | DBG(DBG_CONTROL, | |
3815 | DBG_log("no valid attribute cert found") | |
3816 | ) | |
3817 | } | |
3818 | return p1st->st_peer_pubkey->issuer; | |
3819 | } | |
3820 | return empty_chunk; | |
3821 | } | |
3822 | ||
3823 | struct connection * | |
3824 | find_client_connection(struct connection *c | |
3825 | , const ip_subnet *our_net, const ip_subnet *peer_net | |
3826 | , const u_int8_t our_protocol, const u_int16_t our_port | |
3827 | , const u_int8_t peer_protocol, const u_int16_t peer_port) | |
3828 | { | |
3829 | struct connection *d; | |
3830 | struct spd_route *sr; | |
3831 | ||
3832 | const ietfAttrList_t *peer_list = NULL; | |
3833 | chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_list); | |
3834 | ||
3835 | #ifdef DEBUG | |
3836 | if (DBGP(DBG_CONTROLMORE)) | |
3837 | { | |
3838 | char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF]; | |
3839 | ||
3840 | subnettot(our_net, 0, s1, sizeof(s1)); | |
3841 | subnettot(peer_net, 0, d1, sizeof(d1)); | |
3842 | ||
3843 | DBG_log("find_client_connection starting with %s" | |
3844 | , (c ? c->name : "(none)")); | |
3845 | DBG_log(" looking for %s:%d/%d -> %s:%d/%d" | |
3846 | , s1, our_protocol, our_port | |
3847 | , d1, peer_protocol, peer_port); | |
3848 | } | |
3849 | #endif /* DEBUG */ | |
3850 | ||
3851 | /* give priority to current connection | |
3852 | * but even greater priority to a routed concrete connection | |
3853 | */ | |
3854 | { | |
3855 | struct connection *unrouted = NULL; | |
3856 | int srnum = -1; | |
3857 | ||
3858 | for (sr = &c->spd; unrouted == NULL && sr != NULL; sr = sr->next) | |
3859 | { | |
3860 | srnum++; | |
3861 | ||
3862 | #ifdef DEBUG | |
3863 | if (DBGP(DBG_CONTROLMORE)) | |
3864 | { | |
3865 | char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF]; | |
3866 | ||
3867 | subnettot(&sr->this.client, 0, s2, sizeof(s2)); | |
3868 | subnettot(&sr->that.client, 0, d2, sizeof(d2)); | |
3869 | DBG_log(" concrete checking against sr#%d %s -> %s" | |
3870 | , srnum, s2, d2); | |
3871 | } | |
3872 | #endif /* DEBUG */ | |
3873 | ||
3874 | if (samesubnet(&sr->this.client, our_net) | |
3875 | && samesubnet(&sr->that.client, peer_net) | |
3876 | && sr->this.protocol == our_protocol | |
3877 | && sr->this.port == our_port | |
3878 | && sr->that.protocol == peer_protocol | |
3879 | && sr->that.port == peer_port | |
3880 | && group_membership(peer_list, c->name, sr->that.groups)) | |
3881 | { | |
3882 | passert(oriented(*c)); | |
3883 | if (routed(sr->routing)) | |
3884 | return c; | |
3885 | ||
3886 | unrouted = c; | |
3887 | } | |
3888 | } | |
3889 | ||
3890 | /* exact match? */ | |
3891 | d = fc_try(c, c->host_pair, NULL, our_net, peer_net | |
3892 | , our_protocol, our_port, peer_protocol, peer_port | |
3893 | , peer_ca, peer_list); | |
3894 | ||
3895 | DBG(DBG_CONTROLMORE, | |
3896 | DBG_log(" fc_try %s gives %s" | |
3897 | , c->name | |
3898 | , (d ? d->name : "none")) | |
3899 | ) | |
3900 | ||
3901 | if (d == NULL) | |
3902 | d = unrouted; | |
3903 | } | |
3904 | ||
3905 | if (d == NULL) | |
3906 | { | |
3907 | /* look for an abstract connection to match */ | |
3908 | struct spd_route *sr; | |
3909 | struct host_pair *hp = NULL; | |
3910 | ||
3911 | for (sr = &c->spd; hp==NULL && sr != NULL; sr = sr->next) | |
3912 | { | |
3913 | hp = find_host_pair(&sr->this.host_addr | |
3914 | , sr->this.host_port | |
3915 | , NULL | |
3916 | , sr->that.host_port); | |
3917 | #ifdef DEBUG | |
3918 | if (DBGP(DBG_CONTROLMORE)) | |
3919 | { | |
3920 | char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF]; | |
3921 | ||
3922 | subnettot(&sr->this.client, 0, s2, sizeof(s2)); | |
3923 | subnettot(&sr->that.client, 0, d2, sizeof(d2)); | |
3924 | ||
3925 | DBG_log(" checking hostpair %s -> %s is %s" | |
3926 | , s2, d2 | |
3927 | , (hp ? "found" : "not found")); | |
3928 | } | |
3929 | #endif /* DEBUG */ | |
3930 | } | |
3931 | ||
3932 | if (hp != NULL) | |
3933 | { | |
3934 | /* RW match with actual peer_id or abstract peer_id? */ | |
3935 | d = fc_try(c, hp, NULL, our_net, peer_net | |
3936 | , our_protocol, our_port, peer_protocol, peer_port | |
3937 | , peer_ca, peer_list); | |
3938 | ||
3939 | if (d == NULL | |
3940 | && subnetishost(our_net) | |
3941 | && subnetishost(peer_net)) | |
3942 | { | |
3943 | /* Opportunistic match? | |
3944 | * Always use abstract peer_id. | |
3945 | * Note that later instantiation will result in the same peer_id. | |
3946 | */ | |
3947 | d = fc_try_oppo(c, hp, our_net, peer_net | |
3948 | , our_protocol, our_port, peer_protocol, peer_port | |
3949 | , peer_ca, peer_list); | |
3950 | } | |
3951 | } | |
3952 | } | |
3953 | ||
3954 | DBG(DBG_CONTROLMORE, | |
3955 | DBG_log(" concluding with d = %s" | |
3956 | , (d ? d->name : "none")) | |
3957 | ) | |
3958 | return d; | |
3959 | } | |
3960 | ||
3961 | int | |
3962 | connection_compare(const struct connection *ca | |
3963 | , const struct connection *cb) | |
3964 | { | |
3965 | int ret; | |
3966 | ||
3967 | /* DBG_log("comparing %s to %s", ca->name, cb->name); */ | |
3968 | ||
3969 | ret = strcasecmp(ca->name, cb->name); | |
3970 | if (ret != 0) | |
3971 | return ret; | |
3972 | ||
3973 | ret = ca->kind - cb->kind; /* note: enum connection_kind behaves like int */ | |
3974 | if (ret != 0) | |
3975 | return ret; | |
3976 | ||
3977 | /* same name, and same type */ | |
3978 | switch (ca->kind) | |
3979 | { | |
3980 | case CK_INSTANCE: | |
3981 | return ca->instance_serial < cb->instance_serial ? -1 | |
3982 | : ca->instance_serial > cb->instance_serial ? 1 | |
3983 | : 0; | |
3984 | ||
3985 | default: | |
3986 | return ca->prio < cb->prio ? -1 | |
3987 | : ca->prio > cb->prio ? 1 | |
3988 | : 0; | |
3989 | } | |
3990 | } | |
3991 | ||
3992 | static int | |
3993 | connection_compare_qsort(const void *a, const void *b) | |
3994 | { | |
3995 | return connection_compare(*(const struct connection *const *)a | |
3996 | , *(const struct connection *const *)b); | |
3997 | } | |
3998 | ||
3999 | void | |
4000 | show_connections_status(bool all, const char *name) | |
4001 | { | |
4002 | struct connection *c; | |
4003 | int count, i; | |
4004 | struct connection **array; | |
4005 | ||
4006 | /* make an array of connections, and sort it */ | |
4007 | count = 0; | |
4008 | for (c = connections; c != NULL; c = c->ac_next) | |
4009 | { | |
4010 | if (name == NULL || streq(c->name, name)) | |
4011 | count++; | |
4012 | } | |
4013 | array = alloc_bytes(sizeof(struct connection *)*count, "connection array"); | |
4014 | ||
4015 | count=0; | |
4016 | for (c = connections; c != NULL; c = c->ac_next) | |
4017 | { | |
4018 | if (name == NULL || streq(c->name, name)) | |
4019 | array[count++]=c; | |
4020 | } | |
4021 | ||
4022 | /* sort it! */ | |
4023 | qsort(array, count, sizeof(struct connection *), connection_compare_qsort); | |
4024 | ||
9820c0e2 | 4025 | for (i = 0; i < count; i++) |
997358a6 MW |
4026 | { |
4027 | const char *ifn; | |
4028 | char instance[1 + 10 + 1]; | |
4029 | char prio[POLICY_PRIO_BUF]; | |
4030 | ||
4031 | c = array[i]; | |
4032 | ||
4033 | ifn = oriented(*c)? c->interface->rname : ""; | |
4034 | ||
4035 | instance[0] = '\0'; | |
4036 | if (c->kind == CK_INSTANCE && c->instance_serial != 0) | |
4037 | snprintf(instance, sizeof(instance), "[%lu]", c->instance_serial); | |
4038 | ||
4039 | /* show topology */ | |
4040 | { | |
4041 | char topo[CONNECTION_BUF]; | |
4042 | struct spd_route *sr = &c->spd; | |
4043 | int num=0; | |
4044 | ||
4045 | while (sr != NULL) | |
4046 | { | |
4047 | (void) format_connection(topo, sizeof(topo), c, sr); | |
4048 | whack_log(RC_COMMENT, "\"%s\"%s: %s; %s; eroute owner: #%lu" | |
4049 | , c->name, instance, topo | |
4050 | , enum_name(&routing_story, sr->routing) | |
4051 | , sr->eroute_owner); | |
4052 | sr = sr->next; | |
4053 | num++; | |
4054 | } | |
4055 | } | |
4056 | ||
4057 | if (all) | |
4058 | { | |
4059 | /* show CAs if defined */ | |
4060 | if (c->spd.this.ca.ptr != NULL || c->spd.that.ca.ptr != NULL) | |
4061 | { | |
4062 | char this_ca[BUF_LEN], that_ca[BUF_LEN]; | |
4063 | ||
4064 | dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any"); | |
4065 | dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any"); | |
4066 | ||
4067 | whack_log(RC_COMMENT | |
4068 | , "\"%s\"%s: CAs: '%s'...'%s'" | |
4069 | , c->name | |
4070 | , instance | |
4071 | , this_ca | |
4072 | , that_ca); | |
4073 | } | |
4074 | ||
4075 | /* show group attributes if defined */ | |
4076 | if (c->spd.that.groups != NULL) | |
4077 | { | |
4078 | char buf[BUF_LEN]; | |
9820c0e2 | 4079 | |
997358a6 MW |
4080 | format_groups(c->spd.that.groups, buf, BUF_LEN); |
4081 | whack_log(RC_COMMENT | |
4082 | , "\"%s\"%s: groups: %s" | |
4083 | , c->name | |
4084 | , instance | |
4085 | , buf); | |
4086 | } | |
4087 | ||
4088 | whack_log(RC_COMMENT | |
4089 | , "\"%s\"%s: ike_life: %lus; ipsec_life: %lus;" | |
4090 | " rekey_margin: %lus; rekey_fuzz: %lu%%; keyingtries: %lu" | |
4091 | , c->name | |
4092 | , instance | |
4093 | , (unsigned long) c->sa_ike_life_seconds | |
4094 | , (unsigned long) c->sa_ipsec_life_seconds | |
4095 | , (unsigned long) c->sa_rekey_margin | |
4096 | , (unsigned long) c->sa_rekey_fuzz | |
4097 | , (unsigned long) c->sa_keying_tries); | |
4098 | ||
4099 | /* show DPD parameters if defined */ | |
9820c0e2 | 4100 | |
997358a6 MW |
4101 | if (c->dpd_action != DPD_ACTION_NONE) |
4102 | whack_log(RC_COMMENT | |
4103 | , "\"%s\"%s: dpd_action: %s;" | |
4104 | " dpd_delay: %lus; dpd_timeout: %lus;" | |
4105 | , c->name | |
4106 | , instance | |
4107 | , enum_show(&dpd_action_names, c->dpd_action) | |
4108 | , (unsigned long) c->dpd_delay | |
4109 | , (unsigned long) c->dpd_timeout); | |
4110 | ||
4111 | if (c->policy_next) | |
4112 | { | |
4113 | whack_log(RC_COMMENT | |
4114 | , "\"%s\"%s: policy_next: %s" | |
4115 | , c->name, instance, c->policy_next->name); | |
4116 | } | |
4117 | ||
4118 | /* Note: we display key_from_DNS_on_demand as if policy [lr]KOD */ | |
4119 | fmt_policy_prio(c->prio, prio); | |
4120 | whack_log(RC_COMMENT | |
4121 | , "\"%s\"%s: policy: %s%s%s; prio: %s; interface: %s; " | |
4122 | , c->name | |
4123 | , instance | |
4124 | , prettypolicy(c->policy) | |
4125 | , c->spd.this.key_from_DNS_on_demand? "+lKOD" : "" | |
4126 | , c->spd.that.key_from_DNS_on_demand? "+rKOD" : "" | |
4127 | , prio | |
4128 | , ifn); | |
4129 | } | |
4130 | ||
4131 | whack_log(RC_COMMENT | |
4132 | , "\"%s\"%s: newest ISAKMP SA: #%ld; newest IPsec SA: #%ld; " | |
4133 | , c->name | |
4134 | , instance | |
4135 | , c->newest_isakmp_sa | |
4136 | , c->newest_ipsec_sa); | |
4137 | ||
4138 | if (all) | |
4139 | { | |
4140 | ike_alg_show_connection(c, instance); | |
4141 | kernel_alg_show_connection(c, instance); | |
4142 | } | |
4143 | } | |
9820c0e2 MW |
4144 | if (count > 0) |
4145 | whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */ | |
4146 | ||
997358a6 MW |
4147 | pfree(array); |
4148 | } | |
4149 | ||
4150 | /* struct pending, the structure representing Quick Mode | |
4151 | * negotiations delayed until a Keying Channel has been negotiated. | |
4152 | * Essentially, a pending call to quick_outI1. | |
4153 | */ | |
4154 | ||
4155 | struct pending { | |
4156 | int whack_sock; | |
4157 | struct state *isakmp_sa; | |
4158 | struct connection *connection; | |
4159 | lset_t policy; | |
4160 | unsigned long try; | |
4161 | so_serial_t replacing; | |
4162 | ||
4163 | struct pending *next; | |
4164 | }; | |
4165 | ||
4166 | /* queue a Quick Mode negotiation pending completion of a suitable Main Mode */ | |
4167 | void | |
4168 | add_pending(int whack_sock | |
4169 | , struct state *isakmp_sa | |
4170 | , struct connection *c | |
4171 | , lset_t policy | |
4172 | , unsigned long try | |
4173 | , so_serial_t replacing) | |
4174 | { | |
4175 | bool already_queued = FALSE; | |
4176 | struct pending *p = c->host_pair->pending; | |
4177 | ||
4178 | while (p != NULL) | |
4179 | { | |
4180 | if (streq(c->name, p->connection->name)) | |
4181 | { | |
4182 | already_queued = TRUE; | |
4183 | break; | |
4184 | } | |
4185 | p = p->next; | |
4186 | } | |
4187 | DBG(DBG_CONTROL, | |
4188 | DBG_log("Queuing pending Quick Mode with %s \"%s\"%s" | |
4189 | , ip_str(&c->spd.that.host_addr) | |
4190 | , c->name | |
4191 | , already_queued? " already done" : "") | |
4192 | ) | |
4193 | if (already_queued) | |
4194 | return; | |
4195 | ||
4196 | p = alloc_thing(struct pending, "struct pending"); | |
4197 | p->whack_sock = whack_sock; | |
4198 | p->isakmp_sa = isakmp_sa; | |
4199 | p->connection = c; | |
4200 | p->policy = policy; | |
4201 | p->try = try; | |
4202 | p->replacing = replacing; | |
4203 | p->next = c->host_pair->pending; | |
4204 | c->host_pair->pending = p; | |
4205 | } | |
4206 | ||
4207 | /* Release all the whacks awaiting the completion of this state. | |
4208 | * This is accomplished by closing all the whack socket file descriptors. | |
4209 | * We go to a lot of trouble to tell each whack, but to not tell it twice. | |
4210 | */ | |
4211 | void | |
4212 | release_pending_whacks(struct state *st, err_t story) | |
4213 | { | |
4214 | struct pending *p; | |
4215 | struct stat stst; | |
4216 | ||
4217 | if (st->st_whack_sock == NULL_FD || fstat(st->st_whack_sock, &stst) != 0) | |
4218 | zero(&stst); /* resulting st_dev/st_ino ought to be distinct */ | |
4219 | ||
4220 | release_whack(st); | |
4221 | ||
4222 | for (p = st->st_connection->host_pair->pending; p != NULL; p = p->next) | |
4223 | { | |
4224 | if (p->isakmp_sa == st && p->whack_sock != NULL_FD) | |
4225 | { | |
4226 | struct stat pst; | |
4227 | ||
4228 | if (fstat(p->whack_sock, &pst) == 0 | |
4229 | && (stst.st_dev != pst.st_dev || stst.st_ino != pst.st_ino)) | |
4230 | { | |
4231 | passert(whack_log_fd == NULL_FD); | |
4232 | whack_log_fd = p->whack_sock; | |
4233 | whack_log(RC_COMMENT | |
4234 | , "%s for ISAKMP SA, but releasing whack for pending IPSEC SA" | |
4235 | , story); | |
4236 | whack_log_fd = NULL_FD; | |
4237 | } | |
4238 | close(p->whack_sock); | |
4239 | p->whack_sock = NULL_FD; | |
4240 | } | |
4241 | } | |
4242 | } | |
4243 | ||
4244 | static void | |
4245 | delete_pending(struct pending **pp) | |
4246 | { | |
4247 | struct pending *p = *pp; | |
4248 | ||
4249 | *pp = p->next; | |
4250 | if (p->connection != NULL) | |
4251 | connection_discard(p->connection); | |
4252 | close_any(p->whack_sock); | |
4253 | pfree(p); | |
4254 | } | |
4255 | ||
4256 | void | |
4257 | unpend(struct state *st) | |
4258 | { | |
4259 | struct pending **pp | |
4260 | , *p; | |
4261 | ||
4262 | for (pp = &st->st_connection->host_pair->pending; (p = *pp) != NULL; ) | |
4263 | { | |
4264 | if (p->isakmp_sa == st) | |
4265 | { | |
4266 | DBG(DBG_CONTROL, DBG_log("unqueuing pending Quick Mode with %s \"%s\"" | |
4267 | , ip_str(&p->connection->spd.that.host_addr) | |
4268 | , p->connection->name)); | |
4269 | (void) quick_outI1(p->whack_sock, st, p->connection, p->policy | |
4270 | , p->try, p->replacing); | |
4271 | p->whack_sock = NULL_FD; /* ownership transferred */ | |
4272 | p->connection = NULL; /* ownership transferred */ | |
4273 | delete_pending(pp); | |
4274 | } | |
4275 | else | |
4276 | { | |
4277 | pp = &p->next; | |
4278 | } | |
4279 | } | |
4280 | } | |
4281 | ||
4282 | /* a Main Mode negotiation has been replaced; update any pending */ | |
4283 | void | |
4284 | update_pending(struct state *os, struct state *ns) | |
4285 | { | |
4286 | struct pending *p; | |
4287 | ||
4288 | for (p = os->st_connection->host_pair->pending; p != NULL; p = p->next) | |
4289 | { | |
4290 | if (p->isakmp_sa == os) | |
4291 | p->isakmp_sa = ns; | |
4292 | #ifdef NAT_TRAVERSAL | |
4293 | if (p->connection->spd.this.host_port != ns->st_connection->spd.this.host_port) | |
4294 | { | |
4295 | p->connection->spd.this.host_port = ns->st_connection->spd.this.host_port; | |
4296 | p->connection->spd.that.host_port = ns->st_connection->spd.that.host_port; | |
4297 | } | |
4298 | #endif | |
4299 | } | |
4300 | } | |
4301 | ||
4302 | /* a Main Mode negotiation has failed; discard any pending */ | |
4303 | void | |
4304 | flush_pending_by_state(struct state *st) | |
4305 | { | |
4306 | struct host_pair *hp = st->st_connection->host_pair; | |
4307 | ||
4308 | if (hp != NULL) | |
4309 | { | |
4310 | struct pending **pp | |
4311 | , *p; | |
4312 | ||
4313 | for (pp = &hp->pending; (p = *pp) != NULL; ) | |
4314 | { | |
4315 | if (p->isakmp_sa == st) | |
4316 | delete_pending(pp); | |
4317 | else | |
4318 | pp = &p->next; | |
4319 | } | |
4320 | } | |
4321 | } | |
4322 | ||
4323 | /* a connection has been deleted; discard any related pending */ | |
4324 | static void | |
4325 | flush_pending_by_connection(struct connection *c) | |
4326 | { | |
4327 | if (c->host_pair != NULL) | |
4328 | { | |
4329 | struct pending **pp | |
4330 | , *p; | |
4331 | ||
4332 | for (pp = &c->host_pair->pending; (p = *pp) != NULL; ) | |
4333 | { | |
4334 | if (p->connection == c) | |
4335 | { | |
4336 | p->connection = NULL; /* prevent delete_pending from releasing */ | |
4337 | delete_pending(pp); | |
4338 | } | |
4339 | else | |
4340 | { | |
4341 | pp = &p->next; | |
4342 | } | |
4343 | } | |
4344 | } | |
4345 | } | |
4346 | ||
4347 | void | |
4348 | show_pending_phase2(const struct host_pair *hp, const struct state *st) | |
4349 | { | |
4350 | const struct pending *p; | |
4351 | ||
4352 | for (p = hp->pending; p != NULL; p = p->next) | |
4353 | { | |
4354 | if (p->isakmp_sa == st) | |
4355 | { | |
4356 | /* connection-name state-number [replacing state-number] */ | |
4357 | char cip[CONN_INST_BUF]; | |
4358 | ||
4359 | fmt_conn_instance(p->connection, cip); | |
4360 | whack_log(RC_COMMENT, "#%lu: pending Phase 2 for \"%s\"%s replacing #%lu" | |
4361 | , p->isakmp_sa->st_serialno | |
4362 | , p->connection->name | |
4363 | , cip | |
4364 | , p->replacing); | |
4365 | } | |
4366 | } | |
4367 | } | |
4368 | ||
4369 | /* Delete a connection if it is an instance and it is no longer in use. | |
4370 | * We must be careful to avoid circularity: | |
4371 | * we don't touch it if it is CK_GOING_AWAY. | |
4372 | */ | |
4373 | void | |
4374 | connection_discard(struct connection *c) | |
4375 | { | |
4376 | if (c->kind == CK_INSTANCE) | |
4377 | { | |
4378 | /* see if it is being used by a pending */ | |
4379 | struct pending *p; | |
4380 | ||
4381 | for (p = c->host_pair->pending; p != NULL; p = p->next) | |
4382 | if (p->connection == c) | |
4383 | return; /* in use, so we're done */ | |
4384 | ||
4385 | if (!states_use_connection(c)) | |
4386 | delete_connection(c, FALSE); | |
4387 | } | |
4388 | } | |
4389 | ||
4390 | ||
4391 | /* A template connection's eroute can be eclipsed by | |
4392 | * either a %hold or an eroute for an instance iff | |
4393 | * the template is a /32 -> /32. This requires some special casing. | |
4394 | */ | |
4395 | ||
4396 | long eclipse_count = 0; | |
4397 | ||
4398 | struct connection * | |
4399 | eclipsed(struct connection *c, struct spd_route **esrp) | |
4400 | { | |
4401 | struct connection *ue; | |
4402 | struct spd_route *sr1 = &c->spd; | |
4403 | ||
4404 | ue = NULL; | |
4405 | ||
4406 | while (sr1 != NULL && ue != NULL) | |
4407 | { | |
4408 | for (ue = connections; ue != NULL; ue = ue->ac_next) | |
4409 | { | |
4410 | struct spd_route *srue = &ue->spd; | |
4411 | ||
4412 | while (srue != NULL | |
4413 | && srue->routing == RT_ROUTED_ECLIPSED | |
4414 | && !(samesubnet(&sr1->this.client, &srue->this.client) | |
4415 | && samesubnet(&sr1->that.client, &srue->that.client))) | |
4416 | { | |
4417 | srue = srue->next; | |
4418 | } | |
4419 | if (srue != NULL && srue->routing==RT_ROUTED_ECLIPSED) | |
4420 | { | |
4421 | *esrp = srue; | |
4422 | break; | |
4423 | } | |
4424 | } | |
4425 | } | |
4426 | return ue; | |
4427 | } | |
4428 | ||
4429 | /* | |
4430 | * Local Variables: | |
4431 | * c-basic-offset:4 | |
4432 | * c-style: pluto | |
4433 | * End: | |
4434 | */ |