Removed backend for old Android frontend patch
Moved the remaining DNS handler to a new plugin.
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@ include $(CLEAR_VARS)
|
|||||||
# this is the list of plugins that are built into libstrongswan and charon
|
# this is the list of plugins that are built into libstrongswan and charon
|
||||||
# also these plugins are loaded by default (if not changed in strongswan.conf)
|
# also these plugins are loaded by default (if not changed in strongswan.conf)
|
||||||
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
|
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
|
||||||
pkcs1 pkcs8 pem xcbc hmac kernel-netlink socket-default android \
|
pkcs1 pkcs8 pem xcbc hmac kernel-netlink socket-default android-dns \
|
||||||
stroke eap-identity eap-mschapv2 eap-md5 eap-gtc
|
stroke eap-identity eap-mschapv2 eap-md5 eap-gtc
|
||||||
|
|
||||||
ifneq ($(strongswan_BUILD_SCEPCLIENT),)
|
ifneq ($(strongswan_BUILD_SCEPCLIENT),)
|
||||||
|
|||||||
+5
-5
@@ -218,7 +218,7 @@ ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.])
|
|||||||
ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.])
|
ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.])
|
||||||
ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.])
|
ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.])
|
||||||
ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.])
|
ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.])
|
||||||
ARG_ENABL_SET([android], [enable Android specific plugin.])
|
ARG_ENABL_SET([android-dns], [enable Android specific DNS handler.])
|
||||||
ARG_ENABL_SET([android-log], [enable Android specific logger plugin.])
|
ARG_ENABL_SET([android-log], [enable Android specific logger plugin.])
|
||||||
ARG_ENABL_SET([maemo], [enable Maemo specific plugin.])
|
ARG_ENABL_SET([maemo], [enable Maemo specific plugin.])
|
||||||
ARG_ENABL_SET([nm], [enable NetworkManager backend.])
|
ARG_ENABL_SET([nm], [enable NetworkManager backend.])
|
||||||
@@ -800,7 +800,7 @@ if test x$uci = xtrue; then
|
|||||||
AC_CHECK_HEADER([uci.h],,[AC_MSG_ERROR([UCI header uci.h not found!])])
|
AC_CHECK_HEADER([uci.h],,[AC_MSG_ERROR([UCI header uci.h not found!])])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$android = xtrue; then
|
if test x$android_dns = xtrue; then
|
||||||
AC_CHECK_LIB([cutils],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([Android library libcutils not found])],[])
|
AC_CHECK_LIB([cutils],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([Android library libcutils not found])],[])
|
||||||
AC_CHECK_HEADER([cutils/properties.h],,[AC_MSG_ERROR([Android header cutils/properties.h not found!])])
|
AC_CHECK_HEADER([cutils/properties.h],,[AC_MSG_ERROR([Android header cutils/properties.h not found!])])
|
||||||
# we have to force the use of libdl here because the autodetection
|
# we have to force the use of libdl here because the autodetection
|
||||||
@@ -1007,7 +1007,7 @@ ADD_PLUGIN([tnccs-dynamic], [c charon])
|
|||||||
ADD_PLUGIN([medsrv], [c charon])
|
ADD_PLUGIN([medsrv], [c charon])
|
||||||
ADD_PLUGIN([medcli], [c charon])
|
ADD_PLUGIN([medcli], [c charon])
|
||||||
ADD_PLUGIN([dhcp], [c charon])
|
ADD_PLUGIN([dhcp], [c charon])
|
||||||
ADD_PLUGIN([android], [c charon])
|
ADD_PLUGIN([android-dns], [c charon])
|
||||||
ADD_PLUGIN([android-log], [c charon])
|
ADD_PLUGIN([android-log], [c charon])
|
||||||
ADD_PLUGIN([ha], [c charon])
|
ADD_PLUGIN([ha], [c charon])
|
||||||
ADD_PLUGIN([whitelist], [c charon])
|
ADD_PLUGIN([whitelist], [c charon])
|
||||||
@@ -1095,7 +1095,7 @@ AM_CONDITIONAL(USE_STROKE, test x$stroke = xtrue)
|
|||||||
AM_CONDITIONAL(USE_MEDSRV, test x$medsrv = xtrue)
|
AM_CONDITIONAL(USE_MEDSRV, test x$medsrv = xtrue)
|
||||||
AM_CONDITIONAL(USE_MEDCLI, test x$medcli = xtrue)
|
AM_CONDITIONAL(USE_MEDCLI, test x$medcli = xtrue)
|
||||||
AM_CONDITIONAL(USE_UCI, test x$uci = xtrue)
|
AM_CONDITIONAL(USE_UCI, test x$uci = xtrue)
|
||||||
AM_CONDITIONAL(USE_ANDROID, test x$android = xtrue)
|
AM_CONDITIONAL(USE_ANDROID_DNS, test x$android_dns = xtrue)
|
||||||
AM_CONDITIONAL(USE_ANDROID_LOG, test x$android_log = xtrue)
|
AM_CONDITIONAL(USE_ANDROID_LOG, test x$android_log = xtrue)
|
||||||
AM_CONDITIONAL(USE_MAEMO, test x$maemo = xtrue)
|
AM_CONDITIONAL(USE_MAEMO, test x$maemo = xtrue)
|
||||||
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
|
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
|
||||||
@@ -1357,7 +1357,7 @@ AC_CONFIG_FILES([
|
|||||||
src/libcharon/plugins/duplicheck/Makefile
|
src/libcharon/plugins/duplicheck/Makefile
|
||||||
src/libcharon/plugins/coupling/Makefile
|
src/libcharon/plugins/coupling/Makefile
|
||||||
src/libcharon/plugins/radattr/Makefile
|
src/libcharon/plugins/radattr/Makefile
|
||||||
src/libcharon/plugins/android/Makefile
|
src/libcharon/plugins/android_dns/Makefile
|
||||||
src/libcharon/plugins/android_log/Makefile
|
src/libcharon/plugins/android_log/Makefile
|
||||||
src/libcharon/plugins/maemo/Makefile
|
src/libcharon/plugins/maemo/Makefile
|
||||||
src/libcharon/plugins/stroke/Makefile
|
src/libcharon/plugins/stroke/Makefile
|
||||||
|
|||||||
@@ -125,9 +125,8 @@ processing/jobs/adopt_children_job.c processing/jobs/adopt_children_job.h
|
|||||||
|
|
||||||
# adding the plugin source files
|
# adding the plugin source files
|
||||||
|
|
||||||
LOCAL_SRC_FILES += $(call add_plugin, android)
|
LOCAL_SRC_FILES += $(call add_plugin, android-dns)
|
||||||
ifneq ($(call plugin_enabled, android),)
|
ifneq ($(call plugin_enabled, android-dns),)
|
||||||
LOCAL_C_INCLUDES += frameworks/base/cmds/keystore
|
|
||||||
LOCAL_SHARED_LIBRARIES += libcutils
|
LOCAL_SHARED_LIBRARIES += libcutils
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -457,10 +457,10 @@ if MONOLITHIC
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_ANDROID
|
if USE_ANDROID_DNS
|
||||||
SUBDIRS += plugins/android
|
SUBDIRS += plugins/android_dns
|
||||||
if MONOLITHIC
|
if MONOLITHIC
|
||||||
libcharon_la_LIBADD += plugins/android/libstrongswan-android.la
|
libcharon_la_LIBADD += plugins/android_dns/libstrongswan-android-dns.la
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
|
|
||||||
-I$(top_srcdir)/src/libcharon
|
|
||||||
|
|
||||||
AM_CFLAGS = -rdynamic
|
|
||||||
|
|
||||||
if MONOLITHIC
|
|
||||||
noinst_LTLIBRARIES = libstrongswan-android.la
|
|
||||||
else
|
|
||||||
plugin_LTLIBRARIES = libstrongswan-android.la
|
|
||||||
endif
|
|
||||||
|
|
||||||
libstrongswan_android_la_SOURCES = \
|
|
||||||
android_plugin.c android_plugin.h \
|
|
||||||
android_service.c android_service.h \
|
|
||||||
android_handler.c android_handler.h \
|
|
||||||
android_creds.c android_creds.h
|
|
||||||
|
|
||||||
libstrongswan_android_la_LDFLAGS = -module -avoid-version
|
|
||||||
libstrongswan_android_la_LIBADD = -lcutils
|
|
||||||
@@ -1,294 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Tobias Brunner
|
|
||||||
* 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
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <keystore_get.h>
|
|
||||||
|
|
||||||
#include "android_creds.h"
|
|
||||||
|
|
||||||
#include <daemon.h>
|
|
||||||
#include <threading/rwlock.h>
|
|
||||||
|
|
||||||
typedef struct private_android_creds_t private_android_creds_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private data of an android_creds_t object
|
|
||||||
*/
|
|
||||||
struct private_android_creds_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public interface
|
|
||||||
*/
|
|
||||||
android_creds_t public;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of trusted certificates, certificate_t*
|
|
||||||
*/
|
|
||||||
linked_list_t *certs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User name (ID)
|
|
||||||
*/
|
|
||||||
identification_t *user;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User password
|
|
||||||
*/
|
|
||||||
char *pass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* read/write lock
|
|
||||||
*/
|
|
||||||
rwlock_t *lock;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Certificate enumerator data
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
private_android_creds_t *this;
|
|
||||||
key_type_t key;
|
|
||||||
identification_t *id;
|
|
||||||
} cert_data_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter function for certificates enumerator
|
|
||||||
*/
|
|
||||||
static bool cert_filter(cert_data_t *data, certificate_t **in,
|
|
||||||
certificate_t **out)
|
|
||||||
{
|
|
||||||
certificate_t *cert = *in;
|
|
||||||
public_key_t *public;
|
|
||||||
|
|
||||||
public = cert->get_public_key(cert);
|
|
||||||
if (!public)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (data->key != KEY_ANY && public->get_type(public) != data->key)
|
|
||||||
{
|
|
||||||
public->destroy(public);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (data->id && data->id->get_type(data->id) == ID_KEY_ID &&
|
|
||||||
public->has_fingerprint(public, data->id->get_encoding(data->id)))
|
|
||||||
{
|
|
||||||
public->destroy(public);
|
|
||||||
*out = cert;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
public->destroy(public);
|
|
||||||
if (data->id && !cert->has_subject(cert, data->id))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
*out = cert;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy certificate enumerator data
|
|
||||||
*/
|
|
||||||
static void cert_data_destroy(cert_data_t *this)
|
|
||||||
{
|
|
||||||
this->this->lock->unlock(this->this->lock);
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
|
|
||||||
private_android_creds_t *this, certificate_type_t cert, key_type_t key,
|
|
||||||
identification_t *id, bool trusted)
|
|
||||||
{
|
|
||||||
if (cert == CERT_X509 || cert == CERT_ANY)
|
|
||||||
{
|
|
||||||
cert_data_t *data;
|
|
||||||
this->lock->read_lock(this->lock);
|
|
||||||
INIT(data, .this = this, .id = id, .key = key);
|
|
||||||
return enumerator_create_filter(
|
|
||||||
this->certs->create_enumerator(this->certs),
|
|
||||||
(void*)cert_filter, data, (void*)cert_data_destroy);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shared key enumerator implementation
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
enumerator_t public;
|
|
||||||
private_android_creds_t *this;
|
|
||||||
shared_key_t *key;
|
|
||||||
bool done;
|
|
||||||
} shared_enumerator_t;
|
|
||||||
|
|
||||||
METHOD(enumerator_t, shared_enumerate, bool,
|
|
||||||
shared_enumerator_t *this, shared_key_t **key, id_match_t *me,
|
|
||||||
id_match_t *other)
|
|
||||||
{
|
|
||||||
if (this->done)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
*key = this->key;
|
|
||||||
*me = ID_MATCH_PERFECT;
|
|
||||||
*other = ID_MATCH_ANY;
|
|
||||||
this->done = TRUE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(enumerator_t, shared_destroy, void,
|
|
||||||
shared_enumerator_t *this)
|
|
||||||
{
|
|
||||||
this->key->destroy(this->key);
|
|
||||||
this->this->lock->unlock(this->this->lock);
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
|
|
||||||
private_android_creds_t *this, shared_key_type_t type,
|
|
||||||
identification_t *me, identification_t *other)
|
|
||||||
{
|
|
||||||
shared_enumerator_t *enumerator;
|
|
||||||
|
|
||||||
this->lock->read_lock(this->lock);
|
|
||||||
|
|
||||||
if (!this->user || !this->pass)
|
|
||||||
{
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (type != SHARED_EAP && type != SHARED_IKE)
|
|
||||||
{
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (me && !me->equals(me, this->user))
|
|
||||||
{
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT(enumerator,
|
|
||||||
.public = {
|
|
||||||
.enumerate = (void*)_shared_enumerate,
|
|
||||||
.destroy = _shared_destroy,
|
|
||||||
},
|
|
||||||
.this = this,
|
|
||||||
.done = FALSE,
|
|
||||||
.key = shared_key_create(type, chunk_clone(chunk_create(this->pass,
|
|
||||||
strlen(this->pass)))),
|
|
||||||
);
|
|
||||||
return &enumerator->public;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(android_creds_t, add_certificate, bool,
|
|
||||||
private_android_creds_t *this, char *name)
|
|
||||||
{
|
|
||||||
certificate_t *cert = NULL;
|
|
||||||
bool status = FALSE;
|
|
||||||
chunk_t chunk;
|
|
||||||
#ifdef KEYSTORE_MESSAGE_SIZE
|
|
||||||
/* most current interface, the eclair interface (without key length) is
|
|
||||||
* currently not supported */
|
|
||||||
char value[KEYSTORE_MESSAGE_SIZE];
|
|
||||||
chunk.ptr = value;
|
|
||||||
chunk.len = keystore_get(name, strlen(name), chunk.ptr);
|
|
||||||
if (chunk.len > 0)
|
|
||||||
#else
|
|
||||||
/* 1.6 interface, allocates memory */
|
|
||||||
chunk.ptr = keystore_get(name, &chunk.len);
|
|
||||||
if (chunk.ptr)
|
|
||||||
#endif /* KEYSTORE_MESSAGE_SIZE */
|
|
||||||
{
|
|
||||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
|
||||||
BUILD_BLOB_PEM, chunk, BUILD_END);
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
this->lock->write_lock(this->lock);
|
|
||||||
this->certs->insert_last(this->certs, cert);
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
status = TRUE;
|
|
||||||
}
|
|
||||||
#ifndef KEYSTORE_MESSAGE_SIZE
|
|
||||||
free(chunk.ptr);
|
|
||||||
#endif /* KEYSTORE_MESSAGE_SIZE */
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(android_creds_t, set_username_password, void,
|
|
||||||
private_android_creds_t *this, identification_t *id, char *password)
|
|
||||||
{
|
|
||||||
this->lock->write_lock(this->lock);
|
|
||||||
DESTROY_IF(this->user);
|
|
||||||
this->user = id->clone(id);
|
|
||||||
free(this->pass);
|
|
||||||
this->pass = strdupnull(password);
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(android_creds_t, clear, void,
|
|
||||||
private_android_creds_t *this)
|
|
||||||
{
|
|
||||||
certificate_t *cert;
|
|
||||||
this->lock->write_lock(this->lock);
|
|
||||||
while (this->certs->remove_last(this->certs, (void**)&cert) == SUCCESS)
|
|
||||||
{
|
|
||||||
cert->destroy(cert);
|
|
||||||
}
|
|
||||||
DESTROY_IF(this->user);
|
|
||||||
free(this->pass);
|
|
||||||
this->user = NULL;
|
|
||||||
this->pass = NULL;
|
|
||||||
this->lock->unlock(this->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(android_creds_t, destroy, void,
|
|
||||||
private_android_creds_t *this)
|
|
||||||
{
|
|
||||||
clear(this);
|
|
||||||
this->certs->destroy(this->certs);
|
|
||||||
this->lock->destroy(this->lock);
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Described in header.
|
|
||||||
*/
|
|
||||||
android_creds_t *android_creds_create()
|
|
||||||
{
|
|
||||||
private_android_creds_t *this;
|
|
||||||
|
|
||||||
INIT(this,
|
|
||||||
.public = {
|
|
||||||
.set = {
|
|
||||||
.create_cert_enumerator = _create_cert_enumerator,
|
|
||||||
.create_shared_enumerator = _create_shared_enumerator,
|
|
||||||
.create_private_enumerator = (void*)return_null,
|
|
||||||
.create_cdp_enumerator = (void*)return_null,
|
|
||||||
.cache_cert = (void*)nop,
|
|
||||||
},
|
|
||||||
.add_certificate = _add_certificate,
|
|
||||||
.set_username_password = _set_username_password,
|
|
||||||
.clear = _clear,
|
|
||||||
.destroy = _destroy,
|
|
||||||
},
|
|
||||||
.certs = linked_list_create(),
|
|
||||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
|
||||||
);
|
|
||||||
|
|
||||||
return &this->public;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Tobias Brunner
|
|
||||||
* 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
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup android_creds android_creds
|
|
||||||
* @{ @ingroup android
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ANDROID_CREDS_H_
|
|
||||||
#define ANDROID_CREDS_H_
|
|
||||||
|
|
||||||
#include <credentials/credential_set.h>
|
|
||||||
|
|
||||||
typedef struct android_creds_t android_creds_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Android credentials helper.
|
|
||||||
*/
|
|
||||||
struct android_creds_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements credential_set_t
|
|
||||||
*/
|
|
||||||
credential_set_t set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a trusted CA certificate from the Android keystore to serve by
|
|
||||||
* this set.
|
|
||||||
*
|
|
||||||
* @param name name/ID of the certificate in the keystore
|
|
||||||
* @return FALSE if the certificate does not exist or is invalid
|
|
||||||
*/
|
|
||||||
bool (*add_certificate)(android_creds_t *this, char *name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the username and password for authentication.
|
|
||||||
*
|
|
||||||
* @param id ID of the user
|
|
||||||
* @param password password to use for authentication
|
|
||||||
*/
|
|
||||||
void (*set_username_password)(android_creds_t *this, identification_t *id,
|
|
||||||
char *password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the stored credentials.
|
|
||||||
*/
|
|
||||||
void (*clear)(android_creds_t *this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy a android_creds instance.
|
|
||||||
*/
|
|
||||||
void (*destroy)(android_creds_t *this);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an android_creds instance.
|
|
||||||
*/
|
|
||||||
android_creds_t *android_creds_create();
|
|
||||||
|
|
||||||
#endif /** ANDROID_CREDS_H_ @}*/
|
|
||||||
@@ -1,389 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Tobias Brunner
|
|
||||||
* 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
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <cutils/sockets.h>
|
|
||||||
#include <cutils/properties.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "android_service.h"
|
|
||||||
|
|
||||||
#include <daemon.h>
|
|
||||||
#include <threading/thread.h>
|
|
||||||
#include <processing/jobs/callback_job.h>
|
|
||||||
|
|
||||||
typedef struct private_android_service_t private_android_service_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* private data of Android service
|
|
||||||
*/
|
|
||||||
struct private_android_service_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* public interface
|
|
||||||
*/
|
|
||||||
android_service_t public;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* current IKE_SA
|
|
||||||
*/
|
|
||||||
ike_sa_t *ike_sa;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* android credentials
|
|
||||||
*/
|
|
||||||
android_creds_t *creds;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* android control socket
|
|
||||||
*/
|
|
||||||
int control;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some of the error codes defined in VpnManager.java
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
/** Error code to indicate an error from authentication. */
|
|
||||||
VPN_ERROR_AUTH = 51,
|
|
||||||
/** Error code to indicate the connection attempt failed. */
|
|
||||||
VPN_ERROR_CONNECTION_FAILED = 101,
|
|
||||||
/** Error code to indicate an error of remote server hanging up. */
|
|
||||||
VPN_ERROR_REMOTE_HUNG_UP = 7,
|
|
||||||
/** Error code to indicate an error of losing connectivity. */
|
|
||||||
VPN_ERROR_CONNECTION_LOST = 103,
|
|
||||||
} android_vpn_errors_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* send a status code back to the Android app
|
|
||||||
*/
|
|
||||||
static void send_status(private_android_service_t *this, u_char code)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "status of Android plugin changed: %d", code);
|
|
||||||
send(this->control, &code, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 an authentication error */
|
|
||||||
if (this->ike_sa == ike_sa && !up)
|
|
||||||
{
|
|
||||||
send_status(this, VPN_ERROR_AUTH);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(listener_t, child_state_change, bool,
|
|
||||||
private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
|
||||||
child_sa_state_t state)
|
|
||||||
{
|
|
||||||
/* this callback is only registered during initiation, so we still have
|
|
||||||
* the control socket open */
|
|
||||||
if (this->ike_sa == ike_sa && state == CHILD_DESTROYING)
|
|
||||||
{
|
|
||||||
send_status(this, VPN_ERROR_CONNECTION_FAILED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback used to shutdown the daemon
|
|
||||||
*/
|
|
||||||
static job_requeue_t shutdown_callback(void *data)
|
|
||||||
{
|
|
||||||
kill(0, SIGTERM);
|
|
||||||
return JOB_REQUEUE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(listener_t, child_updown, bool,
|
|
||||||
private_android_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
|
||||||
bool up)
|
|
||||||
{
|
|
||||||
if (this->ike_sa == ike_sa)
|
|
||||||
{
|
|
||||||
if (up)
|
|
||||||
{
|
|
||||||
/* disable the hooks registered to catch initiation failures */
|
|
||||||
this->public.listener.ike_updown = NULL;
|
|
||||||
this->public.listener.child_state_change = NULL;
|
|
||||||
property_set("vpn.status", "ok");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
callback_job_t *job;
|
|
||||||
/* the control socket is closed as soon as vpn.status is set to "ok"
|
|
||||||
* and the daemon proxy then only checks for terminated daemons to
|
|
||||||
* detect lost connections, so... */
|
|
||||||
DBG1(DBG_CFG, "connection lost, raising delayed SIGTERM");
|
|
||||||
/* to avoid any conflicts we send the SIGTERM not directly from this
|
|
||||||
* callback, but from a different thread. we also delay it to avoid
|
|
||||||
* a race condition during a regular shutdown */
|
|
||||||
job = callback_job_create(shutdown_callback, NULL, NULL, NULL);
|
|
||||||
lib->scheduler->schedule_job(lib->scheduler, (job_t*)job, 1);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a string argument from the Android control socket
|
|
||||||
*/
|
|
||||||
static char *read_argument(int fd, u_char length)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
char *data = malloc(length + 1);
|
|
||||||
while (offset < length)
|
|
||||||
{
|
|
||||||
int n = recv(fd, &data[offset], length - offset, 0);
|
|
||||||
if (n < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "failed to read argument from Android"
|
|
||||||
" control socket: %s", strerror(errno));
|
|
||||||
free(data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
offset += n;
|
|
||||||
}
|
|
||||||
data[length] = '\0';
|
|
||||||
DBG3(DBG_CFG, "received argument from Android control socket: %s", data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle the request received from the Android control socket
|
|
||||||
*/
|
|
||||||
static job_requeue_t initiate(private_android_service_t *this)
|
|
||||||
{
|
|
||||||
bool oldstate;
|
|
||||||
int fd, i = 0;
|
|
||||||
char *hostname = NULL, *cacert = NULL, *username = NULL, *password = NULL;
|
|
||||||
identification_t *gateway = NULL, *user = NULL;
|
|
||||||
ike_cfg_t *ike_cfg;
|
|
||||||
peer_cfg_t *peer_cfg;
|
|
||||||
child_cfg_t *child_cfg;
|
|
||||||
traffic_selector_t *ts;
|
|
||||||
ike_sa_t *ike_sa;
|
|
||||||
auth_cfg_t *auth;
|
|
||||||
lifetime_cfg_t lifetime = {
|
|
||||||
.time = {
|
|
||||||
.life = 10800, /* 3h */
|
|
||||||
.rekey = 10200, /* 2h50min */
|
|
||||||
.jitter = 300 /* 5min */
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fd = accept(this->control, NULL, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "accept on Android control socket failed: %s",
|
|
||||||
strerror(errno));
|
|
||||||
return JOB_REQUEUE_NONE;
|
|
||||||
}
|
|
||||||
/* the original control socket is not used anymore */
|
|
||||||
close(this->control);
|
|
||||||
this->control = fd;
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
u_char length;
|
|
||||||
if (recv(fd, &length, 1, 0) != 1)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "failed to read from Android control socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
return JOB_REQUEUE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length == 0xFF)
|
|
||||||
{ /* last argument */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (i++)
|
|
||||||
{
|
|
||||||
case 0: /* gateway */
|
|
||||||
hostname = read_argument(fd, length);
|
|
||||||
break;
|
|
||||||
case 1: /* CA certificate name */
|
|
||||||
cacert = read_argument(fd, length);
|
|
||||||
break;
|
|
||||||
case 2: /* username */
|
|
||||||
username = read_argument(fd, length);
|
|
||||||
break;
|
|
||||||
case 3: /* password */
|
|
||||||
password = read_argument(fd, length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cacert)
|
|
||||||
{
|
|
||||||
if (!this->creds->add_certificate(this->creds, cacert))
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "failed to load CA certificate");
|
|
||||||
}
|
|
||||||
/* if this is a server cert we could use the cert subject as id
|
|
||||||
* but we have to test first if that possible to configure */
|
|
||||||
}
|
|
||||||
|
|
||||||
gateway = identification_create_from_string(hostname);
|
|
||||||
DBG1(DBG_CFG, "using CA certificate, gateway identitiy '%Y'", gateway);
|
|
||||||
|
|
||||||
if (username)
|
|
||||||
{
|
|
||||||
user = identification_create_from_string(username);
|
|
||||||
this->creds->set_username_password(this->creds, user, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE,
|
|
||||||
charon->socket->get_port(charon->socket, FALSE),
|
|
||||||
hostname, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO,
|
|
||||||
0);
|
|
||||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
|
||||||
|
|
||||||
peer_cfg = peer_cfg_create("android", ike_cfg, CERT_SEND_IF_ASKED,
|
|
||||||
UNIQUE_REPLACE, 1, /* keyingtries */
|
|
||||||
36000, 0, /* rekey 10h, reauth none */
|
|
||||||
600, 600, /* jitter, over 10min */
|
|
||||||
TRUE, FALSE, /* mobike, aggressive */
|
|
||||||
0, 0, /* DPD delay, timeout */
|
|
||||||
FALSE, NULL, NULL); /* mediation */
|
|
||||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
|
||||||
|
|
||||||
auth = auth_cfg_create();
|
|
||||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
|
|
||||||
auth->add(auth, AUTH_RULE_IDENTITY, user);
|
|
||||||
peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
|
|
||||||
auth = auth_cfg_create();
|
|
||||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
|
|
||||||
auth->add(auth, AUTH_RULE_IDENTITY, gateway);
|
|
||||||
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
|
|
||||||
|
|
||||||
child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
|
|
||||||
ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
|
|
||||||
0, 0, NULL, NULL, 0);
|
|
||||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
|
||||||
ts = traffic_selector_create_dynamic(0, 0, 65535);
|
|
||||||
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
|
|
||||||
ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "0.0.0.0",
|
|
||||||
0, "255.255.255.255", 65535);
|
|
||||||
child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
|
|
||||||
peer_cfg->add_child_cfg(peer_cfg, child_cfg);
|
|
||||||
|
|
||||||
/* get us an IKE_SA */
|
|
||||||
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
|
|
||||||
}
|
|
||||||
peer_cfg->destroy(peer_cfg);
|
|
||||||
|
|
||||||
/* store the IKE_SA so we can track its progress */
|
|
||||||
this->ike_sa = ike_sa;
|
|
||||||
|
|
||||||
/* confirm that we received the request */
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "failed to initiate tunnel");
|
|
||||||
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
|
||||||
ike_sa);
|
|
||||||
send_status(this, VPN_ERROR_CONNECTION_FAILED);
|
|
||||||
return JOB_REQUEUE_NONE;
|
|
||||||
}
|
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
|
||||||
return JOB_REQUEUE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(android_service_t, destroy, void,
|
|
||||||
private_android_service_t *this)
|
|
||||||
{
|
|
||||||
charon->bus->remove_listener(charon->bus, &this->public.listener);
|
|
||||||
close(this->control);
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See header
|
|
||||||
*/
|
|
||||||
android_service_t *android_service_create(android_creds_t *creds)
|
|
||||||
{
|
|
||||||
private_android_service_t *this;
|
|
||||||
|
|
||||||
INIT(this,
|
|
||||||
.public = {
|
|
||||||
.listener = {
|
|
||||||
.ike_updown = _ike_updown,
|
|
||||||
.child_state_change = _child_state_change,
|
|
||||||
.child_updown = _child_updown,
|
|
||||||
.ike_rekey = _ike_rekey,
|
|
||||||
},
|
|
||||||
.destroy = _destroy,
|
|
||||||
},
|
|
||||||
.creds = creds,
|
|
||||||
);
|
|
||||||
|
|
||||||
this->control = android_get_control_socket("charon");
|
|
||||||
if (this->control == -1)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "failed to get Android control socket");
|
|
||||||
free(this);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listen(this->control, 1) < 0)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "failed to listen on Android control socket: %s",
|
|
||||||
strerror(errno));
|
|
||||||
close(this->control);
|
|
||||||
free(this);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
charon->bus->add_listener(charon->bus, &this->public.listener);
|
|
||||||
lib->processor->queue_job(lib->processor,
|
|
||||||
(job_t*)callback_job_create((callback_job_cb_t)initiate, this,
|
|
||||||
NULL, NULL));
|
|
||||||
|
|
||||||
return &this->public;
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 Tobias Brunner
|
|
||||||
* 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
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup android_service android_service
|
|
||||||
* @{ @ingroup android
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ANDROID_SERVICE_H_
|
|
||||||
#define ANDROID_SERVICE_H_
|
|
||||||
|
|
||||||
typedef struct android_service_t android_service_t;
|
|
||||||
|
|
||||||
#include <bus/listeners/listener.h>
|
|
||||||
|
|
||||||
#include "android_creds.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service that interacts with the Android Settings frontend.
|
|
||||||
*/
|
|
||||||
struct android_service_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements listener_t.
|
|
||||||
*/
|
|
||||||
listener_t listener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy a android_service_t.
|
|
||||||
*/
|
|
||||||
void (*destroy)(android_service_t *this);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an Android service instance.
|
|
||||||
*
|
|
||||||
* @param creds Android credentials
|
|
||||||
*/
|
|
||||||
android_service_t *android_service_create(android_creds_t *creds);
|
|
||||||
|
|
||||||
#endif /** ANDROID_SERVICE_H_ @}*/
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
|
||||||
|
-I$(top_srcdir)/src/libcharon
|
||||||
|
|
||||||
|
AM_CFLAGS = -rdynamic
|
||||||
|
|
||||||
|
if MONOLITHIC
|
||||||
|
noinst_LTLIBRARIES = libstrongswan-android-dns.la
|
||||||
|
else
|
||||||
|
plugin_LTLIBRARIES = libstrongswan-android-dns.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
libstrongswan_android_dns_la_SOURCES = \
|
||||||
|
android_dns_plugin.c android_dns_plugin.h \
|
||||||
|
android_dns_handler.c android_dns_handler.h
|
||||||
|
|
||||||
|
libstrongswan_android_dns_la_LDFLAGS = -module -avoid-version
|
||||||
|
libstrongswan_android_dns_la_LIBADD = -lcutils
|
||||||
+23
-28
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2011 Tobias Brunner
|
* Copyright (C) 2010-2013 Tobias Brunner
|
||||||
* Copyright (C) 2010 Martin Willi
|
* Copyright (C) 2010 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -14,41 +14,35 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "android_handler.h"
|
#include "android_dns_handler.h"
|
||||||
|
|
||||||
#include <networking/host.h>
|
#include <networking/host.h>
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
|
|
||||||
#include <cutils/properties.h>
|
#include <cutils/properties.h>
|
||||||
|
|
||||||
typedef struct private_android_handler_t private_android_handler_t;
|
typedef struct private_android_dns_handler_t private_android_dns_handler_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of an android_handler_t object.
|
* Private data of an android_dns_handler_t object.
|
||||||
*/
|
*/
|
||||||
struct private_android_handler_t {
|
struct private_android_dns_handler_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public android_handler_t interface.
|
* Public interface
|
||||||
*/
|
*/
|
||||||
android_handler_t public;
|
android_dns_handler_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of registered DNS servers
|
* List of registered DNS servers
|
||||||
*/
|
*/
|
||||||
linked_list_t *dns;
|
linked_list_t *dns;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the VPN frontend is used
|
|
||||||
*/
|
|
||||||
bool frontend;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefixes to be used when installing DNS servers
|
* Prefix to be used when installing DNS servers
|
||||||
*/
|
*/
|
||||||
#define DNS_PREFIX_DEFAULT "net"
|
#define DNS_PREFIX_DEFAULT "net"
|
||||||
#define DNS_PREFIX_FRONTEND "vpn"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct to store a pair of old and installed DNS servers
|
* Struct to store a pair of old and installed DNS servers
|
||||||
@@ -63,7 +57,7 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
* Destroy a pair of old and installed DNS servers
|
* Destroy a pair of old and installed DNS servers
|
||||||
*/
|
*/
|
||||||
void destroy_dns_pair(dns_pair_t *this)
|
static void destroy_dns_pair(dns_pair_t *this)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->dns);
|
DESTROY_IF(this->dns);
|
||||||
DESTROY_IF(this->old);
|
DESTROY_IF(this->old);
|
||||||
@@ -73,7 +67,7 @@ void destroy_dns_pair(dns_pair_t *this)
|
|||||||
/**
|
/**
|
||||||
* Filter pairs of DNS servers
|
* Filter pairs of DNS servers
|
||||||
*/
|
*/
|
||||||
bool filter_dns_pair(void *data, dns_pair_t **in, host_t **out)
|
static bool filter_dns_pair(void *data, dns_pair_t **in, host_t **out)
|
||||||
{
|
{
|
||||||
*out = (*in)->dns;
|
*out = (*in)->dns;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -82,11 +76,11 @@ bool filter_dns_pair(void *data, dns_pair_t **in, host_t **out)
|
|||||||
/**
|
/**
|
||||||
* Read DNS server property with a given index
|
* Read DNS server property with a given index
|
||||||
*/
|
*/
|
||||||
host_t *get_dns_server(private_android_handler_t *this, int index)
|
static host_t *get_dns_server(private_android_dns_handler_t *this, int index)
|
||||||
{
|
{
|
||||||
host_t *dns = NULL;
|
host_t *dns = NULL;
|
||||||
char key[10], value[PROPERTY_VALUE_MAX],
|
char key[10], value[PROPERTY_VALUE_MAX],
|
||||||
*prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT;
|
*prefix = DNS_PREFIX_DEFAULT;
|
||||||
|
|
||||||
if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
|
if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
|
||||||
{
|
{
|
||||||
@@ -103,10 +97,11 @@ host_t *get_dns_server(private_android_handler_t *this, int index)
|
|||||||
/**
|
/**
|
||||||
* Set DNS server property with a given index
|
* Set DNS server property with a given index
|
||||||
*/
|
*/
|
||||||
bool set_dns_server(private_android_handler_t *this, int index, host_t *dns)
|
static bool set_dns_server(private_android_dns_handler_t *this, int index,
|
||||||
|
host_t *dns)
|
||||||
{
|
{
|
||||||
char key[10], value[PROPERTY_VALUE_MAX],
|
char key[10], value[PROPERTY_VALUE_MAX],
|
||||||
*prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT;
|
*prefix = DNS_PREFIX_DEFAULT;
|
||||||
|
|
||||||
if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
|
if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
|
||||||
{
|
{
|
||||||
@@ -133,7 +128,7 @@ bool set_dns_server(private_android_handler_t *this, int index, host_t *dns)
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(attribute_handler_t, handle, bool,
|
METHOD(attribute_handler_t, handle, bool,
|
||||||
private_android_handler_t *this, identification_t *id,
|
private_android_dns_handler_t *this, identification_t *id,
|
||||||
configuration_attribute_type_t type, chunk_t data)
|
configuration_attribute_type_t type, chunk_t data)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -163,7 +158,7 @@ METHOD(attribute_handler_t, handle, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(attribute_handler_t, release, void,
|
METHOD(attribute_handler_t, release, void,
|
||||||
private_android_handler_t *this, identification_t *server,
|
private_android_dns_handler_t *this, identification_t *server,
|
||||||
configuration_attribute_type_t type, chunk_t data)
|
configuration_attribute_type_t type, chunk_t data)
|
||||||
{
|
{
|
||||||
if (type == INTERNAL_IP4_DNS)
|
if (type == INTERNAL_IP4_DNS)
|
||||||
@@ -197,7 +192,8 @@ METHOD(enumerator_t, enumerate_dns, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
||||||
android_handler_t *this, identification_t *id, linked_list_t *vips)
|
private_android_dns_handler_t *this, identification_t *id,
|
||||||
|
linked_list_t *vips)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
@@ -208,8 +204,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
|||||||
return enumerator;
|
return enumerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(android_handler_t, destroy, void,
|
METHOD(android_dns_handler_t, destroy, void,
|
||||||
private_android_handler_t *this)
|
private_android_dns_handler_t *this)
|
||||||
{
|
{
|
||||||
this->dns->destroy_function(this->dns, (void*)destroy_dns_pair);
|
this->dns->destroy_function(this->dns, (void*)destroy_dns_pair);
|
||||||
free(this);
|
free(this);
|
||||||
@@ -218,9 +214,9 @@ METHOD(android_handler_t, destroy, void,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
android_handler_t *android_handler_create(bool frontend)
|
android_dns_handler_t *android_dns_handler_create()
|
||||||
{
|
{
|
||||||
private_android_handler_t *this;
|
private_android_dns_handler_t *this;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
@@ -232,7 +228,6 @@ android_handler_t *android_handler_create(bool frontend)
|
|||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.dns = linked_list_create(),
|
.dns = linked_list_create(),
|
||||||
.frontend = frontend,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
+11
-13
@@ -15,21 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup android_handler android_handler
|
* @defgroup android_dns_handler android_dns_handler
|
||||||
* @{ @ingroup android
|
* @{ @ingroup android_dns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ANDROID_HANDLER_H_
|
#ifndef ANDROID_DNS_HANDLER_H_
|
||||||
#define ANDROID_HANDLER_H_
|
#define ANDROID_DNS_HANDLER_H_
|
||||||
|
|
||||||
#include <attributes/attribute_handler.h>
|
#include <attributes/attribute_handler.h>
|
||||||
|
|
||||||
typedef struct android_handler_t android_handler_t;
|
typedef struct android_dns_handler_t android_dns_handler_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Android specific DNS attribute handler.
|
* Android specific DNS attribute handler.
|
||||||
*/
|
*/
|
||||||
struct android_handler_t {
|
struct android_dns_handler_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements attribute_handler_t.
|
* Implements attribute_handler_t.
|
||||||
@@ -37,16 +37,14 @@ struct android_handler_t {
|
|||||||
attribute_handler_t handler;
|
attribute_handler_t handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a android_handler_t.
|
* Destroy a android_dns_handler_t.
|
||||||
*/
|
*/
|
||||||
void (*destroy)(android_handler_t *this);
|
void (*destroy)(android_dns_handler_t *this);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a android_handler instance.
|
* Create an android_dns_handler_t instance.
|
||||||
*
|
|
||||||
* @param frontend TRUE if the VPN frontend is used
|
|
||||||
*/
|
*/
|
||||||
android_handler_t *android_handler_create(bool frontend);
|
android_dns_handler_t *android_dns_handler_create();
|
||||||
|
|
||||||
#endif /** ANDROID_HANDLER_H_ @}*/
|
#endif /** ANDROID_DNS_HANDLER_H_ @}*/
|
||||||
+15
-36
@@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Tobias Brunner
|
* Copyright (C) 2010-2013 Tobias Brunner
|
||||||
* Copyright (C) 2010 Martin Willi
|
|
||||||
* Hochschule fuer Technik Rapperswil
|
* 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
|
||||||
@@ -14,66 +13,51 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "android_plugin.h"
|
#include "android_dns_plugin.h"
|
||||||
#include "android_handler.h"
|
#include "android_dns_handler.h"
|
||||||
#include "android_creds.h"
|
|
||||||
#include "android_service.h"
|
|
||||||
|
|
||||||
#include <hydra.h>
|
#include <hydra.h>
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
|
|
||||||
typedef struct private_android_plugin_t private_android_plugin_t;
|
typedef struct private_android_dns_plugin_t private_android_dns_plugin_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of an android_plugin_t object.
|
* Private data of an android_dns_plugin_t object.
|
||||||
*/
|
*/
|
||||||
struct private_android_plugin_t {
|
struct private_android_dns_plugin_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public android_plugin_t interface.
|
* Public interface
|
||||||
*/
|
*/
|
||||||
android_plugin_t public;
|
android_dns_plugin_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Android specific DNS handler
|
* Android specific DNS handler
|
||||||
*/
|
*/
|
||||||
android_handler_t *handler;
|
android_dns_handler_t *handler;
|
||||||
|
|
||||||
/**
|
|
||||||
* Android specific credential set
|
|
||||||
*/
|
|
||||||
android_creds_t *creds;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service that interacts with the Android Settings frontend
|
|
||||||
*/
|
|
||||||
android_service_t *service;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(plugin_t, get_name, char*,
|
METHOD(plugin_t, get_name, char*,
|
||||||
private_android_plugin_t *this)
|
private_android_dns_plugin_t *this)
|
||||||
{
|
{
|
||||||
return "android";
|
return "android-dns";
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(plugin_t, destroy, void,
|
METHOD(plugin_t, destroy, void,
|
||||||
private_android_plugin_t *this)
|
private_android_dns_plugin_t *this)
|
||||||
{
|
{
|
||||||
hydra->attributes->remove_handler(hydra->attributes,
|
hydra->attributes->remove_handler(hydra->attributes,
|
||||||
&this->handler->handler);
|
&this->handler->handler);
|
||||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
|
||||||
this->creds->destroy(this->creds);
|
|
||||||
this->handler->destroy(this->handler);
|
this->handler->destroy(this->handler);
|
||||||
DESTROY_IF(this->service);
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
plugin_t *android_plugin_create()
|
plugin_t *android_dns_plugin_create()
|
||||||
{
|
{
|
||||||
private_android_plugin_t *this;
|
private_android_dns_plugin_t *this;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
@@ -83,15 +67,10 @@ plugin_t *android_plugin_create()
|
|||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.creds = android_creds_create(),
|
.handler = android_dns_handler_create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
this->service = android_service_create(this->creds);
|
|
||||||
this->handler = android_handler_create(this->service != NULL);
|
|
||||||
|
|
||||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
|
||||||
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
||||||
|
|
||||||
return &this->public.plugin;
|
return &this->public.plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
+10
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Martin Willi
|
* Copyright (C) 2013 Tobias Brunner
|
||||||
* Hochschule fuer Technik Rapperswil
|
* 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
|
||||||
@@ -14,24 +14,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup android android
|
* @defgroup android_dns android_dns
|
||||||
* @ingroup cplugins
|
* @ingroup cplugins
|
||||||
*
|
*
|
||||||
* @defgroup android_plugin android_plugin
|
* @defgroup android_dns_plugin android_dns_plugin
|
||||||
* @{ @ingroup android
|
* @{ @ingroup android_dns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ANDROID_PLUGIN_H_
|
#ifndef ANDROID_DNS_PLUGIN_H_
|
||||||
#define ANDROID_PLUGIN_H_
|
#define ANDROID_DNS_PLUGIN_H_
|
||||||
|
|
||||||
#include <plugins/plugin.h>
|
#include <plugins/plugin.h>
|
||||||
|
|
||||||
typedef struct android_plugin_t android_plugin_t;
|
typedef struct android_dns_plugin_t android_dns_plugin_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin providing functionality specific to the Android platform.
|
* Plugin providing an Android-specific handler for DNS servers.
|
||||||
*/
|
*/
|
||||||
struct android_plugin_t {
|
struct android_dns_plugin_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements plugin interface.
|
* Implements plugin interface.
|
||||||
@@ -39,4 +39,4 @@ struct android_plugin_t {
|
|||||||
plugin_t plugin;
|
plugin_t plugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /** ANDROID_PLUGIN_H_ @}*/
|
#endif /** ANDROID_DNS_PLUGIN_H_ @}*/
|
||||||
Reference in New Issue
Block a user