vici: Order auth rounds by optional round parameter instead of by position in the request

This commit is contained in:
Tobias Brunner
2016-03-08 10:04:55 +01:00
parent fab4c845ec
commit 229cdf6bc8
2 changed files with 74 additions and 40 deletions
+64 -40
View File
@@ -2,6 +2,7 @@
* Copyright (C) 2014 Martin Willi * Copyright (C) 2014 Martin Willi
* Copyright (C) 2014 revosec AG * Copyright (C) 2014 revosec AG
* *
* Copyright (C) 2015-2016 Tobias Brunner
* Copyright (C) 2015 Andreas Steffen * Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@@ -224,6 +225,24 @@ typedef struct {
vici_message_t *reply; vici_message_t *reply;
} request_data_t; } 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 * Data associated to a peer config
*/ */
@@ -318,7 +337,7 @@ static void log_auth(auth_cfg_t *auth)
static void log_peer_data(peer_data_t *data) static void log_peer_data(peer_data_t *data)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
auth_cfg_t *auth; auth_data_t *auth;
host_t *host; host_t *host;
DBG2(DBG_CFG, " version = %u", data->version); DBG2(DBG_CFG, " version = %u", data->version);
@@ -357,7 +376,7 @@ static void log_peer_data(peer_data_t *data)
while (enumerator->enumerate(enumerator, &auth)) while (enumerator->enumerate(enumerator, &auth))
{ {
DBG2(DBG_CFG, " local:"); DBG2(DBG_CFG, " local:");
log_auth(auth); log_auth(auth->cfg);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
@@ -365,7 +384,7 @@ static void log_peer_data(peer_data_t *data)
while (enumerator->enumerate(enumerator, &auth)) while (enumerator->enumerate(enumerator, &auth))
{ {
DBG2(DBG_CFG, " remote:"); DBG2(DBG_CFG, " remote:");
log_auth(auth); log_auth(auth->cfg);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
@@ -375,10 +394,8 @@ static void log_peer_data(peer_data_t *data)
*/ */
static void free_peer_data(peer_data_t *data) static void free_peer_data(peer_data_t *data)
{ {
data->local->destroy_offset(data->local, data->local->destroy_function(data->local, (void*)free_auth_data);
offsetof(auth_cfg_t, destroy)); data->remote->destroy_function(data->remote, (void*)free_auth_data);
data->remote->destroy_offset(data->remote,
offsetof(auth_cfg_t, destroy));
data->children->destroy_offset(data->children, data->children->destroy_offset(data->children,
offsetof(child_cfg_t, destroy)); offsetof(child_cfg_t, destroy));
data->proposals->destroy_offset(data->proposals, data->proposals->destroy_offset(data->proposals,
@@ -467,14 +484,6 @@ static void free_child_data(child_data_t *data)
free(data->updown); free(data->updown);
} }
/**
* Auth config data
*/
typedef struct {
request_data_t *request;
auth_cfg_t *cfg;
} auth_data_t;
/** /**
* Common proposal parsing * Common proposal parsing
*/ */
@@ -1344,6 +1353,7 @@ CALLBACK(auth_kv, bool,
{ "eap_id", parse_eap_id, auth->cfg }, { "eap_id", parse_eap_id, auth->cfg },
{ "xauth_id", parse_xauth_id, auth->cfg }, { "xauth_id", parse_xauth_id, auth->cfg },
{ "revocation", parse_revocation, auth->cfg }, { "revocation", parse_revocation, auth->cfg },
{ "round", parse_uint32, &auth->round },
}; };
return parse_rules(rules, countof(rules), name, value, return parse_rules(rules, countof(rules), name, value,
@@ -1547,25 +1557,28 @@ CALLBACK(peer_sn, bool,
if (strcasepfx(name, "local") || if (strcasepfx(name, "local") ||
strcasepfx(name, "remote")) strcasepfx(name, "remote"))
{ {
auth_data_t auth = { enumerator_t *enumerator;
.request = peer->request, linked_list_t *auths;
.cfg = auth_cfg_create(), auth_data_t *auth, *current;
};
auth_rule_t rule; auth_rule_t rule;
certificate_t *cert; certificate_t *cert;
pubkey_cert_t *pubkey_cert; pubkey_cert_t *pubkey_cert;
identification_t *id; identification_t *id;
enumerator_t *enumerator;
bool default_id = FALSE; 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; 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)) while (enumerator->enumerate(enumerator, &rule, &cert))
{ {
if (rule == AUTH_RULE_SUBJECT_CERT && !default_id) if (rule == AUTH_RULE_SUBJECT_CERT && !default_id)
@@ -1575,7 +1588,7 @@ CALLBACK(peer_sn, bool,
id = cert->get_subject(cert); id = cert->get_subject(cert);
DBG1(DBG_CFG, " id not specified, defaulting to" DBG1(DBG_CFG, " id not specified, defaulting to"
" cert subject '%Y'", id); " 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; default_id = TRUE;
} }
else if (cert->get_type(cert) == CERT_TRUSTED_PUBKEY && else if (cert->get_type(cert) == CERT_TRUSTED_PUBKEY &&
@@ -1589,14 +1602,17 @@ CALLBACK(peer_sn, bool,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (strcasepfx(name, "local")) auths = strcasepfx(name, "local") ? peer->local : peer->remote;
enumerator = auths->create_enumerator(auths);
while (enumerator->enumerate(enumerator, &current))
{ {
peer->local->insert_last(peer->local, auth.cfg); if (auth->round < current->round)
} {
else break;
{ }
peer->remote->insert_last(peer->remote, auth.cfg);
} }
auths->insert_before(auths, enumerator, auth);
enumerator->destroy(enumerator);
return TRUE; return TRUE;
} }
peer->request->reply = create_reply("invalid section: %s", name); peer->request->reply = create_reply("invalid section: %s", name);
@@ -1932,7 +1948,7 @@ CALLBACK(config_sn, bool,
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
ike_cfg_t *ike_cfg; ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg; child_cfg_t *child_cfg;
auth_cfg_t *auth_cfg; auth_data_t *auth;
proposal_t *proposal; proposal_t *proposal;
host_t *host; host_t *host;
char *str; char *str;
@@ -1947,13 +1963,17 @@ CALLBACK(config_sn, bool,
if (peer.local->get_count(peer.local) == 0) if (peer.local->get_count(peer.local) == 0)
{ {
auth_cfg = auth_cfg_create(); INIT(auth,
peer.local->insert_last(peer.local, auth_cfg); .cfg = auth_cfg_create(),
);
peer.local->insert_last(peer.local, auth);
} }
if (peer.remote->get_count(peer.remote) == 0) if (peer.remote->get_count(peer.remote) == 0)
{ {
auth_cfg = auth_cfg_create(); INIT(auth,
peer.remote->insert_last(peer.remote, auth_cfg); .cfg = auth_cfg_create(),
);
peer.remote->insert_last(peer.remote, auth);
} }
if (peer.proposals->get_count(peer.proposals) == 0) if (peer.proposals->get_count(peer.proposals) == 0)
{ {
@@ -2029,14 +2049,18 @@ CALLBACK(config_sn, bool,
FALSE, NULL, NULL); FALSE, NULL, NULL);
while (peer.local->remove_first(peer.local, 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, 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, while (peer.children->remove_first(peer.children,
(void**)&child_cfg) == SUCCESS) (void**)&child_cfg) == SUCCESS)
+10
View File
@@ -268,6 +268,11 @@ connections.<conn>.local<suffix> {}
unique suffix. To define a single authentication round, the suffix may be unique suffix. To define a single authentication round, the suffix may be
omitted. omitted.
connections.<conn>.local<suffix>.round = 0
Optional numeric identifier by which authentication rounds are sorted. If
not specified rounds are ordered by their position in the config file/VICI
message.
connections.<conn>.local<suffix>.certs = connections.<conn>.local<suffix>.certs =
Comma separated list of certificate candidates to use for authentication. Comma separated list of certificate candidates to use for authentication.
@@ -374,6 +379,11 @@ connections.<conn>.remote<suffix> {}
optional unique suffix. To define a single authentication round, the suffix optional unique suffix. To define a single authentication round, the suffix
may be omitted. may be omitted.
connections.<conn>.remote<suffix>.round = 0
Optional numeric identifier by which authentication rounds are sorted. If
not specified rounds are ordered by their position in the config file/VICI
message.
connections.<conn>.remote<suffix>.id = %any connections.<conn>.remote<suffix>.id = %any
IKE identity to expect for authentication round. IKE identity to expect for authentication round.