Removed backend for old Android frontend patch
Moved the remaining DNS handler to a new plugin.laforge/swu
parent
b038c62e4a
commit
9804fccea3
|
@ -17,7 +17,7 @@ include $(CLEAR_VARS)
|
|||
# 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)
|
||||
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
|
||||
|
||||
ifneq ($(strongswan_BUILD_SCEPCLIENT),)
|
||||
|
|
10
configure.in
10
configure.in
|
@ -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([unity], [enables Cisco Unity extension 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([maemo], [enable Maemo specific plugin.])
|
||||
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!])])
|
||||
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_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
|
||||
|
@ -1007,7 +1007,7 @@ ADD_PLUGIN([tnccs-dynamic], [c charon])
|
|||
ADD_PLUGIN([medsrv], [c charon])
|
||||
ADD_PLUGIN([medcli], [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([ha], [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_MEDCLI, test x$medcli = 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_MAEMO, test x$maemo = xtrue)
|
||||
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
|
||||
|
@ -1357,7 +1357,7 @@ AC_CONFIG_FILES([
|
|||
src/libcharon/plugins/duplicheck/Makefile
|
||||
src/libcharon/plugins/coupling/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/maemo/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
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, android)
|
||||
ifneq ($(call plugin_enabled, android),)
|
||||
LOCAL_C_INCLUDES += frameworks/base/cmds/keystore
|
||||
LOCAL_SRC_FILES += $(call add_plugin, android-dns)
|
||||
ifneq ($(call plugin_enabled, android-dns),)
|
||||
LOCAL_SHARED_LIBRARIES += libcutils
|
||||
endif
|
||||
|
||||
|
|
|
@ -457,10 +457,10 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_ANDROID
|
||||
SUBDIRS += plugins/android
|
||||
if USE_ANDROID_DNS
|
||||
SUBDIRS += plugins/android_dns
|
||||
if MONOLITHIC
|
||||
libcharon_la_LIBADD += plugins/android/libstrongswan-android.la
|
||||
libcharon_la_LIBADD += plugins/android_dns/libstrongswan-android-dns.la
|
||||
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
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2011 Tobias Brunner
|
||||
* Copyright (C) 2010-2013 Tobias Brunner
|
||||
* Copyright (C) 2010 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -14,41 +14,35 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
#include "android_handler.h"
|
||||
#include "android_dns_handler.h"
|
||||
|
||||
#include <networking/host.h>
|
||||
#include <collections/linked_list.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
|
||||
*/
|
||||
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_FRONTEND "vpn"
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void destroy_dns_pair(dns_pair_t *this)
|
||||
static void destroy_dns_pair(dns_pair_t *this)
|
||||
{
|
||||
DESTROY_IF(this->dns);
|
||||
DESTROY_IF(this->old);
|
||||
|
@ -73,7 +67,7 @@ void destroy_dns_pair(dns_pair_t *this)
|
|||
/**
|
||||
* 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;
|
||||
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
|
||||
*/
|
||||
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;
|
||||
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))
|
||||
{
|
||||
|
@ -103,10 +97,11 @@ host_t *get_dns_server(private_android_handler_t *this, int 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],
|
||||
*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))
|
||||
{
|
||||
|
@ -133,7 +128,7 @@ bool set_dns_server(private_android_handler_t *this, int index, host_t *dns)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -163,7 +158,7 @@ METHOD(attribute_handler_t, handle, bool,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (type == INTERNAL_IP4_DNS)
|
||||
|
@ -197,7 +192,8 @@ METHOD(enumerator_t, enumerate_dns, bool,
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -208,8 +204,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
|||
return enumerator;
|
||||
}
|
||||
|
||||
METHOD(android_handler_t, destroy, void,
|
||||
private_android_handler_t *this)
|
||||
METHOD(android_dns_handler_t, destroy, void,
|
||||
private_android_dns_handler_t *this)
|
||||
{
|
||||
this->dns->destroy_function(this->dns, (void*)destroy_dns_pair);
|
||||
free(this);
|
||||
|
@ -218,9 +214,9 @@ METHOD(android_handler_t, destroy, void,
|
|||
/**
|
||||
* 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,
|
||||
.public = {
|
||||
|
@ -232,7 +228,6 @@ android_handler_t *android_handler_create(bool frontend)
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.dns = linked_list_create(),
|
||||
.frontend = frontend,
|
||||
);
|
||||
|
||||
return &this->public;
|
|
@ -15,21 +15,21 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @defgroup android_handler android_handler
|
||||
* @{ @ingroup android
|
||||
* @defgroup android_dns_handler android_dns_handler
|
||||
* @{ @ingroup android_dns
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HANDLER_H_
|
||||
#define ANDROID_HANDLER_H_
|
||||
#ifndef ANDROID_DNS_HANDLER_H_
|
||||
#define ANDROID_DNS_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.
|
||||
*/
|
||||
struct android_handler_t {
|
||||
struct android_dns_handler_t {
|
||||
|
||||
/**
|
||||
* Implements attribute_handler_t.
|
||||
|
@ -37,16 +37,14 @@ struct android_handler_t {
|
|||
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.
|
||||
*
|
||||
* @param frontend TRUE if the VPN frontend is used
|
||||
* Create an android_dns_handler_t instance.
|
||||
*/
|
||||
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_ @}*/
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Tobias Brunner
|
||||
* Copyright (C) 2010 Martin Willi
|
||||
* Copyright (C) 2010-2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -14,66 +13,51 @@
|
|||
* for more details.
|
||||
*/
|
||||
|
||||
#include "android_plugin.h"
|
||||
#include "android_handler.h"
|
||||
#include "android_creds.h"
|
||||
#include "android_service.h"
|
||||
#include "android_dns_plugin.h"
|
||||
#include "android_dns_handler.h"
|
||||
|
||||
#include <hydra.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_handler_t *handler;
|
||||
|
||||
/**
|
||||
* Android specific credential set
|
||||
*/
|
||||
android_creds_t *creds;
|
||||
|
||||
/**
|
||||
* Service that interacts with the Android Settings frontend
|
||||
*/
|
||||
android_service_t *service;
|
||||
android_dns_handler_t *handler;
|
||||
};
|
||||
|
||||
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,
|
||||
private_android_plugin_t *this)
|
||||
private_android_dns_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->creds->destroy(this->creds);
|
||||
this->handler->destroy(this->handler);
|
||||
DESTROY_IF(this->service);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
.public = {
|
||||
|
@ -83,15 +67,10 @@ plugin_t *android_plugin_create()
|
|||
.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);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Martin Willi
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @defgroup android_plugin android_plugin
|
||||
* @{ @ingroup android
|
||||
* @defgroup android_dns_plugin android_dns_plugin
|
||||
* @{ @ingroup android_dns
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_PLUGIN_H_
|
||||
#define ANDROID_PLUGIN_H_
|
||||
#ifndef ANDROID_DNS_PLUGIN_H_
|
||||
#define ANDROID_DNS_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.
|
||||
|
@ -39,4 +39,4 @@ struct android_plugin_t {
|
|||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** ANDROID_PLUGIN_H_ @}*/
|
||||
#endif /** ANDROID_DNS_PLUGIN_H_ @}*/
|
Loading…
Reference in New Issue