android: Add state of IMC to VpnStateService and update it via JNI
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "imc_android_state.h"
|
#include "imc_android_state.h"
|
||||||
#include "../android_jni.h"
|
#include "../android_jni.h"
|
||||||
|
#include "../charonservice.h"
|
||||||
|
|
||||||
#include <tnc/tnc.h>
|
#include <tnc/tnc.h>
|
||||||
#include <libpts.h>
|
#include <libpts.h>
|
||||||
@@ -98,6 +99,29 @@ static TNC_Result tnc_imc_initialize(TNC_IMCID imc_id,
|
|||||||
return TNC_RESULT_SUCCESS;
|
return TNC_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the state in the GUI.
|
||||||
|
*/
|
||||||
|
static void update_imc_state(TNC_ConnectionState state)
|
||||||
|
{
|
||||||
|
android_imc_state_t imc_state = ANDROID_IMC_STATE_UNKNOWN;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{ /* map connection states to the values used by the GUI */
|
||||||
|
case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
|
||||||
|
imc_state = ANDROID_IMC_STATE_ALLOW;
|
||||||
|
break;
|
||||||
|
case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
|
||||||
|
imc_state = ANDROID_IMC_STATE_ISOLATE;
|
||||||
|
break;
|
||||||
|
case TNC_CONNECTION_STATE_ACCESS_NONE:
|
||||||
|
imc_state = ANDROID_IMC_STATE_BLOCK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
charonservice->update_imc_state(charonservice, imc_state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
|
* see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
|
||||||
*/
|
*/
|
||||||
@@ -128,6 +152,11 @@ static TNC_Result tnc_imc_notifyconnectionchange(TNC_IMCID imc_id,
|
|||||||
return TNC_RESULT_SUCCESS;
|
return TNC_RESULT_SUCCESS;
|
||||||
case TNC_CONNECTION_STATE_DELETE:
|
case TNC_CONNECTION_STATE_DELETE:
|
||||||
return imc_android->delete_state(imc_android, connection_id);
|
return imc_android->delete_state(imc_android, connection_id);
|
||||||
|
case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
|
||||||
|
case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
|
||||||
|
case TNC_CONNECTION_STATE_ACCESS_NONE:
|
||||||
|
update_imc_state(new_state);
|
||||||
|
/* fall-through */
|
||||||
default:
|
default:
|
||||||
return imc_android->change_state(imc_android, connection_id,
|
return imc_android->change_state(imc_android, connection_id,
|
||||||
new_state, NULL);
|
new_state, NULL);
|
||||||
|
|||||||
@@ -162,6 +162,30 @@ failed:
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(charonservice_t, update_imc_state, bool,
|
||||||
|
private_charonservice_t *this, android_imc_state_t state)
|
||||||
|
{
|
||||||
|
JNIEnv *env;
|
||||||
|
jmethodID method_id;
|
||||||
|
bool success = FALSE;
|
||||||
|
|
||||||
|
androidjni_attach_thread(&env);
|
||||||
|
|
||||||
|
method_id = (*env)->GetMethodID(env, android_charonvpnservice_class,
|
||||||
|
"updateImcState", "(I)V");
|
||||||
|
if (!method_id)
|
||||||
|
{
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
(*env)->CallVoidMethod(env, this->vpn_service, method_id, (jint)state);
|
||||||
|
success = !androidjni_exception_occurred(env);
|
||||||
|
|
||||||
|
failed:
|
||||||
|
androidjni_exception_occurred(env);
|
||||||
|
androidjni_detach_thread();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bypass a single socket
|
* Bypass a single socket
|
||||||
*/
|
*/
|
||||||
@@ -466,6 +490,7 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
|||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.update_status = _update_status,
|
.update_status = _update_status,
|
||||||
|
.update_imc_state = _update_imc_state,
|
||||||
.bypass_socket = _bypass_socket,
|
.bypass_socket = _bypass_socket,
|
||||||
.get_trusted_certificates = _get_trusted_certificates,
|
.get_trusted_certificates = _get_trusted_certificates,
|
||||||
.get_user_certificate = _get_user_certificate,
|
.get_user_certificate = _get_user_certificate,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Tobias Brunner
|
* Copyright (C) 2012-2013 Tobias Brunner
|
||||||
* Copyright (C) 2012 Giuliano Grassi
|
* Copyright (C) 2012 Giuliano Grassi
|
||||||
* Copyright (C) 2012 Ralf Sager
|
* Copyright (C) 2012 Ralf Sager
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
|
|
||||||
typedef enum android_vpn_state_t android_vpn_state_t;
|
typedef enum android_vpn_state_t android_vpn_state_t;
|
||||||
|
typedef enum android_imc_state_t android_imc_state_t;
|
||||||
typedef struct charonservice_t charonservice_t;
|
typedef struct charonservice_t charonservice_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +57,16 @@ enum android_vpn_state_t {
|
|||||||
CHARONSERVICE_GENERIC_ERROR,
|
CHARONSERVICE_GENERIC_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final IMC state as defined in ImcState.java
|
||||||
|
*/
|
||||||
|
enum android_imc_state_t {
|
||||||
|
ANDROID_IMC_STATE_UNKNOWN = 0,
|
||||||
|
ANDROID_IMC_STATE_ALLOW = 1,
|
||||||
|
ANDROID_IMC_STATE_BLOCK = 2,
|
||||||
|
ANDROID_IMC_STATE_ISOLATE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public interface of charonservice.
|
* Public interface of charonservice.
|
||||||
*
|
*
|
||||||
@@ -71,6 +82,14 @@ struct charonservice_t {
|
|||||||
*/
|
*/
|
||||||
bool (*update_status)(charonservice_t *this, android_vpn_state_t code);
|
bool (*update_status)(charonservice_t *this, android_vpn_state_t code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update final IMC state in the Java domain (UI)
|
||||||
|
*
|
||||||
|
* @param state IMC state
|
||||||
|
* @return TRUE on success
|
||||||
|
*/
|
||||||
|
bool (*update_imc_state)(charonservice_t *this, android_imc_state_t state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install a bypass policy for the given socket using the protect() Method
|
* Install a bypass policy for the given socket using the protect() Method
|
||||||
* of the Android VpnService interface.
|
* of the Android VpnService interface.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Tobias Brunner
|
* Copyright (C) 2012-2013 Tobias Brunner
|
||||||
* Copyright (C) 2012 Giuliano Grassi
|
* Copyright (C) 2012 Giuliano Grassi
|
||||||
* Copyright (C) 2012 Ralf Sager
|
* Copyright (C) 2012 Ralf Sager
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@@ -27,6 +27,7 @@ import org.strongswan.android.data.VpnProfile;
|
|||||||
import org.strongswan.android.data.VpnProfileDataSource;
|
import org.strongswan.android.data.VpnProfileDataSource;
|
||||||
import org.strongswan.android.logic.VpnStateService.ErrorState;
|
import org.strongswan.android.logic.VpnStateService.ErrorState;
|
||||||
import org.strongswan.android.logic.VpnStateService.State;
|
import org.strongswan.android.logic.VpnStateService.State;
|
||||||
|
import org.strongswan.android.logic.imc.ImcState;
|
||||||
import org.strongswan.android.ui.MainActivity;
|
import org.strongswan.android.ui.MainActivity;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@@ -208,6 +209,7 @@ public class CharonVpnService extends VpnService implements Runnable
|
|||||||
setProfile(mCurrentProfile);
|
setProfile(mCurrentProfile);
|
||||||
setError(ErrorState.NO_ERROR);
|
setError(ErrorState.NO_ERROR);
|
||||||
setState(State.CONNECTING);
|
setState(State.CONNECTING);
|
||||||
|
setImcState(ImcState.UNKNOWN);
|
||||||
mIsDisconnecting = false;
|
mIsDisconnecting = false;
|
||||||
|
|
||||||
BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName());
|
BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName());
|
||||||
@@ -296,6 +298,23 @@ public class CharonVpnService extends VpnService implements Runnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the IMC state on the state service. Called by the handler thread and
|
||||||
|
* any of charon's threads.
|
||||||
|
*
|
||||||
|
* @param state IMC state
|
||||||
|
*/
|
||||||
|
private void setImcState(ImcState state)
|
||||||
|
{
|
||||||
|
synchronized (mServiceLock)
|
||||||
|
{
|
||||||
|
if (mService != null)
|
||||||
|
{
|
||||||
|
mService.setImcState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an error on the state service and disconnect the current connection.
|
* Set an error on the state service and disconnect the current connection.
|
||||||
* This is not done by calling stopCurrentConnection() above, but instead
|
* This is not done by calling stopCurrentConnection() above, but instead
|
||||||
@@ -355,6 +374,21 @@ public class CharonVpnService extends VpnService implements Runnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the IMC state of the current connection.
|
||||||
|
* Called via JNI by different threads (but not concurrently).
|
||||||
|
*
|
||||||
|
* @param value new state
|
||||||
|
*/
|
||||||
|
public void updateImcState(int value)
|
||||||
|
{
|
||||||
|
ImcState state = ImcState.fromValue(value);
|
||||||
|
if (state != null)
|
||||||
|
{
|
||||||
|
setImcState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called via JNI to generate a list of DER encoded CA certificates
|
* Function called via JNI to generate a list of DER encoded CA certificates
|
||||||
* as byte array.
|
* as byte array.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Tobias Brunner
|
* Copyright (C) 2012-2013 Tobias Brunner
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -20,6 +20,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import org.strongswan.android.data.VpnProfile;
|
import org.strongswan.android.data.VpnProfile;
|
||||||
|
import org.strongswan.android.logic.imc.ImcState;
|
||||||
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -36,6 +37,7 @@ public class VpnStateService extends Service
|
|||||||
private VpnProfile mProfile;
|
private VpnProfile mProfile;
|
||||||
private State mState = State.DISABLED;
|
private State mState = State.DISABLED;
|
||||||
private ErrorState mError = ErrorState.NO_ERROR;
|
private ErrorState mError = ErrorState.NO_ERROR;
|
||||||
|
private ImcState mImcState = ImcState.UNKNOWN;
|
||||||
|
|
||||||
public enum State
|
public enum State
|
||||||
{
|
{
|
||||||
@@ -146,6 +148,16 @@ public class VpnStateService extends Service
|
|||||||
return mError;
|
return mError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current IMC state, if any.
|
||||||
|
*
|
||||||
|
* @return imc state
|
||||||
|
*/
|
||||||
|
public ImcState getImcState()
|
||||||
|
{ /* only updated from the main thread so no synchronization needed */
|
||||||
|
return mImcState;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect any existing connection and shutdown the daemon, the
|
* Disconnect any existing connection and shutdown the daemon, the
|
||||||
* VpnService is not stopped but it is reset so new connections can be
|
* VpnService is not stopped but it is reset so new connections can be
|
||||||
@@ -261,4 +273,27 @@ public class VpnStateService extends Service
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current IMC state and notify all listeners, if changed.
|
||||||
|
*
|
||||||
|
* May be called from threads other than the main thread.
|
||||||
|
*
|
||||||
|
* @param error error state
|
||||||
|
*/
|
||||||
|
public void setImcState(final ImcState state)
|
||||||
|
{
|
||||||
|
notifyListeners(new Callable<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception
|
||||||
|
{
|
||||||
|
if (VpnStateService.this.mImcState != state)
|
||||||
|
{
|
||||||
|
VpnStateService.this.mImcState = state;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.strongswan.android.logic.imc;
|
||||||
|
|
||||||
|
public enum ImcState
|
||||||
|
{
|
||||||
|
UNKNOWN(0),
|
||||||
|
ALLOW(1),
|
||||||
|
BLOCK(2),
|
||||||
|
ISOLATE(3);
|
||||||
|
|
||||||
|
private final int mValue;
|
||||||
|
|
||||||
|
private ImcState(int value)
|
||||||
|
{
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the numeric value of the IMC state.
|
||||||
|
* @return numeric value
|
||||||
|
*/
|
||||||
|
public int getValue()
|
||||||
|
{
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the enum entry from a numeric value, if defined
|
||||||
|
*
|
||||||
|
* @param value numeric value
|
||||||
|
* @return the enum entry or null
|
||||||
|
*/
|
||||||
|
public static ImcState fromValue(int value)
|
||||||
|
{
|
||||||
|
for (ImcState state : ImcState.values())
|
||||||
|
{
|
||||||
|
if (state.mValue == value)
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user