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 "../android_jni.h"
|
||||
#include "../charonservice.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <libpts.h>
|
||||
@@ -98,6 +99,29 @@ static TNC_Result tnc_imc_initialize(TNC_IMCID imc_id,
|
||||
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
|
||||
*/
|
||||
@@ -128,6 +152,11 @@ static TNC_Result tnc_imc_notifyconnectionchange(TNC_IMCID imc_id,
|
||||
return TNC_RESULT_SUCCESS;
|
||||
case TNC_CONNECTION_STATE_DELETE:
|
||||
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:
|
||||
return imc_android->change_state(imc_android, connection_id,
|
||||
new_state, NULL);
|
||||
|
||||
@@ -162,6 +162,30 @@ failed:
|
||||
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
|
||||
*/
|
||||
@@ -466,6 +490,7 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
||||
INIT(this,
|
||||
.public = {
|
||||
.update_status = _update_status,
|
||||
.update_imc_state = _update_imc_state,
|
||||
.bypass_socket = _bypass_socket,
|
||||
.get_trusted_certificates = _get_trusted_certificates,
|
||||
.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 Ralf Sager
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <collections/linked_list.h>
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -56,6 +57,16 @@ enum android_vpn_state_t {
|
||||
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.
|
||||
*
|
||||
@@ -71,6 +82,14 @@ struct charonservice_t {
|
||||
*/
|
||||
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
|
||||
* 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 Ralf Sager
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -27,6 +27,7 @@ import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.data.VpnProfileDataSource;
|
||||
import org.strongswan.android.logic.VpnStateService.ErrorState;
|
||||
import org.strongswan.android.logic.VpnStateService.State;
|
||||
import org.strongswan.android.logic.imc.ImcState;
|
||||
import org.strongswan.android.ui.MainActivity;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
@@ -208,6 +209,7 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
setProfile(mCurrentProfile);
|
||||
setError(ErrorState.NO_ERROR);
|
||||
setState(State.CONNECTING);
|
||||
setImcState(ImcState.UNKNOWN);
|
||||
mIsDisconnecting = false;
|
||||
|
||||
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.
|
||||
* 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
|
||||
* as byte array.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012-2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.logic.imc.ImcState;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
@@ -36,6 +37,7 @@ public class VpnStateService extends Service
|
||||
private VpnProfile mProfile;
|
||||
private State mState = State.DISABLED;
|
||||
private ErrorState mError = ErrorState.NO_ERROR;
|
||||
private ImcState mImcState = ImcState.UNKNOWN;
|
||||
|
||||
public enum State
|
||||
{
|
||||
@@ -146,6 +148,16 @@ public class VpnStateService extends Service
|
||||
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
|
||||
* 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