1 /* strongSwan IPsec config file parser
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
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>.
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
15 #include <sys/types.h>
27 #include "../pluto/constants.h"
28 #include "../pluto/defs.h"
29 #include "../pluto/log.h"
36 #include "interfaces.h"
38 /* strings containing a colon are interpreted as an IPv6 address */
39 #define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
41 static const char ike_defaults
[] = "aes128-sha1-modp2048,3des-sha1-modp1536";
42 static const char esp_defaults
[] = "aes128-sha1,3des-sha1";
44 static const char firewall_defaults
[] = "ipsec _updown iptables";
46 static bool daemon_exists(char *daemon
, char *path
)
49 if (stat(path
, &st
) != 0)
51 plog("Disabling %sstart option, '%s' not found", daemon
, path
);
57 static void default_values(starter_config_t
*cfg
)
62 memset(cfg
, 0, sizeof(struct starter_config
));
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
);
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");
81 cfg
->setup
.charonstart
= TRUE
;
84 cfg
->setup
.plutostart
= TRUE
;
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
;
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 */
106 cfg
->conn_default
.left
.seen
= LEMPTY
;
107 cfg
->conn_default
.right
.seen
= LEMPTY
;
109 cfg
->conn_default
.left
.sendcert
= CERT_SEND_IF_ASKED
;
110 cfg
->conn_default
.right
.sendcert
= CERT_SEND_IF_ASKED
;
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;
119 cfg
->ca_default
.seen
= LEMPTY
;
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++; }
127 static void load_setup(starter_config_t
*cfg
, config_parsed_t
*cfgp
)
132 DBG_log("Loading config setup")
135 for (kw
= cfgp
->config_setup
; kw
; kw
= kw
->next
)
137 bool assigned
= FALSE
;
139 kw_token_t token
= kw
->entry
->token
;
141 if (token
< KW_SETUP_FIRST
|| token
> KW_SETUP_LAST
)
143 plog("# unsupported keyword '%s' in config setup", kw
->entry
->name
);
148 if (!assign_arg(token
, KW_SETUP_FIRST
, kw
, (char *)cfg
, &assigned
))
150 plog(" bad argument value in config setup");
156 /* verify the executables are actually available (some distros split
157 * packages but enabled both) */
159 cfg
->setup
.charonstart
= cfg
->setup
.charonstart
&&
160 daemon_exists("charon", CHARON_CMD
);
162 cfg
->setup
.charonstart
= FALSE
;
165 cfg
->setup
.plutostart
= cfg
->setup
.plutostart
&&
166 daemon_exists("pluto", PLUTO_CMD
);
168 cfg
->setup
.plutostart
= FALSE
;
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
)
176 bool assigned
= FALSE
;
177 bool has_port_wildcard
; /* set if port is %any */
179 char *name
= kw
->entry
->name
;
180 char *value
= kw
->value
;
182 if (!assign_arg(token
, KW_END_FIRST
, kw
, (char *)end
, &assigned
))
185 /* post processing of some keywords that were assigned automatically */
191 if (streq(value
, "%defaultroute"))
193 if (cfg
->defaultroute
.defined
)
195 end
->addr
= cfg
->defaultroute
.addr
;
196 end
->nexthop
= cfg
->defaultroute
.nexthop
;
198 else if (!cfg
->defaultroute
.supported
)
200 plog("%%defaultroute not supported, fallback to %%any");
204 plog("# default route not known: %s=%s", name
, value
);
208 else if (streq(value
, "%any") || streq(value
, "%any4"))
210 anyaddr(conn
->addr_family
, &end
->addr
);
212 else if (streq(value
, "%any6"))
214 conn
->addr_family
= AF_INET6
;
215 anyaddr(conn
->addr_family
, &end
->addr
);
217 else if (streq(value
, "%group"))
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
;
228 /* check for allow_any prefix */
231 end
->allow_any
= TRUE
;
234 conn
->addr_family
= ip_version(value
);
235 ugh
= ttoaddr(value
, 0, conn
->addr_family
, &end
->addr
);
238 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
239 if (streq(ugh
, "does not look numeric and name lookup failed"))
241 end
->dns_failed
= TRUE
;
242 anyaddr(conn
->addr_family
, &end
->addr
);
251 end
->host
= clone_str(value
);
256 if ((strlen(value
) >= 6 && strncmp(value
,"vhost:",6) == 0)
257 || (strlen(value
) >= 5 && strncmp(value
,"vnet:",5) == 0))
259 /* used by pluto only */
260 end
->has_virt
= TRUE
;
268 end
->has_client
= TRUE
;
269 conn
->tunnel_addr_family
= ip_version(value
);
271 pos
= strchr(value
, ',');
276 ugh
= ttosubnet(value
, len
, ip_version(value
), &net
);
279 plog("# bad subnet: %s=%s [%s]", name
, value
, ugh
);
287 plog("# natip and sourceip cannot be defined at the same time");
292 if (streq(value
, "%modeconfig") || streq(value
, "%modecfg") ||
293 streq(value
, "%config") || streq(value
, "%cfg"))
295 /* request ip via config payload */
297 end
->sourceip
= NULL
;
298 end
->sourceip_mask
= 1;
301 { /* %poolname, strip %, serve ip requests */
303 end
->sourceip
= clone_str(value
+1);
304 end
->sourceip_mask
= 0;
314 conn
->tunnel_addr_family
= ip_version(value
);
315 pos
= strchr(value
, '/');
318 { /* CIDR notation, address pool */
319 ugh
= ttosubnet(value
, 0, conn
->tunnel_addr_family
, &net
);
322 plog("# bad subnet: %s=%s [%s]", name
, value
, ugh
);
327 end
->sourceip
= clone_str(value
);
328 end
->sourceip_mask
= atoi(pos
+ 1);
332 ugh
= ttoaddr(value
, 0, conn
->tunnel_addr_family
, &addr
);
335 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
338 end
->sourceip_mask
= (conn
->tunnel_addr_family
== AF_INET
) ?
342 conn
->policy
|= POLICY_TUNNEL
;
345 if (end
->sendcert
== CERT_YES_SEND
)
347 end
->sendcert
= CERT_ALWAYS_SEND
;
349 else if (end
->sendcert
== CERT_NO_SEND
)
351 end
->sendcert
= CERT_NEVER_SEND
;
361 /* individual processing of keywords that were not assigned automatically */
365 if (streq(value
, "%defaultroute"))
367 if (cfg
->defaultroute
.defined
)
369 end
->nexthop
= cfg
->defaultroute
.nexthop
;
373 plog("# default route not known: %s=%s", name
, value
);
377 else if (streq(value
, "%direct"))
379 ugh
= anyaddr(conn
->addr_family
, &end
->nexthop
);
383 conn
->addr_family
= ip_version(value
);
384 ugh
= ttoaddr(value
, 0, conn
->addr_family
, &end
->nexthop
);
388 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
392 case KW_SUBNETWITHIN
:
396 end
->has_client
= TRUE
;
397 end
->has_client_wildcard
= TRUE
;
398 conn
->tunnel_addr_family
= ip_version(value
);
400 ugh
= ttosubnet(value
, 0, ip_version(value
), &net
);
403 plog("# bad subnet: %s=%s [%s]", name
, value
, ugh
);
406 end
->subnet
= clone_str(value
);
410 ugh
= ttoprotoport(value
, 0, &end
->protocol
, &end
->port
, &has_port_wildcard
);
411 end
->has_port_wildcard
= has_port_wildcard
;
416 plog("# natip and sourceip cannot be defined at the same time");
419 if (streq(value
, "%defaultroute"))
423 if (cfg
->defaultroute
.defined
)
425 addrtot(&cfg
->defaultroute
.addr
, 0, buf
, sizeof(buf
));
426 end
->sourceip
= clone_str(buf
);
430 plog("# default route not known: %s=%s", name
, value
);
438 conn
->tunnel_addr_family
= ip_version(value
);
439 ugh
= ttoaddr(value
, 0, conn
->tunnel_addr_family
, &addr
);
442 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
445 end
->sourceip
= clone_str(value
);
447 end
->has_natip
= TRUE
;
448 conn
->policy
|= POLICY_TUNNEL
;
456 plog(" bad argument value in conn '%s'", conn_name
);
461 * handles left|right=<FQDN> DNS resolution failure
463 static void handle_dns_failure(const char *label
, starter_end_t
*end
,
464 starter_config_t
*cfg
, starter_conn_t
*conn
)
470 plog("# fallback to %s=%%any due to '%%' prefix or %sallowany=yes",
473 else if (!end
->host
|| conn
->keyexchange
!= KEY_EXCHANGE_IKEV2
)
475 /* declare an error */
482 * handles left|rightfirewall and left|rightupdown parameters
484 static void handle_firewall(const char *label
, starter_end_t
*end
,
485 starter_config_t
*cfg
)
487 if (end
->firewall
&& (end
->seen
& LELEM(KW_FIREWALL
- KW_END_FIRST
)))
489 if (end
->updown
!= NULL
)
491 plog("# cannot have both %sfirewall and %supdown", label
, label
);
496 end
->updown
= clone_str(firewall_defaults
);
497 end
->firewall
= FALSE
;
502 static bool handle_mark(char *value
, mark_t
*mark
)
506 pos
= strchr(value
, '/');
510 mark
->mask
= strtoul(pos
+1, &endptr
, 0);
513 plog("# invalid mark mask: %s", pos
+1);
519 mark
->mask
= 0xffffffff;
527 mark
->value
= strtoul(value
, &endptr
, 0);
530 plog("# invalid mark value: %s", value
);
538 * parse a conn section
540 static void load_conn(starter_conn_t
*conn
, kw_list_t
*kw
, starter_config_t
*cfg
)
542 char *conn_name
= (conn
->name
== NULL
)?
"%default":conn
->name
;
544 for ( ; kw
; kw
= kw
->next
)
546 bool assigned
= FALSE
;
548 kw_token_t token
= kw
->entry
->token
;
550 if (token
>= KW_LEFT_FIRST
&& token
<= KW_LEFT_LAST
)
552 kw_end(conn
, &conn
->left
, token
- KW_LEFT_FIRST
+ KW_END_FIRST
553 , kw
, conn_name
, cfg
);
556 else if (token
>= KW_RIGHT_FIRST
&& token
<= KW_RIGHT_LAST
)
558 kw_end(conn
, &conn
->right
, token
- KW_RIGHT_FIRST
+ KW_END_FIRST
559 , kw
, conn_name
, cfg
);
563 if (token
== KW_AUTO
)
565 token
= KW_CONN_SETUP
;
567 else if (token
== KW_ALSO
)
571 also_t
*also
= malloc_thing(also_t
);
573 also
->name
= clone_str(kw
->value
);
574 also
->next
= conn
->also
;
578 DBG_log(" also=%s", kw
->value
)
584 if (token
< KW_CONN_FIRST
|| token
> KW_CONN_LAST
)
586 plog("# unsupported keyword '%s' in conn '%s'"
587 , kw
->entry
->name
, conn_name
);
592 if (!assign_arg(token
, KW_CONN_FIRST
, kw
, (char *)conn
, &assigned
))
594 plog(" bad argument value in conn '%s'", conn_name
);
605 conn
->policy
&= ~(POLICY_TUNNEL
| POLICY_SHUNT_MASK
);
606 if (streq(kw
->value
, "tunnel"))
608 conn
->policy
|= POLICY_TUNNEL
;
610 else if (streq(kw
->value
, "beet"))
612 conn
->policy
|= POLICY_BEET
;
614 else if (streq(kw
->value
, "transport_proxy"))
616 conn
->policy
|= POLICY_PROXY
;
618 else if (streq(kw
->value
, "passthrough") || streq(kw
->value
, "pass"))
620 conn
->policy
|= POLICY_SHUNT_PASS
;
622 else if (streq(kw
->value
, "drop"))
624 conn
->policy
|= POLICY_SHUNT_DROP
;
626 else if (streq(kw
->value
, "reject"))
628 conn
->policy
|= POLICY_SHUNT_REJECT
;
630 else if (strcmp(kw
->value
, "transport") != 0)
632 plog("# bad policy value: %s=%s", kw
->entry
->name
, kw
->value
);
637 KW_POLICY_FLAG("yes", "no", POLICY_PFS
)
640 KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS
)
643 KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE
)
646 conn
->policy
&= ~(POLICY_ID_AUTH_MASK
| POLICY_ENCRYPT
);
648 if (!streq(kw
->value
, "never"))
650 char *value
= kw
->value
;
651 char *second
= strchr(kw
->value
, '|');
658 /* also handles the cases secret|rsasig and rsasig|secret */
661 if (streq(value
, "rsa") || streq(value
, "rsasig") ||
662 streq(value
, "ecdsa") || streq(value
, "ecdsasig") ||
663 streq(value
, "pubkey"))
665 conn
->policy
|= POLICY_PUBKEY
| POLICY_ENCRYPT
;
667 else if (streq(value
, "secret") || streq(value
, "psk"))
669 conn
->policy
|= POLICY_PSK
| POLICY_ENCRYPT
;
671 else if (streq(value
, "xauthrsasig"))
673 conn
->policy
|= POLICY_XAUTH_RSASIG
| POLICY_ENCRYPT
;
675 else if (streq(value
, "xauthpsk") || streq(value
, "eap"))
677 conn
->policy
|= POLICY_XAUTH_PSK
| POLICY_ENCRYPT
;
681 plog("# bad policy value: %s=%s", kw
->entry
->name
, kw
->value
);
690 second
= NULL
; /* traverse the loop no more than twice */
698 /* check for vendor-type format */
699 sep
= strchr(kw
->value
, '-');
703 conn
->eap_type
= atoi(kw
->value
);
704 conn
->eap_vendor
= atoi(sep
);
705 if (conn
->eap_type
== 0 || conn
->eap_vendor
== 0)
707 plog("# invalid EAP type: %s=%s", kw
->entry
->name
, kw
->value
);
712 conn
->eap_type
= eap_type_from_string(kw
->value
);
713 if (conn
->eap_type
== 0)
715 conn
->eap_type
= atoi(kw
->value
);
716 if (conn
->eap_type
== 0)
718 plog("# unknown EAP type: %s=%s", kw
->entry
->name
, kw
->value
);
725 if (!handle_mark(kw
->value
, &conn
->mark_in
))
730 conn
->mark_out
= conn
->mark_in
;
733 if (!handle_mark(kw
->value
, &conn
->mark_in
))
739 if (!handle_mark(kw
->value
, &conn
->mark_out
))
745 if (streq(kw
->value
, "%mtu"))
753 conn
->tfc
= strtoul(kw
->value
, &endptr
, 10);
756 plog("# bad integer value: %s=%s", kw
->entry
->name
, kw
->value
);
762 if (streq(kw
->value
, "%forever"))
764 conn
->sa_keying_tries
= 0;
770 conn
->sa_keying_tries
= strtoul(kw
->value
, &endptr
, 10);
773 plog("# bad integer value: %s=%s", kw
->entry
->name
, kw
->value
);
779 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY
)
782 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REAUTH
)
785 KW_POLICY_FLAG("yes", "no", POLICY_MOBIKE
)
788 KW_POLICY_FLAG("yes", "no", POLICY_FORCE_ENCAP
)
791 KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH
)
794 KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER
)
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
);
808 * initialize a conn object with the default conn
810 static void conn_default(char *name
, starter_conn_t
*conn
, starter_conn_t
*def
)
812 memcpy(conn
, def
, sizeof(starter_conn_t
));
813 conn
->name
= clone_str(name
);
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
);
823 static void load_ca(starter_ca_t
*ca
, kw_list_t
*kw
, starter_config_t
*cfg
)
825 char *ca_name
= (ca
->name
== NULL
)?
"%default":ca
->name
;
827 for ( ; kw
; kw
= kw
->next
)
829 bool assigned
= FALSE
;
831 kw_token_t token
= kw
->entry
->token
;
833 if (token
== KW_AUTO
)
837 else if (token
== KW_ALSO
)
841 also_t
*also
= malloc_thing(also_t
);
843 also
->name
= clone_str(kw
->value
);
844 also
->next
= ca
->also
;
848 DBG_log(" also=%s", kw
->value
)
854 if (token
< KW_CA_FIRST
|| token
> KW_CA_LAST
)
856 plog("# unsupported keyword '%s' in ca '%s'", kw
->entry
->name
, ca_name
);
861 if (!assign_arg(token
, KW_CA_FIRST
, kw
, (char *)ca
, &assigned
))
863 plog(" bad argument value in ca '%s'", ca_name
);
868 /* treat 'route' and 'start' as 'add' */
869 if (ca
->startup
!= STARTUP_NO
)
870 ca
->startup
= STARTUP_ADD
;
874 * initialize a ca object with the default ca
876 static void ca_default(char *name
, starter_ca_t
*ca
, starter_ca_t
*def
)
878 memcpy(ca
, def
, sizeof(starter_ca_t
));
879 ca
->name
= clone_str(name
);
881 clone_args(KW_CA_FIRST
, KW_CA_LAST
, (char *)ca
, (char *)def
);
884 static kw_list_t
* find_also_conn(const char* name
, starter_conn_t
*conn
,
885 starter_config_t
*cfg
);
887 static void load_also_conns(starter_conn_t
*conn
, also_t
*also
,
888 starter_config_t
*cfg
)
892 kw_list_t
*kw
= find_also_conn(also
->name
, conn
, cfg
);
896 plog(" conn '%s' cannot include '%s'", conn
->name
, also
->name
);
901 DBG_log("conn '%s' includes '%s'", conn
->name
, also
->name
)
903 /* only load if no error occurred in the first round */
905 load_conn(conn
, kw
, cfg
);
912 * find a conn included by also
914 static kw_list_t
* find_also_conn(const char* name
, starter_conn_t
*conn
,
915 starter_config_t
*cfg
)
917 starter_conn_t
*c
= cfg
->conn_first
;
921 if (streq(name
, c
->name
))
923 if (conn
->visit
== c
->visit
)
925 plog("# detected also loop");
929 c
->visit
= conn
->visit
;
930 load_also_conns(conn
, c
->also
, cfg
);
936 plog("# also '%s' not found", name
);
941 static kw_list_t
* find_also_ca(const char* name
, starter_ca_t
*ca
,
942 starter_config_t
*cfg
);
944 static void load_also_cas(starter_ca_t
*ca
, also_t
*also
, starter_config_t
*cfg
)
948 kw_list_t
*kw
= find_also_ca(also
->name
, ca
, cfg
);
952 plog(" ca '%s' cannot include '%s'", ca
->name
, also
->name
);
957 DBG_log("ca '%s' includes '%s'", ca
->name
, also
->name
)
959 /* only load if no error occurred in the first round */
961 load_ca(ca
, kw
, cfg
);
968 * find a ca included by also
970 static kw_list_t
* find_also_ca(const char* name
, starter_ca_t
*ca
,
971 starter_config_t
*cfg
)
973 starter_ca_t
*c
= cfg
->ca_first
;
977 if (streq(name
, c
->name
))
979 if (ca
->visit
== c
->visit
)
981 plog("# detected also loop");
985 c
->visit
= ca
->visit
;
986 load_also_cas(ca
, c
->also
, cfg
);
992 plog("# also '%s' not found", name
);
998 * free the memory used by also_t objects
1000 static void free_also(also_t
*head
)
1002 while (head
!= NULL
)
1004 also_t
*also
= head
;
1013 * free the memory used by a starter_conn_t object
1015 static void confread_free_conn(starter_conn_t
*conn
)
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
);
1024 * free the memory used by a starter_ca_t object
1027 confread_free_ca(starter_ca_t
*ca
)
1029 free_args(KW_CA_NAME
, KW_CA_LAST
, (char *)ca
);
1030 free_also(ca
->also
);
1034 * free the memory used by a starter_config_t object
1036 void confread_free(starter_config_t
*cfg
)
1038 starter_conn_t
*conn
= cfg
->conn_first
;
1039 starter_ca_t
*ca
= cfg
->ca_first
;
1041 free_args(KW_SETUP_FIRST
, KW_SETUP_LAST
, (char *)cfg
);
1043 confread_free_conn(&cfg
->conn_default
);
1045 while (conn
!= NULL
)
1047 starter_conn_t
*conn_aux
= conn
;
1050 confread_free_conn(conn_aux
);
1054 confread_free_ca(&cfg
->ca_default
);
1058 starter_ca_t
*ca_aux
= ca
;
1061 confread_free_ca(ca_aux
);
1069 * load and parse an IPsec configuration file
1071 starter_config_t
* confread_load(const char *file
)
1073 starter_config_t
*cfg
= NULL
;
1074 config_parsed_t
*cfgp
;
1075 section_list_t
*sconn
, *sca
;
1076 starter_conn_t
*conn
;
1082 /* load IPSec configuration file */
1083 cfgp
= parser_load_conf(file
);
1088 cfg
= malloc_thing(starter_config_t
);
1090 /* set default values */
1091 default_values(cfg
);
1093 /* determine default route */
1094 get_defaultroute(&cfg
->defaultroute
);
1096 /* load config setup section */
1097 load_setup(cfg
, cfgp
);
1099 /* in the first round parse also statements */
1100 cfg
->parse_also
= TRUE
;
1102 /* find %default ca section */
1103 for (sca
= cfgp
->ca_first
; sca
; sca
= sca
->next
)
1105 if (streq(sca
->name
, "%default"))
1108 DBG_log("Loading ca %%default")
1110 load_ca(&cfg
->ca_default
, sca
->kw
, cfg
);
1114 /* parameters defined in ca %default sections can be overloads */
1115 cfg
->ca_default
.seen
= LEMPTY
;
1117 /* load other ca sections */
1118 for (sca
= cfgp
->ca_first
; sca
; sca
= sca
->next
)
1122 /* skip %default ca section */
1123 if (streq(sca
->name
, "%default"))
1127 DBG_log("Loading ca '%s'", sca
->name
)
1129 ca
= malloc_thing(starter_ca_t
);
1131 ca_default(sca
->name
, ca
, &cfg
->ca_default
);
1135 previous_err
= cfg
->err
;
1136 load_ca(ca
, ca
->kw
, cfg
);
1137 if (cfg
->err
> previous_err
)
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
;
1146 /* success - insert the ca into the chained list */
1148 cfg
->ca_last
->next
= ca
;
1155 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
1157 also_t
*also
= ca
->also
;
1159 while (also
!= NULL
)
1161 kw_list_t
*kw
= find_also_ca(also
->name
, cfg
->ca_first
, cfg
);
1163 load_ca(ca
, kw
, cfg
);
1167 if (ca
->startup
!= STARTUP_NO
)
1168 ca
->state
= STATE_TO_ADD
;
1171 /* find %default conn sections */
1172 for (sconn
= cfgp
->conn_first
; sconn
; sconn
= sconn
->next
)
1174 if (streq(sconn
->name
, "%default"))
1177 DBG_log("Loading conn %%default")
1179 load_conn(&cfg
->conn_default
, sconn
->kw
, cfg
);
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
;
1188 /* load other conn sections */
1189 for (sconn
= cfgp
->conn_first
; sconn
; sconn
= sconn
->next
)
1193 /* skip %default conn section */
1194 if (streq(sconn
->name
, "%default"))
1198 DBG_log("Loading conn '%s'", sconn
->name
)
1200 conn
= malloc_thing(starter_conn_t
);
1202 conn_default(sconn
->name
, conn
, &cfg
->conn_default
);
1203 conn
->kw
= sconn
->kw
;
1206 previous_err
= cfg
->err
;
1207 load_conn(conn
, conn
->kw
, cfg
);
1208 if (cfg
->err
> previous_err
)
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
;
1217 /* success - insert the conn into the chained list */
1219 cfg
->conn_last
->next
= conn
;
1220 cfg
->conn_last
= conn
;
1221 if (!cfg
->conn_first
)
1222 cfg
->conn_first
= conn
;
1226 /* in the second round do not parse also statements */
1227 cfg
->parse_also
= FALSE
;
1229 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
1231 ca
->visit
= ++visit
;
1232 load_also_cas(ca
, ca
->also
, cfg
);
1234 if (ca
->startup
!= STARTUP_NO
)
1235 ca
->state
= STATE_TO_ADD
;
1238 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
1240 conn
->visit
= ++visit
;
1241 load_also_conns(conn
, conn
->also
, cfg
);
1243 if (conn
->startup
!= STARTUP_NO
)
1244 conn
->state
= STATE_TO_ADD
;
1247 parser_free_conf(cfgp
);
1249 total_err
= cfg
->err
+ cfg
->non_fatal_err
;
1252 plog("### %d parsing error%s (%d fatal) ###"
1253 , total_err
, (total_err
> 1)?
"s":"", cfg
->err
);