678 lines
17 KiB
C
678 lines
17 KiB
C
/*
|
|
* Copyright (C) 2006-2008 Martin Willi
|
|
* Copyright (C) 2010 Andreas Steffen
|
|
* HSR Hochschule fuer Technik Rapperswil
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "sql_config.h"
|
|
|
|
#include <daemon.h>
|
|
|
|
typedef struct private_sql_config_t private_sql_config_t;
|
|
|
|
/**
|
|
* Private data of an sql_config_t object
|
|
*/
|
|
struct private_sql_config_t {
|
|
|
|
/**
|
|
* Public part
|
|
*/
|
|
sql_config_t public;
|
|
|
|
/**
|
|
* database connection
|
|
*/
|
|
database_t *db;
|
|
};
|
|
|
|
/**
|
|
* Forward declaration
|
|
*/
|
|
static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
|
|
identification_t *me, identification_t *other);
|
|
|
|
/**
|
|
* Build a traffic selector from an SQL query
|
|
*/
|
|
static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
|
|
enumerator_t *e, bool *local)
|
|
{
|
|
int type, protocol, start_port, end_port;
|
|
chunk_t start_addr, end_addr;
|
|
traffic_selector_t *ts;
|
|
enum {
|
|
TS_LOCAL = 0,
|
|
TS_REMOTE = 1,
|
|
TS_LOCAL_DYNAMIC = 2,
|
|
TS_REMOTE_DYNAMIC = 3,
|
|
} kind;
|
|
|
|
while (e->enumerate(e, &kind, &type, &protocol,
|
|
&start_addr, &end_addr, &start_port, &end_port))
|
|
{
|
|
*local = FALSE;
|
|
switch (kind)
|
|
{
|
|
case TS_LOCAL:
|
|
*local = TRUE;
|
|
/* FALL */
|
|
case TS_REMOTE:
|
|
ts = traffic_selector_create_from_bytes(protocol, type,
|
|
start_addr, start_port, end_addr, end_port);
|
|
break;
|
|
case TS_LOCAL_DYNAMIC:
|
|
*local = TRUE;
|
|
/* FALL */
|
|
case TS_REMOTE_DYNAMIC:
|
|
ts = traffic_selector_create_dynamic(protocol,
|
|
start_port, end_port);
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
if (ts)
|
|
{
|
|
return ts;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Add traffic selectors to a child config
|
|
*/
|
|
static void add_traffic_selectors(private_sql_config_t *this,
|
|
child_cfg_t *child, int id)
|
|
{
|
|
enumerator_t *e;
|
|
traffic_selector_t *ts;
|
|
bool local;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT ct.kind, t.type, t.protocol, "
|
|
"t.start_addr, t.end_addr, t.start_port, t.end_port "
|
|
"FROM traffic_selectors AS t "
|
|
"JOIN child_config_traffic_selector AS ct "
|
|
"ON t.id = ct.traffic_selector WHERE ct.child_cfg = ?",
|
|
DB_INT, id,
|
|
DB_INT, DB_INT, DB_INT,
|
|
DB_BLOB, DB_BLOB, DB_INT, DB_INT);
|
|
if (e)
|
|
{
|
|
while ((ts = build_traffic_selector(this, e, &local)))
|
|
{
|
|
child->add_traffic_selector(child, local, ts);
|
|
}
|
|
e->destroy(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add ESP proposals to a child config
|
|
*/
|
|
static void add_esp_proposals(private_sql_config_t *this,
|
|
child_cfg_t *child, int id)
|
|
{
|
|
enumerator_t *e;
|
|
proposal_t *proposal;
|
|
char *prop;
|
|
bool use_default = TRUE;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT p.proposal "
|
|
"FROM proposals AS p JOIN child_config_proposal AS cp "
|
|
"ON p.id = cp.prop WHERE cp.child_cfg = ? ORDER BY cp.prio",
|
|
DB_INT, id, DB_TEXT);
|
|
if (e)
|
|
{
|
|
while (e->enumerate(e, &prop))
|
|
{
|
|
proposal = proposal_create_from_string(PROTO_ESP, prop);
|
|
if (!proposal)
|
|
{
|
|
DBG1(DBG_CFG, "could not create ESP proposal from '%s'", prop);
|
|
break;
|
|
}
|
|
child->add_proposal(child, proposal);
|
|
use_default = FALSE;
|
|
}
|
|
e->destroy(e);
|
|
}
|
|
if (use_default)
|
|
{
|
|
child->add_proposal(child, proposal_create_default_aead(PROTO_ESP));
|
|
child->add_proposal(child, proposal_create_default(PROTO_ESP));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a child config from an SQL query
|
|
*/
|
|
static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
|
|
{
|
|
int id, lifetime, rekeytime, jitter, hostaccess, mode, ipcomp, reqid;
|
|
int start, dpd, close;
|
|
char *name, *updown;
|
|
child_cfg_t *child_cfg;
|
|
|
|
if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, &updown,
|
|
&hostaccess, &mode, &start, &dpd, &close, &ipcomp, &reqid))
|
|
{
|
|
child_cfg_create_t child = {
|
|
.mode = mode,
|
|
.reqid = reqid,
|
|
.options = (ipcomp ? OPT_IPCOMP : 0) |
|
|
(hostaccess ? OPT_HOSTACCESS : 0),
|
|
.lifetime = {
|
|
.time = {
|
|
.life = lifetime, .rekey = rekeytime, .jitter = jitter
|
|
},
|
|
},
|
|
.start_action = start,
|
|
.dpd_action = dpd,
|
|
.close_action = close,
|
|
.updown = updown,
|
|
};
|
|
child_cfg = child_cfg_create(name, &child);
|
|
add_esp_proposals(this, child_cfg, id);
|
|
add_traffic_selectors(this, child_cfg, id);
|
|
return child_cfg;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Add child configs to peer config
|
|
*/
|
|
static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
|
|
{
|
|
enumerator_t *e;
|
|
child_cfg_t *child_cfg;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT c.id, c.name, c.lifetime, c.rekeytime, c.jitter, c.updown, "
|
|
"c.hostaccess, c.mode, c.start_action, c.dpd_action, "
|
|
"c.close_action, c.ipcomp, c.reqid "
|
|
"FROM child_configs AS c JOIN peer_config_child_config AS pc "
|
|
"ON c.id = pc.child_cfg WHERE pc.peer_cfg = ?",
|
|
DB_INT, id,
|
|
DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT, DB_TEXT, DB_INT,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
|
|
if (e)
|
|
{
|
|
while ((child_cfg = build_child_cfg(this, e)))
|
|
{
|
|
peer->add_child_cfg(peer, child_cfg);
|
|
}
|
|
e->destroy(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add IKE proposals to an IKE config
|
|
*/
|
|
static void add_ike_proposals(private_sql_config_t *this,
|
|
ike_cfg_t *ike_cfg, int id)
|
|
{
|
|
enumerator_t *e;
|
|
proposal_t *proposal;
|
|
char *prop;
|
|
bool use_default = TRUE;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT p.proposal "
|
|
"FROM proposals AS p "
|
|
"JOIN ike_config_proposal AS ip ON p.id = ip.prop "
|
|
"WHERE ip.ike_cfg = ? ORDER BY ip.prio",
|
|
DB_INT, id, DB_TEXT);
|
|
if (e)
|
|
{
|
|
while (e->enumerate(e, &prop))
|
|
{
|
|
proposal = proposal_create_from_string(PROTO_IKE, prop);
|
|
if (!proposal)
|
|
{
|
|
DBG1(DBG_CFG, "could not create IKE proposal from '%s'", prop);
|
|
break;
|
|
}
|
|
ike_cfg->add_proposal(ike_cfg, proposal);
|
|
use_default = FALSE;
|
|
}
|
|
e->destroy(e);
|
|
}
|
|
if (use_default)
|
|
{
|
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build an IKE config from an SQL query
|
|
*/
|
|
static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
|
|
host_t *my_host, host_t *other_host)
|
|
{
|
|
int id, certreq, force_encap;
|
|
char *local, *remote;
|
|
|
|
while (e->enumerate(e, &id, &certreq, &force_encap, &local, &remote))
|
|
{
|
|
ike_cfg_t *ike_cfg;
|
|
ike_cfg_create_t ike = {
|
|
.version = IKEV2,
|
|
.local = local,
|
|
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
|
.remote = remote,
|
|
.remote_port = IKEV2_UDP_PORT,
|
|
.no_certreq = !certreq,
|
|
.force_encap = force_encap,
|
|
.fragmentation = FRAGMENTATION_YES,
|
|
};
|
|
|
|
ike_cfg = ike_cfg_create(&ike);
|
|
add_ike_proposals(this, ike_cfg, id);
|
|
return ike_cfg;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Query an IKE config by its id
|
|
*/
|
|
static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
|
|
{
|
|
enumerator_t *e;
|
|
ike_cfg_t *ike_cfg = NULL;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT c.id, c.certreq, c.force_encap, c.local, c.remote "
|
|
"FROM ike_configs AS c WHERE c.id = ?",
|
|
DB_INT, id,
|
|
DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
|
|
if (e)
|
|
{
|
|
ike_cfg = build_ike_cfg(this, e, NULL, NULL);
|
|
e->destroy(e);
|
|
}
|
|
return ike_cfg;
|
|
}
|
|
|
|
#ifdef ME
|
|
/**
|
|
* Query a peer config by its id
|
|
*/
|
|
static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
|
|
{
|
|
enumerator_t *e;
|
|
peer_cfg_t *peer_cfg = NULL;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
|
|
"c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
|
|
"c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
|
|
"c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
|
|
"c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
|
|
"FROM peer_configs AS c "
|
|
"JOIN identities AS l ON c.local_id = l.id "
|
|
"JOIN identities AS r ON c.remote_id = r.id "
|
|
"LEFT JOIN identities AS p ON c.peer_id = p.id "
|
|
"WHERE c.id = ?",
|
|
DB_INT, id,
|
|
DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
|
|
DB_INT, DB_TEXT, DB_TEXT,
|
|
DB_INT, DB_INT, DB_INT, DB_BLOB);
|
|
if (e)
|
|
{
|
|
peer_cfg = build_peer_cfg(this, e, NULL, NULL);
|
|
e->destroy(e);
|
|
}
|
|
return peer_cfg;
|
|
}
|
|
#endif /* ME */
|
|
|
|
/**
|
|
* Check if the two IDs match (the first one is optional)
|
|
*/
|
|
static inline bool id_matches(identification_t *id, identification_t *sql_id)
|
|
{
|
|
return !id || id->matches(id, sql_id) || sql_id->matches(sql_id, id);
|
|
}
|
|
|
|
/**
|
|
* Build a peer config from an SQL query
|
|
*/
|
|
static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
|
|
identification_t *me, identification_t *other)
|
|
{
|
|
int id, ike_cfg, l_type, r_type,
|
|
cert_policy, uniqueid, auth_method, eap_type, eap_vendor, keyingtries,
|
|
rekeytime, reauthtime, jitter, overtime, mobike, dpd_delay,
|
|
mediation, mediated_by, p_type;
|
|
chunk_t l_data, r_data, p_data;
|
|
char *name, *virtual, *pool;
|
|
enumerator_t *enumerator;
|
|
|
|
while (e->enumerate(e,
|
|
&id, &name, &ike_cfg, &l_type, &l_data, &r_type, &r_data,
|
|
&cert_policy, &uniqueid, &auth_method, &eap_type, &eap_vendor,
|
|
&keyingtries, &rekeytime, &reauthtime, &jitter, &overtime, &mobike,
|
|
&dpd_delay, &virtual, &pool,
|
|
&mediation, &mediated_by, &p_type, &p_data))
|
|
{
|
|
identification_t *local_id, *remote_id, *peer_id = NULL;
|
|
peer_cfg_t *peer_cfg, *mediated_cfg = NULL;
|
|
ike_cfg_t *ike;
|
|
host_t *vip = NULL;
|
|
auth_cfg_t *auth;
|
|
|
|
local_id = identification_create_from_encoding(l_type, l_data);
|
|
remote_id = identification_create_from_encoding(r_type, r_data);
|
|
if (!id_matches(me, local_id) || !id_matches(other, remote_id))
|
|
{
|
|
local_id->destroy(local_id);
|
|
remote_id->destroy(remote_id);
|
|
continue;
|
|
}
|
|
ike = get_ike_cfg_by_id(this, ike_cfg);
|
|
|
|
#ifdef ME
|
|
mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by)
|
|
: NULL;
|
|
if (p_type)
|
|
{
|
|
peer_id = identification_create_from_encoding(p_type, p_data);
|
|
}
|
|
#endif /* ME */
|
|
|
|
if (virtual)
|
|
{
|
|
vip = host_create_from_string(virtual, 0);
|
|
}
|
|
if (ike)
|
|
{
|
|
peer_cfg_create_t peer = {
|
|
.cert_policy = cert_policy,
|
|
.unique = uniqueid,
|
|
.keyingtries = keyingtries,
|
|
.rekey_time = rekeytime,
|
|
.reauth_time = reauthtime,
|
|
.jitter_time = jitter,
|
|
.over_time = overtime,
|
|
.no_mobike = !mobike,
|
|
.dpd = dpd_delay,
|
|
#ifdef ME
|
|
.mediation = mediation,
|
|
.mediated_by = mediated_cfg ?
|
|
mediated_cfg->get_name(mediated_cfg) : NULL,
|
|
.peer_id = peer_id,
|
|
#endif /* ME */
|
|
};
|
|
|
|
peer_cfg = peer_cfg_create(name, ike, &peer);
|
|
if (vip)
|
|
{
|
|
peer_cfg->add_virtual_ip(peer_cfg, vip);
|
|
}
|
|
if (pool)
|
|
{
|
|
/* attr-sql used comma separated pools, but we now completely
|
|
* support multiple pools directly. Support old SQL configs: */
|
|
enumerator = enumerator_create_token(pool, ",", " ");
|
|
while (enumerator->enumerate(enumerator, &pool))
|
|
{
|
|
peer_cfg->add_pool(peer_cfg, pool);
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
}
|
|
auth = auth_cfg_create();
|
|
auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
|
|
auth->add(auth, AUTH_RULE_IDENTITY, local_id);
|
|
peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
|
|
auth = auth_cfg_create();
|
|
auth->add(auth, AUTH_RULE_IDENTITY, remote_id);
|
|
if (eap_type)
|
|
{
|
|
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
|
|
auth->add(auth, AUTH_RULE_EAP_TYPE, eap_type);
|
|
if (eap_vendor)
|
|
{
|
|
auth->add(auth, AUTH_RULE_EAP_VENDOR, eap_vendor);
|
|
}
|
|
}
|
|
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
|
|
add_child_cfgs(this, peer_cfg, id);
|
|
DESTROY_IF(mediated_cfg);
|
|
return peer_cfg;
|
|
}
|
|
DESTROY_IF(ike);
|
|
DESTROY_IF(mediated_cfg);
|
|
DESTROY_IF(peer_id);
|
|
DESTROY_IF(local_id);
|
|
DESTROY_IF(remote_id);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
|
|
private_sql_config_t *this, char *name)
|
|
{
|
|
enumerator_t *e;
|
|
peer_cfg_t *peer_cfg = NULL;
|
|
|
|
e = this->db->query(this->db,
|
|
"SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
|
|
"c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
|
|
"c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
|
|
"c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
|
|
"c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
|
|
"FROM peer_configs AS c "
|
|
"JOIN identities AS l ON c.local_id = l.id "
|
|
"JOIN identities AS r ON c.remote_id = r.id "
|
|
"LEFT JOIN identities AS p ON c.peer_id = p.id "
|
|
"WHERE c.ike_version = ? AND c.name = ?",
|
|
DB_INT, 2, DB_TEXT, name,
|
|
DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
|
|
DB_INT, DB_TEXT, DB_TEXT,
|
|
DB_INT, DB_INT, DB_INT, DB_BLOB);
|
|
if (e)
|
|
{
|
|
peer_cfg = build_peer_cfg(this, e, NULL, NULL);
|
|
e->destroy(e);
|
|
}
|
|
return peer_cfg;
|
|
}
|
|
|
|
typedef struct {
|
|
/** implements enumerator */
|
|
enumerator_t public;
|
|
/** reference to context */
|
|
private_sql_config_t *this;
|
|
/** filtering own host */
|
|
host_t *me;
|
|
/** filtering remote host */
|
|
host_t *other;
|
|
/** inner SQL enumerator */
|
|
enumerator_t *inner;
|
|
/** currently enumerated peer config */
|
|
ike_cfg_t *current;
|
|
} ike_enumerator_t;
|
|
|
|
METHOD(enumerator_t, ike_enumerator_enumerate, bool,
|
|
ike_enumerator_t *this, va_list args)
|
|
{
|
|
ike_cfg_t **cfg;
|
|
|
|
VA_ARGS_VGET(args, cfg);
|
|
DESTROY_IF(this->current);
|
|
this->current = build_ike_cfg(this->this, this->inner, this->me, this->other);
|
|
if (this->current)
|
|
{
|
|
*cfg = this->current;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
METHOD(enumerator_t, ike_enumerator_destroy, void,
|
|
ike_enumerator_t *this)
|
|
{
|
|
DESTROY_IF(this->current);
|
|
this->inner->destroy(this->inner);
|
|
free(this);
|
|
}
|
|
|
|
METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
|
|
private_sql_config_t *this, host_t *me, host_t *other)
|
|
{
|
|
ike_enumerator_t *e;
|
|
|
|
INIT(e,
|
|
.public = {
|
|
.enumerate = enumerator_enumerate_default,
|
|
.venumerate = _ike_enumerator_enumerate,
|
|
.destroy = _ike_enumerator_destroy,
|
|
},
|
|
.this = this,
|
|
.me = me,
|
|
.other = other,
|
|
);
|
|
e->inner = this->db->query(this->db,
|
|
"SELECT c.id, c.certreq, c.force_encap, "
|
|
"c.local, c.remote FROM ike_configs AS c",
|
|
DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
|
|
if (!e->inner)
|
|
{
|
|
free(e);
|
|
return NULL;
|
|
}
|
|
return &e->public;
|
|
}
|
|
|
|
|
|
typedef struct {
|
|
/** implements enumerator */
|
|
enumerator_t public;
|
|
/** reference to context */
|
|
private_sql_config_t *this;
|
|
/** filtering own identity */
|
|
identification_t *me;
|
|
/** filtering remote identity */
|
|
identification_t *other;
|
|
/** inner SQL enumerator */
|
|
enumerator_t *inner;
|
|
/** currently enumerated peer config */
|
|
peer_cfg_t *current;
|
|
} peer_enumerator_t;
|
|
|
|
METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
|
peer_enumerator_t *this, va_list args)
|
|
{
|
|
peer_cfg_t **cfg;
|
|
|
|
VA_ARGS_VGET(args, cfg);
|
|
DESTROY_IF(this->current);
|
|
this->current = build_peer_cfg(this->this, this->inner, this->me, this->other);
|
|
if (this->current)
|
|
{
|
|
*cfg = this->current;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
METHOD(enumerator_t, peer_enumerator_destroy, void,
|
|
peer_enumerator_t *this)
|
|
{
|
|
DESTROY_IF(this->current);
|
|
this->inner->destroy(this->inner);
|
|
free(this);
|
|
}
|
|
|
|
METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|
private_sql_config_t *this, identification_t *me, identification_t *other)
|
|
{
|
|
peer_enumerator_t *e;
|
|
|
|
INIT(e,
|
|
.public = {
|
|
.enumerate = enumerator_enumerate_default,
|
|
.venumerate = _peer_enumerator_enumerate,
|
|
.destroy = _peer_enumerator_destroy,
|
|
},
|
|
.this = this,
|
|
.me = me,
|
|
.other = other,
|
|
);
|
|
|
|
/* TODO: only get configs whose IDs match exactly or contain wildcards */
|
|
e->inner = this->db->query(this->db,
|
|
"SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
|
|
"c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
|
|
"c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
|
|
"c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
|
|
"c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
|
|
"FROM peer_configs AS c "
|
|
"JOIN identities AS l ON c.local_id = l.id "
|
|
"JOIN identities AS r ON c.remote_id = r.id "
|
|
"LEFT JOIN identities AS p ON c.peer_id = p.id "
|
|
"WHERE c.ike_version = ?",
|
|
DB_INT, 2,
|
|
DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
|
|
DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
|
|
DB_INT, DB_TEXT, DB_TEXT,
|
|
DB_INT, DB_INT, DB_INT, DB_BLOB);
|
|
if (!e->inner)
|
|
{
|
|
free(e);
|
|
return NULL;
|
|
}
|
|
return &e->public;
|
|
}
|
|
|
|
METHOD(sql_config_t, destroy, void,
|
|
private_sql_config_t *this)
|
|
{
|
|
free(this);
|
|
}
|
|
|
|
/**
|
|
* Described in header.
|
|
*/
|
|
sql_config_t *sql_config_create(database_t *db)
|
|
{
|
|
private_sql_config_t *this;
|
|
|
|
INIT(this,
|
|
.public = {
|
|
.backend = {
|
|
.create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
|
|
.create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
|
|
.get_peer_cfg_by_name = _get_peer_cfg_by_name,
|
|
},
|
|
.destroy = _destroy,
|
|
},
|
|
.db = db
|
|
);
|
|
|
|
return &this->public;
|
|
}
|