2 * Copyright (C) 2006-2008 Martin Willi
3 * Copyright (C) 2010 Andreas Steffen
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
19 #include "sql_config.h"
23 typedef struct private_sql_config_t private_sql_config_t
;
26 * Private data of an sql_config_t object
28 struct private_sql_config_t
{
44 static peer_cfg_t
*build_peer_cfg(private_sql_config_t
*this, enumerator_t
*e
,
45 identification_t
*me
, identification_t
*other
);
48 * Build a traffic selector from an SQL query
50 static traffic_selector_t
*build_traffic_selector(private_sql_config_t
*this,
51 enumerator_t
*e
, bool *local
)
53 int type
, protocol
, start_port
, end_port
;
54 chunk_t start_addr
, end_addr
;
55 traffic_selector_t
*ts
;
60 TS_REMOTE_DYNAMIC
= 3,
63 while (e
->enumerate(e
, &kind
, &type
, &protocol
,
64 &start_addr
, &end_addr
, &start_port
, &end_port
))
73 ts
= traffic_selector_create_from_bytes(protocol
, type
,
74 start_addr
, start_port
, end_addr
, end_port
);
76 case TS_LOCAL_DYNAMIC
:
79 case TS_REMOTE_DYNAMIC
:
80 ts
= traffic_selector_create_dynamic(protocol
,
81 start_port
, end_port
);
95 * Add traffic selectors to a child config
97 static void add_traffic_selectors(private_sql_config_t
*this,
98 child_cfg_t
*child
, int id
)
101 traffic_selector_t
*ts
;
104 e
= this->db
->query(this->db
,
105 "SELECT kind, type, protocol, "
106 "start_addr, end_addr, start_port, end_port "
107 "FROM traffic_selectors JOIN child_config_traffic_selector "
108 "ON id = traffic_selector WHERE child_cfg = ?",
110 DB_INT
, DB_INT
, DB_INT
,
111 DB_BLOB
, DB_BLOB
, DB_INT
, DB_INT
);
114 while ((ts
= build_traffic_selector(this, e
, &local
)))
116 child
->add_traffic_selector(child
, local
, ts
);
123 * Add ESP proposals to a child config
125 static void add_esp_proposals(private_sql_config_t
*this,
126 child_cfg_t
*child
, int id
)
129 proposal_t
*proposal
;
131 bool use_default
= TRUE
;
133 e
= this->db
->query(this->db
,
135 "FROM proposals JOIN child_config_proposal ON id = prop "
136 "WHERE child_cfg = ? ORDER BY prio",
137 DB_INT
, id
, DB_TEXT
);
140 while (e
->enumerate(e
, &prop
))
142 proposal
= proposal_create_from_string(PROTO_ESP
, prop
);
143 child
->add_proposal(child
, proposal
);
150 child
->add_proposal(child
, proposal_create_default(PROTO_ESP
));
155 * Build a child config from an SQL query
157 static child_cfg_t
*build_child_cfg(private_sql_config_t
*this, enumerator_t
*e
)
159 int id
, lifetime
, rekeytime
, jitter
, hostaccess
, mode
, ipcomp
;
160 int start
, dpd
, close
;
162 child_cfg_t
*child_cfg
;
164 if (e
->enumerate(e
, &id
, &name
, &lifetime
, &rekeytime
, &jitter
, &updown
,
165 &hostaccess
, &mode
, &start
, &dpd
, &close
, &ipcomp
))
167 lifetime_cfg_t lft
= {
168 .time
= { .life
= lifetime
, .rekey
= rekeytime
, .jitter
= jitter
}
170 child_cfg
= child_cfg_create(name
, &lft
, updown
, hostaccess
, mode
,
171 start
, dpd
, close
, ipcomp
, 0, 0, NULL
, NULL
);
172 add_esp_proposals(this, child_cfg
, id
);
173 add_traffic_selectors(this, child_cfg
, id
);
180 * Add child configs to peer config
182 static void add_child_cfgs(private_sql_config_t
*this, peer_cfg_t
*peer
, int id
)
185 child_cfg_t
*child_cfg
;
187 e
= this->db
->query(this->db
,
188 "SELECT id, name, lifetime, rekeytime, jitter, updown, "
189 "hostaccess, mode, start_action, dpd_action, close_action, ipcomp "
190 "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
191 "WHERE peer_cfg = ?",
193 DB_INT
, DB_TEXT
, DB_INT
, DB_INT
, DB_INT
, DB_TEXT
,
194 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
);
197 while ((child_cfg
= build_child_cfg(this, e
)))
199 peer
->add_child_cfg(peer
, child_cfg
);
206 * Add IKE proposals to an IKE config
208 static void add_ike_proposals(private_sql_config_t
*this,
209 ike_cfg_t
*ike_cfg
, int id
)
212 proposal_t
*proposal
;
214 bool use_default
= TRUE
;
216 e
= this->db
->query(this->db
,
218 "FROM proposals JOIN ike_config_proposal ON id = prop "
219 "WHERE ike_cfg = ? ORDER BY prio",
220 DB_INT
, id
, DB_TEXT
);
223 while (e
->enumerate(e
, &prop
))
225 proposal
= proposal_create_from_string(PROTO_IKE
, prop
);
226 ike_cfg
->add_proposal(ike_cfg
, proposal
);
233 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
238 * Build an IKE config from an SQL query
240 static ike_cfg_t
*build_ike_cfg(private_sql_config_t
*this, enumerator_t
*e
,
241 host_t
*my_host
, host_t
*other_host
)
243 int id
, certreq
, force_encap
;
244 char *local
, *remote
;
246 while (e
->enumerate(e
, &id
, &certreq
, &force_encap
, &local
, &remote
))
250 ike_cfg
= ike_cfg_create(certreq
, force_encap
,
251 local
, IKEV2_UDP_PORT
, remote
, IKEV2_UDP_PORT
);
252 add_ike_proposals(this, ike_cfg
, id
);
259 * Query an IKE config by its id
261 static ike_cfg_t
* get_ike_cfg_by_id(private_sql_config_t
*this, int id
)
264 ike_cfg_t
*ike_cfg
= NULL
;
266 e
= this->db
->query(this->db
,
267 "SELECT id, certreq, force_encap, local, remote "
268 "FROM ike_configs WHERE id = ?",
270 DB_INT
, DB_INT
, DB_INT
, DB_TEXT
, DB_TEXT
);
273 ike_cfg
= build_ike_cfg(this, e
, NULL
, NULL
);
280 * Query a peer config by its id
282 static peer_cfg_t
*get_peer_cfg_by_id(private_sql_config_t
*this, int id
)
285 peer_cfg_t
*peer_cfg
= NULL
;
287 e
= this->db
->query(this->db
,
288 "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
289 "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
290 "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
291 "dpd_delay, virtual, pool, "
292 "mediation, mediated_by, COALESCE(p.type, 0), p.data "
293 "FROM peer_configs AS c "
294 "JOIN identities AS l ON local_id = l.id "
295 "JOIN identities AS r ON remote_id = r.id "
296 "LEFT JOIN identities AS p ON peer_id = p.id "
299 DB_INT
, DB_TEXT
, DB_INT
, DB_INT
, DB_BLOB
, DB_INT
, DB_BLOB
,
300 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
301 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
302 DB_INT
, DB_TEXT
, DB_TEXT
,
303 DB_INT
, DB_INT
, DB_INT
, DB_BLOB
);
306 peer_cfg
= build_peer_cfg(this, e
, NULL
, NULL
);
313 * Build a peer config from an SQL query
315 static peer_cfg_t
*build_peer_cfg(private_sql_config_t
*this, enumerator_t
*e
,
316 identification_t
*me
, identification_t
*other
)
318 int id
, ike_cfg
, l_type
, r_type
,
319 cert_policy
, uniqueid
, auth_method
, eap_type
, eap_vendor
, keyingtries
,
320 rekeytime
, reauthtime
, jitter
, overtime
, mobike
, dpd_delay
,
321 mediation
, mediated_by
, p_type
;
322 chunk_t l_data
, r_data
, p_data
;
323 char *name
, *virtual, *pool
;
325 while (e
->enumerate(e
,
326 &id
, &name
, &ike_cfg
, &l_type
, &l_data
, &r_type
, &r_data
,
327 &cert_policy
, &uniqueid
, &auth_method
, &eap_type
, &eap_vendor
,
328 &keyingtries
, &rekeytime
, &reauthtime
, &jitter
, &overtime
, &mobike
,
329 &dpd_delay
, &virtual, &pool
,
330 &mediation
, &mediated_by
, &p_type
, &p_data
))
332 identification_t
*local_id
, *remote_id
, *peer_id
= NULL
;
333 peer_cfg_t
*peer_cfg
, *mediated_cfg
;
338 local_id
= identification_create_from_encoding(l_type
, l_data
);
339 remote_id
= identification_create_from_encoding(r_type
, r_data
);
340 if ((me
&& !me
->matches(me
, local_id
)) ||
341 (other
&& !other
->matches(other
, remote_id
)))
343 local_id
->destroy(local_id
);
344 remote_id
->destroy(remote_id
);
347 ike
= get_ike_cfg_by_id(this, ike_cfg
);
348 mediated_cfg
= mediated_by ?
get_peer_cfg_by_id(this, mediated_by
) : NULL
;
351 peer_id
= identification_create_from_encoding(p_type
, p_data
);
355 vip
= host_create_from_string(virtual, 0);
359 peer_cfg
= peer_cfg_create(
360 name
, 2, ike
, cert_policy
, uniqueid
,
361 keyingtries
, rekeytime
, reauthtime
, jitter
, overtime
,
362 mobike
, dpd_delay
, vip
, pool
,
363 mediation
, mediated_cfg
, peer_id
);
364 auth
= auth_cfg_create();
365 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, auth_method
);
366 auth
->add(auth
, AUTH_RULE_IDENTITY
, local_id
);
367 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
368 auth
= auth_cfg_create();
369 auth
->add(auth
, AUTH_RULE_IDENTITY
, remote_id
);
372 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
373 auth
->add(auth
, AUTH_RULE_EAP_TYPE
, eap_type
);
376 auth
->add(auth
, AUTH_RULE_EAP_VENDOR
, eap_vendor
);
379 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, FALSE
);
380 add_child_cfgs(this, peer_cfg
, id
);
384 DESTROY_IF(mediated_cfg
);
386 DESTROY_IF(local_id
);
387 DESTROY_IF(remote_id
);
393 * implements backend_t.get_peer_cfg_by_name.
395 static peer_cfg_t
*get_peer_cfg_by_name(private_sql_config_t
*this, char *name
)
398 peer_cfg_t
*peer_cfg
= NULL
;
400 e
= this->db
->query(this->db
,
401 "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
402 "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
403 "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
404 "dpd_delay, virtual, pool, "
405 "mediation, mediated_by, COALESCE(p.type, 0), p.data "
406 "FROM peer_configs AS c "
407 "JOIN identities AS l ON local_id = l.id "
408 "JOIN identities AS r ON remote_id = r.id "
409 "LEFT JOIN identities AS p ON peer_id = p.id "
410 "WHERE ike_version = ? AND name = ?",
411 DB_INT
, 2, DB_TEXT
, name
,
412 DB_INT
, DB_TEXT
, DB_INT
, DB_INT
, DB_BLOB
, DB_INT
, DB_BLOB
,
413 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
414 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
415 DB_INT
, DB_TEXT
, DB_TEXT
,
416 DB_INT
, DB_INT
, DB_INT
, DB_BLOB
);
419 peer_cfg
= build_peer_cfg(this, e
, NULL
, NULL
);
426 /** implements enumerator */
428 /** reference to context */
429 private_sql_config_t
*this;
430 /** filtering own host */
432 /** filtering remote host */
434 /** inner SQL enumerator */
436 /** currently enumerated peer config */
441 * Implementation of ike_enumerator_t.public.enumerate
443 static bool ike_enumerator_enumerate(ike_enumerator_t
*this, ike_cfg_t
**cfg
)
445 DESTROY_IF(this->current
);
446 this->current
= build_ike_cfg(this->this, this->inner
, this->me
, this->other
);
449 *cfg
= this->current
;
456 * Implementation of ike_enumerator_t.public.destroy
458 static void ike_enumerator_destroy(ike_enumerator_t
*this)
460 DESTROY_IF(this->current
);
461 this->inner
->destroy(this->inner
);
466 * Implementation of backend_t.create_ike_cfg_enumerator.
468 static enumerator_t
* create_ike_cfg_enumerator(private_sql_config_t
*this,
469 host_t
*me
, host_t
*other
)
471 ike_enumerator_t
*e
= malloc_thing(ike_enumerator_t
);
477 e
->public.enumerate
= (void*)ike_enumerator_enumerate
;
478 e
->public.destroy
= (void*)ike_enumerator_destroy
;
480 e
->inner
= this->db
->query(this->db
,
481 "SELECT id, certreq, force_encap, local, remote "
483 DB_INT
, DB_INT
, DB_INT
, DB_TEXT
, DB_TEXT
);
494 /** implements enumerator */
496 /** reference to context */
497 private_sql_config_t
*this;
498 /** filtering own identity */
499 identification_t
*me
;
500 /** filtering remote identity */
501 identification_t
*other
;
502 /** inner SQL enumerator */
504 /** currently enumerated peer config */
509 * Implementation of peer_enumerator_t.public.enumerate
511 static bool peer_enumerator_enumerate(peer_enumerator_t
*this, peer_cfg_t
**cfg
)
513 DESTROY_IF(this->current
);
514 this->current
= build_peer_cfg(this->this, this->inner
, this->me
, this->other
);
517 *cfg
= this->current
;
524 * Implementation of peer_enumerator_t.public.destroy
526 static void peer_enumerator_destroy(peer_enumerator_t
*this)
528 DESTROY_IF(this->current
);
529 this->inner
->destroy(this->inner
);
534 * Implementation of backend_t.create_peer_cfg_enumerator.
536 static enumerator_t
* create_peer_cfg_enumerator(private_sql_config_t
*this,
537 identification_t
*me
,
538 identification_t
*other
)
540 peer_enumerator_t
*e
= malloc_thing(peer_enumerator_t
);
546 e
->public.enumerate
= (void*)peer_enumerator_enumerate
;
547 e
->public.destroy
= (void*)peer_enumerator_destroy
;
549 /* TODO: only get configs whose IDs match exactly or contain wildcards */
550 e
->inner
= this->db
->query(this->db
,
551 "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
552 "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
553 "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
554 "dpd_delay, virtual, pool, "
555 "mediation, mediated_by, COALESCE(p.type, 0), p.data "
556 "FROM peer_configs AS c "
557 "JOIN identities AS l ON local_id = l.id "
558 "JOIN identities AS r ON remote_id = r.id "
559 "LEFT JOIN identities AS p ON peer_id = p.id "
560 "WHERE ike_version = ?",
562 DB_INT
, DB_TEXT
, DB_INT
, DB_INT
, DB_BLOB
, DB_INT
, DB_BLOB
,
563 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
564 DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
, DB_INT
,
565 DB_INT
, DB_TEXT
, DB_TEXT
,
566 DB_INT
, DB_INT
, DB_INT
, DB_BLOB
);
576 * Implementation of sql_config_t.destroy.
578 static void destroy(private_sql_config_t
*this)
584 * Described in header.
586 sql_config_t
*sql_config_create(database_t
*db
)
588 private_sql_config_t
*this = malloc_thing(private_sql_config_t
);
590 this->public.backend
.create_peer_cfg_enumerator
= (enumerator_t
*(*)(backend_t
*, identification_t
*me
, identification_t
*other
))create_peer_cfg_enumerator
;
591 this->public.backend
.create_ike_cfg_enumerator
= (enumerator_t
*(*)(backend_t
*, host_t
*me
, host_t
*other
))create_ike_cfg_enumerator
;
592 this->public.backend
.get_peer_cfg_by_name
= (peer_cfg_t
* (*)(backend_t
*,char*))get_peer_cfg_by_name
;
593 this->public.destroy
= (void(*)(sql_config_t
*))destroy
;
597 return &this->public;