Added missing Android.mk files to distribution.
[strongswan.git] / src / starter / confread.c
1 /* strongSwan IPsec config file parser
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
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 */
14
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <stddef.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <assert.h>
22
23 #include <freeswan.h>
24
25 #include <eap/eap.h>
26
27 #include "../pluto/constants.h"
28 #include "../pluto/defs.h"
29 #include "../pluto/log.h"
30
31 #include "keywords.h"
32 #include "confread.h"
33 #include "args.h"
34 #include "files.h"
35 #include "interfaces.h"
36
37 /* strings containing a colon are interpreted as an IPv6 address */
38 #define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
39
40 static const char ike_defaults[] = "aes128-sha1-modp2048,3des-sha1-modp1536";
41 static const char esp_defaults[] = "aes128-sha1,3des-sha1";
42
43 static const char firewall_defaults[] = "ipsec _updown iptables";
44
45 static bool daemon_exists(char *daemon, char *path)
46 {
47 struct stat st;
48 if (stat(path, &st) != 0)
49 {
50 plog("Disabling %sstart option, '%s' not found", daemon, path);
51 return FALSE;
52 }
53 return TRUE;
54 }
55
56 static void default_values(starter_config_t *cfg)
57 {
58 if (cfg == NULL)
59 return;
60
61 memset(cfg, 0, sizeof(struct starter_config));
62
63 /* is there enough space for all seen flags? */
64 assert(KW_SETUP_LAST - KW_SETUP_FIRST <
65 sizeof(cfg->setup.seen) * BITS_PER_BYTE);
66 assert(KW_CONN_LAST - KW_CONN_FIRST <
67 sizeof(cfg->conn_default.seen) * BITS_PER_BYTE);
68 assert(KW_END_LAST - KW_END_FIRST <
69 sizeof(cfg->conn_default.right.seen) * BITS_PER_BYTE);
70 assert(KW_CA_LAST - KW_CA_FIRST <
71 sizeof(cfg->ca_default.seen) * BITS_PER_BYTE);
72
73 cfg->setup.seen = LEMPTY;
74 cfg->setup.fragicmp = TRUE;
75 cfg->setup.hidetos = TRUE;
76 cfg->setup.uniqueids = TRUE;
77 cfg->setup.interfaces = new_list("%defaultroute");
78
79 #ifdef START_CHARON
80 cfg->setup.charonstart = TRUE;
81 #endif
82 #ifdef START_PLUTO
83 cfg->setup.plutostart = TRUE;
84 #endif
85
86 cfg->conn_default.seen = LEMPTY;
87 cfg->conn_default.startup = STARTUP_NO;
88 cfg->conn_default.state = STATE_IGNORE;
89 cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_PUBKEY |
90 POLICY_PFS | POLICY_MOBIKE;
91
92 cfg->conn_default.ike = clone_str(ike_defaults);
93 cfg->conn_default.esp = clone_str(esp_defaults);
94 cfg->conn_default.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
95 cfg->conn_default.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
96 cfg->conn_default.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
97 cfg->conn_default.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
98 cfg->conn_default.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
99 cfg->conn_default.addr_family = AF_INET;
100 cfg->conn_default.tunnel_addr_family = AF_INET;
101 cfg->conn_default.install_policy = TRUE;
102 cfg->conn_default.dpd_delay = 30; /* seconds */
103 cfg->conn_default.dpd_timeout = 150; /* seconds */
104
105 cfg->conn_default.left.seen = LEMPTY;
106 cfg->conn_default.right.seen = LEMPTY;
107
108 cfg->conn_default.left.sendcert = CERT_SEND_IF_ASKED;
109 cfg->conn_default.right.sendcert = CERT_SEND_IF_ASKED;
110
111 anyaddr(AF_INET, &cfg->conn_default.left.addr);
112 anyaddr(AF_INET, &cfg->conn_default.left.nexthop);
113 anyaddr(AF_INET, &cfg->conn_default.right.addr);
114 anyaddr(AF_INET, &cfg->conn_default.right.nexthop);
115 cfg->conn_default.left.ikeport = 500;
116 cfg->conn_default.right.ikeport = 500;
117
118 cfg->ca_default.seen = LEMPTY;
119 }
120
121 #define KW_POLICY_FLAG(sy, sn, fl) \
122 if (streq(kw->value, sy)) { conn->policy |= fl; } \
123 else if (streq(kw->value, sn)) { conn->policy &= ~fl; } \
124 else { plog("# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; }
125
126 static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
127 {
128 kw_list_t *kw;
129
130 DBG(DBG_CONTROL,
131 DBG_log("Loading config setup")
132 )
133
134 for (kw = cfgp->config_setup; kw; kw = kw->next)
135 {
136 bool assigned = FALSE;
137
138 kw_token_t token = kw->entry->token;
139
140 if (token < KW_SETUP_FIRST || token > KW_SETUP_LAST)
141 {
142 plog("# unsupported keyword '%s' in config setup", kw->entry->name);
143 cfg->err++;
144 continue;
145 }
146
147 if (!assign_arg(token, KW_SETUP_FIRST, kw, (char *)cfg, &assigned))
148 {
149 plog(" bad argument value in config setup");
150 cfg->err++;
151 continue;
152 }
153 }
154
155 /* verify the executables are actually available (some distros split
156 * packages but enabled both) */
157 #ifdef START_CHARON
158 cfg->setup.charonstart = cfg->setup.charonstart &&
159 daemon_exists("charon", CHARON_CMD);
160 #else
161 cfg->setup.charonstart = FALSE;
162 #endif
163 #ifdef START_PLUTO
164 cfg->setup.plutostart = cfg->setup.plutostart &&
165 daemon_exists("pluto", PLUTO_CMD);
166 #else
167 cfg->setup.plutostart = FALSE;
168 #endif
169 }
170
171 static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
172 kw_list_t *kw, char *conn_name, starter_config_t *cfg)
173 {
174 err_t ugh = NULL;
175 bool assigned = FALSE;
176 bool has_port_wildcard; /* set if port is %any */
177
178 char *name = kw->entry->name;
179 char *value = kw->value;
180
181 if (!assign_arg(token, KW_END_FIRST, kw, (char *)end, &assigned))
182 goto err;
183
184 /* post processing of some keywords that were assigned automatically */
185 switch (token)
186 {
187 case KW_HOST:
188 free(end->host);
189 end->host = NULL;
190 if (streq(value, "%defaultroute"))
191 {
192 if (cfg->defaultroute.defined)
193 {
194 end->addr = cfg->defaultroute.addr;
195 end->nexthop = cfg->defaultroute.nexthop;
196 }
197 else if (!cfg->defaultroute.supported)
198 {
199 plog("%%defaultroute not supported, fallback to %%any");
200 }
201 else
202 {
203 plog("# default route not known: %s=%s", name, value);
204 goto err;
205 }
206 }
207 else if (streq(value, "%any") || streq(value, "%any4"))
208 {
209 anyaddr(conn->addr_family, &end->addr);
210 }
211 else if (streq(value, "%any6"))
212 {
213 conn->addr_family = AF_INET6;
214 anyaddr(conn->addr_family, &end->addr);
215 }
216 else if (streq(value, "%group"))
217 {
218 ip_address any;
219
220 conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
221 anyaddr(conn->addr_family, &end->addr);
222 anyaddr(conn->tunnel_addr_family, &any);
223 end->has_client = TRUE;
224 }
225 else
226 {
227 /* check for allow_any prefix */
228 if (value[0] == '%')
229 {
230 end->allow_any = TRUE;
231 value++;
232 }
233 conn->addr_family = ip_version(value);
234 ugh = ttoaddr(value, 0, conn->addr_family, &end->addr);
235 if (ugh != NULL)
236 {
237 plog("# bad addr: %s=%s [%s]", name, value, ugh);
238 if (streq(ugh, "does not look numeric and name lookup failed"))
239 {
240 end->dns_failed = TRUE;
241 anyaddr(conn->addr_family, &end->addr);
242 }
243 else
244 {
245 goto err;
246 }
247 }
248 end->host = clone_str(value);
249 }
250 break;
251 case KW_SUBNET:
252 if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
253 || (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
254 {
255 /* used by pluto only */
256 end->has_virt = TRUE;
257 }
258 else
259 {
260 ip_subnet net;
261 char *pos;
262 int len = 0;
263
264 end->has_client = TRUE;
265 conn->tunnel_addr_family = ip_version(value);
266
267 pos = strchr(value, ',');
268 if (pos)
269 {
270 len = pos - value;
271 }
272 ugh = ttosubnet(value, len, ip_version(value), &net);
273 if (ugh != NULL)
274 {
275 plog("# bad subnet: %s=%s [%s]", name, value, ugh);
276 goto err;
277 }
278 }
279 break;
280 case KW_SOURCEIP:
281 if (end->has_natip)
282 {
283 plog("# natip and sourceip cannot be defined at the same time");
284 goto err;
285 }
286 if (value[0] == '%')
287 {
288 if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
289 streq(value, "%config") || streq(value, "%cfg"))
290 {
291 /* request ip via config payload */
292 free(end->sourceip);
293 end->sourceip = NULL;
294 end->sourceip_mask = 1;
295 }
296 else
297 { /* %poolname, strip %, serve ip requests */
298 free(end->sourceip);
299 end->sourceip = clone_str(value+1);
300 end->sourceip_mask = 0;
301 }
302 end->modecfg = TRUE;
303 }
304 else
305 {
306 char *pos;
307 ip_address addr;
308 ip_subnet net;
309
310 conn->tunnel_addr_family = ip_version(value);
311 pos = strchr(value, '/');
312
313 if (pos)
314 { /* CIDR notation, address pool */
315 ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &net);
316 if (ugh != NULL)
317 {
318 plog("# bad subnet: %s=%s [%s]", name, value, ugh);
319 goto err;
320 }
321 *pos = '\0';
322 free(end->sourceip);
323 end->sourceip = clone_str(value);
324 end->sourceip_mask = atoi(pos + 1);
325 }
326 else
327 { /* fixed srcip */
328 ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
329 if (ugh != NULL)
330 {
331 plog("# bad addr: %s=%s [%s]", name, value, ugh);
332 goto err;
333 }
334 end->sourceip_mask = (conn->tunnel_addr_family == AF_INET) ?
335 32 : 128;
336 }
337 }
338 conn->policy |= POLICY_TUNNEL;
339 break;
340 case KW_SENDCERT:
341 if (end->sendcert == CERT_YES_SEND)
342 {
343 end->sendcert = CERT_ALWAYS_SEND;
344 }
345 else if (end->sendcert == CERT_NO_SEND)
346 {
347 end->sendcert = CERT_NEVER_SEND;
348 }
349 break;
350 default:
351 break;
352 }
353
354 if (assigned)
355 return;
356
357 /* individual processing of keywords that were not assigned automatically */
358 switch (token)
359 {
360 case KW_NEXTHOP:
361 if (streq(value, "%defaultroute"))
362 {
363 if (cfg->defaultroute.defined)
364 {
365 end->nexthop = cfg->defaultroute.nexthop;
366 }
367 else
368 {
369 plog("# default route not known: %s=%s", name, value);
370 goto err;
371 }
372 }
373 else if (streq(value, "%direct"))
374 {
375 ugh = anyaddr(conn->addr_family, &end->nexthop);
376 }
377 else
378 {
379 conn->addr_family = ip_version(value);
380 ugh = ttoaddr(value, 0, conn->addr_family, &end->nexthop);
381 }
382 if (ugh != NULL)
383 {
384 plog("# bad addr: %s=%s [%s]", name, value, ugh);
385 goto err;
386 }
387 break;
388 case KW_SUBNETWITHIN:
389 {
390 ip_subnet net;
391
392 end->has_client = TRUE;
393 end->has_client_wildcard = TRUE;
394 conn->tunnel_addr_family = ip_version(value);
395
396 ugh = ttosubnet(value, 0, ip_version(value), &net);
397 if (ugh != NULL)
398 {
399 plog("# bad subnet: %s=%s [%s]", name, value, ugh);
400 goto err;
401 }
402 end->subnet = clone_str(value);
403 break;
404 }
405 case KW_PROTOPORT:
406 ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
407 end->has_port_wildcard = has_port_wildcard;
408 break;
409 case KW_NATIP:
410 if (end->sourceip)
411 {
412 plog("# natip and sourceip cannot be defined at the same time");
413 goto err;
414 }
415 if (streq(value, "%defaultroute"))
416 {
417 char buf[64];
418
419 if (cfg->defaultroute.defined)
420 {
421 addrtot(&cfg->defaultroute.addr, 0, buf, sizeof(buf));
422 end->sourceip = clone_str(buf);
423 }
424 else
425 {
426 plog("# default route not known: %s=%s", name, value);
427 goto err;
428 }
429 }
430 else
431 {
432 ip_address addr;
433
434 conn->tunnel_addr_family = ip_version(value);
435 ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
436 if (ugh != NULL)
437 {
438 plog("# bad addr: %s=%s [%s]", name, value, ugh);
439 goto err;
440 }
441 end->sourceip = clone_str(value);
442 }
443 end->has_natip = TRUE;
444 conn->policy |= POLICY_TUNNEL;
445 break;
446 default:
447 break;
448 }
449 return;
450
451 err:
452 plog(" bad argument value in conn '%s'", conn_name);
453 cfg->err++;
454 }
455
456 /*
457 * handles left|right=<FQDN> DNS resolution failure
458 */
459 static void handle_dns_failure(const char *label, starter_end_t *end,
460 starter_config_t *cfg, starter_conn_t *conn)
461 {
462 if (end->dns_failed)
463 {
464 if (end->allow_any)
465 {
466 plog("# fallback to %s=%%any due to '%%' prefix or %sallowany=yes",
467 label, label);
468 }
469 else if (!end->host || conn->keyexchange == KEY_EXCHANGE_IKEV1)
470 {
471 /* declare an error */
472 cfg->err++;
473 }
474 }
475 }
476
477 /*
478 * handles left|rightfirewall and left|rightupdown parameters
479 */
480 static void handle_firewall(const char *label, starter_end_t *end,
481 starter_config_t *cfg)
482 {
483 if (end->firewall && (end->seen & LELEM(KW_FIREWALL - KW_END_FIRST)))
484 {
485 if (end->updown != NULL)
486 {
487 plog("# cannot have both %sfirewall and %supdown", label, label);
488 cfg->err++;
489 }
490 else
491 {
492 end->updown = clone_str(firewall_defaults);
493 end->firewall = FALSE;
494 }
495 }
496 }
497
498 static bool handle_mark(char *value, mark_t *mark)
499 {
500 char *pos, *endptr;
501
502 pos = strchr(value, '/');
503 if (pos)
504 {
505 *pos = '\0';
506 mark->mask = strtoul(pos+1, &endptr, 0);
507 if (*endptr != '\0')
508 {
509 plog("# invalid mark mask: %s", pos+1);
510 return FALSE;
511 }
512 }
513 else
514 {
515 mark->mask = 0xffffffff;
516 }
517 if (value == '\0')
518 {
519 mark->value = 0;
520 }
521 else
522 {
523 mark->value = strtoul(value, &endptr, 0);
524 if (*endptr != '\0')
525 {
526 plog("# invalid mark value: %s", value);
527 return FALSE;
528 }
529 }
530 return TRUE;
531 }
532
533 /*
534 * parse a conn section
535 */
536 static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
537 {
538 char *conn_name = (conn->name == NULL)? "%default":conn->name;
539
540 for ( ; kw; kw = kw->next)
541 {
542 bool assigned = FALSE;
543
544 kw_token_t token = kw->entry->token;
545
546 if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST)
547 {
548 kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST
549 , kw, conn_name, cfg);
550 continue;
551 }
552 else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST)
553 {
554 kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST
555 , kw, conn_name, cfg);
556 continue;
557 }
558
559 if (token == KW_AUTO)
560 {
561 token = KW_CONN_SETUP;
562 }
563 else if (token == KW_ALSO)
564 {
565 if (cfg->parse_also)
566 {
567 also_t *also = malloc_thing(also_t);
568
569 also->name = clone_str(kw->value);
570 also->next = conn->also;
571 conn->also = also;
572
573 DBG(DBG_CONTROL,
574 DBG_log(" also=%s", kw->value)
575 )
576 }
577 continue;
578 }
579
580 if (token < KW_CONN_FIRST || token > KW_CONN_LAST)
581 {
582 plog("# unsupported keyword '%s' in conn '%s'"
583 , kw->entry->name, conn_name);
584 cfg->err++;
585 continue;
586 }
587
588 if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned))
589 {
590 plog(" bad argument value in conn '%s'", conn_name);
591 cfg->err++;
592 continue;
593 }
594
595 if (assigned)
596 continue;
597
598 switch (token)
599 {
600 case KW_TYPE:
601 conn->policy &= ~(POLICY_TUNNEL | POLICY_SHUNT_MASK);
602 if (streq(kw->value, "tunnel"))
603 {
604 conn->policy |= POLICY_TUNNEL;
605 }
606 else if (streq(kw->value, "beet"))
607 {
608 conn->policy |= POLICY_BEET;
609 }
610 else if (streq(kw->value, "transport_proxy"))
611 {
612 conn->policy |= POLICY_PROXY;
613 }
614 else if (streq(kw->value, "passthrough") || streq(kw->value, "pass"))
615 {
616 conn->policy |= POLICY_SHUNT_PASS;
617 }
618 else if (streq(kw->value, "drop"))
619 {
620 conn->policy |= POLICY_SHUNT_DROP;
621 }
622 else if (streq(kw->value, "reject"))
623 {
624 conn->policy |= POLICY_SHUNT_REJECT;
625 }
626 else if (strcmp(kw->value, "transport") != 0)
627 {
628 plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
629 cfg->err++;
630 }
631 break;
632 case KW_PFS:
633 KW_POLICY_FLAG("yes", "no", POLICY_PFS)
634 break;
635 case KW_COMPRESS:
636 KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS)
637 break;
638 case KW_AUTH:
639 KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE)
640 break;
641 case KW_AUTHBY:
642 conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT);
643
644 if (!streq(kw->value, "never"))
645 {
646 char *value = kw->value;
647 char *second = strchr(kw->value, '|');
648
649 if (second != NULL)
650 {
651 *second = '\0';
652 }
653
654 /* also handles the cases secret|rsasig and rsasig|secret */
655 for (;;)
656 {
657 if (streq(value, "rsa") || streq(value, "rsasig") ||
658 streq(value, "ecdsa") || streq(value, "ecdsasig") ||
659 streq(value, "pubkey"))
660 {
661 conn->policy |= POLICY_PUBKEY | POLICY_ENCRYPT;
662 }
663 else if (streq(value, "secret") || streq(value, "psk"))
664 {
665 conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
666 }
667 else if (streq(value, "xauthrsasig"))
668 {
669 conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
670 }
671 else if (streq(value, "xauthpsk") || streq(value, "eap"))
672 {
673 conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT;
674 }
675 else
676 {
677 plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
678 cfg->err++;
679 break;
680 }
681 if (second == NULL)
682 {
683 break;
684 }
685 value = second;
686 second = NULL; /* traverse the loop no more than twice */
687 }
688 }
689 break;
690 case KW_EAP:
691 {
692 char *sep;
693
694 /* check for vendor-type format */
695 sep = strchr(kw->value, '-');
696 if (sep)
697 {
698 *(sep++) = '\0';
699 conn->eap_type = atoi(kw->value);
700 conn->eap_vendor = atoi(sep);
701 if (conn->eap_type == 0 || conn->eap_vendor == 0)
702 {
703 plog("# invalid EAP type: %s=%s", kw->entry->name, kw->value);
704 cfg->err++;
705 }
706 break;
707 }
708 conn->eap_type = eap_type_from_string(kw->value);
709 if (conn->eap_type == 0)
710 {
711 conn->eap_type = atoi(kw->value);
712 if (conn->eap_type == 0)
713 {
714 plog("# unknown EAP type: %s=%s", kw->entry->name, kw->value);
715 cfg->err++;
716 }
717 }
718 break;
719 }
720 case KW_MARK:
721 if (!handle_mark(kw->value, &conn->mark_in))
722 {
723 cfg->err++;
724 break;
725 }
726 conn->mark_out = conn->mark_in;
727 break;
728 case KW_MARK_IN:
729 if (!handle_mark(kw->value, &conn->mark_in))
730 {
731 cfg->err++;
732 }
733 break;
734 case KW_MARK_OUT:
735 if (!handle_mark(kw->value, &conn->mark_out))
736 {
737 cfg->err++;
738 }
739 break;
740 case KW_TFC:
741 if (streq(kw->value, "%mtu"))
742 {
743 conn->tfc = -1;
744 }
745 else
746 {
747 char *endptr;
748
749 conn->tfc = strtoul(kw->value, &endptr, 10);
750 if (*endptr != '\0')
751 {
752 plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
753 cfg->err++;
754 }
755 }
756 break;
757 case KW_KEYINGTRIES:
758 if (streq(kw->value, "%forever"))
759 {
760 conn->sa_keying_tries = 0;
761 }
762 else
763 {
764 char *endptr;
765
766 conn->sa_keying_tries = strtoul(kw->value, &endptr, 10);
767 if (*endptr != '\0')
768 {
769 plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
770 cfg->err++;
771 }
772 }
773 break;
774 case KW_REKEY:
775 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY)
776 break;
777 case KW_REAUTH:
778 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REAUTH)
779 break;
780 case KW_MOBIKE:
781 KW_POLICY_FLAG("yes", "no", POLICY_MOBIKE)
782 break;
783 case KW_FORCEENCAPS:
784 KW_POLICY_FLAG("yes", "no", POLICY_FORCE_ENCAP)
785 break;
786 case KW_MODECONFIG:
787 KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH)
788 break;
789 case KW_XAUTH:
790 KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER)
791 break;
792 default:
793 break;
794 }
795 }
796
797 handle_dns_failure("left", &conn->left, cfg, conn);
798 handle_dns_failure("right", &conn->right, cfg, conn);
799 handle_firewall("left", &conn->left, cfg);
800 handle_firewall("right", &conn->right, cfg);
801 }
802
803 /*
804 * initialize a conn object with the default conn
805 */
806 static void conn_default(char *name, starter_conn_t *conn, starter_conn_t *def)
807 {
808 memcpy(conn, def, sizeof(starter_conn_t));
809 conn->name = clone_str(name);
810
811 clone_args(KW_CONN_FIRST, KW_CONN_LAST, (char *)conn, (char *)def);
812 clone_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left, (char *)&def->left);
813 clone_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right, (char *)&def->right);
814 }
815
816 /*
817 * parse a ca section
818 */
819 static void load_ca(starter_ca_t *ca, kw_list_t *kw, starter_config_t *cfg)
820 {
821 char *ca_name = (ca->name == NULL)? "%default":ca->name;
822
823 for ( ; kw; kw = kw->next)
824 {
825 bool assigned = FALSE;
826
827 kw_token_t token = kw->entry->token;
828
829 if (token == KW_AUTO)
830 {
831 token = KW_CA_SETUP;
832 }
833 else if (token == KW_ALSO)
834 {
835 if (cfg->parse_also)
836 {
837 also_t *also = malloc_thing(also_t);
838
839 also->name = clone_str(kw->value);
840 also->next = ca->also;
841 ca->also = also;
842
843 DBG(DBG_CONTROL,
844 DBG_log(" also=%s", kw->value)
845 )
846 }
847 continue;
848 }
849
850 if (token < KW_CA_FIRST || token > KW_CA_LAST)
851 {
852 plog("# unsupported keyword '%s' in ca '%s'", kw->entry->name, ca_name);
853 cfg->err++;
854 continue;
855 }
856
857 if (!assign_arg(token, KW_CA_FIRST, kw, (char *)ca, &assigned))
858 {
859 plog(" bad argument value in ca '%s'", ca_name);
860 cfg->err++;
861 }
862 }
863
864 /* treat 'route' and 'start' as 'add' */
865 if (ca->startup != STARTUP_NO)
866 ca->startup = STARTUP_ADD;
867 }
868
869 /*
870 * initialize a ca object with the default ca
871 */
872 static void ca_default(char *name, starter_ca_t *ca, starter_ca_t *def)
873 {
874 memcpy(ca, def, sizeof(starter_ca_t));
875 ca->name = clone_str(name);
876
877 clone_args(KW_CA_FIRST, KW_CA_LAST, (char *)ca, (char *)def);
878 }
879
880 static kw_list_t* find_also_conn(const char* name, starter_conn_t *conn,
881 starter_config_t *cfg);
882
883 static void load_also_conns(starter_conn_t *conn, also_t *also,
884 starter_config_t *cfg)
885 {
886 while (also != NULL)
887 {
888 kw_list_t *kw = find_also_conn(also->name, conn, cfg);
889
890 if (kw == NULL)
891 {
892 plog(" conn '%s' cannot include '%s'", conn->name, also->name);
893 }
894 else
895 {
896 DBG(DBG_CONTROL,
897 DBG_log("conn '%s' includes '%s'", conn->name, also->name)
898 )
899 /* only load if no error occurred in the first round */
900 if (cfg->err == 0)
901 load_conn(conn, kw, cfg);
902 }
903 also = also->next;
904 }
905 }
906
907 /*
908 * find a conn included by also
909 */
910 static kw_list_t* find_also_conn(const char* name, starter_conn_t *conn,
911 starter_config_t *cfg)
912 {
913 starter_conn_t *c = cfg->conn_first;
914
915 while (c != NULL)
916 {
917 if (streq(name, c->name))
918 {
919 if (conn->visit == c->visit)
920 {
921 plog("# detected also loop");
922 cfg->err++;
923 return NULL;
924 }
925 c->visit = conn->visit;
926 load_also_conns(conn, c->also, cfg);
927 return c->kw;
928 }
929 c = c->next;
930 }
931
932 plog("# also '%s' not found", name);
933 cfg->err++;
934 return NULL;
935 }
936
937 static kw_list_t* find_also_ca(const char* name, starter_ca_t *ca,
938 starter_config_t *cfg);
939
940 static void load_also_cas(starter_ca_t *ca, also_t *also, starter_config_t *cfg)
941 {
942 while (also != NULL)
943 {
944 kw_list_t *kw = find_also_ca(also->name, ca, cfg);
945
946 if (kw == NULL)
947 {
948 plog(" ca '%s' cannot include '%s'", ca->name, also->name);
949 }
950 else
951 {
952 DBG(DBG_CONTROL,
953 DBG_log("ca '%s' includes '%s'", ca->name, also->name)
954 )
955 /* only load if no error occurred in the first round */
956 if (cfg->err == 0)
957 load_ca(ca, kw, cfg);
958 }
959 also = also->next;
960 }
961 }
962
963 /*
964 * find a ca included by also
965 */
966 static kw_list_t* find_also_ca(const char* name, starter_ca_t *ca,
967 starter_config_t *cfg)
968 {
969 starter_ca_t *c = cfg->ca_first;
970
971 while (c != NULL)
972 {
973 if (streq(name, c->name))
974 {
975 if (ca->visit == c->visit)
976 {
977 plog("# detected also loop");
978 cfg->err++;
979 return NULL;
980 }
981 c->visit = ca->visit;
982 load_also_cas(ca, c->also, cfg);
983 return c->kw;
984 }
985 c = c->next;
986 }
987
988 plog("# also '%s' not found", name);
989 cfg->err++;
990 return NULL;
991 }
992
993 /*
994 * free the memory used by also_t objects
995 */
996 static void free_also(also_t *head)
997 {
998 while (head != NULL)
999 {
1000 also_t *also = head;
1001
1002 head = also->next;
1003 free(also->name);
1004 free(also);
1005 }
1006 }
1007
1008 /*
1009 * free the memory used by a starter_conn_t object
1010 */
1011 static void confread_free_conn(starter_conn_t *conn)
1012 {
1013 free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
1014 free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
1015 free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
1016 free_also(conn->also);
1017 }
1018
1019 /*
1020 * free the memory used by a starter_ca_t object
1021 */
1022 static void
1023 confread_free_ca(starter_ca_t *ca)
1024 {
1025 free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
1026 free_also(ca->also);
1027 }
1028
1029 /*
1030 * free the memory used by a starter_config_t object
1031 */
1032 void confread_free(starter_config_t *cfg)
1033 {
1034 starter_conn_t *conn = cfg->conn_first;
1035 starter_ca_t *ca = cfg->ca_first;
1036
1037 free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
1038
1039 confread_free_conn(&cfg->conn_default);
1040
1041 while (conn != NULL)
1042 {
1043 starter_conn_t *conn_aux = conn;
1044
1045 conn = conn->next;
1046 confread_free_conn(conn_aux);
1047 free(conn_aux);
1048 }
1049
1050 confread_free_ca(&cfg->ca_default);
1051
1052 while (ca != NULL)
1053 {
1054 starter_ca_t *ca_aux = ca;
1055
1056 ca = ca->next;
1057 confread_free_ca(ca_aux);
1058 free(ca_aux);
1059 }
1060
1061 free(cfg);
1062 }
1063
1064 /*
1065 * load and parse an IPsec configuration file
1066 */
1067 starter_config_t* confread_load(const char *file)
1068 {
1069 starter_config_t *cfg = NULL;
1070 config_parsed_t *cfgp;
1071 section_list_t *sconn, *sca;
1072 starter_conn_t *conn;
1073 starter_ca_t *ca;
1074
1075 u_int total_err;
1076 u_int visit = 0;
1077
1078 /* load IPSec configuration file */
1079 cfgp = parser_load_conf(file);
1080 if (!cfgp)
1081 {
1082 return NULL;
1083 }
1084 cfg = malloc_thing(starter_config_t);
1085
1086 /* set default values */
1087 default_values(cfg);
1088
1089 /* determine default route */
1090 get_defaultroute(&cfg->defaultroute);
1091
1092 /* load config setup section */
1093 load_setup(cfg, cfgp);
1094
1095 /* in the first round parse also statements */
1096 cfg->parse_also = TRUE;
1097
1098 /* find %default ca section */
1099 for (sca = cfgp->ca_first; sca; sca = sca->next)
1100 {
1101 if (streq(sca->name, "%default"))
1102 {
1103 DBG(DBG_CONTROL,
1104 DBG_log("Loading ca %%default")
1105 )
1106 load_ca(&cfg->ca_default, sca->kw, cfg);
1107 }
1108 }
1109
1110 /* parameters defined in ca %default sections can be overloads */
1111 cfg->ca_default.seen = LEMPTY;
1112
1113 /* load other ca sections */
1114 for (sca = cfgp->ca_first; sca; sca = sca->next)
1115 {
1116 u_int previous_err;
1117
1118 /* skip %default ca section */
1119 if (streq(sca->name, "%default"))
1120 continue;
1121
1122 DBG(DBG_CONTROL,
1123 DBG_log("Loading ca '%s'", sca->name)
1124 )
1125 ca = malloc_thing(starter_ca_t);
1126
1127 ca_default(sca->name, ca, &cfg->ca_default);
1128 ca->kw = sca->kw;
1129 ca->next = NULL;
1130
1131 previous_err = cfg->err;
1132 load_ca(ca, ca->kw, cfg);
1133 if (cfg->err > previous_err)
1134 {
1135 /* errors occurred - free the ca */
1136 confread_free_ca(ca);
1137 cfg->non_fatal_err += cfg->err - previous_err;
1138 cfg->err = previous_err;
1139 }
1140 else
1141 {
1142 /* success - insert the ca into the chained list */
1143 if (cfg->ca_last)
1144 cfg->ca_last->next = ca;
1145 cfg->ca_last = ca;
1146 if (!cfg->ca_first)
1147 cfg->ca_first = ca;
1148 }
1149 }
1150
1151 for (ca = cfg->ca_first; ca; ca = ca->next)
1152 {
1153 also_t *also = ca->also;
1154
1155 while (also != NULL)
1156 {
1157 kw_list_t *kw = find_also_ca(also->name, cfg->ca_first, cfg);
1158
1159 load_ca(ca, kw, cfg);
1160 also = also->next;
1161 }
1162
1163 if (ca->startup != STARTUP_NO)
1164 ca->state = STATE_TO_ADD;
1165 }
1166
1167 /* find %default conn sections */
1168 for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
1169 {
1170 if (streq(sconn->name, "%default"))
1171 {
1172 DBG(DBG_CONTROL,
1173 DBG_log("Loading conn %%default")
1174 )
1175 load_conn(&cfg->conn_default, sconn->kw, cfg);
1176 }
1177 }
1178
1179 /* parameter defined in conn %default sections can be overloaded */
1180 cfg->conn_default.seen = LEMPTY;
1181 cfg->conn_default.right.seen = LEMPTY;
1182 cfg->conn_default.left.seen = LEMPTY;
1183
1184 /* load other conn sections */
1185 for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
1186 {
1187 u_int previous_err;
1188
1189 /* skip %default conn section */
1190 if (streq(sconn->name, "%default"))
1191 continue;
1192
1193 DBG(DBG_CONTROL,
1194 DBG_log("Loading conn '%s'", sconn->name)
1195 )
1196 conn = malloc_thing(starter_conn_t);
1197
1198 conn_default(sconn->name, conn, &cfg->conn_default);
1199 conn->kw = sconn->kw;
1200 conn->next = NULL;
1201
1202 previous_err = cfg->err;
1203 load_conn(conn, conn->kw, cfg);
1204 if (cfg->err > previous_err)
1205 {
1206 /* error occurred - free the conn */
1207 confread_free_conn(conn);
1208 cfg->non_fatal_err += cfg->err - previous_err;
1209 cfg->err = previous_err;
1210 }
1211 else
1212 {
1213 /* success - insert the conn into the chained list */
1214 if (cfg->conn_last)
1215 cfg->conn_last->next = conn;
1216 cfg->conn_last = conn;
1217 if (!cfg->conn_first)
1218 cfg->conn_first = conn;
1219 }
1220 }
1221
1222 /* in the second round do not parse also statements */
1223 cfg->parse_also = FALSE;
1224
1225 for (ca = cfg->ca_first; ca; ca = ca->next)
1226 {
1227 ca->visit = ++visit;
1228 load_also_cas(ca, ca->also, cfg);
1229
1230 if (ca->startup != STARTUP_NO)
1231 ca->state = STATE_TO_ADD;
1232 }
1233
1234 for (conn = cfg->conn_first; conn; conn = conn->next)
1235 {
1236 conn->visit = ++visit;
1237 load_also_conns(conn, conn->also, cfg);
1238
1239 if (conn->startup != STARTUP_NO)
1240 conn->state = STATE_TO_ADD;
1241 }
1242
1243 parser_free_conf(cfgp);
1244
1245 total_err = cfg->err + cfg->non_fatal_err;
1246 if (total_err > 0)
1247 {
1248 plog("### %d parsing error%s (%d fatal) ###"
1249 , total_err, (total_err > 1)?"s":"", cfg->err);
1250 }
1251
1252 return cfg;
1253 }