android: Fix handling of redirects during IKE_AUTH

This commit is contained in:
Tobias Brunner
2016-05-02 16:41:25 +02:00
parent 1dabd0fb1c
commit d9c5e6d786
@@ -1,8 +1,8 @@
/*
* Copyright (C) 2010-2015 Tobias Brunner
* Copyright (C) 2010-2016 Tobias Brunner
* Copyright (C) 2012 Giuliano Grassi
* Copyright (C) 2012 Ralf Sager
* Hochschule fuer Technik Rapperswil
* 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
@@ -430,6 +430,84 @@ CALLBACK(reestablish, job_requeue_t,
return JOB_REQUEUE_NONE;
}
METHOD(listener_t, ike_updown, bool,
private_android_service_t *this, ike_sa_t *ike_sa, bool up)
{
/* this callback is only registered during initiation, so if the IKE_SA
* goes down we assume some kind of authentication error, more specific
* errors are catched in the alert() handler */
if (this->ike_sa == ike_sa && !up)
{
charonservice->update_status(charonservice,
CHARONSERVICE_AUTH_ERROR);
return FALSE;
}
return TRUE;
}
METHOD(listener_t, ike_rekey, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
{
if (this->ike_sa == old)
{
this->ike_sa = new;
}
return TRUE;
}
METHOD(listener_t, ike_reestablish_post_redirect, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
bool initiated)
{
if (this->ike_sa == old && initiated)
{ /* if we get redirected during IKE_AUTH we just migrate to the new SA,
* we don't have a TUN device yet, so reinstalling it without DNS would
* fail (and using the DNS proxy is not required anyway) */
this->ike_sa = new;
}
return TRUE;
}
METHOD(listener_t, ike_reestablish_pre, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
{
if (this->ike_sa == old)
{
/* enable DNS proxy so hosts are properly resolved while the TUN device
* is still active */
this->lock->write_lock(this->lock);
this->use_dns_proxy = TRUE;
this->lock->unlock(this->lock);
/* if DNS servers are installed that are only reachable through the VPN
* the DNS proxy doesn't help, so uninstall DNS servers */
if (!setup_tun_device_without_dns(this))
{
DBG1(DBG_DMN, "failed to setup TUN device without DNS");
charonservice->update_status(charonservice,
CHARONSERVICE_GENERIC_ERROR);
}
}
return TRUE;
}
METHOD(listener_t, ike_reestablish_post, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
bool initiated)
{
if (this->ike_sa == old && initiated)
{
this->ike_sa = new;
/* re-register hook to detect initiation failures */
this->public.listener.ike_updown = _ike_updown;
/* if the IKE_SA got deleted by the responder we get the child_down()
* event on the old IKE_SA after this hook has been called, so they
* get ignored and thus we trigger the event here */
charonservice->update_status(charonservice,
CHARONSERVICE_CHILD_STATE_DOWN);
}
return TRUE;
}
METHOD(listener_t, child_updown, bool,
private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
bool up)
@@ -440,6 +518,9 @@ METHOD(listener_t, child_updown, bool,
{
/* disable the hooks registered to catch initiation failures */
this->public.listener.ike_updown = NULL;
/* enable hooks to handle reauthentications */
this->public.listener.ike_reestablish_pre = _ike_reestablish_pre;
this->public.listener.ike_reestablish_post = _ike_reestablish_post;
/* CHILD_SA is up so we can disable the DNS proxy we enabled to
* reestablish the SA */
this->lock->write_lock(this->lock);
@@ -465,21 +546,6 @@ METHOD(listener_t, child_updown, bool,
return TRUE;
}
METHOD(listener_t, ike_updown, bool,
private_android_service_t *this, ike_sa_t *ike_sa, bool up)
{
/* this callback is only registered during initiation, so if the IKE_SA
* goes down we assume some kind of authentication error, more specific
* errors are catched in the alert() handler */
if (this->ike_sa == ike_sa && !up)
{
charonservice->update_status(charonservice,
CHARONSERVICE_AUTH_ERROR);
return FALSE;
}
return TRUE;
}
METHOD(listener_t, alert, bool,
private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
va_list args)
@@ -554,56 +620,6 @@ METHOD(listener_t, alert, bool,
return TRUE;
}
METHOD(listener_t, ike_rekey, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
{
if (this->ike_sa == old)
{
this->ike_sa = new;
}
return TRUE;
}
METHOD(listener_t, ike_reestablish_pre, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new)
{
if (this->ike_sa == old)
{
/* enable DNS proxy so hosts are properly resolved while the TUN device
* is still active */
this->lock->write_lock(this->lock);
this->use_dns_proxy = TRUE;
this->lock->unlock(this->lock);
/* if DNS servers are installed that are only reachable through the VPN
* the DNS proxy doesn't help, so uninstall DNS servers */
if (!setup_tun_device_without_dns(this))
{
DBG1(DBG_DMN, "failed to setup TUN device without DNS");
charonservice->update_status(charonservice,
CHARONSERVICE_GENERIC_ERROR);
}
}
return TRUE;
}
METHOD(listener_t, ike_reestablish_post, bool,
private_android_service_t *this, ike_sa_t *old, ike_sa_t *new,
bool initiated)
{
if (this->ike_sa == old && initiated)
{
this->ike_sa = new;
/* re-register hook to detect initiation failures */
this->public.listener.ike_updown = _ike_updown;
/* if the IKE_SA got deleted by the responder we get the child_down()
* event on the old IKE_SA after this hook has been called, so they
* get ignored and thus we trigger the event here */
charonservice->update_status(charonservice,
CHARONSERVICE_CHILD_STATE_DOWN);
}
return TRUE;
}
static void add_auth_cfg_pw(private_android_service_t *this,
peer_cfg_t *peer_cfg, bool byod)
{
@@ -824,8 +840,7 @@ android_service_t *android_service_create(android_creds_t *creds,
.public = {
.listener = {
.ike_rekey = _ike_rekey,
.ike_reestablish_pre = _ike_reestablish_pre,
.ike_reestablish_post = _ike_reestablish_post,
.ike_reestablish_post = _ike_reestablish_post_redirect,
.ike_updown = _ike_updown,
.child_updown = _child_updown,
.alert = _alert,