2 * Copyright (C) 2012-2014 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "stroke_config.h"
21 #include <threading/mutex.h>
22 #include <utils/lexparser.h>
26 typedef struct private_stroke_config_t private_stroke_config_t
;
29 * private data of stroke_config
31 struct private_stroke_config_t
{
36 stroke_config_t
public;
44 * mutex to lock config list
59 * Virtual IP pool / DNS backend
61 stroke_attribute_t
*attributes
;
64 METHOD(backend_t
, create_peer_cfg_enumerator
, enumerator_t
*,
65 private_stroke_config_t
*this, identification_t
*me
, identification_t
*other
)
67 this->mutex
->lock(this->mutex
);
68 return enumerator_create_cleaner(this->list
->create_enumerator(this->list
),
69 (void*)this->mutex
->unlock
, this->mutex
);
73 * filter function for ike configs
75 static bool ike_filter(void *data
, peer_cfg_t
**in
, ike_cfg_t
**out
)
77 *out
= (*in
)->get_ike_cfg(*in
);
81 METHOD(backend_t
, create_ike_cfg_enumerator
, enumerator_t
*,
82 private_stroke_config_t
*this, host_t
*me
, host_t
*other
)
84 this->mutex
->lock(this->mutex
);
85 return enumerator_create_filter(this->list
->create_enumerator(this->list
),
86 (void*)ike_filter
, this->mutex
,
87 (void*)this->mutex
->unlock
);
90 METHOD(backend_t
, get_peer_cfg_by_name
, peer_cfg_t
*,
91 private_stroke_config_t
*this, char *name
)
93 enumerator_t
*e1
, *e2
;
94 peer_cfg_t
*current
, *found
= NULL
;
97 this->mutex
->lock(this->mutex
);
98 e1
= this->list
->create_enumerator(this->list
);
99 while (e1
->enumerate(e1
, ¤t
))
101 /* compare peer_cfgs name first */
102 if (streq(current
->get_name(current
), name
))
105 found
->get_ref(found
);
108 /* compare all child_cfg names otherwise */
109 e2
= current
->create_child_cfg_enumerator(current
);
110 while (e2
->enumerate(e2
, &child
))
112 if (streq(child
->get_name(child
), name
))
115 found
->get_ref(found
);
126 this->mutex
->unlock(this->mutex
);
131 * parse a proposal string, either into ike_cfg or child_cfg
133 static void add_proposals(private_stroke_config_t
*this, char *string
,
134 ike_cfg_t
*ike_cfg
, child_cfg_t
*child_cfg
, protocol_id_t proto
)
140 proposal_t
*proposal
;
142 strict
= string
+ strlen(string
) - 1;
151 while ((single
= strsep(&string
, ",")))
153 proposal
= proposal_create_from_string(proto
, single
);
158 ike_cfg
->add_proposal(ike_cfg
, proposal
);
162 child_cfg
->add_proposal(child_cfg
, proposal
);
166 DBG1(DBG_CFG
, "skipped invalid proposal string: %s", single
);
172 /* add default porposal to the end if not strict */
176 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(proto
));
177 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default_aead(proto
));
181 child_cfg
->add_proposal(child_cfg
, proposal_create_default(proto
));
182 child_cfg
->add_proposal(child_cfg
, proposal_create_default_aead(proto
));
187 * Build an IKE config from a stroke message
189 static ike_cfg_t
*build_ike_cfg(private_stroke_config_t
*this, stroke_msg_t
*msg
)
191 enumerator_t
*enumerator
;
192 stroke_end_t tmp_end
;
196 char me
[256], other
[256], *token
;
197 bool swapped
= FALSE
;;
199 enumerator
= enumerator_create_token(msg
->add_conn
.other
.address
, ",", " ");
200 while (enumerator
->enumerate(enumerator
, &token
))
202 if (!strchr(token
, '/'))
204 host
= host_create_from_dns(token
, 0, 0);
207 if (hydra
->kernel_interface
->get_interface(
208 hydra
->kernel_interface
, host
, NULL
))
210 DBG2(DBG_CFG
, "left is other host, swapping ends");
211 tmp_end
= msg
->add_conn
.me
;
212 msg
->add_conn
.me
= msg
->add_conn
.other
;
213 msg
->add_conn
.other
= tmp_end
;
220 enumerator
->destroy(enumerator
);
224 enumerator
= enumerator_create_token(msg
->add_conn
.me
.address
, ",", " ");
225 while (enumerator
->enumerate(enumerator
, &token
))
227 if (!strchr(token
, '/'))
229 host
= host_create_from_dns(token
, 0, 0);
232 if (!hydra
->kernel_interface
->get_interface(
233 hydra
->kernel_interface
, host
, NULL
))
235 DBG1(DBG_CFG
, "left nor right host is our side, "
236 "assuming left=local");
242 enumerator
->destroy(enumerator
);
245 if (msg
->add_conn
.me
.allow_any
)
247 snprintf(me
, sizeof(me
), "%s,0.0.0.0/0,::/0",
248 msg
->add_conn
.me
.address
);
250 if (msg
->add_conn
.other
.allow_any
)
252 snprintf(other
, sizeof(other
), "%s,0.0.0.0/0,::/0",
253 msg
->add_conn
.other
.address
);
255 ikeport
= msg
->add_conn
.me
.ikeport
;
256 ikeport
= (ikeport
== IKEV2_UDP_PORT
) ?
257 charon
->socket
->get_port(charon
->socket
, FALSE
) : ikeport
;
258 ike_cfg
= ike_cfg_create(msg
->add_conn
.version
,
259 msg
->add_conn
.other
.sendcert
!= CERT_NEVER_SEND
,
260 msg
->add_conn
.force_encap
,
261 msg
->add_conn
.me
.allow_any ?
262 me
: msg
->add_conn
.me
.address
,
264 msg
->add_conn
.other
.allow_any ?
265 other
: msg
->add_conn
.other
.address
,
266 msg
->add_conn
.other
.ikeport
,
267 msg
->add_conn
.fragmentation
,
268 msg
->add_conn
.ikedscp
);
270 add_proposals(this, msg
->add_conn
.algorithms
.ike
, ike_cfg
, NULL
, PROTO_IKE
);
275 * Add CRL constraint to config
277 static void build_crl_policy(auth_cfg_t
*cfg
, bool local
, int policy
)
279 /* CRL/OCSP policy, for remote config only */
285 /* if yes, we require a GOOD validation */
286 cfg
->add(cfg
, AUTH_RULE_CRL_VALIDATION
, VALIDATION_GOOD
);
288 case CRL_STRICT_IFURI
:
289 /* for ifuri, a SKIPPED validation is sufficient */
290 cfg
->add(cfg
, AUTH_RULE_CRL_VALIDATION
, VALIDATION_SKIPPED
);
299 * Parse public key / signature strength constraints
301 static void parse_pubkey_constraints(char *auth
, auth_cfg_t
*cfg
)
303 enumerator_t
*enumerator
;
304 bool rsa
= FALSE
, ecdsa
= FALSE
, rsa_len
= FALSE
, ecdsa_len
= FALSE
;
308 enumerator
= enumerator_create_token(auth
, "-", "");
309 while (enumerator
->enumerate(enumerator
, &token
))
315 signature_scheme_t scheme
;
318 { "md5", SIGN_RSA_EMSA_PKCS1_MD5
, KEY_RSA
, },
319 { "sha1", SIGN_RSA_EMSA_PKCS1_SHA1
, KEY_RSA
, },
320 { "sha224", SIGN_RSA_EMSA_PKCS1_SHA224
, KEY_RSA
, },
321 { "sha256", SIGN_RSA_EMSA_PKCS1_SHA256
, KEY_RSA
, },
322 { "sha384", SIGN_RSA_EMSA_PKCS1_SHA384
, KEY_RSA
, },
323 { "sha512", SIGN_RSA_EMSA_PKCS1_SHA512
, KEY_RSA
, },
324 { "sha1", SIGN_ECDSA_WITH_SHA1_DER
, KEY_ECDSA
, },
325 { "sha256", SIGN_ECDSA_WITH_SHA256_DER
, KEY_ECDSA
, },
326 { "sha384", SIGN_ECDSA_WITH_SHA384_DER
, KEY_ECDSA
, },
327 { "sha512", SIGN_ECDSA_WITH_SHA512_DER
, KEY_ECDSA
, },
328 { "sha256", SIGN_ECDSA_256
, KEY_ECDSA
, },
329 { "sha384", SIGN_ECDSA_384
, KEY_ECDSA
, },
330 { "sha512", SIGN_ECDSA_521
, KEY_ECDSA
, },
333 if (rsa_len
|| ecdsa_len
)
334 { /* expecting a key strength token */
335 strength
= atoi(token
);
340 cfg
->add(cfg
, AUTH_RULE_RSA_STRENGTH
, (uintptr_t)strength
);
344 cfg
->add(cfg
, AUTH_RULE_ECDSA_STRENGTH
, (uintptr_t)strength
);
347 rsa_len
= ecdsa_len
= FALSE
;
353 if (streq(token
, "rsa"))
355 rsa
= rsa_len
= TRUE
;
358 if (streq(token
, "ecdsa"))
360 ecdsa
= ecdsa_len
= TRUE
;
363 if (streq(token
, "pubkey"))
368 for (i
= 0; i
< countof(schemes
); i
++)
370 if (streq(schemes
[i
].name
, token
))
372 /* for each matching string, allow the scheme, if:
373 * - it is an RSA scheme, and we enforced RSA
374 * - it is an ECDSA scheme, and we enforced ECDSA
375 * - it is not a key type specific scheme
377 if ((rsa
&& schemes
[i
].key
== KEY_RSA
) ||
378 (ecdsa
&& schemes
[i
].key
== KEY_ECDSA
) ||
381 cfg
->add(cfg
, AUTH_RULE_SIGNATURE_SCHEME
,
382 (uintptr_t)schemes
[i
].scheme
);
389 DBG1(DBG_CFG
, "ignoring invalid auth token: '%s'", token
);
392 enumerator
->destroy(enumerator
);
396 * build authentication config
398 static auth_cfg_t
*build_auth_cfg(private_stroke_config_t
*this,
399 stroke_msg_t
*msg
, bool local
, bool primary
)
401 identification_t
*identity
;
402 certificate_t
*certificate
;
403 char *auth
, *id
, *pubkey
, *cert
, *ca
, *groups
;
404 stroke_end_t
*end
, *other_end
;
411 end
= &msg
->add_conn
.me
;
412 other_end
= &msg
->add_conn
.other
;
416 end
= &msg
->add_conn
.other
;
417 other_end
= &msg
->add_conn
.me
;
424 { /* leftid/rightid fallback to address */
429 if (ca
&& streq(ca
, "%same"))
439 { /* leftid2 falls back to leftid */
444 if (ca
&& streq(ca
, "%same"))
449 if (id
&& *id
== '%' && !streq(id
, "%any") && !streq(id
, "%any6"))
450 { /* has only an effect on rightid/2 */
462 { /* no second authentication round, fine. But load certificates
463 * for other purposes (EAP-TLS) */
466 certificate
= this->cred
->load_peer(this->cred
, cert
);
469 certificate
->destroy(certificate
);
476 cfg
= auth_cfg_create();
478 /* add identity and peer certificate */
479 identity
= identification_create_from_string(id
);
482 enumerator_t
*enumerator
;
483 bool has_subject
= FALSE
;
484 certificate_t
*first
= NULL
;
486 enumerator
= enumerator_create_token(cert
, ",", " ");
487 while (enumerator
->enumerate(enumerator
, &cert
))
489 certificate
= this->cred
->load_peer(this->cred
, cert
);
494 this->ca
->check_for_hash_and_url(this->ca
, certificate
);
496 cfg
->add(cfg
, AUTH_RULE_SUBJECT_CERT
, certificate
);
501 if (identity
->get_type(identity
) != ID_ANY
&&
502 certificate
->has_subject(certificate
, identity
))
508 enumerator
->destroy(enumerator
);
510 if (first
&& !has_subject
)
512 DBG1(DBG_CFG
, " id '%Y' not confirmed by certificate, "
513 "defaulting to '%Y'", identity
, first
->get_subject(first
));
514 identity
->destroy(identity
);
515 identity
= first
->get_subject(first
);
516 identity
= identity
->clone(identity
);
519 /* add raw RSA public key */
520 pubkey
= end
->rsakey
;
521 if (pubkey
&& !streq(pubkey
, "") && !streq(pubkey
, "%cert"))
523 certificate
= this->cred
->load_pubkey(this->cred
, pubkey
, identity
);
526 cfg
->add(cfg
, AUTH_RULE_SUBJECT_CERT
, certificate
);
529 if (identity
->get_type(identity
) != ID_ANY
)
531 cfg
->add(cfg
, AUTH_RULE_IDENTITY
, identity
);
534 cfg
->add(cfg
, AUTH_RULE_IDENTITY_LOOSE
, TRUE
);
539 identity
->destroy(identity
);
545 identity
= identification_create_from_string(ca
);
546 certificate
= lib
->credmgr
->get_cert(lib
->credmgr
, CERT_X509
,
547 KEY_ANY
, identity
, TRUE
);
548 identity
->destroy(identity
);
551 cfg
->add(cfg
, AUTH_RULE_CA_CERT
, certificate
);
555 DBG1(DBG_CFG
, "CA certificate \"%s\" not found, discarding CA "
561 groups
= primary ? end
->groups
: end
->groups2
;
564 enumerator_t
*enumerator
;
567 enumerator
= enumerator_create_token(groups
, ",", " ");
568 while (enumerator
->enumerate(enumerator
, &group
))
570 cfg
->add(cfg
, AUTH_RULE_GROUP
,
571 identification_create_from_string(group
));
573 enumerator
->destroy(enumerator
);
576 /* certificatePolicies */
577 if (end
->cert_policy
)
579 enumerator_t
*enumerator
;
582 enumerator
= enumerator_create_token(end
->cert_policy
, ",", " ");
583 while (enumerator
->enumerate(enumerator
, &policy
))
585 cfg
->add(cfg
, AUTH_RULE_CERT_POLICY
, strdup(policy
));
587 enumerator
->destroy(enumerator
);
590 /* authentication metod (class, actually) */
591 if (strpfx(auth
, "pubkey") ||
592 strpfx(auth
, "rsa") ||
593 strpfx(auth
, "ecdsa"))
595 cfg
->add(cfg
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
596 build_crl_policy(cfg
, local
, msg
->add_conn
.crl_policy
);
598 parse_pubkey_constraints(auth
, cfg
);
600 else if (streq(auth
, "psk") || streq(auth
, "secret"))
602 cfg
->add(cfg
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PSK
);
604 else if (strpfx(auth
, "xauth"))
608 pos
= strchr(auth
, '-');
611 cfg
->add(cfg
, AUTH_RULE_XAUTH_BACKEND
, strdup(++pos
));
613 cfg
->add(cfg
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_XAUTH
);
614 if (msg
->add_conn
.xauth_identity
)
616 cfg
->add(cfg
, AUTH_RULE_XAUTH_IDENTITY
,
617 identification_create_from_string(msg
->add_conn
.xauth_identity
));
620 else if (strpfx(auth
, "eap"))
622 eap_vendor_type_t
*type
;
625 cfg
->add(cfg
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
626 /* check for public key constraints for EAP-TLS etc. */
627 pos
= strchr(auth
, ':');
631 parse_pubkey_constraints(pos
+ 1, cfg
);
633 type
= eap_vendor_type_from_string(auth
);
636 cfg
->add(cfg
, AUTH_RULE_EAP_TYPE
, type
->type
);
639 cfg
->add(cfg
, AUTH_RULE_EAP_VENDOR
, type
->vendor
);
644 if (msg
->add_conn
.eap_identity
)
646 if (streq(msg
->add_conn
.eap_identity
, "%identity"))
648 identity
= identification_create_from_encoding(ID_ANY
,
653 identity
= identification_create_from_string(
654 msg
->add_conn
.eap_identity
);
656 cfg
->add(cfg
, AUTH_RULE_EAP_IDENTITY
, identity
);
658 if (msg
->add_conn
.aaa_identity
)
660 cfg
->add(cfg
, AUTH_RULE_AAA_IDENTITY
,
661 identification_create_from_string(msg
->add_conn
.aaa_identity
));
666 if (!streq(auth
, "any"))
668 DBG1(DBG_CFG
, "authentication method %s unknown, fallback to any",
671 build_crl_policy(cfg
, local
, msg
->add_conn
.crl_policy
);
677 * build a mem_pool_t from an address range
679 static mem_pool_t
*create_pool_range(char *str
)
684 if (!host_create_from_range(str
, &from
, &to
))
688 pool
= mem_pool_create_range(str
, from
, to
);
695 * build a peer_cfg from a stroke msg
697 static peer_cfg_t
*build_peer_cfg(private_stroke_config_t
*this,
698 stroke_msg_t
*msg
, ike_cfg_t
*ike_cfg
)
700 identification_t
*peer_id
= NULL
;
701 peer_cfg_t
*mediated_by
= NULL
;
702 unique_policy_t unique
;
703 u_int32_t rekey
= 0, reauth
= 0, over
, jitter
;
704 peer_cfg_t
*peer_cfg
;
705 auth_cfg_t
*auth_cfg
;
708 if (msg
->add_conn
.ikeme
.mediation
&& msg
->add_conn
.ikeme
.mediated_by
)
710 DBG1(DBG_CFG
, "a mediation connection cannot be a mediated connection "
711 "at the same time, aborting");
715 if (msg
->add_conn
.ikeme
.mediation
)
717 /* force unique connections for mediation connections */
718 msg
->add_conn
.unique
= 1;
721 if (msg
->add_conn
.ikeme
.mediated_by
)
723 mediated_by
= charon
->backends
->get_peer_cfg_by_name(charon
->backends
,
724 msg
->add_conn
.ikeme
.mediated_by
);
727 DBG1(DBG_CFG
, "mediation connection '%s' not found, aborting",
728 msg
->add_conn
.ikeme
.mediated_by
);
731 if (!mediated_by
->is_mediation(mediated_by
))
733 DBG1(DBG_CFG
, "connection '%s' as referred to by '%s' is "
734 "no mediation connection, aborting",
735 msg
->add_conn
.ikeme
.mediated_by
, msg
->add_conn
.name
);
736 mediated_by
->destroy(mediated_by
);
739 if (msg
->add_conn
.ikeme
.peerid
)
741 peer_id
= identification_create_from_string(msg
->add_conn
.ikeme
.peerid
);
743 else if (msg
->add_conn
.other
.id
)
745 peer_id
= identification_create_from_string(msg
->add_conn
.other
.id
);
750 jitter
= msg
->add_conn
.rekey
.margin
* msg
->add_conn
.rekey
.fuzz
/ 100;
751 over
= msg
->add_conn
.rekey
.margin
;
752 if (msg
->add_conn
.rekey
.reauth
)
754 reauth
= msg
->add_conn
.rekey
.ike_lifetime
- over
;
758 rekey
= msg
->add_conn
.rekey
.ike_lifetime
- over
;
760 switch (msg
->add_conn
.unique
)
763 case 2: /* replace */
764 unique
= UNIQUE_REPLACE
;
767 unique
= UNIQUE_KEEP
;
770 unique
= UNIQUE_NEVER
;
776 if (msg
->add_conn
.dpd
.action
== 0)
777 { /* dpdaction=none disables DPD */
778 msg
->add_conn
.dpd
.delay
= 0;
781 /* other.sourceip is managed in stroke_attributes. If it is set, we define
782 * the pool name as the connection name, which the attribute provider
783 * uses to serve pool addresses. */
784 peer_cfg
= peer_cfg_create(msg
->add_conn
.name
, ike_cfg
,
785 msg
->add_conn
.me
.sendcert
, unique
,
786 msg
->add_conn
.rekey
.tries
, rekey
, reauth
, jitter
, over
,
787 msg
->add_conn
.mobike
, msg
->add_conn
.aggressive
,
788 msg
->add_conn
.pushmode
== 0,
789 msg
->add_conn
.dpd
.delay
, msg
->add_conn
.dpd
.timeout
,
790 msg
->add_conn
.ikeme
.mediation
, mediated_by
, peer_id
);
792 if (msg
->add_conn
.other
.sourceip
)
794 enumerator_t
*enumerator
;
797 enumerator
= enumerator_create_token(msg
->add_conn
.other
.sourceip
,
799 while (enumerator
->enumerate(enumerator
, &token
))
801 if (streq(token
, "%modeconfig") || streq(token
, "%modecfg") ||
802 streq(token
, "%config") || streq(token
, "%cfg") ||
803 streq(token
, "%config4") || streq(token
, "%config6"))
805 /* empty pool, uses connection name */
806 this->attributes
->add_pool(this->attributes
,
807 mem_pool_create(msg
->add_conn
.name
, NULL
, 0));
808 peer_cfg
->add_pool(peer_cfg
, msg
->add_conn
.name
);
810 else if (*token
== '%')
812 /* external named pool */
813 peer_cfg
->add_pool(peer_cfg
, token
+ 1);
817 /* in-memory pool, using range or CIDR notation */
822 pool
= create_pool_range(token
);
825 base
= host_create_from_subnet(token
, &bits
);
828 pool
= mem_pool_create(token
, base
, bits
);
834 this->attributes
->add_pool(this->attributes
, pool
);
835 peer_cfg
->add_pool(peer_cfg
, token
);
839 DBG1(DBG_CFG
, "IP pool %s invalid, ignored", token
);
843 enumerator
->destroy(enumerator
);
846 if (msg
->add_conn
.me
.sourceip
&& msg
->add_conn
.other
.sourceip
)
848 DBG1(DBG_CFG
, "'%s' has both left- and rightsourceip, but IKE can "
849 "negotiate one virtual IP only, ignoring local virtual IP",
852 else if (msg
->add_conn
.me
.sourceip
)
854 enumerator_t
*enumerator
;
857 enumerator
= enumerator_create_token(msg
->add_conn
.me
.sourceip
, ",", " ");
858 while (enumerator
->enumerate(enumerator
, &token
))
862 if (streq(token
, "%modeconfig") || streq(token
, "%modecfg") ||
863 streq(token
, "%config") || streq(token
, "%cfg"))
864 { /* try to deduce an address family */
865 if (msg
->add_conn
.me
.subnets
)
866 { /* use the same family as in local subnet, if any */
867 if (strchr(msg
->add_conn
.me
.subnets
, '.'))
869 vip
= host_create_any(AF_INET
);
873 vip
= host_create_any(AF_INET6
);
876 else if (msg
->add_conn
.other
.subnets
)
877 { /* use the same family as in remote subnet, if any */
878 if (strchr(msg
->add_conn
.other
.subnets
, '.'))
880 vip
= host_create_any(AF_INET
);
884 vip
= host_create_any(AF_INET6
);
889 char *addr
, *next
, *hit
;
891 /* guess virtual IP family based on local address. If
892 * multiple addresses are specified, we look at the first
893 * only, as with leftallowany a ::/0 is always appended. */
894 addr
= ike_cfg
->get_my_addr(ike_cfg
);
895 next
= strchr(addr
, ',');
896 hit
= strchr(addr
, ':');
897 if (hit
&& (!next
|| hit
< next
))
899 vip
= host_create_any(AF_INET6
);
903 vip
= host_create_any(AF_INET
);
907 else if (streq(token
, "%config4"))
909 vip
= host_create_any(AF_INET
);
911 else if (streq(token
, "%config6"))
913 vip
= host_create_any(AF_INET6
);
917 vip
= host_create_from_string(token
, 0);
920 DBG1(DBG_CFG
, "ignored invalid subnet token: %s", token
);
926 peer_cfg
->add_virtual_ip(peer_cfg
, vip
);
929 enumerator
->destroy(enumerator
);
932 /* build leftauth= */
933 auth_cfg
= build_auth_cfg(this, msg
, TRUE
, TRUE
);
936 peer_cfg
->add_auth_cfg(peer_cfg
, auth_cfg
, TRUE
);
939 { /* we require at least one config on our side */
940 peer_cfg
->destroy(peer_cfg
);
943 /* build leftauth2= */
944 auth_cfg
= build_auth_cfg(this, msg
, TRUE
, FALSE
);
947 peer_cfg
->add_auth_cfg(peer_cfg
, auth_cfg
, TRUE
);
949 /* build rightauth= */
950 auth_cfg
= build_auth_cfg(this, msg
, FALSE
, TRUE
);
953 peer_cfg
->add_auth_cfg(peer_cfg
, auth_cfg
, FALSE
);
955 /* build rightauth2= */
956 auth_cfg
= build_auth_cfg(this, msg
, FALSE
, FALSE
);
959 peer_cfg
->add_auth_cfg(peer_cfg
, auth_cfg
, FALSE
);
965 * Parse a protoport specifier
967 static bool parse_protoport(char *token
, u_int16_t
*from_port
,
968 u_int16_t
*to_port
, u_int8_t
*protocol
)
970 char *sep
, *port
= "", *endptr
;
971 struct protoent
*proto
;
975 sep
= strrchr(token
, ']');
982 sep
= strchr(token
, '/');
984 { /* protocol/port */
989 if (streq(token
, "%any"))
995 proto
= getprotobyname(token
);
998 *protocol
= proto
->p_proto
;
1002 p
= strtol(token
, &endptr
, 0);
1003 if ((*token
&& *endptr
) || p
< 0 || p
> 0xff)
1007 *protocol
= (u_int8_t
)p
;
1010 if (streq(port
, "%any"))
1015 else if (streq(port
, "%opaque"))
1017 *from_port
= 0xffff;
1022 svc
= getservbyname(port
, NULL
);
1025 *from_port
= *to_port
= ntohs(svc
->s_port
);
1029 p
= strtol(port
, &endptr
, 0);
1030 if (p
< 0 || p
> 0xffff)
1038 p
= strtol(port
, &endptr
, 0);
1039 if (p
< 0 || p
> 0xffff)
1055 * build a traffic selector from a stroke_end
1057 static void add_ts(private_stroke_config_t
*this,
1058 stroke_end_t
*end
, child_cfg_t
*child_cfg
, bool local
)
1060 traffic_selector_t
*ts
;
1064 ts
= traffic_selector_create_dynamic(end
->protocol
,
1065 end
->from_port
, end
->to_port
);
1066 child_cfg
->add_traffic_selector(child_cfg
, local
, ts
);
1074 net
= host_create_from_string(end
->address
, 0);
1077 ts
= traffic_selector_create_from_subnet(net
, 0, end
->protocol
,
1078 end
->from_port
, end
->to_port
);
1079 child_cfg
->add_traffic_selector(child_cfg
, local
, ts
);
1084 enumerator_t
*enumerator
;
1086 u_int16_t from_port
, to_port
;
1089 enumerator
= enumerator_create_token(end
->subnets
, ",", " ");
1090 while (enumerator
->enumerate(enumerator
, &subnet
))
1092 from_port
= end
->from_port
;
1093 to_port
= end
->to_port
;
1094 proto
= end
->protocol
;
1096 pos
= strchr(subnet
, '[');
1100 if (!parse_protoport(pos
, &from_port
, &to_port
, &proto
))
1102 DBG1(DBG_CFG
, "invalid proto/port: %s, skipped subnet",
1107 if (streq(subnet
, "%dynamic"))
1109 ts
= traffic_selector_create_dynamic(proto
,
1110 from_port
, to_port
);
1114 ts
= traffic_selector_create_from_cidr(subnet
, proto
,
1115 from_port
, to_port
);
1119 child_cfg
->add_traffic_selector(child_cfg
, local
, ts
);
1123 DBG1(DBG_CFG
, "invalid subnet: %s, skipped", subnet
);
1126 enumerator
->destroy(enumerator
);
1132 * map starter magic values to our action type
1134 static action_t
map_action(int starter_action
)
1136 switch (starter_action
)
1139 return ACTION_ROUTE
;
1140 case 3: /* =restart */
1141 return ACTION_RESTART
;
1148 * build a child config from the stroke message
1150 static child_cfg_t
*build_child_cfg(private_stroke_config_t
*this,
1153 child_cfg_t
*child_cfg
;
1154 lifetime_cfg_t lifetime
= {
1156 .life
= msg
->add_conn
.rekey
.ipsec_lifetime
,
1157 .rekey
= msg
->add_conn
.rekey
.ipsec_lifetime
- msg
->add_conn
.rekey
.margin
,
1158 .jitter
= msg
->add_conn
.rekey
.margin
* msg
->add_conn
.rekey
.fuzz
/ 100
1161 .life
= msg
->add_conn
.rekey
.life_bytes
,
1162 .rekey
= msg
->add_conn
.rekey
.life_bytes
- msg
->add_conn
.rekey
.margin_bytes
,
1163 .jitter
= msg
->add_conn
.rekey
.margin_bytes
* msg
->add_conn
.rekey
.fuzz
/ 100
1166 .life
= msg
->add_conn
.rekey
.life_packets
,
1167 .rekey
= msg
->add_conn
.rekey
.life_packets
- msg
->add_conn
.rekey
.margin_packets
,
1168 .jitter
= msg
->add_conn
.rekey
.margin_packets
* msg
->add_conn
.rekey
.fuzz
/ 100
1172 .value
= msg
->add_conn
.mark_in
.value
,
1173 .mask
= msg
->add_conn
.mark_in
.mask
1176 .value
= msg
->add_conn
.mark_out
.value
,
1177 .mask
= msg
->add_conn
.mark_out
.mask
1180 child_cfg
= child_cfg_create(
1181 msg
->add_conn
.name
, &lifetime
, msg
->add_conn
.me
.updown
,
1182 msg
->add_conn
.me
.hostaccess
, msg
->add_conn
.mode
, ACTION_NONE
,
1183 map_action(msg
->add_conn
.dpd
.action
),
1184 map_action(msg
->add_conn
.close_action
), msg
->add_conn
.ipcomp
,
1185 msg
->add_conn
.inactivity
, msg
->add_conn
.reqid
,
1186 &mark_in
, &mark_out
, msg
->add_conn
.tfc
);
1187 if (msg
->add_conn
.replay_window
!= -1)
1189 child_cfg
->set_replay_window(child_cfg
, msg
->add_conn
.replay_window
);
1191 child_cfg
->set_mipv6_options(child_cfg
, msg
->add_conn
.proxy_mode
,
1192 msg
->add_conn
.install_policy
);
1193 add_ts(this, &msg
->add_conn
.me
, child_cfg
, TRUE
);
1194 add_ts(this, &msg
->add_conn
.other
, child_cfg
, FALSE
);
1196 if (msg
->add_conn
.algorithms
.ah
)
1198 add_proposals(this, msg
->add_conn
.algorithms
.ah
,
1199 NULL
, child_cfg
, PROTO_AH
);
1203 add_proposals(this, msg
->add_conn
.algorithms
.esp
,
1204 NULL
, child_cfg
, PROTO_ESP
);
1209 METHOD(stroke_config_t
, add
, void,
1210 private_stroke_config_t
*this, stroke_msg_t
*msg
)
1212 ike_cfg_t
*ike_cfg
, *existing_ike
;
1213 peer_cfg_t
*peer_cfg
, *existing
;
1214 child_cfg_t
*child_cfg
;
1215 enumerator_t
*enumerator
;
1216 bool use_existing
= FALSE
;
1218 ike_cfg
= build_ike_cfg(this, msg
);
1223 peer_cfg
= build_peer_cfg(this, msg
, ike_cfg
);
1226 ike_cfg
->destroy(ike_cfg
);
1230 enumerator
= create_peer_cfg_enumerator(this, NULL
, NULL
);
1231 while (enumerator
->enumerate(enumerator
, &existing
))
1233 existing_ike
= existing
->get_ike_cfg(existing
);
1234 if (existing
->equals(existing
, peer_cfg
) &&
1235 existing_ike
->equals(existing_ike
, peer_cfg
->get_ike_cfg(peer_cfg
)))
1237 use_existing
= TRUE
;
1238 peer_cfg
->destroy(peer_cfg
);
1239 peer_cfg
= existing
;
1240 peer_cfg
->get_ref(peer_cfg
);
1241 DBG1(DBG_CFG
, "added child to existing configuration '%s'",
1242 peer_cfg
->get_name(peer_cfg
));
1246 enumerator
->destroy(enumerator
);
1248 child_cfg
= build_child_cfg(this, msg
);
1251 peer_cfg
->destroy(peer_cfg
);
1254 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
1258 peer_cfg
->destroy(peer_cfg
);
1262 /* add config to backend */
1263 DBG1(DBG_CFG
, "added configuration '%s'", msg
->add_conn
.name
);
1264 this->mutex
->lock(this->mutex
);
1265 this->list
->insert_last(this->list
, peer_cfg
);
1266 this->mutex
->unlock(this->mutex
);
1270 METHOD(stroke_config_t
, del
, void,
1271 private_stroke_config_t
*this, stroke_msg_t
*msg
)
1273 enumerator_t
*enumerator
, *children
;
1276 bool deleted
= FALSE
;
1278 this->mutex
->lock(this->mutex
);
1279 enumerator
= this->list
->create_enumerator(this->list
);
1280 while (enumerator
->enumerate(enumerator
, &peer
))
1284 /* remove any child with such a name */
1285 children
= peer
->create_child_cfg_enumerator(peer
);
1286 while (children
->enumerate(children
, &child
))
1288 if (streq(child
->get_name(child
), msg
->del_conn
.name
))
1290 peer
->remove_child_cfg(peer
, children
);
1291 child
->destroy(child
);
1299 children
->destroy(children
);
1301 /* if peer config has no children anymore, remove it */
1304 this->list
->remove_at(this->list
, enumerator
);
1305 peer
->destroy(peer
);
1308 enumerator
->destroy(enumerator
);
1309 this->mutex
->unlock(this->mutex
);
1313 DBG1(DBG_CFG
, "deleted connection '%s'", msg
->del_conn
.name
);
1317 DBG1(DBG_CFG
, "connection '%s' not found", msg
->del_conn
.name
);
1321 METHOD(stroke_config_t
, set_user_credentials
, void,
1322 private_stroke_config_t
*this, stroke_msg_t
*msg
, FILE *prompt
)
1324 enumerator_t
*enumerator
, *children
, *remote_auth
;
1325 peer_cfg_t
*peer
, *found
= NULL
;
1326 auth_cfg_t
*auth_cfg
, *remote_cfg
;
1327 auth_class_t auth_class
;
1329 identification_t
*id
, *identity
, *gw
= NULL
;
1330 shared_key_type_t type
= SHARED_ANY
;
1331 chunk_t password
= chunk_empty
;
1333 this->mutex
->lock(this->mutex
);
1334 enumerator
= this->list
->create_enumerator(this->list
);
1335 while (enumerator
->enumerate(enumerator
, (void**)&peer
))
1336 { /* find the peer (or child) config with the given name */
1337 if (streq(peer
->get_name(peer
), msg
->user_creds
.name
))
1343 children
= peer
->create_child_cfg_enumerator(peer
);
1344 while (children
->enumerate(children
, &child
))
1346 if (streq(child
->get_name(child
), msg
->user_creds
.name
))
1352 children
->destroy(children
);
1360 enumerator
->destroy(enumerator
);
1364 DBG1(DBG_CFG
, " no config named '%s'", msg
->user_creds
.name
);
1365 fprintf(prompt
, "no config named '%s'\n", msg
->user_creds
.name
);
1366 this->mutex
->unlock(this->mutex
);
1370 id
= identification_create_from_string(msg
->user_creds
.username
);
1371 if (strlen(msg
->user_creds
.username
) == 0 ||
1372 !id
|| id
->get_type(id
) == ID_ANY
)
1374 DBG1(DBG_CFG
, " invalid username '%s'", msg
->user_creds
.username
);
1375 fprintf(prompt
, "invalid username '%s'\n", msg
->user_creds
.username
);
1376 this->mutex
->unlock(this->mutex
);
1381 /* replace/set the username in the first EAP/XAuth auth_cfg, also look for
1382 * a suitable remote ID.
1383 * note that adding the identity here is not fully thread-safe as the
1384 * peer_cfg and in turn the auth_cfg could be in use. for the default use
1385 * case (setting user credentials before upping the connection) this will
1386 * not be a problem, though. */
1387 enumerator
= found
->create_auth_cfg_enumerator(found
, TRUE
);
1388 remote_auth
= found
->create_auth_cfg_enumerator(found
, FALSE
);
1389 while (enumerator
->enumerate(enumerator
, (void**)&auth_cfg
))
1391 if (remote_auth
->enumerate(remote_auth
, (void**)&remote_cfg
))
1392 { /* fall back on rightid, in case aaa_identity is not specified */
1393 identity
= remote_cfg
->get(remote_cfg
, AUTH_RULE_IDENTITY
);
1394 if (identity
&& identity
->get_type(identity
) != ID_ANY
)
1400 auth_class
= (uintptr_t)auth_cfg
->get(auth_cfg
, AUTH_RULE_AUTH_CLASS
);
1401 if (auth_class
== AUTH_CLASS_EAP
|| auth_class
== AUTH_CLASS_XAUTH
)
1403 if (auth_class
== AUTH_CLASS_EAP
)
1405 auth_cfg
->add(auth_cfg
, AUTH_RULE_EAP_IDENTITY
, id
->clone(id
));
1406 /* if aaa_identity is specified use that as remote ID */
1407 identity
= auth_cfg
->get(auth_cfg
, AUTH_RULE_AAA_IDENTITY
);
1408 if (identity
&& identity
->get_type(identity
) != ID_ANY
)
1412 DBG1(DBG_CFG
, " configured EAP-Identity %Y", id
);
1416 auth_cfg
->add(auth_cfg
, AUTH_RULE_XAUTH_IDENTITY
,
1418 DBG1(DBG_CFG
, " configured XAuth username %Y", id
);
1424 enumerator
->destroy(enumerator
);
1425 remote_auth
->destroy(remote_auth
);
1426 /* clone the gw ID before unlocking the mutex */
1431 this->mutex
->unlock(this->mutex
);
1433 if (type
== SHARED_ANY
)
1435 DBG1(DBG_CFG
, " config '%s' unsuitable for user credentials",
1436 msg
->user_creds
.name
);
1437 fprintf(prompt
, "config '%s' unsuitable for user credentials\n",
1438 msg
->user_creds
.name
);
1444 if (msg
->user_creds
.password
)
1448 pass
= msg
->user_creds
.password
;
1449 password
= chunk_clone(chunk_create(pass
, strlen(pass
)));
1450 memwipe(pass
, strlen(pass
));
1453 { /* prompt the user for the password */
1456 fprintf(prompt
, "Password:\n");
1457 if (fgets(buf
, sizeof(buf
), prompt
))
1459 password
= chunk_clone(chunk_create(buf
, strlen(buf
)));
1460 if (password
.len
> 0)
1461 { /* trim trailing \n */
1464 memwipe(buf
, sizeof(buf
));
1470 shared_key_t
*shared
;
1471 linked_list_t
*owners
;
1473 shared
= shared_key_create(type
, password
);
1475 owners
= linked_list_create();
1476 owners
->insert_last(owners
, id
->clone(id
));
1477 if (gw
&& gw
->get_type(gw
) != ID_ANY
)
1479 owners
->insert_last(owners
, gw
->clone(gw
));
1480 DBG1(DBG_CFG
, " added %N secret for %Y %Y", shared_key_type_names
,
1485 DBG1(DBG_CFG
, " added %N secret for %Y", shared_key_type_names
,
1488 this->cred
->add_shared(this->cred
, shared
, owners
);
1489 DBG4(DBG_CFG
, " secret: %#B", &password
);
1492 { /* in case a user answers the password prompt by just pressing enter */
1493 chunk_clear(&password
);
1499 METHOD(stroke_config_t
, destroy
, void,
1500 private_stroke_config_t
*this)
1502 this->list
->destroy_offset(this->list
, offsetof(peer_cfg_t
, destroy
));
1503 this->mutex
->destroy(this->mutex
);
1510 stroke_config_t
*stroke_config_create(stroke_ca_t
*ca
, stroke_cred_t
*cred
,
1511 stroke_attribute_t
*attributes
)
1513 private_stroke_config_t
*this;
1518 .create_peer_cfg_enumerator
= _create_peer_cfg_enumerator
,
1519 .create_ike_cfg_enumerator
= _create_ike_cfg_enumerator
,
1520 .get_peer_cfg_by_name
= _get_peer_cfg_by_name
,
1524 .set_user_credentials
= _set_user_credentials
,
1525 .destroy
= _destroy
,
1527 .list
= linked_list_create(),
1528 .mutex
= mutex_create(MUTEX_TYPE_RECURSIVE
),
1531 .attributes
= attributes
,
1534 return &this->public;