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