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 Giuliano Grassi
|
||||||
* Copyright (C) 2012 Ralf Sager
|
* 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
|
* 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
|
* 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;
|
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,
|
METHOD(listener_t, child_updown, bool,
|
||||||
private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||||
bool up)
|
bool up)
|
||||||
@@ -440,6 +518,9 @@ METHOD(listener_t, child_updown, bool,
|
|||||||
{
|
{
|
||||||
/* disable the hooks registered to catch initiation failures */
|
/* disable the hooks registered to catch initiation failures */
|
||||||
this->public.listener.ike_updown = NULL;
|
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
|
/* CHILD_SA is up so we can disable the DNS proxy we enabled to
|
||||||
* reestablish the SA */
|
* reestablish the SA */
|
||||||
this->lock->write_lock(this->lock);
|
this->lock->write_lock(this->lock);
|
||||||
@@ -465,21 +546,6 @@ METHOD(listener_t, child_updown, bool,
|
|||||||
return TRUE;
|
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,
|
METHOD(listener_t, alert, bool,
|
||||||
private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
|
private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert,
|
||||||
va_list args)
|
va_list args)
|
||||||
@@ -554,56 +620,6 @@ METHOD(listener_t, alert, bool,
|
|||||||
return TRUE;
|
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,
|
static void add_auth_cfg_pw(private_android_service_t *this,
|
||||||
peer_cfg_t *peer_cfg, bool byod)
|
peer_cfg_t *peer_cfg, bool byod)
|
||||||
{
|
{
|
||||||
@@ -824,8 +840,7 @@ android_service_t *android_service_create(android_creds_t *creds,
|
|||||||
.public = {
|
.public = {
|
||||||
.listener = {
|
.listener = {
|
||||||
.ike_rekey = _ike_rekey,
|
.ike_rekey = _ike_rekey,
|
||||||
.ike_reestablish_pre = _ike_reestablish_pre,
|
.ike_reestablish_post = _ike_reestablish_post_redirect,
|
||||||
.ike_reestablish_post = _ike_reestablish_post,
|
|
||||||
.ike_updown = _ike_updown,
|
.ike_updown = _ike_updown,
|
||||||
.child_updown = _child_updown,
|
.child_updown = _child_updown,
|
||||||
.alert = _alert,
|
.alert = _alert,
|
||||||
|
|||||||
Reference in New Issue
Block a user