Removed backend for old Android frontend patch

Moved the remaining DNS handler to a new plugin.
This commit is contained in:
Tobias Brunner 2013-03-02 15:57:00 +01:00
parent b038c62e4a
commit 9804fccea3
14 changed files with 88 additions and 929 deletions

View File

@ -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),)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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_ @}*/

View File

@ -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;
}

View File

@ -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_ @}*/

View File

@ -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

View File

@ -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;

View File

@ -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_ @}*/

View File

@ -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;
}

View File

@ -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_ @}*/