2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 typedef struct private_config_t private_config_t
;
24 * Private data of an config_t object.
26 struct private_config_t
{
29 * Public config_t interface.
34 * List of loaded peer configs
36 linked_list_t
*configs
;
40 * filter function for ike configs
42 static bool ike_filter(void *data
, peer_cfg_t
**in
, ike_cfg_t
**out
)
44 *out
= (*in
)->get_ike_cfg(*in
);
48 METHOD(backend_t
, create_ike_cfg_enumerator
, enumerator_t
*,
49 private_config_t
*this, host_t
*me
, host_t
*other
)
52 return enumerator_create_filter(
53 this->configs
->create_enumerator(this->configs
),
54 (void*)ike_filter
, NULL
, NULL
);
57 METHOD(backend_t
, create_peer_cfg_enumerator
, enumerator_t
*,
58 private_config_t
*this, identification_t
*me
, identification_t
*other
)
60 return this->configs
->create_enumerator(this->configs
);
63 METHOD(backend_t
, get_peer_cfg_by_name
, peer_cfg_t
*,
64 private_config_t
*this, char *name
)
66 enumerator_t
*e1
, *e2
;
67 peer_cfg_t
*current
, *found
= NULL
;
70 e1
= this->configs
->create_enumerator(this->configs
);
71 while (e1
->enumerate(e1
, ¤t
))
73 e2
= current
->create_child_cfg_enumerator(current
);
74 while (e2
->enumerate(e2
, &child
))
76 if (streq(child
->get_name(child
), name
))
79 found
->get_ref(found
);
94 * Load IKE config for a given section name
96 static ike_cfg_t
*load_ike_config(private_config_t
*this,
97 settings_t
*settings
, char *config
)
99 enumerator_t
*enumerator
;
101 proposal_t
*proposal
;
104 ike_cfg
= ike_cfg_create(TRUE
, FALSE
,
105 settings
->get_str(settings
, "configs.%s.lhost", "%any", config
), 500,
106 settings
->get_str(settings
, "configs.%s.rhost", "%any", config
), 500);
107 token
= settings
->get_str(settings
, "configs.%s.proposal", NULL
, config
);
110 enumerator
= enumerator_create_token(token
, ",", " ");
111 while (enumerator
->enumerate(enumerator
, &token
))
113 proposal
= proposal_create_from_string(PROTO_IKE
, token
);
116 ike_cfg
->add_proposal(ike_cfg
, proposal
);
120 DBG1(DBG_CFG
, "parsing proposal '%s' failed, skipped", token
);
123 enumerator
->destroy(enumerator
);
127 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
132 * Load CHILD config for given section names
134 static child_cfg_t
*load_child_config(private_config_t
*this,
135 settings_t
*settings
, char *config
, char *child
)
137 child_cfg_t
*child_cfg
;
138 lifetime_cfg_t lifetime
= {};
139 enumerator_t
*enumerator
;
140 proposal_t
*proposal
;
141 traffic_selector_t
*ts
;
146 child_cfg
= child_cfg_create(child
, &lifetime
, NULL
, FALSE
,
147 settings
->get_bool(settings
, "configs.%s.%s.transport",
148 FALSE
, config
, child
),
149 ACTION_NONE
, ACTION_NONE
, FALSE
, 0, 0, NULL
, NULL
);
151 token
= settings
->get_str(settings
, "configs.%s.%s.proposal",
152 NULL
, config
, child
);
155 enumerator
= enumerator_create_token(token
, ",", " ");
156 while (enumerator
->enumerate(enumerator
, &token
))
158 proposal
= proposal_create_from_string(PROTO_ESP
, token
);
161 child_cfg
->add_proposal(child_cfg
, proposal
);
165 DBG1(DBG_CFG
, "parsing proposal '%s' failed, skipped", token
);
168 enumerator
->destroy(enumerator
);
172 child_cfg
->add_proposal(child_cfg
, proposal_create_default(PROTO_ESP
));
175 token
= settings
->get_str(settings
, "configs.%s.%s.lts", NULL
, config
);
178 enumerator
= enumerator_create_token(token
, ",", " ");
179 while (enumerator
->enumerate(enumerator
, &token
))
181 net
= host_create_from_subnet(token
, &bits
);
184 ts
= traffic_selector_create_from_subnet(net
, bits
, 0, 0);
185 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
189 DBG1(DBG_CFG
, "invalid local ts: %s, skipped", token
);
192 enumerator
->destroy(enumerator
);
196 ts
= traffic_selector_create_dynamic(0, 0, 65535);
197 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
200 token
= settings
->get_str(settings
, "configs.%s.%s.rts", NULL
, config
);
203 enumerator
= enumerator_create_token(token
, ",", " ");
204 while (enumerator
->enumerate(enumerator
, &token
))
206 net
= host_create_from_subnet(token
, &bits
);
209 ts
= traffic_selector_create_from_subnet(net
, bits
, 0, 0);
210 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
214 DBG1(DBG_CFG
, "invalid remote ts: %s, skipped", token
);
217 enumerator
->destroy(enumerator
);
221 ts
= traffic_selector_create_dynamic(0, 0, 65535);
222 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
228 * Load peer config for a given section name
230 static peer_cfg_t
*load_peer_config(private_config_t
*this,
231 settings_t
*settings
, char *config
)
234 peer_cfg_t
*peer_cfg
;
236 child_cfg_t
*child_cfg
;
237 enumerator_t
*enumerator
;
238 identification_t
*lid
, *rid
;
241 ike_cfg
= load_ike_config(this, settings
, config
);
242 peer_cfg
= peer_cfg_create(config
, 2, ike_cfg
, CERT_ALWAYS_SEND
,
243 UNIQUE_NO
, 1, 0, 0, 0, 0, TRUE
, 0,
244 NULL
, NULL
, FALSE
, NULL
, NULL
);
246 auth
= auth_cfg_create();
247 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
248 lid
= identification_create_from_string(
249 settings
->get_str(settings
, "configs.%s.lid", "%any", config
));
250 auth
->add(auth
, AUTH_RULE_IDENTITY
, lid
);
251 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
253 auth
= auth_cfg_create();
254 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
255 rid
= identification_create_from_string(
256 settings
->get_str(settings
, "configs.%s.rid", "%any", config
));
257 auth
->add(auth
, AUTH_RULE_IDENTITY
, rid
);
258 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, FALSE
);
260 DBG1(DBG_CFG
, "loaded config %s: %Y - %Y", config
, lid
, rid
);
262 enumerator
= settings
->create_section_enumerator(settings
,
263 "configs.%s", config
);
264 while (enumerator
->enumerate(enumerator
, &child
))
266 child_cfg
= load_child_config(this, settings
, config
, child
);
267 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
269 enumerator
->destroy(enumerator
);
273 METHOD(config_t
, load
, void,
274 private_config_t
*this, settings_t
*settings
)
276 enumerator_t
*enumerator
;
279 enumerator
= settings
->create_section_enumerator(settings
, "configs");
280 while (enumerator
->enumerate(enumerator
, &config
))
282 this->configs
->insert_last(this->configs
,
283 load_peer_config(this, settings
, config
));
285 enumerator
->destroy(enumerator
);
288 METHOD(config_t
, destroy
, void,
289 private_config_t
*this)
291 this->configs
->destroy_offset(this->configs
, offsetof(peer_cfg_t
, destroy
));
298 config_t
*config_create()
300 private_config_t
*this;
305 .create_ike_cfg_enumerator
= _create_ike_cfg_enumerator
,
306 .create_peer_cfg_enumerator
= _create_peer_cfg_enumerator
,
307 .get_peer_cfg_by_name
= _get_peer_cfg_by_name
,
312 .configs
= linked_list_create(),
315 return &this->public;