android: Determine source address dynamically
This commit is contained in:
@@ -58,11 +58,6 @@ struct private_android_service_t {
|
|||||||
*/
|
*/
|
||||||
char *type;
|
char *type;
|
||||||
|
|
||||||
/**
|
|
||||||
* local ipv4 address
|
|
||||||
*/
|
|
||||||
char *local_address;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gateway
|
* gateway
|
||||||
*/
|
*/
|
||||||
@@ -480,7 +475,7 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ike_cfg = ike_cfg_create(TRUE, TRUE, this->local_address, FALSE,
|
ike_cfg = ike_cfg_create(TRUE, TRUE, "0.0.0.0", FALSE,
|
||||||
charon->socket->get_port(charon->socket, FALSE),
|
charon->socket->get_port(charon->socket, FALSE),
|
||||||
this->gateway, FALSE, IKEV2_UDP_PORT);
|
this->gateway, FALSE, IKEV2_UDP_PORT);
|
||||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||||
@@ -591,7 +586,6 @@ METHOD(android_service_t, destroy, void,
|
|||||||
close_tun_device(this);
|
close_tun_device(this);
|
||||||
this->lock->destroy(this->lock);
|
this->lock->destroy(this->lock);
|
||||||
free(this->type);
|
free(this->type);
|
||||||
free(this->local_address);
|
|
||||||
free(this->gateway);
|
free(this->gateway);
|
||||||
free(this->username);
|
free(this->username);
|
||||||
if (this->password)
|
if (this->password)
|
||||||
@@ -606,8 +600,8 @@ METHOD(android_service_t, destroy, void,
|
|||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
android_service_t *android_service_create(android_creds_t *creds, char *type,
|
android_service_t *android_service_create(android_creds_t *creds, char *type,
|
||||||
char *local_address, char *gateway,
|
char *gateway, char *username,
|
||||||
char *username, char *password)
|
char *password)
|
||||||
{
|
{
|
||||||
private_android_service_t *this;
|
private_android_service_t *this;
|
||||||
|
|
||||||
@@ -624,7 +618,6 @@ android_service_t *android_service_create(android_creds_t *creds, char *type,
|
|||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||||
.local_address = local_address,
|
|
||||||
.username = username,
|
.username = username,
|
||||||
.password = password,
|
.password = password,
|
||||||
.gateway = gateway,
|
.gateway = gateway,
|
||||||
|
|||||||
@@ -53,13 +53,12 @@ struct android_service_t {
|
|||||||
*
|
*
|
||||||
* @param creds Android specific credential set
|
* @param creds Android specific credential set
|
||||||
* @param type VPN type (see VpnType.java)
|
* @param type VPN type (see VpnType.java)
|
||||||
* @param local_address local ip address
|
|
||||||
* @param gateway gateway address
|
* @param gateway gateway address
|
||||||
* @param username user name (local identity)
|
* @param username user name (local identity)
|
||||||
* @param password password (if any)
|
* @param password password (if any)
|
||||||
*/
|
*/
|
||||||
android_service_t *android_service_create(android_creds_t *creds, char *type,
|
android_service_t *android_service_create(android_creds_t *creds, char *type,
|
||||||
char *local_address, char *gateway,
|
char *gateway, char *username,
|
||||||
char *username, char *password);
|
char *password);
|
||||||
|
|
||||||
#endif /** ANDROID_SERVICE_H_ @}*/
|
#endif /** ANDROID_SERVICE_H_ @}*/
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ struct private_charonservice_t {
|
|||||||
*/
|
*/
|
||||||
vpnservice_builder_t *builder;
|
vpnservice_builder_t *builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NetworkManager instance (accessed via JNI)
|
||||||
|
*/
|
||||||
|
network_manager_t *network_manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CharonVpnService reference
|
* CharonVpnService reference
|
||||||
*/
|
*/
|
||||||
@@ -330,22 +335,26 @@ METHOD(charonservice_t, get_vpnservice_builder, vpnservice_builder_t*,
|
|||||||
return this->builder;
|
return this->builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(charonservice_t, get_network_manager, network_manager_t*,
|
||||||
|
private_charonservice_t *this)
|
||||||
|
{
|
||||||
|
return this->network_manager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate a new connection
|
* Initiate a new connection
|
||||||
*
|
*
|
||||||
* @param local local ip address (gets owned)
|
|
||||||
* @param gateway gateway address (gets owned)
|
* @param gateway gateway address (gets owned)
|
||||||
* @param username username (gets owned)
|
* @param username username (gets owned)
|
||||||
* @param password password (gets owned)
|
* @param password password (gets owned)
|
||||||
*/
|
*/
|
||||||
static void initiate(char *type, char *local, char *gateway,
|
static void initiate(char *type, char *gateway, char *username, char *password)
|
||||||
char *username, char *password)
|
|
||||||
{
|
{
|
||||||
private_charonservice_t *this = (private_charonservice_t*)charonservice;
|
private_charonservice_t *this = (private_charonservice_t*)charonservice;
|
||||||
|
|
||||||
this->creds->clear(this->creds);
|
this->creds->clear(this->creds);
|
||||||
DESTROY_IF(this->service);
|
DESTROY_IF(this->service);
|
||||||
this->service = android_service_create(this->creds, type, local, gateway,
|
this->service = android_service_create(this->creds, type, gateway,
|
||||||
username, password);
|
username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,10 +409,12 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
|||||||
.get_user_certificate = _get_user_certificate,
|
.get_user_certificate = _get_user_certificate,
|
||||||
.get_user_key = _get_user_key,
|
.get_user_key = _get_user_key,
|
||||||
.get_vpnservice_builder = _get_vpnservice_builder,
|
.get_vpnservice_builder = _get_vpnservice_builder,
|
||||||
|
.get_network_manager = _get_network_manager,
|
||||||
},
|
},
|
||||||
.attr = android_attr_create(),
|
.attr = android_attr_create(),
|
||||||
.creds = android_creds_create(),
|
.creds = android_creds_create(),
|
||||||
.builder = vpnservice_builder_create(builder),
|
.builder = vpnservice_builder_create(builder),
|
||||||
|
.network_manager = network_manager_create(),
|
||||||
.vpn_service = (*env)->NewGlobalRef(env, service),
|
.vpn_service = (*env)->NewGlobalRef(env, service),
|
||||||
);
|
);
|
||||||
charonservice = &this->public;
|
charonservice = &this->public;
|
||||||
@@ -439,6 +450,7 @@ static void charonservice_deinit(JNIEnv *env)
|
|||||||
{
|
{
|
||||||
private_charonservice_t *this = (private_charonservice_t*)charonservice;
|
private_charonservice_t *this = (private_charonservice_t*)charonservice;
|
||||||
|
|
||||||
|
this->network_manager->destroy(this->network_manager);
|
||||||
this->builder->destroy(this->builder);
|
this->builder->destroy(this->builder);
|
||||||
this->creds->destroy(this->creds);
|
this->creds->destroy(this->creds);
|
||||||
this->attr->destroy(this->attr);
|
this->attr->destroy(this->attr);
|
||||||
@@ -555,16 +567,14 @@ JNI_METHOD(CharonVpnService, deinitializeCharon, void)
|
|||||||
* Initiate SA
|
* Initiate SA
|
||||||
*/
|
*/
|
||||||
JNI_METHOD(CharonVpnService, initiate, void,
|
JNI_METHOD(CharonVpnService, initiate, void,
|
||||||
jstring jtype, jstring jlocal_address, jstring jgateway, jstring jusername,
|
jstring jtype, jstring jgateway, jstring jusername, jstring jpassword)
|
||||||
jstring jpassword)
|
|
||||||
{
|
{
|
||||||
char *type, *local_address, *gateway, *username, *password;
|
char *type, *gateway, *username, *password;
|
||||||
|
|
||||||
type = androidjni_convert_jstring(env, jtype);
|
type = androidjni_convert_jstring(env, jtype);
|
||||||
local_address = androidjni_convert_jstring(env, jlocal_address);
|
|
||||||
gateway = androidjni_convert_jstring(env, jgateway);
|
gateway = androidjni_convert_jstring(env, jgateway);
|
||||||
username = androidjni_convert_jstring(env, jusername);
|
username = androidjni_convert_jstring(env, jusername);
|
||||||
password = androidjni_convert_jstring(env, jpassword);
|
password = androidjni_convert_jstring(env, jpassword);
|
||||||
|
|
||||||
initiate(type, local_address, gateway, username, password);
|
initiate(type, gateway, username, password);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#define CHARONSERVICE_H_
|
#define CHARONSERVICE_H_
|
||||||
|
|
||||||
#include "vpnservice_builder.h"
|
#include "vpnservice_builder.h"
|
||||||
|
#include "kernel/network_manager.h"
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
@@ -111,6 +112,12 @@ struct charonservice_t {
|
|||||||
*/
|
*/
|
||||||
vpnservice_builder_t *(*get_vpnservice_builder)(charonservice_t *this);
|
vpnservice_builder_t *(*get_vpnservice_builder)(charonservice_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current network_manager_t object
|
||||||
|
*
|
||||||
|
* @return NetworkManager instance
|
||||||
|
*/
|
||||||
|
network_manager_t *(*get_network_manager)(charonservice_t *this);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "android_net.h"
|
#include "android_net.h"
|
||||||
|
|
||||||
|
#include "../charonservice.h"
|
||||||
|
|
||||||
typedef struct private_kernel_android_net_t private_kernel_android_net_t;
|
typedef struct private_kernel_android_net_t private_kernel_android_net_t;
|
||||||
|
|
||||||
struct private_kernel_android_net_t {
|
struct private_kernel_android_net_t {
|
||||||
@@ -22,8 +24,20 @@ struct private_kernel_android_net_t {
|
|||||||
* Public kernel interface
|
* Public kernel interface
|
||||||
*/
|
*/
|
||||||
kernel_android_net_t public;
|
kernel_android_net_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to NetworkManager object
|
||||||
|
*/
|
||||||
|
network_manager_t *network_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
METHOD(kernel_net_t, get_source_addr, host_t*,
|
||||||
|
private_kernel_android_net_t *this, host_t *dest, host_t *src)
|
||||||
|
{
|
||||||
|
return this->network_manager->get_local_address(this->network_manager,
|
||||||
|
dest->get_family(dest) == AF_INET);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(kernel_net_t, add_ip, status_t,
|
METHOD(kernel_net_t, add_ip, status_t,
|
||||||
private_kernel_android_net_t *this, host_t *virtual_ip, host_t *iface_ip)
|
private_kernel_android_net_t *this, host_t *virtual_ip, host_t *iface_ip)
|
||||||
{
|
{
|
||||||
@@ -47,7 +61,7 @@ kernel_android_net_t *kernel_android_net_create()
|
|||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.interface = {
|
.interface = {
|
||||||
.get_source_addr = (void*)return_null,
|
.get_source_addr = _get_source_addr,
|
||||||
.get_nexthop = (void*)return_null,
|
.get_nexthop = (void*)return_null,
|
||||||
.get_interface = (void*)return_null,
|
.get_interface = (void*)return_null,
|
||||||
.create_address_enumerator = (void*)enumerator_create_empty,
|
.create_address_enumerator = (void*)enumerator_create_empty,
|
||||||
@@ -58,6 +72,7 @@ kernel_android_net_t *kernel_android_net_create()
|
|||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.network_manager = charonservice->get_network_manager(charonservice),
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -18,14 +18,10 @@
|
|||||||
package org.strongswan.android.logic;
|
package org.strongswan.android.logic;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.cert.CertificateEncodingException;
|
import java.security.cert.CertificateEncodingException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
|
||||||
|
|
||||||
import org.strongswan.android.data.VpnProfile;
|
import org.strongswan.android.data.VpnProfile;
|
||||||
import org.strongswan.android.data.VpnProfileDataSource;
|
import org.strongswan.android.data.VpnProfileDataSource;
|
||||||
@@ -218,9 +214,7 @@ public class CharonVpnService extends VpnService implements Runnable
|
|||||||
initializeCharon(builder, mLogFile);
|
initializeCharon(builder, mLogFile);
|
||||||
Log.i(TAG, "charon started");
|
Log.i(TAG, "charon started");
|
||||||
|
|
||||||
String local_address = getLocalIPv4Address();
|
|
||||||
initiate(mCurrentProfile.getVpnType().getIdentifier(),
|
initiate(mCurrentProfile.getVpnType().getIdentifier(),
|
||||||
local_address != null ? local_address : "0.0.0.0",
|
|
||||||
mCurrentProfile.getGateway(), mCurrentProfile.getUsername(),
|
mCurrentProfile.getGateway(), mCurrentProfile.getUsername(),
|
||||||
mCurrentProfile.getPassword());
|
mCurrentProfile.getPassword());
|
||||||
}
|
}
|
||||||
@@ -486,41 +480,7 @@ public class CharonVpnService extends VpnService implements Runnable
|
|||||||
/**
|
/**
|
||||||
* Initiate VPN, provided by libandroidbridge.so
|
* Initiate VPN, provided by libandroidbridge.so
|
||||||
*/
|
*/
|
||||||
public native void initiate(String type, String local_address, String gateway,
|
public native void initiate(String type, String gateway, String username, String password);
|
||||||
String username, String password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function that retrieves a local IPv4 address.
|
|
||||||
*
|
|
||||||
* @return string representation of an IPv4 address, or null if none found
|
|
||||||
*/
|
|
||||||
private static String getLocalIPv4Address()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
|
|
||||||
while (en.hasMoreElements())
|
|
||||||
{
|
|
||||||
NetworkInterface intf = en.nextElement();
|
|
||||||
|
|
||||||
Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses();
|
|
||||||
while (enumIpAddr.hasMoreElements())
|
|
||||||
{
|
|
||||||
InetAddress inetAddress = enumIpAddr.nextElement();
|
|
||||||
if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == 4)
|
|
||||||
{
|
|
||||||
return inetAddress.getHostAddress().toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SocketException ex)
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter for VpnService.Builder which is used to access it safely via JNI.
|
* Adapter for VpnService.Builder which is used to access it safely via JNI.
|
||||||
|
|||||||
Reference in New Issue
Block a user