From 03472aea1f28bd05d3c6feb0975a8a52a28c1044 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 20 Sep 2016 19:20:22 +0200 Subject: [PATCH 01/13] android: Update Gradle plugin and wrapper --- src/frontends/android/build.gradle | 2 +- .../android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontends/android/build.gradle b/src/frontends/android/build.gradle index 33b908c6d..3d5ba798f 100644 --- a/src/frontends/android/build.gradle +++ b/src/frontends/android/build.gradle @@ -3,7 +3,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.2' + classpath 'com.android.tools.build:gradle:2.2.3' } } diff --git a/src/frontends/android/gradle/wrapper/gradle-wrapper.properties b/src/frontends/android/gradle/wrapper/gradle-wrapper.properties index 33892269f..a6bd91c6c 100644 --- a/src/frontends/android/gradle/wrapper/gradle-wrapper.properties +++ b/src/frontends/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 13 11:22:32 CEST 2016 +#Tue Sep 20 17:56:35 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip From 4d47adb639de6385af2c9c5ee7f5e86bc79c0d24 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 18 Nov 2015 11:25:29 +0100 Subject: [PATCH 02/13] android: Optionally build the chapoly plugin --- src/libstrongswan/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index 0e8f7f3c8..ca030368b 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -64,6 +64,8 @@ LOCAL_SRC_FILES := $(libstrongswan_la_SOURCES) LOCAL_SRC_FILES += $(call add_plugin, aes) +LOCAL_SRC_FILES += $(call add_plugin, chapoly) + LOCAL_SRC_FILES += $(call add_plugin, curl) ifneq ($(call plugin_enabled, curl),) LOCAL_C_INCLUDES += $(libcurl_PATH) From 8c0b38e9df145378d8f65594d5ce3a44ed0c5e7b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 18 Nov 2015 11:31:03 +0100 Subject: [PATCH 03/13] android: Enable chapoly plugin in the app --- src/frontends/android/app/src/main/jni/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/android/app/src/main/jni/Android.mk b/src/frontends/android/app/src/main/jni/Android.mk index 849bdec31..75e3f3797 100644 --- a/src/frontends/android/app/src/main/jni/Android.mk +++ b/src/frontends/android/app/src/main/jni/Android.mk @@ -6,7 +6,7 @@ include $(CLEAR_VARS) strongswan_USE_BYOD := true strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \ - pkcs1 pkcs8 pem xcbc hmac socket-default \ + chapoly pkcs1 pkcs8 pem xcbc hmac socket-default \ eap-identity eap-mschapv2 eap-md5 eap-gtc eap-tls ifneq ($(strongswan_USE_BYOD),) From 5f0913fc1e745b254a03ead0018aea2557fd6daa Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 18 Nov 2015 11:31:14 +0100 Subject: [PATCH 04/13] android: Propose ChaCha20/Poly1305 in the ESP AEAD proposals --- .../src/main/jni/libandroidbridge/backend/android_service.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c index 2532402bb..87e934215 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c @@ -789,7 +789,8 @@ static job_requeue_t initiate(private_android_service_t *this) /* create ESP proposals with and without DH groups, let responder decide * if PFS is used */ child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, - "aes128gcm16-aes256gcm16-ecp256")); + "aes128gcm16-aes256gcm16-chacha20poly1305-" + "ecp256-modp3072")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, "aes128-sha256-ecp256-modp3072")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, @@ -799,7 +800,7 @@ static job_requeue_t initiate(private_android_service_t *this) "ecp256-ecp384-ecp521-" "modp2048-modp3072-modp4096-modp1024")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, - "aes128gcm16-aes256gcm16")); + "aes128gcm16-aes256gcm16-chacha20poly1305")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, "aes128-sha256")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, From b077a2a71a55b0c544bbddd3c627e2194132ba79 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 6 Dec 2016 11:50:25 +0100 Subject: [PATCH 05/13] android: Optionally build the curve25519 plugin --- src/libstrongswan/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index ca030368b..b594dabcc 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -72,6 +72,8 @@ LOCAL_C_INCLUDES += $(libcurl_PATH) LOCAL_SHARED_LIBRARIES += libcurl endif +LOCAL_SRC_FILES += $(call add_plugin, curve25519) + LOCAL_SRC_FILES += $(call add_plugin, des) LOCAL_SRC_FILES += $(call add_plugin, fips-prf) From fec47b61464ec73e71e3a5546b16f6c9f24ecb20 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 6 Dec 2016 11:51:19 +0100 Subject: [PATCH 06/13] android: Enable curve25519 plugin in the app --- src/frontends/android/app/src/main/jni/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/android/app/src/main/jni/Android.mk b/src/frontends/android/app/src/main/jni/Android.mk index 75e3f3797..51a61b883 100644 --- a/src/frontends/android/app/src/main/jni/Android.mk +++ b/src/frontends/android/app/src/main/jni/Android.mk @@ -6,7 +6,7 @@ include $(CLEAR_VARS) strongswan_USE_BYOD := true strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \ - chapoly pkcs1 pkcs8 pem xcbc hmac socket-default \ + chapoly curve25519 pkcs1 pkcs8 pem xcbc hmac socket-default \ eap-identity eap-mschapv2 eap-md5 eap-gtc eap-tls ifneq ($(strongswan_USE_BYOD),) From cefbf2bf9b880bb9a106f1450c6b6f777200c6fe Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 6 Dec 2016 11:51:33 +0100 Subject: [PATCH 07/13] android: Propose curve25519 in the ESP proposals --- .../src/main/jni/libandroidbridge/backend/android_service.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c index 87e934215..e5ecfdad7 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c @@ -790,14 +790,14 @@ static job_requeue_t initiate(private_android_service_t *this) * if PFS is used */ child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, "aes128gcm16-aes256gcm16-chacha20poly1305-" - "ecp256-modp3072")); + "curve25519-ecp256-modp3072")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, - "aes128-sha256-ecp256-modp3072")); + "aes128-sha256-curve25519-ecp256-modp3072")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, "aes256-sha384-ecp521-modp8192")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, "aes128-aes192-aes256-sha1-sha256-sha384-sha512-" - "ecp256-ecp384-ecp521-" + "curve25519-ecp256-ecp384-ecp521-" "modp2048-modp3072-modp4096-modp1024")); child_cfg->add_proposal(child_cfg, proposal_create_from_string(PROTO_ESP, "aes128gcm16-aes256gcm16-chacha20poly1305")); From ef2ad9db1c9b3f34cf53c4e30fa0f7d1523f787e Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 2 Nov 2016 16:33:29 +0100 Subject: [PATCH 08/13] android: Report an error for invalid integer values Previously we'd just ignore the invalid values without notifying the user. --- .../android/ui/VpnProfileDetailActivity.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java index dbbfaefb1..30fb101be 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java @@ -496,14 +496,12 @@ public class VpnProfileDetailActivity extends AppCompatActivity showCertificateAlert(); valid = false; } - Integer mtu = getInteger(mMTU); - if (mtu != null && (mtu < MTU_MIN || mtu > MTU_MAX)) + if (!validateInteger(mMTU, MTU_MIN, MTU_MAX)) { mMTUWrap.setError(String.format(getString(R.string.alert_text_out_of_range), MTU_MIN, MTU_MAX)); valid = false; } - Integer port = getInteger(mPort); - if (port != null && (port < 1 || port > 65535)) + if (!validateInteger(mPort, 1, 65535)) { mPortWrap.setError(String.format(getString(R.string.alert_text_out_of_range), 1, 65535)); valid = false; @@ -633,6 +631,31 @@ public class VpnProfileDetailActivity extends AppCompatActivity } } + /** + * Check that the value in the given text box is a valid integer in the given range + * + * @param view text box (numeric entry assumed) + * @param min minimum value (inclusive) + * @param max maximum value (inclusive) + */ + private boolean validateInteger(EditText view, Integer min, Integer max) + { + String value = view.getText().toString().trim(); + try + { + if (value.isEmpty()) + { + return true; + } + Integer val = Integer.valueOf(value); + return min <= val && val <= max; + } + catch (NumberFormatException e) + { + return false; + } + } + private class SelectUserCertOnClickListener implements OnClickListener, KeyChainAliasCallback { @Override From d6d12bab14641a11db04de9c08325586100b9c60 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 2 Nov 2016 16:35:50 +0100 Subject: [PATCH 09/13] android: Unregister listener in case of error alerts This avoids triggering additional errors via e.g. ike_updown() that might cause the error message displayed in the GUI to change if the status fragment is recreated. References #2134. --- .../jni/libandroidbridge/backend/android_service.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c index e5ecfdad7..33585df32 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_service.c @@ -550,6 +550,8 @@ METHOD(listener_t, alert, bool, private_android_service_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args) { + bool stay_registered = TRUE; + if (this->ike_sa == ike_sa) { switch (alert) @@ -557,11 +559,13 @@ METHOD(listener_t, alert, bool, case ALERT_PEER_ADDR_FAILED: charonservice->update_status(charonservice, CHARONSERVICE_LOOKUP_ERROR); - break; + return FALSE; + case ALERT_PEER_AUTH_FAILED: charonservice->update_status(charonservice, CHARONSERVICE_PEER_AUTH_ERROR); - break; + return FALSE; + case ALERT_KEEP_ON_CHILD_SA_FAILURE: { uint32_t *id = malloc_thing(uint32_t); @@ -593,6 +597,7 @@ METHOD(listener_t, alert, bool, (job_t*)callback_job_create_with_prio( (callback_job_cb_t)terminate, id, free, (callback_job_cancel_t)return_false, JOB_PRIO_HIGH)); + stay_registered = FALSE; } else { @@ -609,6 +614,7 @@ METHOD(listener_t, alert, bool, { charonservice->update_status(charonservice, CHARONSERVICE_UNREACHABLE_ERROR); + stay_registered = FALSE; } } this->lock->unlock(this->lock); @@ -617,7 +623,7 @@ METHOD(listener_t, alert, bool, break; } } - return TRUE; + return stay_registered; } static void add_auth_cfg_pw(private_android_service_t *this, From e03c9369823e4b6f79733c6d15a8ee95da70c389 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 2 Nov 2016 16:40:36 +0100 Subject: [PATCH 10/13] android: Log any installed DNS servers --- .../app/src/main/jni/libandroidbridge/backend/android_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c index 8015b7c38..47933d1f2 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c @@ -58,7 +58,7 @@ METHOD(attribute_handler_t, handle, bool, DESTROY_IF(dns); return FALSE; } - + DBG1(DBG_IKE, "installing DNS server %H", dns); builder = charonservice->get_vpnservice_builder(charonservice); builder->add_dns(builder, dns); dns->destroy(dns); From d5070425a0acefb9a316c52c253f24c29e929554 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 2 Nov 2016 18:26:43 +0100 Subject: [PATCH 11/13] android: Display a permanent notification while connected This forces the service to run in the foreground, meaning the system won't kill it when low on memory. --- .../android/logic/CharonVpnService.java | 142 +++++++++++++++--- .../android/logic/VpnStateService.java | 2 +- .../android/ui/VpnStateFragment.java | 3 +- .../res/drawable-hdpi/ic_notification.png | Bin 0 -> 356 bytes .../drawable-hdpi/ic_notification_warning.png | Bin 0 -> 367 bytes .../res/drawable-mdpi/ic_notification.png | Bin 0 -> 291 bytes .../drawable-mdpi/ic_notification_warning.png | Bin 0 -> 297 bytes .../res/drawable-xhdpi/ic_notification.png | Bin 0 -> 441 bytes .../ic_notification_warning.png | Bin 0 -> 451 bytes 9 files changed, 120 insertions(+), 27 deletions(-) create mode 100644 src/frontends/android/app/src/main/res/drawable-hdpi/ic_notification.png create mode 100644 src/frontends/android/app/src/main/res/drawable-hdpi/ic_notification_warning.png create mode 100644 src/frontends/android/app/src/main/res/drawable-mdpi/ic_notification.png create mode 100644 src/frontends/android/app/src/main/res/drawable-mdpi/ic_notification_warning.png create mode 100644 src/frontends/android/app/src/main/res/drawable-xhdpi/ic_notification.png create mode 100644 src/frontends/android/app/src/main/res/drawable-xhdpi/ic_notification_warning.png diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index a6b9fc52d..bf710f03b 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -17,29 +17,9 @@ package org.strongswan.android.logic; -import java.io.File; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import org.strongswan.android.data.VpnProfile; -import org.strongswan.android.data.VpnProfileDataSource; -import org.strongswan.android.data.VpnType.VpnTypeFeature; -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 org.strongswan.android.utils.SettingsWriter; - import android.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; @@ -53,13 +33,39 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.security.KeyChain; import android.security.KeyChainException; +import android.support.v4.app.NotificationCompat; +import android.support.v4.content.ContextCompat; import android.system.OsConstants; import android.util.Log; -public class CharonVpnService extends VpnService implements Runnable +import org.strongswan.android.R; +import org.strongswan.android.data.VpnProfile; +import org.strongswan.android.data.VpnProfileDataSource; +import org.strongswan.android.data.VpnType.VpnTypeFeature; +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 org.strongswan.android.utils.SettingsWriter; + +import java.io.File; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class CharonVpnService extends VpnService implements Runnable, VpnStateService.VpnStateListener { private static final String TAG = CharonVpnService.class.getSimpleName(); public static final String LOG_FILE = "charon.log"; + public static final int VPN_STATE_NOTIFICATION_ID = 1; private String mLogFile; private VpnProfileDataSource mDataSource; @@ -71,6 +77,7 @@ public class CharonVpnService extends VpnService implements Runnable private volatile boolean mProfileUpdated; private volatile boolean mTerminate; private volatile boolean mIsDisconnecting; + private volatile boolean mShowNotification; private VpnStateService mService; private final Object mServiceLock = new Object(); private final ServiceConnection mServiceConnection = new ServiceConnection() { @@ -91,6 +98,7 @@ public class CharonVpnService extends VpnService implements Runnable mService = ((VpnStateService.LocalBinder)service).getService(); } /* we are now ready to start the handler thread */ + mService.registerListener(CharonVpnService.this); mConnectionHandler.start(); } }; @@ -163,6 +171,7 @@ public class CharonVpnService extends VpnService implements Runnable } if (mService != null) { + mService.unregisterListener(this); unbindService(mServiceConnection); } mDataSource.close(); @@ -220,6 +229,7 @@ public class CharonVpnService extends VpnService implements Runnable startConnection(mCurrentProfile); mIsDisconnecting = false; + addNotification(); BuilderAdapter builder = new BuilderAdapter(mCurrentProfile.getName(), mCurrentProfile.getSplitTunneling()); if (initializeCharon(builder, mLogFile, mCurrentProfile.getVpnType().has(VpnTypeFeature.BYOD))) { @@ -268,10 +278,94 @@ public class CharonVpnService extends VpnService implements Runnable deinitializeCharon(); Log.i(TAG, "charon stopped"); mCurrentProfile = null; + removeNotification(); } } } + /** + * Add a permanent notification while we are connected to avoid the service getting killed by + * the system when low on memory. + */ + private void addNotification() + { + mShowNotification = true; + startForeground(VPN_STATE_NOTIFICATION_ID, buildNotification()); + } + + /** + * Remove the permanent notification. + */ + private void removeNotification() + { + mShowNotification = false; + stopForeground(true); + } + + + /** + * Build a notification matching the current state + */ + private Notification buildNotification() + { + VpnProfile profile = mService.getProfile(); + State state = mService.getState(); + ErrorState error = mService.getErrorState(); + String name = ""; + + if (profile != null) + { + name = profile.getName(); + } + android.support.v4.app.NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + .setContentText(name) + .setSmallIcon(R.drawable.ic_notification) + .setCategory(NotificationCompat.CATEGORY_SERVICE) + .setVisibility(NotificationCompat.VISIBILITY_SECRET); + int s = R.string.state_disabled; + if (error != ErrorState.NO_ERROR) + { + s = R.string.state_error; + builder.setSmallIcon(R.drawable.ic_notification_warning); + builder.setColor(ContextCompat.getColor(this, R.color.error_text)); + } + else + { + switch (state) + { + case CONNECTING: + s = R.string.state_connecting; + builder.setSmallIcon(R.drawable.ic_notification_warning); + builder.setColor(ContextCompat.getColor(this, R.color.warning_text)); + break; + case CONNECTED: + s = R.string.state_connected; + builder.setColor(ContextCompat.getColor(this, R.color.success_text)); + builder.setUsesChronometer(true); + break; + case DISCONNECTING: + s = R.string.state_disconnecting; + break; + } + } + builder.setContentTitle(getString(s)); + + Intent intent = new Intent(getApplicationContext(), MainActivity.class); + PendingIntent pending = PendingIntent.getActivity(getApplicationContext(), 0, intent, + PendingIntent.FLAG_UPDATE_CURRENT); + builder.setContentIntent(pending); + return builder.build(); + } + + @Override + public void stateChanged() { + if (mShowNotification) + { + NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + manager.notify(VPN_STATE_NOTIFICATION_ID, buildNotification()); + } + } + /** * Notify the state service about a new connection attempt. * Called by the handler thread. @@ -521,7 +615,7 @@ 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 + * @param byod enable BYOD features * @return TRUE if initialization was successful */ public native boolean initializeCharon(BuilderAdapter builder, String logfile, boolean byod); diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/VpnStateService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/VpnStateService.java index 7b40e942f..e35277d8c 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/VpnStateService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/VpnStateService.java @@ -315,7 +315,7 @@ public class VpnStateService extends Service * * May be called from threads other than the main thread. * - * @param error error state + * @param state IMC state */ public void setImcState(final ImcState state) { diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnStateFragment.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnStateFragment.java index 0b093d78f..1ea01515c 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnStateFragment.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnStateFragment.java @@ -187,12 +187,11 @@ public class VpnStateFragment extends Fragment implements VpnStateListener State state = mService.getState(); ErrorState error = mService.getErrorState(); ImcState imcState = mService.getImcState(); - String name = "", gateway = ""; + String name = ""; if (profile != null) { name = profile.getName(); - gateway = profile.getGateway(); } if (reportError(connectionID, name, error, imcState)) diff --git a/src/frontends/android/app/src/main/res/drawable-hdpi/ic_notification.png b/src/frontends/android/app/src/main/res/drawable-hdpi/ic_notification.png new file mode 100644 index 0000000000000000000000000000000000000000..d723ee611fde72b4e74421dbe62e221de64ef999 GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFtT~NIEGZ*dNa+D>yUwftE}i6b`7N+FL`6GR;`vh-Yd<& z;I`c22a9Iwu~f4vK2Yj2=r-sv(R9>4)9ydBB<+*bEt7<`b9+25H;8-+~f{9gXjHzgpohvOqSw&RyNsl=JD%Q?(5>cE4@A{WC5HCu^J! z70i~8+W6zu&cz@0lZ0j27~*UtKB4 y@qA&v+ysaFimX8jFtotl=1|kR35%yQFf;rRy{D3ty)*|HYz&^RelF{r5}E*+VUHF7 literal 0 HcmV?d00001 diff --git a/src/frontends/android/app/src/main/res/drawable-hdpi/ic_notification_warning.png b/src/frontends/android/app/src/main/res/drawable-hdpi/ic_notification_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..05198c8102289db3b2090ff80026d5f93ce3cf75 GIT binary patch literal 367 zcmV-#0g(QQP)cu;+OWZ|$fzSGB0n3ciy)WJe#`6wvh9dz z$stzrfeRixU+;165&|G+X7qlJY1g+GAJ33U*$1oN8*36EXod`Y>5@8%3SMneb z?nCdqAc5{76=dxN&>2!eD(G9!vR?n2x@3P_7`QYU})&{ zi&HX>?@0c?$87lvvI=G$>`?DG()hzjpxf!Ee?x`+l(!s5i~_!8D_moJG<^wMp!p>4 zbVft%Niy0YJZ!s8axStCIQzX}25YwscgQ>Y5M58P4N5!n)a2aHxC9;V^5qro`|#W? zss8w6j{T1>Fthvcn6Q~_Z(!|R&#?68gd;yD9J$E2$;whetYMS<0hWuO8MmI|Jr>CA nrYo^E;R+L%&H^h24g&_Ef@5~etRi;-J;dPY>gTe~DWM4fsbFlb literal 0 HcmV?d00001 diff --git a/src/frontends/android/app/src/main/res/drawable-mdpi/ic_notification_warning.png b/src/frontends/android/app/src/main/res/drawable-mdpi/ic_notification_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..f6cd212beb281d04028ee07277b1f9c4320867b4 GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XPJ6mIhE&{2`t$$4J+m+42_~ipo{rrOKg`QYU})&{ zi&HX>?@0c?$87lvvI=G$>`?DG()hzjpxf!Ee?x`+l(!s5i~_!8D_moJG<^wMp!p>4 zbVft%Niy0YJZ!s8axStCIQzX}25YwscgQ>Y5M58P4N5!n)a2aHxC9;V^5qro`|#W? zss8w6j{T1>Fthvcn6Q~_Z(!|R&#?68gd;yD9J$E2$;whetYMS<0hWuO8MmI|J?5Cr tsNDI=O;@5xtY_Jx#0isE@-Z;+FfblHYp4D5t25AB44$rjF6*2UngD~KaM1t& literal 0 HcmV?d00001 diff --git a/src/frontends/android/app/src/main/res/drawable-xhdpi/ic_notification.png b/src/frontends/android/app/src/main/res/drawable-xhdpi/ic_notification.png new file mode 100644 index 0000000000000000000000000000000000000000..9961c0ae5af352c8cfbc91356b98196e5c5abefe GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@jM1Jhjv*Dd-pnxcKja{CJo-YbNm*ga6@SHMwHAvV2Nre5 zcOT)?)A8A1VKL)@dBQOZ3k!n{7f)3D)2|fX8Mov0*On*$C*3dF`~6+rmh~~Sw3bdv z?h7k=A{exQH}9Z?&H*-!MCIh!9 zC8o1>FvlJAJ=>nZ_wGRc8#xW89J`59t@)eY%Stpw9^Gm>qoMqRa&qhi_WlQZl=4~P zl1vJ@YrzD45=kXH9?%ULH1fN@4x6wqifX$Eh@qIa_WiqkW|NA#zFbm@I zUo5hKft63kPv`nN-sG82@9!*$xxMvT`|HAA7wp29ykX=DXkY><(QrUwHYOzg-Z1qO fpG${5BO8NaoyAE3hqHyixM1*f^>bP0l+XkK5-GS0 literal 0 HcmV?d00001 diff --git a/src/frontends/android/app/src/main/res/drawable-xhdpi/ic_notification_warning.png b/src/frontends/android/app/src/main/res/drawable-xhdpi/ic_notification_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..1b5be812f133f283a1e4a1d29484b22a7c91516d GIT binary patch literal 451 zcmV;!0X+VRP)viL)D6p0vz5Re%r{sf6djznViEwf#ZOA}uj zeD@%?$dOCTzV+)qh4lDygMa1lB1|zC`e3P3Ko^`E{96YBrWl<&{foQMPoNmyMk#;- zDB#HKq~zJa;7dxr&bj5>wz*zyuhYl&yCP-}P(a`&_F1!vJ3s*xKmim$0ZsdmDeeGE th<72D5KkeN5C#0_CXTrS0qj?R0RRu&JkLT!G>!lO002ovPDHLkV1lHL!Ug~U literal 0 HcmV?d00001 From 85059424a7fd036f7a3153ebd7c35263e19cff02 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 7 Dec 2016 17:51:42 +0100 Subject: [PATCH 12/13] android: Add a public notification --- .../android/logic/CharonVpnService.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index bf710f03b..d3077f7ff 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -290,7 +290,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe private void addNotification() { mShowNotification = true; - startForeground(VPN_STATE_NOTIFICATION_ID, buildNotification()); + startForeground(VPN_STATE_NOTIFICATION_ID, buildNotification(false)); } /** @@ -302,11 +302,10 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe stopForeground(true); } - /** * Build a notification matching the current state */ - private Notification buildNotification() + private Notification buildNotification(boolean publicVersion) { VpnProfile profile = mService.getProfile(); State state = mService.getState(); @@ -318,10 +317,10 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe name = profile.getName(); } android.support.v4.app.NotificationCompat.Builder builder = new NotificationCompat.Builder(this) - .setContentText(name) .setSmallIcon(R.drawable.ic_notification) .setCategory(NotificationCompat.CATEGORY_SERVICE) - .setVisibility(NotificationCompat.VISIBILITY_SECRET); + .setVisibility(publicVersion ? NotificationCompat.VISIBILITY_PUBLIC + : NotificationCompat.VISIBILITY_PRIVATE); int s = R.string.state_disabled; if (error != ErrorState.NO_ERROR) { @@ -349,6 +348,11 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe } } builder.setContentTitle(getString(s)); + if (!publicVersion) + { + builder.setContentText(name); + builder.setPublicVersion(buildNotification(true)); + } Intent intent = new Intent(getApplicationContext(), MainActivity.class); PendingIntent pending = PendingIntent.getActivity(getApplicationContext(), 0, intent, @@ -362,7 +366,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe if (mShowNotification) { NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - manager.notify(VPN_STATE_NOTIFICATION_ID, buildNotification()); + manager.notify(VPN_STATE_NOTIFICATION_ID, buildNotification(false)); } } From 3e85b5a492aa001d6064ee7d88feb2e36ad14359 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 7 Dec 2016 17:52:33 +0100 Subject: [PATCH 13/13] android: Ensure that the certificates are loaded when accessing them via JNI --- .../java/org/strongswan/android/logic/CharonVpnService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index d3077f7ff..0048a2daf 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -542,7 +542,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe private byte[][] getTrustedCertificates() { ArrayList certs = new ArrayList(); - TrustedCertificateManager certman = TrustedCertificateManager.getInstance(); + TrustedCertificateManager certman = TrustedCertificateManager.getInstance().load(); try { String alias = this.mCurrentCertificateAlias;