vici: Order auth rounds by optional round parameter instead of by position in the request
This commit is contained in:
@@ -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, ¤t))
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user