android: Fix handling of redirects during IKE_AUTH
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user