Handle initiation of not supported IKE versions properly

This commit is contained in:
Martin Willi
2012-03-20 17:31:30 +01:00
parent daee47ba46
commit 3d54ae94d9
9 changed files with 111 additions and 47 deletions
+11
View File
@@ -217,6 +217,17 @@ METHOD(job_t, initiate_execute, void,
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
peer_cfg); peer_cfg);
if (!ike_sa)
{
listener->child_cfg->destroy(listener->child_cfg);
peer_cfg->destroy(peer_cfg);
/* trigger down event to release listener */
listener->ike_sa = charon->ike_sa_manager->checkout_new(
charon->ike_sa_manager, IKE_ANY, TRUE);
DESTROY_IF(listener->ike_sa);
listener->status = FAILED;
return;
}
listener->ike_sa = ike_sa; listener->ike_sa = ike_sa;
if (ike_sa->get_peer_cfg(ike_sa) == NULL) if (ike_sa->get_peer_cfg(ike_sa) == NULL)
@@ -300,12 +300,17 @@ static job_requeue_t initiate(private_android_service_t *this)
0, "255.255.255.255", 65535); 0, "255.255.255.255", 65535);
child_cfg->add_traffic_selector(child_cfg, FALSE, ts); child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
peer_cfg->add_child_cfg(peer_cfg, child_cfg); peer_cfg->add_child_cfg(peer_cfg, child_cfg);
/* get an additional reference because initiate consumes one */
child_cfg->get_ref(child_cfg);
/* get us an IKE_SA */ /* get us an IKE_SA */
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
peer_cfg); peer_cfg);
if (!ike_sa)
{
peer_cfg->destroy(peer_cfg);
send_status(this, VPN_ERROR_CONNECTION_FAILED);
return JOB_REQUEUE_NONE;
}
if (!ike_sa->get_peer_cfg(ike_sa)) if (!ike_sa->get_peer_cfg(ike_sa))
{ {
ike_sa->set_peer_cfg(ike_sa, peer_cfg); ike_sa->set_peer_cfg(ike_sa, peer_cfg);
@@ -318,6 +323,8 @@ static job_requeue_t initiate(private_android_service_t *this)
/* confirm that we received the request */ /* confirm that we received the request */
send_status(this, i); send_status(this, i);
/* get an additional reference because initiate consumes one */
child_cfg->get_ref(child_cfg);
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
{ {
DBG1(DBG_CFG, "failed to initiate tunnel"); DBG1(DBG_CFG, "failed to initiate tunnel");
+8 -2
View File
@@ -355,12 +355,16 @@ static gboolean initiate_connection(private_maemo_service_t *this,
0, "255.255.255.255", 65535); 0, "255.255.255.255", 65535);
child_cfg->add_traffic_selector(child_cfg, FALSE, ts); child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
peer_cfg->add_child_cfg(peer_cfg, child_cfg); peer_cfg->add_child_cfg(peer_cfg, child_cfg);
/* get an additional reference because initiate consumes one */
child_cfg->get_ref(child_cfg);
/* get us an IKE_SA */ /* get us an IKE_SA */
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
peer_cfg); peer_cfg);
if (!ike_sa)
{
peer_cfg->destroy(peer_cfg);
this->status = VPN_STATUS_CONNECTION_FAILED;
return FALSE;
}
if (!ike_sa->get_peer_cfg(ike_sa)) if (!ike_sa->get_peer_cfg(ike_sa))
{ {
ike_sa->set_peer_cfg(ike_sa, peer_cfg); ike_sa->set_peer_cfg(ike_sa, peer_cfg);
@@ -374,6 +378,8 @@ static gboolean initiate_connection(private_maemo_service_t *this,
this->public.listener.ike_state_change = _ike_state_change; this->public.listener.ike_state_change = _ike_state_change;
charon->bus->add_listener(charon->bus, &this->public.listener); charon->bus->add_listener(charon->bus, &this->public.listener);
/* get an additional reference because initiate consumes one */
child_cfg->get_ref(child_cfg);
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
{ {
DBG1(DBG_CFG, "failed to initiate tunnel"); DBG1(DBG_CFG, "failed to initiate tunnel");
+8
View File
@@ -533,6 +533,13 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
*/ */
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
peer_cfg); peer_cfg);
if (!ike_sa)
{
peer_cfg->destroy(peer_cfg);
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
"IKE version not supported.");
return FALSE;
}
if (!ike_sa->get_peer_cfg(ike_sa)) if (!ike_sa->get_peer_cfg(ike_sa))
{ {
ike_sa->set_peer_cfg(ike_sa, peer_cfg); ike_sa->set_peer_cfg(ike_sa, peer_cfg);
@@ -550,6 +557,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
/** /**
* Initiate * Initiate
*/ */
child_cfg->get_ref(child_cfg);
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
{ {
charon->bus->remove_listener(charon->bus, &priv->listener); charon->bus->remove_listener(charon->bus, &priv->listener);
+21 -5
View File
@@ -1412,6 +1412,10 @@ METHOD(ike_sa_t, reestablish, status_t,
new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
this->version, TRUE); this->version, TRUE);
if (!new)
{
return FAILED;
}
new->set_peer_cfg(new, this->peer_cfg); new->set_peer_cfg(new, this->peer_cfg);
host = this->other_host; host = this->other_host;
new->set_other_host(new, host->clone(host)); new->set_other_host(new, host->clone(host));
@@ -1802,7 +1806,7 @@ METHOD(ike_sa_t, destroy, void,
charon->bus->set_sa(charon->bus, &this->public); charon->bus->set_sa(charon->bus, &this->public);
set_state(this, IKE_DESTROYING); set_state(this, IKE_DESTROYING);
this->task_manager->destroy(this->task_manager); DESTROY_IF(this->task_manager);
/* remove attributes first, as we pass the IKE_SA to the handler */ /* remove attributes first, as we pass the IKE_SA to the handler */
while (this->attributes->remove_last(this->attributes, while (this->attributes->remove_last(this->attributes,
@@ -1820,7 +1824,7 @@ METHOD(ike_sa_t, destroy, void,
/* unset SA after here to avoid usage by the listeners */ /* unset SA after here to avoid usage by the listeners */
charon->bus->set_sa(charon->bus, NULL); charon->bus->set_sa(charon->bus, NULL);
this->keymat->destroy(this->keymat); DESTROY_IF(this->keymat);
if (this->my_virtual_ip) if (this->my_virtual_ip)
{ {
@@ -1881,6 +1885,15 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
private_ike_sa_t *this; private_ike_sa_t *this;
static u_int32_t unique_id = 0; static u_int32_t unique_id = 0;
if (version == IKE_ANY)
{ /* prefer IKEv2 if protocol not specified */
#ifdef USE_IKEV2
version = IKEV2;
#else
version = IKEV1;
#endif
}
INIT(this, INIT(this,
.public = { .public = {
.get_version = _get_version, .get_version = _get_version,
@@ -1991,8 +2004,11 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
this->task_manager = task_manager_create(&this->public); this->task_manager = task_manager_create(&this->public);
this->my_host->set_port(this->my_host, IKEV2_UDP_PORT); this->my_host->set_port(this->my_host, IKEV2_UDP_PORT);
/* TODO-IKEv1: check if keymat and task manager created successfully. if (!this->task_manager || !this->keymat)
* Return NULL otherwise? */ {
DBG1(DBG_IKE, "IKE version %d not supported", this->version);
destroy(this);
return NULL;
}
return &this->public; return &this->public;
} }
+21 -16
View File
@@ -955,9 +955,11 @@ METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*,
ike_sa = ike_sa_create(ike_sa_id, initiator, version); ike_sa = ike_sa_create(ike_sa_id, initiator, version);
ike_sa_id->destroy(ike_sa_id); ike_sa_id->destroy(ike_sa_id);
DBG2(DBG_MGR, "created IKE_SA %s[%u]", ike_sa->get_name(ike_sa), if (ike_sa)
ike_sa->get_unique_id(ike_sa)); {
DBG2(DBG_MGR, "created IKE_SA %s[%u]", ike_sa->get_name(ike_sa),
ike_sa->get_unique_id(ike_sa));
}
return ike_sa; return ike_sa;
} }
@@ -1033,23 +1035,26 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
{ {
/* no IKE_SA found, create a new one */ /* no IKE_SA found, create a new one */
id->set_responder_spi(id, get_spi(this)); id->set_responder_spi(id, get_spi(this));
entry = entry_create(); ike_sa = ike_sa_create(id, FALSE, ike_version);
/* a new SA checked out by message is a responder SA */ if (ike_sa)
entry->ike_sa = ike_sa_create(id, FALSE, ike_version); {
entry->ike_sa_id = id->clone(id); entry = entry_create();
/* a new SA checked out by message is a responder SA */
entry->ike_sa = ike_sa;
entry->ike_sa_id = id->clone(id);
segment = put_entry(this, entry); segment = put_entry(this, entry);
entry->checked_out = TRUE; entry->checked_out = TRUE;
unlock_single_segment(this, segment); unlock_single_segment(this, segment);
entry->message_id = message->get_message_id(message); entry->message_id = message->get_message_id(message);
entry->init_hash = hash; entry->init_hash = hash;
ike_sa = entry->ike_sa;
DBG2(DBG_MGR, "created IKE_SA %s[%u]", DBG2(DBG_MGR, "created IKE_SA %s[%u]",
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa)); ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
}
} }
else if (ike_sa == NULL)
{ {
chunk_free(&hash); chunk_free(&hash);
DBG1(DBG_MGR, "ignoring message, no such IKE_SA"); DBG1(DBG_MGR, "ignoring message, no such IKE_SA");
+6 -4
View File
@@ -54,7 +54,6 @@ METHOD(task_t, process_i, status_t,
ike_sa_t *new; ike_sa_t *new;
host_t *host; host_t *host;
enumerator_t *enumerator; enumerator_t *enumerator;
ike_version_t version;
child_sa_t *child_sa; child_sa_t *child_sa;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
@@ -75,9 +74,12 @@ METHOD(task_t, process_i, status_t,
return FAILED; return FAILED;
} }
version = this->ike_sa->get_version(this->ike_sa); new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, version, this->ike_sa->get_version(this->ike_sa), TRUE);
TRUE); if (!new)
{ /* shouldn't happen */
return FAILED;
}
new->set_peer_cfg(new, peer_cfg); new->set_peer_cfg(new, peer_cfg);
host = this->ike_sa->get_other_host(this->ike_sa); host = this->ike_sa->get_other_host(this->ike_sa);
+11 -5
View File
@@ -123,16 +123,20 @@ METHOD(task_t, process_i_delete, status_t,
METHOD(task_t, build_i, status_t, METHOD(task_t, build_i, status_t,
private_ike_rekey_t *this, message_t *message) private_ike_rekey_t *this, message_t *message)
{ {
ike_version_t version;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
host_t *other_host; host_t *other_host;
/* create new SA only on first try */ /* create new SA only on first try */
if (this->new_sa == NULL) if (this->new_sa == NULL)
{ {
ike_version_t version = this->ike_sa->get_version(this->ike_sa); version = this->ike_sa->get_version(this->ike_sa);
this->new_sa = charon->ike_sa_manager->checkout_new( this->new_sa = charon->ike_sa_manager->checkout_new(
charon->ike_sa_manager, version, TRUE); charon->ike_sa_manager, version, TRUE);
if (!this->new_sa)
{ /* shouldn't happen */
return FAILED;
}
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
other_host = this->ike_sa->get_other_host(this->ike_sa); other_host = this->ike_sa->get_other_host(this->ike_sa);
this->new_sa->set_peer_cfg(this->new_sa, peer_cfg); this->new_sa->set_peer_cfg(this->new_sa, peer_cfg);
@@ -149,7 +153,6 @@ METHOD(task_t, process_r, status_t,
private_ike_rekey_t *this, message_t *message) private_ike_rekey_t *this, message_t *message)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
ike_version_t version;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
child_sa_t *child_sa; child_sa_t *child_sa;
@@ -177,9 +180,12 @@ METHOD(task_t, process_r, status_t,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
version = this->ike_sa->get_version(this->ike_sa);
this->new_sa = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, this->new_sa = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
version, FALSE); this->ike_sa->get_version(this->ike_sa), FALSE);
if (!this->new_sa)
{ /* shouldn't happen */
return FAILED;
}
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
this->new_sa->set_peer_cfg(this->new_sa, peer_cfg); this->new_sa->set_peer_cfg(this->new_sa, peer_cfg);
+16 -13
View File
@@ -274,21 +274,24 @@ METHOD(trap_manager_t, acquire, void,
peer = found->peer_cfg; peer = found->peer_cfg;
ike_sa = charon->ike_sa_manager->checkout_by_config( ike_sa = charon->ike_sa_manager->checkout_by_config(
charon->ike_sa_manager, peer); charon->ike_sa_manager, peer);
if (ike_sa->get_peer_cfg(ike_sa) == NULL) if (ike_sa)
{ {
ike_sa->set_peer_cfg(ike_sa, peer); if (ike_sa->get_peer_cfg(ike_sa) == NULL)
} {
child->get_ref(child); ike_sa->set_peer_cfg(ike_sa, peer);
reqid = found->child_sa->get_reqid(found->child_sa); }
if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME) child->get_ref(child);
{ reqid = found->child_sa->get_reqid(found->child_sa);
found->pending = ike_sa; if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME)
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); {
} found->pending = ike_sa;
else charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
{ }
charon->ike_sa_manager->checkin_and_destroy( else
{
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, ike_sa); charon->ike_sa_manager, ike_sa);
}
} }
} }
this->lock->unlock(this->lock); this->lock->unlock(this->lock);