diff options
author | Tobias Brunner <tobias@strongswan.org> | 2013-05-15 15:52:16 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2013-07-08 18:49:28 +0200 |
commit | dc52cfab73298272a68eaef3f85b571536ad8a06 (patch) | |
tree | 44856903125ce16e1fb43f3cd7a963ff845a9d6f /src | |
parent | d087f080f0f0eae9b965c61c6732d053fca55f72 (diff) | |
download | strongswan-dc52cfab73298272a68eaef3f85b571536ad8a06.tar.bz2 strongswan-dc52cfab73298272a68eaef3f85b571536ad8a06.tar.xz |
android: Add state of IMC to VpnStateService and update it via JNI
Diffstat (limited to 'src')
6 files changed, 203 insertions, 3 deletions
diff --git a/src/frontends/android/jni/libandroidbridge/byod/imc_android.c b/src/frontends/android/jni/libandroidbridge/byod/imc_android.c index 7dfc3a2fd..7067e1f89 100644 --- a/src/frontends/android/jni/libandroidbridge/byod/imc_android.c +++ b/src/frontends/android/jni/libandroidbridge/byod/imc_android.c @@ -18,6 +18,7 @@ #include "imc_android_state.h" #include "../android_jni.h" +#include "../charonservice.h" #include <tnc/tnc.h> #include <libpts.h> @@ -99,6 +100,29 @@ static TNC_Result tnc_imc_initialize(TNC_IMCID imc_id, } /** + * 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 */ static TNC_Result tnc_imc_notifyconnectionchange(TNC_IMCID imc_id, @@ -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); diff --git a/src/frontends/android/jni/libandroidbridge/charonservice.c b/src/frontends/android/jni/libandroidbridge/charonservice.c index 1c62e282c..115b53232 100644 --- a/src/frontends/android/jni/libandroidbridge/charonservice.c +++ b/src/frontends/android/jni/libandroidbridge/charonservice.c @@ -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, diff --git a/src/frontends/android/jni/libandroidbridge/charonservice.h b/src/frontends/android/jni/libandroidbridge/charonservice.h index f142f78e5..90f5bc952 100644 --- a/src/frontends/android/jni/libandroidbridge/charonservice.h +++ b/src/frontends/android/jni/libandroidbridge/charonservice.h @@ -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; /** @@ -57,6 +58,16 @@ enum android_vpn_state_t { }; /** + * 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. * * Used to communicate with CharonVpnService via JNI @@ -72,6 +83,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. * diff --git a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java index f08a48135..9f920a9ed 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java @@ -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()); @@ -297,6 +299,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 * is done asynchronously via state service. @@ -356,6 +375,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. * diff --git a/src/frontends/android/src/org/strongswan/android/logic/VpnStateService.java b/src/frontends/android/src/org/strongswan/android/logic/VpnStateService.java index 1c14cb601..62ca31f13 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/VpnStateService.java +++ b/src/frontends/android/src/org/strongswan/android/logic/VpnStateService.java @@ -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 { @@ -147,6 +149,16 @@ public class VpnStateService extends Service } /** + * 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 * started. @@ -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; + } + }); + } } diff --git a/src/frontends/android/src/org/strongswan/android/logic/imc/ImcState.java b/src/frontends/android/src/org/strongswan/android/logic/imc/ImcState.java new file mode 100644 index 000000000..4fc3834f9 --- /dev/null +++ b/src/frontends/android/src/org/strongswan/android/logic/imc/ImcState.java @@ -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; + } +} |