Merge branch 'android-byod'
Adds support for EAP-TNC with a custom Android-specific IMC that collects data such as installed packages, file hashes or system settings. Some parts of the implementation are based on the bachelor semester project 'strongSwan Android 4 Client with Endpoint Assessment' by Christoph Bühler and Patrick Lötscher.
This commit is contained in:
+5
-1
@@ -37,4 +37,8 @@ apidoc/
|
||||
coverage/
|
||||
*.gcno
|
||||
*.gcda
|
||||
*.gcov
|
||||
*.gcov
|
||||
.cproject
|
||||
.project
|
||||
.metadata/
|
||||
.settings/
|
||||
@@ -13,6 +13,17 @@ add_plugin = $(if $(call plugin_enabled,$(1)), \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
add_plugin_subdirs = $(if $(call plugin_enabled,$(1)), \
|
||||
$(patsubst $(LOCAL_PATH)/%,%, \
|
||||
$(wildcard \
|
||||
$(subst %,$(subst -,_,$(strip $(1))), \
|
||||
$(addprefix $(LOCAL_PATH)/plugins/%/,$(addsuffix /*.c, \
|
||||
$(strip $(2)) \
|
||||
)) \
|
||||
) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
# strongSwan version, replaced by top Makefile
|
||||
strongswan_VERSION := "@PACKAGE_VERSION@"
|
||||
|
||||
+2
-1
@@ -100,7 +100,8 @@ strongswan_BUILD := \
|
||||
libhydra \
|
||||
libstrongswan \
|
||||
libtncif \
|
||||
libtnccs
|
||||
libtnccs \
|
||||
libimcv
|
||||
|
||||
ifneq ($(strongswan_BUILD_STARTER),)
|
||||
strongswan_BUILD += \
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
android:name=".ui.LogActivity"
|
||||
android:label="@string/log_title" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.RemediationInstructionsActivity"
|
||||
android:label="@string/remediation_instructions_title" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.VpnProfileSelectActivity"
|
||||
android:label="@string/strongswan_shortcut" >
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# use "bring your own device" (BYOD) features (also see USE_BYOD in
|
||||
# MainActivity.java)
|
||||
strongswan_USE_BYOD := true
|
||||
|
||||
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
|
||||
pkcs1 pkcs8 pem xcbc hmac socket-default kernel-netlink \
|
||||
eap-identity eap-mschapv2 eap-md5 eap-gtc
|
||||
|
||||
strongswan_PLUGINS := $(strongswan_CHARON_PLUGINS)
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
strongswan_BYOD_PLUGINS := eap-ttls eap-tnc tnc-imc tnc-tnccs tnccs-20
|
||||
endif
|
||||
|
||||
strongswan_PLUGINS := $(strongswan_CHARON_PLUGINS) \
|
||||
$(strongswan_BYOD_PLUGINS)
|
||||
|
||||
include $(LOCAL_PATH)/strongswan/Android.common.mk
|
||||
|
||||
@@ -52,12 +61,26 @@ strongswan_CFLAGS := \
|
||||
-DDEV_RANDOM=\"/dev/random\" \
|
||||
-DDEV_URANDOM=\"/dev/urandom\"
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
strongswan_CFLAGS += -DUSE_BYOD
|
||||
endif
|
||||
|
||||
strongswan_BUILD := \
|
||||
vstr \
|
||||
openssl \
|
||||
libandroidbridge \
|
||||
strongswan/src/libipsec \
|
||||
strongswan/src/libcharon \
|
||||
strongswan/src/libhydra \
|
||||
strongswan/src/libstrongswan
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
strongswan_BUILD += \
|
||||
strongswan/src/libtnccs \
|
||||
strongswan/src/libtncif \
|
||||
strongswan/src/libimcv \
|
||||
strongswan/src/libpts
|
||||
endif
|
||||
|
||||
include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
|
||||
vstr \
|
||||
openssl \
|
||||
libandroidbridge \
|
||||
strongswan/src/libipsec \
|
||||
strongswan/src/libcharon \
|
||||
strongswan/src/libhydra \
|
||||
strongswan/src/libstrongswan \
|
||||
))
|
||||
$(strongswan_BUILD)))
|
||||
|
||||
@@ -14,6 +14,12 @@ kernel/android_net.c \
|
||||
kernel/network_manager.c \
|
||||
vpnservice_builder.c
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
LOCAL_SRC_FILES += \
|
||||
byod/imc_android_state.c \
|
||||
byod/imc_android.c
|
||||
endif
|
||||
|
||||
# build libandroidbridge -------------------------------------------------------
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
@@ -23,9 +29,22 @@ LOCAL_C_INCLUDES += \
|
||||
$(strongswan_PATH)/src/libcharon \
|
||||
$(strongswan_PATH)/src/libstrongswan
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(strongswan_PATH)/src/libimcv \
|
||||
$(strongswan_PATH)/src/libtncif \
|
||||
$(strongswan_PATH)/src/libtnccs \
|
||||
$(strongswan_PATH)/src/libpts \
|
||||
$(strongswan_PATH)/src/libtls
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS := $(strongswan_CFLAGS) \
|
||||
-DPLUGINS='"$(strongswan_CHARON_PLUGINS)"'
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
LOCAL_CFLAGS += -DPLUGINS_BYOD='"$(strongswan_BYOD_PLUGINS)"'
|
||||
endif
|
||||
|
||||
LOCAL_MODULE := libandroidbridge
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
@@ -38,6 +57,8 @@ LOCAL_LDLIBS := -llog
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libstrongswan libhydra libipsec libcharon
|
||||
|
||||
ifneq ($(strongswan_USE_BYOD),)
|
||||
LOCAL_SHARED_LIBRARIES += libimcv libtncif libtnccs libpts
|
||||
endif
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
|
||||
|
||||
@@ -464,13 +464,18 @@ METHOD(listener_t, ike_reestablish, bool,
|
||||
}
|
||||
|
||||
static void add_auth_cfg_eap(private_android_service_t *this,
|
||||
peer_cfg_t *peer_cfg)
|
||||
peer_cfg_t *peer_cfg, bool byod)
|
||||
{
|
||||
identification_t *user;
|
||||
auth_cfg_t *auth;
|
||||
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
|
||||
if (byod)
|
||||
{ /* use EAP-TTLS if BYOD is enabled */
|
||||
auth->add(auth, AUTH_RULE_EAP_TYPE, EAP_TTLS);
|
||||
}
|
||||
|
||||
user = identification_create_from_string(this->username);
|
||||
auth->add(auth, AUTH_RULE_IDENTITY, user);
|
||||
|
||||
@@ -549,9 +554,10 @@ static job_requeue_t initiate(private_android_service_t *this)
|
||||
}
|
||||
}
|
||||
if (streq("ikev2-eap", this->type) ||
|
||||
streq("ikev2-cert-eap", this->type))
|
||||
streq("ikev2-cert-eap", this->type) ||
|
||||
streq("ikev2-byod-eap", this->type))
|
||||
{
|
||||
add_auth_cfg_eap(this, peer_cfg);
|
||||
add_auth_cfg_eap(this, peer_cfg, strpfx(this->type, "ikev2-byod"));
|
||||
}
|
||||
|
||||
/* remote auth config */
|
||||
|
||||
@@ -0,0 +1,725 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* Copyright (C) 2011-2012 Andreas Steffen
|
||||
* 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 "imc_android_state.h"
|
||||
#include "../android_jni.h"
|
||||
#include "../charonservice.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <libpts.h>
|
||||
#include <imcv.h>
|
||||
#include <imc/imc_agent.h>
|
||||
#include <imc/imc_msg.h>
|
||||
#include <pa_tnc/pa_tnc_msg.h>
|
||||
#include <ietf/ietf_attr.h>
|
||||
#include <ietf/ietf_attr_attr_request.h>
|
||||
#include <ietf/ietf_attr_installed_packages.h>
|
||||
#include <ietf/ietf_attr_pa_tnc_error.h>
|
||||
#include <ietf/ietf_attr_product_info.h>
|
||||
#include <ietf/ietf_attr_remediation_instr.h>
|
||||
#include <ietf/ietf_attr_string_version.h>
|
||||
#include <ita/ita_attr.h>
|
||||
#include <ita/ita_attr_get_settings.h>
|
||||
#include <tcg/tcg_pts_attr_file_meas.h>
|
||||
#include <tcg/tcg_pts_attr_meas_algo.h>
|
||||
#include <tcg/tcg_pts_attr_proto_caps.h>
|
||||
#include <tcg/tcg_pts_attr_req_file_meas.h>
|
||||
#include <os_info/os_info.h>
|
||||
|
||||
#include <tncif_pa_subtypes.h>
|
||||
|
||||
#include <pen/pen.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* IMC definitions */
|
||||
|
||||
static const char imc_name[] = "Android";
|
||||
|
||||
static pen_type_t msg_types[] = {
|
||||
{ PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM },
|
||||
{ PEN_IETF, PA_SUBTYPE_IETF_VPN },
|
||||
{ PEN_TCG, PA_SUBTYPE_TCG_PTS },
|
||||
};
|
||||
|
||||
static imc_agent_t *imc_android;
|
||||
|
||||
/**
|
||||
* AndroidImc object accessed via JNI
|
||||
*/
|
||||
static jobject android_imc;
|
||||
|
||||
/**
|
||||
* AndroidImc class object
|
||||
*/
|
||||
static jclass android_imc_cls;
|
||||
|
||||
/**
|
||||
* see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
|
||||
*/
|
||||
static TNC_Result tnc_imc_initialize(TNC_IMCID imc_id,
|
||||
TNC_Version min_version,
|
||||
TNC_Version max_version,
|
||||
TNC_Version *actual_version)
|
||||
{
|
||||
if (imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
|
||||
return TNC_RESULT_ALREADY_INITIALIZED;
|
||||
}
|
||||
imc_android = imc_agent_create(imc_name, msg_types, countof(msg_types),
|
||||
imc_id, actual_version);
|
||||
if (!imc_android)
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
libpts_init();
|
||||
|
||||
if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
|
||||
{
|
||||
DBG1(DBG_IMC, "no common IF-IMC version");
|
||||
return TNC_RESULT_NO_COMMON_VERSION;
|
||||
}
|
||||
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
|
||||
*/
|
||||
static TNC_Result tnc_imc_notifyconnectionchange(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_ConnectionState new_state)
|
||||
{
|
||||
imc_state_t *state;
|
||||
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
switch (new_state)
|
||||
{
|
||||
case TNC_CONNECTION_STATE_CREATE:
|
||||
state = imc_android_state_create(connection_id);
|
||||
return imc_android->create_state(imc_android, state);
|
||||
case TNC_CONNECTION_STATE_HANDSHAKE:
|
||||
if (imc_android->change_state(imc_android, connection_id, new_state,
|
||||
&state) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
state->set_result(state, imc_id,
|
||||
TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the native C strings in the enumerator to a Java String array.
|
||||
* The given enumerator gets destroyed.
|
||||
*/
|
||||
static jobjectArray string_array_create(JNIEnv *env, enumerator_t *enumerator)
|
||||
{
|
||||
linked_list_t *list;
|
||||
jobjectArray jarray;
|
||||
jstring jstring;
|
||||
char *native;
|
||||
jclass cls;
|
||||
int i = 0;
|
||||
|
||||
cls = (*env)->FindClass(env, "java/lang/String");
|
||||
list = linked_list_create_from_enumerator(enumerator);
|
||||
jarray = (*env)->NewObjectArray(env, list->get_count(list), cls, NULL);
|
||||
if (!jarray)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, (void**)&native))
|
||||
{
|
||||
jstring = (*env)->NewStringUTF(env, native);
|
||||
if (!jstring)
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
goto failed;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, jarray, i++, jstring);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
list->destroy(list);
|
||||
return jarray;
|
||||
|
||||
failed:
|
||||
androidjni_exception_occurred(env);
|
||||
list->destroy(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a measurement for the given attribute type from the Android IMC.
|
||||
* NULL is returned if no measurement is available or an error occurred.
|
||||
*
|
||||
* The optional args is an enumerator over char* (gets destroyed).
|
||||
*/
|
||||
static pa_tnc_attr_t *get_measurement(pen_type_t attr_type, enumerator_t *args)
|
||||
{
|
||||
JNIEnv *env;
|
||||
pa_tnc_attr_t *attr;
|
||||
jmethodID method_id;
|
||||
jbyteArray jmeasurement;
|
||||
jobjectArray jargs = NULL;
|
||||
chunk_t data;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
if (args)
|
||||
{
|
||||
jargs = string_array_create(env, args);
|
||||
if (!jargs)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
method_id = (*env)->GetMethodID(env, android_imc_cls, "getMeasurement",
|
||||
"(II[Ljava/lang/String;)[B");
|
||||
}
|
||||
else
|
||||
{
|
||||
method_id = (*env)->GetMethodID(env, android_imc_cls, "getMeasurement",
|
||||
"(II)[B");
|
||||
}
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
jmeasurement = (*env)->CallObjectMethod(env, android_imc, method_id,
|
||||
attr_type.vendor_id, attr_type.type,
|
||||
jargs);
|
||||
if (!jmeasurement || androidjni_exception_occurred(env))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
data = chunk_create((*env)->GetByteArrayElements(env, jmeasurement, NULL),
|
||||
(*env)->GetArrayLength(env, jmeasurement));
|
||||
if (!data.ptr)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
||||
attr_type.vendor_id, attr_type.type,
|
||||
data);
|
||||
(*env)->ReleaseByteArrayElements(env, jmeasurement, data.ptr, JNI_ABORT);
|
||||
androidjni_detach_thread();
|
||||
return attr;
|
||||
|
||||
failed:
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the measurement for the requested attribute type with optional
|
||||
* arguments (enumerator over char*, gets destroyed).
|
||||
*/
|
||||
static void add_measurement(pen_type_t attr_type, imc_msg_t *msg,
|
||||
enumerator_t *args)
|
||||
{
|
||||
pa_tnc_attr_t *attr;
|
||||
enum_name_t *pa_attr_names;
|
||||
|
||||
attr = get_measurement(attr_type, args);
|
||||
if (attr)
|
||||
{
|
||||
msg->add_attribute(msg, attr);
|
||||
return;
|
||||
}
|
||||
pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
|
||||
attr_type.vendor_id);
|
||||
if (pa_attr_names)
|
||||
{
|
||||
DBG1(DBG_IMC, "no measurement available for PA-TNC attribute type "
|
||||
"'%N/%N' 0x%06x/0x%08x", pen_names, attr_type.vendor_id,
|
||||
pa_attr_names, attr_type.type, attr_type.vendor_id, attr_type.type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IMC, "no measurement available for PA-TNC attribute type '%N' "
|
||||
"0x%06x/0x%08x", pen_names, attr_type.vendor_id,
|
||||
attr_type.vendor_id, attr_type.type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an IETF attribute
|
||||
*/
|
||||
static void handle_ietf_attribute(pen_type_t attr_type, pa_tnc_attr_t *attr,
|
||||
imc_msg_t *out_msg)
|
||||
{
|
||||
if (attr_type.type == IETF_ATTR_ATTRIBUTE_REQUEST)
|
||||
{
|
||||
ietf_attr_attr_request_t *attr_cast;
|
||||
pen_type_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
attr_cast = (ietf_attr_attr_request_t*)attr;
|
||||
enumerator = attr_cast->create_enumerator(attr_cast);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
add_measurement(*entry, out_msg, NULL);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
else if (attr_type.type == IETF_ATTR_REMEDIATION_INSTRUCTIONS)
|
||||
{
|
||||
ietf_attr_remediation_instr_t *attr_cast;
|
||||
pen_type_t param;
|
||||
chunk_t str;
|
||||
char *instr;
|
||||
|
||||
attr_cast = (ietf_attr_remediation_instr_t*)attr;
|
||||
param = attr_cast->get_parameters_type(attr_cast);
|
||||
|
||||
if (pen_type_is(param, PEN_IETF, IETF_REMEDIATION_PARAMETERS_STRING))
|
||||
{
|
||||
str = attr_cast->get_string(attr_cast, NULL);
|
||||
instr = strndup(str.ptr, str.len);
|
||||
charonservice->add_remediation_instr(charonservice, instr);
|
||||
free (instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an ITA attribute
|
||||
*/
|
||||
static void handle_ita_attribute(pen_type_t attr_type, pa_tnc_attr_t *attr,
|
||||
imc_msg_t *out_msg)
|
||||
{
|
||||
if (attr_type.type == ITA_ATTR_GET_SETTINGS)
|
||||
{
|
||||
ita_attr_get_settings_t *attr_cast;
|
||||
|
||||
attr_cast = (ita_attr_get_settings_t*)attr;
|
||||
add_measurement((pen_type_t){ PEN_ITA, ITA_ATTR_SETTINGS },
|
||||
out_msg, attr_cast->create_enumerator(attr_cast));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a TCG attribute
|
||||
*/
|
||||
static void handle_tcg_attribute(imc_android_state_t *state,
|
||||
pen_type_t attr_type, pa_tnc_attr_t *attr,
|
||||
imc_msg_t *out_msg)
|
||||
{
|
||||
pts_t *pts;
|
||||
|
||||
pts = state->get_pts(state);
|
||||
switch (attr_type.type)
|
||||
{
|
||||
case TCG_PTS_REQ_PROTO_CAPS:
|
||||
{
|
||||
tcg_pts_attr_proto_caps_t *attr_cast;
|
||||
pts_proto_caps_flag_t caps;
|
||||
|
||||
attr_cast = (tcg_pts_attr_proto_caps_t*)attr;
|
||||
caps = attr_cast->get_flags(attr_cast) & pts->get_proto_caps(pts);
|
||||
pts->set_proto_caps(pts, caps);
|
||||
attr = tcg_pts_attr_proto_caps_create(caps, FALSE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
case TCG_PTS_MEAS_ALGO:
|
||||
{
|
||||
tcg_pts_attr_meas_algo_t *attr_cast;
|
||||
pts_meas_algorithms_t supported, algo;
|
||||
|
||||
if (!pts_meas_algo_probe(&supported))
|
||||
{
|
||||
attr = pts_hash_alg_error_create(PTS_MEAS_ALGO_NONE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
|
||||
algo = pts_meas_algo_select(supported,
|
||||
attr_cast->get_algorithms(attr_cast));
|
||||
if (algo == PTS_MEAS_ALGO_NONE)
|
||||
{
|
||||
attr = pts_hash_alg_error_create(supported);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
pts->set_meas_algorithm(pts, algo);
|
||||
attr = tcg_pts_attr_meas_algo_create(algo, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
case TCG_PTS_REQ_FILE_MEAS:
|
||||
{
|
||||
tcg_pts_attr_req_file_meas_t *attr_cast;
|
||||
pts_file_meas_t *measurements;
|
||||
pts_error_code_t pts_error;
|
||||
u_int32_t delim;
|
||||
u_int16_t req_id;
|
||||
bool is_dir;
|
||||
char *path;
|
||||
|
||||
attr_cast = (tcg_pts_attr_req_file_meas_t*)attr;
|
||||
path = attr_cast->get_pathname(attr_cast);
|
||||
if (!pts->is_path_valid(pts, path, &pts_error))
|
||||
{ /* silently ignore internal errors */
|
||||
break;
|
||||
}
|
||||
else if (pts_error)
|
||||
{
|
||||
attr = ietf_attr_pa_tnc_error_create(pen_type_create(PEN_TCG,
|
||||
pts_error), attr->get_value(attr));
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
delim = attr_cast->get_delimiter(attr_cast);
|
||||
if (delim != SOLIDUS_UTF && delim != REVERSE_SOLIDUS_UTF)
|
||||
{
|
||||
attr = ietf_attr_pa_tnc_error_create(pen_type_create(PEN_TCG,
|
||||
TCG_PTS_INVALID_DELIMITER), attr->get_value(attr));
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
req_id = attr_cast->get_request_id(attr_cast);
|
||||
is_dir = attr_cast->get_directory_flag(attr_cast);
|
||||
|
||||
DBG1(DBG_IMC, "measurement request %d for %s '%s'", req_id,
|
||||
is_dir ? "directory" : "file", path);
|
||||
measurements = pts_file_meas_create_from_path(req_id, path, is_dir,
|
||||
TRUE, pts->get_meas_algorithm(pts));
|
||||
if (!measurements)
|
||||
{
|
||||
attr = ietf_attr_pa_tnc_error_create(pen_type_create(PEN_TCG,
|
||||
TCG_PTS_FILE_NOT_FOUND), attr->get_value(attr));
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
attr = tcg_pts_attr_file_meas_create(measurements);
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DBG1(DBG_IMC, "received unsupported TCG attribute '%N'",
|
||||
tcg_attr_names, attr_type.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
|
||||
*/
|
||||
static TNC_Result tnc_imc_beginhandshake(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id)
|
||||
{
|
||||
imc_state_t *state;
|
||||
imc_msg_t *out_msg;
|
||||
TNC_Result result = TNC_RESULT_SUCCESS;
|
||||
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
if (!imc_android->get_state(imc_android, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"android.imc.send_os_info", TRUE))
|
||||
{
|
||||
out_msg = imc_msg_create(imc_android, state, connection_id, imc_id,
|
||||
TNC_IMVID_ANY, msg_types[0]);
|
||||
add_measurement((pen_type_t){ PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION },
|
||||
out_msg, NULL);
|
||||
add_measurement((pen_type_t){ PEN_IETF, IETF_ATTR_STRING_VERSION },
|
||||
out_msg, NULL);
|
||||
add_measurement((pen_type_t){ PEN_ITA, ITA_ATTR_DEVICE_ID },
|
||||
out_msg, NULL);
|
||||
/* send PA-TNC message with the excl flag not set */
|
||||
result = out_msg->send(out_msg, FALSE);
|
||||
out_msg->destroy(out_msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static TNC_Result receive_message(imc_android_state_t *state, imc_msg_t *in_msg)
|
||||
{
|
||||
imc_msg_t *out_msg;
|
||||
enumerator_t *enumerator;
|
||||
pa_tnc_attr_t *attr;
|
||||
pen_type_t attr_type;
|
||||
TNC_Result result;
|
||||
bool fatal_error = FALSE;
|
||||
|
||||
/* parse received PA-TNC message and handle local and remote errors */
|
||||
result = in_msg->receive(in_msg, &fatal_error);
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
out_msg = imc_msg_create_as_reply(in_msg);
|
||||
|
||||
/* analyze PA-TNC attributes */
|
||||
enumerator = in_msg->create_attribute_enumerator(in_msg);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
attr_type = attr->get_type(attr);
|
||||
|
||||
switch (attr_type.vendor_id)
|
||||
{
|
||||
case PEN_IETF:
|
||||
handle_ietf_attribute(attr_type, attr, out_msg);
|
||||
continue;
|
||||
case PEN_ITA:
|
||||
handle_ita_attribute(attr_type, attr, out_msg);
|
||||
continue;
|
||||
case PEN_TCG:
|
||||
handle_tcg_attribute(state, attr_type, attr, out_msg);
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (fatal_error)
|
||||
{
|
||||
result = TNC_RESULT_FATAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = out_msg->send(out_msg, TRUE);
|
||||
}
|
||||
out_msg->destroy(out_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
|
||||
|
||||
*/
|
||||
static TNC_Result tnc_imc_receivemessage(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_MessageType msg_type)
|
||||
{
|
||||
imc_state_t *state;
|
||||
imc_msg_t *in_msg;
|
||||
TNC_Result result;
|
||||
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
if (!imc_android->get_state(imc_android, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
in_msg = imc_msg_create_from_data(imc_android, state, connection_id,
|
||||
msg_type, chunk_create(msg, msg_len));
|
||||
result = receive_message((imc_android_state_t*)state, in_msg);
|
||||
in_msg->destroy(in_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
|
||||
*/
|
||||
static TNC_Result tnc_imc_receivemessagelong(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_UInt32 msg_flags,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_VendorID msg_vid,
|
||||
TNC_MessageSubtype msg_subtype,
|
||||
TNC_UInt32 src_imv_id,
|
||||
TNC_UInt32 dst_imc_id)
|
||||
{
|
||||
imc_state_t *state;
|
||||
imc_msg_t *in_msg;
|
||||
TNC_Result result;
|
||||
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
if (!imc_android->get_state(imc_android, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
in_msg = imc_msg_create_from_long_data(imc_android, state, connection_id,
|
||||
src_imv_id, dst_imc_id,msg_vid, msg_subtype,
|
||||
chunk_create(msg, msg_len));
|
||||
result = receive_message((imc_android_state_t*)state, in_msg);
|
||||
in_msg->destroy(in_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
|
||||
*/
|
||||
static TNC_Result tnc_imc_batchending(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id)
|
||||
{
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
|
||||
*/
|
||||
static TNC_Result tnc_imc_terminate(TNC_IMCID imc_id)
|
||||
{
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
imc_android->destroy(imc_android);
|
||||
imc_android = NULL;
|
||||
libpts_deinit();
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
|
||||
*/
|
||||
static TNC_Result tnc_imc_providebindfunction(TNC_IMCID imc_id,
|
||||
TNC_TNCC_BindFunctionPointer bind_function)
|
||||
{
|
||||
if (!imc_android)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
return imc_android->bind_functions(imc_android, bind_function);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
bool imc_android_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
bool reg, void *data)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
jobject obj, context = (jobject)data;
|
||||
jclass cls;
|
||||
bool success = TRUE;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
if (reg)
|
||||
{
|
||||
cls = (*env)->FindClass(env, JNI_PACKAGE_STRING "/imc/AndroidImc");
|
||||
if (!cls)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
android_imc_cls = (*env)->NewGlobalRef(env, cls);
|
||||
method_id = (*env)->GetMethodID(env, cls, "<init>",
|
||||
"(Landroid/content/Context;)V");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
obj = (*env)->NewObject(env, cls, method_id, context);
|
||||
if (!obj)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
android_imc = (*env)->NewGlobalRef(env, obj);
|
||||
androidjni_detach_thread();
|
||||
|
||||
if (tnc->imcs->load_from_functions(tnc->imcs, "Android",
|
||||
tnc_imc_initialize, tnc_imc_notifyconnectionchange,
|
||||
tnc_imc_beginhandshake, tnc_imc_receivemessage,
|
||||
tnc_imc_receivemessagelong, tnc_imc_batchending,
|
||||
tnc_imc_terminate, tnc_imc_providebindfunction))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
failed:
|
||||
DBG1(DBG_IMC, "initialization of Android IMC failed");
|
||||
androidjni_exception_occurred(env);
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (android_imc)
|
||||
{
|
||||
(*env)->DeleteGlobalRef(env, android_imc);
|
||||
android_imc = NULL;
|
||||
}
|
||||
if (android_imc_cls)
|
||||
{
|
||||
(*env)->DeleteGlobalRef(env, android_imc_cls);
|
||||
android_imc_cls = NULL;
|
||||
}
|
||||
androidjni_detach_thread();
|
||||
return success;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup android_imc android_imc
|
||||
* @{ @ingroup android_byod
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_IMC_H_
|
||||
#define ANDROID_IMC_H_
|
||||
|
||||
/**
|
||||
* Callback for the Android IMC plugin
|
||||
*/
|
||||
bool imc_android_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
bool reg, void *data);
|
||||
|
||||
#endif /** ANDROID_IMC_H_ @}*/
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012 Andreas Steffen
|
||||
* 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 "imc_android_state.h"
|
||||
|
||||
#include <tncif_names.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_imc_android_state_t private_imc_android_state_t;
|
||||
|
||||
/**
|
||||
* Private data of an imc_state_t object.
|
||||
*/
|
||||
struct private_imc_android_state_t {
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
imc_android_state_t public;
|
||||
|
||||
/**
|
||||
* TNCCS connection ID
|
||||
*/
|
||||
TNC_ConnectionID connection_id;
|
||||
|
||||
/**
|
||||
* TNCCS connection state
|
||||
*/
|
||||
TNC_ConnectionState state;
|
||||
|
||||
/**
|
||||
* Assessment/Evaluation Result
|
||||
*/
|
||||
TNC_IMV_Evaluation_Result result;
|
||||
|
||||
/**
|
||||
* Does the TNCCS connection support long message types?
|
||||
*/
|
||||
bool has_long;
|
||||
|
||||
/**
|
||||
* Does the TNCCS connection support exclusive delivery?
|
||||
*/
|
||||
bool has_excl;
|
||||
|
||||
/**
|
||||
* Maximum PA-TNC message size for this TNCCS connection
|
||||
*/
|
||||
u_int32_t max_msg_len;
|
||||
|
||||
/**
|
||||
* TCG Platform Trust Service (PTS)
|
||||
*/
|
||||
pts_t *pts;
|
||||
};
|
||||
|
||||
METHOD(imc_state_t, get_connection_id, TNC_ConnectionID,
|
||||
private_imc_android_state_t *this)
|
||||
{
|
||||
return this->connection_id;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, has_long, bool,
|
||||
private_imc_android_state_t *this)
|
||||
{
|
||||
return this->has_long;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, has_excl, bool,
|
||||
private_imc_android_state_t *this)
|
||||
{
|
||||
return this->has_excl;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, set_flags, void,
|
||||
private_imc_android_state_t *this, bool has_long, bool has_excl)
|
||||
{
|
||||
this->has_long = has_long;
|
||||
this->has_excl = has_excl;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, set_max_msg_len, void,
|
||||
private_imc_android_state_t *this, u_int32_t max_msg_len)
|
||||
{
|
||||
this->max_msg_len = max_msg_len;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, get_max_msg_len, u_int32_t,
|
||||
private_imc_android_state_t *this)
|
||||
{
|
||||
return this->max_msg_len;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, change_state, void,
|
||||
private_imc_android_state_t *this, TNC_ConnectionState new_state)
|
||||
{
|
||||
this->state = new_state;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, set_result, void,
|
||||
private_imc_android_state_t *this, TNC_IMCID id, TNC_IMV_Evaluation_Result result)
|
||||
{
|
||||
this->result = result;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, get_result, bool,
|
||||
private_imc_android_state_t *this, TNC_IMCID id, TNC_IMV_Evaluation_Result *result)
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
*result = this->result;
|
||||
}
|
||||
return this->result != TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
|
||||
}
|
||||
|
||||
METHOD(imc_state_t, destroy, void,
|
||||
private_imc_android_state_t *this)
|
||||
{
|
||||
this->pts->destroy(this->pts);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(imc_android_state_t, get_pts, pts_t*,
|
||||
private_imc_android_state_t *this)
|
||||
{
|
||||
return this->pts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
imc_state_t *imc_android_state_create(TNC_ConnectionID connection_id)
|
||||
{
|
||||
private_imc_android_state_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.interface = {
|
||||
.get_connection_id = _get_connection_id,
|
||||
.has_long = _has_long,
|
||||
.has_excl = _has_excl,
|
||||
.set_flags = _set_flags,
|
||||
.set_max_msg_len = _set_max_msg_len,
|
||||
.get_max_msg_len = _get_max_msg_len,
|
||||
.change_state = _change_state,
|
||||
.set_result = _set_result,
|
||||
.get_result = _get_result,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_pts = _get_pts,
|
||||
},
|
||||
.state = TNC_CONNECTION_STATE_CREATE,
|
||||
.result = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
|
||||
.connection_id = connection_id,
|
||||
.pts = pts_create(TRUE),
|
||||
);
|
||||
|
||||
return &this->public.interface;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup imc_android_state imc_android_state
|
||||
* @{ @ingroup android_byod
|
||||
*/
|
||||
|
||||
#ifndef IMC_ANDROID_STATE_H_
|
||||
#define IMC_ANDROID_STATE_H_
|
||||
|
||||
#include <imc/imc_state.h>
|
||||
#include <pts/pts.h>
|
||||
|
||||
typedef struct imc_android_state_t imc_android_state_t;
|
||||
|
||||
/**
|
||||
* Internal state of an imc_android_t connection instance
|
||||
*/
|
||||
struct imc_android_state_t {
|
||||
|
||||
/**
|
||||
* imc_state_t interface
|
||||
*/
|
||||
imc_state_t interface;
|
||||
|
||||
/**
|
||||
* Get TCG Platform Trust Service (PTS) object
|
||||
*/
|
||||
pts_t *(*get_pts)(imc_android_state_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an imc_android_state_t instance
|
||||
*
|
||||
* @param id connection ID
|
||||
*/
|
||||
imc_state_t* imc_android_state_create(TNC_ConnectionID id);
|
||||
|
||||
#endif /** IMC_ANDROID_STATE_H_ @}*/
|
||||
@@ -30,6 +30,10 @@
|
||||
#include "kernel/android_ipsec.h"
|
||||
#include "kernel/android_net.h"
|
||||
|
||||
#ifdef USE_BYOD
|
||||
#include "byod/imc_android.h"
|
||||
#endif
|
||||
|
||||
#include <daemon.h>
|
||||
#include <hydra.h>
|
||||
#include <ipsec.h>
|
||||
@@ -158,6 +162,61 @@ 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;
|
||||
}
|
||||
|
||||
METHOD(charonservice_t, add_remediation_instr, bool,
|
||||
private_charonservice_t *this, char *instr)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jmethodID method_id;
|
||||
jstring jinstr;
|
||||
bool success = FALSE;
|
||||
|
||||
androidjni_attach_thread(&env);
|
||||
|
||||
method_id = (*env)->GetMethodID(env, android_charonvpnservice_class,
|
||||
"addRemediationInstruction",
|
||||
"(Ljava/lang/String;)V");
|
||||
if (!method_id)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
jinstr = (*env)->NewStringUTF(env, instr);
|
||||
if (!jinstr)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
(*env)->CallVoidMethod(env, this->vpn_service, method_id, jinstr);
|
||||
success = !androidjni_exception_occurred(env);
|
||||
|
||||
failed:
|
||||
androidjni_exception_occurred(env);
|
||||
androidjni_detach_thread();
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bypass a single socket
|
||||
*/
|
||||
@@ -357,7 +416,7 @@ static void initiate(char *type, char *gateway, char *username, char *password)
|
||||
/**
|
||||
* Initialize/deinitialize Android backend
|
||||
*/
|
||||
static bool charonservice_register(void *plugin, plugin_feature_t *feature,
|
||||
static bool charonservice_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
bool reg, void *data)
|
||||
{
|
||||
private_charonservice_t *this = (private_charonservice_t*)charonservice;
|
||||
@@ -434,25 +493,37 @@ static void set_options(char *logfile)
|
||||
lib->settings->set_str(lib->settings,
|
||||
"charon.interfaces_ignore", "lo, tun0, tun1, tun2, tun3, "
|
||||
"tun4");
|
||||
|
||||
#ifdef USE_BYOD
|
||||
lib->settings->set_str(lib->settings,
|
||||
"charon.plugins.eap-tnc.protocol", "tnccs-2.0");
|
||||
lib->settings->set_bool(lib->settings,
|
||||
"android.imc.send_os_info", TRUE);
|
||||
lib->settings->set_str(lib->settings,
|
||||
"libtnccs.tnc_config", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the charonservice object
|
||||
*/
|
||||
static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
||||
static void charonservice_init(JNIEnv *env, jobject service, jobject builder,
|
||||
jboolean byod)
|
||||
{
|
||||
private_charonservice_t *this;
|
||||
static plugin_feature_t features[] = {
|
||||
PLUGIN_CALLBACK(kernel_ipsec_register, kernel_android_ipsec_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)charonservice_register, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "Android backend"),
|
||||
PLUGIN_CALLBACK(charonservice_register, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "android-backend"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "libcharon"),
|
||||
};
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.update_status = _update_status,
|
||||
.update_imc_state = _update_imc_state,
|
||||
.add_remediation_instr = _add_remediation_instr,
|
||||
.bypass_socket = _bypass_socket,
|
||||
.get_trusted_certificates = _get_trusted_certificates,
|
||||
.get_user_certificate = _get_user_certificate,
|
||||
@@ -471,6 +542,21 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
||||
|
||||
lib->plugins->add_static_features(lib->plugins, "androidbridge", features,
|
||||
countof(features), TRUE);
|
||||
|
||||
#ifdef USE_BYOD
|
||||
if (byod)
|
||||
{
|
||||
plugin_feature_t byod_features[] = {
|
||||
PLUGIN_CALLBACK(imc_android_register, this->vpn_service),
|
||||
PLUGIN_PROVIDE(CUSTOM, "android-imc"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "android-backend"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "imc-manager"),
|
||||
};
|
||||
|
||||
lib->plugins->add_static_features(lib->plugins, "android-byod",
|
||||
byod_features, countof(byod_features), TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -504,11 +590,11 @@ static void segv_handler(int signal)
|
||||
* Initialize charon and the libraries via JNI
|
||||
*/
|
||||
JNI_METHOD(CharonVpnService, initializeCharon, void,
|
||||
jobject builder, jstring jlogfile)
|
||||
jobject builder, jstring jlogfile, jboolean byod)
|
||||
{
|
||||
struct sigaction action;
|
||||
struct utsname utsname;
|
||||
char *logfile;
|
||||
char *logfile, *plugins;
|
||||
|
||||
/* logging for library during initialization, as we have no bus yet */
|
||||
dbg = dbg_android;
|
||||
@@ -551,7 +637,7 @@ JNI_METHOD(CharonVpnService, initializeCharon, void,
|
||||
|
||||
charon->load_loggers(charon, NULL, FALSE);
|
||||
|
||||
charonservice_init(env, this, builder);
|
||||
charonservice_init(env, this, builder, byod);
|
||||
|
||||
if (uname(&utsname) != 0)
|
||||
{
|
||||
@@ -560,7 +646,18 @@ JNI_METHOD(CharonVpnService, initializeCharon, void,
|
||||
DBG1(DBG_DMN, "Starting IKE charon daemon (strongSwan "VERSION", %s %s, %s)",
|
||||
utsname.sysname, utsname.release, utsname.machine);
|
||||
|
||||
if (!charon->initialize(charon, PLUGINS))
|
||||
#ifdef PLUGINS_BYOD
|
||||
if (byod)
|
||||
{
|
||||
plugins = PLUGINS " " PLUGINS_BYOD;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
plugins = PLUGINS;
|
||||
}
|
||||
|
||||
if (!charon->initialize(charon, plugins))
|
||||
{
|
||||
libcharon_deinit();
|
||||
charonservice_deinit(env);
|
||||
|
||||
@@ -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
|
||||
@@ -21,6 +21,9 @@
|
||||
* @defgroup android_backend backend
|
||||
* @ingroup libandroidbridge
|
||||
*
|
||||
* @defgroup android_byod byod
|
||||
* @ingroup libandroidbridge
|
||||
*
|
||||
* @defgroup android_kernel kernel
|
||||
* @ingroup libandroidbridge
|
||||
*
|
||||
@@ -38,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;
|
||||
|
||||
/**
|
||||
@@ -53,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.
|
||||
*
|
||||
@@ -68,6 +82,22 @@ 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);
|
||||
|
||||
/**
|
||||
* Add a remediation instruction via JNI
|
||||
*
|
||||
* @param instr remediation instruction
|
||||
* @return TRUE on success
|
||||
*/
|
||||
bool (*add_remediation_instr)(charonservice_t *this, char *instr);
|
||||
|
||||
/**
|
||||
* Install a bypass policy for the given socket using the protect() Method
|
||||
* of the Android VpnService interface.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape>
|
||||
<solid
|
||||
android:color="@color/panel_separator" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:left="2dp">
|
||||
<shape>
|
||||
<solid
|
||||
android:color="@color/panel_background" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2012-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.
|
||||
-->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape>
|
||||
<solid
|
||||
android:color="@color/panel_separator" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:bottom="2dp">
|
||||
<shape>
|
||||
<solid
|
||||
android:color="@color/panel_background" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false" >
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.RemediationInstructionsFragment"
|
||||
android:id="@+id/remediation_instructions_fragment"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:layout_width="0dp"
|
||||
android:background="@drawable/remediation_instruction_background_large"
|
||||
android:padding="5dp" >
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.RemediationInstructionFragment"
|
||||
android:id="@+id/remediation_instruction_fragment"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="2dp"
|
||||
android:background="@drawable/state_background"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/imc_state_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="@string/imc_state_label"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/imc_state"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="20sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/action"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:text="@string/show_remediation_instructions"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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
|
||||
@@ -24,6 +24,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.ImcStateFragment"
|
||||
android:id="@+id/imc_state_frag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<fragment
|
||||
class="org.strongswan.android.ui.VpnProfileListFragment"
|
||||
android:id="@+id/profile_list_frag"
|
||||
|
||||
@@ -65,6 +65,11 @@
|
||||
android:spinnerMode="dropdown"
|
||||
android:entries="@array/vpn_types" />
|
||||
|
||||
<include
|
||||
android:id="@+id/tnc_notice"
|
||||
layout="@layout/two_line_button"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/username_password_group"
|
||||
android:layout_width="match_parent"
|
||||
@@ -114,7 +119,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/select_user_certificate"
|
||||
layout="@layout/certificate_selector" />
|
||||
layout="@layout/two_line_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -132,7 +137,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/select_certificate"
|
||||
layout="@layout/certificate_selector" />
|
||||
layout="@layout/two_line_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textIsSelectable="true"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textIsSelectable="true"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/list_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textIsSelectable="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<include
|
||||
layout="@android:layout/list_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="8dip"
|
||||
android:paddingTop="8dip"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:mode="twoLine" >
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textIsSelectable="false" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/text1"
|
||||
android:layout_alignLeft="@android:id/text1"
|
||||
android:layout_alignRight="@android:id/text1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textIsSelectable="false" />
|
||||
|
||||
</TwoLineListItem>
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2012 Tobias Brunner
|
||||
Copyright (C) 2013 Tobias Brunner
|
||||
Hochschule fuer Technik Rapperswil
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
@@ -13,9 +13,9 @@
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/fragment_container">
|
||||
|
||||
<solid
|
||||
android:color="#333" />
|
||||
|
||||
</shape>
|
||||
</FrameLayout>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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
|
||||
@@ -18,8 +18,8 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="5dp"
|
||||
android:background="@drawable/vpn_state_background"
|
||||
android:paddingBottom="2dp"
|
||||
android:background="@drawable/state_background"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<GridLayout
|
||||
@@ -83,9 +83,4 @@
|
||||
style="?android:attr/borderlessButtonStyle" >
|
||||
</Button>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
<item>IKEv2 EAP (Benutzername/Passwort)</item>
|
||||
<item>IKEv2 Zertifikat</item>
|
||||
<item>IKEv2 Zertifikat + EAP (Benutzername/Passwort)</item>
|
||||
<item>IKEv2 EAP-TNC (Benutzername/Passwort)</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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
|
||||
@@ -69,6 +69,9 @@
|
||||
<string name="alert_text_no_input_username">Bitte geben Sie hier Ihren Benutzernamen ein</string>
|
||||
<string name="alert_text_nocertfound_title">Kein CA-Zertifikat ausgewählt</string>
|
||||
<string name="alert_text_nocertfound">Bitte wählen Sie eines aus oder aktivieren Sie <i>Automatisch wählen</i></string>
|
||||
<string name="tnc_notice_title">EAP-TNC kann Ihre Privatsphäre beeinträchtigen</string>
|
||||
<string name="tnc_notice_subtitle">Gerätedaten werden an den Gateway-Betreiber gesendet</string>
|
||||
<string name="tnc_notice_details"><p>Trusted Network Connect (TNC) erlaubt Gateway-Betreibern den Gesundheitszustand von Endgeräten zu prüfen.</p><p>Dazu kann der Betreiber Daten verlangen, wie etwa eine eindeutige Identifikationsnummer, eine Liste der installierten Pakete, Systemeinstellungen oder kryptografische Prüfsummen von Dateien.</p><b>Solche Daten werden nur übermittelt nachdem die Identität des Gateways geprüft wurde.</b></string>
|
||||
|
||||
<!-- Trusted certificate selection -->
|
||||
<string name="trusted_certs_title">CA-Zertifikate</string>
|
||||
@@ -86,6 +89,15 @@
|
||||
<string name="state_disabled">Kein aktives Profil</string>
|
||||
<string name="state_error">Fehler</string>
|
||||
|
||||
<!-- IMC state fragment -->
|
||||
<string name="imc_state_label">Assessment:</string>
|
||||
<string name="imc_state_isolate">Eingeschränkt</string>
|
||||
<string name="imc_state_block">Fehlgeschlagen</string>
|
||||
<string name="show_remediation_instructions">Korrekturanweisungen anzeigen</string>
|
||||
|
||||
<!-- Remediation instructions -->
|
||||
<string name="remediation_instructions_title">Korrekturanweisungen</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
<string name="login_title">Passwort eingeben um zu verbinden</string>
|
||||
<string name="login_confirm">Verbinden</string>
|
||||
@@ -94,6 +106,7 @@
|
||||
<string name="error_unreachable">Gateway ist nicht erreichbar.</string>
|
||||
<string name="error_peer_auth_failed">Authentifizierung des Gateway ist fehlgeschlagen.</string>
|
||||
<string name="error_auth_failed">Benutzerauthentifizierung ist fehlgeschlagen.</string>
|
||||
<string name="error_assessment_failed">Sicherheitsassessment ist fehlgeschlagen.</string>
|
||||
<string name="error_generic">Unbekannter Fehler während des Verbindens.</string>
|
||||
<string name="connecting_title">Verbinden: %1$s</string>
|
||||
<string name="connecting_message">Verbinde mit \""%1$s\".</string>
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
<item>IKEv2 EAP (użytkownik/hasło)</item>
|
||||
<item>IKEv2 certyfikat</item>
|
||||
<item>IKEv2 certyfikat + EAP (użytkownik/hasło)</item>
|
||||
<item>IKEv2 EAP-TNC (użytkownik/hasło)</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2012 Giuliano Grassi
|
||||
Copyright (C) 2012 Ralf Sager
|
||||
Copyright (C) 2012 Andreas Steffen
|
||||
HSR Hochschule fuer Technik Rapperswil
|
||||
|
||||
@@ -71,6 +69,9 @@
|
||||
<string name="alert_text_no_input_username">Wprowadź swoją nazwę użytkownika</string>
|
||||
<string name="alert_text_nocertfound_title">Nie wybrano żadnego certyfikatu CA</string>
|
||||
<string name="alert_text_nocertfound">Wybierz lub uaktywnij jeden <i>Wybierz automatycznie</i></string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the gateway operator</string>
|
||||
<string name="tnc_notice_details"><p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b></string>
|
||||
|
||||
<!-- Trusted certificate selection -->
|
||||
<string name="trusted_certs_title">Certyfikaty CA</string>
|
||||
@@ -88,6 +89,15 @@
|
||||
<string name="state_disabled">Brak aktywnego VPN</string>
|
||||
<string name="state_error">Błąd</string>
|
||||
|
||||
<!-- IMC state fragment -->
|
||||
<string name="imc_state_label">Assessment:</string>
|
||||
<string name="imc_state_isolate">Restricted</string>
|
||||
<string name="imc_state_block">Failed</string>
|
||||
<string name="show_remediation_instructions">View remediation instructions</string>
|
||||
|
||||
<!-- Remediation instructions -->
|
||||
<string name="remediation_instructions_title">Remediation instructions</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
<string name="login_title">Wprowadż hasło</string>
|
||||
<string name="login_confirm">Połącz</string>
|
||||
@@ -96,6 +106,7 @@
|
||||
<string name="error_unreachable">Bramka jest nieosiągalna</string>
|
||||
<string name="error_peer_auth_failed">Błąd przy weryfikacji bramki</string>
|
||||
<string name="error_auth_failed">Błąd przy autoryzacji użytkownika</string>
|
||||
<string name="error_assessment_failed">Security assessment failed.</string>
|
||||
<string name="error_generic">Nieznany błąd w czasie połączenia</string>
|
||||
<string name="connecting_title">Łączenie: %1$s</string>
|
||||
<string name="connecting_message">Tworzenie tunelu VPN z \""%1$s\".</string>
|
||||
|
||||
@@ -18,5 +18,6 @@
|
||||
<item>IKEv2 EAP (Логин/Пароль)</item>
|
||||
<item>IKEv2 Сертификат</item>
|
||||
<item>IKEv2 Сертификат + EAP (Логин/Пароль)</item>
|
||||
<item>IKEv2 EAP-TNC (Логин/Пароль)</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
<string name="alert_text_no_input_username">Пожалуйста введите имя пользователя</string>
|
||||
<string name="alert_text_nocertfound_title">Не выбран сертификат CA</string>
|
||||
<string name="alert_text_nocertfound">Пожалуйста выберите один <i>Выбрать автоматически</i></string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the gateway operator</string>
|
||||
<string name="tnc_notice_details"><p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b></string>
|
||||
|
||||
<!-- Trusted certificate selection -->
|
||||
<string name="trusted_certs_title">Сертификаты CA</string>
|
||||
@@ -83,6 +86,15 @@
|
||||
<string name="state_disabled">Нет активных VPN</string>
|
||||
<string name="state_error">Ошибка</string>
|
||||
|
||||
<!-- IMC state fragment -->
|
||||
<string name="imc_state_label">Assessment:</string>
|
||||
<string name="imc_state_isolate">Restricted</string>
|
||||
<string name="imc_state_block">Failed</string>
|
||||
<string name="show_remediation_instructions">View remediation instructions</string>
|
||||
|
||||
<!-- Remediation instructions -->
|
||||
<string name="remediation_instructions_title">Remediation instructions</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
<string name="login_title">Введите пароль для соединения</string>
|
||||
<string name="login_confirm">Соединить</string>
|
||||
@@ -91,6 +103,7 @@
|
||||
<string name="error_unreachable">Шлюз недоступен.</string>
|
||||
<string name="error_peer_auth_failed">Ошибка авторизаци при подключении к шлюзу.</string>
|
||||
<string name="error_auth_failed">Ошибка авторизации пользователя.</string>
|
||||
<string name="error_assessment_failed">Security assessment failed.</string>
|
||||
<string name="error_generic">Неизвестная ошибка.</string>
|
||||
<string name="connecting_title">Подключение: %1$s</string>
|
||||
<string name="connecting_message">Подключение к VPN с \""%1$s\".</string>
|
||||
|
||||
@@ -18,5 +18,6 @@
|
||||
<item>IKEv2 EAP (Логін/Пароль)</item>
|
||||
<item>IKEv2 Сертифікати</item>
|
||||
<item>IKEv2 Сертифікати + EAP (Логін/Пароль)</item>
|
||||
<item>IKEv2 EAP-TNC (Логін/Пароль)</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2012 Dmitry Korzhevin
|
||||
Copyright (C) 2013 Pavel Kopchyk
|
||||
Copyright (C) 2012 Dmitry Korzhevin
|
||||
|
||||
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
|
||||
@@ -67,6 +67,9 @@
|
||||
<string name="alert_text_no_input_username">Введіть ім\'я користувача тут</string>
|
||||
<string name="alert_text_nocertfound_title">Не вибрано сертифікат CA</string>
|
||||
<string name="alert_text_nocertfound">Будь ласка виберіть один <i>Вибрати автоматично</i></string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the gateway operator</string>
|
||||
<string name="tnc_notice_details"><p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b></string>
|
||||
|
||||
<!-- Trusted certificate selection -->
|
||||
<string name="trusted_certs_title">Сертифікати CA</string>
|
||||
@@ -84,6 +87,15 @@
|
||||
<string name="state_disabled">Немає активних VPN</string>
|
||||
<string name="state_error">Помилка</string>
|
||||
|
||||
<!-- IMC state fragment -->
|
||||
<string name="imc_state_label">Assessment:</string>
|
||||
<string name="imc_state_isolate">Restricted</string>
|
||||
<string name="imc_state_block">Failed</string>
|
||||
<string name="show_remediation_instructions">View remediation instructions</string>
|
||||
|
||||
<!-- Remediation instructions -->
|
||||
<string name="remediation_instructions_title">Remediation instructions</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
<string name="login_title">Введіть пароль для з\'єднання</string>
|
||||
<string name="login_confirm">Підключити</string>
|
||||
@@ -92,6 +104,7 @@
|
||||
<string name="error_unreachable">Немає зв\'язку зі шлюзом.</string>
|
||||
<string name="error_peer_auth_failed">Помилка перевірки данних аутентифікації шлюза.</string>
|
||||
<string name="error_auth_failed">Помилка аутентифікації користувача.</string>
|
||||
<string name="error_assessment_failed">Security assessment failed.</string>
|
||||
<string name="error_generic">Невідома помилка під час підключення.</string>
|
||||
<string name="connecting_title">Підключення: %1$s</string>
|
||||
<string name="connecting_message">Підключення VPN з \""%1$s\".</string>
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
<item>IKEv2 EAP (Username/Password)</item>
|
||||
<item>IKEv2 Certificate</item>
|
||||
<item>IKEv2 Certificate + EAP (Username/Password)</item>
|
||||
<item>IKEv2 EAP-TNC (Username/Password)</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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
|
||||
@@ -18,7 +18,16 @@
|
||||
<color
|
||||
name="error_text">#D9192C</color>
|
||||
|
||||
<color
|
||||
name="warning_text">#FF9909</color>
|
||||
|
||||
<color
|
||||
name="success_text">#99CC00</color>
|
||||
|
||||
<color
|
||||
name="panel_background">#333333</color>
|
||||
|
||||
<color
|
||||
name="panel_separator">#5a5a5a</color>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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
|
||||
@@ -69,6 +69,9 @@
|
||||
<string name="alert_text_no_input_username">Please enter your username here</string>
|
||||
<string name="alert_text_nocertfound_title">No CA certificate selected</string>
|
||||
<string name="alert_text_nocertfound">Please select one or activate <i>Select automatically</i></string>
|
||||
<string name="tnc_notice_title">EAP-TNC may affect your privacy</string>
|
||||
<string name="tnc_notice_subtitle">Device data is sent to the gateway operator</string>
|
||||
<string name="tnc_notice_details"><p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b></string>
|
||||
|
||||
<!-- Trusted certificate selection -->
|
||||
<string name="trusted_certs_title">CA certificates</string>
|
||||
@@ -86,6 +89,15 @@
|
||||
<string name="state_disabled">No active VPN</string>
|
||||
<string name="state_error">Error</string>
|
||||
|
||||
<!-- IMC state fragment -->
|
||||
<string name="imc_state_label">Assessment:</string>
|
||||
<string name="imc_state_isolate">Restricted</string>
|
||||
<string name="imc_state_block">Failed</string>
|
||||
<string name="show_remediation_instructions">View remediation instructions</string>
|
||||
|
||||
<!-- Remediation instructions -->
|
||||
<string name="remediation_instructions_title">Remediation instructions</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
<string name="login_title">Enter password to connect</string>
|
||||
<string name="login_confirm">Connect</string>
|
||||
@@ -94,6 +106,7 @@
|
||||
<string name="error_unreachable">Gateway is unreachable.</string>
|
||||
<string name="error_peer_auth_failed">Verifying gateway authentication failed.</string>
|
||||
<string name="error_auth_failed">User authentication failed.</string>
|
||||
<string name="error_assessment_failed">Security assessment failed.</string>
|
||||
<string name="error_generic">Unspecified failure while connecting.</string>
|
||||
<string name="connecting_title">Connecting: %1$s</string>
|
||||
<string name="connecting_message">Establishing VPN with \""%1$s\".</string>
|
||||
|
||||
@@ -20,11 +20,13 @@ public enum VpnType
|
||||
/* the order here must match the items in R.array.vpn_types */
|
||||
IKEV2_EAP("ikev2-eap", true, false),
|
||||
IKEV2_CERT("ikev2-cert", false, true),
|
||||
IKEV2_CERT_EAP("ikev2-cert-eap", true, true);
|
||||
IKEV2_CERT_EAP("ikev2-cert-eap", true, true),
|
||||
IKEV2_BYOD_EAP("ikev2-byod-eap", true, false, true);
|
||||
|
||||
private String mIdentifier;
|
||||
private boolean mCertificate;
|
||||
private boolean mUsernamePassword;
|
||||
private boolean mBYOD;
|
||||
|
||||
/**
|
||||
* Enum which provides additional information about the supported VPN types.
|
||||
@@ -34,10 +36,24 @@ public enum VpnType
|
||||
* @param certificate true if a client certificate is required
|
||||
*/
|
||||
VpnType(String id, boolean userpass, boolean certificate)
|
||||
{
|
||||
this(id, userpass, certificate, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum which provides additional information about the supported VPN types.
|
||||
*
|
||||
* @param id identifier used to store and transmit this specific type
|
||||
* @param userpass true if username and password are required
|
||||
* @param certificate true if a client certificate is required
|
||||
* @param byod true to enable BYOD features
|
||||
*/
|
||||
VpnType(String id, boolean userpass, boolean certificate, boolean byod)
|
||||
{
|
||||
mIdentifier = id;
|
||||
mUsernamePassword = userpass;
|
||||
mCertificate = certificate;
|
||||
mBYOD = byod;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +85,16 @@ public enum VpnType
|
||||
return mCertificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether BYOD features should be enabled.
|
||||
*
|
||||
* @return true if BYOD features are to be enabled
|
||||
*/
|
||||
public boolean getEnableBYOD()
|
||||
{
|
||||
return mBYOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum entry with the given identifier.
|
||||
*
|
||||
|
||||
@@ -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,8 @@ 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.logic.imc.RemediationInstruction;
|
||||
import org.strongswan.android.ui.MainActivity;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
@@ -208,10 +210,11 @@ 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());
|
||||
initializeCharon(builder, mLogFile);
|
||||
initializeCharon(builder, mLogFile, mCurrentProfile.getVpnType().getEnableBYOD());
|
||||
Log.i(TAG, "charon started");
|
||||
|
||||
initiate(mCurrentProfile.getVpnType().getIdentifier(),
|
||||
@@ -296,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
|
||||
@@ -355,6 +375,41 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a remediation instruction to the VPN state service.
|
||||
* Called via JNI by different threads (but not concurrently).
|
||||
*
|
||||
* @param xml XML text
|
||||
*/
|
||||
public void addRemediationInstruction(String xml)
|
||||
{
|
||||
for (RemediationInstruction instruction : RemediationInstruction.fromXml(xml))
|
||||
{
|
||||
synchronized (mServiceLock)
|
||||
{
|
||||
if (mService != null)
|
||||
{
|
||||
mService.addRemediationInstruction(instruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called via JNI to generate a list of DER encoded CA certificates
|
||||
* as byte array.
|
||||
@@ -461,8 +516,9 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
*
|
||||
* @param builder BuilderAdapter for this connection
|
||||
* @param logfile absolute path to the logfile
|
||||
* @param boyd enable BYOD features
|
||||
*/
|
||||
public native void initializeCharon(BuilderAdapter builder, String logfile);
|
||||
public native void initializeCharon(BuilderAdapter builder, String logfile, boolean byod);
|
||||
|
||||
/**
|
||||
* Deinitialize charon, provided by libandroidbridge.so
|
||||
@@ -600,6 +656,15 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
{
|
||||
System.loadLibrary("crypto");
|
||||
System.loadLibrary("strongswan");
|
||||
|
||||
if (MainActivity.USE_BYOD)
|
||||
{
|
||||
System.loadLibrary("tncif");
|
||||
System.loadLibrary("tnccs");
|
||||
System.loadLibrary("imcv");
|
||||
System.loadLibrary("pts");
|
||||
}
|
||||
|
||||
System.loadLibrary("hydra");
|
||||
System.loadLibrary("charon");
|
||||
System.loadLibrary("ipsec");
|
||||
|
||||
@@ -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
|
||||
@@ -16,10 +16,14 @@
|
||||
package org.strongswan.android.logic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.logic.imc.ImcState;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
@@ -36,6 +40,8 @@ public class VpnStateService extends Service
|
||||
private VpnProfile mProfile;
|
||||
private State mState = State.DISABLED;
|
||||
private ErrorState mError = ErrorState.NO_ERROR;
|
||||
private ImcState mImcState = ImcState.UNKNOWN;
|
||||
private final LinkedList<RemediationInstruction> mRemediationInstructions = new LinkedList<RemediationInstruction>();
|
||||
|
||||
public enum State
|
||||
{
|
||||
@@ -146,6 +152,26 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remediation instructions, if any.
|
||||
*
|
||||
* @return read-only list of instructions
|
||||
*/
|
||||
public List<RemediationInstruction> getRemediationInstructions()
|
||||
{ /* only updated from the main thread so no synchronization needed */
|
||||
return Collections.unmodifiableList(mRemediationInstructions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect any existing connection and shutdown the daemon, the
|
||||
* VpnService is not stopped but it is reset so new connections can be
|
||||
@@ -261,4 +287,54 @@ public class VpnStateService extends Service
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current IMC state and notify all listeners, if changed.
|
||||
*
|
||||
* Setting the state to UNKNOWN clears all remediation instructions.
|
||||
*
|
||||
* 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 (state == ImcState.UNKNOWN)
|
||||
{
|
||||
VpnStateService.this.mRemediationInstructions.clear();
|
||||
}
|
||||
if (VpnStateService.this.mImcState != state)
|
||||
{
|
||||
VpnStateService.this.mImcState = state;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given remediation instruction to the internal list. Listeners
|
||||
* are not notified.
|
||||
*
|
||||
* Instructions are cleared if the IMC state is set to UNKNOWN.
|
||||
*
|
||||
* May be called from threads other than the main thread.
|
||||
*
|
||||
* @param instruction remediation instruction
|
||||
*/
|
||||
public void addRemediationInstruction(final RemediationInstruction instruction)
|
||||
{
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
VpnStateService.this.mRemediationInstructions.add(instruction);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.AttributeType;
|
||||
import org.strongswan.android.logic.imc.collectors.Collector;
|
||||
import org.strongswan.android.logic.imc.collectors.DeviceIdCollector;
|
||||
import org.strongswan.android.logic.imc.collectors.InstalledPackagesCollector;
|
||||
import org.strongswan.android.logic.imc.collectors.PortFilterCollector;
|
||||
import org.strongswan.android.logic.imc.collectors.ProductInformationCollector;
|
||||
import org.strongswan.android.logic.imc.collectors.SettingsCollector;
|
||||
import org.strongswan.android.logic.imc.collectors.StringVersionCollector;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class AndroidImc
|
||||
{
|
||||
private final Context mContext;
|
||||
|
||||
public AndroidImc(Context context)
|
||||
{
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a measurement (the binary encoding of the requested attribute) for
|
||||
* the given vendor specific attribute type.
|
||||
*
|
||||
* @param vendor vendor ID
|
||||
* @param type vendor specific attribute type
|
||||
* @return encoded attribute, or null if not available or failed
|
||||
*/
|
||||
public byte[] getMeasurement(int vendor, int type)
|
||||
{
|
||||
return getMeasurement(vendor, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a measurement (the binary encoding of the requested attribute) for
|
||||
* the given vendor specific attribute type.
|
||||
*
|
||||
* @param vendor vendor ID
|
||||
* @param type vendor specific attribute type
|
||||
* @param args optional arguments for a measurement
|
||||
* @return encoded attribute, or null if not available or failed
|
||||
*/
|
||||
public byte[] getMeasurement(int vendor, int type, String[] args)
|
||||
{
|
||||
AttributeType attributeType = AttributeType.fromValues(vendor, type);
|
||||
Collector collector = null;
|
||||
|
||||
switch (attributeType)
|
||||
{
|
||||
case IETF_PRODUCT_INFORMATION:
|
||||
collector = new ProductInformationCollector();
|
||||
break;
|
||||
case IETF_STRING_VERSION:
|
||||
collector = new StringVersionCollector();
|
||||
break;
|
||||
case IETF_PORT_FILTER:
|
||||
collector = new PortFilterCollector();
|
||||
break;
|
||||
case IETF_INSTALLED_PACKAGES:
|
||||
collector = new InstalledPackagesCollector(mContext);
|
||||
break;
|
||||
case ITA_SETTINGS:
|
||||
collector = new SettingsCollector(mContext, args);
|
||||
break;
|
||||
case ITA_DEVICE_ID:
|
||||
collector = new DeviceIdCollector(mContext);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (collector != null)
|
||||
{
|
||||
Attribute attribute = collector.getMeasurement();
|
||||
if (attribute != null)
|
||||
{
|
||||
return attribute.getEncoding();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Xml;
|
||||
|
||||
public class RemediationInstruction implements Parcelable
|
||||
{
|
||||
private String mTitle;
|
||||
private String mDescription;
|
||||
private String mHeader;
|
||||
private final List<String> mItems = new LinkedList<String>();
|
||||
|
||||
@Override
|
||||
public int describeContents()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags)
|
||||
{
|
||||
dest.writeString(mTitle);
|
||||
dest.writeString(mDescription);
|
||||
dest.writeString(mHeader);
|
||||
dest.writeStringList(mItems);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<RemediationInstruction> CREATOR = new Creator<RemediationInstruction>() {
|
||||
|
||||
@Override
|
||||
public RemediationInstruction[] newArray(int size)
|
||||
{
|
||||
return new RemediationInstruction[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemediationInstruction createFromParcel(Parcel source)
|
||||
{
|
||||
return new RemediationInstruction(source);
|
||||
}
|
||||
};
|
||||
|
||||
private RemediationInstruction()
|
||||
{
|
||||
}
|
||||
|
||||
private RemediationInstruction(Parcel source)
|
||||
{
|
||||
mTitle = source.readString();
|
||||
mDescription = source.readString();
|
||||
mHeader = source.readString();
|
||||
source.readStringList(mItems);
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
private void setTitle(String title)
|
||||
{
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
private void setDescription(String description)
|
||||
{
|
||||
mDescription = description;
|
||||
}
|
||||
|
||||
public String getHeader()
|
||||
{
|
||||
return mHeader;
|
||||
}
|
||||
|
||||
private void setHeader(String header)
|
||||
{
|
||||
mHeader = header;
|
||||
}
|
||||
|
||||
public List<String> getItems()
|
||||
{
|
||||
return Collections.unmodifiableList(mItems);
|
||||
}
|
||||
|
||||
private void addItem(String item)
|
||||
{
|
||||
mItems.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of RemediationInstruction objects from the given XML data.
|
||||
*
|
||||
* @param xml XML data
|
||||
* @return list of RemediationInstruction objects
|
||||
*/
|
||||
public static List<RemediationInstruction> fromXml(String xml)
|
||||
{
|
||||
List<RemediationInstruction> instructions = new LinkedList<RemediationInstruction>();
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
try
|
||||
{
|
||||
parser.setInput(new StringReader(xml));
|
||||
parser.nextTag();
|
||||
readInstructions(parser, instructions);
|
||||
}
|
||||
catch (XmlPullParserException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return instructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a <remediationinstructions> element and store the extracted
|
||||
* RemediationInstruction objects in the given list.
|
||||
*
|
||||
* @param parser
|
||||
* @param instructions
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void readInstructions(XmlPullParser parser, List<RemediationInstruction> instructions) throws XmlPullParserException, IOException
|
||||
{
|
||||
parser.require(XmlPullParser.START_TAG, null, "remediationinstructions");
|
||||
while (parser.next() != XmlPullParser.END_TAG)
|
||||
{
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (parser.getName().equals("instruction"))
|
||||
{
|
||||
RemediationInstruction instruction = new RemediationInstruction();
|
||||
readInstruction(parser, instruction);
|
||||
instructions.add(instruction);
|
||||
}
|
||||
else
|
||||
{
|
||||
skipTag(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an <instruction> element and store the information in the
|
||||
* given RemediationInstruction object.
|
||||
*
|
||||
* @param parser
|
||||
* @param instruction
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void readInstruction(XmlPullParser parser, RemediationInstruction instruction) throws XmlPullParserException, IOException
|
||||
{
|
||||
parser.require(XmlPullParser.START_TAG, null, "instruction");
|
||||
while (parser.next() != XmlPullParser.END_TAG)
|
||||
{
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("title"))
|
||||
{
|
||||
instruction.setTitle(parser.nextText());
|
||||
}
|
||||
else if (name.equals("description"))
|
||||
{
|
||||
instruction.setDescription(parser.nextText());
|
||||
}
|
||||
else if (name.equals("itemsheader"))
|
||||
{
|
||||
instruction.setHeader(parser.nextText());
|
||||
}
|
||||
else if (name.equals("items"))
|
||||
{
|
||||
readItems(parser, instruction);
|
||||
}
|
||||
else
|
||||
{
|
||||
skipTag(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all items of an <items> node and add them to the given
|
||||
* RemediationInstruction object.
|
||||
*
|
||||
* @param parser
|
||||
* @param instruction
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void readItems(XmlPullParser parser, RemediationInstruction instruction) throws XmlPullParserException, IOException
|
||||
{
|
||||
while (parser.next() != XmlPullParser.END_TAG)
|
||||
{
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (parser.getName().equals("item"))
|
||||
{
|
||||
instruction.addItem(parser.nextText());
|
||||
}
|
||||
else
|
||||
{
|
||||
skipTag(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the current tag and all child elements.
|
||||
*
|
||||
* @param parser
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void skipTag(XmlPullParser parser) throws XmlPullParserException, IOException
|
||||
{
|
||||
int depth = 1;
|
||||
|
||||
parser.require(XmlPullParser.START_TAG, null, null);
|
||||
while (depth != 0)
|
||||
{
|
||||
switch (parser.next())
|
||||
{
|
||||
case XmlPullParser.END_TAG:
|
||||
depth--;
|
||||
break;
|
||||
case XmlPullParser.START_TAG:
|
||||
depth++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.attributes;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by attribute classes
|
||||
*/
|
||||
public interface Attribute
|
||||
{
|
||||
/**
|
||||
* Returns the binary encoding of the attribute
|
||||
* @return binary encoding
|
||||
*/
|
||||
public byte[] getEncoding();
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.attributes;
|
||||
|
||||
public enum AttributeType
|
||||
{
|
||||
/* IETF standard PA-TNC attribute types defined by RFC 5792 */
|
||||
IETF_TESTING(PrivateEnterpriseNumber.IETF, 0),
|
||||
IETF_ATTRIBUTE_REQUEST(PrivateEnterpriseNumber.IETF, 1),
|
||||
IETF_PRODUCT_INFORMATION(PrivateEnterpriseNumber.IETF, 2),
|
||||
IETF_NUMERIC_VERSION(PrivateEnterpriseNumber.IETF, 3),
|
||||
IETF_STRING_VERSION(PrivateEnterpriseNumber.IETF, 4),
|
||||
IETF_OPERATIONAL_STATUS(PrivateEnterpriseNumber.IETF, 5),
|
||||
IETF_PORT_FILTER(PrivateEnterpriseNumber.IETF, 6),
|
||||
IETF_INSTALLED_PACKAGES(PrivateEnterpriseNumber.IETF, 7),
|
||||
IETF_PA_TNC_ERROR(PrivateEnterpriseNumber.IETF, 8),
|
||||
IETF_ASSESSMENT_RESULT(PrivateEnterpriseNumber.IETF, 9),
|
||||
IETF_REMEDIATION_INSTRUCTIONS(PrivateEnterpriseNumber.IETF, 10),
|
||||
IETF_FORWARDING_ENABLED(PrivateEnterpriseNumber.IETF, 11),
|
||||
IETF_FACTORY_DEFAULT_PWD_ENABLED(PrivateEnterpriseNumber.IETF, 12),
|
||||
IETF_RESERVED(PrivateEnterpriseNumber.IETF, 0xffffffff),
|
||||
/* ITA attributes */
|
||||
ITA_SETTINGS(PrivateEnterpriseNumber.ITA, 4),
|
||||
ITA_DEVICE_ID(PrivateEnterpriseNumber.ITA, 8);
|
||||
|
||||
private PrivateEnterpriseNumber mVendor;
|
||||
private int mType;
|
||||
|
||||
/**
|
||||
* Enum type for vendor specific attributes (defined in their namespace)
|
||||
*
|
||||
* @param vendor private enterprise number of vendor
|
||||
* @param type vendor specific attribute type
|
||||
*/
|
||||
private AttributeType(PrivateEnterpriseNumber vendor, int type)
|
||||
{
|
||||
mVendor = vendor;
|
||||
mType = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get private enterprise number of vendor
|
||||
*
|
||||
* @return PEN
|
||||
*/
|
||||
public PrivateEnterpriseNumber getVendor()
|
||||
{
|
||||
return mVendor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vendor specific type
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
public int getType()
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum entry from the given numeric values, if defined
|
||||
*
|
||||
* @param vendor vendor id
|
||||
* @param type vendor specific type
|
||||
* @return enum entry or null
|
||||
*/
|
||||
public static AttributeType fromValues(int vendor, int type)
|
||||
{
|
||||
PrivateEnterpriseNumber pen = PrivateEnterpriseNumber.fromValue(vendor);
|
||||
|
||||
if (pen == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (AttributeType attr : AttributeType.values())
|
||||
{
|
||||
if (attr.mVendor == pen && attr.mType == type)
|
||||
{
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.attributes;
|
||||
|
||||
/**
|
||||
* ITA Device ID attribute
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Device ID (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
public class DeviceIdAttribute implements Attribute
|
||||
{
|
||||
private String mDeviceId;
|
||||
|
||||
/**
|
||||
* Set the device ID
|
||||
* @param version version number
|
||||
*/
|
||||
public void setDeviceId(String deviceId)
|
||||
{
|
||||
this.mDeviceId = deviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoding()
|
||||
{
|
||||
return mDeviceId.getBytes();
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.attributes;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.strongswan.android.utils.BufferedByteWriter;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
/**
|
||||
* PA-TNC Installed Packages attribute (see section 4.2.7 of RFC 5792)
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reserved | Package Count |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Pkg Name Len | Package Name (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Version Len | Package Version Number (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
public class InstalledPackagesAttribute implements Attribute
|
||||
{
|
||||
private final short RESERVED = 0;
|
||||
private final LinkedList<Pair<String, String>> mPackages = new LinkedList<Pair<String, String>>();
|
||||
|
||||
/**
|
||||
* Add an installed package to this attribute.
|
||||
* @param name name of the package
|
||||
* @param version version number of the package
|
||||
*/
|
||||
public void addPackage(String name, String version)
|
||||
{
|
||||
mPackages.add(new Pair<String, String>(name, version));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoding()
|
||||
{
|
||||
BufferedByteWriter writer = new BufferedByteWriter();
|
||||
writer.put16(RESERVED);
|
||||
writer.put16((short)mPackages.size());
|
||||
for (Pair<String, String> pair : mPackages)
|
||||
{
|
||||
writer.putLen8(pair.first.getBytes());
|
||||
writer.putLen8(pair.second.getBytes());
|
||||
}
|
||||
return writer.toByteArray();
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.attributes;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.strongswan.android.logic.imc.collectors.Protocol;
|
||||
import org.strongswan.android.utils.BufferedByteWriter;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
/**
|
||||
* PA-TNC Port Filter attribute (see section 4.2.6 of RFC 5792)
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reserved |B| Protocol | Port Number |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reserved |B| Protocol | Port Number |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
public class PortFilterAttribute implements Attribute
|
||||
{
|
||||
private final LinkedList<Pair<Protocol, Short>> mPorts = new LinkedList<Pair<Protocol, Short>>();
|
||||
|
||||
/**
|
||||
* Add an open port with the given protocol and port number
|
||||
* @param protocol transport protocol
|
||||
* @param port port number
|
||||
*/
|
||||
public void addPort(Protocol protocol, short port)
|
||||
{
|
||||
mPorts.add(new Pair<Protocol, Short>(protocol, port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoding()
|
||||
{
|
||||
BufferedByteWriter writer = new BufferedByteWriter();
|
||||
for (Pair<Protocol, Short> port : mPorts)
|
||||
{
|
||||
/* we report open ports, so the BLOCKED flag is not set */
|
||||
writer.put((byte)0);
|
||||
writer.put(port.first.getValue());
|
||||
writer.put16(port.second);
|
||||
}
|
||||
return writer.toByteArray();
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.attributes;
|
||||
|
||||
public enum PrivateEnterpriseNumber
|
||||
{
|
||||
IETF(0x000000),
|
||||
GOOGLE(0x002B79),
|
||||
ITA(0x00902a),
|
||||
UNASSIGNED(0xfffffe),
|
||||
RESERVED(0xffffff);
|
||||
|
||||
private int mValue;
|
||||
|
||||
/**
|
||||
* Enum for private enterprise numbers (PEN) as allocated by IANA
|
||||
*
|
||||
* @param value numeric value
|
||||
*/
|
||||
private PrivateEnterpriseNumber(int value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numeric value of a PEN
|
||||
*
|
||||
* @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 PrivateEnterpriseNumber fromValue(int value)
|
||||
{
|
||||
for (PrivateEnterpriseNumber pen : PrivateEnterpriseNumber.values())
|
||||
{
|
||||
if (pen.mValue == value)
|
||||
{
|
||||
return pen;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.attributes;
|
||||
|
||||
import org.strongswan.android.utils.BufferedByteWriter;
|
||||
|
||||
/**
|
||||
* PA-TNC Product Information attribute (see section 4.2.2 of RFC 5792)
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Product Vendor ID | Product ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Product ID | Product Name (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
public class ProductInformationAttribute implements Attribute
|
||||
{
|
||||
private final String PRODUCT_NAME = "Android";
|
||||
private final short PRODUCT_ID = 0;
|
||||
|
||||
@Override
|
||||
public byte[] getEncoding()
|
||||
{
|
||||
BufferedByteWriter writer = new BufferedByteWriter();
|
||||
writer.put24(PrivateEnterpriseNumber.GOOGLE.getValue());
|
||||
writer.put16(PRODUCT_ID);
|
||||
writer.put(PRODUCT_NAME.getBytes());
|
||||
return writer.toByteArray();
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.attributes;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.strongswan.android.utils.BufferedByteWriter;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
/**
|
||||
* ITA Settings attribute
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Settings Count |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Name Length | Name (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* ~ Name (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Value Length | Value (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* ~ Value (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Name Length | Name (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* ~ Name (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Value Length | Value (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* ~ Value (Variable Length) ~
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* ...........................
|
||||
*/
|
||||
public class SettingsAttribute implements Attribute
|
||||
{
|
||||
private final LinkedList<Pair<String, String>> mSettings = new LinkedList<Pair<String, String>>();
|
||||
|
||||
/**
|
||||
* Add a setting to this attribute.
|
||||
* @param name name of the setting
|
||||
* @param value value of the setting
|
||||
*/
|
||||
public void addSetting(String name, String value)
|
||||
{
|
||||
mSettings.add(new Pair<String, String>(name, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoding()
|
||||
{
|
||||
BufferedByteWriter writer = new BufferedByteWriter();
|
||||
writer.put32(mSettings.size());
|
||||
for (Pair<String, String> pair : mSettings)
|
||||
{
|
||||
writer.putLen16(pair.first.getBytes());
|
||||
writer.putLen16(pair.second.getBytes());
|
||||
}
|
||||
return writer.toByteArray();
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.attributes;
|
||||
|
||||
import org.strongswan.android.utils.BufferedByteWriter;
|
||||
|
||||
/**
|
||||
* PA-TNC String Version attribute (see section 4.2.4 of RFC 5792)
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Version Len | Product Version Number (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Build Num Len | Internal Build Number (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Config. Len | Configuration Version Number (Variable Length)|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
public class StringVersionAttribute implements Attribute
|
||||
{
|
||||
private String mVersionNumber;
|
||||
private String mBuildNumber;
|
||||
|
||||
/**
|
||||
* Set the product version number
|
||||
* @param version version number
|
||||
*/
|
||||
public void setProductVersionNumber(String version)
|
||||
{
|
||||
this.mVersionNumber = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the internal build number
|
||||
* @param build build number
|
||||
*/
|
||||
public void setInternalBuildNumber(String build)
|
||||
{
|
||||
this.mBuildNumber = build;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoding()
|
||||
{
|
||||
BufferedByteWriter writer = new BufferedByteWriter();
|
||||
writer.putLen8(mVersionNumber.getBytes());
|
||||
writer.putLen8(mBuildNumber.getBytes());
|
||||
/* we don't provide a configuration number */
|
||||
writer.put((byte)0);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.collectors;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
|
||||
/**
|
||||
* Interface for measurement collectors
|
||||
*/
|
||||
public interface Collector
|
||||
{
|
||||
/**
|
||||
* This method shall return the result of a measurement, if available
|
||||
* @return attribute or null
|
||||
*/
|
||||
public abstract Attribute getMeasurement();
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.collectors;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.DeviceIdAttribute;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
||||
public class DeviceIdCollector implements Collector
|
||||
{
|
||||
private final ContentResolver mContentResolver;
|
||||
|
||||
public DeviceIdCollector(Context context)
|
||||
{
|
||||
mContentResolver = context.getContentResolver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute getMeasurement()
|
||||
{
|
||||
String id = android.provider.Settings.Secure.getString(mContentResolver, "android_id");
|
||||
if (id != null)
|
||||
{
|
||||
DeviceIdAttribute attribute = new DeviceIdAttribute();
|
||||
attribute.setDeviceId(id);
|
||||
return attribute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.collectors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.InstalledPackagesAttribute;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
public class InstalledPackagesCollector implements Collector
|
||||
{
|
||||
private final PackageManager mPackageManager;
|
||||
|
||||
public InstalledPackagesCollector(Context context)
|
||||
{
|
||||
mPackageManager = context.getPackageManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute getMeasurement()
|
||||
{
|
||||
InstalledPackagesAttribute attribute = new InstalledPackagesAttribute();
|
||||
List<PackageInfo> packages = mPackageManager.getInstalledPackages(0);
|
||||
for (PackageInfo info : packages)
|
||||
{
|
||||
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
|
||||
info.packageName == null || info.versionName == null)
|
||||
{ /* ignore packages installed in the system image */
|
||||
continue;
|
||||
}
|
||||
attribute.addPackage(info.packageName, info.versionName);
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.collectors;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.PortFilterAttribute;
|
||||
|
||||
public class PortFilterCollector implements Collector
|
||||
{
|
||||
private static Pattern LISTEN = Pattern.compile("\\bLISTEN\\b");
|
||||
private static Pattern PROTOCOL = Pattern.compile("\\b(tcp|udp)6?\\b");
|
||||
private static Pattern PORT = Pattern.compile("[:]{1,3}(\\d{1,5})\\b(?!\\.)");
|
||||
|
||||
@Override
|
||||
public Attribute getMeasurement()
|
||||
{
|
||||
PortFilterAttribute attribute = null;
|
||||
try
|
||||
{
|
||||
Process netstat = Runtime.getRuntime().exec("netstat -n");
|
||||
try
|
||||
{
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(netstat.getInputStream()));
|
||||
String line;
|
||||
attribute = new PortFilterAttribute();
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (!LISTEN.matcher(line).find())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Matcher protocolMatcher = PROTOCOL.matcher(line);
|
||||
Matcher portMatcher = PORT.matcher(line);
|
||||
if (protocolMatcher.find() && portMatcher.find())
|
||||
{
|
||||
Protocol protocol = Protocol.fromName(protocolMatcher.group());
|
||||
if (protocol == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int port = Integer.parseInt(portMatcher.group(1));
|
||||
attribute.addPort(protocol, (short)port);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
netstat.destroy();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.collectors;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.ProductInformationAttribute;
|
||||
|
||||
public class ProductInformationCollector implements Collector
|
||||
{
|
||||
@Override
|
||||
public Attribute getMeasurement()
|
||||
{ /* this is currently hardcoded in the attribute */
|
||||
return new ProductInformationAttribute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.collectors;
|
||||
|
||||
public enum Protocol
|
||||
{
|
||||
TCP((byte)6, "tcp", "tcp6"),
|
||||
UDP((byte)17, "udp", "udp6");
|
||||
|
||||
private final byte mValue;
|
||||
private String[] mNames;
|
||||
|
||||
private Protocol(byte value, String... names)
|
||||
{
|
||||
mValue = value;
|
||||
mNames = names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numeric value of the protocol.
|
||||
* @return numeric value
|
||||
*/
|
||||
public byte getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the protocol from the given protocol name, if found.
|
||||
* @param name protocol name (e.g. "udp" or "tcp")
|
||||
* @return enum entry or null
|
||||
*/
|
||||
public static Protocol fromName(String name)
|
||||
{
|
||||
for (Protocol protocol : Protocol.values())
|
||||
{
|
||||
for (String keyword : protocol.mNames)
|
||||
{
|
||||
if (keyword.equalsIgnoreCase(name))
|
||||
{
|
||||
return protocol;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.collectors;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.SettingsAttribute;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
||||
public class SettingsCollector implements Collector
|
||||
{
|
||||
private final ContentResolver mContentResolver;
|
||||
private final String[] mSettings;
|
||||
|
||||
public SettingsCollector(Context context, String[] args)
|
||||
{
|
||||
mContentResolver = context.getContentResolver();
|
||||
mSettings = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute getMeasurement()
|
||||
{
|
||||
if (mSettings == null || mSettings.length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
SettingsAttribute attribute = new SettingsAttribute();
|
||||
for (String name : mSettings)
|
||||
{
|
||||
String value = android.provider.Settings.Secure.getString(mContentResolver, name.toLowerCase(Locale.US));
|
||||
if (value == null)
|
||||
{
|
||||
value = android.provider.Settings.System.getString(mContentResolver, name.toLowerCase(Locale.US));
|
||||
}
|
||||
if (value != null)
|
||||
{
|
||||
attribute.addSetting(name, value);
|
||||
}
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Christoph Buehler
|
||||
* Copyright (C) 2012 Patrick Loetscher
|
||||
* 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.collectors;
|
||||
|
||||
import org.strongswan.android.logic.imc.attributes.Attribute;
|
||||
import org.strongswan.android.logic.imc.attributes.StringVersionAttribute;
|
||||
|
||||
public class StringVersionCollector implements Collector
|
||||
{
|
||||
@Override
|
||||
public Attribute getMeasurement()
|
||||
{
|
||||
StringVersionAttribute attribute = new StringVersionAttribute();
|
||||
attribute.setProductVersionNumber(android.os.Build.VERSION.RELEASE);
|
||||
attribute.setInternalBuildNumber(android.os.Build.DISPLAY);
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.logic.VpnStateService;
|
||||
import org.strongswan.android.logic.VpnStateService.VpnStateListener;
|
||||
import org.strongswan.android.logic.imc.ImcState;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class ImcStateFragment extends Fragment implements VpnStateListener
|
||||
{
|
||||
private TextView mStateView;
|
||||
private TextView mAction;
|
||||
private LinearLayout mButton;
|
||||
private VpnStateService mService;
|
||||
private final ServiceConnection mServiceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name)
|
||||
{
|
||||
mService = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service)
|
||||
{
|
||||
mService = ((VpnStateService.LocalBinder)service).getService();
|
||||
mService.registerListener(ImcStateFragment.this);
|
||||
updateView();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
/* bind to the service only seems to work from the ApplicationContext */
|
||||
Context context = getActivity().getApplicationContext();
|
||||
context.bindService(new Intent(context, VpnStateService.class),
|
||||
mServiceConnection, Service.BIND_AUTO_CREATE);
|
||||
/* hide it initially */
|
||||
getFragmentManager().beginTransaction().hide(this).commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState)
|
||||
{
|
||||
View view = inflater.inflate(R.layout.imc_state_fragment, null);
|
||||
|
||||
mButton = (LinearLayout)view.findViewById(R.id.imc_state_button);
|
||||
mButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent;
|
||||
if (mService != null && !mService.getRemediationInstructions().isEmpty())
|
||||
{
|
||||
intent = new Intent(getActivity(), RemediationInstructionsActivity.class);
|
||||
intent.putParcelableArrayListExtra(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS,
|
||||
new ArrayList<RemediationInstruction>(mService.getRemediationInstructions()));
|
||||
}
|
||||
else
|
||||
{
|
||||
intent = new Intent(getActivity(), LogActivity.class);
|
||||
}
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
final GestureDetector gestures = new GestureDetector(getActivity(), new GestureDetector.SimpleOnGestureListener() {
|
||||
/* a better value would be getScaledTouchExplorationTapSlop() but that is hidden */
|
||||
private final int mMinDistance = ViewConfiguration.get(getActivity()).getScaledTouchSlop() * 4;
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
|
||||
{
|
||||
if (Math.abs(e1.getX() - e2.getX()) >= mMinDistance)
|
||||
{ /* only if the user swiped a minimum horizontal distance */
|
||||
if (mService != null)
|
||||
{
|
||||
mService.setImcState(ImcState.UNKNOWN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
mButton.setOnTouchListener(new OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
return gestures.onTouchEvent(event);
|
||||
}
|
||||
});
|
||||
|
||||
mStateView = (TextView)view.findViewById(R.id.imc_state);
|
||||
mAction = (TextView)view.findViewById(R.id.action);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
if (mService != null)
|
||||
{
|
||||
mService.unregisterListener(this);
|
||||
getActivity().getApplicationContext().unbindService(mServiceConnection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged()
|
||||
{
|
||||
updateView();
|
||||
}
|
||||
|
||||
public void updateView()
|
||||
{
|
||||
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||
|
||||
switch (mService.getImcState())
|
||||
{
|
||||
case UNKNOWN:
|
||||
case ALLOW:
|
||||
ft.hide(this);
|
||||
break;
|
||||
case ISOLATE:
|
||||
mStateView.setText(R.string.imc_state_isolate);
|
||||
mStateView.setTextColor(getResources().getColor(R.color.warning_text));
|
||||
ft.show(this);
|
||||
break;
|
||||
case BLOCK:
|
||||
mStateView.setText(R.string.imc_state_block);
|
||||
mStateView.setTextColor(getResources().getColor(R.color.error_text));
|
||||
ft.show(this);
|
||||
break;
|
||||
}
|
||||
ft.commit();
|
||||
|
||||
mAction.setText(mService.getRemediationInstructions().isEmpty() ? R.string.show_log
|
||||
: R.string.show_remediation_instructions);
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,8 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
|
||||
public static final String CONTACT_EMAIL = "[email protected]";
|
||||
public static final String START_PROFILE = "org.strongswan.android.action.START_PROFILE";
|
||||
public static final String EXTRA_VPN_PROFILE_ID = "org.strongswan.android.VPN_PROFILE_ID";
|
||||
/** Use "bring your own device" (BYOD) features */
|
||||
public static final boolean USE_BYOD = true;
|
||||
private static final int PREPARE_VPN_SERVICE = 0;
|
||||
private static final String PROFILE_NAME = "org.strongswan.android.MainActivity.PROFILE_NAME";
|
||||
private static final String PROFILE_REQUIRES_PASSWORD = "org.strongswan.android.MainActivity.REQUIRES_PASSWORD";
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
|
||||
import android.app.ListFragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class RemediationInstructionFragment extends ListFragment
|
||||
{
|
||||
public static final String ARG_REMEDIATION_INSTRUCTION = "instruction";
|
||||
private RemediationInstruction mInstruction = null;
|
||||
private TextView mTitle;
|
||||
private TextView mDescription;
|
||||
private TextView mHeader;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
return inflater.inflate(R.layout.remediation_instruction, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState)
|
||||
{
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null)
|
||||
{
|
||||
mInstruction = savedInstanceState.getParcelable(ARG_REMEDIATION_INSTRUCTION);
|
||||
}
|
||||
/* show dividers only between list items */
|
||||
getListView().setHeaderDividersEnabled(false);
|
||||
getListView().setFooterDividersEnabled(false);
|
||||
/* don't show loader while adapter is not set */
|
||||
setListShown(true);
|
||||
mTitle = (TextView)getView().findViewById(R.id.title);
|
||||
mDescription = (TextView)getView().findViewById(R.id.description);
|
||||
mHeader = (TextView)getView().findViewById(R.id.list_header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putParcelable(ARG_REMEDIATION_INSTRUCTION, mInstruction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart()
|
||||
{
|
||||
super.onStart();
|
||||
|
||||
Bundle args = getArguments();
|
||||
if (args != null)
|
||||
{
|
||||
mInstruction = args.getParcelable(ARG_REMEDIATION_INSTRUCTION);
|
||||
}
|
||||
updateView(mInstruction);
|
||||
}
|
||||
|
||||
public void updateView(RemediationInstruction instruction)
|
||||
{
|
||||
mInstruction = instruction;
|
||||
if (mInstruction != null)
|
||||
{
|
||||
mTitle.setText(mInstruction.getTitle());
|
||||
mDescription.setText(mInstruction.getDescription());
|
||||
if (mInstruction.getHeader() != null)
|
||||
{
|
||||
mHeader.setText(mInstruction.getHeader());
|
||||
setListAdapter(new ArrayAdapter<String>(getActivity(),
|
||||
android.R.layout.simple_list_item_1, mInstruction.getItems()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mHeader.setText("");
|
||||
setListAdapter(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mTitle.setText("");
|
||||
mDescription.setText("");
|
||||
mHeader.setText("");
|
||||
setListAdapter(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
import org.strongswan.android.ui.RemediationInstructionsFragment.OnRemediationInstructionSelectedListener;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
public class RemediationInstructionsActivity extends Activity implements OnRemediationInstructionSelectedListener
|
||||
{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.remediation_instructions);
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (savedInstanceState != null)
|
||||
{ /* only update if we're not restoring */
|
||||
return;
|
||||
}
|
||||
RemediationInstructionsFragment frag = (RemediationInstructionsFragment)getFragmentManager().findFragmentById(R.id.remediation_instructions_fragment);
|
||||
if (frag != null)
|
||||
{ /* two-pane layout, update fragment */
|
||||
Bundle extras = getIntent().getExtras();
|
||||
ArrayList<RemediationInstruction> list = extras.getParcelableArrayList(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS);
|
||||
frag.updateView(list);
|
||||
}
|
||||
else
|
||||
{ /* one-pane layout, create fragment */
|
||||
frag = new RemediationInstructionsFragment();
|
||||
frag.setArguments(getIntent().getExtras());
|
||||
getFragmentManager().beginTransaction().add(R.id.fragment_container, frag).commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case android.R.id.home:
|
||||
/* one-pane layout, pop possible fragment from stack, finish otherwise */
|
||||
if (!getFragmentManager().popBackStackImmediate())
|
||||
{
|
||||
finish();
|
||||
}
|
||||
getActionBar().setTitle(getTitle());
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemediationInstructionSelected(RemediationInstruction instruction)
|
||||
{
|
||||
RemediationInstructionFragment frag = (RemediationInstructionFragment)getFragmentManager().findFragmentById(R.id.remediation_instruction_fragment);
|
||||
|
||||
if (frag != null)
|
||||
{ /* two-pane layout, update directly */
|
||||
frag.updateView(instruction);
|
||||
}
|
||||
else
|
||||
{ /* one-pane layout, replace fragment */
|
||||
frag = new RemediationInstructionFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(RemediationInstructionFragment.ARG_REMEDIATION_INSTRUCTION, instruction);
|
||||
frag.setArguments(args);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(R.id.fragment_container, frag).addToBackStack(null).commit();
|
||||
getActionBar().setTitle(instruction.getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
import org.strongswan.android.ui.adapter.RemediationInstructionAdapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ListFragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class RemediationInstructionsFragment extends ListFragment
|
||||
{
|
||||
public static final String EXTRA_REMEDIATION_INSTRUCTIONS = "instructions";
|
||||
private static final String KEY_POSITION = "position";
|
||||
private ArrayList<RemediationInstruction> mInstructions = null;
|
||||
private OnRemediationInstructionSelectedListener mListener;
|
||||
private RemediationInstructionAdapter mAdapter;
|
||||
private int mCurrentPosition = -1;
|
||||
|
||||
/**
|
||||
* The activity containing this fragment should implement this interface
|
||||
*/
|
||||
public interface OnRemediationInstructionSelectedListener
|
||||
{
|
||||
public void onRemediationInstructionSelected(RemediationInstruction instruction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState)
|
||||
{
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null)
|
||||
{
|
||||
mInstructions = savedInstanceState.getParcelableArrayList(EXTRA_REMEDIATION_INSTRUCTIONS);
|
||||
mCurrentPosition = savedInstanceState.getInt(KEY_POSITION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putParcelableArrayList(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS, mInstructions);
|
||||
outState.putInt(KEY_POSITION, mCurrentPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity)
|
||||
{
|
||||
super.onAttach(activity);
|
||||
|
||||
if (activity instanceof OnRemediationInstructionSelectedListener)
|
||||
{
|
||||
mListener = (OnRemediationInstructionSelectedListener)activity;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart()
|
||||
{
|
||||
super.onStart();
|
||||
|
||||
boolean two_pane = getFragmentManager().findFragmentById(R.id.remediation_instruction_fragment) != null;
|
||||
if (two_pane)
|
||||
{ /* two-pane layout, make list items selectable */
|
||||
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||
}
|
||||
|
||||
Bundle args = getArguments();
|
||||
if (mInstructions == null && args != null)
|
||||
{
|
||||
mInstructions = args.getParcelableArrayList(EXTRA_REMEDIATION_INSTRUCTIONS);
|
||||
}
|
||||
updateView(mInstructions);
|
||||
|
||||
if (two_pane && mCurrentPosition == -1 && mInstructions.size() > 0)
|
||||
{ /* two-pane layout, select first instruction */
|
||||
mCurrentPosition = 0;
|
||||
mListener.onRemediationInstructionSelected(mInstructions.get(0));
|
||||
}
|
||||
getListView().setItemChecked(mCurrentPosition, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id)
|
||||
{
|
||||
mCurrentPosition = position;
|
||||
mListener.onRemediationInstructionSelected(mInstructions.get(position));
|
||||
getListView().setItemChecked(position, true);
|
||||
}
|
||||
|
||||
public void updateView(ArrayList<RemediationInstruction> instructions)
|
||||
{
|
||||
if (mAdapter == null)
|
||||
{
|
||||
mAdapter = new RemediationInstructionAdapter(getActivity());
|
||||
setListAdapter(mAdapter);
|
||||
}
|
||||
mInstructions = instructions;
|
||||
mAdapter.setData(mInstructions);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ import org.strongswan.android.logic.TrustedCertificateManager;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -36,6 +38,7 @@ import android.os.Bundle;
|
||||
import android.security.KeyChain;
|
||||
import android.security.KeyChainAliasCallback;
|
||||
import android.security.KeyChainException;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@@ -73,6 +76,7 @@ public class VpnProfileDetailActivity extends Activity
|
||||
private TwoLineListItem mSelectUserCert;
|
||||
private CheckBox mCheckAuto;
|
||||
private TwoLineListItem mSelectCert;
|
||||
private TwoLineListItem mTncNotice;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
@@ -90,6 +94,7 @@ public class VpnProfileDetailActivity extends Activity
|
||||
mName = (EditText)findViewById(R.id.name);
|
||||
mGateway = (EditText)findViewById(R.id.gateway);
|
||||
mSelectVpnType = (Spinner)findViewById(R.id.vpn_type);
|
||||
mTncNotice = (TwoLineListItem)findViewById(R.id.tnc_notice);
|
||||
|
||||
mUsernamePassword = (ViewGroup)findViewById(R.id.username_password_group);
|
||||
mUsername = (EditText)findViewById(R.id.username);
|
||||
@@ -117,6 +122,16 @@ public class VpnProfileDetailActivity extends Activity
|
||||
}
|
||||
});
|
||||
|
||||
mTncNotice.getText1().setText(R.string.tnc_notice_title);
|
||||
mTncNotice.getText2().setText(R.string.tnc_notice_subtitle);
|
||||
mTncNotice.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
new TncNoticeDialog().show(VpnProfileDetailActivity.this.getFragmentManager(), "TncNotice");
|
||||
}
|
||||
});
|
||||
|
||||
mSelectUserCert.setOnClickListener(new SelectUserCertOnClickListener());
|
||||
|
||||
mCheckAuto.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
@@ -225,6 +240,7 @@ public class VpnProfileDetailActivity extends Activity
|
||||
{
|
||||
mUsernamePassword.setVisibility(mVpnType.getRequiresUsernamePassword() ? View.VISIBLE : View.GONE);
|
||||
mUserCertificate.setVisibility(mVpnType.getRequiresCertificate() ? View.VISIBLE : View.GONE);
|
||||
mTncNotice.setVisibility(mVpnType.getEnableBYOD() ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (mVpnType.getRequiresCertificate())
|
||||
{
|
||||
@@ -536,4 +552,25 @@ public class VpnProfileDetailActivity extends Activity
|
||||
updateCredentialView();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog with notification message if EAP-TNC is used.
|
||||
*/
|
||||
public static class TncNoticeDialog extends DialogFragment
|
||||
{
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState)
|
||||
{
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.tnc_notice_title)
|
||||
.setMessage(Html.fromHtml(getString(R.string.tnc_notice_details)))
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
}).create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -17,12 +17,17 @@
|
||||
|
||||
package org.strongswan.android.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.data.VpnProfile;
|
||||
import org.strongswan.android.logic.VpnStateService;
|
||||
import org.strongswan.android.logic.VpnStateService.ErrorState;
|
||||
import org.strongswan.android.logic.VpnStateService.State;
|
||||
import org.strongswan.android.logic.VpnStateService.VpnStateListener;
|
||||
import org.strongswan.android.logic.imc.ImcState;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Fragment;
|
||||
@@ -45,6 +50,7 @@ import android.widget.TextView;
|
||||
public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
{
|
||||
private static final String KEY_ERROR = "error";
|
||||
private static final String KEY_IMC_STATE = "imc_state";
|
||||
private static final String KEY_NAME = "name";
|
||||
|
||||
private TextView mProfileNameView;
|
||||
@@ -56,6 +62,7 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
private State mState;
|
||||
private AlertDialog mErrorDialog;
|
||||
private ErrorState mError;
|
||||
private ImcState mImcState;
|
||||
private String mErrorProfileName;
|
||||
private VpnStateService mService;
|
||||
private final ServiceConnection mServiceConnection = new ServiceConnection() {
|
||||
@@ -85,9 +92,11 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
mServiceConnection, Service.BIND_AUTO_CREATE);
|
||||
|
||||
mError = ErrorState.NO_ERROR;
|
||||
mImcState = ImcState.UNKNOWN;
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_ERROR))
|
||||
{
|
||||
mError = (ErrorState)savedInstanceState.getSerializable(KEY_ERROR);
|
||||
mImcState = (ImcState)savedInstanceState.getSerializable(KEY_IMC_STATE);
|
||||
mErrorProfileName = savedInstanceState.getString(KEY_NAME);
|
||||
}
|
||||
}
|
||||
@@ -98,6 +107,7 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putSerializable(KEY_ERROR, mError);
|
||||
outState.putSerializable(KEY_IMC_STATE, mImcState);
|
||||
outState.putString(KEY_NAME, mErrorProfileName);
|
||||
}
|
||||
|
||||
@@ -167,6 +177,7 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
{
|
||||
State state = mService.getState();
|
||||
ErrorState error = ErrorState.NO_ERROR;
|
||||
ImcState imcState = ImcState.UNKNOWN;
|
||||
String name = "", gateway = "";
|
||||
|
||||
if (state != State.DISABLED)
|
||||
@@ -178,9 +189,10 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
gateway = profile.getGateway();
|
||||
}
|
||||
error = mService.getErrorState();
|
||||
imcState = mService.getImcState();
|
||||
}
|
||||
|
||||
if (reportError(name, state, error))
|
||||
if (reportError(name, state, error, imcState))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -223,16 +235,18 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
}
|
||||
}
|
||||
|
||||
private boolean reportError(String name, State state, ErrorState error)
|
||||
private boolean reportError(String name, State state, ErrorState error, ImcState imcState)
|
||||
{
|
||||
if (mError != ErrorState.NO_ERROR)
|
||||
{ /* we are currently reporting an error which was not yet dismissed */
|
||||
error = mError;
|
||||
imcState = mImcState;
|
||||
name = mErrorProfileName;
|
||||
}
|
||||
else if (error != ErrorState.NO_ERROR && (state == State.CONNECTING || state == State.CONNECTED))
|
||||
{ /* while initiating we report errors */
|
||||
mError = error;
|
||||
mImcState = imcState;
|
||||
mErrorProfileName = name;
|
||||
}
|
||||
else
|
||||
@@ -257,7 +271,14 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
switch (error)
|
||||
{
|
||||
case AUTH_FAILED:
|
||||
showErrorDialog(R.string.error_auth_failed);
|
||||
if (imcState == ImcState.BLOCK)
|
||||
{
|
||||
showErrorDialog(R.string.error_assessment_failed);
|
||||
}
|
||||
else
|
||||
{
|
||||
showErrorDialog(R.string.error_auth_failed);
|
||||
}
|
||||
break;
|
||||
case PEER_AUTH_FAILED:
|
||||
showErrorDialog(R.string.error_peer_auth_failed);
|
||||
@@ -305,6 +326,13 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
}
|
||||
}
|
||||
|
||||
private void clearError()
|
||||
{
|
||||
mError = ErrorState.NO_ERROR;
|
||||
mImcState = ImcState.UNKNOWN;
|
||||
updateView();
|
||||
}
|
||||
|
||||
private void showConnectDialog(String profile, String gateway)
|
||||
{
|
||||
mProgressDialog = new ProgressDialog(getActivity());
|
||||
@@ -338,32 +366,46 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
|
||||
|
||||
private void showErrorDialog(int textid)
|
||||
{
|
||||
final List<RemediationInstruction> instructions = mService.getRemediationInstructions();
|
||||
final boolean show_instructions = mImcState == ImcState.BLOCK && !instructions.isEmpty();
|
||||
int text = show_instructions ? R.string.show_remediation_instructions : R.string.show_log;
|
||||
|
||||
mErrorDialog = new AlertDialog.Builder(getActivity())
|
||||
.setMessage(getString(R.string.error_introduction) + " " + getString(textid))
|
||||
.setCancelable(false)
|
||||
.setNeutralButton(R.string.show_log, new DialogInterface.OnClickListener() {
|
||||
.setNeutralButton(text, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
clearError();
|
||||
dialog.dismiss();
|
||||
Intent logIntent = new Intent(getActivity(), LogActivity.class);
|
||||
startActivity(logIntent);
|
||||
Intent intent;
|
||||
if (show_instructions)
|
||||
{
|
||||
intent = new Intent(getActivity(), RemediationInstructionsActivity.class);
|
||||
intent.putParcelableArrayListExtra(RemediationInstructionsFragment.EXTRA_REMEDIATION_INSTRUCTIONS,
|
||||
new ArrayList<RemediationInstruction>(instructions));
|
||||
}
|
||||
else
|
||||
{
|
||||
intent = new Intent(getActivity(), LogActivity.class);
|
||||
}
|
||||
startActivity(intent);
|
||||
}
|
||||
})
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
clearError();
|
||||
dialog.dismiss();
|
||||
}
|
||||
}).create();
|
||||
mErrorDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
{ /* clear the error */
|
||||
mError = ErrorState.NO_ERROR;
|
||||
{
|
||||
mErrorDialog = null;
|
||||
updateView();
|
||||
}
|
||||
});
|
||||
mErrorDialog.show();
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.ui.adapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.strongswan.android.R;
|
||||
import org.strongswan.android.logic.imc.RemediationInstruction;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class RemediationInstructionAdapter extends ArrayAdapter<RemediationInstruction>
|
||||
{
|
||||
public RemediationInstructionAdapter(Context context)
|
||||
{
|
||||
super(context, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new data for this adapter.
|
||||
*
|
||||
* @param data the new data (null to clear)
|
||||
*/
|
||||
public void setData(List<RemediationInstruction> data)
|
||||
{
|
||||
clear();
|
||||
if (data != null)
|
||||
{
|
||||
addAll(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
View view;
|
||||
if (convertView != null)
|
||||
{
|
||||
view = convertView;
|
||||
}
|
||||
else
|
||||
{
|
||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||
view = inflater.inflate(R.layout.remediation_instruction_item, parent, false);
|
||||
}
|
||||
RemediationInstruction item = getItem(position);
|
||||
TextView text = (TextView)view.findViewById(android.R.id.text1);
|
||||
text.setText(item.getTitle());
|
||||
text = (TextView)view.findViewById(android.R.id.text2);
|
||||
text.setText(item.getDescription());
|
||||
return view;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Very similar to ByteBuffer (although with a stripped interface) but it
|
||||
* automatically resizes the underlying buffer.
|
||||
*/
|
||||
public class BufferedByteWriter
|
||||
{
|
||||
/**
|
||||
* The underlying byte buffer
|
||||
*/
|
||||
private byte[] mBuffer;
|
||||
|
||||
/**
|
||||
* ByteBuffer used as wrapper around the buffer to easily convert values
|
||||
*/
|
||||
private ByteBuffer mWriter;
|
||||
|
||||
/**
|
||||
* Create a writer with a default initial capacity
|
||||
*/
|
||||
public BufferedByteWriter()
|
||||
{
|
||||
this(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a writer with the given initial capacity (helps avoid expensive
|
||||
* resizing if known).
|
||||
* @param capacity initial capacity
|
||||
*/
|
||||
public BufferedByteWriter(int capacity)
|
||||
{
|
||||
capacity = capacity > 4 ? capacity : 32;
|
||||
mBuffer = new byte[capacity];
|
||||
mWriter = ByteBuffer.wrap(mBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that there is enough space available to write the requested
|
||||
* number of bytes. If necessary the internal buffer is resized.
|
||||
* @param required required number of bytes
|
||||
*/
|
||||
private void ensureCapacity(int required)
|
||||
{
|
||||
if (mWriter.remaining() >= required)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] buffer = new byte[(mBuffer.length + required) * 2];
|
||||
System.arraycopy(mBuffer, 0, buffer, 0, mWriter.position());
|
||||
mBuffer = buffer;
|
||||
ByteBuffer writer = ByteBuffer.wrap(buffer);
|
||||
writer.position(mWriter.position());
|
||||
mWriter = writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given byte array to the buffer
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter put(byte[] value)
|
||||
{
|
||||
ensureCapacity(value.length);
|
||||
mWriter.put(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given byte to the buffer
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter put(byte value)
|
||||
{
|
||||
ensureCapacity(1);
|
||||
mWriter.put(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the 8-bit length of the given data followed by the data itself
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter putLen8(byte[] value)
|
||||
{
|
||||
ensureCapacity(1 + value.length);
|
||||
mWriter.put((byte)value.length);
|
||||
mWriter.put(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the 16-bit length of the given data followed by the data itself
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter putLen16(byte[] value)
|
||||
{
|
||||
ensureCapacity(2 + value.length);
|
||||
mWriter.putShort((short)value.length);
|
||||
mWriter.put(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given short value (16-bit) in big-endian order to the buffer
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter put16(short value)
|
||||
{
|
||||
ensureCapacity(2);
|
||||
mWriter.putShort(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write 24-bit of the given value in big-endian order to the buffer
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter put24(int value)
|
||||
{
|
||||
ensureCapacity(3);
|
||||
mWriter.put((byte)(value >> 16));
|
||||
mWriter.putShort((short)value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given int value (32-bit) in big-endian order to the buffer
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter put32(int value)
|
||||
{
|
||||
ensureCapacity(4);
|
||||
mWriter.putInt(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given long value (64-bit) in big-endian order to the buffer
|
||||
* @param value
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedByteWriter put64(long value)
|
||||
{
|
||||
ensureCapacity(8);
|
||||
mWriter.putLong(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the internal buffer to a new byte array.
|
||||
* @return byte array
|
||||
*/
|
||||
public byte[] toByteArray()
|
||||
{
|
||||
int length = mWriter.position();
|
||||
byte[] bytes = new byte[length];
|
||||
System.arraycopy(mBuffer, 0, bytes, 0, length);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -186,8 +186,11 @@ endif
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, eap-peap)
|
||||
|
||||
# adding libtls if any of the three plugins above is enabled
|
||||
ifneq ($(or $(call plugin_enabled, eap-tls), $(call plugin_enabled, eap-ttls), $(call plugin_enabled, eap-peap)),)
|
||||
LOCAL_SRC_FILES += $(call add_plugin, eap-tnc)
|
||||
|
||||
# adding libtls if any of the four plugins above is enabled
|
||||
ifneq ($(or $(call plugin_enabled, eap-tls), $(call plugin_enabled, eap-ttls), \
|
||||
$(call plugin_enabled, eap-peap), $(call plugin_enabled, eap-tnc)),)
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libtls/
|
||||
LOCAL_SRC_FILES += $(addprefix ../libtls/, \
|
||||
tls_protection.c tls_compression.c tls_fragmentation.c tls_alert.c \
|
||||
@@ -207,6 +210,32 @@ ifneq ($(call plugin_enabled, stroke),)
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../stroke/
|
||||
endif
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, tnc-imc)
|
||||
ifneq ($(call plugin_enabled, tnc-imc),)
|
||||
LOCAL_SHARED_LIBRARIES += libdl
|
||||
endif
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, tnc-tnccs)
|
||||
|
||||
LOCAL_SRC_FILES += $(call add_plugin, tnccs-20)
|
||||
LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages state_machine)
|
||||
ifneq ($(call plugin_enabled, tnccs-20),)
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/plugins/tnccs_20/
|
||||
# for tls.h
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libtls/
|
||||
endif
|
||||
|
||||
ifneq ($(or $(call plugin_enabled, eap-tnc), $(call plugin_enabled, tnc-imc), \
|
||||
$(call plugin_enabled, tnc-tnccs), $(call plugin_enabled, tnccs-20)),)
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libtnccs/
|
||||
LOCAL_SHARED_LIBRARIES += libtnccs
|
||||
endif
|
||||
|
||||
ifneq ($(or $(call plugin_enabled, tnc-imc), $(call plugin_enabled, tnc-tnccs), \
|
||||
$(call plugin_enabled, tnccs-20)),)
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libtncif/
|
||||
LOCAL_SHARED_LIBRARIES += libtncif
|
||||
endif
|
||||
|
||||
# build libcharon --------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -782,7 +782,7 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
|
||||
enumerator = enumerator_create_token(message, " ", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
if (strneq(token, "S=", 2))
|
||||
if (strpfx(token, "S="))
|
||||
{
|
||||
chunk_t hex;
|
||||
token += 2;
|
||||
@@ -795,7 +795,7 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
|
||||
hex = chunk_create(token, AUTH_RESPONSE_LEN - 2);
|
||||
auth_string = chunk_from_hex(hex, NULL);
|
||||
}
|
||||
else if (strneq(token, "M=", 2))
|
||||
else if (strpfx(token, "M="))
|
||||
{
|
||||
token += 2;
|
||||
msg = strdup(token);
|
||||
@@ -864,16 +864,16 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
|
||||
enumerator = enumerator_create_token(message, " ", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
if (strneq(token, "E=", 2))
|
||||
if (strpfx(token, "E="))
|
||||
{
|
||||
token += 2;
|
||||
error = atoi(token);
|
||||
}
|
||||
else if (strneq(token, "R=", 2))
|
||||
else if (strpfx(token, "R="))
|
||||
{
|
||||
/* ignore retriable */
|
||||
}
|
||||
else if (strneq(token, "C=", 2))
|
||||
else if (strpfx(token, "C="))
|
||||
{
|
||||
chunk_t hex;
|
||||
token += 2;
|
||||
@@ -886,11 +886,11 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
|
||||
hex = chunk_create(token, 2 * CHALLENGE_LEN);
|
||||
challenge = chunk_from_hex(hex, NULL);
|
||||
}
|
||||
else if (strneq(token, "V=", 2))
|
||||
else if (strpfx(token, "V="))
|
||||
{
|
||||
/* ignore version */
|
||||
}
|
||||
else if (strneq(token, "M=", 2))
|
||||
else if (strpfx(token, "M="))
|
||||
{
|
||||
token += 2;
|
||||
msg = strdup(token);
|
||||
|
||||
@@ -355,7 +355,7 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strneq(str, "eap", strlen("eap")))
|
||||
else if (strpfx(str, "eap"))
|
||||
{ /* EAP authentication, use a NAI */
|
||||
class = AUTH_CLASS_EAP;
|
||||
if (*(str + strlen("eap")) == '-')
|
||||
|
||||
@@ -559,9 +559,9 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
|
||||
}
|
||||
|
||||
/* authentication metod (class, actually) */
|
||||
if (strneq(auth, "pubkey", strlen("pubkey")) ||
|
||||
strneq(auth, "rsa", strlen("rsa")) ||
|
||||
strneq(auth, "ecdsa", strlen("ecdsa")))
|
||||
if (strpfx(auth, "pubkey") ||
|
||||
strpfx(auth, "rsa") ||
|
||||
strpfx(auth, "ecdsa"))
|
||||
{
|
||||
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
|
||||
build_crl_policy(cfg, local, msg->add_conn.crl_policy);
|
||||
@@ -572,7 +572,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
|
||||
{
|
||||
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
|
||||
}
|
||||
else if (strneq(auth, "xauth", 5))
|
||||
else if (strpfx(auth, "xauth"))
|
||||
{
|
||||
char *pos;
|
||||
|
||||
@@ -588,7 +588,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
|
||||
identification_create_from_string(msg->add_conn.xauth_identity));
|
||||
}
|
||||
}
|
||||
else if (strneq(auth, "eap", 3))
|
||||
else if (strpfx(auth, "eap"))
|
||||
{
|
||||
eap_vendor_type_t *type;
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
|
||||
certificate_t *cert = NULL;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (strneq(filename, "%smartcard", strlen("%smartcard")))
|
||||
if (strpfx(filename, "%smartcard"))
|
||||
{
|
||||
smartcard_format_t format;
|
||||
char module[SC_PART_LEN], keyid[SC_PART_LEN];
|
||||
@@ -239,7 +239,7 @@ METHOD(stroke_cred_t, load_peer, certificate_t*,
|
||||
certificate_t *cert = NULL;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (strneq(filename, "%smartcard", strlen("%smartcard")))
|
||||
if (strpfx(filename, "%smartcard"))
|
||||
{
|
||||
smartcard_format_t format;
|
||||
char module[SC_PART_LEN], keyid[SC_PART_LEN];
|
||||
@@ -787,7 +787,7 @@ static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr,
|
||||
}
|
||||
|
||||
chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
|
||||
if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
|
||||
if (secret.len == 7 && strpfx(secret.ptr, "%prompt"))
|
||||
{
|
||||
free(secret.ptr);
|
||||
if (!prompt)
|
||||
@@ -880,7 +880,7 @@ static bool load_from_file(chunk_t line, int line_nr, FILE *prompt,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
|
||||
if (secret.len == 7 && strpfx(secret.ptr, "%prompt"))
|
||||
{
|
||||
callback_cred_t *cb;
|
||||
passphrase_cb_data_t pp_data = {
|
||||
@@ -1142,8 +1142,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (line.len > strlen("include ") &&
|
||||
strneq(line.ptr, "include ", strlen("include ")))
|
||||
if (line.len > strlen("include ") && strpfx(line.ptr, "include "))
|
||||
{
|
||||
char **expanded, *dir, pattern[PATH_MAX];
|
||||
u_char *pos;
|
||||
@@ -1211,7 +1210,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.len > 2 && strneq(": ", line.ptr, 2))
|
||||
if (line.len > 2 && strpfx(line.ptr, ": "))
|
||||
{
|
||||
/* no ids, skip the ':' */
|
||||
ids = chunk_empty;
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
/** this is the default number of ipsec devices */
|
||||
#define DEFAULT_IPSEC_DEV_COUNT 4
|
||||
/** TRUE if the given name matches an ipsec device */
|
||||
#define IS_IPSEC_DEV(name) (strneq((name), IPSEC_DEV_PREFIX, sizeof(IPSEC_DEV_PREFIX) - 1))
|
||||
#define IS_IPSEC_DEV(name) (strpfx((name), IPSEC_DEV_PREFIX))
|
||||
|
||||
/** the following stuff is from ipsec_tunnel.h */
|
||||
struct ipsectunnelconf
|
||||
@@ -2332,7 +2332,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
||||
|
||||
while (fgets(line, sizeof(line), file))
|
||||
{
|
||||
if (strneq(line, said, strlen(said)))
|
||||
if (strpfx(line, said))
|
||||
{
|
||||
/* fine we found the correct line, now find the idle time */
|
||||
u_int32_t idle_time;
|
||||
|
||||
@@ -126,7 +126,7 @@ static void remove_nameserver(private_resolve_handler_t *this,
|
||||
/* copy all, but matching line */
|
||||
while (fgets(line, sizeof(line), in))
|
||||
{
|
||||
if (strneq(line, matcher, strlen(matcher)))
|
||||
if (strpfx(line, matcher))
|
||||
{
|
||||
DBG1(DBG_IKE, "removing DNS server %H from %s",
|
||||
addr, this->file);
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# copy-n-paste from Makefile.am
|
||||
libimcv_la_SOURCES := \
|
||||
imcv.h imcv.c \
|
||||
imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
|
||||
imc/imc_msg.h imc/imc_msg.c \
|
||||
imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
|
||||
imv/imv_agent_if.h imv/imv_if.h \
|
||||
imv/imv_database.h imv/imv_database.c \
|
||||
imv/imv_msg.h imv/imv_msg.c \
|
||||
imv/imv_lang_string.h imv/imv_lang_string.c \
|
||||
imv/imv_reason_string.h imv/imv_reason_string.c \
|
||||
imv/imv_remediation_string.h imv/imv_remediation_string.c \
|
||||
imv/imv_session.h imv/imv_session.c \
|
||||
imv/imv_workitem.h imv/imv_workitem.c \
|
||||
imv/tables.sql imv/data.sql \
|
||||
ietf/ietf_attr.h ietf/ietf_attr.c \
|
||||
ietf/ietf_attr_assess_result.h ietf/ietf_attr_assess_result.c \
|
||||
ietf/ietf_attr_attr_request.h ietf/ietf_attr_attr_request.c \
|
||||
ietf/ietf_attr_fwd_enabled.h ietf/ietf_attr_fwd_enabled.c \
|
||||
ietf/ietf_attr_default_pwd_enabled.h ietf/ietf_attr_default_pwd_enabled.c \
|
||||
ietf/ietf_attr_installed_packages.h ietf/ietf_attr_installed_packages.c \
|
||||
ietf/ietf_attr_numeric_version.h ietf/ietf_attr_numeric_version.c \
|
||||
ietf/ietf_attr_op_status.h ietf/ietf_attr_op_status.c \
|
||||
ietf/ietf_attr_pa_tnc_error.h ietf/ietf_attr_pa_tnc_error.c \
|
||||
ietf/ietf_attr_port_filter.h ietf/ietf_attr_port_filter.c \
|
||||
ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
|
||||
ietf/ietf_attr_remediation_instr.h ietf/ietf_attr_remediation_instr.c \
|
||||
ietf/ietf_attr_string_version.h ietf/ietf_attr_string_version.c \
|
||||
ita/ita_attr.h ita/ita_attr.c \
|
||||
ita/ita_attr_command.h ita/ita_attr_command.c \
|
||||
ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
|
||||
ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
|
||||
ita/ita_attr_settings.h ita/ita_attr_settings.c \
|
||||
ita/ita_attr_angel.h ita/ita_attr_angel.c \
|
||||
ita/ita_attr_device_id.h ita/ita_attr_device_id.c \
|
||||
os_info/os_info.h os_info/os_info.c \
|
||||
pa_tnc/pa_tnc_attr.h \
|
||||
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
|
||||
pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c
|
||||
|
||||
LOCAL_SRC_FILES := $(filter %.c,$(libimcv_la_SOURCES))
|
||||
|
||||
# build libimcv ----------------------------------------------------------------
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(libvstr_PATH) \
|
||||
$(strongswan_PATH)/src/libtncif \
|
||||
$(strongswan_PATH)/src/libstrongswan
|
||||
|
||||
LOCAL_CFLAGS := $(strongswan_CFLAGS)
|
||||
|
||||
LOCAL_MODULE := libimcv
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libstrongswan libtncif
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -174,6 +174,7 @@ void libimcv_deinit(void)
|
||||
imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF);
|
||||
imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA);
|
||||
DESTROY_IF(imcv_pa_tnc_attributes);
|
||||
imcv_pa_tnc_attributes = NULL;
|
||||
DESTROY_IF(imcv_db);
|
||||
DBG1(DBG_LIB, "libimcv terminated");
|
||||
}
|
||||
|
||||
@@ -182,8 +182,8 @@ METHOD(os_info_t, get_setting, chunk_t,
|
||||
size_t i = 0;
|
||||
chunk_t value;
|
||||
|
||||
if (!strneq(name, "/etc/", 5) && !strneq(name, "/proc/", 6) &&
|
||||
!strneq(name, "/sys/", 5) && !strneq(name, "/var/", 5))
|
||||
if (!strpfx(name, "/etc/") && !strpfx(name, "/proc/") &&
|
||||
!strpfx(name, "/sys/") && !strpfx(name, "/var/"))
|
||||
{
|
||||
/**
|
||||
* In order to guarantee privacy, only settings from the
|
||||
|
||||
@@ -282,7 +282,10 @@ METHOD(imv_state_t, get_reason_string, bool,
|
||||
/* Instantiate a TNC Reason String object */
|
||||
DESTROY_IF(this->reason_string);
|
||||
this->reason_string = imv_reason_string_create(*reason_language);
|
||||
this->reason_string->add_reason(this->reason_string, reasons);
|
||||
if (this->rec != TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION)
|
||||
{
|
||||
this->reason_string->add_reason(this->reason_string, reasons);
|
||||
}
|
||||
*reason_string = this->reason_string->get_encoding(this->reason_string);
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# copy-n-paste from Makefile.am
|
||||
libpts_la_SOURCES := \
|
||||
libpts.h libpts.c \
|
||||
pts/pts.h pts/pts.c \
|
||||
pts/pts_error.h pts/pts_error.c \
|
||||
pts/pts_pcr.h pts/pts_pcr.c \
|
||||
pts/pts_proto_caps.h \
|
||||
pts/pts_req_func_comp_evid.h \
|
||||
pts/pts_simple_evid_final.h \
|
||||
pts/pts_creds.h pts/pts_creds.c \
|
||||
pts/pts_database.h pts/pts_database.c \
|
||||
pts/pts_dh_group.h pts/pts_dh_group.c \
|
||||
pts/pts_file_meas.h pts/pts_file_meas.c \
|
||||
pts/pts_file_meta.h pts/pts_file_meta.c \
|
||||
pts/pts_file_type.h pts/pts_file_type.c \
|
||||
pts/pts_meas_algo.h pts/pts_meas_algo.c \
|
||||
pts/components/pts_component.h \
|
||||
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
|
||||
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
|
||||
pts/components/pts_comp_func_name.h pts/components/pts_comp_func_name.c \
|
||||
pts/components/ita/ita_comp_func_name.h pts/components/ita/ita_comp_func_name.c \
|
||||
pts/components/ita/ita_comp_ima.h pts/components/ita/ita_comp_ima.c \
|
||||
pts/components/ita/ita_comp_tboot.h pts/components/ita/ita_comp_tboot.c \
|
||||
pts/components/ita/ita_comp_tgrub.h pts/components/ita/ita_comp_tgrub.c \
|
||||
pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \
|
||||
tcg/tcg_attr.h tcg/tcg_attr.c \
|
||||
tcg/tcg_pts_attr_proto_caps.h tcg/tcg_pts_attr_proto_caps.c \
|
||||
tcg/tcg_pts_attr_dh_nonce_params_req.h tcg/tcg_pts_attr_dh_nonce_params_req.c \
|
||||
tcg/tcg_pts_attr_dh_nonce_params_resp.h tcg/tcg_pts_attr_dh_nonce_params_resp.c \
|
||||
tcg/tcg_pts_attr_dh_nonce_finish.h tcg/tcg_pts_attr_dh_nonce_finish.c \
|
||||
tcg/tcg_pts_attr_meas_algo.h tcg/tcg_pts_attr_meas_algo.c \
|
||||
tcg/tcg_pts_attr_get_tpm_version_info.h tcg/tcg_pts_attr_get_tpm_version_info.c \
|
||||
tcg/tcg_pts_attr_tpm_version_info.h tcg/tcg_pts_attr_tpm_version_info.c \
|
||||
tcg/tcg_pts_attr_get_aik.h tcg/tcg_pts_attr_get_aik.c \
|
||||
tcg/tcg_pts_attr_aik.h tcg/tcg_pts_attr_aik.c \
|
||||
tcg/tcg_pts_attr_req_func_comp_evid.h tcg/tcg_pts_attr_req_func_comp_evid.c \
|
||||
tcg/tcg_pts_attr_gen_attest_evid.h tcg/tcg_pts_attr_gen_attest_evid.c \
|
||||
tcg/tcg_pts_attr_simple_comp_evid.h tcg/tcg_pts_attr_simple_comp_evid.c \
|
||||
tcg/tcg_pts_attr_simple_evid_final.h tcg/tcg_pts_attr_simple_evid_final.c \
|
||||
tcg/tcg_pts_attr_req_file_meas.h tcg/tcg_pts_attr_req_file_meas.c \
|
||||
tcg/tcg_pts_attr_file_meas.h tcg/tcg_pts_attr_file_meas.c \
|
||||
tcg/tcg_pts_attr_req_file_meta.h tcg/tcg_pts_attr_req_file_meta.c \
|
||||
tcg/tcg_pts_attr_unix_file_meta.h tcg/tcg_pts_attr_unix_file_meta.c
|
||||
|
||||
LOCAL_SRC_FILES := $(filter %.c,$(libpts_la_SOURCES))
|
||||
|
||||
# build libpts -----------------------------------------------------------------
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(libvstr_PATH) \
|
||||
$(strongswan_PATH)/src/libtncif \
|
||||
$(strongswan_PATH)/src/libimcv \
|
||||
$(strongswan_PATH)/src/libstrongswan
|
||||
|
||||
LOCAL_CFLAGS := $(strongswan_CFLAGS)
|
||||
|
||||
LOCAL_MODULE := libpts
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libstrongswan libimcv
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -302,20 +302,7 @@ pts_file_meas_t *pts_file_meas_create_from_path(u_int16_t request_id,
|
||||
return NULL;
|
||||
}
|
||||
measurement = chunk_create(hash, hasher->get_hash_size(hasher));
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_request_id = _get_request_id,
|
||||
.get_file_count = _get_file_count,
|
||||
.add = _add,
|
||||
.create_enumerator = _create_enumerator,
|
||||
.check = _check,
|
||||
.verify = _verify,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.request_id = request_id,
|
||||
.list = linked_list_create(),
|
||||
);
|
||||
this = (private_pts_file_meas_t*)pts_file_meas_create(request_id);
|
||||
|
||||
if (is_dir)
|
||||
{
|
||||
@@ -338,8 +325,7 @@ pts_file_meas_t *pts_file_meas_create_from_path(u_int16_t request_id,
|
||||
{
|
||||
if (!hash_file(hasher, abs_name, hash))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
filename = use_rel_name ? rel_name : abs_name;
|
||||
DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename);
|
||||
|
||||
@@ -112,7 +112,7 @@ METHOD(fetcher_t, fetch, status_t,
|
||||
status_t status = FAILED;
|
||||
chunk_t *result = userdata;
|
||||
|
||||
if (!strneq(url, "ldap", 4))
|
||||
if (!strpfx(url, "ldap"))
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -666,7 +666,7 @@ mysql_database_t *mysql_database_create(char *uri)
|
||||
conn_t *conn;
|
||||
private_mysql_database_t *this;
|
||||
|
||||
if (!strneq(uri, "mysql://", 8))
|
||||
if (!strpfx(uri, "mysql://"))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ sqlite_database_t *sqlite_database_create(char *uri)
|
||||
/**
|
||||
* parse sqlite:///path/to/file.db uri
|
||||
*/
|
||||
if (!strneq(uri, "sqlite://", 9))
|
||||
if (!strpfx(uri, "sqlite://"))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ static sshkey_public_key_t *parse_public_key(chunk_t blob)
|
||||
BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
|
||||
}
|
||||
else if (format.len > strlen(ECDSA_PREFIX) &&
|
||||
strneq(format.ptr, ECDSA_PREFIX, strlen(ECDSA_PREFIX)))
|
||||
strpfx(format.ptr, ECDSA_PREFIX))
|
||||
{
|
||||
chunk_t ec_blob, identifier, q, oid, encoded;
|
||||
sshkey_public_key_t *key;
|
||||
|
||||
@@ -81,9 +81,20 @@ static inline bool streq(const char *x, const char *y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro compares two strings for equality, length limited
|
||||
* Helper function that compares two strings for equality, length limited
|
||||
*/
|
||||
#define strneq(x,y,len) (strncmp(x, y, len) == 0)
|
||||
static inline bool strneq(const char *x, const char *y, size_t len)
|
||||
{
|
||||
return strncmp(x, y, len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that checks if a string starts with a given prefix
|
||||
*/
|
||||
static inline bool strpfx(const char *x, const char *prefix)
|
||||
{
|
||||
return strneq(x, prefix, strlen(prefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that compares two strings for equality ignoring case
|
||||
@@ -94,9 +105,12 @@ static inline bool strcaseeq(const char *x, const char *y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro compares two strings for equality ignoring case, length limited
|
||||
* Helper function that compares two strings for equality ignoring case, length limited
|
||||
*/
|
||||
#define strncaseeq(x,y,len) (strncasecmp(x, y, len) == 0)
|
||||
static inline bool strncaseeq(const char *x, const char *y, size_t len)
|
||||
{
|
||||
return strncasecmp(x, y, len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* NULL-safe strdup variant
|
||||
@@ -107,9 +121,12 @@ static inline char *strdupnull(const char *s)
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro compares two binary blobs for equality
|
||||
* Helper function that compares two binary blobs for equality
|
||||
*/
|
||||
#define memeq(x,y,len) (memcmp(x, y, len) == 0)
|
||||
static inline bool memeq(const void *x, const void *y, size_t len)
|
||||
{
|
||||
return memcmp(x, y, len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro gives back larger of two values.
|
||||
|
||||
@@ -100,6 +100,11 @@ static bool load_imcvs_from_config(char *filename, bool is_imc)
|
||||
void *addr;
|
||||
char *label;
|
||||
|
||||
if (!filename || !*filename)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
label = is_imc ? "IMC" : "IMV";
|
||||
|
||||
DBG1(DBG_TNC, "loading %ss from '%s'", label, filename);
|
||||
|
||||
Reference in New Issue
Block a user