]>
Commit | Line | Data |
---|---|---|
0fd6e955 MW |
1 | /* |
2 | * Copyright (C) 2008 Martin Willi | |
3 | * Hochschule fuer Technik Rapperswil | |
4 | * | |
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>. | |
9 | * | |
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 | |
13 | * for more details. | |
0fd6e955 MW |
14 | */ |
15 | ||
16 | #include "load_tester_config.h" | |
17 | ||
18 | #include <daemon.h> | |
19 | ||
20 | typedef struct private_load_tester_config_t private_load_tester_config_t; | |
21 | ||
22 | /** | |
23 | * Private data of an load_tester_config_t object | |
24 | */ | |
25 | struct private_load_tester_config_t { | |
26 | ||
27 | /** | |
28 | * Public part | |
29 | */ | |
30 | load_tester_config_t public; | |
7daf5226 | 31 | |
0fd6e955 MW |
32 | /** |
33 | * peer config | |
34 | */ | |
35 | peer_cfg_t *peer_cfg; | |
7daf5226 | 36 | |
5bdc8fc7 MW |
37 | /** |
38 | * virtual IP, if any | |
39 | */ | |
40 | host_t *vip; | |
7daf5226 | 41 | |
5bdc8fc7 MW |
42 | /** |
43 | * Remote address | |
44 | */ | |
45 | char *remote; | |
7daf5226 | 46 | |
d4078ca7 MW |
47 | /** |
48 | * Local address | |
49 | */ | |
50 | char *local; | |
51 | ||
5bdc8fc7 MW |
52 | /** |
53 | * IP address pool | |
54 | */ | |
55 | char *pool; | |
7daf5226 | 56 | |
5bdc8fc7 | 57 | /** |
7b3814f7 MW |
58 | * IKE proposal |
59 | */ | |
5bdc8fc7 | 60 | proposal_t *proposal; |
7daf5226 | 61 | |
5bdc8fc7 | 62 | /** |
a44bb934 | 63 | * Authentication method(s) to use/expect from initiator |
5bdc8fc7 | 64 | */ |
a44bb934 | 65 | char *initiator_auth; |
7daf5226 | 66 | |
a44bb934 MW |
67 | /** |
68 | * Authentication method(s) use/expected from responder | |
69 | */ | |
70 | char *responder_auth; | |
7daf5226 | 71 | |
ac96ca80 MW |
72 | /** |
73 | * Initiator ID to enforce | |
74 | */ | |
75 | char *initiator_id; | |
76 | ||
77 | /** | |
78 | * Responder ID to enforce | |
79 | */ | |
80 | char *responder_id; | |
81 | ||
c04e7548 MW |
82 | /** |
83 | * IKE_SA rekeying delay | |
84 | */ | |
85 | u_int ike_rekey; | |
7daf5226 | 86 | |
c04e7548 MW |
87 | /** |
88 | * CHILD_SA rekeying delay | |
89 | */ | |
90 | u_int child_rekey; | |
7daf5226 | 91 | |
0b04bdde MW |
92 | /** |
93 | * DPD check delay | |
94 | */ | |
95 | u_int dpd_delay; | |
96 | ||
80c5b17d AS |
97 | /** |
98 | * DPD timeout (IKEv1 only) | |
99 | */ | |
100 | u_int dpd_timeout; | |
101 | ||
5bdc8fc7 MW |
102 | /** |
103 | * incremental numbering of generated configs | |
104 | */ | |
105 | u_int num; | |
f16ca9e8 MW |
106 | |
107 | /** | |
108 | * Dynamic source port, if used | |
109 | */ | |
110 | u_int16_t port; | |
0fd6e955 MW |
111 | }; |
112 | ||
a44bb934 MW |
113 | /** |
114 | * Generate auth config from string | |
115 | */ | |
116 | static void generate_auth_cfg(private_load_tester_config_t *this, char *str, | |
117 | peer_cfg_t *peer_cfg, bool local, int num) | |
118 | { | |
119 | enumerator_t *enumerator; | |
120 | auth_cfg_t *auth; | |
121 | identification_t *id; | |
122 | auth_class_t class; | |
123 | eap_type_t type; | |
124 | char buf[128]; | |
125 | int rnd = 0; | |
7daf5226 | 126 | |
a44bb934 MW |
127 | enumerator = enumerator_create_token(str, "|", " "); |
128 | while (enumerator->enumerate(enumerator, &str)) | |
129 | { | |
ac96ca80 | 130 | id = NULL; |
a44bb934 MW |
131 | auth = auth_cfg_create(); |
132 | rnd++; | |
7daf5226 | 133 | |
ac96ca80 MW |
134 | if (this->initiator_id) |
135 | { | |
136 | if ((local && num) || (!local && !num)) | |
a44bb934 | 137 | { |
ac96ca80 MW |
138 | snprintf(buf, sizeof(buf), this->initiator_id, num, rnd); |
139 | id = identification_create_from_string(buf); | |
a44bb934 | 140 | } |
ac96ca80 MW |
141 | } |
142 | if (this->responder_id) | |
143 | { | |
144 | if ((local && !num) || (!local && num)) | |
a44bb934 | 145 | { |
ac96ca80 | 146 | snprintf(buf, sizeof(buf), this->responder_id, num, rnd); |
a44bb934 MW |
147 | id = identification_create_from_string(buf); |
148 | } | |
ac96ca80 MW |
149 | } |
150 | ||
151 | if (streq(str, "psk")) | |
152 | { /* PSK authentication, use FQDNs */ | |
153 | class = AUTH_CLASS_PSK; | |
154 | if (!id) | |
a44bb934 | 155 | { |
ac96ca80 MW |
156 | if ((local && !num) || (!local && num)) |
157 | { | |
158 | id = identification_create_from_string("srv.strongswan.org"); | |
159 | } | |
160 | else if (local) | |
161 | { | |
162 | snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org", | |
163 | num, rnd); | |
164 | id = identification_create_from_string(buf); | |
165 | } | |
166 | else | |
167 | { | |
168 | id = identification_create_from_string("*.strongswan.org"); | |
169 | } | |
a44bb934 MW |
170 | } |
171 | } | |
172 | else if (strneq(str, "eap", strlen("eap"))) | |
173 | { /* EAP authentication, use a NAI */ | |
174 | class = AUTH_CLASS_EAP; | |
175 | if (*(str + strlen("eap")) == '-') | |
176 | { | |
177 | type = eap_type_from_string(str + strlen("eap-")); | |
178 | if (type) | |
179 | { | |
180 | auth->add(auth, AUTH_RULE_EAP_TYPE, type); | |
181 | } | |
182 | } | |
ac96ca80 | 183 | if (!id) |
a44bb934 | 184 | { |
ac96ca80 MW |
185 | if (local && num) |
186 | { | |
187 | snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org", | |
188 | num, rnd); | |
189 | id = identification_create_from_string(buf); | |
190 | } | |
191 | else | |
192 | { | |
193 | id = identification_create_from_encoding(ID_ANY, chunk_empty); | |
194 | } | |
a44bb934 MW |
195 | } |
196 | } | |
197 | else | |
198 | { | |
199 | if (!streq(str, "pubkey")) | |
200 | { | |
201 | DBG1(DBG_CFG, "invalid authentication: '%s', fallback to pubkey", | |
202 | str); | |
203 | } | |
204 | /* certificate authentication, use distinguished names */ | |
205 | class = AUTH_CLASS_PUBKEY; | |
ac96ca80 | 206 | if (!id) |
a44bb934 | 207 | { |
ac96ca80 MW |
208 | if ((local && !num) || (!local && num)) |
209 | { | |
210 | id = identification_create_from_string( | |
211 | "CN=srv, OU=load-test, O=strongSwan"); | |
212 | } | |
213 | else if (local) | |
214 | { | |
215 | snprintf(buf, sizeof(buf), | |
216 | "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd); | |
217 | id = identification_create_from_string(buf); | |
218 | } | |
219 | else | |
220 | { | |
221 | id = identification_create_from_string( | |
222 | "CN=*, OU=load-test, O=strongSwan"); | |
223 | } | |
a44bb934 MW |
224 | } |
225 | } | |
226 | auth->add(auth, AUTH_RULE_AUTH_CLASS, class); | |
227 | auth->add(auth, AUTH_RULE_IDENTITY, id); | |
228 | peer_cfg->add_auth_cfg(peer_cfg, auth, local); | |
229 | } | |
230 | enumerator->destroy(enumerator); | |
231 | } | |
232 | ||
5bdc8fc7 MW |
233 | /** |
234 | * Generate a new initiator config, num = 0 for responder config | |
235 | */ | |
236 | static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num) | |
237 | { | |
238 | ike_cfg_t *ike_cfg; | |
239 | child_cfg_t *child_cfg; | |
240 | peer_cfg_t *peer_cfg; | |
241 | traffic_selector_t *ts; | |
5bdc8fc7 | 242 | proposal_t *proposal; |
e75f4237 TB |
243 | lifetime_cfg_t lifetime = { |
244 | .time = { | |
245 | .life = this->child_rekey * 2, | |
246 | .rekey = this->child_rekey, | |
247 | .jitter = 0 | |
248 | } | |
249 | }; | |
7daf5226 | 250 | |
f16ca9e8 MW |
251 | if (this->port && num) |
252 | { | |
253 | ike_cfg = ike_cfg_create(FALSE, FALSE, | |
1d315bdd AS |
254 | this->local, FALSE, this->port + num - 1, |
255 | this->remote, FALSE, IKEV2_NATT_PORT); | |
f16ca9e8 MW |
256 | } |
257 | else | |
258 | { | |
259 | ike_cfg = ike_cfg_create(FALSE, FALSE, | |
b223d517 | 260 | this->local, FALSE, charon->socket->get_port(charon->socket, FALSE), |
1d315bdd | 261 | this->remote, FALSE, IKEV2_UDP_PORT); |
f16ca9e8 | 262 | } |
5bdc8fc7 | 263 | ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal)); |
f7a8fced | 264 | peer_cfg = peer_cfg_create("load-test", IKEV2, ike_cfg, |
c04e7548 MW |
265 | CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */ |
266 | this->ike_rekey, 0, /* rekey, reauth */ | |
267 | 0, this->ike_rekey, /* jitter, overtime */ | |
5ce59d4c | 268 | FALSE, FALSE, /* mobike, aggressive mode */ |
80c5b17d AS |
269 | this->dpd_delay, /* dpd_delay */ |
270 | this->dpd_timeout, /* dpd_timeout */ | |
c04e7548 MW |
271 | this->vip ? this->vip->clone(this->vip) : NULL, |
272 | this->pool, FALSE, NULL, NULL); | |
a44bb934 MW |
273 | if (num) |
274 | { /* initiator */ | |
275 | generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num); | |
276 | generate_auth_cfg(this, this->responder_auth, peer_cfg, FALSE, num); | |
277 | } | |
278 | else | |
279 | { /* responder */ | |
280 | generate_auth_cfg(this, this->responder_auth, peer_cfg, TRUE, num); | |
281 | generate_auth_cfg(this, this->initiator_auth, peer_cfg, FALSE, num); | |
282 | } | |
7daf5226 | 283 | |
26c4d010 | 284 | child_cfg = child_cfg_create("load-test", &lifetime, NULL, TRUE, MODE_TUNNEL, |
c616d84c | 285 | ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE, |
37788b1d | 286 | 0, 0, NULL, NULL, 0); |
5bdc8fc7 MW |
287 | proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1"); |
288 | child_cfg->add_proposal(child_cfg, proposal); | |
b81d8cd3 | 289 | ts = traffic_selector_create_dynamic(0, 0, 65535); |
5bdc8fc7 | 290 | child_cfg->add_traffic_selector(child_cfg, TRUE, ts); |
b81d8cd3 | 291 | ts = traffic_selector_create_dynamic(0, 0, 65535); |
5bdc8fc7 MW |
292 | child_cfg->add_traffic_selector(child_cfg, FALSE, ts); |
293 | peer_cfg->add_child_cfg(peer_cfg, child_cfg); | |
294 | return peer_cfg; | |
295 | } | |
296 | ||
187bf24e MW |
297 | METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, |
298 | private_load_tester_config_t *this, | |
299 | identification_t *me, identification_t *other) | |
0fd6e955 MW |
300 | { |
301 | return enumerator_create_single(this->peer_cfg, NULL); | |
302 | } | |
303 | ||
187bf24e MW |
304 | METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, |
305 | private_load_tester_config_t *this, host_t *me, host_t *other) | |
0fd6e955 MW |
306 | { |
307 | ike_cfg_t *ike_cfg; | |
308 | ||
309 | ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg); | |
310 | return enumerator_create_single(ike_cfg, NULL); | |
311 | } | |
312 | ||
187bf24e MW |
313 | METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, |
314 | private_load_tester_config_t *this, char *name) | |
0fd6e955 | 315 | { |
a9f081e5 MW |
316 | if (streq(name, "load-test")) |
317 | { | |
5bdc8fc7 | 318 | return generate_config(this, this->num++); |
a9f081e5 MW |
319 | } |
320 | return NULL; | |
0fd6e955 MW |
321 | } |
322 | ||
187bf24e MW |
323 | METHOD(load_tester_config_t, destroy, void, |
324 | private_load_tester_config_t *this) | |
0fd6e955 MW |
325 | { |
326 | this->peer_cfg->destroy(this->peer_cfg); | |
5bdc8fc7 MW |
327 | DESTROY_IF(this->proposal); |
328 | DESTROY_IF(this->vip); | |
0fd6e955 MW |
329 | free(this); |
330 | } | |
331 | ||
332 | /** | |
333 | * Described in header. | |
334 | */ | |
335 | load_tester_config_t *load_tester_config_create() | |
336 | { | |
187bf24e MW |
337 | private_load_tester_config_t *this; |
338 | ||
339 | INIT(this, | |
340 | .public = { | |
341 | .backend = { | |
342 | .create_peer_cfg_enumerator = _create_peer_cfg_enumerator, | |
343 | .create_ike_cfg_enumerator = _create_ike_cfg_enumerator, | |
344 | .get_peer_cfg_by_name = _get_peer_cfg_by_name, | |
345 | }, | |
346 | .destroy = _destroy, | |
347 | }, | |
348 | .num = 1, | |
349 | ); | |
7daf5226 | 350 | |
6a8ecfc8 | 351 | if (lib->settings->get_bool(lib->settings, |
42500c27 | 352 | "%s.plugins.load-tester.request_virtual_ip", FALSE, charon->name)) |
6a8ecfc8 | 353 | { |
5bdc8fc7 | 354 | this->vip = host_create_from_string("0.0.0.0", 0); |
6a8ecfc8 | 355 | } |
5b0bcfb1 | 356 | this->pool = lib->settings->get_str(lib->settings, |
42500c27 | 357 | "%s.plugins.load-tester.pool", NULL, charon->name); |
5b0bcfb1 | 358 | this->remote = lib->settings->get_str(lib->settings, |
42500c27 | 359 | "%s.plugins.load-tester.remote", "127.0.0.1", charon->name); |
d4078ca7 MW |
360 | this->local = lib->settings->get_str(lib->settings, |
361 | "%s.plugins.load-tester.local", "0.0.0.0", charon->name); | |
7daf5226 | 362 | |
5bdc8fc7 | 363 | this->proposal = proposal_create_from_string(PROTO_IKE, |
42500c27 TB |
364 | lib->settings->get_str(lib->settings, |
365 | "%s.plugins.load-tester.proposal", "aes128-sha1-modp768", | |
366 | charon->name)); | |
5bdc8fc7 | 367 | if (!this->proposal) |
0fd6e955 | 368 | { /* fallback */ |
5bdc8fc7 MW |
369 | this->proposal = proposal_create_from_string(PROTO_IKE, |
370 | "aes128-sha1-modp768"); | |
0fd6e955 | 371 | } |
c04e7548 | 372 | this->ike_rekey = lib->settings->get_int(lib->settings, |
42500c27 | 373 | "%s.plugins.load-tester.ike_rekey", 0, charon->name); |
c04e7548 | 374 | this->child_rekey = lib->settings->get_int(lib->settings, |
42500c27 | 375 | "%s.plugins.load-tester.child_rekey", 600, charon->name); |
0b04bdde | 376 | this->dpd_delay = lib->settings->get_int(lib->settings, |
42500c27 | 377 | "%s.plugins.load-tester.dpd_delay", 0, charon->name); |
80c5b17d AS |
378 | this->dpd_timeout = lib->settings->get_int(lib->settings, |
379 | "%s.plugins.load-tester.dpd_timeout", 0, charon->name); | |
7daf5226 | 380 | |
5b0bcfb1 | 381 | this->initiator_auth = lib->settings->get_str(lib->settings, |
42500c27 | 382 | "%s.plugins.load-tester.initiator_auth", "pubkey", charon->name); |
5b0bcfb1 | 383 | this->responder_auth = lib->settings->get_str(lib->settings, |
42500c27 | 384 | "%s.plugins.load-tester.responder_auth", "pubkey", charon->name); |
ac96ca80 | 385 | this->initiator_id = lib->settings->get_str(lib->settings, |
42500c27 | 386 | "%s.plugins.load-tester.initiator_id", NULL, charon->name); |
ac96ca80 | 387 | this->responder_id = lib->settings->get_str(lib->settings, |
42500c27 | 388 | "%s.plugins.load-tester.responder_id", NULL, charon->name); |
7daf5226 | 389 | |
f16ca9e8 | 390 | this->port = lib->settings->get_int(lib->settings, |
42500c27 | 391 | "%s.plugins.load-tester.dynamic_port", 0, charon->name); |
f16ca9e8 | 392 | |
5bdc8fc7 | 393 | this->peer_cfg = generate_config(this, 0); |
7daf5226 | 394 | |
0fd6e955 MW |
395 | return &this->public; |
396 | } | |
397 |