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
14 * RCSID $Id: confread.c,v 1.37 2006/04/17 19:35:07 as Exp $
24 #include "../pluto/constants.h"
25 #include "../pluto/defs.h"
26 #include "../pluto/log.h"
32 #include "interfaces.h"
34 static const char ike_defaults
[] = "3des-sha, 3des-md5";
35 static const char esp_defaults
[] = "3des-sha1, 3des-md5";
37 static const char firewall_defaults
[] = "ipsec _updown iptables";
40 default_values(starter_config_t
*cfg
)
45 memset(cfg
, 0, sizeof(struct starter_config
));
47 /* is there enough space for all seen flags? */
48 assert(KW_SETUP_LAST
- KW_SETUP_FIRST
<
49 sizeof(cfg
->setup
.seen
) * BITS_PER_BYTE
);
50 assert(KW_CONN_LAST
- KW_CONN_FIRST
<
51 sizeof(cfg
->conn_default
.seen
) * BITS_PER_BYTE
);
52 assert(KW_END_LAST
- KW_END_FIRST
<
53 sizeof(cfg
->conn_default
.right
.seen
) * BITS_PER_BYTE
);
54 assert(KW_CA_LAST
- KW_CA_FIRST
<
55 sizeof(cfg
->ca_default
.seen
) * BITS_PER_BYTE
);
57 cfg
->setup
.seen
= LEMPTY
;
58 cfg
->setup
.fragicmp
= TRUE
;
59 cfg
->setup
.hidetos
= TRUE
;
60 cfg
->setup
.uniqueids
= TRUE
;
61 cfg
->setup
.interfaces
= new_list("%defaultroute");
63 cfg
->conn_default
.seen
= LEMPTY
;
64 cfg
->conn_default
.startup
= STARTUP_NO
;
65 cfg
->conn_default
.state
= STATE_IGNORE
;
66 cfg
->conn_default
.policy
= POLICY_ENCRYPT
| POLICY_TUNNEL
| POLICY_RSASIG
69 cfg
->conn_default
.ike
= clone_str(ike_defaults
, "ike_defaults");
70 cfg
->conn_default
.esp
= clone_str(esp_defaults
, "esp_defaults");
71 cfg
->conn_default
.sa_ike_life_seconds
= OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT
;
72 cfg
->conn_default
.sa_ipsec_life_seconds
= PLUTO_SA_LIFE_DURATION_DEFAULT
;
73 cfg
->conn_default
.sa_rekey_margin
= SA_REPLACEMENT_MARGIN_DEFAULT
;
74 cfg
->conn_default
.sa_rekey_fuzz
= SA_REPLACEMENT_FUZZ_DEFAULT
;
75 cfg
->conn_default
.sa_keying_tries
= SA_REPLACEMENT_RETRIES_DEFAULT
;
76 cfg
->conn_default
.addr_family
= AF_INET
;
77 cfg
->conn_default
.tunnel_addr_family
= AF_INET
;
79 cfg
->conn_default
.left
.seen
= LEMPTY
;
80 cfg
->conn_default
.right
.seen
= LEMPTY
;
82 anyaddr(AF_INET
, &cfg
->conn_default
.left
.addr
);
83 anyaddr(AF_INET
, &cfg
->conn_default
.left
.nexthop
);
84 anyaddr(AF_INET
, &cfg
->conn_default
.left
.srcip
);
85 anyaddr(AF_INET
, &cfg
->conn_default
.right
.addr
);
86 anyaddr(AF_INET
, &cfg
->conn_default
.right
.nexthop
);
87 anyaddr(AF_INET
, &cfg
->conn_default
.right
.srcip
);
89 cfg
->ca_default
.seen
= LEMPTY
;
92 #define KW_POLICY_FLAG(sy, sn, fl) \
93 if (streq(kw->value, sy)) { conn->policy |= fl; } \
94 else if (streq(kw->value, sn)) { conn->policy &= ~fl; } \
95 else { plog("# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; }
98 load_setup(starter_config_t
*cfg
, config_parsed_t
*cfgp
)
103 DBG_log("Loading config setup")
106 for (kw
= cfgp
->config_setup
; kw
; kw
= kw
->next
)
108 bool assigned
= FALSE
;
110 kw_token_t token
= kw
->entry
->token
;
112 if (token
< KW_SETUP_FIRST
|| token
> KW_SETUP_LAST
)
114 plog("# unsupported keyword '%s' in config setup", kw
->entry
->name
);
119 if (!assign_arg(token
, KW_SETUP_FIRST
, kw
, (char *)cfg
, &assigned
))
121 plog(" bad argument value in config setup");
129 kw_end(starter_conn_t
*conn
, starter_end_t
*end
, kw_token_t token
130 , kw_list_t
*kw
, char *conn_name
, starter_config_t
*cfg
)
133 bool assigned
= FALSE
;
134 int has_port_wildcard
; /* set if port is %any */
136 char *name
= kw
->entry
->name
;
137 char *value
= kw
->value
;
139 if (!assign_arg(token
, KW_END_FIRST
, kw
, (char *)end
, &assigned
))
142 if (token
== KW_SENDCERT
)
144 if (end
->sendcert
== CERT_YES_SEND
)
145 end
->sendcert
= CERT_ALWAYS_SEND
;
146 else if (end
->sendcert
== CERT_NO_SEND
)
147 end
->sendcert
= CERT_NEVER_SEND
;
156 if (streq(value
, "%defaultroute"))
158 if (cfg
->defaultroute
.defined
)
160 end
->addr
= cfg
->defaultroute
.addr
;
161 end
->nexthop
= cfg
->defaultroute
.nexthop
;
165 plog("# default route not known: %s=%s", name
, value
);
169 else if (streq(value
,"%any"))
171 anyaddr(conn
->addr_family
, &end
->addr
);
173 else if (value
[0] == '%')
177 end
->iface
= clone_str(value
+1, "iface");
178 if (starter_iface_find(end
->iface
, conn
->addr_family
, &end
->addr
,
179 &end
->nexthop
) == -1)
181 conn
->state
= STATE_INVALID
;
186 ugh
= ttoaddr(value
, 0, conn
->addr_family
, &end
->addr
);
189 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
195 if (streq(value
, "%defaultroute"))
197 if (cfg
->defaultroute
.defined
)
198 end
->nexthop
= cfg
->defaultroute
.nexthop
;
201 plog("# default route not known: %s=%s", name
, value
);
205 else if (streq(value
, "%direct"))
206 ugh
= anyaddr(conn
->addr_family
, &end
->nexthop
);
208 ugh
= ttoaddr(value
, 0, conn
->addr_family
, &end
->nexthop
);
212 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
217 if ((strlen(value
) >= 6 && strncmp(value
,"vhost:",6) == 0)
218 || (strlen(value
) >= 5 && strncmp(value
,"vnet:",5) == 0))
220 end
->virt
= clone_str(value
, "virt");
224 end
->has_client
= TRUE
;
225 ugh
= ttosubnet(value
, 0, conn
->tunnel_addr_family
, &end
->subnet
);
228 plog("# bad subnet: %s=%s [%s]", name
, value
, ugh
);
233 case KW_SUBNETWITHIN
:
234 end
->has_client
= TRUE
;
235 end
->has_client_wildcard
= TRUE
;
236 ugh
= ttosubnet(value
, 0, conn
->tunnel_addr_family
, &end
->subnet
);
239 ugh
= ttoprotoport(value
, 0, &end
->protocol
, &end
->port
, &has_port_wildcard
);
240 end
->has_port_wildcard
= has_port_wildcard
;
243 if (streq(value
, "%modeconfig") || streq(value
, "%modecfg"))
249 ugh
= ttoaddr(value
, 0, conn
->addr_family
, &end
->srcip
);
252 plog("# bad addr: %s=%s [%s]", name
, value
, ugh
);
255 end
->has_srcip
= TRUE
;
257 conn
->policy
|= POLICY_TUNNEL
;
265 plog(" bad argument value in conn '%s'", conn_name
);
270 * handles left|rightfirewall and left|rightupdown parameters
273 handle_firewall( const char *label
, starter_end_t
*end
, starter_config_t
*cfg
)
275 if (end
->firewall
&& (end
->seen
& LELEM(KW_FIREWALL
- KW_END_FIRST
)))
277 if (end
->updown
!= NULL
)
279 plog("# cannot have both %sfirewall and %supdown", label
, label
);
284 end
->updown
= clone_str(firewall_defaults
, "firewall_defaults");
285 end
->firewall
= FALSE
;
291 * parse a conn section
294 load_conn(starter_conn_t
*conn
, kw_list_t
*kw
, starter_config_t
*cfg
)
296 char *conn_name
= (conn
->name
== NULL
)? "%default":conn
->name
;
298 for ( ; kw
; kw
= kw
->next
)
300 bool assigned
= FALSE
;
302 kw_token_t token
= kw
->entry
->token
;
304 if (token
>= KW_LEFT_FIRST
&& token
<= KW_LEFT_LAST
)
306 kw_end(conn
, &conn
->left
, token
- KW_LEFT_FIRST
+ KW_END_FIRST
307 , kw
, conn_name
, cfg
);
310 else if (token
>= KW_RIGHT_FIRST
&& token
<= KW_RIGHT_LAST
)
312 kw_end(conn
, &conn
->right
, token
- KW_RIGHT_FIRST
+ KW_END_FIRST
313 , kw
, conn_name
, cfg
);
317 if (token
== KW_AUTO
)
319 token
= KW_CONN_SETUP
;
321 else if (token
== KW_ALSO
)
325 also_t
*also
= alloc_thing(also_t
, "also_t");
327 also
->name
= clone_str(kw
->value
, "also");
328 also
->next
= conn
->also
;
332 DBG_log(" also=%s", kw
->value
)
338 if (token
< KW_CONN_FIRST
|| token
> KW_CONN_LAST
)
340 plog("# unsupported keyword '%s' in conn '%s'"
341 , kw
->entry
->name
, conn_name
);
346 if (!assign_arg(token
, KW_CONN_FIRST
, kw
, (char *)conn
, &assigned
))
348 plog(" bad argument value in conn '%s'", conn_name
);
359 conn
->policy
&= ~(POLICY_TUNNEL
| POLICY_SHUNT_MASK
);
360 if (streq(kw
->value
, "tunnel"))
361 conn
->policy
|= POLICY_TUNNEL
;
362 else if (streq(kw
->value
, "passthrough") || streq(kw
->value
, "pass"))
363 conn
->policy
|= POLICY_SHUNT_PASS
;
364 else if (streq(kw
->value
, "drop"))
365 conn
->policy
|= POLICY_SHUNT_DROP
;
366 else if (streq(kw
->value
, "reject"))
367 conn
->policy
|= POLICY_SHUNT_REJECT
;
368 else if (strcmp(kw
->value
, "transport") != 0)
370 plog("# bad policy value: %s=%s", kw
->entry
->name
, kw
->value
);
375 KW_POLICY_FLAG("yes", "no", POLICY_PFS
)
378 KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS
)
381 KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE
)
384 conn
->policy
&= ~(POLICY_RSASIG
| POLICY_PSK
| POLICY_ENCRYPT
);
386 if (strcmp(kw
->value
, "never") != 0)
388 char *value
= kw
->value
;
389 char *second
= strchr(kw
->value
, '|');
394 /* also handles the cases secret|rsasig and rsasig|secret */
397 if (streq(value
, "rsasig"))
398 conn
->policy
|= POLICY_RSASIG
| POLICY_ENCRYPT
;
399 else if (streq(value
, "secret"))
400 conn
->policy
|= POLICY_PSK
| POLICY_ENCRYPT
;
403 plog("# bad policy value: %s=%s", kw
->entry
->name
, kw
->value
);
410 second
= NULL
; /* traverse the loop no more than twice */
415 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY
)
421 handle_firewall("left", &conn
->left
, cfg
);
422 handle_firewall("right", &conn
->right
, cfg
);
426 * initialize a conn object with the default conn
429 conn_default(char *name
, starter_conn_t
*conn
, starter_conn_t
*def
)
431 memcpy(conn
, def
, sizeof(starter_conn_t
));
432 conn
->name
= clone_str(name
, "conn name");
434 clone_args(KW_CONN_FIRST
, KW_CONN_LAST
435 , (char *)conn
, (char *)def
);
436 clone_args(KW_END_FIRST
, KW_END_LAST
437 , (char *)&conn
->left
, (char *)&def
->left
);
438 clone_args(KW_END_FIRST
, KW_END_LAST
439 , (char *)&conn
->right
, (char *)&def
->right
);
446 load_ca(starter_ca_t
*ca
, kw_list_t
*kw
, starter_config_t
*cfg
)
448 char *ca_name
= (ca
->name
== NULL
)? "%default":ca
->name
;
450 for ( ; kw
; kw
= kw
->next
)
452 bool assigned
= FALSE
;
454 kw_token_t token
= kw
->entry
->token
;
456 if (token
== KW_AUTO
)
460 else if (token
== KW_ALSO
)
464 also_t
*also
= alloc_thing(also_t
, "also_t");
466 also
->name
= clone_str(kw
->value
, "also");
467 also
->next
= ca
->also
;
471 DBG_log(" also=%s", kw
->value
)
477 if (token
< KW_CA_FIRST
|| token
> KW_CA_LAST
)
479 plog("# unsupported keyword '%s' in ca '%s'"
480 , kw
->entry
->name
, ca_name
);
485 if (!assign_arg(token
, KW_CA_FIRST
, kw
, (char *)ca
, &assigned
))
487 plog(" bad argument value in ca '%s'", ca_name
);
492 /* treat 'route' and 'start' as 'add' */
493 if (ca
->startup
!= STARTUP_NO
)
494 ca
->startup
= STARTUP_ADD
;
498 * initialize a ca object with the default ca
501 ca_default(char *name
, starter_ca_t
*ca
, starter_ca_t
*def
)
503 memcpy(ca
, def
, sizeof(starter_ca_t
));
504 ca
->name
= clone_str(name
, "ca name");
506 clone_args(KW_CA_FIRST
, KW_CA_LAST
, (char *)ca
, (char *)def
);
510 find_also_conn(const char* name
, starter_conn_t
*conn
, starter_config_t
*cfg
);
513 load_also_conns(starter_conn_t
*conn
, also_t
*also
, starter_config_t
*cfg
)
517 kw_list_t
*kw
= find_also_conn(also
->name
, conn
, cfg
);
521 plog(" conn '%s' cannot include '%s'", conn
->name
, also
->name
);
526 DBG_log("conn '%s' includes '%s'", conn
->name
, also
->name
)
528 /* only load if no error occurred in the first round */
530 load_conn(conn
, kw
, cfg
);
537 * find a conn included by also
540 find_also_conn(const char* name
, starter_conn_t
*conn
, starter_config_t
*cfg
)
542 starter_conn_t
*c
= cfg
->conn_first
;
546 if (streq(name
, c
->name
))
548 if (conn
->visit
== c
->visit
)
550 plog("# detected also loop");
554 c
->visit
= conn
->visit
;
555 load_also_conns(conn
, c
->also
, cfg
);
561 plog("# also '%s' not found", name
);
567 find_also_ca(const char* name
, starter_ca_t
*ca
, starter_config_t
*cfg
);
570 load_also_cas(starter_ca_t
*ca
, also_t
*also
, starter_config_t
*cfg
)
574 kw_list_t
*kw
= find_also_ca(also
->name
, ca
, cfg
);
578 plog(" ca '%s' cannot include '%s'", ca
->name
, also
->name
);
583 DBG_log("ca '%s' includes '%s'", ca
->name
, also
->name
)
585 /* only load if no error occurred in the first round */
587 load_ca(ca
, kw
, cfg
);
594 * find a ca included by also
597 find_also_ca(const char* name
, starter_ca_t
*ca
, starter_config_t
*cfg
)
599 starter_ca_t
*c
= cfg
->ca_first
;
603 if (streq(name
, c
->name
))
605 if (ca
->visit
== c
->visit
)
607 plog("# detected also loop");
611 c
->visit
= ca
->visit
;
612 load_also_cas(ca
, c
->also
, cfg
);
618 plog("# also '%s' not found", name
);
626 * load and parse an IPsec configuration file
629 confread_load(const char *file
)
631 starter_config_t
*cfg
= NULL
;
632 config_parsed_t
*cfgp
;
633 section_list_t
*sconn
, *sca
;
634 starter_conn_t
*conn
;
639 /* load IPSec configuration file */
640 cfgp
= parser_load_conf(file
);
644 cfg
= (starter_config_t
*)alloc_thing(starter_config_t
, "starter_config_t");
646 /* set default values */
649 /* determine default route */
650 get_defaultroute(&cfg
->defaultroute
);
652 /* load config setup section */
653 load_setup(cfg
, cfgp
);
655 /* in the first round parse also statements */
656 cfg
->parse_also
= TRUE
;
658 /* find %default ca section */
659 for (sca
= cfgp
->ca_first
; sca
; sca
= sca
->next
)
661 if (streq(sca
->name
, "%default"))
664 DBG_log("Loading ca %%default")
666 load_ca(&cfg
->ca_default
, sca
->kw
, cfg
);
670 /* parameters defined in ca %default sections can be overloads */
671 cfg
->ca_default
.seen
= LEMPTY
;
673 /* load other ca sections */
674 for (sca
= cfgp
->ca_first
; sca
; sca
= sca
->next
)
676 /* skip %default ca section */
677 if (streq(sca
->name
, "%default"))
681 DBG_log("Loading ca '%s'", sca
->name
)
683 ca
= (starter_ca_t
*)alloc_thing(starter_ca_t
, "starter_ca_t");
685 ca_default(sca
->name
, ca
, &cfg
->ca_default
);
690 cfg
->ca_last
->next
= ca
;
695 load_ca(ca
, ca
->kw
, cfg
);
698 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
700 also_t
*also
= ca
->also
;
704 kw_list_t
*kw
= find_also_ca(also
->name
, cfg
->ca_first
, cfg
);
706 load_ca(ca
, kw
, cfg
);
710 if (ca
->startup
!= STARTUP_NO
)
711 ca
->state
= STATE_TO_ADD
;
714 /* find %default conn sections */
715 for (sconn
= cfgp
->conn_first
; sconn
; sconn
= sconn
->next
)
717 if (streq(sconn
->name
, "%default"))
720 DBG_log("Loading conn %%default")
722 load_conn(&cfg
->conn_default
, sconn
->kw
, cfg
);
726 /* parameter defined in conn %default sections can be overloaded */
727 cfg
->conn_default
.seen
= LEMPTY
;
728 cfg
->conn_default
.right
.seen
= LEMPTY
;
729 cfg
->conn_default
.left
.seen
= LEMPTY
;
731 /* load other conn sections */
732 for (sconn
= cfgp
->conn_first
; sconn
; sconn
= sconn
->next
)
734 /* skip %default conn section */
735 if (streq(sconn
->name
, "%default"))
739 DBG_log("Loading conn '%s'", sconn
->name
)
741 conn
= (starter_conn_t
*)alloc_thing(starter_conn_t
, "starter_conn_t");
743 conn_default(sconn
->name
, conn
, &cfg
->conn_default
);
744 conn
->kw
= sconn
->kw
;
748 cfg
->conn_last
->next
= conn
;
749 cfg
->conn_last
= conn
;
750 if (!cfg
->conn_first
)
751 cfg
->conn_first
= conn
;
753 load_conn(conn
, conn
->kw
, cfg
);
756 /* in the second round do not parse also statements */
757 cfg
->parse_also
= FALSE
;
759 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
762 load_also_cas(ca
, ca
->also
, cfg
);
764 if (ca
->startup
!= STARTUP_NO
)
765 ca
->state
= STATE_TO_ADD
;
768 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
770 conn
->visit
= ++visit
;
771 load_also_conns(conn
, conn
->also
, cfg
);
773 if (conn
->startup
!= STARTUP_NO
)
774 conn
->state
= STATE_TO_ADD
;
777 parser_free_conf(cfgp
);
781 plog("### %d parsing error%s ###", cfg
->err
, (cfg
->err
> 1)?"s":"");
790 * free the memory used by also_t objects
793 free_also(also_t
*head
)
806 * free the memory used by a starter_conn_t object
809 confread_free_conn(starter_conn_t
*conn
)
811 free_args(KW_END_FIRST
, KW_END_LAST
, (char *)&conn
->left
);
812 free_args(KW_END_FIRST
, KW_END_LAST
, (char *)&conn
->right
);
813 free_args(KW_CONN_NAME
, KW_CONN_LAST
, (char *)conn
);
814 free_also(conn
->also
);
818 * free the memory used by a starter_ca_t object
821 confread_free_ca(starter_ca_t
*ca
)
823 free_args(KW_CA_NAME
, KW_CA_LAST
, (char *)ca
);
828 * free the memory used by a starter_config_t object
831 confread_free(starter_config_t
*cfg
)
833 starter_conn_t
*conn
= cfg
->conn_first
;
834 starter_ca_t
*ca
= cfg
->ca_first
;
836 free_args(KW_SETUP_FIRST
, KW_SETUP_LAST
, (char *)cfg
);
838 confread_free_conn(&cfg
->conn_default
);
842 starter_conn_t
*conn_aux
= conn
;
845 confread_free_conn(conn_aux
);
849 confread_free_ca(&cfg
->ca_default
);
853 starter_ca_t
*ca_aux
= ca
;
856 confread_free_ca(ca_aux
);