mirror of
https://github.com/strongswan/strongswan.git
synced 2025-12-04 00:00:21 -05:00
Native counterpart of VpnService.Builder added, exposed by charonservice
This commit is contained in:
parent
5215d512bf
commit
ae4f1ea180
@ -8,7 +8,8 @@ backend/android_creds.c backend/android_creds.h \
|
||||
backend/android_service.c backend/android_service.h \
|
||||
charonservice.c charonservice.h \
|
||||
kernel/android_ipsec.c kernel/android_ipsec.h \
|
||||
kernel/android_net.c kernel/android_net.h
|
||||
kernel/android_net.c kernel/android_net.h \
|
||||
vpnservice_builder.c vpnservice_builder.h
|
||||
|
||||
# build libandroidbridge -------------------------------------------------------
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
static JavaVM *android_jvm;
|
||||
|
||||
jclass *android_charonvpnservice_class;
|
||||
jclass *android_charonvpnservice_builder_class;
|
||||
|
||||
/**
|
||||
* Thread-local variable. Only used because of the destructor
|
||||
@ -88,6 +89,9 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
android_charonvpnservice_class =
|
||||
(*env)->NewGlobalRef(env, (*env)->FindClass(env,
|
||||
JNI_PACKAGE_STRING "/CharonVpnService"));
|
||||
android_charonvpnservice_builder_class =
|
||||
(*env)->NewGlobalRef(env, (*env)->FindClass(env,
|
||||
JNI_PACKAGE_STRING "/CharonVpnService$BuilderAdapter"));
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
* Initialized in JNI_OnLoad()
|
||||
*/
|
||||
extern jclass *android_charonvpnservice_class;
|
||||
extern jclass *android_charonvpnservice_builder_class;
|
||||
|
||||
/**
|
||||
* Attach the current thread to the JVM
|
||||
|
||||
@ -56,6 +56,11 @@ struct private_charonservice_t {
|
||||
*/
|
||||
android_service_t *service;
|
||||
|
||||
/**
|
||||
* VpnService builder (accessed via JNI)
|
||||
*/
|
||||
vpnservice_builder_t *builder;
|
||||
|
||||
/**
|
||||
* CharonVpnService reference
|
||||
*/
|
||||
@ -201,6 +206,12 @@ failed:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
METHOD(charonservice_t, get_vpnservice_builder, vpnservice_builder_t*,
|
||||
private_charonservice_t *this)
|
||||
{
|
||||
return this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a new connection
|
||||
*
|
||||
@ -248,7 +259,7 @@ static bool charonservice_register(void *plugin, plugin_feature_t *feature,
|
||||
/**
|
||||
* Initialize the charonservice object
|
||||
*/
|
||||
static void charonservice_init(JNIEnv *env, jobject service)
|
||||
static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
||||
{
|
||||
private_charonservice_t *this;
|
||||
static plugin_feature_t features[] = {
|
||||
@ -266,8 +277,10 @@ static void charonservice_init(JNIEnv *env, jobject service)
|
||||
.update_status = _update_status,
|
||||
.bypass_socket = _bypass_socket,
|
||||
.get_trusted_certificates = _get_trusted_certificates,
|
||||
.get_vpnservice_builder = _get_vpnservice_builder,
|
||||
},
|
||||
.creds = android_creds_create(),
|
||||
.builder = vpnservice_builder_create(builder),
|
||||
.vpn_service = (*env)->NewGlobalRef(env, service),
|
||||
);
|
||||
charonservice = &this->public;
|
||||
@ -286,6 +299,7 @@ static void charonservice_deinit(JNIEnv *env)
|
||||
{
|
||||
private_charonservice_t *this = (private_charonservice_t*)charonservice;
|
||||
|
||||
this->builder->destroy(this->builder);
|
||||
this->creds->destroy(this->creds);
|
||||
(*env)->DeleteGlobalRef(env, this->vpn_service);
|
||||
free(this);
|
||||
@ -305,7 +319,8 @@ static void segv_handler(int signal)
|
||||
/**
|
||||
* Initialize charon and the libraries via JNI
|
||||
*/
|
||||
JNI_METHOD(CharonVpnService, initializeCharon, void)
|
||||
JNI_METHOD(CharonVpnService, initializeCharon, void,
|
||||
jobject builder)
|
||||
{
|
||||
struct sigaction action;
|
||||
|
||||
@ -334,7 +349,7 @@ JNI_METHOD(CharonVpnService, initializeCharon, void)
|
||||
return;
|
||||
}
|
||||
|
||||
charonservice_init(env, this);
|
||||
charonservice_init(env, this, builder);
|
||||
|
||||
if (!libcharon_init("charon") ||
|
||||
!charon->initialize(charon, PLUGINS))
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
#ifndef CHARONSERVICE_H_
|
||||
#define CHARONSERVICE_H_
|
||||
|
||||
#include "vpnservice_builder.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
@ -83,6 +85,13 @@ struct charonservice_t {
|
||||
*/
|
||||
linked_list_t *(*get_trusted_certificates)(charonservice_t *this);
|
||||
|
||||
/**
|
||||
* Get the current vpnservice_builder_t object
|
||||
*
|
||||
* @return VpnService.Builder instance
|
||||
*/
|
||||
vpnservice_builder_t *(*get_vpnservice_builder)(charonservice_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
274
src/frontends/android/jni/libandroidbridge/vpnservice_builder.c
Normal file
274
src/frontends/android/jni/libandroidbridge/vpnservice_builder.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012 Giuliano Grassi
|
||||
* Copyright (C) 2012 Ralf Sager
|
||||
* 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 "vpnservice_builder.h"
|
||||
#include "android_jni.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <library.h>
|
||||
|
||||
typedef struct private_vpnservice_builder_t private_vpnservice_builder_t;
|
||||
|
||||
/**
|
||||
* private data of vpnservice_builder
|
||||
*/
|
||||
struct private_vpnservice_builder_t {
|
||||
|
||||
/**
|
||||
* public interface
|
||||
*/
|
||||
vpnservice_builder_t public;
|
||||
|
||||
/**
|
||||
* Java object
|
||||
*/
|
||||
jobject builder;
|
||||
};
|
||||
|
||||
METHOD(vpnservice_builder_t, add_address, bool,
|
||||
private_vpnservice_builder_t *this, host_t *addr)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
jstring str;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
DBG2(DBG_LIB, "builder: adding interface address %H", addr);
|
||||
|
||||
if (addr->get_family(addr) != AF_INET)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (snprintf(buf, sizeof(buf), "%H", addr) >= sizeof(buf))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
|
||||
method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
|
||||
"addAddress", "(Ljava/lang/String;I)Z");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
str = (*env)->NewStringUTF(env, buf);
|
||||
if (!str)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, 32))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
androidjni_detach_thread();
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
DBG1(DBG_LIB, "builder: failed to add address");
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(vpnservice_builder_t, set_mtu, bool,
|
||||
private_vpnservice_builder_t *this, int mtu)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
DBG2(DBG_LIB, "builder: setting MTU to %d", mtu);
|
||||
|
||||
method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
|
||||
"setMtu", "(I)Z");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!(*env)->CallBooleanMethod(env, this->builder, method_id, mtu))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
androidjni_detach_thread();
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
DBG1(DBG_LIB, "builder: failed to set MTU");
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(vpnservice_builder_t, add_route, bool,
|
||||
private_vpnservice_builder_t *this, host_t *net, int prefix)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
jstring str;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
DBG2(DBG_LIB, "builder: adding route %+H/%d", net, prefix);
|
||||
|
||||
if (net->get_family(net) != AF_INET)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (snprintf(buf, sizeof(buf), "%+H", net) >= sizeof(buf))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
|
||||
method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
|
||||
"addRoute", "(Ljava/lang/String;I)Z");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
str = (*env)->NewStringUTF(env, buf);
|
||||
if (!str)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str, prefix))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
androidjni_detach_thread();
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
DBG1(DBG_LIB, "builder: failed to add route");
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(vpnservice_builder_t, add_dns, bool,
|
||||
private_vpnservice_builder_t *this, host_t *dns)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
jstring str;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
DBG2(DBG_LIB, "builder: adding DNS server %H", dns);
|
||||
|
||||
if (dns->get_family(dns) != AF_INET)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (snprintf(buf, sizeof(buf), "%H", dns) >= sizeof(buf))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
|
||||
method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
|
||||
"addDnsServer", "(Ljava/lang/String;)Z");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
str = (*env)->NewStringUTF(env, buf);
|
||||
if (!str)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
if (!(*env)->CallBooleanMethod(env, this->builder, method_id, str))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
androidjni_detach_thread();
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
DBG1(DBG_LIB, "builder: failed to add DNS server");
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(vpnservice_builder_t, establish, int,
|
||||
private_vpnservice_builder_t *this)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
int fd;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
DBG2(DBG_LIB, "builder: building TUN device");
|
||||
|
||||
method_id = (*env)->GetMethodID(env, android_charonvpnservice_builder_class,
|
||||
"establish", "()I");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
fd = (*env)->CallIntMethod(env, this->builder, method_id);
|
||||
if (fd == -1)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
androidjni_detach_thread();
|
||||
return fd;
|
||||
|
||||
failed:
|
||||
DBG1(DBG_LIB, "builder: failed to build TUN device");
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return -1;
|
||||
}
|
||||
|
||||
METHOD(vpnservice_builder_t, destroy, void,
|
||||
private_vpnservice_builder_t *this)
|
||||
{
|
||||
JNIEnv *env;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
(*env)->DeleteGlobalRef(env, this->builder);
|
||||
androidjni_detach_thread();
|
||||
free(this);
|
||||
}
|
||||
|
||||
vpnservice_builder_t *vpnservice_builder_create(jobject builder)
|
||||
{
|
||||
JNIEnv *env;
|
||||
private_vpnservice_builder_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add_address = _add_address,
|
||||
.add_route = _add_route,
|
||||
.add_dns = _add_dns,
|
||||
.set_mtu = _set_mtu,
|
||||
.establish = _establish,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
);
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
this->builder = (*env)->NewGlobalRef(env, builder);
|
||||
androidjni_detach_thread();
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012 Giuliano Grassi
|
||||
* Copyright (C) 2012 Ralf Sager
|
||||
* 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 vpnservice_builder vpnservice_builder
|
||||
* @{ @ingroup libandroidbridge
|
||||
*/
|
||||
|
||||
#ifndef VPNSERVICE_BUILDER_H_
|
||||
#define VPNSERVICE_BUILDER_H_
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/host.h>
|
||||
|
||||
typedef struct vpnservice_builder_t vpnservice_builder_t;
|
||||
|
||||
/**
|
||||
* VpnService.Builder, used to build a TUN device.
|
||||
*
|
||||
* Communicates with CharonVpnService.BuilderAdapter via JNI
|
||||
*/
|
||||
struct vpnservice_builder_t {
|
||||
|
||||
/**
|
||||
* Add an interface address
|
||||
*
|
||||
* @param addr the desired interface address
|
||||
* @return TRUE on success
|
||||
*/
|
||||
bool (*add_address)(vpnservice_builder_t *this, host_t *addr);
|
||||
|
||||
/**
|
||||
* Add a route
|
||||
*
|
||||
* @param net the network address
|
||||
* @param prefix_length the prefix length
|
||||
* @return TRUE on success
|
||||
*/
|
||||
bool (*add_route)(vpnservice_builder_t *this, host_t *net, int prefix);
|
||||
|
||||
/**
|
||||
* Add a DNS server
|
||||
*
|
||||
* @param dns the address of the DNS server
|
||||
* @return TRUE on success
|
||||
*/
|
||||
bool (*add_dns)(vpnservice_builder_t *this, host_t *dns);
|
||||
|
||||
/**
|
||||
* Set the MTU for the TUN device
|
||||
*
|
||||
* @param mtu the MTU to set
|
||||
* @return TRUE on success
|
||||
*/
|
||||
bool (*set_mtu)(vpnservice_builder_t *this, int mtu);
|
||||
|
||||
/**
|
||||
* Build the TUN device
|
||||
*
|
||||
* @return the TUN file descriptor, -1 if failed
|
||||
*/
|
||||
int (*establish)(vpnservice_builder_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a vpnservice_builder
|
||||
*/
|
||||
void (*destroy)(vpnservice_builder_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a vpnservice_builder instance
|
||||
*
|
||||
* @param builder CharonVpnService.BuilderAdapter object
|
||||
* @return vpnservice_builder_t instance
|
||||
*/
|
||||
vpnservice_builder_t *vpnservice_builder_create(jobject builder);
|
||||
|
||||
#endif /** VPNSERVICE_BUILDER_H_ @}*/
|
||||
@ -193,7 +193,8 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
setError(ErrorState.NO_ERROR);
|
||||
setState(State.CONNECTING);
|
||||
|
||||
initializeCharon();
|
||||
BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName());
|
||||
initializeCharon(builder);
|
||||
Log.i(TAG, "charon started");
|
||||
|
||||
String local_address = getLocalIPv4Address();
|
||||
@ -401,8 +402,10 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
|
||||
/**
|
||||
* Initialization of charon, provided by libandroidbridge.so
|
||||
*
|
||||
* @param builder BuilderAdapter for this connection
|
||||
*/
|
||||
public native void initializeCharon();
|
||||
public native void initializeCharon(BuilderAdapter builder);
|
||||
|
||||
/**
|
||||
* Deinitialize charon, provided by libandroidbridge.so
|
||||
@ -450,6 +453,7 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
|
||||
/**
|
||||
* Adapter for VpnService.Builder which is used to access it safely via JNI.
|
||||
* There is a corresponding C object to access it from native code.
|
||||
*/
|
||||
public class BuilderAdapter
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user