* Copyright (C) 2014 Martin Willi
* Copyright (C) 2014 revosec AG
*
+ * Copyright (C) 2015-2016 Tobias Brunner
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
vici_message_t *reply;
} request_data_t;
+/**
+ * Auth config data
+ */
+typedef struct {
+ request_data_t *request;
+ auth_cfg_t *cfg;
+ u_int32_t round;
+} auth_data_t;
+
+/**
+ * Clean up auth config data
+ */
+static void free_auth_data(auth_data_t *data)
+{
+ DESTROY_IF(data->cfg);
+ free(data);
+}
+
/**
* Data associated to a peer config
*/
static void log_peer_data(peer_data_t *data)
{
enumerator_t *enumerator;
- auth_cfg_t *auth;
+ auth_data_t *auth;
host_t *host;
DBG2(DBG_CFG, " version = %u", data->version);
while (enumerator->enumerate(enumerator, &auth))
{
DBG2(DBG_CFG, " local:");
- log_auth(auth);
+ log_auth(auth->cfg);
}
enumerator->destroy(enumerator);
while (enumerator->enumerate(enumerator, &auth))
{
DBG2(DBG_CFG, " remote:");
- log_auth(auth);
+ log_auth(auth->cfg);
}
enumerator->destroy(enumerator);
}
*/
static void free_peer_data(peer_data_t *data)
{
- data->local->destroy_offset(data->local,
- offsetof(auth_cfg_t, destroy));
- data->remote->destroy_offset(data->remote,
- offsetof(auth_cfg_t, destroy));
+ data->local->destroy_function(data->local, (void*)free_auth_data);
+ data->remote->destroy_function(data->remote, (void*)free_auth_data);
data->children->destroy_offset(data->children,
offsetof(child_cfg_t, destroy));
data->proposals->destroy_offset(data->proposals,
free(data->updown);
}
-/**
- * Auth config data
- */
-typedef struct {
- request_data_t *request;
- auth_cfg_t *cfg;
-} auth_data_t;
-
/**
* Common proposal parsing
*/
{ "eap_id", parse_eap_id, auth->cfg },
{ "xauth_id", parse_xauth_id, auth->cfg },
{ "revocation", parse_revocation, auth->cfg },
+ { "round", parse_uint32, &auth->round },
};
return parse_rules(rules, countof(rules), name, value,
if (strcasepfx(name, "local") ||
strcasepfx(name, "remote"))
{
- auth_data_t auth = {
- .request = peer->request,
- .cfg = auth_cfg_create(),
- };
+ enumerator_t *enumerator;
+ linked_list_t *auths;
+ auth_data_t *auth, *current;
auth_rule_t rule;
certificate_t *cert;
pubkey_cert_t *pubkey_cert;
identification_t *id;
- enumerator_t *enumerator;
bool default_id = FALSE;
- if (!message->parse(message, ctx, NULL, auth_kv, auth_li, &auth))
+ INIT(auth,
+ .request = peer->request,
+ .cfg = auth_cfg_create(),
+ );
+
+ if (!message->parse(message, ctx, NULL, auth_kv, auth_li, auth))
{
- auth.cfg->destroy(auth.cfg);
+ free_auth_data(auth);
return FALSE;
}
- id = auth.cfg->get(auth.cfg, AUTH_RULE_IDENTITY);
+ id = auth->cfg->get(auth->cfg, AUTH_RULE_IDENTITY);
- enumerator = auth.cfg->create_enumerator(auth.cfg);
+ enumerator = auth->cfg->create_enumerator(auth->cfg);
while (enumerator->enumerate(enumerator, &rule, &cert))
{
if (rule == AUTH_RULE_SUBJECT_CERT && !default_id)
id = cert->get_subject(cert);
DBG1(DBG_CFG, " id not specified, defaulting to"
" cert subject '%Y'", id);
- auth.cfg->add(auth.cfg, AUTH_RULE_IDENTITY, id->clone(id));
+ auth->cfg->add(auth->cfg, AUTH_RULE_IDENTITY, id->clone(id));
default_id = TRUE;
}
else if (cert->get_type(cert) == CERT_TRUSTED_PUBKEY &&
}
enumerator->destroy(enumerator);
- if (strcasepfx(name, "local"))
+ auths = strcasepfx(name, "local") ? peer->local : peer->remote;
+ enumerator = auths->create_enumerator(auths);
+ while (enumerator->enumerate(enumerator, ¤t))
{
- peer->local->insert_last(peer->local, auth.cfg);
- }
- else
- {
- peer->remote->insert_last(peer->remote, auth.cfg);
+ if (auth->round < current->round)
+ {
+ break;
+ }
}
+ auths->insert_before(auths, enumerator, auth);
+ enumerator->destroy(enumerator);
return TRUE;
}
peer->request->reply = create_reply("invalid section: %s", name);
peer_cfg_t *peer_cfg;
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
- auth_cfg_t *auth_cfg;
+ auth_data_t *auth;
proposal_t *proposal;
host_t *host;
char *str;
if (peer.local->get_count(peer.local) == 0)
{
- auth_cfg = auth_cfg_create();
- peer.local->insert_last(peer.local, auth_cfg);
+ INIT(auth,
+ .cfg = auth_cfg_create(),
+ );
+ peer.local->insert_last(peer.local, auth);
}
if (peer.remote->get_count(peer.remote) == 0)
{
- auth_cfg = auth_cfg_create();
- peer.remote->insert_last(peer.remote, auth_cfg);
+ INIT(auth,
+ .cfg = auth_cfg_create(),
+ );
+ peer.remote->insert_last(peer.remote, auth);
}
if (peer.proposals->get_count(peer.proposals) == 0)
{
FALSE, NULL, NULL);
while (peer.local->remove_first(peer.local,
- (void**)&auth_cfg) == SUCCESS)
+ (void**)&auth) == SUCCESS)
{
- peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
+ peer_cfg->add_auth_cfg(peer_cfg, auth->cfg, TRUE);
+ auth->cfg = NULL;
+ free_auth_data(auth);
}
while (peer.remote->remove_first(peer.remote,
- (void**)&auth_cfg) == SUCCESS)
+ (void**)&auth) == SUCCESS)
{
- peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
+ peer_cfg->add_auth_cfg(peer_cfg, auth->cfg, FALSE);
+ auth->cfg = NULL;
+ free_auth_data(auth);
}
while (peer.children->remove_first(peer.children,
(void**)&child_cfg) == SUCCESS)