android: Handle and store IETF remediation instructions
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#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>
|
||||
@@ -317,6 +318,24 @@ static void handle_ietf_attribute(pen_type_t attr_type, pa_tnc_attr_t *attr,
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -186,6 +186,37 @@ failed:
|
||||
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
|
||||
*/
|
||||
@@ -491,6 +522,7 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder)
|
||||
.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,
|
||||
|
||||
@@ -90,6 +90,14 @@ struct charonservice_t {
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -28,6 +28,7 @@ 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;
|
||||
@@ -389,6 +390,26 @@ public class CharonVpnService extends VpnService implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -16,11 +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;
|
||||
@@ -38,6 +41,7 @@ public class VpnStateService extends Service
|
||||
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
|
||||
{
|
||||
@@ -158,6 +162,16 @@ public class VpnStateService extends Service
|
||||
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
|
||||
@@ -277,6 +291,8 @@ 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
|
||||
@@ -287,6 +303,10 @@ public class VpnStateService extends Service
|
||||
@Override
|
||||
public Boolean call() throws Exception
|
||||
{
|
||||
if (state == ImcState.UNKNOWN)
|
||||
{
|
||||
VpnStateService.this.mRemediationInstructions.clear();
|
||||
}
|
||||
if (VpnStateService.this.mImcState != state)
|
||||
{
|
||||
VpnStateService.this.mImcState = state;
|
||||
@@ -296,4 +316,25 @@ public class VpnStateService extends Service
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user