From ffc2a0cbae78aa71e7ca5a64c76b75f1c5bba664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 24 Jun 2015 19:05:39 +0200 Subject: Tuned some times, refactoring tests --- .../leap/bitmaskclient/test/BaseTestDashboard.java | 61 --------------------- .../test/BaseTestDashboardFragment.java | 63 ++++++++++++++++++++++ .../se/leap/bitmaskclient/test/Screenshot.java | 3 +- .../leap/bitmaskclient/test/VpnTestController.java | 2 +- .../test/testConfigurationWizard.java | 5 ++ .../test/testDashboardIntegration.java | 12 +---- .../bitmaskclient/test/testUserStatusFragment.java | 5 +- .../leap/bitmaskclient/test/testVpnFragment.java | 11 +--- app/src/main/AndroidManifest.xml | 3 +- ics-openvpn | 2 +- 10 files changed, 79 insertions(+), 88 deletions(-) delete mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboard.java create mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboard.java deleted file mode 100644 index 9a9131fd..00000000 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboard.java +++ /dev/null @@ -1,61 +0,0 @@ -package se.leap.bitmaskclient.test; - -import android.content.*; -import android.graphics.*; -import android.test.*; -import android.view.*; - -import com.robotium.solo.*; - -import se.leap.bitmaskclient.*; - -public abstract class BaseTestDashboard extends ActivityInstrumentationTestCase2 { - - Solo solo; - Context context; - UserStatusTestController user_status_controller; - VpnTestController vpn_controller; - - public BaseTestDashboard() { super(Dashboard.class); } - - @Override - protected void setUp() throws Exception { - super.setUp(); - context = getInstrumentation().getContext(); - solo = new Solo(getInstrumentation(), getActivity()); - user_status_controller = new UserStatusTestController(solo); - vpn_controller = new VpnTestController(solo); - ConnectionManager.setMobileDataEnabled(true, context); - solo.unlockScreen(); - if (solo.searchText(solo.getString(R.string.configuration_wizard_title))) - new testConfigurationWizard(solo).toDashboardAnonymously("demo.bitmask.net"); - } - - void changeProviderAndLogIn(String provider) { - tapSwitchProvider(); - solo.clickOnText(provider); - useRegistered(); - } - - void tapSwitchProvider() { - solo.clickOnMenuItem(solo.getString(R.string.switch_provider_menu_option)); - solo.waitForActivity(ConfigurationWizard.class); - } - - private void useRegistered() { - String text = solo.getString(R.string.signup_or_login_button); - clickAndWaitForDashboard(text); - user_status_controller.logIn("parmegvtest10", "holahola2"); - } - - private void clickAndWaitForDashboard(String click_text) { - solo.clickOnText(click_text); - assertTrue(solo.waitForActivity(Dashboard.class, 80 * 1000)); - } - - static boolean isShownWithinConfinesOfVisibleScreen(View view) { - Rect scrollBounds = new Rect(); - view.getHitRect(scrollBounds); - return view.getLocalVisibleRect(scrollBounds); - } -} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java new file mode 100644 index 00000000..aef968b8 --- /dev/null +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java @@ -0,0 +1,63 @@ +package se.leap.bitmaskclient.test; + +import android.content.*; +import android.graphics.*; +import android.test.*; +import android.view.*; + +import com.robotium.solo.*; + +import se.leap.bitmaskclient.*; + +public abstract class BaseTestDashboardFragment extends ActivityInstrumentationTestCase2 { + + Solo solo; + Context context; + UserStatusTestController user_status_controller; + VpnTestController vpn_controller; + + public BaseTestDashboardFragment() { super(Dashboard.class); } + + @Override + protected void setUp() throws Exception { + super.setUp(); + context = getInstrumentation().getContext(); + solo = new Solo(getInstrumentation(), getActivity()); + Screenshot.initialize(solo); + user_status_controller = new UserStatusTestController(solo); + vpn_controller = new VpnTestController(solo); + ConnectionManager.setMobileDataEnabled(true, context); + solo.unlockScreen(); + if (solo.searchText(solo.getString(R.string.configuration_wizard_title))) + new testConfigurationWizard(solo).toDashboardAnonymously("demo.bitmask.net"); + } + + void changeProviderAndLogIn(String provider) { + tapSwitchProvider(); + solo.clickOnText(provider); + useRegistered(); + } + + void tapSwitchProvider() { + solo.clickOnMenuItem(solo.getString(R.string.switch_provider_menu_option)); + solo.waitForActivity(ConfigurationWizard.class); + } + + private void useRegistered() { + solo.waitForFragmentById(R.id.provider_detail_fragment); + String text = solo.getString(R.string.signup_or_login_button); + clickAndWaitForDashboard(text); + user_status_controller.logIn("parmegvtest10", "holahola2"); + } + + private void clickAndWaitForDashboard(String click_text) { + solo.clickOnText(click_text); + assertTrue(solo.waitForActivity(Dashboard.class, 80 * 1000)); + } + + static boolean isShownWithinConfinesOfVisibleScreen(View view) { + Rect scrollBounds = new Rect(); + view.getHitRect(scrollBounds); + return view.getLocalVisibleRect(scrollBounds); + } +} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/Screenshot.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/Screenshot.java index 91d51402..ade28b73 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/Screenshot.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/Screenshot.java @@ -26,8 +26,7 @@ public class Screenshot { } public static void take() { - sleepBefore(); - solo.takeScreenshot(default_name + "_" + getTimeStamp()); + take(default_name + "_" + getTimeStamp()); } public static void takeWithSleep() { diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java index 25d81da1..39ab37dd 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java @@ -79,7 +79,7 @@ public class VpnTestController { a = whole_icon != null ? (ProgressRingView) getVpnWholeIcon().findViewById(R.id.fabbutton_ring) : new ProgressRingView(solo.getCurrentActivity()); - BaseTestDashboard.isShownWithinConfinesOfVisibleScreen(a); + BaseTestDashboardFragment.isShownWithinConfinesOfVisibleScreen(a); } private boolean iconShowsConnected() { diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java index 931457ee..8b897b96 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java @@ -29,6 +29,7 @@ public class testConfigurationWizard extends ActivityInstrumentationTestCase2 - + Date: Tue, 16 Jun 2015 11:59:56 +0200 Subject: Use https to fetch submodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 8bd0f9d5..7c73874b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "ics-openvpn"] path = ics-openvpn branch = bitmask - url = git@github.com:parmegv/ics-openvpn.git + url = https://github.com/parmegv/ics-openvpn.git -- cgit v1.2.3 From c55786ffd17842f638d84812be8d544f51c53ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 17 Jun 2015 08:58:59 +0200 Subject: Remove mips architecture in ics-openvpn, and use fdroid's buildtools version --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 9acd5ab1..fbbc8eb8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 21 - buildToolsVersion "22.0.1" + buildToolsVersion "22.0.0" signingConfigs { release { -- cgit v1.2.3 From c8c12c38ca561ea5ccd8587f4136b2bf9713ffa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 24 Jun 2015 20:30:11 +0200 Subject: Write SD card permission needs to be turned on for tests only --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ce6d5ddd..b4ada5fc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,7 +23,8 @@ - + Date: Sat, 15 Aug 2015 17:14:04 +0200 Subject: A quote too much This is also an open issue in Transifex: https://www.transifex.com/otf/bitmask-android/translate/#es/$/22692144?issue=yes You should double check if this is correct. --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7746795e..06c80f12 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,7 +30,7 @@ Please enter your username password User message - About Bitmask" + About Bitmask Try again: server math error. Incorrect username or password. It should have at least 8 characters. -- cgit v1.2.3 From 013cff913a7ba73cb5d338848ebdb639ddcabaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 6 Feb 2016 11:50:21 +0100 Subject: Init ics-openvpn submodules --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f1921e10..07562089 100644 --- a/README.md +++ b/README.md @@ -28,14 +28,23 @@ Installable via `android` command (SDK Manager): * Android SDK Build-tools, 19.0.3 * Android Support Repository, 4+ -We need Mercurial: -* Mercurial: http://mercurial.selenic.com/downloads - Finally, install a java compiler. For example: sudo apt-get install default-jdk -### Build native sources +## Update git submodules + +We build upon ics-openvpn, which meets a submodule in our project structure. + +For that reason, it is necessary to initialize and update them before being able to build Bitmask Android. + + git submodule init + git submodule update + cd ics-openvpn + git submodule init + git submodule update + +## Build native sources To build NDK sources, you need to issue these commands: -- cgit v1.2.3 From 096faf08f2d0cc4dc4a28677415391942410063d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 6 Feb 2016 12:42:42 +0100 Subject: Update build tools and compile sdk version. Warn about the needed libraries for 64 bit systems. --- README.md | 3 +++ app/build.gradle | 4 ++-- app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java | 8 -------- app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java | 8 -------- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 07562089..885c415b 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ Finally, install a java compiler. For example: sudo apt-get install default-jdk +If you are using a 64-bit machine, you will need to install some libraries too: + sudo apt-get install lib32stdc++6 lib32z1 + ## Update git submodules We build upon ics-openvpn, which meets a submodule in our project structure. diff --git a/app/build.gradle b/app/build.gradle index fbbc8eb8..c6718303 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,8 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 21 - buildToolsVersion "22.0.0" + compileSdkVersion 23 + buildToolsVersion "23.0.2" signingConfigs { release { diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java index 2d7e13fe..df827242 100644 --- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderAPI.java @@ -22,7 +22,6 @@ import android.content.res.*; import android.os.*; import android.util.*; -import org.apache.http.client.*; import org.json.*; import org.thoughtcrime.ssl.pinning.util.*; @@ -440,9 +439,6 @@ public class ProviderAPI extends IntentService { is = urlConnection.getInputStream(); String plain_response = new Scanner(is).useDelimiter("\\A").next(); json_response = new JSONObject(plain_response); - } catch (ClientProtocolException e) { - json_response = getErrorMessage(urlConnection); - e.printStackTrace(); } catch (IOException e) { json_response = getErrorMessage(urlConnection); e.printStackTrace(); @@ -908,10 +904,6 @@ public class ProviderAPI extends IntentService { responseCode = urlConnection.getResponseCode(); broadcastProgress(progress++); LeapSRPSession.setToken(""); - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; } catch (IndexOutOfBoundsException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java index a3f7db6a..b9b449f0 100644 --- a/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/production/java/se/leap/bitmaskclient/ProviderAPI.java @@ -32,7 +32,6 @@ import java.util.*; import javax.net.ssl.*; -import org.apache.http.client.*; import org.json.*; import org.thoughtcrime.ssl.pinning.util.*; @@ -432,9 +431,6 @@ public class ProviderAPI extends IntentService { is = urlConnection.getInputStream(); String plain_response = new Scanner(is).useDelimiter("\\A").next(); json_response = new JSONObject(plain_response); - } catch (ClientProtocolException e) { - json_response = getErrorMessage(urlConnection); - e.printStackTrace(); } catch (IOException e) { json_response = getErrorMessage(urlConnection); e.printStackTrace(); @@ -890,10 +886,6 @@ public class ProviderAPI extends IntentService { responseCode = urlConnection.getResponseCode(); broadcastProgress(progress++); LeapSRPSession.setToken(""); - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; } catch (IndexOutOfBoundsException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From 5b95785060adace6b48a69d560051261233d954d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 6 Feb 2016 13:00:53 +0100 Subject: Update ics-openvpn --- README.md | 12 + app/build.gradle | 2 + app/snappy | 1 - app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 11 +- .../main/java/de/blinkt/openvpn/VpnProfile.java | 148 +++--- .../blinkt/openvpn/activities/DisconnectVPN.java | 2 +- .../de/blinkt/openvpn/activities/LogWindow.java | 4 +- .../main/java/de/blinkt/openvpn/core/CIDRIP.java | 2 +- .../java/de/blinkt/openvpn/core/ConfigParser.java | 54 ++- .../java/de/blinkt/openvpn/core/Connection.java | 7 +- .../blinkt/openvpn/core/DeviceStateReceiver.java | 83 +++- .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 4 +- .../openvpn/core/LollipopDeviceStateListener.java | 2 +- .../java/de/blinkt/openvpn/core/NativeUtils.java | 25 +- .../java/de/blinkt/openvpn/core/NetworkSpace.java | 32 +- .../de/blinkt/openvpn/core/OpenVPNManagement.java | 10 +- .../de/blinkt/openvpn/core/OpenVPNService.java | 108 ++++- .../java/de/blinkt/openvpn/core/OpenVPNThread.java | 2 +- .../openvpn/core/OpenVpnManagementThread.java | 251 +++++----- .../java/de/blinkt/openvpn/core/PRNGFixes.java | 2 +- .../de/blinkt/openvpn/core/ProfileManager.java | 7 +- .../de/blinkt/openvpn/core/ProxyDetection.java | 2 +- .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 29 +- .../java/de/blinkt/openvpn/core/VpnStatus.java | 161 +++++-- .../java/de/blinkt/openvpn/core/X509Utils.java | 71 ++- .../de/blinkt/openvpn/fragments/LogFragment.java | 505 +++++++++++---------- .../java/de/blinkt/openvpn/views/SeekBarTicks.java | 7 +- .../main/res/drawable-hdpi/ic_close_white_24dp.png | Bin 324 -> 221 bytes .../main/res/drawable-mdpi/ic_close_white_24dp.png | Bin 279 -> 175 bytes .../res/drawable-xhdpi/ic_close_white_24dp.png | Bin 402 -> 257 bytes .../res/drawable-xxhdpi/ic_close_white_24dp.png | Bin 492 -> 347 bytes .../res/drawable-xxxhdpi/ic_close_white_24dp.png | Bin 662 -> 436 bytes app/src/main/res/drawable/white_rect.xml | 2 +- .../main/res/layout-sw600dp-port/log_fragment.xml | 2 +- app/src/main/res/layout-sw600dp/log_fragment.xml | 2 +- app/src/main/res/layout/log_fragment.xml | 2 +- app/src/main/res/layout/log_silders.xml | 9 +- app/src/main/res/layout/log_window.xml | 2 +- app/src/main/res/layout/vpnstatus.xml | 2 +- app/src/main/res/menu/logmenu.xml | 13 +- app/src/main/res/values-cs/strings-icsopenvpn.xml | 2 - app/src/main/res/values-de/strings-icsopenvpn.xml | 30 +- app/src/main/res/values-es/strings-icsopenvpn.xml | 4 +- app/src/main/res/values-et/strings-icsopenvpn.xml | 25 +- app/src/main/res/values-fr/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-hu/strings-icsopenvpn.xml | 28 +- app/src/main/res/values-in/strings-icsopenvpn.xml | 135 +++++- app/src/main/res/values-it/strings-icsopenvpn.xml | 3 +- app/src/main/res/values-ja/strings-icsopenvpn.xml | 116 ++++- app/src/main/res/values-ko/strings-icsopenvpn.xml | 17 +- app/src/main/res/values-nl/strings-icsopenvpn.xml | 10 +- app/src/main/res/values-no/strings-icsopenvpn.xml | 1 - app/src/main/res/values-pl/strings-icsopenvpn.xml | 179 ++++++-- app/src/main/res/values-ro/strings-icsopenvpn.xml | 2 - app/src/main/res/values-ru/strings-icsopenvpn.xml | 53 ++- app/src/main/res/values-sv/strings-icsopenvpn.xml | 4 +- app/src/main/res/values-sw600dp/dimens.xml | 2 +- app/src/main/res/values-sw600dp/styles.xml | 2 +- app/src/main/res/values-tr/strings-icsopenvpn.xml | 27 +- app/src/main/res/values-uk/strings-icsopenvpn.xml | 13 +- app/src/main/res/values-v21/colours.xml | 2 +- app/src/main/res/values-v21/refs.xml | 15 +- app/src/main/res/values-v21/styles.xml | 19 +- app/src/main/res/values-vi/strings-icsopenvpn.xml | 25 +- .../main/res/values-zh-rCN/strings-icsopenvpn.xml | 12 +- .../main/res/values-zh-rTW/strings-icsopenvpn.xml | 239 +++++++--- app/src/main/res/values/colours.xml | 2 +- app/src/main/res/values/dimens.xml | 2 +- app/src/main/res/values/refs.xml | 14 +- app/src/main/res/values/strings-icsopenvpn.xml | 35 +- app/src/main/res/values/styles.xml | 16 +- ics-openvpn | 2 +- 72 files changed, 1771 insertions(+), 848 deletions(-) delete mode 120000 app/snappy diff --git a/README.md b/README.md index 885c415b..913a70c7 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,18 @@ Due to the nature of some tests, adb will lose its connectivity and you won't re We'll polish this process soon, but right now that's what we're doing (well, in fact, we run "adb logcat" in Emacs and then search "failed: test" in the corresponding buffer ;) ). +## Updating ics-openvpn + + cd ics-openvpn + git remote add upstream https://github.com/schwabe/ics-openvpn.git + git pull --rebase upstream master + +A bunch of conflicts may arise. The guidelines are: + 1. Methods in HEAD (upstream) completely removed from Bitmask should be removed again (e.g. askPW) + 2. Sometimes, Dashboard.class is in Bitmask while in ics-openvpn it is replaced by MainActivity.class and other classes. Keep removing them to keep Dashboard.class in there. + 3. Some resources files are stripped from several entries. Remove them if possible (check the code we compile is not using anything else new). + + ./gradlew updateIcsOpenVpn ## Acknowledgements This project bases its work in [ics-openvpn project](https://code.google.com/p/ics-openvpn/). diff --git a/app/build.gradle b/app/build.gradle index c6718303..f65f99fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,7 @@ dependencies { compile 'com.google.code.gson:gson:2.3.1' compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' compile 'mbanje.kurt:fabbutton:1.1.4' + compile 'com.android.support:support-annotations:23.1.1' } def processFileInplace(file, Closure processText) { @@ -81,6 +82,7 @@ task copyIcsOpenVPNClasses( type: Copy ) { include '**/dimens.xml' include '**/logmenu.xml' include '**/core/**.java' + include '**/activities/BaseActivity.java' includeEmptyDirs = false diff --git a/app/snappy b/app/snappy deleted file mode 120000 index c44d7d0f..00000000 --- a/app/snappy +++ /dev/null @@ -1 +0,0 @@ -../ics-openvpn/main/snappy \ No newline at end of file diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 90216a70..721e8991 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -20,6 +20,7 @@ import android.preference.PreferenceManager; import android.text.InputType; import android.text.TextUtils; import android.text.method.PasswordTransformationMethod; +import android.util.Log; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -63,6 +64,8 @@ public class LaunchVPN extends Activity { public static final String EXTRA_KEY = "de.blinkt.openvpn.shortcutProfileUUID"; public static final String EXTRA_NAME = "de.blinkt.openvpn.shortcutProfileName"; public static final String EXTRA_HIDELOG = "de.blinkt.openvpn.showNoLogWindow"; + public static final String CLEARLOG = "clearlogconnect"; + private static final int START_VPN_PROFILE= 70; @@ -93,6 +96,10 @@ public class LaunchVPN extends Activity { if(Intent.ACTION_MAIN.equals(action)) { + // Check if we need to clear the log + if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(CLEARLOG, true)) + VpnStatus.clearLog(); + // we got called to be the starting point, most likely a shortcut String shortcutUUID = intent.getStringExtra( EXTRA_KEY); String shortcutName = intent.getStringExtra( EXTRA_NAME); @@ -115,7 +122,7 @@ public class LaunchVPN extends Activity { } } - + @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index 43e1b57c..dbe4b440 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -18,6 +18,7 @@ import android.os.Build; import android.preference.PreferenceManager; import android.security.KeyChain; import android.security.KeyChainException; +import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Base64; @@ -71,7 +72,7 @@ public class VpnProfile implements Serializable, Cloneable { private static final long serialVersionUID = 7085688938959334563L; public static final int MAXLOGLEVEL = 4; - public static final int CURRENT_PROFILE_VERSION = 5; + public static final int CURRENT_PROFILE_VERSION = 6; public static final int DEFAULT_MSSFIX_SIZE = 1450; public static String DEFAULT_DNS1 = "8.8.8.8"; public static String DEFAULT_DNS2 = "8.8.4.4"; @@ -152,7 +153,7 @@ public class VpnProfile implements Serializable, Cloneable { public int mMssFix =0; // -1 is default, public Connection[] mConnections = new Connection[0]; public boolean mRemoteRandom=false; - public HashSet mAllowedAppsVpn = new HashSet(); + public HashSet mAllowedAppsVpn = new HashSet<>(); public boolean mAllowedAppsVpnAreDisallowed = true; public String mProfileCreator; @@ -160,8 +161,7 @@ public class VpnProfile implements Serializable, Cloneable { public String mServerName = "openvpn.blinkt.de"; public String mServerPort = "1194"; public boolean mUseUdp = true; - - + public boolean mPushPeerInfo=false; public VpnProfile(String name) { mUuid = UUID.randomUUID(); @@ -197,6 +197,7 @@ public class VpnProfile implements Serializable, Cloneable { mCheckRemoteCN = false; mPersistTun = false; mAllowLocalLAN = true; + mPushPeerInfo =false; mMssFix = 0; } @@ -222,10 +223,16 @@ public class VpnProfile implements Serializable, Cloneable { mAllowedAppsVpnAreDisallowed=true; } if (mAllowedAppsVpn==null) - mAllowedAppsVpn = new HashSet(); + mAllowedAppsVpn = new HashSet<>(); if (mConnections ==null) mConnections = new Connection[0]; + if (mProfileVersion < 6) { + if (TextUtils.isEmpty(mProfileCreator)) + mUserEditable=true; + } + + mProfileVersion= CURRENT_PROFILE_VERSION; } @@ -260,8 +267,12 @@ public class VpnProfile implements Serializable, Cloneable { cfg += "management-query-passwords\n"; cfg += "management-hold\n\n"; - if (!configForOvpn3) + if (!configForOvpn3) { cfg += String.format("setenv IV_GUI_VER %s \n", openVpnEscape(getVersionEnvString(context))); + String versionString = String.format("%d %s %s %s %s %s", Build.VERSION.SDK_INT, Build.VERSION.RELEASE, + NativeUtils.getNativeAPI(), Build.BRAND, Build.BOARD, Build.MODEL); + cfg += String.format("setenv IV_PLAT_VER %s\n", openVpnEscape(versionString)) ; + } cfg += "machine-readable-output\n"; @@ -432,9 +443,9 @@ public class VpnProfile implements Serializable, Cloneable { } if (mMssFix !=0){ - if (mMssFix!=1450) - cfg+=String.format("mssfix %d\n", mMssFix, Locale.US); - else + if (mMssFix!=1450) { + cfg += String.format("mssfix %d\n", mMssFix, Locale.US); + } else cfg+="mssfix\n"; } @@ -495,6 +506,9 @@ public class VpnProfile implements Serializable, Cloneable { cfg += "preresolve\n"; } + if (mPushPeerInfo) + cfg+="push-peer-info\n"; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true); if (usesystemproxy) { @@ -541,7 +555,7 @@ public class VpnProfile implements Serializable, Cloneable { } //! Put inline data inline and other data as normal escaped filename - private String insertFileData(String cfgentry, String filedata) { + public static String insertFileData(String cfgentry, String filedata) { if (filedata == null) { // TODO: generate good error return String.format("%s %s\n", cfgentry, "missing"); @@ -553,8 +567,9 @@ public class VpnProfile implements Serializable, Cloneable { } } + @NonNull private Collection getCustomRoutes(String routes) { - Vector cidrRoutes = new Vector(); + Vector cidrRoutes = new Vector<>(); if (routes == null) { // No routes set, return empty vector return cidrRoutes; @@ -563,7 +578,7 @@ public class VpnProfile implements Serializable, Cloneable { if (!route.equals("")) { String cidrroute = cidrToIPAndNetmask(route); if (cidrroute == null) - return null; + return cidrRoutes; cidrRoutes.add(cidrroute); } @@ -573,7 +588,7 @@ public class VpnProfile implements Serializable, Cloneable { } private Collection getCustomRoutesv6(String routes) { - Vector cidrRoutes = new Vector(); + Vector cidrRoutes = new Vector<>(); if (routes == null) { // No routes set, return empty vector return cidrRoutes; @@ -606,8 +621,8 @@ public class VpnProfile implements Serializable, Cloneable { return null; - long nm = 0xffffffffl; - nm = (nm << (32 - len)) & 0xffffffffl; + long nm = 0xffffffffL; + nm = (nm << (32 - len)) & 0xffffffffL; String netmask = String.format(Locale.ENGLISH, "%d.%d.%d.%d", (nm & 0xff000000) >> 24, (nm & 0xff0000) >> 16, (nm & 0xff00) >> 8, nm & 0xff); return parts[0] + " " + netmask; @@ -708,7 +723,7 @@ public class VpnProfile implements Serializable, Cloneable { public VpnProfile copy(String name) { try { - VpnProfile copy = (VpnProfile) clone(); + VpnProfile copy = clone(); copy.mName = name; return copy; @@ -726,17 +741,14 @@ public class VpnProfile implements Serializable, Cloneable { } synchronized String[] getKeyStoreCertificates(Context context,int tries) { - PrivateKey privateKey = null; - X509Certificate[] caChain; - Exception exp; try { - privateKey = KeyChain.getPrivateKey(context, mAlias); + PrivateKey privateKey = KeyChain.getPrivateKey(context, mAlias); mPrivateKey = privateKey; String keystoreChain = null; - caChain = KeyChain.getCertificateChain(context, mAlias); + X509Certificate[] caChain = KeyChain.getCertificateChain(context, mAlias); if(caChain == null) throw new NoCertReturnedException("No certificate returned from Keystore"); @@ -758,11 +770,12 @@ public class VpnProfile implements Serializable, Cloneable { String caout = null; if (!TextUtils.isEmpty(mCaFilename)) { try { - Certificate cacert = X509Utils.getCertificateFromFile(mCaFilename); + Certificate[] cacerts = X509Utils.getCertificatesFromFile(mCaFilename); StringWriter caoutWriter = new StringWriter(); PemWriter pw = new PemWriter(caoutWriter); - pw.writeObject(new PemObject("CERTIFICATE", cacert.getEncoded())); + for (Certificate cert: cacerts) + pw.writeObject(new PemObject("CERTIFICATE", cert.getEncoded())); pw.close(); caout= caoutWriter.toString(); @@ -796,20 +809,19 @@ public class VpnProfile implements Serializable, Cloneable { } return new String[]{ca, extra, user}; - } catch (InterruptedException e) { - exp=e; - } catch (FileNotFoundException e) { - exp=e; - } catch (CertificateException e) { - exp=e; - } catch (IOException e) { - exp=e; - } catch (KeyChainException e) { - exp=e; - } catch (NoCertReturnedException e) { - exp =e; - } catch (IllegalArgumentException e) { - exp =e; + } catch (InterruptedException | IOException | KeyChainException | NoCertReturnedException | IllegalArgumentException + | CertificateException e) { + e.printStackTrace(); + VpnStatus.logError(R.string.keyChainAccessError, e.getLocalizedMessage()); + + VpnStatus.logError(R.string.keychain_access); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { + if (!mAlias.matches("^[a-zA-Z0-9]$")) { + VpnStatus.logError(R.string.jelly_keystore_alphanumeric_bug); + } + } + return null; + } catch (AssertionError e) { if (tries ==0) return null; @@ -822,19 +834,9 @@ public class VpnProfile implements Serializable, Cloneable { return getKeyStoreCertificates(context, tries-1); } - exp.printStackTrace(); - VpnStatus.logError(R.string.keyChainAccessError, exp.getLocalizedMessage()); - - VpnStatus.logError(R.string.keychain_access); - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { - if (!mAlias.matches("^[a-zA-Z0-9]$")) { - VpnStatus.logError(R.string.jelly_keystore_alphanumeric_bug); - } - } - return null; } - //! Return an error if somethign is wrong + //! Return an error if something is wrong public int checkProfile(Context context) { if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE) { if (mAlias == null) @@ -845,8 +847,14 @@ public class VpnProfile implements Serializable, Cloneable { if (mIPv4Address == null || cidrToIPAndNetmask(mIPv4Address) == null) return R.string.ipv4_format_error; } - if (!mUseDefaultRoute && (getCustomRoutes(mCustomRoutes) == null || getCustomRoutes(mExcludedRoutes) ==null)) - return R.string.custom_route_format_error; + if (!mUseDefaultRoute) { + if (!TextUtils.isEmpty(mCustomRoutes) && getCustomRoutes(mCustomRoutes).size() == 0 ) + return R.string.custom_route_format_error; + + if (!TextUtils.isEmpty(mExcludedRoutes) && getCustomRoutes(mExcludedRoutes).size() == 0 ) + return R.string.custom_route_format_error; + + } boolean noRemoteEnabled = true; for (Connection c : mConnections) @@ -980,7 +988,6 @@ public class VpnProfile implements Serializable, Cloneable { public String getSignedData(String b64data) { PrivateKey privkey = getKeystoreKey(); - Exception err; byte[] data = Base64.decode(b64data, Base64.DEFAULT); @@ -1004,26 +1011,14 @@ public class VpnProfile implements Serializable, Cloneable { byte[] signed_bytes = rsaSigner.doFinal(data); return Base64.encodeToString(signed_bytes, Base64.NO_WRAP); - } catch (NoSuchAlgorithmException e) { - err = e; - } catch (InvalidKeyException e) { - err = e; - } catch (NoSuchPaddingException e) { - err = e; - } catch (IllegalBlockSizeException e) { - err = e; - } catch (BadPaddingException e) { - err = e; + } catch (NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException + | BadPaddingException | NoSuchPaddingException e) { + VpnStatus.logError(R.string.error_rsa_sign, e.getClass().toString(), e.getLocalizedMessage()); + return null; } - - VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); - - return null; - } private String processSignJellyBeans(PrivateKey privkey, byte[] data) { - Exception err; try { Method getKey = privkey.getClass().getSuperclass().getDeclaredMethod("getOpenSSLKey"); getKey.setAccessible(true); @@ -1044,21 +1039,10 @@ public class VpnProfile implements Serializable, Cloneable { byte[] signed_bytes = NativeUtils.rsasign(data, pkey); return Base64.encodeToString(signed_bytes, Base64.NO_WRAP); - } catch (NoSuchMethodException e) { - err = e; - } catch (IllegalArgumentException e) { - err = e; - } catch (IllegalAccessException e) { - err = e; - } catch (InvocationTargetException e) { - err = e; - } catch (InvalidKeyException e) { - err = e; + } catch (NoSuchMethodException | InvalidKeyException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { + VpnStatus.logError(R.string.error_rsa_sign, e.getClass().toString(), e.getLocalizedMessage()); + return null; } - VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); - - return null; - } diff --git a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java index dfd815e4..f55de486 100644 --- a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ diff --git a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java index 45f09c8e..130084f5 100644 --- a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java +++ b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -15,7 +15,7 @@ import de.blinkt.openvpn.fragments.LogFragment; /** * Created by arne on 13.10.13. */ -public class LogWindow extends Activity { +public class LogWindow extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java index 94ed8a0b..07f2152f 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java +++ b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 232c454b..80a15c54 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -37,6 +37,8 @@ public class ConfigParser { public void parseConfig(Reader reader) throws IOException, ConfigParseError { + HashMap optionAliases = new HashMap<>(); + optionAliases.put("server-poll-timeout", "timeout-connect"); BufferedReader br = new BufferedReader(reader); @@ -48,9 +50,15 @@ public class ConfigParser { if (line == null) break; - if (lineno == 1 && (line.startsWith("PK\003\004") - || (line.startsWith("PK\007\008")))) - throw new ConfigParseError("Input looks like a ZIP Archive. Import is only possible for OpenVPN config files (.ovpn/.conf)"); + if (lineno == 1) { + if ((line.startsWith("PK\003\004") + || (line.startsWith("PK\007\008")))) { + throw new ConfigParseError("Input looks like a ZIP Archive. Import is only possible for OpenVPN config files (.ovpn/.conf)"); + } + if (line.startsWith("\uFEFF")) { + line = line.substring(1); + } + } // Check for OpenVPN Access Server Meta information if (line.startsWith("# OVPN_ACCESS_SERVER_")) { @@ -70,6 +78,9 @@ public class ConfigParser { checkinlinefile(args, br); String optionname = args.get(0); + if (optionAliases.get(optionname)!=null) + optionname = optionAliases.get(optionname); + if (!options.containsKey(optionname)) { options.put(optionname, new Vector>()); } @@ -137,7 +148,7 @@ public class ConfigParser { } - public class ConfigParseError extends Exception { + public static class ConfigParseError extends Exception { private static final long serialVersionUID = -60L; public ConfigParseError(String msg) { @@ -388,6 +399,10 @@ public class ConfigParser { np.mCustomRoutesv6 = customIPv6Routes; } + Vector routeNoPull = getOption("route-nopull", 1, 1); + if (routeNoPull!=null) + np.mRoutenopull=true; + // Also recognize tls-auth [inline] direction ... Vector> tlsauthoptions = getAllOption("tls-auth", 1, 2); if (tlsauthoptions != null) { @@ -567,6 +582,9 @@ public class ConfigParser { if (getOption("persist-tun", 0, 0) != null) np.mPersistTun = true; + if (getOption("push-peer-info", 0, 0) != null) + np.mPushPeerInfo = true; + Vector connectretry = getOption("connect-retry", 1, 1); if (connectretry != null) np.mConnectRetry = connectretry.get(1); @@ -709,8 +727,18 @@ public class ConfigParser { conn.mUseUdp = isUdpProto(proto.get(1)); } + Vector connectTimeout = getOption("connect-timeout", 1, 1); + if (connectTimeout != null) { + try { + conn.mConnectTimeout = Integer.parseInt(connectTimeout.get(1)); + } catch (NumberFormatException nfe) { + throw new ConfigParseError(String.format("Argument to connect-timeout (%s) must to be an integer: %s", + connectTimeout.get(1), nfe.getLocalizedMessage())); + + } + } - // Parse remote config + // Parse remote config Vector> remotes = getAllOption("remote", 1, 3); @@ -838,13 +866,21 @@ public class ConfigParser { return false; } + //! Generate options for custom options private String getOptionStrings(Vector> option) { String custom = ""; for (Vector optionsline : option) { if (!ignoreThisOption(optionsline)) { - for (String arg : optionsline) - custom += VpnProfile.openVpnEscape(arg) + " "; - custom += "\n"; + // Check if option had been inlined and inline again + if (optionsline.size() == 2 && "extra-certs".equals(optionsline.get(0)) ) { + custom += VpnProfile.insertFileData(optionsline.get(0), optionsline.get(1)); + + + } else { + for (String arg : optionsline) + custom += VpnProfile.openVpnEscape(arg) + " "; + custom += "\n"; + } } } return custom; diff --git a/app/src/main/java/de/blinkt/openvpn/core/Connection.java b/app/src/main/java/de/blinkt/openvpn/core/Connection.java index b10664ce..3455450b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/Connection.java +++ b/app/src/main/java/de/blinkt/openvpn/core/Connection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -16,6 +16,7 @@ public class Connection implements Serializable, Cloneable { public String mCustomConfiguration=""; public boolean mUseCustomConfig=false; public boolean mEnabled=true; + public int mConnectTimeout = 0; private static final long serialVersionUID = 92031902903829089L; @@ -33,6 +34,10 @@ public class Connection implements Serializable, Cloneable { else cfg += " tcp-client\n"; + if (mConnectTimeout!=0) + cfg += String.format(" connect-timeout %d\n" , mConnectTimeout); + + if (!TextUtils.isEmpty(mCustomConfiguration) && mUseCustomConfig) { cfg += mCustomConfiguration; cfg += "\n"; diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java index 4ccf5472..40684af3 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -12,15 +12,19 @@ import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.State; +import android.os.Handler; import android.preference.PreferenceManager; + import se.leap.bitmaskclient.R; import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; import java.util.LinkedList; +import java.util.Objects; import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason; -public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener { +public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener, OpenVPNManagement.PausedStateCallback { + private final Handler mDisconnectHandler; private int lastNetwork = -1; private OpenVPNManagement mManagement; @@ -29,12 +33,36 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL // Data traffic limit in bytes private final long TRAFFIC_LIMIT = 64 * 1024; + // Time to wait after network disconnect to pause the VPN + private final int DISCONNECT_WAIT = 20; + connectState network = connectState.DISCONNECTED; connectState screen = connectState.SHOULDBECONNECTED; connectState userpause = connectState.SHOULDBECONNECTED; private String lastStateMsg = null; + private java.lang.Runnable mDelayDisconnectRunnable = new Runnable() { + @Override + public void run() { + if (!(network == connectState.PENDINGDISCONNECT)) + return; + + network = connectState.DISCONNECTED; + + // Set screen state to be disconnected if disconnect pending + if (screen == connectState.PENDINGDISCONNECT) + screen = connectState.DISCONNECTED; + + mManagement.pause(getPauseReason()); + } + }; + private NetworkInfo lastConnectedNetwork; + + @Override + public boolean shouldBeRunning() { + return shouldBeConnected(); + } enum connectState { SHOULDBECONNECTED, @@ -54,6 +82,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL LinkedList trafficdata = new LinkedList(); + @Override public void updateByteCount(long in, long out, long diffIn, long diffOut) { if (screen != connectState.PENDINGDISCONNECT) @@ -99,6 +128,8 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL public DeviceStateReceiver(OpenVPNManagement magnagement) { super(); mManagement = magnagement; + mManagement.setPauseCallback(this); + mDisconnectHandler = new Handler(); } @@ -113,7 +144,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL boolean screenOffPause = prefs.getBoolean("screenoff", false); if (screenOffPause) { - if (ProfileManager.getLastConnectedVpn()!=null && !ProfileManager.getLastConnectedVpn().mPersistTun) + if (ProfileManager.getLastConnectedVpn() != null && !ProfileManager.getLastConnectedVpn().mPersistTun) VpnStatus.logError(R.string.screen_nopersistenttun); screen = connectState.PENDINGDISCONNECT; @@ -126,6 +157,8 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL boolean connected = shouldBeConnected(); screen = connectState.SHOULDBECONNECTED; + /* We should connect now, cancel any outstanding disconnect timer */ + mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable); /* should be connected has changed because the screen is on now, connect the VPN */ if (shouldBeConnected() != connected) mManagement.resume(); @@ -140,6 +173,10 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL private void fillTrafficData() { trafficdata.add(new Datapoint(System.currentTimeMillis(), TRAFFIC_LIMIT)); } + public static boolean equalsObj(Object a, Object b) { + return (a == null) ? (b == null) : a.equals(b); + } + public void networkStateChange(Context context) { @@ -175,34 +212,49 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL if (networkInfo != null && networkInfo.getState() == State.CONNECTED) { int newnet = networkInfo.getType(); + + boolean pendingDisconnect = (network == connectState.PENDINGDISCONNECT); network = connectState.SHOULDBECONNECTED; - if (lastNetwork != newnet) { + boolean sameNetwork; + if (lastConnectedNetwork == null + || lastConnectedNetwork.getType() != networkInfo.getType() + || !equalsObj(lastConnectedNetwork.getExtraInfo(), networkInfo.getExtraInfo()) + ) + sameNetwork = false; + else + sameNetwork = true; + + /* Same network, connection still 'established' */ + if (pendingDisconnect && sameNetwork) { + mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable); + // Reprotect the sockets just be sure + mManagement.networkChange(true); + } else { + /* Different network or connection not established anymore */ + if (screen == connectState.PENDINGDISCONNECT) screen = connectState.DISCONNECTED; if (shouldBeConnected()) { - if (lastNetwork == -1) { - mManagement.resume(); - } else { - mManagement.networkChange(); + mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable); - } + if (pendingDisconnect || !sameNetwork) + mManagement.networkChange(sameNetwork); + else + mManagement.resume(); } lastNetwork = newnet; + lastConnectedNetwork = networkInfo; } } else if (networkInfo == null) { // Not connected, stop openvpn, set last connected network to no network lastNetwork = -1; if (sendusr1) { - network = connectState.DISCONNECTED; - - // Set screen state to be disconnected if disconnect pending - if (screen == connectState.PENDINGDISCONNECT) - screen = connectState.DISCONNECTED; + network = connectState.PENDINGDISCONNECT; + mDisconnectHandler.postDelayed(mDelayDisconnectRunnable, DISCONNECT_WAIT * 1000); - mManagement.pause(getPauseReason()); } } @@ -213,6 +265,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL } + public boolean isUserPaused() { return userpause == connectState.DISCONNECTED; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java index 6e9e63c5..db3ae751 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -37,5 +37,7 @@ public class ICSOpenVPNApplication extends Application { if (BuildConfig.DEBUG) { //ACRA.init(this); } + + VpnStatus.initLogCache(getApplicationContext().getCacheDir()); } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java b/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java index 440458e4..04e4e8b4 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java +++ b/app/src/main/java/de/blinkt/openvpn/core/LollipopDeviceStateListener.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ diff --git a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java index f67b7730..ea003d41 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -1,19 +1,26 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; +import android.os.Build; + import java.security.InvalidKeyException; public class NativeUtils { - public static native byte[] rsasign(byte[] input,int pkey) throws InvalidKeyException; - public static native String[] getIfconfig() throws IllegalArgumentException; - static native void jniclose(int fdint); - - static { - System.loadLibrary("stlport_shared"); - System.loadLibrary("opvpnutil"); - } + public static native byte[] rsasign(byte[] input, int pkey) throws InvalidKeyException; + + public static native String[] getIfconfig() throws IllegalArgumentException; + + static native void jniclose(int fdint); + + public static native String getNativeAPI(); + + static { + System.loadLibrary("opvpnutil"); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) + System.loadLibrary("jbcrypto"); + } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java index c86f9e44..eb6d4d42 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java @@ -1,28 +1,28 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; import android.os.Build; +import android.support.annotation.NonNull; import android.text.TextUtils; import junit.framework.Assert; -import org.jetbrains.annotations.NotNull; - import java.math.BigInteger; import java.net.Inet6Address; -import java.util.*; +import java.util.Collection; +import java.util.Locale; +import java.util.PriorityQueue; +import java.util.TreeSet; +import java.util.Vector; import se.leap.bitmaskclient.BuildConfig; public class NetworkSpace { - - - static class ipAddress implements Comparable { private BigInteger netAddress; public int networkMask; @@ -38,7 +38,7 @@ public class NetworkSpace { * 2. smaller networks are returned as smaller */ @Override - public int compareTo(@NotNull ipAddress another) { + public int compareTo(@NonNull ipAddress another) { int comp = getFirstAddress().compareTo(another.getFirstAddress()); if (comp != 0) return comp; @@ -159,16 +159,20 @@ public class NetworkSpace { String getIPv6Address() { if (BuildConfig.DEBUG) Assert.assertTrue (!isV4); BigInteger r = netAddress; - if (r.compareTo(BigInteger.ZERO)==0 && networkMask==0) - return "::"; Vector parts = new Vector(); - while (r.compareTo(BigInteger.ZERO) == 1) { - parts.add(0, String.format(Locale.US, "%x", r.mod(BigInteger.valueOf(0x10000)).longValue())); + while (r.compareTo(BigInteger.ZERO) == 1 || parts.size() <3) { + long part = r.mod(BigInteger.valueOf(0x10000)).longValue(); + if (part!=0) + parts.add(0, String.format(Locale.US, "%x", part)); + else + parts.add(0, ""); r = r.shiftRight(16); } - - return TextUtils.join(":", parts); + String ipv6str = TextUtils.join(":", parts); + while (ipv6str.contains(":::")) + ipv6str = ipv6str.replace(":::", "::"); + return ipv6str; } public boolean containsNet(ipAddress network) { diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java index 1f28c77d..2771fa6a 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -1,11 +1,15 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; public interface OpenVPNManagement { + interface PausedStateCallback { + boolean shouldBeRunning(); + } + enum pauseReason { noNetwork, userPause, @@ -25,5 +29,7 @@ public interface OpenVPNManagement { /* * Rebind the interface */ - void networkChange(); + void networkChange(boolean sameNetwork); + + void setPauseCallback(PausedStateCallback callback); } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index f9cb9a86..17be29b0 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -10,15 +10,18 @@ import android.annotation.TargetApi; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.UiModeManager; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.net.ConnectivityManager; import android.net.VpnService; import android.os.Binder; import android.os.Build; +import android.os.Handler; import android.os.Handler.Callback; import android.os.IBinder; import android.os.Message; @@ -27,6 +30,7 @@ import android.preference.PreferenceManager; import android.system.OsConstants; import android.text.TextUtils; import android.util.Log; +import android.widget.Toast; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -81,6 +85,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private String mLastTunCfg; private String mRemoteGW; private final Object mProcessLock = new Object(); + private Handler guiHandler; + private Toast mlastToast; // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java public static String humanReadableByteCount(long bytes, boolean mbit) { @@ -109,6 +115,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac @Override public void onRevoke() { + VpnStatus.logInfo(R.string.permission_revoked); mManagement.stopVPN(); endVpnService(); } @@ -135,7 +142,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } } - private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) { + private void showNotification(final String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) { String ns = Context.NOTIFICATION_SERVICE; NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); @@ -164,6 +171,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) jbNotificationExtras(lowpriority, nbuilder); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + lpNotificationExtras(nbuilder); + if (tickerText != null && !tickerText.equals("")) nbuilder.setTicker(tickerText); @@ -173,6 +183,33 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mNotificationManager.notify(OPENVPN_STATUS, notification); //startForeground(OPENVPN_STATUS, notification); + + // Check if running on a TV + if(runningOnAndroidTV() && !lowpriority) + guiHandler.post(new Runnable() { + + @Override + public void run() { + + if (mlastToast!=null) + mlastToast.cancel(); + String toastText = String.format(Locale.getDefault(), "%s - %s", mProfile.mName, msg); + mlastToast = Toast.makeText(getBaseContext(), toastText, Toast.LENGTH_SHORT); + mlastToast.show(); + } + }); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void lpNotificationExtras(Notification.Builder nbuilder) { + nbuilder.setCategory(Notification.CATEGORY_SERVICE); + nbuilder.setLocalOnly(true); + + } + + private boolean runningOnAndroidTV() { + UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); + return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION; } private int getIconByConnectionStatus(ConnectionStatus level) { @@ -215,20 +252,20 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac disconnectVPN.setAction(DISCONNECT_VPN); PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0); - nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, + nbuilder.addAction(R.drawable.ic_menu_close_clear_cancel, getString(R.string.cancel_connection), disconnectPendingIntent); Intent pauseVPN = new Intent(this, OpenVPNService.class); if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) { pauseVPN.setAction(PAUSE_VPN); PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0); - nbuilder.addAction(android.R.drawable.ic_media_pause, + nbuilder.addAction(R.drawable.ic_menu_pause, getString(R.string.pauseVPN), pauseVPNPending); } else { pauseVPN.setAction(RESUME_VPN); PendingIntent resumeVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0); - nbuilder.addAction(android.R.drawable.ic_media_play, + nbuilder.addAction(R.drawable.ic_menu_play, getString(R.string.resumevpn), resumeVPNPending); } @@ -297,6 +334,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.addStateListener(this); VpnStatus.addByteCountListener(this); + guiHandler = new Handler(getMainLooper()); + + if (intent != null && PAUSE_VPN.equals(intent.getAction())) { if (mDeviceStateReceiver != null) mDeviceStateReceiver.userPause(true); @@ -454,6 +494,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } // Just in case unregister for state VpnStatus.removeStateListener(this); + VpnStatus.flushLog(); } @@ -536,6 +577,26 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac Collection positiveIPv4Routes = mRoutes.getPositiveIPList(); Collection positiveIPv6Routes = mRoutesv6.getPositiveIPList(); + if ("samsung".equals(Build.BRAND) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mDnslist.size() >= 1) { + // Check if the first DNS Server is in the VPN range + try { + ipAddress dnsServer = new ipAddress(new CIDRIP(mDnslist.get(0), 32), true); + boolean dnsIncluded=false; + for (ipAddress net : positiveIPv4Routes) { + if (net.containsNet(dnsServer)) { + dnsIncluded = true; + } + } + if (!dnsIncluded) { + String samsungwarning = String.format("Warning Samsung Android 5.0+ devices ignore DNS servers outside the VPN range. To enable DNS resolution a route to your DNS Server (%s) has been added.", mDnslist.get(0)); + VpnStatus.logWarning(samsungwarning); + positiveIPv4Routes.add(dnsServer); + } + } catch (Exception e) { + VpnStatus.logError("Error parsing DNS Server IP: " + mDnslist.get(0)); + } + } + ipAddress multicastRange = new ipAddress(new CIDRIP("224.0.0.0", 3), true); for (NetworkSpace.ipAddress route : positiveIPv4Routes) { @@ -558,24 +619,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } } - if ("samsung".equals(Build.BRAND) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mDnslist.size() >= 1) { - // Check if the first DNS Server is in the VPN range - try { - ipAddress dnsServer = new ipAddress(new CIDRIP(mDnslist.get(0), 32), true); - boolean dnsIncluded=false; - for (ipAddress net : positiveIPv4Routes) { - if (net.containsNet(dnsServer)) { - dnsIncluded = true; - } - } - if (!dnsIncluded) { - String samsungwarning = String.format("Warning Samsung Android 5.0+ devices ignore DNS servers outside the VPN range. To enable DNS add a custom route to your DNS Server (%s) or change to a DNS inside your VPN range", mDnslist.get(0)); - VpnStatus.logWarning(samsungwarning); - } - } catch (Exception e) { - VpnStatus.logError("Error parsing DNS Server IP: " + mDnslist.get(0)); - } - } + if (mDomain != null) @@ -672,12 +716,14 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void setAllowedVpnPackages(Builder builder) { + boolean atLeastOneAllowedApp=false; for (String pkg : mProfile.mAllowedAppsVpn) { try { if (mProfile.mAllowedAppsVpnAreDisallowed) { builder.addDisallowedApplication(pkg); } else { builder.addAllowedApplication(pkg); + atLeastOneAllowedApp = true; } } catch (PackageManager.NameNotFoundException e) { mProfile.mAllowedAppsVpn.remove(pkg); @@ -685,6 +731,15 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } } + if (!mProfile.mAllowedAppsVpnAreDisallowed && !atLeastOneAllowedApp) { + VpnStatus.logDebug(R.string.no_allowed_app, getPackageName()); + try { + builder.addAllowedApplication(getPackageName()); + } catch (PackageManager.NameNotFoundException e) { + VpnStatus.logError("This should not happen: " + e.getLocalizedMessage()); + } + } + if (mProfile.mAllowedAppsVpnAreDisallowed) { VpnStatus.logDebug(R.string.disallowed_vpn_apps_info, TextUtils.join(", ", mProfile.mAllowedAppsVpn)); } else { @@ -839,7 +894,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } else if (level == LEVEL_CONNECTED) { mDisplayBytecount = true; mConnecttime = System.currentTimeMillis(); - lowpriority = true; + if (!runningOnAndroidTV()) + lowpriority = true; + String ns = Context.NOTIFICATION_SERVICE; NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); mNotificationManager.cancel(OPENVPN_STATUS); @@ -852,7 +909,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // CONNECTED // Does not work :( String msg = getString(resid); - // showNotification(msg + " " + logmessage, msg, lowpriority, 0, level); + // showNotification(VpnStatus.getLastCleanLogMessage(this), + // msg, lowpriority, 0, level); } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java index d856feb7..10bc9e87 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 1c3b3362..4c550f47 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -1,23 +1,20 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; import android.content.Context; -import android.content.SharedPreferences; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; -import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import android.util.Log; import junit.framework.Assert; -import org.jetbrains.annotations.NotNull; - import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; @@ -42,30 +39,23 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { private LocalSocket mSocket; private VpnProfile mProfile; private OpenVPNService mOpenVPNService; - private LinkedList mFDList = new LinkedList(); + private LinkedList mFDList = new LinkedList<>(); private LocalServerSocket mServerSocket; - private boolean mReleaseHold = true; private boolean mWaitingForRelease = false; private long mLastHoldRelease = 0; - private static final Vector active = new Vector(); + private static final Vector active = new Vector<>(); private LocalSocket mServerSocketLocal; private pauseReason lastPauseReason = pauseReason.noNetwork; + private PausedStateCallback mPauseCallback; public OpenVpnManagementThread(VpnProfile profile, OpenVPNService openVpnService) { mProfile = profile; mOpenVPNService = openVpnService; - - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService); - boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true); - if (managemeNetworkState) - mReleaseHold = false; - } - public boolean openManagementInterface(@NotNull Context c) { + public boolean openManagementInterface(@NonNull Context c) { // Could take a while to open connection int tries = 8; @@ -74,7 +64,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { mServerSocketLocal = new LocalSocket(); - while (tries > 0 && !mServerSocketLocal.isConnected()) { + while (tries > 0 && !mServerSocketLocal.isBound()) { try { mServerSocketLocal.bind(new LocalSocketAddress(socketName, LocalSocketAddress.Namespace.FILESYSTEM)); @@ -82,7 +72,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { // wait 300 ms before retrying try { Thread.sleep(300); - } catch (InterruptedException e1) { + } catch (InterruptedException ignored) { } } @@ -167,7 +157,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //! Hack O Rama 2000! private void protectFileDescriptor(FileDescriptor fd) { - Exception exp; try { Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$"); int fdint = (Integer) getInt.invoke(fd); @@ -183,20 +172,12 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //pfd.close(); NativeUtils.jniclose(fdint); return; - } catch (NoSuchMethodException e) { - exp = e; - } catch (IllegalArgumentException e) { - exp = e; - } catch (IllegalAccessException e) { - exp = e; - } catch (InvocationTargetException e) { - exp = e; - } catch (NullPointerException e) { - exp = e; + } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException | NullPointerException e) { + VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", e); } Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd); - VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", exp); + } private String processInput(String pendingInput) { @@ -225,31 +206,41 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { String argument = parts[1]; - if (cmd.equals("INFO")) { + switch (cmd) { + case "INFO": /* Ignore greeting from management */ - return; - } else if (cmd.equals("PASSWORD")) { - processPWCommand(argument); - } else if (cmd.equals("HOLD")) { - handleHold(); - } else if (cmd.equals("NEED-OK")) { - processNeedCommand(argument); - } else if (cmd.equals("BYTECOUNT")) { - processByteCount(argument); - } else if (cmd.equals("STATE")) { - processState(argument); - } else if (cmd.equals("PROXY")) { - processProxyCMD(argument); - } else if (cmd.equals("LOG")) { - processLogMessage(argument); - } else if (cmd.equals("RSA_SIGN")) { - processSignCommand(argument); - } else { - VpnStatus.logWarning("MGMT: Got unrecognized command" + command); - Log.i(TAG, "Got unrecognized command" + command); + return; + case "PASSWORD": + processPWCommand(argument); + break; + case "HOLD": + handleHold(); + break; + case "NEED-OK": + processNeedCommand(argument); + break; + case "BYTECOUNT": + processByteCount(argument); + break; + case "STATE": + processState(argument); + break; + case "PROXY": + processProxyCMD(argument); + break; + case "LOG": + processLogMessage(argument); + break; + case "RSA_SIGN": + processSignCommand(argument); + break; + default: + VpnStatus.logWarning("MGMT: Got unrecognized command" + command); + Log.i(TAG, "Got unrecognized command" + command); + break; } } else if (command.startsWith("SUCCESS:")) { - /* Ignore this kind of message too */ + /* Ignore this kind of message too */ return; } else if (command.startsWith("PROTECTFD: ")) { FileDescriptor fdtoprotect = mFDList.pollFirst(); @@ -278,16 +269,22 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { Log.d("OpenVPN", argument); VpnStatus.LogLevel level; - if (args[1].equals("I")) { - level = VpnStatus.LogLevel.INFO; - } else if (args[1].equals("W")) { - level = VpnStatus.LogLevel.WARNING; - } else if (args[1].equals("D")) { - level = VpnStatus.LogLevel.VERBOSE; - } else if (args[1].equals("F")) { - level = VpnStatus.LogLevel.ERROR; - } else { - level = VpnStatus.LogLevel.INFO; + switch (args[1]) { + case "I": + level = VpnStatus.LogLevel.INFO; + break; + case "W": + level = VpnStatus.LogLevel.WARNING; + break; + case "D": + level = VpnStatus.LogLevel.VERBOSE; + break; + case "F": + level = VpnStatus.LogLevel.ERROR; + break; + default: + level = VpnStatus.LogLevel.INFO; + break; } int ovpnlevel = Integer.parseInt(args[2]) & 0x0F; @@ -299,8 +296,15 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { VpnStatus.logMessageOpenVPN(level, ovpnlevel, msg); } + boolean shouldBeRunning() { + if (mPauseCallback == null) + return false; + else + return mPauseCallback.shouldBeRunning(); + } + private void handleHold() { - if (mReleaseHold) { + if (shouldBeRunning()) { releaseHoldCmd(); } else { mWaitingForRelease = true; @@ -327,11 +331,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //managmentCommand("log on all\n"); } + public void releaseHold() { - mReleaseHold = true; if (mWaitingForRelease) releaseHoldCmd(); - } private void processProxyCMD(String argument) { @@ -391,15 +394,19 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { String status = "ok"; - if (needed.equals("PROTECTFD")) { - FileDescriptor fdtoprotect = mFDList.pollFirst(); - protectFileDescriptor(fdtoprotect); - } else if (needed.equals("DNSSERVER")) { - mOpenVPNService.addDNS(extra); - } else if (needed.equals("DNSDOMAIN")) { - mOpenVPNService.setDomain(extra); - } else if (needed.equals("ROUTE")) { - String[] routeparts = extra.split(" "); + switch (needed) { + case "PROTECTFD": + FileDescriptor fdtoprotect = mFDList.pollFirst(); + protectFileDescriptor(fdtoprotect); + break; + case "DNSSERVER": + mOpenVPNService.addDNS(extra); + break; + case "DNSDOMAIN": + mOpenVPNService.setDomain(extra); + break; + case "ROUTE": { + String[] routeparts = extra.split(" "); /* buf_printf (&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface); @@ -407,38 +414,46 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { buf_printf (&out, "%s %s %s", network, netmask, gateway); */ - if (routeparts.length == 5) { - if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]); - mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]); - } else if (routeparts.length >= 3) { - mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null); - } else { - VpnStatus.logError("Unrecognized ROUTE cmd:" + Arrays.toString(routeparts) + " | " + argument); + if (routeparts.length == 5) { + if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]); + mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]); + } else if (routeparts.length >= 3) { + mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null); + } else { + VpnStatus.logError("Unrecognized ROUTE cmd:" + Arrays.toString(routeparts) + " | " + argument); + } + + break; } + case "ROUTE6": { + String[] routeparts = extra.split(" "); + mOpenVPNService.addRoutev6(routeparts[0], routeparts[1]); + break; + } + case "IFCONFIG": + String[] ifconfigparts = extra.split(" "); + int mtu = Integer.parseInt(ifconfigparts[2]); + mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1], mtu, ifconfigparts[3]); + break; + case "IFCONFIG6": + mOpenVPNService.setLocalIPv6(extra); + + break; + case "PERSIST_TUN_ACTION": + // check if tun cfg stayed the same + status = mOpenVPNService.getTunReopenStatus(); + break; + case "OPENTUN": + if (sendTunFD(needed, extra)) + return; + else + status = "cancel"; + // This not nice or anything but setFileDescriptors accepts only FilDescriptor class :( - } else if (needed.equals("ROUTE6")) { - String[] routeparts = extra.split(" "); - mOpenVPNService.addRoutev6(routeparts[0], routeparts[1]); - } else if (needed.equals("IFCONFIG")) { - String[] ifconfigparts = extra.split(" "); - int mtu = Integer.parseInt(ifconfigparts[2]); - mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1], mtu, ifconfigparts[3]); - } else if (needed.equals("IFCONFIG6")) { - mOpenVPNService.setLocalIPv6(extra); - - } else if (needed.equals("PERSIST_TUN_ACTION")) { - // check if tun cfg stayed the same - status = mOpenVPNService.getTunReopenStatus(); - } else if (needed.equals("OPENTUN")) { - if (sendTunFD(needed, extra)) + break; + default: + Log.e(TAG, "Unkown needok command " + argument); return; - else - status = "cancel"; - // This not nice or anything but setFileDescriptors accepts only FilDescriptor class :( - - } else { - Log.e(TAG, "Unkown needok command " + argument); - return; } String cmd = String.format("needok '%s' %s\n", needed, status); @@ -446,7 +461,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } private boolean sendTunFD(String needed, String extra) { - Exception exp; if (!extra.equals("tun")) { // We only support tun VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra)); @@ -480,18 +494,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { pfd.close(); return true; - } catch (NoSuchMethodException e) { - exp = e; - } catch (IllegalArgumentException e) { - exp = e; - } catch (IllegalAccessException e) { - exp = e; - } catch (InvocationTargetException e) { - exp = e; - } catch (IOException e) { - exp = e; + } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | + IOException | IllegalAccessException exp) { + VpnStatus.logException("Could not send fd over socket", exp); } - VpnStatus.logException("Could not send fd over socket", exp); return false; } @@ -559,14 +565,21 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } @Override - public void networkChange() { - if (!mWaitingForRelease) + public void networkChange(boolean samenetwork) { + if (mWaitingForRelease) + releaseHold(); + else if (samenetwork) + managmentCommand("network-change samenetwork\n"); + else managmentCommand("network-change\n"); } - public void signalusr1() { - mReleaseHold = false; + @Override + public void setPauseCallback(PausedStateCallback callback) { + mPauseCallback = callback; + } + public void signalusr1() { if (!mWaitingForRelease) managmentCommand("signal SIGUSR1\n"); else diff --git a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java index a788426a..49a7eaa9 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java +++ b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java index 086cdb44..4f9c219b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -128,6 +128,11 @@ public class ProfileManager { ProfileManager.tmpprofile = tmp; } + public static boolean isTempProfile() + { + return mLastConnectedVpn == tmpprofile; + } + public void saveProfile(Context context, VpnProfile profile) { ObjectOutputStream vpnfile; diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java index 6e2abb13..34fb69f8 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java index 47cb633c..f2cf8cec 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -14,14 +14,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.Vector; import se.leap.bitmaskclient.R; import de.blinkt.openvpn.VpnProfile; public class VPNLaunchHelper { - private static final String MININONPIEVPN = "nopievpn"; - private static final String MINIPIEVPN = "pievpn"; + private static final String MININONPIEVPN = "nopie_openvpn"; + private static final String MINIPIEVPN = "pie_openvpn"; private static final String OVPNCONFIGFILE = "android.conf"; @@ -29,15 +30,22 @@ public class VPNLaunchHelper { static private String writeMiniVPN(Context context) { String[] abis; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - abis = getSupportedAbisLollipop(); + abis = getSupportedABIsLollipop(); else + //noinspection deprecation abis = new String[]{Build.CPU_ABI, Build.CPU_ABI2}; + String nativeAPI = NativeUtils.getNativeAPI(); + if (!nativeAPI.equals(abis[0])) { + VpnStatus.logWarning(R.string.abi_mismatch, Arrays.toString(abis), nativeAPI); + abis = new String[] {nativeAPI}; + } + for (String abi: abis) { - File mvpnout = new File(context.getCacheDir(), getMiniVPNExecutableName() + "." + abi); - if ((mvpnout.exists() && mvpnout.canExecute()) || writeMiniVPNBinary(context, abi, mvpnout)) { - return mvpnout.getPath(); + File vpnExecutable = new File(context.getCacheDir(), getMiniVPNExecutableName() + "." + abi); + if ((vpnExecutable.exists() && vpnExecutable.canExecute()) || writeMiniVPNBinary(context, abi, vpnExecutable)) { + return vpnExecutable.getPath(); } } @@ -45,7 +53,7 @@ public class VPNLaunchHelper { } @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private static String[] getSupportedAbisLollipop() { + private static String[] getSupportedABIsLollipop() { return Build.SUPPORTED_ABIS; } @@ -118,12 +126,13 @@ public class VPNLaunchHelper { public static void startOpenVpn(VpnProfile startprofile, Context context) { - if(writeMiniVPN(context)==null) { + VpnStatus.logInfo(R.string.building_configration); + VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, VpnStatus.ConnectionStatus.LEVEL_START); + if(writeMiniVPN(context)==null) { VpnStatus.logError("Error writing minivpn binary"); return; } - VpnStatus.logInfo(R.string.building_configration); Intent startVPN = startprofile.prepareStartService(context); if(startVPN!=null) diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index 62a60643..3ac1595c 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -1,18 +1,19 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; import android.annotation.SuppressLint; -import android.app.Activity; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.os.Build; +import android.os.HandlerThread; +import android.os.Message; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -74,6 +75,58 @@ public class VpnStatus { private static final int MAXLOGENTRIES = 1000; + + public static String getLastCleanLogMessage(Context c) { + String message = mLaststatemsg; + switch (mLastLevel) { + case LEVEL_CONNECTED: + String[] parts = mLaststatemsg.split(","); + /* + (a) the integer unix date/time, + (b) the state name, + 0 (c) optional descriptive string (used mostly on RECONNECTING + and EXITING to show the reason for the disconnect), + + 1 (d) optional TUN/TAP local IPv4 address + 2 (e) optional address of remote server, + 3 (f) optional port of remote server, + 4 (g) optional local address, + 5 (h) optional local port, and + 6 (i) optional TUN/TAP local IPv6 address. +*/ + // Return only the assigned IP addresses in the UI + if (parts.length >= 7) + message = String.format(Locale.US, "%s %s", parts[1], parts[6]); + break; + } + + while (message.endsWith(",")) + message = message.substring(0, message.length() - 1); + + String status = mLaststate; + if (status.equals("NOPROCESS")) + return message; + + String prefix = c.getString(mLastStateresid); + if (mLastStateresid == R.string.unknown_state) + message = status + message; + if (message.length() > 0) + prefix += ": "; + + return prefix + message; + + } + + public static void initLogCache(File cacheDir) { + Message m = mLogFileHandler.obtainMessage(LogFileHandler.LOG_INIT, cacheDir); + mLogFileHandler.sendMessage(m); + + } + + public static void flushLog() { + mLogFileHandler.sendEmptyMessage(LogFileHandler.FLUSH_TO_DISK); + } + public enum ConnectionStatus { LEVEL_CONNECTED, LEVEL_VPNPAUSED, @@ -81,6 +134,7 @@ public class VpnStatus { LEVEL_CONNECTING_NO_SERVER_REPLY_YET, LEVEL_NONETWORK, LEVEL_NOTCONNECTED, + LEVEL_START, LEVEL_AUTH_FAILED, LEVEL_WAITING_FOR_USER_INPUT, UNKNOWN_LEVEL @@ -128,18 +182,24 @@ public class VpnStatus { private static ConnectionStatus mLastLevel = ConnectionStatus.LEVEL_NOTCONNECTED; + private static final LogFileHandler mLogFileHandler; + static { logbuffer = new LinkedList<>(); logListener = new Vector<>(); stateListener = new Vector<>(); byteCountListener = new Vector<>(); + + HandlerThread mHandlerThread = new HandlerThread("LogFileWriter", Thread.MIN_PRIORITY); + mHandlerThread.start(); + mLogFileHandler = new LogFileHandler(mHandlerThread.getLooper()); + logInformation(); + } public static class LogItem implements Parcelable { - - private Object[] mArgs = null; private String mMessage = null; private int mRessourceId; @@ -261,6 +321,7 @@ public class VpnStatus { String version = "error getting version"; try { + @SuppressLint("PackageManagerGetSignatures") Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0]; CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray())); @@ -287,11 +348,11 @@ public class VpnStatus { NoSuchAlgorithmException ignored) { } - Object[] argsext = Arrays.copyOf(mArgs, mArgs.length + 2); + Object[] argsext = Arrays.copyOf(mArgs, mArgs.length); argsext[argsext.length - 1] = apksign; argsext[argsext.length - 2] = version; - return c.getString(R.string.mobile_info_extended, argsext); + return c.getString(R.string.mobile_info, argsext); } @@ -310,12 +371,6 @@ public class VpnStatus { } } - public void saveLogToDisk(Context c) { - - File logOut = new File(c.getCacheDir(), "log.xml"); - - } - public interface LogListener { void newLog(LogItem logItem); } @@ -336,10 +391,12 @@ public class VpnStatus { public synchronized static void clearLog() { logbuffer.clear(); logInformation(); + mLogFileHandler.sendEmptyMessage(LogFileHandler.TRIM_LOG_FILE); } private static void logInformation() { - logInfo(R.string.mobile_info, Build.MODEL, Build.BOARD, Build.BRAND, Build.VERSION.SDK_INT); + logInfo(R.string.mobile_info, Build.MODEL, Build.BOARD, Build.BRAND, Build.VERSION.SDK_INT, + NativeUtils.getNativeAPI(), Build.VERSION.RELEASE, Build.ID, Build.FINGERPRINT, "", ""); } public synchronized static void addLogListener(LogListener ll) { @@ -369,32 +426,34 @@ public class VpnStatus { } private static int getLocalizedState(String state) { - if (state.equals("CONNECTING")) - return R.string.state_connecting; - else if (state.equals("WAIT")) - return R.string.state_wait; - else if (state.equals("AUTH")) - return R.string.state_auth; - else if (state.equals("GET_CONFIG")) - return R.string.state_get_config; - else if (state.equals("ASSIGN_IP")) - return R.string.state_assign_ip; - else if (state.equals("ADD_ROUTES")) - return R.string.state_add_routes; - else if (state.equals("CONNECTED")) - return R.string.state_connected; - else if (state.equals("DISCONNECTED")) - return R.string.state_disconnected; - else if (state.equals("RECONNECTING")) - return R.string.state_reconnecting; - else if (state.equals("EXITING")) - return R.string.state_exiting; - else if (state.equals("RESOLVE")) - return R.string.state_resolve; - else if (state.equals("TCP_CONNECT")) - return R.string.state_tcp_connect; - else - return R.string.unknown_state; + switch (state) { + case "CONNECTING": + return R.string.state_connecting; + case "WAIT": + return R.string.state_wait; + case "AUTH": + return R.string.state_auth; + case "GET_CONFIG": + return R.string.state_get_config; + case "ASSIGN_IP": + return R.string.state_assign_ip; + case "ADD_ROUTES": + return R.string.state_add_routes; + case "CONNECTED": + return R.string.state_connected; + case "DISCONNECTED": + return R.string.state_disconnected; + case "RECONNECTING": + return R.string.state_reconnecting; + case "EXITING": + return R.string.state_exiting; + case "RESOLVE": + return R.string.state_resolve; + case "TCP_CONNECT": + return R.string.state_tcp_connect; + default: + return R.string.unknown_state; + } } @@ -496,17 +555,33 @@ public class VpnStatus { newLogItem(new LogItem(LogLevel.DEBUG, resourceId, args)); } + private static void newLogItem(LogItem logItem) { + newLogItem(logItem, false); + } + + + synchronized static void newLogItem(LogItem logItem, boolean cachedLine) { + if (cachedLine) { + logbuffer.addFirst(logItem); + } else { + logbuffer.addLast(logItem); + Message m = mLogFileHandler.obtainMessage(LogFileHandler.LOG_MESSAGE, logItem); + mLogFileHandler.sendMessage(m); + } + + if (logbuffer.size() > MAXLOGENTRIES + MAXLOGENTRIES / 2) { + while (logbuffer.size() > MAXLOGENTRIES) + logbuffer.removeFirst(); + mLogFileHandler.sendMessage(mLogFileHandler.obtainMessage(LogFileHandler.TRIM_LOG_FILE)); + } - private synchronized static void newLogItem(LogItem logItem) { - logbuffer.addLast(logItem); - if (logbuffer.size() > MAXLOGENTRIES) - logbuffer.removeFirst(); for (LogListener ll : logListener) { ll.newLog(logItem); } } + public static void logError(String msg) { newLogItem(new LogItem(LogLevel.ERROR, msg)); diff --git a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java index 0786967b..4048f0e0 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java @@ -1,11 +1,12 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; import android.content.Context; +import android.content.res.Resources; import android.text.TextUtils; import se.leap.bitmaskclient.R; @@ -20,30 +21,39 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; +import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Date; import java.util.Hashtable; +import java.util.Vector; public class X509Utils { - public static Certificate getCertificateFromFile(String certfilename) throws FileNotFoundException, CertificateException { + public static Certificate[] getCertificatesFromFile(String certfilename) throws FileNotFoundException, CertificateException { CertificateFactory certFact = CertificateFactory.getInstance("X.509"); - InputStream inStream; - + Vector certificates = new Vector<>(); if(VpnProfile.isEmbedded(certfilename)) { - // The java certifcate reader is ... kind of stupid - // It does NOT ignore chars before the --BEGIN ... int subIndex = certfilename.indexOf("-----BEGIN CERTIFICATE-----"); - subIndex = Math.max(0,subIndex); - inStream = new ByteArrayInputStream(certfilename.substring(subIndex).getBytes()); + do { + // The java certifcate reader is ... kind of stupid + // It does NOT ignore chars before the --BEGIN ... + subIndex = Math.max(0, subIndex); + InputStream inStream = new ByteArrayInputStream(certfilename.substring(subIndex).getBytes()); + certificates.add(certFact.generateCertificate(inStream)); + subIndex = certfilename.indexOf("-----BEGIN CERTIFICATE-----", subIndex+1); + } while (subIndex > 0); + return certificates.toArray(new Certificate[certificates.size()]); } else { - inStream = new FileInputStream(certfilename); + InputStream inStream = new FileInputStream(certfilename); + return new Certificate[] {certFact.generateCertificate(inStream)}; } - return certFact.generateCertificate(inStream); } public static PemObject readPemObjectFromFile (String keyfilename) throws IOException { @@ -67,9 +77,10 @@ public class X509Utils { public static String getCertificateFriendlyName (Context c, String filename) { if(!TextUtils.isEmpty(filename)) { try { - X509Certificate cert = (X509Certificate) getCertificateFromFile(filename); - - return getCertificateFriendlyName(cert); + X509Certificate cert = (X509Certificate) getCertificatesFromFile(filename)[0]; + String friendlycn = getCertificateFriendlyName(cert); + friendlycn = getCertificateValidityString(cert, c.getResources()) + friendlycn; + return friendlycn; } catch (Exception e) { VpnStatus.logError("Could not read certificate" + e.getLocalizedMessage()); @@ -78,6 +89,40 @@ public class X509Utils { return c.getString(R.string.cannotparsecert); } + public static String getCertificateValidityString(X509Certificate cert, Resources res) { + try { + cert.checkValidity(); + } catch (CertificateExpiredException ce) { + return "EXPIRED: "; + } catch (CertificateNotYetValidException cny) { + return "NOT YET VALID: "; + } + + Date certNotAfter = cert.getNotAfter(); + Date now = new Date(); + long timeLeft = certNotAfter.getTime() - now.getTime(); // Time left in ms + + // More than 72h left, display days + // More than 3 months display months + if (timeLeft > 90l* 24 * 3600 * 1000) { + long months = getMonthsDifference(now, certNotAfter); + return res.getString(R.string.months_left, months); + } else if (timeLeft > 72 * 3600 * 1000) { + long days = timeLeft / (24 * 3600 * 1000); + return res.getString(R.string.days_left, days); + } else { + long hours = timeLeft / (3600 * 1000); + + return res.getString(R.string.hours_left, hours); + } + } + + public static int getMonthsDifference(Date date1, Date date2) { + int m1 = date1.getYear() * 12 + date1.getMonth(); + int m2 = date2.getYear() * 12 + date2.getMonth(); + return m2 - m1 + 1; + } + public static String getCertificateFriendlyName(X509Certificate cert) { X500Principal principal = cert.getSubjectX500Principal(); byte[] encodedSubject = principal.getEncoded(); diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index 2a75c15e..f75e459e 100644 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -22,6 +22,9 @@ import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; +import android.preference.Preference; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; import android.text.SpannableString; import android.text.format.DateFormat; import android.text.style.ImageSpan; @@ -33,6 +36,8 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; @@ -41,8 +46,6 @@ import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; -import org.jetbrains.annotations.Nullable; - import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; @@ -67,11 +70,12 @@ import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; import se.leap.bitmaskclient.Dashboard; public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { - private static final String LOGTIMEFORMAT = "logtimeformat"; - private static final int START_VPN_CONFIG = 0; + private static final String LOGTIMEFORMAT = "logtimeformat"; + private static final int START_VPN_CONFIG = 0; private static final String VERBOSITYLEVEL = "verbositylevel"; + private SeekBar mLogLevelSlider; private LinearLayout mOptionsLayout; private RadioGroup mTimeRadioGroup; @@ -79,10 +83,11 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. private TextView mDownStatus; private TextView mConnectStatus; private boolean mShowOptionsLayout; + private CheckBox mClearLogCheckBox; @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - ladapter.setLogLevel(progress+1); + ladapter.setLogLevel(progress + 1); } @Override @@ -134,7 +139,7 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. private static final int MESSAGE_NEWLOG = 0; - private static final int MESSAGE_CLEARLOG = 1; + private static final int MESSAGE_CLEARLOG = 1; private static final int MESSAGE_NEWTS = 2; private static final int MESSAGE_NEWLOGLEVEL = 3; @@ -144,110 +149,109 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. public static final int TIME_FORMAT_ISO = 2; private static final int MAX_STORED_LOG_ENTRIES = 1000; - private Vector allEntries=new Vector(); + private Vector allEntries = new Vector<>(); - private Vector currentLevelEntries=new Vector(); + private Vector currentLevelEntries = new Vector(); - private Handler mHandler; + private Handler mHandler; - private Vector observers=new Vector(); + private Vector observers = new Vector(); - private int mTimeFormat=0; - private int mLogLevel=3; + private int mTimeFormat = 0; + private int mLogLevel = 3; public LogWindowListAdapter() { - initLogBuffer(); - if (mHandler == null) { - mHandler = new Handler(this); - } - - VpnStatus.addLogListener(this); - } + initLogBuffer(); + if (mHandler == null) { + mHandler = new Handler(this); + } + VpnStatus.addLogListener(this); + } - private void initLogBuffer() { - allEntries.clear(); + private void initLogBuffer() { + allEntries.clear(); Collections.addAll(allEntries, VpnStatus.getlogbuffer()); initCurrentMessages(); - } - - String getLogStr() { - String str = ""; - for(LogItem entry:allEntries) { - str+=getTime(entry, TIME_FORMAT_ISO) + entry.getString(getActivity()) + '\n'; - } - return str; - } - - - private void shareLog() { - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr()); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.ics_openvpn_log_file)); - shareIntent.setType("text/plain"); - startActivity(Intent.createChooser(shareIntent, "Send Logfile")); - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - observers.add(observer); - - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - observers.remove(observer); - } - - @Override - public int getCount() { - return currentLevelEntries.size(); - } - - @Override - public Object getItem(int position) { - return currentLevelEntries.get(position); - } - - @Override - public long getItemId(int position) { - return ((Object)currentLevelEntries.get(position)).hashCode(); - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - TextView v; - if(convertView==null) - v = new TextView(getActivity()); - else - v = (TextView) convertView; - - LogItem le = currentLevelEntries.get(position); - String msg = le.getString(getActivity()); + } + + String getLogStr() { + String str = ""; + for (LogItem entry : allEntries) { + str += getTime(entry, TIME_FORMAT_ISO) + entry.getString(getActivity()) + '\n'; + } + return str; + } + + + private void shareLog() { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr()); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.ics_openvpn_log_file)); + shareIntent.setType("text/plain"); + startActivity(Intent.createChooser(shareIntent, "Send Logfile")); + } + + @Override + public void registerDataSetObserver(DataSetObserver observer) { + observers.add(observer); + + } + + @Override + public void unregisterDataSetObserver(DataSetObserver observer) { + observers.remove(observer); + } + + @Override + public int getCount() { + return currentLevelEntries.size(); + } + + @Override + public Object getItem(int position) { + return currentLevelEntries.get(position); + } + + @Override + public long getItemId(int position) { + return ((Object) currentLevelEntries.get(position)).hashCode(); + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView v; + if (convertView == null) + v = new TextView(getActivity()); + else + v = (TextView) convertView; + + LogItem le = currentLevelEntries.get(position); + String msg = le.getString(getActivity()); String time = getTime(le, mTimeFormat); - msg = time + msg; + msg = time + msg; int spanStart = time.length(); SpannableString t = new SpannableString(msg); //t.setSpan(getSpanImage(le,(int)v.getTextSize()),spanStart,spanStart+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - v.setText(t); - return v; - } + v.setText(t); + return v; + } private String getTime(LogItem le, int time) { if (time != TIME_FORMAT_NONE) { Date d = new Date(le.getLogtime()); java.text.DateFormat timeformat; - if (time== TIME_FORMAT_ISO) + if (time == TIME_FORMAT_ISO) timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); else timeformat = DateFormat.getTimeFormat(getActivity()); @@ -289,49 +293,49 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. } @Override - public int getItemViewType(int position) { - return 0; - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public boolean isEmpty() { - return currentLevelEntries.isEmpty(); - - } - - @Override - public boolean areAllItemsEnabled() { - return true; - } - - @Override - public boolean isEnabled(int position) { - return true; - } - - @Override - public void newLog(LogItem logMessage) { - Message msg = Message.obtain(); - assert (msg!=null); - msg.what=MESSAGE_NEWLOG; - Bundle bundle=new Bundle(); - bundle.putParcelable("logmessage", logMessage); - msg.setData(bundle); - mHandler.sendMessage(msg); - } - - @Override - public boolean handleMessage(Message msg) { - // We have been called - if(msg.what==MESSAGE_NEWLOG) { - - LogItem logMessage = msg.getData().getParcelable("logmessage"); - if(addLogMessage(logMessage)) + public int getItemViewType(int position) { + return 0; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public boolean isEmpty() { + return currentLevelEntries.isEmpty(); + + } + + @Override + public boolean areAllItemsEnabled() { + return true; + } + + @Override + public boolean isEnabled(int position) { + return true; + } + + @Override + public void newLog(LogItem logMessage) { + Message msg = Message.obtain(); + assert (msg != null); + msg.what = MESSAGE_NEWLOG; + Bundle bundle = new Bundle(); + bundle.putParcelable("logmessage", logMessage); + msg.setData(bundle); + mHandler.sendMessage(msg); + } + + @Override + public boolean handleMessage(Message msg) { + // We have been called + if (msg.what == MESSAGE_NEWLOG) { + + LogItem logMessage = msg.getData().getParcelable("logmessage"); + if (addLogMessage(logMessage)) for (DataSetObserver observer : observers) { observer.onChanged(); } @@ -340,25 +344,25 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. observer.onInvalidated(); } initLogBuffer(); - } else if (msg.what == MESSAGE_NEWTS) { - for (DataSetObserver observer : observers) { - observer.onInvalidated(); - } - } else if (msg.what == MESSAGE_NEWLOGLEVEL) { + } else if (msg.what == MESSAGE_NEWTS) { + for (DataSetObserver observer : observers) { + observer.onInvalidated(); + } + } else if (msg.what == MESSAGE_NEWLOGLEVEL) { initCurrentMessages(); - for (DataSetObserver observer: observers) { + for (DataSetObserver observer : observers) { observer.onChanged(); } } - return true; - } + return true; + } private void initCurrentMessages() { currentLevelEntries.clear(); - for(LogItem li: allEntries) { + for (LogItem li : allEntries) { if (li.getVerbosityLevel() <= mLogLevel || mLogLevel == VpnProfile.MAXLOGLEVEL) currentLevelEntries.add(li); @@ -366,7 +370,6 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. } /** - * * @param logmessage * @return True if the current entries have changed */ @@ -376,7 +379,7 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. if (allEntries.size() > MAX_STORED_LOG_ENTRIES) { Vector oldAllEntries = allEntries; allEntries = new Vector(allEntries.size()); - for (int i=50;i diff --git a/app/src/main/res/layout-sw600dp-port/log_fragment.xml b/app/src/main/res/layout-sw600dp-port/log_fragment.xml index 1fb9fa54..7a4b60fe 100644 --- a/app/src/main/res/layout-sw600dp-port/log_fragment.xml +++ b/app/src/main/res/layout-sw600dp-port/log_fragment.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/layout-sw600dp/log_fragment.xml b/app/src/main/res/layout-sw600dp/log_fragment.xml index 0bd3f991..26f63df4 100644 --- a/app/src/main/res/layout-sw600dp/log_fragment.xml +++ b/app/src/main/res/layout-sw600dp/log_fragment.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/layout/log_fragment.xml b/app/src/main/res/layout/log_fragment.xml index 491882a9..ab070117 100644 --- a/app/src/main/res/layout/log_fragment.xml +++ b/app/src/main/res/layout/log_fragment.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/layout/log_silders.xml b/app/src/main/res/layout/log_silders.xml index 152407f9..4196e243 100644 --- a/app/src/main/res/layout/log_silders.xml +++ b/app/src/main/res/layout/log_silders.xml @@ -2,7 +2,7 @@ @@ -63,4 +63,11 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/log_window.xml b/app/src/main/res/layout/log_window.xml index fcc7aa7a..7c25dcfa 100644 --- a/app/src/main/res/layout/log_window.xml +++ b/app/src/main/res/layout/log_window.xml @@ -1,5 +1,5 @@ diff --git a/app/src/main/res/layout/vpnstatus.xml b/app/src/main/res/layout/vpnstatus.xml index 2d77bbab..b304ad10 100644 --- a/app/src/main/res/layout/vpnstatus.xml +++ b/app/src/main/res/layout/vpnstatus.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/menu/logmenu.xml b/app/src/main/res/menu/logmenu.xml index 2df53141..890d1c2e 100644 --- a/app/src/main/res/menu/logmenu.xml +++ b/app/src/main/res/menu/logmenu.xml @@ -1,6 +1,6 @@ @@ -11,34 +11,33 @@ android:id="@+id/toggle_time" android:alphabeticShortcut="t" android:icon="@drawable/ic_menu_view" - android:showAsAction="withText|ifRoom" + android:showAsAction="ifRoom" android:title="@string/logview_options" /> - diff --git a/app/src/main/res/values-cs/strings-icsopenvpn.xml b/app/src/main/res/values-cs/strings-icsopenvpn.xml index 12837f13..c2b47b77 100755 --- a/app/src/main/res/values-cs/strings-icsopenvpn.xml +++ b/app/src/main/res/values-cs/strings-icsopenvpn.xml @@ -180,7 +180,6 @@ Žádný CA certifikát nebyl získán z úložiště, autentikace pravděpodobně selže. Zobrazit okno s logem při připojování. okno lze vždy otevřít z notifikace. Zobrazit okno s logem - Spuštěno na %1$s (%2$s) %3$s, Android API %4$d Chyba při podepisování klíčem %1$s: %2$s VPN varování při připojování oznamující o možnosti přesměrování veškerého provozu je vynuceno systémem, aby se zabránilo zneužití VPNService API.\nNotifikace (symbol s klíčem) je také vynucena systémem, aby signalizovala odchozí VPN spojení. Na některých systémech přehrává notifikace i zvuk.\nAndroid zavedl tyto dialogy pro tvoji osobní bezpečnost a ujistil se, že nejdou obejít. (Někdu to bohužel zahrnuje i zvuk notifikace.) Varování při připojení a zvuková notifikace @@ -260,7 +259,6 @@ Šifrovací algoritmus Ověřování paketů Zadej způsob ověřování paketů - Běží na %1$s (%2$s) %3$s, Android API %4$d, verze %5$s, %6$s sestaveno od %s ladící verze oficiální verze diff --git a/app/src/main/res/values-de/strings-icsopenvpn.xml b/app/src/main/res/values-de/strings-icsopenvpn.xml index bb22c373..c1b3f10a 100755 --- a/app/src/main/res/values-de/strings-icsopenvpn.xml +++ b/app/src/main/res/values-de/strings-icsopenvpn.xml @@ -149,7 +149,7 @@ Kein lokales Binden Importiere Konfigurationsdatei Bemerkungen zur Sicherheit - Da OpenVPN sicherheitsrelevant ist, sind einige Worte zur Sicherheit der Anwendung angebracht. Alle Daten, die sich auf der SD Karte befinden sind als absolut unsicher anzusehen. Jede Anwendung kann diese lesen. (Diese Anwendung braucht zum Beispiel keine SD Karten Berechtigung). Die restlichen Konfiguration dieser Anwendung kann nur von der Anwendung selbst gelesen werden. Wenn die Option genutzt wird, dass die Zertifikate und Schlüssel eingebettet werden, werden diese im VPN Profil gespeichert. Die VPN Profile sind nur von der Anwendung selbst lesbar. (Vergessen Sie nicht die ursprünglichen Zertifikate/Schlüssel von der SD Karte zu löschen). Die Daten die Anwendung selbst speichert sind unverschlüsselt. Es besteht die Möglichkeit diese mittels \"rooten\" des Telefons/Tablets oder anderen Schwachstellend diese Daten auszulesen. Gespeicherte Passwörter werden auch im Klartext gespeichert. Es wird dringend empfohlen die Zertifikate in dem Android Keystore zu speichern.\" + Da OpenVPN sicherheitsrelevant ist, sind einige Worte zur Sicherheit der Anwendung angebracht. Alle Daten, die sich auf der SD Karte befinden sind als absolut unsicher anzusehen. Jede Anwendung kann diese lesen. (Diese Anwendung braucht zum Beispiel keine SD Karten Berechtigung). Die restlichen Konfiguration dieser Anwendung kann nur von der Anwendung selbst gelesen werden. Wenn die Option genutzt wird, dass die Zertifikate und Schlüssel eingebettet werden, werden diese im VPN Profil gespeichert. Die VPN Profile sind nur von der Anwendung selbst lesbar. (Vergessen Sie nicht die ursprünglichen Zertifikate/Schlüssel von der SD Karte zu löschen). Die Daten die Anwendung selbst speichert sind unverschlüsselt. Es besteht die Möglichkeit diese mittels \"rooten\" des Telefons/Tablets oder anderen Schwachstellen diese Daten auszulesen. Gespeicherte Passwörter werden auch im Klartext gespeichert. Es wird dringend empfohlen die Zertifikate in dem Android Keystore zu speichern.\" Importieren Fehler beim Anzeigen des Zertifikatsauswahlbildschirmes Android hat einen Fehler beim Anzeigen des Zertifikat Dialog gemeldet. Dies sollte nie passieren, da dies ein Standard Feature von Android 4.0+ ist. Eventuell ist Unterstützung von Zertifikaten in Ihrer Firmware fehlerhaft @@ -180,7 +180,7 @@ Beim Abfragen des Android KeyStore wurde kein CA Zertifikat zurückgegeben. Überprüfen des Serverzertifikat wird wahrscheinlich fehlschlagen. Geben Sie manuell ein CA Zertifikat an. Zeigt das Status Log, wenn ein VPN verbunden wird. Das Status log kann immer über die Benachrichtigung aufgerufen werden. Zeige Log - Modell %1$s (%2$s) %3$s, Android API %4$d + %10$s %9$s läuft auf %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) Fehler beim Zugriff auf den Android Keystore %1$s: %2$s Die Meldung, dass OpenVPN versucht eine VPN-Verbindung aufzubauen und dabei den gesamten Netzwerkverkehr abhören kann, wird vom Android System selbst erzeugt. Diese wird vom System erzwungen, damit keine Anwendung vom Benutzer unbemerkt eine VPN Verbindung aufbauen kann\Die VPN Benachrichtigung (Das Schlüssel Symbol) wird genauso vom Android System angezeigt um eine bestehende VPN anzuzeigen.\nDiese beiden Features wurden in Android für die Sicherheit des Nutzers implementiert und können nicht umgangen werden. (Auf machen Telefon/Tablets wird die Benachrichtigung leider mit einem Ton signalisiert.) Warnung beim Verbinden und Benachrichtigungston @@ -260,7 +260,6 @@ Verschlüsselungsalgorithmus Packetauthentifizierung Geben Sie den Authentifizierungsalgorithmus an - Modell %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s compiliert von %s Testversion offizielle Version @@ -350,7 +349,7 @@ VPN Profil duplizieren VPN Profil duplizieren: %s Log anzeigen - Es gibt es mehrere OpenVPN-Clients für Android. Die am häufigsten genutzten sind OpenVPN für Android (dieser Client), OpenVPN Connect und OpenVPN Settings. <p> Die Clients in zwei Gruppen eingeteilt werden können: OpenVPN für Android und OpenVPN Connect verwenden die offizielle VPNService-API (Android 4.0+) und erfordern keine Rootrechte und OpenVPN-Settings, das Rootrechte benötigt. < p > OpenVPN für Android ist ein von Arne Schwabe entwickelter Open-Source-Client. Es richtet sich an fortgeschrittene Benutzer und bietet viele erweiterete Einstellungen sowie die Möglichkeit, Profile aus Dateien zu importieren und das konfigurieren und ändern von Profilen innerhalb der App. Der Client basiert auf der Community-Version von OpenVPN 2.x und kann als semioffizieller Client der community angesehen werden. <p> OpenVPN Connect ist ein Closed-Source-Client, der von OpenVPN Technologies, Inc. entwickelt wird. Der Client ist für die normale Verwendung und auf den durchschnittlichen Benutzer ausgerichtet werden und ermöglicht den Import von OpenVPN-Profilen ohne diese innerhalb der App ändern zu können. Dieser Client basiert auf der OpenVPN C++ Neuimplementierung des OpenVPN-Protokolls (Diese war erforderlich, damit OpenVPN Technologies, Inc, eine iOS-app von OpenVPN veröffentlichen onnte). Dieser Client ist auch der offizielle Client von OpenVPN Technologies, Inc. < p> OpenVPN Settings ist der älteste von den Clients und auch eine Benutzeroberfläche für das Open-Source OpenVPN. Im Gegensatz zu OpenVPN für Android es erfordert es Rootrechte und verwendet nicht die VPNService-API; benötigt aber auch nicht Android 4.0+ + Es gibt es mehrere OpenVPN-Clients für Android. Die am häufigsten genutzten sind OpenVPN für Android (dieser Client), OpenVPN Connect und OpenVPN Settings. <p> Die Clients in zwei Gruppen eingeteilt werden können: OpenVPN für Android und OpenVPN Connect verwenden die offizielle VPNService-API (Android 4.0+) und erfordern keine Rootrechte und OpenVPN-Settings, das Rootrechte benötigt. < p > OpenVPN für Android ist ein von Arne Schwabe entwickelter Open-Source-Client. Es richtet sich an fortgeschrittene Benutzer und bietet viele erweiterete Einstellungen sowie die Möglichkeit, Profile aus Dateien zu importieren und das konfigurieren und ändern von Profilen innerhalb der App. Der Client basiert auf der Community-Version von OpenVPN 2.x und kann als semioffizieller Client der community angesehen werden. <p> OpenVPN Connect ist ein Closed-Source-Client, der von OpenVPN Technologies, Inc. entwickelt wird. Der Client ist für die normale Verwendung und auf den durchschnittlichen Benutzer ausgerichtet werden und ermöglicht den Import von OpenVPN-Profilen ohne diese innerhalb der App ändern zu können. Dieser Client basiert auf der OpenVPN C++ Neuimplementierung des OpenVPN-Protokolls (Diese war erforderlich, damit OpenVPN Technologies, Inc, eine iOS-app von OpenVPN veröffentlichen onnte). Dieser Client ist auch der offizielle Client von OpenVPN Technologies, Inc. < p> OpenVPN Settings ist der älteste von den Clients und auch eine Benutzeroberfläche für das Open-Source OpenVPN. Im Gegensatz zu OpenVPN für Android es erfordert es Rootrechte und verwendet nicht die VPNService-API; benötigt aber auch nicht Android 4.0 + Unterschiede zwischen Android OpenVPN Apps Ignoriere Multicastroute: %s Android unterstützt nur CIDR Routen. Da Routen, die nicht CIDR sind, fast nie verwendet werden, wird OpenVPN für Android eine /32 Route für nicht konforme Routen verwenden und eine Warnung ausgegeben. @@ -359,6 +358,7 @@ Android wird ihre Proxy-Einstellungen für die WLan-Verbindung beibehalten wenn keine DNS-Servereinstellungen vorhanden sind. OpenVPN für Android gibt einen entsprechenden Warnhinweis in der Log-Datei aus.

Wenn eine VPN-Verbindung einen DNS-Server vorgibt kann kein Proxy genutzt werden. Es gibt keine API um einen Proxy-Server für eine VPN-Verbindung zu nutzen.

Ihre VPN-Anwendung funktioniert möglicherweise nicht mehr wenn diese erst de- und später neu installiert wird. Für Details siehe #80074 Die konfigurierte Klient-IP-Adresse und die IP-Adressen in die Netzwerkmaske sind nicht in das VPN geroutet. OpenVPN umgeht diesen Fehler, indem eine Route hinzugefügt wird, die zu der Client-IP-Adresse und deren Netzmaske passt. + Beim Öffnen eines neuen VPN devices (tun) während eines bereits geöffnet ist (für persist-tun Unterstützung) führt zum Absturz des VPN Dienstes auf Android, der nur durch einen Neustart behoben werden kann. OpenVPN für Android versucht deshalb dieses erneute Öffnen zu vermeiden. Wenn ein erneutes Öffnen zwingend notwendig ist, wird erst das alte Device geschlossen before ein neues geöffnet wird. Dies kann dazu führen, dass teilweise Pakete unverschlüsselt über die normal Internetverbindung gesendet werden. Auch mit diesem Workaround stürzt teilweise der VPN Dienst ab und erfordert einen Neustart des Gerätes. VPN funktioniert überhaupt nicht für die Sekundärnutzer. Mehrere Benutzer berichten, dass die mobile Verbindung/Mobile Datenverbindung häufig getrennt wird, wenn ein VPN aktiv. Das Verhalten scheint nur einige Anbieter/Mobilgerät-Kombination beeinflussen und bisher konnte weder Ursache noch Lösung für den Bug identifiziert werden. Nur Ziele, die ohne VPN erreichbar sind, sind auch mit VPN erreichbar. IPv6 VPNs funktionieren überhaupt nicht. @@ -373,4 +373,26 @@ Definieren Sie benutzerdefinierte verbindungsspezifische Optionen. Seien Sie vorsichtig! Benutzerdefinierte Optionen Verbindung entfernen + Sporadische Verlust der Verbindung mit dem Mobilfunknetz + Entfernte Netzwerkresourcen nicht erreichbar + Persistenter tun Modus + %s und neuer + Verbindung schlägt mit \"SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure\" fehl + OpenVPN für die Android Versionen ab 0.6.29 (März 2015) verwenden einen sicheren Default für die zulässigen TLS Chiffren (\"DEFAULT:!EXP:!PSK:!SRP:!kRSA\"). Leider hat Weglassen der weniger sicheren Verschlüsselungschiffren und Exportchfriffen, vor allem aber der Wegfall der Cipher Suites, die keine Unterstützung für Perfect-Forward-Secrecy (Diffie-Hellman) einige Probleme verursacht. In der Regel sind dies gut gemeinte, aber schlecht ausgeführte Versuche, die TLS Sicherheit durch eine händische Wahl zu verbessern oder bei einigen eingebetteten Betriebssysteme mit abgespeckten OpenSSL (z.B. MikroTik).\n Um dieses Problem lösen das Problem, setzen Sie die TLS-Verschlüsselung Einstellungen auf dem Server auf einen sinnvollen Standardwert wie z.B. tls-cipher \"DEFAULT: EXP: PSK: SRP: KRSA\". Als Workaround für Problem auf dem Client, fügen Sie die benutzerdefinierte Option tls-cipher DEFAULT dem VPN Profil hinzu um die weniger sicheren Chiffren wieder zuzulassen. + Dieses Profil wurde von einer externen Anwendung (%s) hinzugefügt und als nicht vom Benutzer bearbeitbar markiert. + Zertifikatsperrliste + Neustarten von OpenVPN Service (App vermutlich abgestürzt oder wegen Speicherdruck beendet) + Importieren der Config ergab einen Fehler, kann diese nicht speichern + Suche + (Letzten Dump ist %1$d:%2$dh alt (%3$s)) + Protokoll bei neuer Verbindung leeren + Verbindungstimeout + Keine erlaubte App hinzgefügt. Füge die App selbst (%s) hinzu um wenigsten eine App in der Liste der nicht erlaubten Anwendungen zu haben + OpenVPN für Android kann versuchen, die fehlende(n) Datei(en) auf der SD-Karte automatisch zu finden. Tippen Sie auf diese Meldung um die Berechtigungsanfrage zu starten. + Protokoll + Aktiviert + Bevorzugte native ABI Reihenfolge dieses Gerätes (%1$s) und die installierten nativen Bibliotheken (%2$s) unterscheiden sich + Noch %d Monate gültig + Noch %d Tage gültig + Noch %d Stunden gültig diff --git a/app/src/main/res/values-es/strings-icsopenvpn.xml b/app/src/main/res/values-es/strings-icsopenvpn.xml index f7ce4bf0..203e51dc 100755 --- a/app/src/main/res/values-es/strings-icsopenvpn.xml +++ b/app/src/main/res/values-es/strings-icsopenvpn.xml @@ -181,7 +181,6 @@ hacia/de Móvil)
No se obtuvo ningún certificado de CA al leer el almacén de claves de Android. La autenticación probablemente fallará. Muestra la ventana de registro el conectarse. La ventana de registro siempre puede accederse desde el estado de la notificación. Mostrar ventana de registro - Ejecutándose en %1$s (%2$s) %3$s, API de Android %4$d Error al firmar con la llave del almacén de llaves de Android %1$s: %2$s El aviso de conectividad VPN que esta aplicación puede interceptar todo el trafico esta impuesta por el sistema para evitar abusos de la API VPNService.\nLa notificación de conectividad (El símbolo de llave) también esta impuesta por el sistema Android para notificar una conexión VPN en curso. En algunas imágenes, esta notificación también emite un sonido.\nAndroid ha introducido estos diálogos de sistema para su seguridad e se ha asegurado que no pueden ser evitados. (En algunas imágenes, esto incluye la notificación sonora) Advertencia de conexión y sonido de notificación @@ -261,7 +260,6 @@ hacia/de Móvil)
Algoritmo de encriptación Autenticación de paquetes Introduzca método de autenticación de paquetes - Corriendo sobre %1$s (%2$s) %3$s, API Android %4$d, versión %5$s, %6$s compilado por %s versión de depuración versión oficial @@ -351,7 +349,7 @@ hacia/de Móvil)
Duplicar perfil VPN Duplicando Perfil: %s Mostrar registro - Existen múltiples clientes OpenVPN para Android. Los más comunes son OpenVPN para Android (este cliente), OpenVPN Connect y Configuración de OpenVPN<p>Los clientes se pueden agrupar en dos grupos:. OpenVPN para Android y OpenVPN Conectar utilizar la API VPNService oficial (Android 4.0+) y requieren ninguna raíz y Configuración de OpenVPN que utiliza la raíz.<p>OpenVPN para Android es un cliente de código abierto y desarrollado por Arne Schwabe. Está dirigido a los usuarios más avanzados y ofrece muchas opciones y la posibilidad de importar los perfiles de los archivos y configurar perfiles / cambio dentro de la aplicación. El cliente se basa en la versión de la comunidad de OpenVPN. Se basa en el código fuente 2.x OpenVPN. Este cliente puede ser visto como el semi oficialmente cliente de la comunidad.<p>OpenVPN Connect es cliente de código abierto no que es desarrollado por OpenVPN Technologies, Inc. El cliente tiene sangría para ser cliente de uso general y moree dirigido al usuario medio y permite la importación de perfiles de OpenVPN. Este cliente se basa en la reimplementación OpenVPN C ++ del protocolo OpenVPN (Esto fue necesario para permitir Tecnologías OpenVPN, Inc para publicar una aplicación para iOS OpenVPN). Este cliente es el cliente oficial de las tecnologías deO penVPN<p> OpenVPN Ajustes es el más antiguo de los clientes y también una interfaz de usuario para el software libre OpenVPN. En contraste con OpenVPN para Android requiere raíz y no utiliza el API VPNService. No depende de Android 4.0+ + Existen múltiples clientes OpenVPN para Android. Los más comunes son OpenVPN para Android (este cliente), OpenVPN Connect y Configuración de OpenVPN<p>Los clientes se pueden agrupar en dos grupos:. OpenVPN para Android y OpenVPN Conectar utilizar la API VPNService oficial (Android 4.0+) y requieren ninguna raíz y Configuración de OpenVPN que utiliza la raíz.<p>OpenVPN para Android es un cliente de código abierto y desarrollado por Arne Schwabe. Está dirigido a los usuarios más avanzados y ofrece muchas opciones y la posibilidad de importar los perfiles de los archivos y configurar perfiles / cambio dentro de la aplicación. El cliente se basa en la versión de la comunidad de OpenVPN. Se basa en el código fuente 2.x OpenVPN. Este cliente puede ser visto como el semi oficialmente cliente de la comunidad.<p>OpenVPN Connect es cliente de código abierto no que es desarrollado por OpenVPN Technologies, Inc. El cliente tiene sangría para ser cliente de uso general y moree dirigido al usuario medio y permite la importación de perfiles de OpenVPN. Este cliente se basa en la reimplementación OpenVPN C ++ del protocolo OpenVPN (Esto fue necesario para permitir Tecnologías OpenVPN, Inc para publicar una aplicación para iOS OpenVPN). Este cliente es el cliente oficial de las tecnologías de OpenVPN<p> OpenVPN Ajustes es el más antiguo de los clientes y también una interfaz de usuario para el software libre OpenVPN. En contraste con OpenVPN para Android requiere raíz y no utiliza el API VPNService. No depende de Android 4.0+ Differences between the OpenVPN Android clients Haciendo caso omiso de ruta multidifusión: %s Android sólo admite rutas CIDR a la VPN. Desde rutas no CIDR casi nunca se usan, OpenVPN para Android utilizará un / 32 para las rutas que no son CIDR y emitir una advertencia. diff --git a/app/src/main/res/values-et/strings-icsopenvpn.xml b/app/src/main/res/values-et/strings-icsopenvpn.xml index a132ed7a..dcc134bf 100755 --- a/app/src/main/res/values-et/strings-icsopenvpn.xml +++ b/app/src/main/res/values-et/strings-icsopenvpn.xml @@ -180,7 +180,7 @@ Androidi võtmehoidlast lugemine ei andnud ühtegi CA sertifikaati. Suure tõenäosusega autentimine ebaõnnestub. Näitab ühendumisel logiakent. Logiakna saab alati ette manada VPN teatisealast. Näita logiakent - Töötamas %1$s (%2$s) %3$s peal, Android API %4$d + %10$s %9$s töötab seadmel %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) Viga allkirjastamisel Androidi võtmehoidla võtmega %1$s: %2$s VPN ühendumisel ilmub ekraanile hoiatus et see programm võib pealt kuulata kogu võrguliiklust. Tegemist on VPNService API süsteemse hoiatusega et hoida ära väärkasutust.\nVPN ühenduse teatis (Võtme sümbol) on samuti VPNService API poolt kuvatav aktiivse VPN ühenduse indikaator. Mõne süsteemitarkvara puhul võib see indikaator anda märku ka heliga.\nNeed teatised on Androidi süsteemile lisatud teie turvalisuse tagamiseks ja samuti on välistatud nende kasutamisest mööda minemine. (Kahjuks tähendab see seda et mõne süsteemitarkvara puhul kaasneb ühendusega alati ka heliteade) Hoiatused ja helimärguanded ühenduse loomisel @@ -260,7 +260,6 @@ Krüptošiffer Pakettide autentimine Sisestage pakettide autentimismeetod - Töötab seadmel %1$s (%2$s) %3$s, Android API %4$d, versioon %5$s, %6$s Kompileerija: %s Silumisversioon Ametlik versioon @@ -374,4 +373,26 @@ Seadista kohandatavad ühendusespetsiifilised valikud. Kasuta ettevaatlikult Kohandatavad valikud Eemalda ühenduse kirje + Pistelised mobiilivõrgu katkestused + Kaugvõrgud on väljaspool ulatust + Püsiv tun režiim + %s ja hilisem + Ühendused nurjuvad teatega SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure + Uuemad OpenVPN for Android versioonid (0.6.29/Märts 2015) kasutavad turvalisemat vaikešifrikoplekti (tls-cipher \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\"). Paraku tekitab nõrgemate šifri- ning eksportšifrikomplektide vältimine, eriti nende šifrikomplektide mis ei toeta Täiuslikku Edastussaladust (Diffie-Hellman), mõningaid probleeme. Probleemid esinevad tavaliselt heade kavatsustega, kuid viletsa teostusega TLS tugevdamise katsetel, valides serveris tls-šifri mõnede kärbitud SSL algoritmiga põim-operatsioonisüsteemidel (n.n. MkroTik).\nProbleemi lahendamiseks seadke serveri tls-šifri parameetrid mõistlikule vaikeväärtusele nagu \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\". Kliendipoolseks lahenduseks lisage Androidi klientseadme tls-šifri kohandatud parameetriks DEFAULT. + Selle profiili lisas väline programm (%s) ning see on tähistatud kui kasutajale muudetamatu. + Sertifikaadi tühistusnimekiri + OpenVPN teenuse taaskäivitamine (Programm jooksis tõenäoliselt kokku või suleti mälusurve tõttu) + Seadistuse importimine lõppes veaga, salvestamine ebaõnnestus + Otsing + (Viimne tõmmis on %1$d:%2$dh vana (%3$s)) + Järgmisel ühendumisel tühjenda logi + Ühenduse ajalõpp + Lisati lubamatu programm. Lisame ennast (%s) et lubatud programmide seas oleks vähemalt üks ja ei lubataks kõiki programme + OpenVPN for Android võib üritada leida automaatselt sd-kaardi puuduvad failid. Koputa seda teadet et algatada õiguste tellimine. + Protokoll + Lubatud + Selle seadme eelistatud ABI eelisjärjekord (%1$s) ja seadme kaasnevate teekide teatatud ABI (%2$s) ei ühildu + Jäänud on %d kuud + jäänud on %d päeva + Jäänud on %d tundi diff --git a/app/src/main/res/values-fr/strings-icsopenvpn.xml b/app/src/main/res/values-fr/strings-icsopenvpn.xml index d5ab917c..3e9b416c 100755 --- a/app/src/main/res/values-fr/strings-icsopenvpn.xml +++ b/app/src/main/res/values-fr/strings-icsopenvpn.xml @@ -180,7 +180,6 @@ "Aucun certificat CA renvoyée lors de la lecture depuis le gestionnaire de clés. L\'authentification échouera probablement." "Affiche la fenêtre de log à la connexion. Cette fenêtre peut toujours être consultée à partir de la notification d\'état." "Afficher la fenêtre de log" - "Fonctionnant sur %1$s (%2$s) %3$s , Android API %4$d" "Erreur de signature de la clé %1$s : %2$s par le gestionnaire d\'Android" \"L\'avertissement de connexion au VPN qui vous informe que cette application peut intercepter tout le trafic est imposé par le système pour éviter les abus de l\'API du service VPN.\nLa notification de connexion au VPN (Le symbole qui ressemble à une clé) est aussi imposé par le système Android pour signaler une connexion VPN en cours de fonctionnement. Sur certaines images, cette notification joue un son.\nAndroid à introduit ces dialogues système pour votre propre sécurité et à fait en sorte d\'être impossible à contourner. (Cela peut inclure en plus une notification sonore pour certaines images)\" @@ -261,7 +260,6 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces Chiffrement de cryptage Authentification des paquets Méthode d\'authentification des paquets - Environnement: %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s compilé par %s version de debug version officielle @@ -317,7 +315,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces Si vous avez \"rooté\" votre Android vous pouvez installer <a href=\"http://xposed.info/\">Xposed framework</a> et <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">le module de confirmation VPN</a> à vos risques et périls\" Licences complètes Les réseaux directement connectés aux interfaces locales ne seront pas routés via le VPN. Décochez cette option pour rediriger tout le trafic local vers le VPN. - Ne pas utiliser le VPN pour les réseaux locaux + Bypass VPN pour les réseaux locaux Fichier Nom d\'utilisateur/Mot de passe [Importé de : %s] Certains fichiers sont introuvables. Sélectionner les fichiers pour importer le profil : @@ -350,4 +348,5 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces No remote defined Dupliquer le profil VPN Duplicating profile: %s + Afficher le journal diff --git a/app/src/main/res/values-hu/strings-icsopenvpn.xml b/app/src/main/res/values-hu/strings-icsopenvpn.xml index 5be8bbc4..fcdf3f23 100755 --- a/app/src/main/res/values-hu/strings-icsopenvpn.xml +++ b/app/src/main/res/values-hu/strings-icsopenvpn.xml @@ -60,7 +60,7 @@ Szétkapcsolás VPN kapcsolat szétkapcsolása napló törlése - jóváhagyás törlése + Megszakítás jóváhagyása VPN kapcsolat/kapcsolódás megszakítása? VPN kapcsolat eltávolítása Ellenőrzi, hogy a kiszolgáló használ-e tanúsitványt TLS Server kiterjesztéssel (--remote-cert-tls server) @@ -111,7 +111,7 @@ Az %1$s/%2$s útvonal javítva: %3$s/%2$s Nem sikerült hozzáférni az Android Keychain Tanúsivànyokhoz. Ezt egy firmware frissítés vagy az alkalmazás/beállításainak visszaállítása okozhatja. Kérem szerkessze meg a VPN-t, és újra válassza ki a tanúsítványokat az alapvető beállításoknál, hogy visszaálljanak a tanúsítványok hozzáférési jogai. %1$s %2$s - naplófájl küldése + Naplófájl küldése küld ICS OpenVPN naplófájl Naplóbejegyzés másolva a vágólapra @@ -178,7 +178,6 @@ Nem jött vissza CA tanúsítvány az Android keystore olvasása során. A hitelesítés valószínűleg sikertelen lesz. Napló ablak mutatása a csatlakozás alatt. A napló ablak mindig elérető a rolóról is. Naplózási ablak mutatása - %1$s (%2$s) %3$s, Android API %4$d Hiba az Android keystore %1$s: %2$s kulccsal való belépéskor Kapcsolat figyelmeztetés és értesítés hang A magyar fordítást készítette Juhász Sándor <msc@digitaltrip.hu> @@ -251,7 +250,6 @@ Titkosítás Csomag hitelesítés Adja meg a csomaghitelesítési metódust - %1$s (%2$s) %3$s, Android API %4$d, %5$s, %6$s verzió %s fordítóval hibakeresési fordítás hivatalos build @@ -274,6 +272,8 @@ Kapcsolat szüneteltetése a képernyő kikapcsolt állapotában: kevesebb mint %1$s %2$ss alatt Figyelmeztetés: Megmaradó tun nem engedélyezett ehhez a VPN-hez. A forgalom a normál internetcsatlakozáson megy amikor a képernyő ki van kapcsolva. Jelszó mentése + Napló törölve. + Jelszó mutatása Rövid ISO Időbélyegzők @@ -284,4 +284,24 @@ Nézet beállításai Nem kezelt kivétel: %1$s\n\n%2$s Teljes engedélyek + Felhasználónév/Jelszó fájl + [Innen importálva: %s] + Néhány fájl nem található. Kérlek válaszd ki a fájlokat a profil importálásához: + Importálási napló: + Betöltés… + Engedélyezett VPN programok: %1$s + Letiltott VPN programok: %1$s + %s csomag már nincs telepítve, eltávolítás a program engedélyező/letiltó listáról + Megtartás + Törlés + Szerver lista + Napló mutatása + Egyéni beállítások + %s és később + Keresés + Protokoll + Engedélyezett + %d hónap van hátra + %d nap van hátra + %d óra van hátra diff --git a/app/src/main/res/values-in/strings-icsopenvpn.xml b/app/src/main/res/values-in/strings-icsopenvpn.xml index 07331433..07415d29 100755 --- a/app/src/main/res/values-in/strings-icsopenvpn.xml +++ b/app/src/main/res/values-in/strings-icsopenvpn.xml @@ -7,9 +7,9 @@ Alamat Server: - Port server: + Server Port: Lokasi - Gagal membaca direktori + Gagal membaca direktori: Pilih Batal Tak ada data @@ -20,33 +20,33 @@ Berkas PKCS12 Sertifikat CA Anda harus memilih sertifikat - Kode program dan perekam masalah tersedia di - Aplikasi memakai komponen berikut; lihat kode program untuk lebih jelas mengenai lisensi - Tentang… + Kode sumber dan pelacak masalah tersedia di http://code.google.com/p/ics-openvpn/ + Program ini menggunakan komponen-komponen berikut ini; lihat kode sumber penjelasan lengkap mengenai lisensi + Tentang Profil - Tipe + Jenis Password PKCS12 Pilih… - Anda harus memilih berkas (file) - Pakai otentikasi TLS + Anda harus memilih setidaknya satu berkas + Gunakan Autentikasi TLS Pengarah TLS - Masukkan IPv6 Address/Netmask dalam format CIDR (contoh: 2000:dd::23/64) + Masukkan Alamat IPv6/Netmask dalam Format CIDR (contoh: 2000:dd::23/64) Masukkan IPv4 Address/Netmask dalam format CIDR (contoh: 1.2.3.4/24) Alamat IPv4 Alamat IPv6 - Masukan seting openvpn. Gunakan dengan hati-hati. Harap dicatat, TUN yanng terkait seting OpenVPN tidak didukung oleh VPNsettings. Jika anda berpikir ada hal penting belum tersedia, hubungi pembuatnya + Masukan pengaturan kustom OpenVPN. Harap gunakan dengan hati-hati. Perlu dicatat bahwa pengaturan yang terkait dengan TUN OpenVPN tidak didukung oleh disain VPNSettings. Jika anda fikir ada hal penting yang belum tersedia segera hubungi pembuatnya Nama Penguna - Password - Untuk konfigurasi statis, kunci otentifikasi TLS akan digunakan sebagai kunci konfigurasi statis + Kata Sandi + Untuk pengaturan tetap, kunci otentifikasi TLS akan digunakan sebagai kunci statis Konfigurasi VPN Tambah Profil Masukkan nama profil yang baru - Silakan masukan UPN (Unique Profile Name) + Silakan masukan nama profil yang berbeda Nama profil Anda harus memilih sertifikat pengguna Tidak ada kesalahan Konfigurasi Salah - Gagal menganalisa alamat IPV4 + Kesalahan penulisan alamat IPV4 Gagal menganalisa rute buatan (biarkan kosong untuk antrian permintaan) Jalan Pintas OpenVPN @@ -55,7 +55,7 @@ Acak awalan Host Tambah 6 karakter acak di depan nama host Aktifkan pilihan buatan - Tentukan seting buatan. Gunakan hati-hati + Tentukan seting buatan. Gunakan hati-hati! Rute ditolak Android Putus Memutuskan sambungan VPN @@ -77,7 +77,7 @@ DNS Menimpa pengaturan DNS oleh Server Gunakan server DNS pribadi - Cari domain + cari domain Server DNS yang akan digunakan Server DNS Server DNS sekunder digunakan jika Server DNS yang normal tidak dapat dicapai. @@ -100,22 +100,24 @@ Gagal membuka layanan antarmuka TUN "Kesalahan: " Bersihkan - Membuka interface tun : - IPv4 lokal : %1$s/%2$d IPv6: %3$s MTU: %4$d + Membuka interface tun: + IPv4 lokal: %1$s/%2$d IPv6: %3$s MTU: %4$d DNS Server: %1$s, Domain: %2$s Rute: %1$s %2$s + Rute terkecualikan: %1$s %2$s + Rute LayananVpn telah terpasang: %1$s %2$s Memilki informasi antarmuka %1$s dan %2$s, asumsi alamat kedua adalah alamat remote. Menggunakan netmask /32 untuk IP lokal. Mode yang diberikan oleh OpenVPN adalah \"%3$s\". Tidak masuk akal membuat %1$s dan %2$s sebagai rute IP dengan netmask CIDR, Gunakan /32 sebagai netmask. - rute yang diperbaiki %1$s/%2$s hingga %3$s/%2$s + Rute yang diperbaiki %1$s/%2$s hingga %3$s/%2$s Tidak dapat mengakses sertifikat Keychain Android. Dapat disebabkan karena upgrade firmware atau pengembalian backup pengaturan app. Mohon ubah VPN, dan pilih ulang sertifikat berbasis pengaturan dasar agar izin mengakses sertifikat dapat dibuat ulang. %1$s %2$s Kirim berkas catatan Kirim Berkas catatan ICS OpenVPN Salin catatan masuk ke clipboard - Mode TAP + Mode Tap Mode TAP tidak diijinkan tanpa VPN API non admin/root. Karena itu aplikasi ini tidak dapat memberikan dukungan mode TAP - Lagi ? Becanda ? mode TAP benar-benar tidak didukung dan mengirim email menanyakan apakah akan ada dukungan TAP, tidak akan membantu + Lagi? Becanda? mode Tap benar-benar tidak didukung dan mengirim email menanyakan apakah akan ada dukungan Tap, tidak akan membantu. Untuk ketiga kalinya? Sebenarnya, seseorang bisa menulis emulator TAP berdasarkan tun yang akan menambahkan lapisan2 informasi pengiriman dan lapisan2 informasi penerimaan. Tapi emulator TAP ini juga harus menerapkan ARP dan mungkin klien DHCP. Saya tidak tau apakah ada yang bekerja ke arah ini. Hubungi saya jika Anda ingin memulai menulis kode2 emulator TAP ini. FAQ Menyalin catatan @@ -138,11 +140,11 @@ Ambil Tidak dapat membaca profil yang akan diambil Kesalahan membaca berkas konfigurasi - Tambah Profil + tambah Profil Tidak dapat menemukan berkas %1$s yang disebut dalam berkas konfigurasi Mengambil berkas konfigurasi dari sumber %1$s Konfigurasi Anda memiliki beberapa pilihan konfigurasi yang tidak dipetakan ke konfigurasi UI. Pilihan ini ditambahkan sebagai opsi konfigurasi kustom. Konfigurasi kustom ditampilkan di bawah ini: - Berkas konfigurasi selesai dibaca + Berkas konfigurasi selesai dibaca. Jangan kaitkan ke alamat dan port lokal Tidak ada ikatan lokal Ambil berkas konfigurasi @@ -178,7 +180,7 @@ Tidak ada sertifikat CA yang didapat saat membaca dari Android Keystore. Otentifikasi mungkin gagal Tampilkan jendela catatan saat terkoneksi. Jendela catatan juga dapat diakses melalui status notifikasi Tampilkan jendela catatan - Berjalan di %1$s (%2$s) %3$s, Android API %4$d + %10$s %9$s berjalan pada %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) Kesalahan masuk dengan kunci Android keystore %1$s: %2$s Peringatan sambungan VPN yang memberitahukan Anda bahwa aplikasi ini dapat mencegat semua lalu lintas dikeluarkan oleh sistem untuk mencegah penyalahgunaan dari sambungan VPNService API.\nPemberitahuan sambungan VPN (simbol kunci) juga dikeluarkan oleh sistem Android untuk memberitahu VPN yang sedang berlangsung. Pada beberapa gambar pemberitahuan ini memainkan suara. \nAndroid memperkenalkan sistem dialog ini untuk keselamatan Anda sendiri dan memastikan bahwa mereka tidak membuat masalah. (Pada beberapa gambar sayangnya ini termasuk peringatan suara) Peringatan sambungan dan pemberitahuan melalui suara @@ -191,6 +193,7 @@ Konfigurasi ICS Openvpn Tidak DNS server yang digunakan. Name Resolution mungkin akan gagal bekerja. Pertimbangkan pengaturan server DNS. Harap dicatat Android akan terus memakai pengaturan proxy untuk koneksi mobile/wifi saat tidak ada server DNS diatur. Tak bisa menambahkan Server DNS \"%1$s\", ditolak oleh sistem: %2$s + Tidak bisa mengkonfigurasi IP Address \"%1$s\", ditolak oleh sistem: %2$s <p> Ambil konfigurasi yang dapat berjalan (diuji pada komputer Anda atau download dari penyedia/organisasi) </p> <p> Satu file(berkas) saja tanpa tambahan berkas pem/pks12. Anda dapat kirim imel berkas dan membuka lampirannya. Jika Anda memiliki beberapa berkas, salin ke sd-card </p> <p> klik pada lampiran imel atau gunakan ikon folder dalam daftar vpn untuk mengimpor berkas konfigurasi </p> <p> jika ada berkas yang kurang, salin file hilang ke sd-card. </p> <p> klik pada simbol Simpan untuk menambahkan VPN yang diimpor ke daftar VPN </p> <p > Connect VPN dengan mengklik nama VPN </p> <p> jika ada kesalahan atau peringatan di catatan, coba pahami peringatannya dan coba untuk memperbaikinya </p> Mulai Cepat Coba pakai tun.ko kernel sebelum mencoba koneksi. Membutuhkan perangkat yang sudah diroot. Google: android superuser @@ -215,6 +218,7 @@ Gunakan ikon < img src = \"ic_menu_archive\" / > untuk mengimpor profil (.ovpn atau .conf) yang ada dari sdcard Anda. Pastikan untuk juga memeriksa FAQ. Ada petunjuk untuk memudahkan anda. Konfigurasi rute\antarmuka + Konfigurasi Routing dan antarmuka tidak dilakukan melalui perintah ifconfig/rute tradisional tetapi dengan menggunakan VPNService API. Ini hasil dalam konfigurasi perutean berbeda daripada pada OS lain. \nThe konfigurasi VPN terowongan terdiri dari alamat IP dan jaringan yang harus dialihkan melalui antarmuka ini. Terutama, tidak ada rekan mitra alamat atau alamat gateway adalah diperlukan atau diperlukan. Khusus rute untuk mencapai VPN Server (misalnya ditambahkan dengan menggunakan redirect-gateway) tidak diperlukan baik. Aplikasi akibatnya akan mengabaikan pengaturan ini ketika mengimpor konfigurasi. App menjamin dengan VPNService API bahwa koneksi ke server tidak diarahkan melalui VPN terowongan. \nThe VPNService API tidak memungkinkan menentukan jaringan yang tidak dapat diteruskan melalui VPN. Sebagai solusi app mencoba untuk mendeteksi jaringan yang tidak dapat diteruskan melalui terowongan (misalnya rute x.x.x.x y.y.y.y net_gateway) dan menghitung seperangkat rute yang mengecualikan ini rute untuk meniru perilaku platform lainnya. Jendela log menunjukkan konfigurasi VPNService berdasarkan membangun koneksi. \nBehind adegan: Android 4,4 + menggunakan kebijakan routing. Menggunakan rute ifconfig tidak akan menunjukkan rute yang diinstal. Alih-alih menggunakan aturan ip, iptables -t mangle -L Jangan kembali ke status tidak ada koneksi VPN ketika OpenVPN mencoba terhubung kembali. Paksa mode TUN Catatan OpenVPN @@ -256,7 +260,6 @@ Enkripsi sandi Otentikasi paket Masukkan metode otentikasi paket - Berjalan pada Android API %4$d, versi %5$s %1$s (%2$s) %3$s, %6$s dibangun oleh %s Pengembangan debug Build Resmi @@ -271,6 +274,7 @@ TLS-remote (DEPRECATED) Anda dapat membantu menerjemahkan dengan mengunjungi http://crowdin.net/project/ics-openvpn/invite %1$s berusaha mengendalikan %2$s + Dengan melanjutkan, Anda memberi izin aplikasi untuk sepenuhnya mengontrol OpenVPN untuk Android dan untuk mencegat semua lalu lintas jaringan. Jangan terima kecuali Anda mempercayai aplikasi. Jika tidak, data Anda beresiko diambil oleh perangkat lunak jahat.\" Saya percaya aplikasi ini. App tidak diizinkan untuk menggunakan API eksternal apps yang diijinkan : %s @@ -288,4 +292,85 @@ Tidak dapat menampilkan informasi sertifikat Prilaku Aplikasi Prilaku VPN + Memungkinkan perubahan Profil VPN + Hardware Keystore: + Ikon aplikasi mencoba menggunakan OpenVPN untuk Android + "Dimulai dengan Android 4.3 konfirmasi VPN dijaga terhadap\" overlay apps \". Hal ini menyebabkan dialog tidak bereaksi menyentuh input. Jika Anda memiliki sebuah aplikasi yang menggunakan lapisan itu dapat menyebabkan perilaku ini. Jika Anda menemukan kontak aplikasi menyinggung penulis app. Masalah ini mempengaruhi semua aplikasi VPN di Android 4.3 dan kemudian. Lihat juga <a href=\"https://github.com/schwabe/ics-openvpn/issues/185\"> Issue 185 <a> untuk rincian tambahan " + VPN Konfirmasi Dialog + Atau Anda dapat mengirimkan saya donasi dengan Play Store: + Terima kasih untuk menyumbangkan %s! + Log dibersihkan. + Tampilkan sandi + Keychain Akses error: %s + Pendek + ISO + Cap waktu + Tak satupun + Upload + Unduh + Vpn Status + Lihat pilihan + Tertangani pengecualian: %1$s \ n \ n%2$s + %3$s: %1$s \ n \ n%2$s + Jika Anda telah berakar perangkat Android Anda Anda dapat menginstal Xposed kerangka dan VPN Dialog mengkonfirmasi modul risiko Anda sendiri\" + Lisensi penuh + Jaringan langsung terhubung ke antarmuka lokal tidak akan diarahkan melalui VPN. Tidak memilih opsi ini akan mengarahkan semua lalu lintas menjorok untuk jaringan lokal ke VPN. + Bypass VPN for local networks + Username Password File / + [Impor dari: %s] + Beberapa file tidak dapat ditemukan. Silakan pilih file untuk mengimpor profil: + Untuk menggunakan aplikasi ini Anda membutuhkan penyedia VPN / gateway VPN mendukung OpenVPN (sering disediakan oleh majikan Anda). Periksa http://community.openvpn.net/ untuk informasi lebih lanjut tentang OpenVPN dan cara men-setup OpenVPN server Anda sendiri. + Log impor: + Vpn topologi \"%3$s\" ditentukan tapi ifconfig %1$s %2$s terlihat lebih seperti alamat IP dengan mask jaringan. Dengan asumsi \"subnet\" topologi. + Nilai menimpa MSS telah menjadi bulat antara 0 dan 9000 + Mengumumkan kepada sesi TCP berjalan di atas terowongan bahwa mereka harus membatasi kirim ukuran paket mereka seperti bahwa setelah OpenVPN telah dikemas mereka, sehingga UDP ukuran paket yang OpenVPN mengirim ke rekan-nya tidak akan melebihi jumlah ini byte. (default adalah 1450) + Mengganti nilai MSS TCP muatan + Mengatur muatan MSS TCP + Perilaku klien + Menghapus aplikasi eksternal diizinkan + Memuat… + Yang diizinkan aplikasi VPN: %1$s + Batasan VPN apps: %1$s + Paket %s tidak lagi diinstall, menghapus itu dari app memungkinkan/melarang daftar + VPN digunakan untuk semua aplikasi tapi mengecualikan yang dipilih + VPN digunakan untuk hanya untuk aplikasi yang dipilih + Hapus entri server jauh? + Biarkan + Hapus + Menambahkan baru remote + Gunakan entri koneksi secara acak pada koneksi + Anda harus menentukan dan memungkinkan setidaknya satu server jauh. + Daftar Server + Diizinkan Apps + Pengaturan lanjutan + Muatan pilihan + Pengaturan TLS + Didefinisikan Tidak ada remote + Profil duplikat VPN + Duplikasi profil: %s + Tampilkan log + Ada beberapa klien OpenVPN untuk Android. Yang paling umum adalah OpenVPN untuk Android (ini klien), OpenVPN Connect dan OpenVPN pengaturan. < p > klien dapat dikelompokkan menjadi dua kelompok: OpenVPN untuk Android dan OpenVPN Connect menggunakan API VPNService resmi (Android 4.0 +) dan memerlukan tanpa akar dan pengaturan OpenVPN yang menggunakan akar. < p > OpenVPN untuk Android adalah klien sumber terbuka dan dikembangkan oleh Arne Schwabe. Ini ditargetkan untuk pengguna yang lebih maju dan menawarkan banyak pengaturan dan kemampuan untuk mengimpor profil dari file dan mengkonfigurasi/Ubah profil di dalam app. Klien didasarkan pada versi komunitas OpenVPN. Hal ini didasarkan pada kode sumber 2.x OpenVPN. Klien ini dapat dilihat sebagai semi resmi klien masyarakat. < p > OpenVPN Connect adalah klien sumber terbuka bebas yang dikembangkan oleh OpenVPN Technologies, Inc Klien indentasi untuk penggunaan umum klien dan moree ditargetkan untuk pengguna rata-rata dan memungkinkan impor OpenVPN profil. Klien ini didasarkan pada reimplementation OpenVPN C++ OpenVPN Protokol (ini diperlukan untuk memungkinkan OpenVPN Technologies, Inc untuk menerbitkan sebuah aplikasi OpenVPN iOS). Klien ini adalah resmi klien OpenVPN teknologi < p > OpenVPN pengaturan tertua klien dan juga UI untuk open source OpenVPN. Berbeda dengan OpenVPN untuk Android itu memerlukan akar dan tidak menggunakan VPNService API. Tidak tergantung pada Android 4.0 + + Perbedaan antara klien OpenVPN Android + Mengabaikan rute multicast: %s + Android hanya mendukung rute CIDR ke VPN. Sejak non-CIDR rute yang hampir tidak pernah digunakan, OpenVPN untuk Android akan menggunakan / 32 untuk rute yang tidak CIDR dan mengeluarkan peringatan. + Penarikan bekerja sementara VPN aktif. Ditambatkan sambungan tidak akan menggunakan VPN. + Versi KitKat awal menetapkan nilai MSS salah pada TCP koneksi (# 61948). OpenVPN untuk secara otomatis mengaktifkan mssfix pilihan untuk solusi bug ini. + Android akan tetap menggunakan pengaturan proxy Anda ditentukan untuk mobile koneksi / Wi-Fi ketika tidak ada server DNS diatur. OpenVPN untuk Android akan memperingatkan Anda tentang hal ini dalam log.

Ketika VPN menetapkan server DNS Android tidak akan proxy. Tidak ada API untuk mengatur proxy untuk koneksi VPN.

+ Aplikasi VPN dapat berhenti bekerja ketika dihapus dan diinstal ulang lagi. Untuk jelasnya lihat # 80074 + IP klien dikonfigurasi dan IP di topeng jaringan tidak diteruskan ke VPN. OpenVPN bekerja di sekitar bug ini dengan secara eksplisit menambahkan rute yang corrosponds ke IP klien dan netmask nya + Membuka perangkat tun saat perangkat tun lain sedang aktif, yang digunakan untuk dukungan bertahan-tun, crash VPNServices pada perangkat. A reboot diperlukan untuk membuat pekerjaan VPN lagi. OpenVPN untuk Android mencoba untuk menghindari membuka kembali perangkat tun dan jika benar-benar diperlukan pertama menutup TUN saat sebelum membuka perangkat TUN baru untuk menghindari crash. Hal ini dapat menyebabkan jendela pendek di mana paket dikirim melalui koneksi non-VPN. Bahkan dengan solusi ini VPNServices kadang-kadang crash dan memerlukan reboot perangkat. + VPN tidak bekerja sama sekali bagi pengguna sekunder. + "Beberapa pengguna melaporkan bahwa koneksi mobile / koneksi data mobile sering menjatuhkan saat menggunakan aplikasi VPN. Perilaku tampaknya hanya mempengaruhi beberapa kombinasi perangkat mobile provider / dan sejauh ini tidak ada penyebab / solusi untuk bug dapat diidentifikasi." + Hanya tujuan yang bisa dicapai melalui VPN yang bisa dijangkau tanpa VPN. VPN IPv6 tidak bekerja sama sekali. + Rute non CIDR + Tindakan Proxy untuk VPN + Menginstal ulang aplikasi VPN + %s dan sebelumnya + Salinan dari %s + Alihkan ke alamat IP yang telah ditentukan + Nilai MSS yang salah untuk koneksi VPN + Pengguna tablet sekunder + Tentukan pengaturan untuk koneksi khusus . Gunakan dengan hati-hati + Pilihan buatan + Hapus entri koneksi
diff --git a/app/src/main/res/values-it/strings-icsopenvpn.xml b/app/src/main/res/values-it/strings-icsopenvpn.xml index f35a4b66..a8cafa72 100755 --- a/app/src/main/res/values-it/strings-icsopenvpn.xml +++ b/app/src/main/res/values-it/strings-icsopenvpn.xml @@ -182,7 +182,6 @@ Effettuata la lettura del file di configurazione
Nessun certificato della CA è stato prelevato dal Keystore di Android. E\' probabile che l\'autenticazione fallisca. Mostra la finestra dei log della connessione. Si può sempre accedere alla finestra dei log tramite la barra delle notifiche. Visualizza la finestra dei log - In esecuzione su %1$s (%2$s) %3$s, Android API %4$d Errore di firma con la chiave %1$s: %2$s del Keystore di Android. L\'avvertimento durante la connessione VPN, in cui si informa che questo programma può intercettare tutto il traffico del sistema, serve a prevenire un uso fraudolento delle API del servizio VPN.\nL\'icona di notifica a forma di chiave è altresì imposta dal sistema Android per avvertire che si è connessi ad una VPN. Su alcuni apparecchi questa notifica è accompagnata da un suono.\nAndroid utilizza questi sistemi per la tua sicurezza e per assicurarsi che questi non vengano aggirati (in alcuni firmware questo sfortunamente è accompagnato da un suono di avvertimento). Avviso di connessione e notifica sonora @@ -262,7 +261,6 @@ Effettuata la lettura del file di configurazione
Algoritmo di crittografia Autenticazione pacchetti Seleziona il metodo di autenticazione dei pacchetti - In esecuzione su %1$s (%2$s) %3$s, Android API %4$d, versione %5$s, %6$s compilato da %s versione di debug versione ufficiale @@ -346,6 +344,7 @@ Effettuata la lettura del file di configurazione
Impostazioni TLS Profilo VPN duplicato Duplicazione del profilo: %s + Mostra il log %s e precedenti Copia di %s diff --git a/app/src/main/res/values-ja/strings-icsopenvpn.xml b/app/src/main/res/values-ja/strings-icsopenvpn.xml index f12d149b..93e82f79 100755 --- a/app/src/main/res/values-ja/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ja/strings-icsopenvpn.xml @@ -6,8 +6,8 @@ --> - サーバアドレス - ポート番号 + サーバーアドレス: + ポート番号: 場所 ディレクトリが読み取れません 選択 @@ -20,7 +20,7 @@ PKCS12ファイル CA 証明書 証明書を選択する必要があります。 - ソースコードと問題管理はここにあります: http://code.google.com/p/ics-openvpn/ + ソースコードと問題管理はこちら: https://github.com/schwabe/ics-openvpn/ プログラムは、次のコンポーネントを使用します。完全な詳細についてはソース上のライセンスを参照してください。 バージョン情報 プロファイル @@ -28,7 +28,7 @@ PKCS12のパスワード 選択… ファイルを選択する必要があります。 - TLS認証を使用します。 + TLS認証を使用する TLS Direction IPv6アドレスをCIDR形式で入力(例:2000:dd::23/64) IPv4アドレスをCIDR形式で入力(例:1.2.3.4/24) @@ -55,7 +55,7 @@ ランダムなホスト プレフィックス ランダムな6文字をホスト名の前に付加します。 カスタム オプションを使用する - カスタムオプションを指定します。注意を要します。 + カスタムオプションを指定します。注意して使用してください! 経路がAndroidにより拒否されました。 切断 VPNを切断します @@ -63,6 +63,8 @@ キャンセルの確認 接続中または試行中の接続をキャンセルしますか? VPN を削除 + サーバが証明書とともにTLS拡張(--remote-cert-tls server)を使用しているか確認する + TLSサーバー証明書を要求する リモートサーバー証明書の所有者識別子(Subject DN)を確認します。 証明書のホスト名を確認する リモート証明書の照合に使用する識別名(DN)を指定します。(例: C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\n完全な識別名(DN)または相対識別名(RDN)、あるいは相対識別名のプリフィクスを指定します。\n\nたとえば相対識別名のプリフィクスとして\"Server\"を指定すると、\"Server-1\"と\"Server-2\"にマッチします。\n\n空欄にした場合は相対識別名とサーバのホスト名をチェックします。\n\n詳細についてはOpenVPN 2.3.1以降のマニュアルの「--verify-x509-name」の項を参照してください。 @@ -73,7 +75,7 @@ サーバからは何も情報が取得できません。指定が必要な設定は以下の通りです。 情報取得の設定 DNS - サーバ指定のDNSサーバ設定をオーバーライドします。 + DNSを手動設定する DNSをユーザ側で指定します。 検索ドメイン 使用する DNS サーバー @@ -90,7 +92,7 @@ ログの詳細度 認証済みパケットをどのIPからでも受け付けます。 フローティング サーバーを許可 - カスタム オプション + カスタムオプション VPN 設定の編集 VPN プロファイル %s を削除しますか? いくつかのカスタムICSイメージは、/dev/tunのパーミッションが異常か、TUNモジュールが含まれていません。CM9イメージの場合は全般設定で所有権設定を修正してください。 @@ -102,12 +104,13 @@ DNSサーバ: %1$s, ドメイン: %2$s 経路: %1$s %2$s 除外された経路: %1$s %2$s + VpnServiceの経路を設定しました: %1$s %2$s インターフェース情報として %1$s と %2$s を取得しました。2つ目のアドレスはリモート側のピアアドレスです。32ビットマスクをローカルIPに使用します。 OpenVPNのモードは \"%3$s\" です。 %1$sと%2$sではCIDR形式のIP経路情報として意味をなしません。32ビットマスクを使用します。 経路情報%1$s/%2$sを%3$s/%2$sに修正しました。 Androidの証明書管理にアクセスできません。(ファームウェアの更新、アプリケーションまたはその設定のリストアによって発生する場合があります)。VPNの設定で証明書の選択を再度行ってください。 %1$s %2$s - ログ ファイルを送信します。 + ログファイルを送信 送信 ICS OpenVPN ログ ファイル ログ エントリをクリップボードにコピーしました @@ -159,7 +162,9 @@ SDカード上のデータは本質的に無防備です。すべてのアプリ 状態メッセージを待っています。 インポートされたプロファイル インポートされたプロファイル %d - 壊れたイメージ + 壊れたファームウェア + <p>HTCの公式ファームウェアにはトンネルにトラフィックを流すことができない奇妙なルーティングの問題を抱えています。 (バグトラッカーを参照 <a href=\"https://github.com/schwabe/ics-openvpn/issues/18\">Issue 18</a>)</p><p>古いSONY、Xperia Arc SとXperia RayのファームウェアはVPNServiceが完全に欠落していると報告されています。(バグトラッカーを参照 <a href=\"https://github.com/schwabe/ics-openvpn/issues/29\">Issue 29</a>)</p><p>カスタムビルドされたファームウェアにおいてtunモジュールがなかったり、あるいは権限が間違っている場合があります。いくつかのCM9では +\"Device specific hacks(デバイス固有のhack)\"を有効にして\"Fix ownership(所有権を修正)\"オプションを使用する必要があります。</p><p>とても重要なこと: もしあなたがファームウェアの不完全なAndroidデバイスを所有していたら、メーカーに報告してください。より多くの人が問題を報告すれば、彼らが修正することでしょう。</p> PKCS12ファイルの暗号化キー 秘密鍵のパスワード パスワード @@ -180,7 +185,7 @@ SDカード上のデータは本質的に無防備です。すべてのアプリ 認証局証明書(CA Cert)がAndroidのキーストアから取得できませんでした。認証はおそらく失敗します。 接続時にログウィンドウを表示します。ログウィンドウは常に状態通知からアクセスできます。 ログウィンドウを表示 - 実行中:%1$s (%2$s)%3$s Android API %4$d + %10$s %9$s は次の環境で実行中です %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) Androidキーストアに保存されたキー %1$s: %2$sの署名エラーです VPN接続の警告は、このアプリケーションがVPNService APIを悪用してすべての通信を傍受できることを、システムがあなたに知らせるものです。\n VPN接続通知(鍵の形)は、VPN接続が稼働中であることをAndroidが知らせています。いくつかのシステムではこの通知で音を鳴らします。\n @@ -236,6 +241,9 @@ OpenVPNの接続を保証するためには、アプリケーションを高い OpenVPN のログ OpenVPN の構成のインポート バッテリー消費量 + 個人的な検証では、OpenVPNがバッテリを多く消費する主な原因はkeepaliveパケットです。 +大部分のOpenVPNサーバは\'keepalive 10 60\'のような設定を持っており、これは10秒ごとにサーバとクライアントで相互にkeepaliveパケットを送信しあうことを意味します。 <p>これらのパケットは小さく多くの帯域は使用しませんが、モバイル回線機能を常に稼動させ続け電力消費を増大させます。 <p> +(参考 <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>)<p>このkeepalive設定はクライアント側からは変更できません。OpenVPNのシステム管理者のみが変更可能です。 <p> 残念なことに、60秒より大きな間隔のUDP keepaliveはいくつかのNATゲートウェイにおいては接続状態が維持できず、それより短い時間でタイムアウトします(検証では60秒)。 TCP keepaliveと長いタイムアウト時間の使用は、動作はしますがTCP over TCP問題を引き起こします。(詳細は<a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">なぜTCP over TCPは悪いアイディアなのか</a>を参照) Androidのテザリング機能(WiFi, USB, Bluetooth経由)とVPNService API(このプログラムから使用する機能)は同時に利用できません。詳細については<a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a>を参照 VPN とテザリング 接続の再試行回数 @@ -271,7 +279,6 @@ OpenVPNの接続を保証するためには、アプリケーションを高い 暗号化方式 パケット認証 パケット認証方式を入力してください。 - %1$s (%2$s) %3$s、Android API %4$d、バージョン %5$s %6$s において実行中 %s によりビルド デバッグ ビルド 正式ビルド @@ -293,25 +300,28 @@ OpenVPNの接続を保証するためには、アプリケーションを高い 許可アプリの一覧をクリアしますか?\n現在の許可アプリ一覧:\n\n%s スクリーンがオフかつ60秒で64kB以下のデータ転送量の場合、VPN通信を中断します。「永続的なTUN」設定が有効な場合、VPN接続が中断されると通信ができなくなります。「永続的なTUN」を無効にすると、VPNによる接続保護は行われなくなります。 画面オフ後にVPN接続を中断 - 警告: このVPN接続には永続的なTUNが設定されていません。スクリーンオフ後の通信は通常のインターネット接続を使用します。 + 画面オフにより接続を中断しています: %2$s秒で%1$s 以下 + 警告: このVPN接続には永続的なTUNデバイスが設定されていません。スクリーンオフ後の通信は通常のインターネット接続を使用します。 パスワードを保存 - VPN一時停止 + VPNを中断 VPN再開 - ユーザによってVPN一時停止が要求されました - VPN一時停止中 - screenオフ - デバイス固有のhacks + ユーザによってVPNの中断が要求されました + VPN中断中 - 画面オフ + デバイス固有のハック 証明書の情報が表示できません。 アプリケーションの挙動 VPN の挙動 VPNプロファイルの変更を許可する ハードウェアのキーストア: OpenVPN for Androidを使用しようと試みるアプリのアイコン - Android 4.3以降用VPN確認ダイアログ + Android 4.3で使用した場合、VPN確認画面はオーバーレイ(常に画面全体を覆う表示)を使用するアプリから保護されます。この結果、ダイアログはタッチ操作に反応しなくなります。もしあなたがオーバーレイを使用したアプリを使っていたらこの挙動に遭遇するでしょう。もしあなたがこういった無作法なアプリを見つけたら、そのアプリの作者に連絡しましょう。この問題はAndroid 4.3以降でVPNアプリケーションすべてに影響します。詳細は <a href=\"https://github.com/schwabe/ics-openvpn/issues/185\">Issue 185<a> を参照してください。 + VPN確認ダイアログ ほかの手段として、Play Storeで私に寄付できます。 %s の寄付をお寄せいただきありがとうございます! ログがクリアされました。 パスワードを表示する キーチェーン アクセス エラー: %s + 短め ISO タイムスタンプ なし @@ -331,4 +341,76 @@ OpenVPNの接続を保証するためには、アプリケーションを高い いくつかのファイルが見つかりませんでした。プロファイルをインポートするファイルを選択してください: このアプリを使用するには、(多くの場合、あなたの雇用者によって提供される)OpenVPNをサポートするVPNプロバイダ/ VPNゲートウェイが必要です。あなた独自のOpenVPNサーバーをセットアップするためにはhttp://community.openvpn.net/ をチェックしてください。 インポートログ: + VPNトポロジ \"%3$s\" が設定されていますが ifconfig %1$s %2$s はIPアドレスとネットマスクのように見えます。\"サブネット\"トポロジを仮定します。 + MSSに指定できる値は0~9000の整数です + OpenVPNがカプセル化したあとのパケットサイズで制限するようトンネル越しのTCPセッションに通知します。結果、OpenVPNが相手に送信するUDPパケットサイズはこのバイト数を超えなくなります。(デフォルトは1450) + TCPペイロードのMSSを指定する + TCPペイロードのMSSを設定 + クライアント動作 + 許可された外部アプリをクリア + 読み込み中... + 許可されたVPNアプリケーション:%1$s + 許可されていないVPNアプリ:%1$s + パッケージ %s はインストールされていないため、許可/不許可アプリリストから削除します + VPNは選択したアプリ以外のすべてのアプリから使用されます + VPNは選択されたアプリのみで使用できます + 接続先設定を削除しますか? + 保持 + 削除 + 新しい接続先を追加 + 接続時に接続先をランダムに使用する + 少なくとも一つ以上の接続先を設定し有効化する必要があります + 接続先リスト + 許可されたアプリ + 詳細設定 + ペイロードオプション + TLSの設定 + 接続先が設定されていません + VPNプロファイルを複製 + プロファイルの複製:%s + ログを表示 + Android用のOpenVPNクライアントは複数あります。主なものとしては「OpenVPN for Android」(このアプリ)「OpenVPN Connect」「OpenVPN Settings」があります。<p>クライアントは大きく2種類に分けられます。「OpenVPN for Android」「OpenVPN Connect」は公式なVPNService API (Android 4.0以降)を使用しroot権限は不要です。「OpenVPN Settings」はroot権限が必要です。<p>「OpenVPN for Android」はオープンソースのクライアントでArne Schwabeにより開発されています。詳しい人をターゲットとして、多くの設定とファイルからのプロファイルインポート、アプリ内でのプロファイル設定変更ができるようになっています。コミュニティ版のOpenVPN 2.xのソースコードをベースとしています。コミュニティの準公式クライアントとみなせます。<p>「OpenVPN Connect」はOpenVPN Technologies, Incにより開発されておりオープンソースではありません。より一般的な使い方と平均的なユーザをターゲットとしており、OpenVPNプロファイルのインポートができます。OpenVPNプロトコルのC++による再実装コードをベースとしています(これはOpenVPN Technologies, IncがiOS版を公開するために必要でした)。OpenVPN Technologies, Incの公式クライアントです。<p> 「OpenVPN Settings」は最も古いクライアントであり、オープンソースのOpenVPN用のUIです。「OpenVPN for Android」との大きな違いはroot権限を必要とし、かつVPNService APIを使用しないことです。Android 4.0以降に依存しません。 + OpenVPN Androidクライアント間の違い + マルチキャストされた経路を無視します: %s + AndroidはVPNへの経路としてCIDRのみサポートします。非CIDR経路はほとんど使用されないため、OpenVPN for Androidは非CIDR経路に/32を使用し、警告を発します。 + テザリングはVPNが接続中でも有効です。ただしテザリングした通信はVPNを使用できません。 + 初期のKitKatはTCP接続において間違ったMSS値を使用します。(#61948). このバグを回避するにはmssfixオプションの有効化を試してください。 + AndroidはDNSサーバの設定がされていない場合、モバイル/WiFiのプロキシ設定を使用し続けます。OpenVPN for Androidはこれについてログにて警告します。

VPNがDNSサーバを設定した場合、Androidはプロキシを使用しなくなります。VPNでプロキシを使用するよう設定するAPIは存在しません。

+ VPNアプリはアンインストール/再インストール時に正常に動作しなくなることがあります。詳細は#80074を参照してください。 + 設定されたクライアントIPとネットマスクに含まれるIPアドレスはVPNを経由しません。OpenVPNは明示的に経路を追加することでこのバグを回避します。 + ほかのTUNデバイスが使用されている間に、永続的なTUNデバイス機能のためにTUNデバイスを開こうとするとデバイス上のVPNServiceがクラッシュします。VPNが再び動作するためにはデバイスの再起動が必要です。OpenVPN for Androidはクラッシュを避けるため、新しいTUNデバイスを開く前に現在のTUNデバイスを閉じます。これは短期間、パケットが非VPN接続に送信される原因になります。この回避策があっても、VPNServiceは時々クラッシュし、デバイスの再起動が必要になります。 + VPNはほかのユーザーに対しては動作しません。 + "複数のユーザが、VPNアプリ使用中にモバイル接続が頻繁に欠落すると報告しています。この挙動は特定のプロバイダ/デバイスの組み合わせでのみ発生すると思われ、これまでのところこのバグに対する原因や回避策は特定されていません。" + VPNなしでも到達可能なネットワークにのみVPN経由で到達できる場合。IPv6 VPN は動作しません。 + 非CIDRルート + VPNのプロキシ動作 + VPNアプリを再インストールする場合 + %sおよびそれ以前 + %sのコピー + 設定されたIPアドレスへの経路 + VPN接続に不正なMSS値 + タブレットの複数ユーザー + カスタム指定の接続オプションを設定します。慎重に利用してください + カスタムオプション + 接続エントリを削除します + モバイルネットワークが突発的に切断される + リモートネットワークに到達できない + 持続的なTUNモード + %s以降 + SSL23_GET_SERVER_HELLO:sslv3 alert handshake failureで接続が失敗する + OpenVPN for Androidの新しいバージョン(0.6.29/March 2015)は、暗号化スイートが許す限りよりセキュアなデフォルトを使用します(tls-cipher \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\")。 残念なことに、欠陥のある暗号化スイートあるいは輸出用暗号化スイート、特にPerfect Forward Secrecy (Diffie-Hellman)に欠陥がある暗号化スイートでは問題を生じます。これらは通常、サーバのtls-cipherの設定や最小限のSSLを実装した組み込みOS(例えば MikroTik)で、よりTLSセキュリティを強化しようとした善意での、しかし不完全な試みにより生じます\nこの問題を解決するには、サーバ側で tls-cipher に \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\" のような妥当なデフォルトを設定します。この問題のクライアント側の回避策としては、カスタムオプションに tls-cipher DEFAULT を追加します。 + このプロファイルは外部のアプリ(%s)より追加され、ユーザによる編集が無効化されています + 証明書失効リスト + OpenVPNを再起動しています(クラッシュしたか、メモリ不足により停止させられたため) + 設定のインポートでエラーが発生したため、保存できません。 + 検索 + 新規接続時にログをクリアする + 接続タイムアウト + OpenVPN for Androidは見失ったファイルを自動でSDカードから再探索することができます。このメッセージをタップして権限のリクエストを行ってください。 + プロトコル + 有効 + Preferred native ABI precedence of this device (%1$s) and ABI reported by native libraries (%2$s) mismatch + 残り %dヵ月 + 残り %d日 + 残り %d時間
diff --git a/app/src/main/res/values-ko/strings-icsopenvpn.xml b/app/src/main/res/values-ko/strings-icsopenvpn.xml index 4a4273d8..ce748cfa 100755 --- a/app/src/main/res/values-ko/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ko/strings-icsopenvpn.xml @@ -87,9 +87,9 @@ VPN을 통해 모든 트래픽을 보냅니다. 기본 라우트 사용하기 사용자 지정 라우트를 입력하십시오. 목적지는 CIDR 형식으로만 입력하십시오. \"10.0.0.0/8 2002::/16\"은 10.0.0.0/8 과 2002::/16 네트워크를 VPN으로 보냅니다. - VPN을 통해 라우팅하지 말아 경로. 포함 경로와 동일한 구문을 사용합니다. + VPN을 통해 라우팅되면 안되는 경로(라우트). 포함된 경로와 동일한 구문을 사용합니다. 사용자 지정 라우트 - 123456 + 제외된 네트워크 로그의 자세한 정도 인증된 패킷은 IP와 상관없이 허용 플로팅 서버 허용 @@ -103,6 +103,8 @@ TUN 인터페이스 열기: 로컬 IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d DNS 서버: %1$s, 도메인: %2$s + 경로: %1$s %2$s + 제외된 경로: %1$s %2$s 인터페이스 정보 %1$s와 %2$s에 있어, 두 번째 주소를 원격 피어 주소로 가정 하겠습니다. 로컬 IP의 넷마스크로는 /32를 사용하겠습니다. OpenVPN에 의해 주어진 모드는 \"%3$s\" 입니다. CIDR 넷마스크가 있는 IP 라우트 %1$s 와 %2$s 에 있어서 처리가 불가능합니다. /32를 넷마스크로 사용하겠습니다. %1$s/%2$s 에서 %3$s/%2$s로 라우트 수정 @@ -177,7 +179,6 @@ 안드로이드 keystore에서 CA 인증서를 찾지 못했습니다. Auhtentication은 실패할 것 입니다. 연결시 로그 윈도우를 보여드립니다. 로그 윈도우는 항상 notification status에서 접근이 가능합니다. 로그 윈도우 보기 - %1$s (%2$s) %3$s, 안드로이드 API %4$d 에서 실행 안드로이드 keystore 키 %1$s: %2$s과 싸이닝 오류 시스템에서는 VPN연결 경고를 통해 당신에게 본앱이 모든 트래픽을 가로챌수있다는 점을 알리게 되어 있는데 이는 VPNService API가 남용하는것을 막기 위함입니다.\nVPN 연결 알림 (키 아이콘) 또한 안드로이드 시스템에서 부과하는 부분이며 이는 VPN연결을 알리는 신호입니다. 어떤 버전에서는 소리를 알림으로 사용하는 경우도 있습니다.\n안드로이드는 이같은 방법을 당신의 안전을 위해 도입하였으며 사용은 필수적입니다. (어떤 버전에서는 유감스럽게도 소리 알림 또한 포함됩니다.) 연결 경고 및 알림 소리 @@ -256,7 +257,6 @@ 암호화 암호 패킷 인증 패킷 인증 방법을 입력한다 - %1$s (%2$s) %3$s, 안드로이드 API %4$d, 버전 %5$s, %6$s에서 실행 개발자 %s 디버그 빌드 공식 빌드 @@ -282,6 +282,7 @@ 경고: 이 VPN은 persistent tun이 비활성화 되어있습니다. 화면이 꺼졌을 때 트래픽은 터널을 사용하지 않고 인터넷을 바로 사용합니다. 암호 저장 VPN 일시중지 + VPN 재개하기 VPN 일시 정지 사용자의 요청 VPN 일시정지됨 - 화면 끄기 장치 관련 Hacks @@ -309,4 +310,12 @@ 처리 되지 않은 예외: %1$s\n\n%2$s %3$s: %1$s\n\n%2$s 전체 라이센스 + 사용자 이름/암호 파일 + MSS override의 값은 0과 9000 사이의 정수이어야합니다 + 로드 중... + 유지 + 삭제 + 페이로드 옵션 + TLS 설정 + 안드로이드 OpenVPN 클라이언트 간의 차이 diff --git a/app/src/main/res/values-nl/strings-icsopenvpn.xml b/app/src/main/res/values-nl/strings-icsopenvpn.xml index 2b3468e3..e05b9105 100755 --- a/app/src/main/res/values-nl/strings-icsopenvpn.xml +++ b/app/src/main/res/values-nl/strings-icsopenvpn.xml @@ -20,7 +20,7 @@ PKCS12 Bestand CA Certificaat Je moet een certificaat selecteren - De broncode en bugs zijn te vinden op http://code.google.com/p/ics-openvpn/ + De broncode en bugs zijn te vinden op https://github.com/schwabe/ics-openvpn/ Het programma gebruikt de volgende componenten. Zie de broncode voor volledige details over de licenties. Over Profielen @@ -30,9 +30,9 @@ Je moet een bestand selecteren Gebruik TLS autentificatie TLS Richting - Voer een IPv6 Adres/Netmask in met het CIDR Formaat (v.b. 2000:dd::23/64) - Voer een IPv4 Adres/Netmask in met het CIDR Formaat (v.b. 1.2.3.4/24) - IPv4 Adres + Voer een IPv6 Adres/Netmask in met het CIDR Formaat (b.v. 2000:dd::23/64) + Voer een IPv4 Adres/Netmask in met het CIDR Formaat (b.v. 1.2.3.4/24) + IPv6 Adres IPv4 Adres Geavanceerde OpenVPN opties. Veel van de tun gerelateerde OpenVPN instellingen worden niet ondersteund. Als u denkt dat een belangrijke optie ontbreekt, neem dan contact op met de auteur. Gebruikersnaam @@ -106,8 +106,10 @@ %1$s %2$s Logboek verzenden Verzenden + Kopiëer de log ingave naar het clip bord Tap mode De VPN API van Android werkt zonder rooten van de telefoon en ondersteunt alleen de tun modus. Daarom is de tap modus niet mogelijk met deze app. + Alweer? Maak je een grapje? Nee, tap mode wordt echt niet ondersteund en meer mails sturen met het verzoek of het ondersteund kan worden zal echt niet helpen, dus Neen. Veelgestelde vragen Codering Codering methode diff --git a/app/src/main/res/values-no/strings-icsopenvpn.xml b/app/src/main/res/values-no/strings-icsopenvpn.xml index bd71a77c..d4fa66a4 100755 --- a/app/src/main/res/values-no/strings-icsopenvpn.xml +++ b/app/src/main/res/values-no/strings-icsopenvpn.xml @@ -125,7 +125,6 @@ Nettverksstatus: %s Velg Vis logg-vindu - Kjører på %1$s (%2$s) %3$s, Android API %4$d Norsk oversettelse av Jonny IP og DNS Grunnleggende diff --git a/app/src/main/res/values-pl/strings-icsopenvpn.xml b/app/src/main/res/values-pl/strings-icsopenvpn.xml index dece207b..0e76b956 100755 --- a/app/src/main/res/values-pl/strings-icsopenvpn.xml +++ b/app/src/main/res/values-pl/strings-icsopenvpn.xml @@ -8,8 +8,8 @@ Adres serwera: Port serwera: - Lokalizacja - Nie można odczytać katalogu + Ścieżka + Nie mogę odczytać katalogu Wybierz Anuluj Brak danych @@ -18,11 +18,11 @@ Certyfikat klienta Klucz certyfikatu klienta Plik PKCS12 - Certyfikat urzędu certyfikacji + Certyfikat CA Musisz wybrać certyfikat - Kod źródłowy i formularz zgłoszeniowy błędów dostępny pod http://code.google.com/p/ics-openvpn/ + Kod źródłowy i formularz zgłoszeniowy błędów dostępny pod https://github.com/schwabe/ics-openvpn/ Program ten wykorzystuje następujące składniki; Szczegółowe informacje o licencjach w kodzie źródłowym - O + O programie Profile Typ Hasło PKCS12 @@ -46,8 +46,8 @@ Musisz wybrać certyfikat użytkownika Brak błędów Błąd w konfiguracji - Błąd parsowania adresu IPv4 - Błąd parsowania niestandardowych tras + Błąd analizowania adresu IPv4 + Błąd analizowania niestandardowych tras (Pozostaw puste, aby wywołać na żądanie) Skrót OpenVPN Połącz się z siecią VPN @@ -63,15 +63,21 @@ Anuluj potwierdzenie Odłącz podłączone VPN / zrezygnować z próby połączenia? Usuń VPN + Sprawdza, czy serwer używa certyfikatu z rozszerzeniami serwera TLS (--remote-cert-tls server) Oczekiwanie na certyfikat TLS z serwera + Sprawdza podmiot DN certyfikatu zdalnego Weryfikuj nazwę domenową zawartą w certyfikacie - Temat zdalnego certyfikatu + Określ czynność weryfikującą DN zdalnego certyfikatu (np. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nUżyj pełnego DN lub RDN (przykładowo penvpn.blinkt.de), lub prefiks RDN w celu weryfikacji\n\nUżywając prefiksu \"Serwer\", RDN będzie prawidłowy dla \"Serwer-1\" lub \"Serwer-Agaty\"\n\nPozostawiając pole puste RDN będzie sprawdzany pod kątem nazwy serwera.\n\nAby uzyskać więcej informacji, spójrz do podręcznika OpenVPN 2.3.1 w dziale —verify-x509-name + Podmiot zdalnego certyfikatu Włącza uwierzytelnianie kluczem TLS Plik TLS + Pobierz z serwera adresy IP, trasy oraz inne opcje. + Żadne opcje nie będą pobierane z serwera, należy je ustawić poniżej. Pobierz ustawienia DNS Nadpisz DNS z serwera Użyj własnych serwerów DNS + searchDomain Używany serwer DNS. Serwer DNS Pomocniczy serwer DNS używany, jeśli normalny serwer DNS jest nieosiągalny. @@ -80,9 +86,13 @@ Ignoruj trasy serwera. Przekieruj cały ruch przez tunel VPN Użyj domyślnej trasy + Wprowadź własne trasy. Muszą być wprwadzone w formacie CIDR. \"10.0.0.0/8 2002::/16\" przekieruje ruch z 10.0.0.0/8 i 2002::/16 przez VPN. + Trasy, które NIE powinny być kierowane przez VPN. Użyj tej samej składni, jak w trasach opcjonalnych. Opcjonalne trasy + Wykluczone Sieci Poziom logowania Zezwalaj uwierzytelnionym pakietom z każdego IP + Zezwól na \"pływający\" serwer. Opcje użytkownika Edytuj ustawienia VPN Usunąć profil VPN \'%s\'? @@ -93,14 +103,22 @@ Otwieram interfejs tun: Lokalne IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d Serwer DNS: %1$s, Domena: %2$s + Trasy: %1$s %2$s + Wykluczone trasy: %1$s %2$s + VpnService dodano trasy: %1$s %2$s + Interfejs uzyskał %1$s oraz %2$s, zakładam, że drugi adres jest adresem zdalnym - peer. Użyto maski /32 dla lokalnego IP. Tryb OpenVPN to \"%3$s\". + %1$s i %2$s, nie są trasami IP w formacie CIDR, używam /32 jako maski sieci. + Poprawiłem trasę %1$s/%2$s na %3$s/%2$s + Nie mam dostępu do pęku kluczy Androida. Może być to spowodowane aktualizacją systemu lub przywróceniem kopii aplikacji lub jej opcji. Proszę, edytuj połączenie VPN i wybierz ponownie certyfikat w opcjach, w celu odtworzenia pozwoleń dostępu do certyfikatu. %1$s %2$s Wyślij loga Wyślij Plik logów ICS OpenVPN Skopiowano log do schowka Tryb TAP - Tryb TAP nie jest możliwy z nierootwanym API VPN. Dlatego ta aplikacja nie zapewnia wsparcia TAP - Znowu. Żartujesz sobie? Tryb tap jest naprawdę nie wspierany, a wysyłanie więcej maili o to czy będzie wsparcie wcale nie pomoże. + Tryb tap nie jest możliwy z API VPN bez użycia root-a. W związku z powyższym ta aplikacja nie wspiera tap + Jeszcze raz?! Raczysz sobie żartować... Tryb tap naprawdę nie jest wspierany, a zasypywanie mnie wiadomościami z tego typu pytaniami naprawdę, ale to naprawdę nie pomaga... + Trzeci raz?! Właściwie można by napisać emulator tap bazując na tun, który dodawałby informacje layer2 przy wysyłaniu oraz ucinał opcje L2 przy odbiorze. No, ale wymagałoby to zaimplementowania ARP - i pewnie klienta DHCP. Pierwsze słyszę, by ktoś w ogóle to robił - skontaktuj się ze mną, jeśli masz plan pomocy przy współtworzeniu wspomnianego emulatora. FAQ Kopiowanie wpisów dziennika Aby skopiować pojedynczy wpis dziennika, naciśnij i przytrzymaj interesującą Cię pozycję. Celem skopiowania całego dziennika, należy użyć opcji Wyślij Log - jeżeli nie jest widoczna, użyj klawisza menu na obudowie urządzenia. @@ -110,75 +128,104 @@ Szyfrowanie Wprowadź metodę szyfrowania Wybierz algorytm szyfrowania wykorzystywany przez OpenVPN. Pozostaw puste, aby skorzystać z ustawień domyślnych. - Wprowadź dane logowania użyte do OpenVPN. Pozostaw puste, aby skorzystać z ustawień domyślnych. + Wprowadź tryb autoryzacji używany z OpenVPN. Pozostaw puste, aby skorzystać z ustawień domyślnych. Uwierzytelnianie/Szyfrowanie - Manager plików + Przeglądanie plików + Zawarte w pliku Błąd importu pliku Nie można zaimportować pliku z systemu [[Inline file data]] + Odmowa otwarcia urządzenia tun bez informacji o IP Wczytaj profil z pliku ovpn - Wczytaj + Importuj Nie można odczytać Profilu do importu Błąd podczas czytania pliku konfiguracyjnego Dodaj profil Nie można znaleźć pliku %1$s zawartego w zaimportowanym pliku Importowanie pliku konfiguracyjnego ze źródła %1$s - Skończono czytać plik konfiguracyjny. + Importowana konfiguracja zawierała kilka opcji, które nie są przypisane w interfejsie graficznym. Opcje te zostały dodane jako opcje dodatkowe. Opcje te wyświetlono poniżej: + Pomyślnie przeczytano plik konfiguracyjny. Nie przypisuj do lokalnego adresu i portu + Nie wiąż lokalnie Importuj plik konfiguracji + Zagadnienia dotyczące bezpieczeństwa + "Jako, że OpenVPN jest wrażliwe na bezpieczeństwo, kilka rozsądnych zdań na ten temat. Wszystke dane na karcie SD z zasady nie są bezpieczne. Każda aplikacja może je odczytać - dla przykładu, ten program nie wymaga żadnych specjalnych uprawnień do odczytu karty SD. Dane tej aplikacji mogą być odczytywane tylko przez nią samą. Używając opcji importu certyfikatów/CA lub kluczy, dane przechowywane są w profilu VPN. Profile VPN odczytywalne są tylko przez tę aplikację. (Nie zapomnij usunąc kopii z karty SD po imporcie). Rootując telefon, lub używając innych exploitów istnieje pradopodobieństwo odczytu tych danych. Zapisane hasła przechowywane są w postaci czystego tekstu. W przypadku plików PKCS12, jest wysoce zalecane, aby zaimportować je do magazynu kluczy Android." Importuj + Błąd przy wyświetlaniu wyboru certyfikatu + Wystąpił wyjątek w trakcie próby wyświetlenia okna z wyborem certyfikatu. To w ogóle nie powinno się zdarzyć, gdyż jest to standardowa opcja Androida 4.0+. Być może wsparcie dla magazynu certyfikatów w Twoim ROMie jest źle zaimplementowane IPv4 IPv6 Oczekiwanie na wiadomość powitalną… + profil zaimportowany + zaimportowano profil %d Uszkodzone obrazy + <p> Oficjalne obrazy HTC są znane z posiadania dziwnych problemów z routingiem powodując, że dane nie przepływają przez tunel (sprawdź także <a href=\"https://github.com/schwabe/ics-openvpn/issues/18\">Issue 18</a> w śledzeniu błędów). </p><p> Starsze oficjalne obrazy SONY dla Xperia Arc S oraz Xperia Ray są znane z całkowitego braku VPNService w obrazie. (Sprawdź także <a href=\"https://github.com/schwabe/ics-openvpn/issues/29\">Issue 29</a> w śledzeniu błędów). </p><p> We własnoręcznie kompilowanych obrazach może brakować modułu TUN, lub prawa dostępu do /dev/tun mogą być nieprawidłowe. Niektóre obrazy CM9 mogą wymagać opcji \"Popraw prawa dostępu\" w zakładce \"Dodatkowe opcje urządzenia\". </p><p>Co najważniejsze: jeśli Twoje urządzenie ma błędy w Android, zgłoś to producentowi. Im więcej osób zgłasza problemy, tym większe prawdopodobieństwo ich poprawy. </p> Klucz pliku PKCS12 Hasło klucza prywatnego Hasło plik ikony Uwierzytelnianie TLS - Wygenerowana konfiguracja + Utworzona konfiguracja Ustawienia + Stara się ustawić właściciela /dev/tun na system. Niektóre obrazy CM9 wymagają tego, aby API VPNService zaczęło działać. Wymaga root-a. Popraw uprawnienia do /dev/tun Pokazuje wygenerowany plik konfiguracji OpenVPN - Edycja \"%s\" + Edytujesz \"%s\" Tworzenie konfiguracji… Włączenie tej opcji spowoduje ponowne połączenie jeśli stan sieci się zmienił (np. z WiFi na GSM) Połącz ponownie przy zmianie sieci - Status sieci: %s + Stan sieci: %s + Certyfikat CA z reguły zwracany jest z pęku kluczy Androida. Wybierz zewnętrzny certyfikat, jeśli występują błędy w weryfikacji. Wybierz + Brak certyfikatu CA zwróconego z pęku kluczy Androida. Autoryzacja najprawdopodobniej nie powiedzie się. + Pokazuje okno dziennika przy łączeniu. Do okna dziennika można dostać się zawsze z paska powiadomień. Pokaż okno loga + %10$s %9$s na %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) + Błąd podpisania kluczem z pęku kluczy Androida %1$s: %2$s + Ostrzeżenie przy połączeniu VPN informuje Cię, że ta aplikacja przekierowuje cały ruch jest narzucona przez system w celu zapobieżenia nadużyciom API VPNService.\nPowiadomienie połączenia VPN (znak klucza) jest także narzucone przez Android, aby zasygnalizować połączenie z siecią VPN. Na niektórych obrazach Android to powiadomienie odtwarza dźwięk.\nAndroid wprowadził te dialogi systemowe dla Twojego bezpieczeństwa i aby upewnić się, że nie można ich obejść. (Niestety, na niektórych obrazach to także implikuje wydanie dźwięku) Ostrzeżenie połączeń oraz dźwięki powiadomień Angielskie tłumaczenie Arne Schwabe<arne@rfc2549.org> IP i DNS Podstawowe Routing + Niejasne ustawienia OpenVPN. Zazwyczaj nie są potrzebne. Zaawansowane - Konfiguracja ICS Openvpn + Konfiguracja Openvpn ICS + Nie są używane żadne serwery DNS. Rozpoznawanie nazw może nie działać. Rozważ ustawienie własnych serwerów DNS. Miej również na uwadze, że Android nadal będzie korzystać z ustawień proxy Twojego połączenia mobilnego/Wi-Fi, nawet gdy opcje DNS nie są ustawione. Nie można dodać serwera DNS \"%1$s\", odrzucone przez system: %2$s + Nie można skonfigurować adresu IP \"%1$s\", odrzucone przez system: %2$s + <p>Przygotuj działającą konfigurację (sprawdzoną na Twoim komputerze lub pobraną od Twojego dostawcy/pracodawcy)</p><p>Jeśli, jest to jeden plik - bez dodatkowych plików pem/pkcs12 - możesz taki plik wysłać do siebie e-mailem i otworzyć załącznik. Jeśli masz więcej, niż jeden plik - pobierz je na kartę SD.</p><p>Kliknij na załącznik w e-mailu/użyj ikony folderu na liście VPN, aby zaimportować plik konfiguracyjny.</p><p>Jeśli występują błędy brakującego pliku - umieść je na karcie SD.</p><p>Kliknij na ikonę zapisu, aby dodać zaimportowaną konfigurację do Twojej listy.</p><p>Połącz się z VPN klikając na nazwę połączenia VPN</p><p>Jeśli występują błędy/ostrzeżenia w logu, spróbuj je namierzyć i poprawić</p> Szybki start Próba załadowania modułu tun.ko kernel przez próbą połączenia. Potrzeba rootowanych urządzeń. Załaduj moduł tun - Importuj PKCS12 z konfiguracji do slepu kluczy Androida - Błąd ustawień proxy: %s - Użycie proxy %1$s%2$d + Importuj PKCS12 z konfiguracji do pęku kluczy Androida + Błąd pobierania ustawień proxy: %s + Używam proxy %1$s%2$d Użyj proxy systemowego - Użyj konfiguracji systemowej dla HTTP/HTTPS proxy w celu połączenia. + Połącz używając systemowej konfiguracji proxy HTTP/HTTPS. Możesz <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">wspomóc przez PayPal</a> - OpenVPN połączy VPN jeśli był aktywny przy restarcie/zamknięciu systemu. Proszę przeczytać FAQ ostrzeżenia połączenia przez użyciem tej opcji. - Połącz przy reboocie + OpenVPN połączy ponownie z VPN jeśli połączenie było aktywne przy restarcie/zamknięciu systemu. Przeczytaj proszę FAQ z ostrzeżeniami przed użyciem tej opcji. + Połącz po restarcie Ignoruj - Restartuj + Uruchom ponownie Zmiany konfiguracji będą zatwierdzone po restarcie VPN. Uruchomić ponowie teraz? Zmieniono konfigurację Nie można ustalić ostatnio połączonego profilu do edycji Podwójne powiadomienia - Nie zdefiniowano żadnego profilu. + Jeśli Android ma obciążoną pamięć (RAM), aplikacje i usługi, które nie są aktualnie potrzebne są usuwane z pamięci. To potrafi zakończyć aktualne połączenie VPN. Aby upewnić się, że połączenie/OpenVPN przetrwa usługa uruchomiona jest z wyższym priorytetem. Aby działać z wyższym priorytetem ta aplikacja musi wyświetlać powiadomienie. Ikona klucza jest narzucona przez system w sposób opisany w poprzednim wpisie FAQ. To nie liczy się jako powiadomienie w celu działania z wyższym priorytetem. + Brak połączeń VPN. + Użyj ikony <img src=\"ic_menu_add\"/> aby dodać nowe połączenie VPN + Użyj ikony <img src=\"ic_menu_archive\"/> aby zaimportować istniejący profil (.ovpn lub .conf) z karty SD. Sprawdź także nasze FAQ. Znajdziesz tam krótki poradnik dla początkujących. Konfiguracja trasy/interfejsu + Konfiguracja routingu i interfejsów nie odbywa się za pomocą tradycyjnych komend ifconfig/route, lecz za pomocą API VPNService. Powoduje to inną konfigurację trasowania, niż ma to miejsce w innych systemach operacyjnych.\nKonfiguracja tunelu VPN składa się z listy adresów IP oraz sieci, które powinny być trasowane przez interfejs. Dzięki temu nie jest potrzebny ani wymagany adres peer\'a lub bramy. Trasy specjalne wymagane do połączenia z serwerem VPN także nie są wymagane (np. te dodawane w przypadku użycia redirect-gateway). Aplikacja podczas importu konsekwentnie ignoruje te ustawienia. Aplikacja poprzez API VPNService upewnia się, że połączenie do serwera nie jest realizowane przez tunel VPN.\nAPI VPNService nie zezwala na ustawianie sieci, które NIE powinny być trasowane przez VPN, jako obejście aplikacja stara się wykryć te sieci, które nie powinny być trasowane przez tunel (np. route x.x.x.x y.y.y.y net_gateway) i oblicza zestaw tras, które wyklucza emulując zachowanie na innych platformach. Okno dziennika pokazuje konfigurację VPNService podczas wykonywania połączenia.\nZa kulisami: Android 4.4+ używa polityki trasowania. Użycie route/ifconfig nie pokaże aktualnie zainstalowanych tras. Zamiast tego użyj ip rule, iptables -t -mangle -L + Nie używaj sieci niezabezpieczonych VPN podczas ponownego łączenia przez OpenVPN. Persistent tun Log OpenVPN Importuj konfigurację OpenVPN Zużycie baterii + Podczas osobistych testów odkryłem, iż głównym powodem sporego zużycia baterii przez OpenVPN są pakiety keepalive. Większość serwerów OpenVPN ma ustawienie \'keepalive 10 60\', które narzuca klientowi oraz serwerowi wymianę pakietów keepalive co 10 sekund. <p> Podczas, gdy te pakiety są małe i nie zużywają wiele pasma, utrzymują one radio komórkowe w trybie pracy i zwiększają zużycie energii. (Sprawdź także <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Ustawienie keepalive nie może być zmienione po stronie klienta. Tylko administrator serwera OpenVPN jest w stanie zmienić to ustawienie. <p> Niestety, w przypadku UDP niektóre konfiguracje NAT źle tolerują ustawienie keepalive większe niż 60 sekund powodując odrzucanie pakietów z powodu nieaktywności połączenia. Używanie protokółu TCP z większym timeout działa, jednak tunelowanie TCP-po-TCP bardzo źle się sprawuje przy połączeniach z dużą stratnością pakietów. (See <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>) + Funkcja Android Tethering (przez WiFi, USB lub Bluetooth) i interfejs API VPNService (stosowany przez ten program) nie działają razem. Aby uzyskać więcej informacji zobacz <href=\"https://github.com/schwabe/ics-openvpn/issues/34\"> problem #34 </a> VPN i Tethering Próby połączenia Ustawienia ponownego połączenia @@ -210,9 +257,9 @@ Łączę z VPN %s Łączę z VPN %s Niektóre wersje Androida 4.1 mają problemy, jeśli nazwa certyfikatu zawiera niealfanumeryczne znaki (spacje, podkreślenia, myślniki). Spróbuj zaimportować certyfikat bez znaków specjalnych + Szyfr kodujący Pakiety uwierzytelniania Wpisz metodę uwierzytelniania pakietów - Działa na %1$s (%2$s) %3$s, Android API %4$d, wersja %5$s, %6$s zbudowany przez %s Kompilacja z debugiem Oficjalna kompilacja @@ -227,6 +274,7 @@ tls-remote (PRZESTARZAŁE) Możesz pomóc w tłumaczeniu odwiedzająć http://crowdin.net/project/ics-openvpn/invite %1$s próby kontroli %2$s + Akceptując, dajesz aplikacji uprawnienia do pełnego kontrolowania przez OpenVPN całego ruchu sieciowego. Nie akceptuj, jeżeli nie ufasz aplikacji w pełni. W przeciwnym razie istnieje ryzyko przejęcia danych przez złośliwe oprogramowanie Ufam tej aplikacji. Żadna aplikacja nie ma pozwolenia do używania zewnętrznego API Dozwolone aplikacje: %s @@ -260,4 +308,81 @@ Wysyłanie Pobieranie Status VPN + Opcje widoku + Nieobsługiwany wyjątek: %1$s\n\n%2$s + %3$s: %1$s\n\n%2$s + Pełne licencje + Sieci połączone bezpośrednio do lokalnych interfejsów nie będą kierowane przez VPN. Odznaczając tę opcję przeniesiesz cały ruch przeznaczony dla sieci lokalnych przez VPN. + Obejdź VPN dla sieci lokalnych + Plik użytkowników/haseł + [Importowane z: %s] + Nie mogę odnaleźć niektórych plików. Wybierz je, aby zaimportować profil: + Aby skorzystać z tej aplikacji potrzebujesz dostawcy lub bramy VPN obsługującej OpenVPN (często świadczonych przez pracodawcę). Aby uzyskać więcej informacji o OpenVPN i dowiedzieć się jak stworzyć własny serwer zajrzyj na http://community.openvpn.net/ + Dziennik importu: + Określono topologię \"%3$s\", jednak ifconfig %1$s %2$s wygląda bardziej na adres IP z maską. Zakładam, że chodzi o topologię \"subnet\". + Wartość nadpisywania MSS musi być liczbą całkowitą pomiędzy 0 i 9000 + Ogłasza sesjom TCP przekazywanym przez tunel, że powinny ograniczyć wielkość pakietu tak, aby po enkapsulacji przez OpenVPN wynikowy rozmiar pakietu UDP wysyłanego przez VPN do peer\'a nie przekraczał tej liczby bajtów (domyślnie 1450) + Zastępuje wartość MSS pakietu TCP + Ustaw wartość MSS pakietu TCP + Zachowanie klienta + Wyczyść dozwolone aplikacje + Trwa ładowanie… + Dozwolone aplikacje VPN: %1$s + Niedozwolone aplikacje VPN: %1$s + Aplikacja %s nie jest już zainstalowana, usuwam ją z listy dozwolonych/zabronionych + VPN jest używany dla wszystkich aplikacji, ale wyklucza wybrane + VPN jest używany tylko dla wybranych aplikacji + Usunąć wpis serwera? + Zachowaj + Usuń + Dodaj nowy + Użyj wpisów w losowej kolejności przy próbie połączenia + Musisz zdefiniować i włączyć co najmniej jeden serwer. + Lista serwerów + Dozwolone aplikacje + Opcje zaawansowane + Opcje ładunku + Ustawienia TLS + Nie ustawiono zdalnego + Powiel profil VPN + Powielam profil: %s + Pokaż dziennik + Różnice pomiędzy klientami OpenVPN dla Androida + Ignoruj trasę multicast: %s + Android wspiera tylko trasy CIDR w sieci VPN. Jako, że trasy nie-CIDR nie są powszechnie używane, OpenVPN dla Androida użyje /32 dla tras w formacie nie-CIDR i wyświetli błąd. + Tethering działa podczas połączenia z VPN. Udostępnione połączenie NIE będzie używało VPN. + Wczesne wersje KitKat ustawiają złą wartość MSS połączeń TCP (#61948). Spróbuj ustawić opcję mssfix w celu obejścia tego problemu. + Aplikacje VPN mogą przestać działać po odinstalowaniu i ponownej instalacji. W celu uzyskania szczegółów zobacz #80074 + VPN absolutnie nie działa dla dodatkowych użytkowników. + "Jest grono użytkowników, którzy donoszą, iż podczas używania aplikacji VPN połączenie danych/komórkowe jest często zrywane. Zachowanie to wydaje się dotykać niewielkiej liczby urządzeń/dostawców danych komórkowych - na tę chwilę nieznana jest przyczyna, ani rozwiązanie problemu." + Trasy nie-CIDR + Zachowanie Proxy w sieci VPN + Ponowna instalacja aplikacji VPN + %s i wcześniejsze + Kopia %s + Trasa do skonfigurowanego adresu IP + Błędna wartość MSS dla połączenia VPN + Dodatkowi użytkownicy tabletu + Określ własne opcje dla połączenia. Używaj z rozwagą + Opcje niestandardowe + Usuń wpis połączenia + Losowe rozłączenia z sieci komórkowej + Zdalne sieci nie są osiągalne + Tryb persist tun + %s i późniejsze + Ten profil został dodany przez zewnętrzną aplikację (%s) i został oznaczony jako nie edytowalny przez użytkownika. + Listy odwoławcze CRL + Restartuję usługę OpenVPN (Aplikacja wywaliła się lub zabito ją z powodu braku pamięci) + Importowanie konfiguracji wyrzuciło błąd, nie mogę tego zapisać + Szukaj + (Ostatni zrzut sprzed %1$d:%2$dh, (%3$s)) + Wyczyść dziennik przy nowym połączeniu + Limit czasu połączenia + Dodano niedozwoloną aplikację. Dodaję siebie (%s), żeby mieć przynajmniej jedną aplikację w liście dozwolonych aplikacji, aby nie pozwolić wszystkim aplikacjom + OpenVPN dla Android spróbuje automatycznie wykryć brakujące pliki na karcie SD. Dotknij tego komunikatu, aby żądać uprawnień. + Protokół + Włączony + pozostało %d miesięcy + pozostało %d dni + pozostało %d godzin diff --git a/app/src/main/res/values-ro/strings-icsopenvpn.xml b/app/src/main/res/values-ro/strings-icsopenvpn.xml index b368995d..ded69fb7 100755 --- a/app/src/main/res/values-ro/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ro/strings-icsopenvpn.xml @@ -174,7 +174,6 @@ Nici un certificat CA nu a fost returnat la citirea din keystore-ul Android. Autentificarea probabil va eşua. Afişează fereastra jurnal la conectare. Fereastra jurnal poate fi accesată oricând din statusul notificare. Arată fereastra Jurnal - Rulează pe %1$s (%2$s) %3$s, Android API %4$d Eroare semnare cu Android keystore key %1$s: %2$s Avertizarea la conexiunea VPN ce vă spune că această aplicaţie poate intercepta întreg traficul este impusă de sistem pentru a preveni abuzul funcţiei API VPNService.\nNotificarea de conexiune VPN(simbolul cheie)este de asemenea impusă de sistemul Android pentru a semnala o conexiune VPN în derulare. În cadrul unor imagini această notificare face şi un sunet.\nAndroid a introdus aceste notificări pentru siguranţa dvs. şi este asigurat că nu pot fi evitate. (Din păcate în anumite imagini acestea includ şi un sunet de notificare) Alertă conexiune şi sunet notificare @@ -252,7 +251,6 @@ Cifru criptare Autentificare pachete Introduceţi metoda de autentificare de pachete - Rulează pe %1$s (%2$s) %3$s, Android API %4$d, versiunea %5$s, %6$s compilat de %s versiune debug versiune oficială diff --git a/app/src/main/res/values-ru/strings-icsopenvpn.xml b/app/src/main/res/values-ru/strings-icsopenvpn.xml index 4af9e15c..921b5342 100755 --- a/app/src/main/res/values-ru/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ru/strings-icsopenvpn.xml @@ -180,7 +180,6 @@ Не удалось получить CA из хранилища ключей Android. Аутентификация не удалась. Показывает окно журнала при подключении. Окно журнала всегда может быть доступно из панели уведомлений. Показать окно журнала - Работает на %1$s (%2$s) %3$s, Android API %4$d Ошибка подписи с использованием ключа из хранилища Android %1$s: %2$s Предупреждение VPN соединения сообщает вам, что это приложение может перехватывать весь сетевой трафик, и сообщается системой предупреждений VPNService API.\nИзвещение о VPN соединении (символ \"Ключа\") также формируется системой Android для сигнализации исходящего VPN соединения. В некоторых прошивках это оповещение сопровождается сигналом.\nAndroid использует эти оповещения для вашей собственной безопасности и из нельзя обойти. (К сожалению, на некоторых прошивках также издается оповещение звуком) Сообщение о подключении и звук уведомления @@ -260,7 +259,6 @@ Алгоритм шифрования Проверка подлинности пакетов Укажите метод проверки подлинности пакетов - Запущен на %1$s (%2$s) %3$s, Android API %4$d, версии %5$s, %6$s создан %s сборка для отладки официальная сборка @@ -323,4 +321,55 @@ Для использования данного приложения Вам необходим VPN провайдер/шлюз поддерживающий OpenVPN. Для получения информации по настройке собственного OpenVPN сервера: http://community.openvpn.net/ Лог импорта: VPN топологии «%3$s» указан но ifconfig %1$s %2$s выглядит больше как IP-адрес с маской сети. Если топология «подсеть». + Значение, перезаписывающее MSS, должно быть целым числом от 0 до 9000 + Объявить TCP сессиям, работающим через туннель, что они должны ограниччить размер своих пакетов так, чтобы после их инкапсуляции OpenVPN, результирующий размер UDP пакета, который OpenVPN посылает своим пирам, не превышал это число байт. (1450 по умолчанию) + Переписать значение MSS для TCP нагрузки + Задать MSS для TCP нагрузки + Поведение клиента-программы + Очистить разрешенные внешние приложения + Загружается… + Разрешенные VPN приложения: %1$s + Запрещенные VPN приложения: %1$s + Пакет %s больше не установлен, происходит его удаление из списка разрешенных/запрещенных приложений + Использовать VPN для всех приложений, кроме выбранных + Использовать VPN только для выбранных приложений + Убрать запись удаленного сервера? + Сохранить + Удалить + Добавить новую удаленку + Использовать список подключений в случайном порядке при соединении + Вы должны определить и включить как минумум один удаленный сервер. + Список серверов + Разрешенные Приложения + Расширенные настройки + Опции нагрузки + Настройки TLS + Нет заданной удаленки + Дублировать VPN профиль + Дублирование профиля: %s + Показать журнал + Существуют различные OpenVPN клиенты для Android. Самые распространенные - OpenVPN for Android (этот клиент), OpenVPN Connect и OpenVPN Settings.<p>Клиенты можно разделить на две группы: OpenVPN for Android и OpenVPN Connect используют официальный VPNService API (Android 4.0+) и не трубуют root-доступ, и OpenVPN Settings, который требует root.<p>OpenVPN for Android - клиент с открытым исходным кодом, который разработал Arne Schwabe. Он предназначен для более опытных пользователей и предоставляет много настроек и возможность испорта профилей из файлов и настраивать/изменять профили внутри приложения. Этот клиент основан на общественной версии OpenVPN. На исходном коде OpenVPN 2.x. Этот клиент может быть представлен как полуофициальный клиент сообщества. <p>OpenVPN Connect - клиент с закрытым исходным кодом, который разработан OpenVPN Technologies, Inc. Он призван для обычного использования и предназначен для средних пользователей, и позволяет импортировать профили из OpenVPN. Этот клиент основан на OpenVPN C++ и написал с использванием протокола OpenVPN (Это требовалось для разрешения OpenVPN Technologies, Inc опубликовать приложение OpenVPN на iOS). Этот клиент - официальный клиент OpenVPN technologies <p> OpenVPN Settings - старейший из клиентов, а также UI для OpenVPN с открытым исходным кодом. В отличие от OpenVPN for Android, он требует root-прав и не использует VPNService API. Он не зависит от Android 4.0+ + Различия между OpenVPN Android клиентами + Игнорируется мультиадресный маршрут: %s + Android поддерживет только CIDR маршруты к VPN. Поскольку не CIDR маршруты почти никогда не используются, OpenVPN for Android будет использовать /32 для не CIDR маршрутов и выдавать предупреждение. + Тетеринг/раздача интернета работает, когда активен VPN. Модемное соединение (тетеринг) НЕ БУДЕТ использовать VPN. + Ранние версии KitKat устанавливают неверное значение MSS для TCP соединений (#61948). OpenVPN for Android автоматически включает опцию mssfix, чтобы обойти этот баг. + Android будет продолжать использовать ваши настройки прокси, указанные для мобильного/Wi-Fi соединения, когда не установлен DNS сервер. OpenVPN for Android предупредит вас об этом в журнале.

Когда VPN устанавливает DNS сервер Android не использует прокси. Для установки прокси для VPN соединения нет API.

+ VPN приложения могут перестать работать после удаления и повторной установки. Подробности см. #80074 + IP сконфигурированного клиента и IPs в его сетевой маске немаршрутизированны к VPN. OpenVPN обходит этот баг, явно добавляя маршрут, который соответствует клиентскому IP и его сетевой маске + Открытие туннеля, когда туннель уже активен, для его постоянного удержания, может привести к ошибке и VPNServices закроется на устройстве. Для возобновления работы VPN требуется перезагрузка. OpenVPN for Android пытается избежать установки второго туннеля, и если действительно нужно - сначала закрывает текущий туннель, перед открытием нового, чтобы избежать краха программы. Это может привести к маленькому интервалу, в котором передача пакетов происходит по обычному (не VPN) соединению. Даже с этими ухищрениями VPNServices иногда крашится и требует перезагрузки устройства. + VPN не работает совсем для вторичных пользователей. + "Различные пользователи сообщают, что мобильная связь/мобильная передача данных часто обрывается, когда используется VPN приложение. Такое поведение, кажется, затрагивает только некторые комбинации провайдеров/устройств, и пока что не выявлена причина/нет обхода этого бага." + Адреса могут работать через VPN только те, которые доступны без VPN. IPv6 VPN не работают вообще. + Не CIDR маршруты + Поведение прокси для VPN + Переустанавливаются приложения VPN + %s и ранее + Копия %s + Маршрутизация к установленному IP адресу + Неверное значение MSS для VPN соединения + Дополнительные пользователи устройства + Укажите особые пользовательские параметры подключения. Используйте с осторожностью + Пользовательские Параметры + Удалить запись подключения diff --git a/app/src/main/res/values-sv/strings-icsopenvpn.xml b/app/src/main/res/values-sv/strings-icsopenvpn.xml index 6ef522c4..b7510ef1 100755 --- a/app/src/main/res/values-sv/strings-icsopenvpn.xml +++ b/app/src/main/res/values-sv/strings-icsopenvpn.xml @@ -87,7 +87,9 @@ Omdirigerar all trafik över VPN-anslutningen Använd standardrutt Ange anpassade rutter. Skriv destination i CIDR-format. \"10.0.0.0/8 2002:: / 16\" dirigerar nätverk 10.0.0.0/8 och 2002:: / 16 över VPN. + Rutter som INTE bör dirigeras över VPN. Använd samma syntax som för ingående rutter. Anpassade rutter + Exkluderade nätverk Utförlighetsnivå för log Tillåter autentiserade paket från alla IP-adresser Tillåt flytande server @@ -174,7 +176,6 @@ Inget CA certifikat returnerades från Android Keystore. Autenticering kommer troligen att misslyckas. Visar loggfönstret vid anslutning. Loggfönstret kan alltid nås från statusgardinen. Visa loggfönstret - Kör på %1$s (%2$s) %3$s, Android API %4$d Fel vid signering med Android keystore nyckeln %1$s: %2$s Varningen vid VPN-anslutning som berättar att denna app kan avlyssna all trafik utfärdas av systemet för att förhindra missbruk av VPNService API.\nNotifieringen om VPN-anslutning (nyckelsymbolen) tillhandahålles också av Android-systemet för att signalera en pågående VPN-anslutning. På vissa ROM spelar denna notifiering ett ljud.\nAndroid har infört dessa dialogrutor och notifieringar för din egen säkerhet och kan inte undvikas. (På vissa ROM innehåller dessa tyvärr ljud) Anslutnings varning och ljud @@ -251,7 +252,6 @@ Krypteringschiffer Paketautentisering Ange autentiseringsmetod för paket - Kör på %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s byggd av %s felsöknings bygge officiellt bygge diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml index 94a120d1..100861fc 100644 --- a/app/src/main/res/values-sw600dp/dimens.xml +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/values-sw600dp/styles.xml b/app/src/main/res/values-sw600dp/styles.xml index c320388d..387b2a81 100644 --- a/app/src/main/res/values-sw600dp/styles.xml +++ b/app/src/main/res/values-sw600dp/styles.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/values-tr/strings-icsopenvpn.xml b/app/src/main/res/values-tr/strings-icsopenvpn.xml index 106f407f..a9622ff1 100755 --- a/app/src/main/res/values-tr/strings-icsopenvpn.xml +++ b/app/src/main/res/values-tr/strings-icsopenvpn.xml @@ -181,7 +181,7 @@ Hayır CA sertifikasını okurken Android deposunu döndürdü. Kimlik doğrulama muhtemelen başarısız olur. Bağlama kütüğü penceresi üzerinde gösterir. Kütüğü penceresi her zaman bildirim durumu erişilebilir. Günlüğü penceresini göster - %1$s (%2$s) %3$s, Android API %4$d d\'çalışması + %10$s %9$s %3$s %1$s (%2$s), Android %6$s (%7$s) API %4$d, ABI %5$s, (%8$s) üzerinde çalışıyor Android deposunun anahtarı %1$s %2$s ile imzalama hatası Bu app tüm trafiği geçirebilir belirten VPN bağlantısı uyarı dayatılan VPNService API.\nThe VPN bağlantısının istismarını önlemek için sistem tarafından bildirim (anahtar simgesi) da devam eden bir VPN bağlantısı sinyal için Android sistem tarafından uygulanmaktadır. Bu bildirim çalış bazı görüntülerde ses. \nAndroid kendi güvenliğiniz için bu sistem diyaloglar tanıttı ve circumenvented olamaz emin oldum. (Bazı görüntülerde bu unfortunely notifciation ses içerir) Bağlantı uyarı ve bildirim sesi @@ -219,6 +219,7 @@ Kullanım < img src = \"ic_menu_archive\" / > simgesi sdcard (.ovpn veya .conf) bir profili almak için. Ayrıca SSS kontrol etmeyi unutmayın. Hızlı Başlangıç Kılavuzu vardır. Yönlendirme/arabirimi yapılandırması + Yönlendirme ve arayüz konfigürasyonu klasik ifconfig / rota komutlarıyla değil VPNService API kullanarak yapılmaktadır. Bu diğer işletim sistemlerindekinden farklı bir yönlendirme konfigürasyonu gerektirmektedir.\n VPN tünelinin konfigürasyonu IP adresleri ve bu adreslerin bu arayüz üstünden yönlendirileceği ağlardan oluşur. Özellikle hiçbir eş ortak adresi ya da ağ geçidi adresi gerekli degildir. VPN sunucusuna ulaşmak için özel yollar (redirect-gateway kullanıldığında eklenenler gibi) da gerekli değildir. Bu sebepten dolayı uygulama, bir konfigurasyon alırken bu ayarları yoksayar. App, VPN Servis API\'sı ile sunucuyla olan bağlantının VPN tüneline yönlendirilmesini engeller.\n VPN servisi APIsı VPN üstünden yönlendirilmemesi gereken ağların belirtilmesine izin vermemektedir. Çözüm olarak program tünel üstünden yönlendirilmemesi gereken ağları (örneğin x.x.x.x y.y.y.y net_gateway rotası) bulmaya çalışıp bu rotaları içermeyen bir rota grubu oluşturarak diğer işletim sistemlerindeki davranışı oluşturur. Kütük penceresi VPN servisinin bağlantı sonucu oluşan konfigürasyonunu gösterir.\n Arka planda Android 4.4+ kural tabanlı yönlendirme kullanır. route/ifconfig komutları kullanılan rotaları göstermeyecektir. Bu komutlar yerine ip rule, iptables -t mangle -L komutlarını kullanın OpenVPN yeniden bağlamadan zaman VPN bağlantısı değil geri dönüş yap Kalıcı tun OpenVPN kayıtları @@ -260,7 +261,6 @@ Şifre şifresi Paket kimlik doğrulama Paket kimlik doğrulama yöntemini girin - Çalışan %1$s (%2$s) %3$s, Android API %4$d, sürüm %5$s, %6$s %s tarafından inşa hata ayıklama yapı resmi yapı @@ -314,12 +314,16 @@ Görünüm seçenekleri Kural dışı durum: %1$s\n\n%2$s %3$s: %1$s\n\n%2$s + Eğer android cihazınızı rootladıysanız <a href=\"http://xposed.info/\">Xposed </a> ve <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm modülünü</a> sorumluluğunu kendiniz alarak yükleyebilirsiniz Lisanslar Yerel ağlar için Bypass VPN Kullanıcı adı / Şifre dosyası [Buradan içeri aktar: %s] + Bazı dosyalar bulunamadı. Lütfen profile aktarılacak dosyaları seçiniz: Kaydı içe aktar: + MSS değeri 0 ile 9000 arasında bir tamsayı olmak zorundadır İstemci davranışı + İzin verilmiş harici uygulamaları temizle Yükleniyor… Izin verilen VPN uygulamaları: %1$s İzin verilmeyen VPN uygulamaları: %1$s @@ -330,19 +334,38 @@ Sakla Sil Yenı uzak sunucu ekle + Bağlanmak için bağlantı girişlerini rasgele bir sırada kullan En az bir uzak sunucu tanımlamalı ve etkinleştirmelisiniz. Sunucu Listesi İzin verilen uygulamalar Gelişmiş Ayarlar Yük seçenekleri TLS Ayarları + VPN profilini kopyala + Profil kopyalama: %s Günlüğü göster + Android için OpenVPN uygulamaları aralarındaki farklar + Multicast rotasını yoksayma:%s VPN\'ler için Proxy davranışı VPN uygulamaları yeniden yükleme %s ve önceki %s kopyası + Yapılandırılmış IP adresine yönlendir VPN bağlantısı için yanlış MSS değeri İkincil tablet kullanıcıları Özel bağlantı seçenekleri belirtin. Dikkatli kullanın Özel Seçenekler + Bağlantı girdisini kaldırın + Uzak ağlar ulaşılamıyor + Sürekli tun modu + %s ve daha sonra + Sertifika iptal listesi + Arama + Yeni bağlantıda günlüğü temizle + Bağlantı zaman aşımına uğradı + Protokol + Etkin + %d ay kaldı + %d gün kaldı + %d saat kaldı diff --git a/app/src/main/res/values-uk/strings-icsopenvpn.xml b/app/src/main/res/values-uk/strings-icsopenvpn.xml index 35d20e8b..f715bf77 100755 --- a/app/src/main/res/values-uk/strings-icsopenvpn.xml +++ b/app/src/main/res/values-uk/strings-icsopenvpn.xml @@ -180,7 +180,6 @@ Не вдалося отримати СА сертифікат при читанні із сховища ключів Андроїд. Автентифікація не вдалася. Показати вікно журналу при з\'єднанні. Вікно журналу може бути завжди дрступним у панелі сповіщень. Показати вікно журналу - Працює на %1$s (%2$s) %3$s, Android API %4$d Помилка підпису з використанням ключа із сховища Андроїд %1$s: %2$s Попередження VPN з\'єднання повідомляє вам, що цей додаток може перехоплювати весь мережевий трафік, і повідомляється системою попереджень VPNService API. \nСповіщення про VPN з\'єднання (символ \"Ключа\") також формується системою Android для сигналізації про вихідне VPN з\'єднання. У деяких прошивках це сповіщення супроводжується сигналом. \nAndroid використовує ці cповіщення для вашої власної безпеки і їх не можна обійти. (На жаль, на деяких прошивках також сповіщення супроводжується звуком) Повідомлення про підключення та звук сповіщеня @@ -260,7 +259,6 @@ Алгоритм шифрування Пакети автентифікації Введіть метод автентифікації пакетів - Запущено на %1$s (%2$s) %3$s, Android API %4$d, версії %5$s, %6$s побудована по %s відлагоджувальна збірка Офіційна збірка @@ -374,4 +372,15 @@ Визначені параметри користувача при з\'єднанні. Будьте обережні! Власні налаштовування Видалити запис підключення + Випадкове відключення від мережі мобільного зв\'язку + Віддалені мережі недоступні + Зберігати tun режим + %s і подальше + Підключення не вдається з \"SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure\" + Пошук + (Останній Dump %1$d:%2$dh старий (%3$s)) + Очистити журнал при новому підключенні + Час очікування з\'єднання + Протокол + Ввімкнено diff --git a/app/src/main/res/values-v21/colours.xml b/app/src/main/res/values-v21/colours.xml index 1fedf7b9..024e47eb 100644 --- a/app/src/main/res/values-v21/colours.xml +++ b/app/src/main/res/values-v21/colours.xml @@ -1,6 +1,6 @@ diff --git a/app/src/main/res/values-v21/refs.xml b/app/src/main/res/values-v21/refs.xml index 2a09271d..eb9c587c 100644 --- a/app/src/main/res/values-v21/refs.xml +++ b/app/src/main/res/values-v21/refs.xml @@ -1,14 +1,15 @@ - @drawable/ic_close_white_24dp - @drawable/ic_share_white_24dp - @drawable/ic_check_white_24dp - @drawable/ic_filter_list_white_24dp - @drawable/ic_delete_white_24dp - @drawable/ic_delete_grey600_24dp + @drawable/ic_close_white_24dp + @drawable/ic_share_white_24dp + @drawable/ic_check_white_24dp + @drawable/ic_filter_list_white_24dp + @drawable/ic_delete_white_24dp + @drawable/ic_delete_grey600_24dp + diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index 4379dd6d..83a693f1 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -1,15 +1,26 @@ - + - - - - - - - + + diff --git a/app/src/main/res/values-vi/strings-icsopenvpn.xml b/app/src/main/res/values-vi/strings-icsopenvpn.xml index 87d040ab..625ab34f 100755 --- a/app/src/main/res/values-vi/strings-icsopenvpn.xml +++ b/app/src/main/res/values-vi/strings-icsopenvpn.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml b/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml index efd8a669..2a3aac46 100755 --- a/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml +++ b/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml b/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml index 179396b8..c9dfeee5 100755 --- a/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml +++ b/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/values/refs.xml b/app/src/main/res/values/refs.xml index dce39385..4d3c257a 100644 --- a/app/src/main/res/values/refs.xml +++ b/app/src/main/res/values/refs.xml @@ -5,10 +5,12 @@ --> - @android:drawable/ic_menu_close_clear_cancel - @android:drawable/ic_menu_share - @android:drawable/ic_menu_save - @android:drawable/ic_menu_view - @android:drawable/ic_menu_delete - @android:drawable/ic_menu_edit + @android:drawable/ic_menu_close_clear_cancel + @android:drawable/ic_media_play + @android:drawable/ic_media_pause + @android:drawable/ic_menu_share + @android:drawable/ic_menu_save + @android:drawable/ic_menu_view + @android:drawable/ic_menu_delete + @android:drawable/ic_menu_edit diff --git a/app/src/main/res/values/strings-icsopenvpn.xml b/app/src/main/res/values/strings-icsopenvpn.xml index aa65a14d..3956604e 100755 --- a/app/src/main/res/values/strings-icsopenvpn.xml +++ b/app/src/main/res/values/strings-icsopenvpn.xml @@ -136,7 +136,7 @@ Refusing to open tun device without IP information Import Profile from ovpn file Import - Could not read Profile to import + Could not read profile to import Error reading config file add Profile Could not find file %1$s mentioned in the imported config file @@ -312,7 +312,7 @@ %3$s: %1$s\n\n%2$s If you have rooted your Android device you can install the <a href=\"http://xposed.info/\">Xposed framework</a> and a the <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm module</a> at your own risk" Full licenses - Networks directly connected to the local interfaces will not be routed over the VPN. Deselecting this option will redirect all traffic indented for local networks to the VPN. + Networks directly connected to the local interfaces will not be routed over the VPN. Deselecting this option will redirect all traffic intented for local networks to the VPN. Bypass VPN for local networks Username/Password file [Imported from: %s] @@ -347,13 +347,13 @@ Duplicate VPN profile Duplicating profile: %s Show log - Multiple OpenVPN clients for Android exist. The most common ones are OpenVPN for Android (this client), OpenVPN Connect and OpenVPN Settings.<p>The clients can be grouped into two groups: OpenVPN for Android and OpenVPN Connect use the official VPNService API (Android 4.0+) and require no root and OpenVPN Settings which uses root.<p>OpenVPN for Android is an open source client and developed by Arne Schwabe. It is targeted at more advanced users and offers many settings and the ability to import profiles from files and to configure/change profiles inside the app. The client is based on the community version of OpenVPN. It is based on the OpenVPN 2.x source code. This client can be seen as the semi officially client of the community. <p>OpenVPN Connect is non open source client that is developed by OpenVPN Technologies, Inc. The client is indented to be general use client and moree targeted at the average user and allows the import of OpenVPN profiles. This client is based on the OpenVPN C++ reimplementation of the OpenVPN protocol (This was required to allow OpenVPN Technologies, Inc to publish an iOS OpenVPN app). This client is the official client of the OpenVPN technologies <p> OpenVPN Settings is the oldest of the clients and also a UI for the open source OpenVPN. In contrast to OpenVPN for Android it requires root and does not use the VPNService API. It does not depend on Android 4.0+ + Multiple OpenVPN clients for Android exist. The most common ones are OpenVPN for Android (this client), OpenVPN Connect and OpenVPN Settings.<p>The clients can be grouped into two groups: OpenVPN for Android and OpenVPN Connect use the official VPNService API (Android 4.0+) and require no root and OpenVPN Settings which uses root.<p>OpenVPN for Android is an open source client and developed by Arne Schwabe. It is targeted at more advanced users and offers many settings and the ability to import profiles from files and to configure/change profiles inside the app. The client is based on the community version of OpenVPN. It is based on the OpenVPN 2.x source code. This client can be seen as the semi officially client of the community. <p>OpenVPN Connect is non open source client that is developed by OpenVPN Technologies, Inc. The client is indented to be general use client and more targeted at the average user and allows the import of OpenVPN profiles. This client is based on the OpenVPN C++ reimplementation of the OpenVPN protocol (This was required to allow OpenVPN Technologies, Inc to publish an iOS OpenVPN app). This client is the official client of the OpenVPN technologies <p> OpenVPN Settings is the oldest of the clients and also a UI for the open source OpenVPN. In contrast to OpenVPN for Android it requires root and does not use the VPNService API. It does not depend on Android 4.0+ Differences between the OpenVPN Android clients Ignoring multicast route: %s Android supports only CIDR routes to the VPN. Since non-CIDR routes are almost never used, OpenVPN for Android will use a /32 for routes that are not CIDR and issue a warning. Tethering works while the VPN is active. The tethered connection will NOT use the VPN. Early KitKat version set the wrong MSS value on TCP connections (#61948). Try to enable the mssfix option to workaround this bug. - Android will keep using your proxy settings specified for the mobile/Wi-Fi connection when no DNS servers are set. OpenVPN for Android will warn you about this in the log.

When a VPN sets a DNS server Android will not a proxy. There is no API to set a proxy for a VPN connection.

+ Android will keep using your proxy settings specified for the mobile/Wi-Fi connection when no DNS servers are set. OpenVPN for Android will warn you about this in the log.

When a VPN sets a DNS server Android will not use a proxy. There is no API to set a proxy for a VPN connection.

VPN apps may stop working when uninstalled and reinstalled again. For details see #80074 The configured client IP and the IPs in its network mask are not routed to the VPN. OpenVPN works around this bug by explicitly adding a route that corrosponds to the client IP and its netmask Opening a tun device while another tun device is active, which is used for persist-tun support, crashes the VPNServices on the device. A reboot is required to make VPN work again. OpenVPN for Android tries to avoid reopening the tun device and if really needed first closes the current TUN before opening the new TUN device to avoid to crash. This may lead to a short window where packets are sent over the non-VPN connection. Even with this workaround the VPNServices sometimes crashes and requires a reboot of the device. @@ -400,4 +400,9 @@ Please enter the password for profile %1$s Use inline data Export configuration file + tls-auth file is missing + Missing user certificate or user certifcate key file + Missing CA certificate + Certifcate Revoke List (optional) + Reread (%d) log items from log cache file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 13d5e0b1..4cdf2c00 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -53,4 +53,10 @@ +
\ No newline at end of file diff --git a/ics-openvpn b/ics-openvpn index ad414d7a..7dbaa266 160000 --- a/ics-openvpn +++ b/ics-openvpn @@ -1 +1 @@ -Subproject commit ad414d7aacadb9db2453c30eeaba13b894708b73 +Subproject commit 7dbaa266ed2aac4ab82672955282a6bfb43008b4 -- cgit v1.2.3 From 48948e1231a91c86e5a3e7b535a44eff62bacb6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 2 Apr 2016 15:04:35 +0200 Subject: VpnStatus.initLogCache must be called only once. onCreate gets called when the activity is back on the screen. If the app was already launched, we should not set everything up again. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 57 ++++++++++++++-------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 218b22a7..dbdf0a51 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -88,36 +88,55 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - app = this; - - PRNGFixes.apply(); - VpnStatus.initLogCache(getApplicationContext().getCacheDir()); - preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); - handleVersion(); - User.init(getString(R.string.default_username)); ProviderAPICommand.initialize(this); providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler(), this); - restoreProvider(savedInstanceState); - if (!provider.isConfigured()) + if (app == null) { + app = this; + + PRNGFixes.apply(); + VpnStatus.initLogCache(getApplicationContext().getCacheDir()); + handleVersion(); + User.init(getString(R.string.default_username)); + } + boolean provider_exists = previousProviderExists(savedInstanceState); + if (provider_exists) { + provider = getProvider(savedInstanceState); + if(!provider.isConfigured()) + startActivityForResult(new Intent(this, ConfigurationWizard.class), CONFIGURE_LEAP); + else { + buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); + user_status_fragment.restoreSessionStatus(savedInstanceState); + } + } else { startActivityForResult(new Intent(this, ConfigurationWizard.class), CONFIGURE_LEAP); - else { - buildDashboard(getIntent().getBooleanExtra(ON_BOOT, false)); - user_status_fragment.restoreSessionStatus(savedInstanceState); } } - private void restoreProvider(Bundle savedInstanceState) { - if (savedInstanceState != null) { - if (savedInstanceState.containsKey(Provider.KEY)) - provider = savedInstanceState.getParcelable(Provider.KEY); - } - if (!provider.isConfigured() && preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false)) + private boolean previousProviderExists(Bundle savedInstanceState) { + return providerInSavedInstance(savedInstanceState) || providerInSharedPreferences(); + } + + private Provider getProvider(Bundle savedInstanceState) { + if(providerInSavedInstance(savedInstanceState)) + provider = savedInstanceState.getParcelable(Provider.KEY); + else if (providerInSharedPreferences()) provider = getSavedProviderFromSharedPreferences(); + return provider; + } + + private boolean providerInSavedInstance(Bundle savedInstanceState) { + return savedInstanceState != null && + savedInstanceState.containsKey(Provider.KEY); + } + + private boolean providerInSharedPreferences() { + return preferences != null && + preferences.getBoolean(Constants.PROVIDER_CONFIGURED, false); + } @Override -- cgit v1.2.3 From 574960d09f5cf054001f8f6e9eb54f80312b60db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 2 Apr 2016 15:29:31 +0200 Subject: Update BuildTools to 23.0.3, and plugins - Android gradle plugin to 1.5.0 - Gson to 2.4 - Support annotations to 23.2.1 - Robotium-solo to 5.5.4 --- app/build.gradle | 8 ++++---- build.gradle | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8c8b6d38..e9fe2f60 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion "23.0.2" + buildToolsVersion "23.0.3" signingConfigs { release { @@ -47,15 +47,15 @@ android { } dependencies { - androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.4.1' + androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4' compile 'com.jakewharton:butterknife:6.1.0' provided 'com.squareup.dagger:dagger-compiler:1.2.2' compile 'com.github.pedrovgs:renderers:1.5' compile 'com.intellij:annotations:12.0' - compile 'com.google.code.gson:gson:2.3.1' + compile 'com.google.code.gson:gson:2.4' compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' compile 'mbanje.kurt:fabbutton:1.1.4' - compile 'com.android.support:support-annotations:23.1.1' + compile 'com.android.support:support-annotations:23.2.1' } def processFileInplace(file, Closure processText) { diff --git a/build.gradle b/build.gradle index 5a212651..e094b5bb 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.2.3' + classpath 'com.android.tools.build:gradle:1.5.0' } } -- cgit v1.2.3 From 2daac1d12c4784443a872492b7f29d02c429d19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sun, 3 Apr 2016 17:19:04 +0200 Subject: Bitmask does not show the log if an error happens. ics-openvpn already shows it if necessary. Our heuristic (just looking for an "error" keyword in the past N messages of the log) is very weak, and it returns an annoying false positive: turning off the VPN triggers the show log error. --- app/src/main/java/se/leap/bitmaskclient/VpnFragment.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java index 2e3d7524..9210c6ec 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java @@ -244,10 +244,7 @@ public class VpnFragment extends Fragment implements Observer { Context context = dashboard.getApplicationContext(); String error = eip_status.lastError(5, context); - if (!error.isEmpty()) { - dashboard.showLog(); - VoidVpnService.stop(); - } + if (!error.isEmpty()) VoidVpnService.stop(); updateIcon(); updateButton(); } -- cgit v1.2.3 From 287ae0ad2ec3e642f429e15bd1c7a8ca43eb6eec Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Mon, 19 Sep 2016 12:24:32 +0200 Subject: remove snappy (closes #8475) --- app/snappy | 1 - 1 file changed, 1 deletion(-) delete mode 120000 app/snappy diff --git a/app/snappy b/app/snappy deleted file mode 120000 index c44d7d0f..00000000 --- a/app/snappy +++ /dev/null @@ -1 +0,0 @@ -../ics-openvpn/main/snappy \ No newline at end of file -- cgit v1.2.3 From bb6a78c291d671a2f2a4f3fde0e37e676edcdc75 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Mon, 19 Sep 2016 12:48:33 +0200 Subject: bump Android SDK minor revision in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7fe5d630..bbbbce83 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ the SDK and NDK to `~/dev` on a linux machine, you would add this to your path: Installable via `android` command (SDK Manager): -* Android SDK Build-tools, 23.0.2 +* Android SDK Build-tools, 23.0.3 * Android Support Repository, 4+ Finally, install a java compiler. For example: -- cgit v1.2.3 From f4fe35129d33de8998c9641d266c23cf1c870e71 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Mon, 19 Sep 2016 12:52:48 +0200 Subject: update gradle version --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index e094b5bb..35bb7bfc 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.5.0' + classpath 'com.android.tools.build:gradle:2.1.3' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c8e43f9e..d1c6fba3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Dec 03 00:07:42 CET 2014 +#Mon Sep 19 11:42:08 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip -- cgit v1.2.3 From 99a4d71753f0a840b2e6b46c6d49b7a1043085cd Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Mon, 19 Sep 2016 22:17:50 +0200 Subject: Remove pins (solves #8455) remove pins, because didn\'t work this way (solves #8455) --- app/assets/urls/bitmask demo.url | 3 +-- app/assets/urls/calyx.url | 4 +--- app/assets/urls/riseup.url | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/assets/urls/bitmask demo.url b/app/assets/urls/bitmask demo.url index 81bdba52..1a412055 100644 --- a/app/assets/urls/bitmask demo.url +++ b/app/assets/urls/bitmask demo.url @@ -1,4 +1,3 @@ { - "main_url" : "https://demo.bitmask.net/", - "ca_cert_fingerprint" : "c3f9f39af6d42d1f201195dec918ac7603597049" + "main_url" : "https://demo.bitmask.net/" } diff --git a/app/assets/urls/calyx.url b/app/assets/urls/calyx.url index 9ae902f7..8de04fe9 100644 --- a/app/assets/urls/calyx.url +++ b/app/assets/urls/calyx.url @@ -1,5 +1,3 @@ { - "main_url" : "https://calyx.net/", - "ca_cert_fingerprint" : "98086aee17b5800acd0bdefe852e7c1ae72bd248" - + "main_url" : "https://calyx.net/" } diff --git a/app/assets/urls/riseup.url b/app/assets/urls/riseup.url index 4c565076..4548b433 100644 --- a/app/assets/urls/riseup.url +++ b/app/assets/urls/riseup.url @@ -1,4 +1,3 @@ { - "main_url" : "https://riseup.net/", - "ca_cert_fingerprint" : "aef7a642d7f8e046770521b354961a95cd4a76a8" + "main_url" : "https://riseup.net/" } -- cgit v1.2.3 From b528b53eea42dbd2f970a628def1465a3439f2a3 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Mon, 19 Sep 2016 22:27:39 +0200 Subject: Update Manifest version 0.9.5RC2 --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b4ada5fc..73808ffb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="127" + android:versionName="0.9.5RC2" > -- cgit v1.2.3 From ff3119d0075579ab57e0c9c160a65c5455a93336 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 20 Sep 2016 12:48:24 -0700 Subject: updated README.md with correct build-native.sh path --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bbbbce83..6863eff6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Bitmask Android App +# Bitmask Android App This repository contains the source code for the [Bitmask](https://bitmask.net/) Android app. @@ -19,9 +19,9 @@ Install from developer.android.com: Make sure add the necessary android tools to your bin path. For example, assuming you installed the SDK and NDK to `~/dev` on a linux machine, you would add this to your path: - ~/dev/android-sdk-linux/tools - ~/dev/android-sdk-linux/platform-tools - ~/dev/android-ndk-r10e/ + ~/dev/android-sdk-linux/tools/ + ~/dev/android-sdk-linux/platform-tools/ + ~/dev/android-sdk-linux/ndk-bundle/ Installable via `android` command (SDK Manager): @@ -33,6 +33,7 @@ Finally, install a java compiler. For example: sudo apt-get install default-jdk If you are using a 64-bit machine, you will need to install some libraries too: + sudo apt-get install lib32stdc++6 lib32z1 ## Update git submodules @@ -51,21 +52,23 @@ For that reason, it is necessary to initialize and update them before being able To build NDK sources, you need to issue these commands: - cd app - ./build-native.sh + cd ics-openvpn/main + misc/build-native.sh cd .. (to get back to the project directory) ### Compiling from the command line + #### Signed APK If you want to release a signed APK, you'll have to create a gradle.properties file in the project root with the following structure: - + storeFileProperty=fullPath storePasswordProperty=store password without quotation marks keyAliasProperty=key alias without quotation marks keyPasswordProperty=key password without quotation marks - + #### Actual command + ./gradlew build The resulting apk(s) will be in `app/build/apk`. @@ -77,12 +80,14 @@ The resulting apk(s) will be in `app/build/apk`. ## Running tests To run the automated tests: + 1. Run an emulator (device doesn't necesarily has root, so testVpnCertificateValidator.testIsValid may fail). 2. Unlock Android 3. Issue the command ./gradlew connectedCheck 4. Pay attention and check the "Trust this app" checkbox, if you don't do so tests won't run. Due to the nature of some tests, adb will lose its connectivity and you won't receive any tests results. To look for failed tests, do the following: + 1. adb kill-server 2. adb logcat | less 3. Look for: "failed: test" @@ -94,13 +99,15 @@ We'll polish this process soon, but right now that's what we're doing (well, in cd ics-openvpn git remote add upstream https://github.com/schwabe/ics-openvpn.git git pull --rebase upstream master - -A bunch of conflicts may arise. The guidelines are: + +A bunch of conflicts may arise. The guidelines are: + 1. Methods in HEAD (upstream) completely removed from Bitmask should be removed again (e.g. askPW) 2. Sometimes, Dashboard.class is in Bitmask while in ics-openvpn it is replaced by MainActivity.class and other classes. Keep removing them to keep Dashboard.class in there. 3. Some resources files are stripped from several entries. Remove them if possible (check the code we compile is not using anything else new). ./gradlew updateIcsOpenVpn + ## Acknowledgements This project bases its work in [ics-openvpn project](https://code.google.com/p/ics-openvpn/). -- cgit v1.2.3 From 9f54528ddd285dc99797483c026fbc7345febb39 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Thu, 13 Oct 2016 09:30:51 +0200 Subject: Handle RequestPermisson sdk>23 closes #8536 --- app/src/main/AndroidManifest.xml | 8 +- .../main/java/de/blinkt/openvpn/core/LogItem.java | 377 +++++++++++++++++++++ .../de/blinkt/openvpn/core/TestLogFileHandler.java | 119 +++++++ build.gradle | 2 +- 4 files changed, 501 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/de/blinkt/openvpn/core/LogItem.java create mode 100644 app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 73808ffb..7e0c9c0b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="128" + android:versionName="0.9.6Beta" > @@ -28,7 +28,7 @@ + android:targetSdkVersion="24"/> + android:theme="@android:style/Theme.Translucent.NoTitleBar" /> diff --git a/app/src/main/java/de/blinkt/openvpn/core/LogItem.java b/app/src/main/java/de/blinkt/openvpn/core/LogItem.java new file mode 100644 index 00000000..6aefbb2e --- /dev/null +++ b/app/src/main/java/de/blinkt/openvpn/core/LogItem.java @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.Signature; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; +import android.util.Log; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.FormatFlagsConversionMismatchException; +import java.util.Locale; +import java.util.UnknownFormatConversionException; + +import se.leap.bitmaskclient.R; + +/** + * Created by arne on 24.04.16. + */ +public class LogItem implements Parcelable { + private Object[] mArgs = null; + private String mMessage = null; + private int mRessourceId; + // Default log priority + VpnStatus.LogLevel mLevel = VpnStatus.LogLevel.INFO; + private long logtime = System.currentTimeMillis(); + private int mVerbosityLevel = -1; + + private LogItem(int ressourceId, Object[] args) { + mRessourceId = ressourceId; + mArgs = args; + } + + public LogItem(VpnStatus.LogLevel level, int verblevel, String message) { + mMessage = message; + mLevel = level; + mVerbosityLevel = verblevel; + } + + @Override + public int describeContents() { + return 0; + } + + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeArray(mArgs); + dest.writeString(mMessage); + dest.writeInt(mRessourceId); + dest.writeInt(mLevel.getInt()); + dest.writeInt(mVerbosityLevel); + + dest.writeLong(logtime); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof LogItem)) + return obj.equals(this); + LogItem other = (LogItem) obj; + + return Arrays.equals(mArgs, other.mArgs) && + ((other.mMessage == null && mMessage == other.mMessage) || + mMessage.equals(other.mMessage)) && + mRessourceId == other.mRessourceId && + ((mLevel == null && other.mLevel == mLevel) || + other.mLevel.equals(mLevel)) && + mVerbosityLevel == other.mVerbosityLevel && + logtime == other.logtime; + + + } + + public byte[] getMarschaledBytes() throws UnsupportedEncodingException { + ByteBuffer bb = ByteBuffer.allocate(16384); + + + bb.put((byte) 0x0); //version + bb.putLong(logtime); //8 + bb.putInt(mVerbosityLevel); //4 + bb.putInt(mLevel.getInt()); + bb.putInt(mRessourceId); + if (mMessage == null || mMessage.length() == 0) { + bb.putInt(0); + } else { + marschalString(mMessage, bb); + } + if (mArgs == null || mArgs.length == 0) { + bb.putInt(0); + } else { + bb.putInt(mArgs.length); + for (Object o : mArgs) { + if (o instanceof String) { + bb.putChar('s'); + marschalString((String) o, bb); + } else if (o instanceof Integer) { + bb.putChar('i'); + bb.putInt((Integer) o); + } else if (o instanceof Float) { + bb.putChar('f'); + bb.putFloat((Float) o); + } else if (o instanceof Double) { + bb.putChar('d'); + bb.putDouble((Double) o); + } else if (o instanceof Long) { + bb.putChar('l'); + bb.putLong((Long) o); + } else if (o == null) { + bb.putChar('0'); + } else { + VpnStatus.logDebug("Unknown object for LogItem marschaling " + o); + bb.putChar('s'); + marschalString(o.toString(), bb); + } + + } + } + + int pos = bb.position(); + bb.rewind(); + return Arrays.copyOf(bb.array(), pos); + + } + + public LogItem(byte[] in, int length) throws UnsupportedEncodingException { + ByteBuffer bb = ByteBuffer.wrap(in, 0, length); + bb.get(); // ignore version + logtime = bb.getLong(); + mVerbosityLevel = bb.getInt(); + mLevel = VpnStatus.LogLevel.getEnumByValue(bb.getInt()); + mRessourceId = bb.getInt(); + int len = bb.getInt(); + if (len == 0) { + mMessage = null; + } else { + if (len > bb.remaining()) + throw new IndexOutOfBoundsException("String length " + len + " is bigger than remaining bytes " + bb.remaining()); + byte[] utf8bytes = new byte[len]; + bb.get(utf8bytes); + mMessage = new String(utf8bytes, "UTF-8"); + } + int numArgs = bb.getInt(); + if (numArgs > 30) { + throw new IndexOutOfBoundsException("Too many arguments for Logitem to unmarschal"); + } + if (numArgs == 0) { + mArgs = null; + } else { + mArgs = new Object[numArgs]; + for (int i = 0; i < numArgs; i++) { + char type = bb.getChar(); + switch (type) { + case 's': + mArgs[i] = unmarschalString(bb); + break; + case 'i': + mArgs[i] = bb.getInt(); + break; + case 'd': + mArgs[i] = bb.getDouble(); + break; + case 'f': + mArgs[i] = bb.getFloat(); + break; + case 'l': + mArgs[i] = bb.getLong(); + break; + case '0': + mArgs[i] = null; + break; + default: + throw new UnsupportedEncodingException("Unknown format type: " + type); + } + } + } + if (bb.hasRemaining()) + throw new UnsupportedEncodingException(bb.remaining() + " bytes left after unmarshaling everything"); + } + + private void marschalString(String str, ByteBuffer bb) throws UnsupportedEncodingException { + byte[] utf8bytes = str.getBytes("UTF-8"); + bb.putInt(utf8bytes.length); + bb.put(utf8bytes); + } + + private String unmarschalString(ByteBuffer bb) throws UnsupportedEncodingException { + int len = bb.getInt(); + byte[] utf8bytes = new byte[len]; + bb.get(utf8bytes); + return new String(utf8bytes, "UTF-8"); + } + + + public LogItem(Parcel in) { + mArgs = in.readArray(Object.class.getClassLoader()); + mMessage = in.readString(); + mRessourceId = in.readInt(); + mLevel = VpnStatus.LogLevel.getEnumByValue(in.readInt()); + mVerbosityLevel = in.readInt(); + logtime = in.readLong(); + } + + public static final Creator CREATOR + = new Creator() { + public LogItem createFromParcel(Parcel in) { + return new LogItem(in); + } + + public LogItem[] newArray(int size) { + return new LogItem[size]; + } + }; + + public LogItem(VpnStatus.LogLevel loglevel, int ressourceId, Object... args) { + mRessourceId = ressourceId; + mArgs = args; + mLevel = loglevel; + } + + + public LogItem(VpnStatus.LogLevel loglevel, String msg) { + mLevel = loglevel; + mMessage = msg; + } + + + public LogItem(VpnStatus.LogLevel loglevel, int ressourceId) { + mRessourceId = ressourceId; + mLevel = loglevel; + } + + public String getString(Context c) { + try { + if (mMessage != null) { + return mMessage; + } else { + if (c != null) { + if (mRessourceId == R.string.mobile_info) + return getMobileInfoString(c); + if (mArgs == null) + return c.getString(mRessourceId); + else + return c.getString(mRessourceId, mArgs); + } else { + String str = String.format(Locale.ENGLISH, "Log (no context) resid %d", mRessourceId); + if (mArgs != null) + str += join("|", mArgs); + + return str; + } + } + } catch (UnknownFormatConversionException e) { + if (c != null) + throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null)); + else + throw e; + } catch (java.util.FormatFlagsConversionMismatchException e) { + if (c != null) + throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null), e.getConversion()); + else + throw e; + } + + } + + + // TextUtils.join will cause not macked exeception in tests .... + public static String join(CharSequence delimiter, Object[] tokens) { + StringBuilder sb = new StringBuilder(); + boolean firstTime = true; + for (Object token : tokens) { + if (firstTime) { + firstTime = false; + } else { + sb.append(delimiter); + } + sb.append(token); + } + return sb.toString(); + } + + + public VpnStatus.LogLevel getLogLevel() { + return mLevel; + } + + + @Override + public String toString() { + return getString(null); + } + + // The lint is wrong here + @SuppressLint("StringFormatMatches") + private String getMobileInfoString(Context c) { + c.getPackageManager(); + String apksign = "error getting package signature"; + + String version = "error getting version"; + try { + @SuppressLint("PackageManagerGetSignatures") + Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray())); + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] der = cert.getEncoded(); + md.update(der); + byte[] digest = md.digest(); + + if (Arrays.equals(digest, VpnStatus.officalkey)) + apksign = c.getString(R.string.official_build); + else if (Arrays.equals(digest, VpnStatus.officaldebugkey)) + apksign = c.getString(R.string.debug_build); + else if (Arrays.equals(digest, VpnStatus.amazonkey)) + apksign = "amazon version"; + else if (Arrays.equals(digest, VpnStatus.fdroidkey)) + apksign = "F-Droid built and signed version"; + else + apksign = c.getString(R.string.built_by, cert.getSubjectX500Principal().getName()); + + PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + version = packageinfo.versionName; + + } catch (PackageManager.NameNotFoundException | CertificateException | + NoSuchAlgorithmException ignored) { + } + + Object[] argsext = Arrays.copyOf(mArgs, mArgs.length); + argsext[argsext.length - 1] = apksign; + argsext[argsext.length - 2] = version; + + return c.getString(R.string.mobile_info, argsext); + + } + + public long getLogtime() { + return logtime; + } + + + public int getVerbosityLevel() { + if (mVerbosityLevel == -1) { + // Hack: + // For message not from OpenVPN, report the status level as log level + return mLevel.getInt(); + } + return mVerbosityLevel; + } + + public boolean verify() { + if (mLevel == null) + return false; + + if (mMessage == null && mRessourceId == 0) + return false; + + return true; + } +} diff --git a/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java b/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java new file mode 100644 index 00000000..c35df598 --- /dev/null +++ b/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java @@ -0,0 +1,119 @@ +package de.blinkt.openvpn.core; + +import android.annotation.SuppressLint; + +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; + +public class TestLogFileHandler { + + byte[] testUnescaped = new byte[]{0x00, 0x55, -27, 0x00, 0x56, 0x10, -128, 0x55, 0x54}; + byte[] expectedEscaped = new byte[]{0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x56, 0x00, -27, 0x00, 0x56, 0x01, 0x10, -128, 0x56, 0x00, 0x54}; + private TestingLogFileHandler lfh; + + + @Before + public void setup() { + lfh = new TestingLogFileHandler(); + } + + @Test + public void testWriteByteArray() throws IOException { + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + lfh.setLogFile(byteArrayOutputStream); + + lfh.writeEscapedBytes(testUnescaped); + + byte[] result = byteArrayOutputStream.toByteArray(); + Assert.assertTrue(Arrays.equals(expectedEscaped, result)); + } + + @Test + public void readByteArray() throws IOException { + + ByteArrayInputStream in = new ByteArrayInputStream(expectedEscaped); + + lfh.readCacheContents(in); + + Assert.assertTrue(Arrays.equals(testUnescaped, lfh.mRestoredByteArray)); + + } + + @Test + public void testMarschal() throws UnsupportedEncodingException { + LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, "foobar"); + LogItem li2 = marschalAndBack(li); + testEquals(li, li2); + Assert.assertEquals(li, li2); + } + + @Test + public void testMarschalArgs() throws UnsupportedEncodingException { + LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, 772, "sinnloser Text", 7723, 723.2f, 7.2); + LogItem li2 = marschalAndBack(li); + testEquals(li, li2); + Assert.assertEquals(li, li2); + } + + @Test + public void testMarschalString() throws UnsupportedEncodingException { + LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, "Nutzlose Nachricht"); + LogItem li2 = marschalAndBack(li); + testEquals(li, li2); + Assert.assertEquals(li, li2); + } + + + private void testEquals(LogItem li, LogItem li2) { + Assert.assertEquals(li.getLogLevel(), li2.getLogLevel()); + Assert.assertEquals(li.getLogtime(), li2.getLogtime()); + Assert.assertEquals(li.getVerbosityLevel(), li2.getVerbosityLevel()); + Assert.assertEquals(li.toString(), li2.toString()); + + } + + private LogItem marschalAndBack(LogItem li) throws UnsupportedEncodingException { + byte[] bytes = li.getMarschaledBytes(); + + return new LogItem(bytes, bytes.length); + } + + + @SuppressLint("HandlerLeak") + static class TestingLogFileHandler extends LogFileHandler { + + public byte[] mRestoredByteArray; + + public TestingLogFileHandler() { + super(null); + } + + public void setLogFile(OutputStream out) { + mLogFile = out; + } + + @Override + public void readCacheContents(InputStream in) throws IOException { + super.readCacheContents(in); + } + + @Override + protected void restoreLogItem(byte[] buf, int len) { + mRestoredByteArray = Arrays.copyOf(buf, len); + } + } + + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 35bb7bfc..db59f144 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.3' + classpath 'com.android.tools.build:gradle:2.2.1' } } -- cgit v1.2.3 From 87ca37e38bd803b0771ae9385ef1372ae1496a98 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Tue, 14 Mar 2017 16:50:33 +0100 Subject: add .gitlab-ci config for CI building --- .gitlab-ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..8784a5b1 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,12 @@ +image: "0xacab.org:4567/leap/gitlab-buildpackage:android" + +stages: + - build + +build: + stage: build + script: + - ./gradlew assembleDebug + artifacts: + paths: + - app/build/outputs/ -- cgit v1.2.3 From cd06e880fe27e803da21bd604a76d27ccd7052df Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Tue, 14 Mar 2017 17:10:25 +0100 Subject: give gitlab builds a try with foreign docker image --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8784a5b1..896b59c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,5 @@ -image: "0xacab.org:4567/leap/gitlab-buildpackage:android" +#image: "0xacab.org:4567/leap/gitlab-buildpackage:android" +image: "jacekmarchwicki/android" stages: - build -- cgit v1.2.3 From 128fed3eff14843f743fdb6cd420649afb5e8593 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Tue, 14 Mar 2017 17:15:16 +0100 Subject: gitlab ci with jdk8 docker --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 896b59c8..d5a0757a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ #image: "0xacab.org:4567/leap/gitlab-buildpackage:android" -image: "jacekmarchwicki/android" +image: "gfx2015/android" stages: - build -- cgit v1.2.3 From a3ed35a4fc5aff4fe6a06f45f0dcaa009759bbd0 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Tue, 14 Mar 2017 17:33:01 +0100 Subject: sync submodules (ics-ovpn) when building --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d5a0757a..af32b362 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,9 @@ #image: "0xacab.org:4567/leap/gitlab-buildpackage:android" image: "gfx2015/android" +variables: + GIT_SUBMODULE_STRATEGY: "recursive" + stages: - build -- cgit v1.2.3 From 061a93d7b1312bfb45f6cba4e63474d392e3c078 Mon Sep 17 00:00:00 2001 From: kwadronaut Date: Tue, 14 Mar 2017 20:54:42 +0100 Subject: try our own docker image for building --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index af32b362..3a72e9b4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ -#image: "0xacab.org:4567/leap/gitlab-buildpackage:android" -image: "gfx2015/android" +image: "0xacab.org:4567/leap/gitlab-buildpackage:android" +#image: "gfx2015/android" variables: GIT_SUBMODULE_STRATEGY: "recursive" -- cgit v1.2.3 From 0688c9e8ceab724874bd795f35dc64f498c416b0 Mon Sep 17 00:00:00 2001 From: varac Date: Wed, 15 Mar 2017 00:06:09 +0100 Subject: Try with explicit git submodule cloning --- .gitlab-ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3a72e9b4..7ad57573 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,13 @@ image: "0xacab.org:4567/leap/gitlab-buildpackage:android" #image: "gfx2015/android" -variables: - GIT_SUBMODULE_STRATEGY: "recursive" - stages: - build +before_script: + - git submodule sync --recursive + - git submodule update --init --recursive + build: stage: build script: -- cgit v1.2.3 From 9edd5d6b3f9e7019fe01867ad4e37d2753d77e18 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Wed, 12 Apr 2017 01:13:11 -0400 Subject: [ag] Update README to promote smoother on-boarding * add detailed instructions on installing and compiling * provide workarounds for gotchas setting up emulator on debian * offer instructions for building in docker side-effects: * update build tools & gradle version * fix indentation in build.gradle * comment out tests in `TestLogFileHandler` causing `build` to break (and provide justification) --- README.md | 475 ++++++++++++++++++--- app/build.gradle | 63 +-- .../de/blinkt/openvpn/core/TestLogFileHandler.java | 252 ++++++----- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 5 files changed, 583 insertions(+), 213 deletions(-) diff --git a/README.md b/README.md index 6863eff6..d827bd6e 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,254 @@ -# Bitmask Android App +# Bitmask Android Client + +This repository contains the source code for the [Bitmask](https://bitmask.net/) Android client. Bitmask Android offers one-click free VPN service from trusted providers of the LEAP stack. + +To lean about the stack, visit [leap.se](https://leap.se). + +Please see the [issues](https://github.com/leapcode/bitmask_android/issues) section to report any bugs or feature requests, and to see the list of known issues. + +# Table Of Contents + +* [License](#license) +* [Installing](#installing) + * [JDK](#jdk) + * [C Libraries](#c-libraries) + * [Android SDK](#android-sdk) + * [With Android Studio](#with-android-studio) + * [With Bash](#with-bash) + * [Updating Your PATH](#updating-your-path) + * [With Docker](#with-docker) + * [Submodules](#submodules) +* [Compiling](#compiling) + * [Just Build It!](#just-build-it) + * [Debug APKs](#debug-apks) + * [Release APKs](#release-apks) + * [Signed Release APKs](#signed-release-apks) +* [Running Tests](#running-tests) +* [Debugging in an Emulator](#debugging-in-an-emulator) + * [From Android Studio](#from-android-studio) + * [From The Shell](#from-the-shell) + * [Debian Gotchas](#debian-gotchas) + * [Virtualization Not Enabled](#virtualization-not-enabled) + * [Unpatched Filepaths Bug](#unpatched-filepaths-bug) + * [Outdated GL Libraries](#outdated-gl-libraries) +* [Updating Submodules](#updating-submodules) +* [Acknowledgments](#acknowledgments) +* [Contributing](#contributing) + +## License -This repository contains the source code for the [Bitmask](https://bitmask.net/) Android app. +* [See LICENSE file](https://github.com/leapcode/bitmask_android/blob/master/LICENSE.txt) -Please see the [issues](https://github.com/leapcode/bitmask_android/issues) section to -report any bugs or feature requests and to see the list of known issues. -## License +## Installing -* [See LICENSE file](https://github.com/leapcode/bitmask_android/blob/master/LICENSE.txt) +We will assume for convenience that you are installing on a Debian- or Ubuntu-based GNU/Linux machine. (Patches welcome with instructions for Mac, Windows, or other GNU/Linux distributions!) + +The Bitmask Android Client has the following system-level dependencies: + +* JDK v. 1.8 +* Assorted 32-bit C libraries +* Android SDK Tools, v. 25.0.2, with these packages: + * Platform-Tools, v. 25.0.2 + * Build-Tools, API v. 23-25 + * Platforms 23-25 + * Android Support Repository + * Google Support Repository + * NDK v. r14b (enables C code in Android) +* For running the app in an emulator, you will also need these packages: + * Android Emulator + * ARMEABI System Images for Adnroid APIs 23-25 +* The ICS-OpenVpn submodule + +You can install them as follows: + +### JDK + +Install with: + +```bash +sudo apt install default-jdk +``` + +### C Libraries + +These are necessary to make sure the program cross-compiles to 32-bit architectures successfully from 64-bit GNU/Linux machines: + +``` +sudo apt install lib32stdc++ lib32z1 +``` + +lib64stdc++ + +### Android SDK + +#### With Android Studio + +All of the Android SDK and NDK packages are downloadable through Android Studio, which (sadly) is probably the most hassle-free way to go about things. + +You can download Android studio here: + +https://developer.android.com/studio/index.html + +Once you've got it installed, use the `SDK Manager` tool (Android figure Icon with blue arrow second from the right in the tool pane) to download all the Android SDK and NDK depencencies listed above. + +#### With Bash + +Alternatley (eg: for build machines), you may download the `android-sdk` tarball from Google as follows: + +``` +cd +wget -q https://dl.google.com/android/android-sdk_r23.0.3-linux.tgz -O android-sdk.tgz +tar -xvzf android-sdk.tgz +rm -f android-sdk.tgz +``` + +After updating your PATH (see next step), you may now use the `sdkmanager` tool bundled with `android-sdk` to browse and install new sdk packages from Google. + +To browse all available packages, run: + +```shell +sdkmanager --list +``` + +To search for available packages of a certain type (eg: `tools`), run: + +```shell +sdkmanager --list | grep tools +``` -## Build Requirements +To install all of the dependencies listed above (targetting SDK versions 23 - 25), run: -Install from developer.android.com: +```shell +# update sdk tools +sdkmanager tools -* Android SDK, API 23: http://developer.android.com/sdk/index.html -* Android NDK, r10e: http://developer.android.com/tools/sdk/ndk/index.html +# get supporting packages +sdkmanager platform-tools +sdkmanager extras;android;m2repository +sdkmanager extras;google;m2repository -Make sure add the necessary android tools to your bin path. For example, assuming you installed -the SDK and NDK to `~/dev` on a linux machine, you would add this to your path: +# get build tools and sdk platforms for api v 23 - 25 +sdkmanager build-tools;25.0.2 +sdkmanager build-tools;24.0.3 +sdkmanager build-tools;23.0.3 +sdkmanager platforms;android-25 +sdkmanager platforms;android-24 +sdkmanager platforms;android-23 - ~/dev/android-sdk-linux/tools/ - ~/dev/android-sdk-linux/platform-tools/ - ~/dev/android-sdk-linux/ndk-bundle/ +# install NDK (for C code) +sdkmanager ndk-bundle +``` -Installable via `android` command (SDK Manager): +#### Updating Your Path -* Android SDK Build-tools, 23.0.3 -* Android Support Repository, 4+ +Once you've installed Android SDK & NDK packages, you need to modify your PATH so you can invoke all the programs you just installed. (On GNU/Linux, machines, this is generally `~/Android/Sdk`.) -Finally, install a java compiler. For example: +You can do that with something like the following in your `~/.shellrc` or `~/.bash_profile`: - sudo apt-get install default-jdk +```shell +export ANDROID_HOME= +export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle +export PATH=$ANDROID_NDK_HOME:$PATH +export PATH=$ANDROID_HOME/platform-tools:$PATH +export PATH=$ANDROID_HOME/tools/bin:$PATH +``` -If you are using a 64-bit machine, you will need to install some libraries too: +#### With Docker - sudo apt-get install lib32stdc++6 lib32z1 +Geesh! If all that above seems like a lot, it is! -## Update git submodules +To keep ourselves from messing it up all the time everyone someone new joins the project, we made a Dockerfile that creates the above environment with one line. You can pull the image and run builds from inside it, or consult the [Dockerfile](/docker/android-sdk.dockerfile) itself for requirements that your system might need but be missing. -We build upon ics-openvpn, which meets a submodule in our project structure. +Assuming you've already [installed docker](https://docs.docker.com/engine/installation/), you can pull the image with: -For that reason, it is necessary to initialize and update them before being able to build Bitmask Android. +``` shell +docker pull 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 +``` - git submodule init - git submodule update - cd ics-openvpn - git submodule init - git submodule update +Run the image with: -## Build native sources +``` shell +docker run -i -t 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 +``` +More likely than not, you'll want to run the image with the source code mounted. You can do that with: -To build NDK sources, you need to issue these commands: +``` shell +cd +docker run -i -v`pwd`:/bitmask_android -t 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 +``` - cd ics-openvpn/main - misc/build-native.sh - cd .. (to get back to the project directory) +*TODO(@aguestuser|04.16.17): move docker registry to 0xacab.org/leap (pending permissions)* -### Compiling from the command line +### Submodules -#### Signed APK +We depend on [ics-openvpn](https://github.com/schwabe/ics-openvpn) as an interface to Android's OpenVPN implementation. We include it as a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) in our project, which requires that we initialize and update it (and its respective upstream submodule dependencies) in order to compile and run Bitmask Android. -If you want to release a signed APK, you'll have to create a gradle.properties file in the project root with the following structure: +We do so with: - storeFileProperty=fullPath - storePasswordProperty=store password without quotation marks - keyAliasProperty=key alias without quotation marks - keyPasswordProperty=key password without quotation marks +```bash +cd +git submodule init +git submodule update --init --recursive +``` -#### Actual command +## Compiling - ./gradlew build +You have lots of options for compiling, all of which will output Android-executable `apk` packages to `/bitmask_android/app/build/outputs/apk/`. -The resulting apk(s) will be in `app/build/apk`. +### Just Build It! -### Using Android Studio +You are welcome to run: -* `Import project` => select bitmask_android top folder +``` +./gradlew build +``` -## Running tests +This will compile the code and run the tests, but not output any `apk` packages. As such, it's not all that useful. :) + +### Debug APKs + +To assemble debug packages for running locally or testing in CI, run: + +```bash +./gradlew assembleDebug +``` + +This will output `app-insecure-debug.apk` and `app-production-debug.apk` to `/bitmask_android/app/build/outputs/apk/`. + +### Release APKs + +To assemble release packages, run: + +```bash +./gradlew assembleRelease +``` + +This will output `app-insecure-release.apk` and `app-production-release.apk` to `/bitmask_android/app/build/outputs/apk/`. + +### Signed Release APKs + +If you want to release a signed APK (which you *must* do to publish the app to the Google Play store), you'll have to create a gradle.properties file in the project root with the following structure: + +```properties +storeFileProperty= +storePasswordProperty= +keyAliasProperty= +keyPasswordProperty= +``` + +### Building In Docker + +If you want to make sure the environment you use to build APKs matches exactly the environment that Gitlab will use to build and publish artifacts, you can run any of the above build commands from inside Docker. To assemble a release build this way, run the following commands: + +``` shell +$ cd +$ sudo docker run -i -t `pwd`:/bitmask_android 0xacab.org/aguestuser/bitmask_android:android-sdk-25 +# cd /bitmask_android +# ./gradlew assembleRelease +``` + +## Running Tests To run the automated tests: @@ -92,33 +263,213 @@ Due to the nature of some tests, adb will lose its connectivity and you won't re 2. adb logcat | less 3. Look for: "failed: test" -We'll polish this process soon, but right now that's what we're doing (well, in fact, we run "adb logcat" in Emacs and then search "failed: test" in the corresponding buffer ;) ). +We'll polish this process soon, but right now that's what we're doing. + +## Debugging in an Emulator + +You can run the app in an emulator running any version of Android and simulating (almost) any device. To run it you'll have to create an emulator, run the emulator, and then load an assembled APK of the app onto the emulator. (You can then use all sort of nifty tools in [Anroid Debug Bridge](https://developer.android.com/studio/command-line/adb.html) to tail the logs and debug the app.) + +Assuming you've already tackled (or don't need to tackle) the [Debian Gotchas](#debian-gotchas) listed below, you can do that using either Android Studio or a bash shell as follows: + +### From Android Studio + +To create an emulator: + +* Select `Tools/Android/AVD Manager` from the application menu +* Follow the instructions + +To run a pre-existing emulator: + +* Open the `AVD Manager` as above +* Press the "Play" button next to the emulator you want to run + +To run the app: + +* Ensure you have an emulator running +* Open the left-hand project pane (Meta-1 or Cmd-1, depending on your keybindings) +* Navigate to `bitmask_android/app/src/main/java/se/leap/bitmaskclient/Dashboard` +* Right-click over the `Dashboard` filename and click the `Run 'Dashboard'` option (or use Shift-Ctl-F10 or Shift-Ctl-R, depending on your keybindings) +* After you have done this once, you should be able to simply select `Dashboard` from the dropdown menu next to the big green arrow in the toolbar, then click the green arrow to run the app. + +### From the Shell -## Updating ics-openvpn +To list the available avd images for creating an emulator: - cd ics-openvpn - git remote add upstream https://github.com/schwabe/ics-openvpn.git - git pull --rebase upstream master +``` shell +avdmanager list +``` +To create an emulator: + +``` shell +avdmanager create avd +``` + +To list the emulators you have already created: + +``` shell +avdmanager list avd +``` + +To run a pre-existing emulator called `Nexus_5_API_25`: + +``` shell +emulator @Nexus_5_API_15 +``` + +Verify the device is running with: + +``` shell +adb devices +``` + +You should see something like: + +``` shell +List of devices attached +emulator-5554 device +``` +Install APK with: + +``` shell +abd install .apk +``` + +Uninstall with: + +``` shell +abd uninstall se.leap.bitmaskclient +``` +Install with option to reinstall: + +``` shell +abd install -r +``` + +### Debian Gotchas + +If you are running Debian on a 64-bit machine, your emulator will likely not work out of the gate. Test to see if this is the case by: + +* first creating an emulator in Android Studio (with name, eg, `Nexus_5_API_25`) +* then running: + ```shell + cd ~/ + emulator @ + ``` +If you can launch an emulator, HUZZAH! If not, you likely have one of 3 problems: + +#### 1. Virtualization Not Enabled + +Boo! Try turning it on. The second half of [this article](https://docs.fedoraproject.org/en-US/Fedora/13/html/Virtualization_Guide/sect-Virtualization-Troubleshooting-Enabling_Intel_VT_and_AMD_V_virtualization_hardware_extensions_in_BIOS.html) is a decent enough guide. + +#### 2. Unpatched Filepaths Bug + +**Symptoms:** If you have this bug, you will see something like the following when you try to spin up an emulator: + +``` shell +[140500439390016]:ERROR:./android/qt/qt_setup.cpp:28:Qt library not found at ../emulator/lib64/qt/lib +Could not launch '../emulator/qemu/linux-x86_64/qemu-system-i386': No such file or directory +``` +As [documented here](https://stackoverflow.com/questions/42554337/cannot-launch-avd-in-emulatorqt-library-not-found), there is a standing bug in the version of `emulator` packaged for emulator that assumes it always runs from within the `$ANDROID_HOME/emulator` directory, and can thus safely use relative filepaths, when in fact this is almost never the case. (Cool bug!) + +**Fixes:** + +You have a couple options. The second is more robust: + +1. Always run emulator from within its own directory (clunky!): + +``` shell + cd "$(dirname "$(which emulator)")" + emulator +``` + +2. Insert a line in your `~/.bashrc` to automatically navigate to the correct directory (and back) whenever you invoke `emulator`: + + ```shell +function emulator { pushd `pwd`; cd "$(dirname "$(which emulator)")" && ./emulator "$@"; popd;} +``` + +*** PROBLEM 2: OUTDATED VERSIONS OF GL LIBRARIES + +#### 3. Outdated GL Libraries + +**Symptoms:** If you have this bug, you will see something like the following: + +``` shell +libGL error: failed to load driver: swrast +X Error of failed request: BadValue (integer parameter out of range for operation) +# redacted incredibly long stack trace +``` + +As documented [here](http://stackoverflow.com/questions/36554322/cannot-start-emulator-in-android-studio-2-0), the current emulator package ships without outdated versions of LibGL libraries. To work around this: + +1. Install modern GL libriaries with: + +``` shell +sudo apt-get install mesa-utils +``` + +2. Ensure that `emulator` always uses the correct libraries by either: + + a. always calling `emulator` with the `-use-system-libs` flag, like so: + + ``` shell + emulator -use-system-libs -avd Nexus_5_API_25 + ``` + b. adding the following line to your ~/.bashrc or ~/.bash_profile: + + ```shell + export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 + ``` + +**Special Android Studio Debian Bonus Gotcha:** + +Assuming you have made all the above fixes (great job!), to be able to launch emulators from Android Studio, you must either: + +1. Use the environment variable solution above (option a), then *always* launch Android Studio from a bash shell with: + +``` shell +studio +``` + +This means never using the desktop launcher. :( + +2. If you want to use the desktop launcher: + + * You must *always* launch emulators from the terminal. :( + * But: you can quickly access a terminal inside of Android Studio with `OPTION-F12` + +## Updating Submodules + +If you need to refresh of our upstream dependency on ics-openvpn, you may do so with: + +``` shell +cd +./gradlew updateIcsOpenVpn +``` + +Alternately: + +```shell +cd +cd ics-openvpn +git remote add upstream https://github.com/schwabe/ics-openvpn.git +git pull --rebase upstream master +``` A bunch of conflicts may arise. The guidelines are: 1. Methods in HEAD (upstream) completely removed from Bitmask should be removed again (e.g. askPW) 2. Sometimes, Dashboard.class is in Bitmask while in ics-openvpn it is replaced by MainActivity.class and other classes. Keep removing them to keep Dashboard.class in there. 3. Some resources files are stripped from several entries. Remove them if possible (check the code we compile is not using anything else new). - ./gradlew updateIcsOpenVpn - -## Acknowledgements +## Acknowledgments This project bases its work in [ics-openvpn project](https://code.google.com/p/ics-openvpn/). -## Contributing +## Contributing -Please fork this repository and contribute back using -[pull requests](https://github.com/leapcode/leap_android/pulls). +Please fork this repository and contribute back using [pull requests](https://github.com/leapcode/leap_android/pulls). Our preferred method for receiving translations is our [Transifex project](https://www.transifex.com/projects/p/bitmask-android). -Any contributions, large or small, major features, bug fixes, additional -language translations, unit/integration tests are welcomed and appreciated -but will be thoroughly reviewed and discussed. +Any contributions, large or small, major features, bug fixes, additional language translations, unit/integration tests are welcomed and appreciated but will be thoroughly reviewed and discussed. diff --git a/app/build.gradle b/app/build.gradle index e9fe2f60..cd7e6e21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion "23.0.3" + buildToolsVersion '25.0.0' signingConfigs { release { @@ -13,26 +13,26 @@ android { } } - productFlavors { - production { + productFlavors { + production { - } - insecure { + } + insecure { - } } + } buildTypes { release { //runProguard true if(signingConfigs.contains(release)) - signingConfig signingConfigs.release.isSigningReady() ? signingConfigs.release : signingConfigs.debug + signingConfig signingConfigs.release.isSigningReady() ? signingConfigs.release : signingConfigs.debug } } - lintOptions { - abortOnError false - } + lintOptions { + abortOnError false + } sourceSets { main { @@ -48,6 +48,7 @@ android { dependencies { androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4' + testCompile 'junit:junit:4.12' compile 'com.jakewharton:butterknife:6.1.0' provided 'com.squareup.dagger:dagger-compiler:1.2.2' compile 'com.github.pedrovgs:renderers:1.5' @@ -55,7 +56,7 @@ dependencies { compile 'com.google.code.gson:gson:2.4' compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' compile 'mbanje.kurt:fabbutton:1.1.4' - compile 'com.android.support:support-annotations:23.2.1' + compile 'com.android.support:support-annotations:23.2.1' } def processFileInplace(file, Closure processText) { @@ -82,17 +83,17 @@ task copyIcsOpenVPNClasses( type: Copy ) { include '**/dimens.xml' include '**/logmenu.xml' include '**/core/**.java' - include '**/activities/BaseActivity.java' + include '**/activities/BaseActivity.java' includeEmptyDirs = false - + filter { line -> line.replaceAll('de.blinkt.openvpn.R', 'se.leap.bitmaskclient.R') } filter { line -> line.replaceAll('de.blinkt.openvpn.BuildConfig', 'se.leap.bitmaskclient.BuildConfig') } - filter { + filter { line -> line.replace('package de.blinkt.openvpn;', 'package de.blinkt.openvpn;\n\nimport se.leap.bitmaskclient.R;') } } into '.' @@ -107,11 +108,11 @@ task copyIcsOpenVPNXml( type: Copy ) { include '**/styles.xml' include '**/dimens.xml' include '**/refs.xml' - include '**/colours.xml' + include '**/colours.xml' include '**/logmenu.xml' include '**/white_rect.xml' includeEmptyDirs = false - + rename 'strings.xml', 'strings-icsopenvpn.xml' filter { line -> line.replaceAll('.*name="app".*', '') @@ -128,8 +129,8 @@ task copyIcsOpenVPNImages( type: Copy ) { include '**/ic_close*.png' include '**/ic_edit*.png' include '**/ic_check*.png' - include '**/ic_pause*.png' - include '**/ic_play*.png' + include '**/ic_pause*.png' + include '**/ic_play*.png' includeEmptyDirs = false } into '.' } @@ -141,14 +142,14 @@ task removeDuplicatedStrings() { if(it.name.equals('strings.xml')) { def ics_openvpn_file = file(it.absolutePath.replace('strings.xml', 'strings-icsopenvpn.xml')) if(ics_openvpn_file.exists()) { - def ics_openvpn_strings_names = (new XmlParser()).parse(ics_openvpn_file) - def current_file = it - - ics_openvpn_strings_names.string.each { - processFileInplace(current_file) { text -> - text.replaceAll('.*name=\"' + it.attribute('name') + '\".*(\n)*.*string>.*\n+', '') - } - } + def ics_openvpn_strings_names = (new XmlParser()).parse(ics_openvpn_file) + def current_file = it + + ics_openvpn_strings_names.string.each { + processFileInplace(current_file) { text -> + text.replaceAll('.*name=\"' + it.attribute('name') + '\".*(\n)*.*string>.*\n+', '') + } + } } } } @@ -167,20 +168,20 @@ task mergeUntranslatable( type: Copy ) { ics_openvpn_untranslatable.eachLine { text -> if(text.contains('string name=')) { if(!bitmask_untranslatable.text.contains(text)) - bitmask_untranslatable << text - if(text.contains('
')) - string_continuation = true + bitmask_untranslatable << text + if(text.contains('
')) + string_continuation = true } else if(string_continuation) { bitmask_untranslatable << text } - + if(text.contains('
')) { string_continuation = false bitmask_untranslatable << System.getProperty("line.separator") } } - + bitmask_untranslatable.write(bitmask_untranslatable.text.replaceAll("", "")) bitmask_untranslatable << "" diff --git a/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java b/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java index c35df598..476d8151 100644 --- a/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java +++ b/app/src/test/java/de/blinkt/openvpn/core/TestLogFileHandler.java @@ -1,119 +1,137 @@ package de.blinkt.openvpn.core; -import android.annotation.SuppressLint; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; - -public class TestLogFileHandler { - - byte[] testUnescaped = new byte[]{0x00, 0x55, -27, 0x00, 0x56, 0x10, -128, 0x55, 0x54}; - byte[] expectedEscaped = new byte[]{0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x56, 0x00, -27, 0x00, 0x56, 0x01, 0x10, -128, 0x56, 0x00, 0x54}; - private TestingLogFileHandler lfh; - - - @Before - public void setup() { - lfh = new TestingLogFileHandler(); - } - - @Test - public void testWriteByteArray() throws IOException { - - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - - lfh.setLogFile(byteArrayOutputStream); - - lfh.writeEscapedBytes(testUnescaped); - - byte[] result = byteArrayOutputStream.toByteArray(); - Assert.assertTrue(Arrays.equals(expectedEscaped, result)); - } - - @Test - public void readByteArray() throws IOException { - - ByteArrayInputStream in = new ByteArrayInputStream(expectedEscaped); - - lfh.readCacheContents(in); - - Assert.assertTrue(Arrays.equals(testUnescaped, lfh.mRestoredByteArray)); - - } - - @Test - public void testMarschal() throws UnsupportedEncodingException { - LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, "foobar"); - LogItem li2 = marschalAndBack(li); - testEquals(li, li2); - Assert.assertEquals(li, li2); - } - - @Test - public void testMarschalArgs() throws UnsupportedEncodingException { - LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, 772, "sinnloser Text", 7723, 723.2f, 7.2); - LogItem li2 = marschalAndBack(li); - testEquals(li, li2); - Assert.assertEquals(li, li2); - } - - @Test - public void testMarschalString() throws UnsupportedEncodingException { - LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, "Nutzlose Nachricht"); - LogItem li2 = marschalAndBack(li); - testEquals(li, li2); - Assert.assertEquals(li, li2); - } - - - private void testEquals(LogItem li, LogItem li2) { - Assert.assertEquals(li.getLogLevel(), li2.getLogLevel()); - Assert.assertEquals(li.getLogtime(), li2.getLogtime()); - Assert.assertEquals(li.getVerbosityLevel(), li2.getVerbosityLevel()); - Assert.assertEquals(li.toString(), li2.toString()); - - } - - private LogItem marschalAndBack(LogItem li) throws UnsupportedEncodingException { - byte[] bytes = li.getMarschaledBytes(); - - return new LogItem(bytes, bytes.length); - } - - - @SuppressLint("HandlerLeak") - static class TestingLogFileHandler extends LogFileHandler { - - public byte[] mRestoredByteArray; - - public TestingLogFileHandler() { - super(null); - } - - public void setLogFile(OutputStream out) { - mLogFile = out; - } - - @Override - public void readCacheContents(InputStream in) throws IOException { - super.readCacheContents(in); - } - - @Override - protected void restoreLogItem(byte[] buf, int len) { - mRestoredByteArray = Arrays.copyOf(buf, len); - } - } - - -} \ No newline at end of file +//import android.annotation.SuppressLint; +// +//import junit.framework.Assert; +// +//import org.junit.Before; +//import org.junit.Ignore; +//import org.junit.Test; +// +//import java.io.ByteArrayInputStream; +//import java.io.ByteArrayOutputStream; +//import java.io.IOException; +//import java.io.InputStream; +//import java.io.OutputStream; +//import java.io.UnsupportedEncodingException; +//import java.util.Arrays; + +/** + * NOTE [@aguestuser|04.11.17]: + * + * As the tests below: + * + * (1) are testing the logic of library code (the openvpn class `LogFileHandler`) + * -- thus making them low-value tests + * (2) currently diverge from the signatures of the class under test (overriding non-existent methods, etc.) + * -- thus failing to compile and breaking the build + * + * I am taking the liberty of commenting them out, and proposing we delete this file altogether + * upon feedback from the team. + * + **/ + + +//@Ignore +//public class TestLogFileHandler { +// +// byte[] testUnescaped = new byte[]{0x00, 0x55, -27, 0x00, 0x56, 0x10, -128, 0x55, 0x54}; +// byte[] expectedEscaped = new byte[]{0x55, 0x00, 0x00, 0x00, 0x09, 0x00, 0x56, 0x00, -27, 0x00, 0x56, 0x01, 0x10, -128, 0x56, 0x00, 0x54}; +// private TestingLogFileHandler lfh; +// +// +// @Before +// public void setup() { +// lfh = new TestingLogFileHandler(); +// } +// +// @Test +// public void testWriteByteArray() throws IOException { +// +// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); +// +// lfh.setLogFile(byteArrayOutputStream); +// +// lfh.writeEscapedBytes(testUnescaped); +// +// byte[] result = byteArrayOutputStream.toByteArray(); +// Assert.assertTrue(Arrays.equals(expectedEscaped, result)); +// } +// +// @Test +// public void readByteArray() throws IOException { +// +// ByteArrayInputStream in = new ByteArrayInputStream(expectedEscaped); +// +// lfh.readCacheContents(in); +// +// Assert.assertTrue(Arrays.equals(testUnescaped, lfh.mRestoredByteArray)); +// +// } +// +// @Test +// public void testMarschal() throws UnsupportedEncodingException { +// LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, "foobar"); +// LogItem li2 = marschalAndBack(li); +// testEquals(li, li2); +// Assert.assertEquals(li, li2); +// } +// +// @Test +// public void testMarschalArgs() throws UnsupportedEncodingException { +// LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, 72, 772, "sinnloser Text", 7723, 723.2f, 7.2); +// LogItem li2 = marschalAndBack(li); +// testEquals(li, li2); +// Assert.assertEquals(li, li2); +// } +// +// @Test +// public void testMarschalString() throws UnsupportedEncodingException { +// LogItem li = new LogItem(VpnStatus.LogLevel.DEBUG, "Nutzlose Nachricht"); +// LogItem li2 = marschalAndBack(li); +// testEquals(li, li2); +// Assert.assertEquals(li, li2); +// } +// +// +// private void testEquals(LogItem li, LogItem li2) { +// Assert.assertEquals(li.getLogLevel(), li2.getLogLevel()); +// Assert.assertEquals(li.getLogtime(), li2.getLogtime()); +// Assert.assertEquals(li.getVerbosityLevel(), li2.getVerbosityLevel()); +// Assert.assertEquals(li.toString(), li2.toString()); +// +// } +// +// private LogItem marschalAndBack(LogItem li) throws UnsupportedEncodingException { +// byte[] bytes = li.getMarschaledBytes(); +// +// return new LogItem(bytes, bytes.length); +// } +// +// +// @SuppressLint("HandlerLeak") +// static class TestingLogFileHandler extends LogFileHandler { +// +// public byte[] mRestoredByteArray; +// +// public TestingLogFileHandler() { +// super(null); +// } +// +// public void setLogFile(OutputStream out) { +// mLogFile = out; +// } +// +// @Override +// public void readCacheContents(InputStream in) throws IOException { +// super.readCacheContents(in); +// } +// +// @Override +// protected void restoreLogItem(byte[] buf, int len) { +// mRestoredByteArray = Arrays.copyOf(buf, len); +// } +// } +// +// +//} \ No newline at end of file diff --git a/build.gradle b/build.gradle index db59f144..dc2396d7 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.1' + classpath 'com.android.tools.build:gradle:2.3.1' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d1c6fba3..732dce4b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Sep 19 11:42:08 CEST 2016 +#Sat Apr 08 20:47:40 EDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip -- cgit v1.2.3 From a7b4f463e4ffc282814ef74daf18c74581fc3a7d Mon Sep 17 00:00:00 2001 From: aguestuser Date: Mon, 17 Apr 2017 00:34:21 -0400 Subject: [ag] Update dockerfile to match config in passing local build * PROBLEM: the build fails on gitlab in a debian-based docker container * BUT: i (@aguestuser) have a recently-achieved passing build on a debian laptop * ATTEMPTED SOLUTION: construct a dockerfile that matches my local configuration as precisely as possible * PROGRESS: the build gets further than it did before -- getting part of the way through the `buildNative` gradle script before failing * REMAINING FAILURE: several arm64 cross-compile steps in the `ndk-build` step fail because they depend on [neon](https://developer.android.com/ndk/guides/cpu-arm-neon.html): ```shell [arm64-v8a] Compile : crypto_static <= aesv8-armx-64.S openssl/crypto/aes/asm/aesv8-armx-64.S:35:2: error: instruction requires: neon eor v0.16b,v0.16b,v0.16b ^ openssl/crypto/aes/asm/aesv8-armx-64.S:36:2: error: instruction requires: neon ld1 {v3.16b},[x0],#16 ^ openssl/crypto/aes/asm/aesv8-armx-64.S:38:2: error: instruction requires: neon ld1 {v1.4s,v2.4s},[x3],#32 ``` * PROPOSED NEXT STEPS: * consult team to see if there's any collective wisdom about `neon` * look for ways to analyze diff of c dependencies in local machine v. docker instance * consider using ubuntu or debian:sid as the base image for the android container? --- app/build.gradle | 4 +- docker/android-sdk.dockerfile | 91 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 docker/android-sdk.dockerfile diff --git a/app/build.gradle b/app/build.gradle index cd7e6e21..b6bb39ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,8 +2,8 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion '25.0.0' - + buildToolsVersion '25.0.2' +; signingConfigs { release { storeFile project.hasProperty('storeFileProperty') ? file(storeFileProperty) : null diff --git a/docker/android-sdk.dockerfile b/docker/android-sdk.dockerfile new file mode 100644 index 00000000..dddf54c6 --- /dev/null +++ b/docker/android-sdk.dockerfile @@ -0,0 +1,91 @@ +FROM debian:stretch + +MAINTAINER LEAP Encryption Access Project +LABEL Description="Android SDK baseimage based on debian:stretch" Vendor="LEAP" Version="0.0.1" + +# ------------------------------------------------------ +# --- Install System Dependencies + +# Update Debian +RUN apt-get update -qq + +# Install Debian Packages +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ + # the basics + wget unzip git locales \ + # java stuff + openjdk-8-jdk maven \ + # c libraries + make clang lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) + +# libgcc-6-dev-arm64-cross + +# Set Locale +RUN locale-gen en_US.UTF-8 +RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 + +# ------------------------------------------------------ +# --- Install Android SDK Tools + +ENV ANDROID_HOME /opt/android-sdk-linux +ENV SDK_TOOLS_VERSION "25.2.5" + +# Install SDK Tools +RUN cd /opt \ + && wget -q -O sdk-tools.zip \ + https://dl.google.com/android/repository/tools_r${SDK_TOOLS_VERSION}-linux.zip \ + && unzip -q sdk-tools.zip -d ${ANDROID_HOME} \ + && rm -f sdk-tools.zip + +# Update PATH +ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME}/platform-tools + +# Install Platform Tools Package +RUN echo y | sdkmanager "platform-tools" # echo y to accept google licenses + +# Install Android Support Repositories +RUN echo y | sdkmanager "extras;android;m2repository" + +# Install Target SDK Packages (Please keep in descending order) +RUN echo y | sdkmanager "platforms;android-25" +RUN echo y | sdkmanager "platforms;android-24" +RUN echo y | sdkmanager "platforms;android-23" + +# Install Build Tools (Please keep in descending order) +RUN echo y | sdkmanager "build-tools;25.0.2" +RUN echo y | sdkmanager "build-tools;24.0.3" +RUN echo y | sdkmanager "build-tools;23.0.3" + +# ------------------------------------------------------ +# --- Install Android NDK (for running C code) + +ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk-bundle + +# Install NDK packages from sdk tools + +RUN echo y | sdkmanager "ndk-bundle" +RUN echo y | sdkmanager "cmake;3.6.3155560" +RUN echo y | sdkmanager "lldb;2.3" + +# Update PATH + +ENV PATH ${PATH}:${ANDROID_NDK_HOME} + + +# ------------------------------------------------------ +# --- Install Android Emulator + + +# RUN echo y | sdkmanager "emulator" + +# System Images for emulators +# RUN echo y | sdkmanager "system-images;android-25;google_apis;armeabi-v7a" +# RUN echo y | sdkmanager "system-images;android-24;google_apis;armeabi-v7a" +# RUN echo y | sdkmanager "system-images;android-23;google_apis;armeabi-v7a" +# RUN echo y | sdkmanager "system-images;android-23;google_apis;arm64-v8a" + +# ------------------------------------------------------ +# --- Cleanup + +RUN apt-get clean + -- cgit v1.2.3 From e79058d8797c918d37e406245ca7683cf07240d1 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 23 Apr 2017 16:39:03 -0400 Subject: [ag] Fix native build step with revised dockerfile * PROBLEM: * most recent version (r14b) of `android-ndk` uses `clang` for cross-compilation * BUT: `openssl` cannot compile successfully w/ `clang` * AND: we depend on `openssl` transitively through `ics-openvpn` while trying to use `android-ndk` r14b * FIX: * downgrade to `android-ndk` (12b) (most recent versoin that still uses `gcc` instead of `clang`) * modify some of the default * REMAINING PROBLEMS: * some string translations for Jamaica now break the build (unclear why -- outdated country abbreviation? ja for jm???) * we are now using a version of ndk that is 2 versions old and a version of ics-openvpn (pinned to a 3.1.2016 commit via submodule) that depends on an outdated version of `openssl`, which raises security concerns. updating to the most recent version will force us to wade into all the dependency problems amongst `ics-openvpn`/`openssl`/`ndk` * REFERENCES: * on `openssl` incompatibility w/ clang: https://github.com/openssl/openssl/pull/2229 * on `ics-openvpn` problems with `ndk`: https://github.com/android-ndk/ndk/issues/144 --- .gitlab-ci.yml | 9 ++++- docker/android-sdk.dockerfile | 86 ++++++++++++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ad57573..920f65d0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,12 @@ +# NOTE(@aguestuser|4.23.17): +# - we would prefer 0xacab.org:4567/leap/bitmask_android:android-sdk +# as the build image, but cant do that presently b/c: +# (1) i do not have permissions to create docker repositories in this repo +# (2) we need to add whatever image we use to gitlab ci's whitelist +# or else we get a message like: +# `ERROR: The 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 is not present on list of allowed images` + image: "0xacab.org:4567/leap/gitlab-buildpackage:android" -#image: "gfx2015/android" stages: - build diff --git a/docker/android-sdk.dockerfile b/docker/android-sdk.dockerfile index dddf54c6..31b89d4c 100644 --- a/docker/android-sdk.dockerfile +++ b/docker/android-sdk.dockerfile @@ -3,6 +3,22 @@ FROM debian:stretch MAINTAINER LEAP Encryption Access Project LABEL Description="Android SDK baseimage based on debian:stretch" Vendor="LEAP" Version="0.0.1" +# ------------------------------------------------------ +# --- Env Vars + + +ENV ANDROID_SDK_VERSION "25.2.5" +ENV ANDROID_NDK_VERSION "r12b" + +# NOTE(@aguestuser|4.23.17) +# We woud like to use te current version of Android NDK () + +ENV ANDROID_HOME /opt/android-sdk-linux +ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} + +ENV ANDROID_SDK_URL https://dl.google.com/android/repository/tools_r${ANDROID_SDK_VERSION}-linux.zip +ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip + # ------------------------------------------------------ # --- Install System Dependencies @@ -12,13 +28,11 @@ RUN apt-get update -qq # Install Debian Packages RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ # the basics - wget unzip git locales \ + curl unzip git locales \ # java stuff openjdk-8-jdk maven \ # c libraries - make clang lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) - -# libgcc-6-dev-arm64-cross + make gcc lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) # Set Locale RUN locale-gen en_US.UTF-8 @@ -27,19 +41,54 @@ RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 # ------------------------------------------------------ # --- Install Android SDK Tools -ENV ANDROID_HOME /opt/android-sdk-linux -ENV SDK_TOOLS_VERSION "25.2.5" # Install SDK Tools -RUN cd /opt \ - && wget -q -O sdk-tools.zip \ - https://dl.google.com/android/repository/tools_r${SDK_TOOLS_VERSION}-linux.zip \ - && unzip -q sdk-tools.zip -d ${ANDROID_HOME} \ +RUN curl -L $ANDROID_SDK_URL -o sdk-tools.zip \ + && unzip -q sdk-tools.zip -d $ANDROID_HOME \ && rm -f sdk-tools.zip # Update PATH ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME}/platform-tools +# ------------------------------------------------------ +# --- Install Android NDK (for running C code) + +RUN curl -L $ANDROID_NDK_URL -o ndk.zip \ + && unzip ndk.zip -d $ANDROID_HOME \ + && rm -rf ndk.zip + +# HACK (@aguestuser|4.23.17): + +# BUG: +# when installed on a 64-bit machine, ndk r12b +# fails to cross-compile for *some* (not all) target architectures +# because it looks for prebuilt packages in /prebuilt/linux-x86 +# instead of /prebuilt/linux-x86_64 (which is where it installed them) + +# PENDING: +# (1) a cleaner solution +# (2) upgrading to ndk r14b (pending openssl/clang bugfix: https://github.com/openssl/openssl/pull/2229) + +# WORKAROUND: +# we simply rename all such directories so the cross-compiler can find them + +ENV TARGETS "aarch64-linux-android-4.9 \ + arm-linux-androideabi-4.9 \ + mipsel-linux-android-4.9 \ + x86-4.9 \ + x86_64-4.9" + +RUN for target in $TARGETS; do \ + cd ${ANDROID_NDK_HOME}/toolchains/${target}/prebuilt \ + && mv linux-x86_64/ linux-x86/; \ + done + +ENV PATH ${PATH}:${ANDROID_NDK_HOME} + +# ------------------------------------------------------ +# --- Install Android SDK Tools Packages + + # Install Platform Tools Package RUN echo y | sdkmanager "platform-tools" # echo y to accept google licenses @@ -53,25 +102,10 @@ RUN echo y | sdkmanager "platforms;android-23" # Install Build Tools (Please keep in descending order) RUN echo y | sdkmanager "build-tools;25.0.2" +RUN echo y | sdkmanager "build-tools;25.0.0" RUN echo y | sdkmanager "build-tools;24.0.3" RUN echo y | sdkmanager "build-tools;23.0.3" -# ------------------------------------------------------ -# --- Install Android NDK (for running C code) - -ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk-bundle - -# Install NDK packages from sdk tools - -RUN echo y | sdkmanager "ndk-bundle" -RUN echo y | sdkmanager "cmake;3.6.3155560" -RUN echo y | sdkmanager "lldb;2.3" - -# Update PATH - -ENV PATH ${PATH}:${ANDROID_NDK_HOME} - - # ------------------------------------------------------ # --- Install Android Emulator -- cgit v1.2.3 From 215edb9840e5a75ed961fbf8b6ce423116deef28 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 23 Apr 2017 20:36:37 -0400 Subject: [ag] eliminate hacky workaround for 64-bit builds * HACK: replace all toolchain references to `linux-x86_64` with `linux-x86` * FIX: provide dependency on `file` package that will allow `ndk-build` to detect 32-bit userland, making this * side-effects: * group sdk/env vars with installation code that uses them * add explanatory note about why we use outdated version of `android-ndk` ------------------ *Explanation:* More careful analysis of the meaning of the word `file` in this (subtle!) error message: ```shell /opt/android-sdk-linux/android-ndk-r12b/build/ndk-build: 143: /opt/android-sdk-linux/android-ndk-r12b/build/ndk-build: file: not found ``` led to inspecting line 143 of `ndk-build`, revealing an undefined variable called `file` that would allow `ndk-build` to detect a 32-bit userland: ```shell file -L "$SHELL" | grep -q "x86[_-]64" ``` Thus the error messsage was *not* trying to tell us that a file could not be found, but that the program called `file` could not be found. FUN! :) --- docker/android-sdk.dockerfile | 61 ++++++++++++------------------------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/docker/android-sdk.dockerfile b/docker/android-sdk.dockerfile index 31b89d4c..468546cf 100644 --- a/docker/android-sdk.dockerfile +++ b/docker/android-sdk.dockerfile @@ -3,22 +3,6 @@ FROM debian:stretch MAINTAINER LEAP Encryption Access Project LABEL Description="Android SDK baseimage based on debian:stretch" Vendor="LEAP" Version="0.0.1" -# ------------------------------------------------------ -# --- Env Vars - - -ENV ANDROID_SDK_VERSION "25.2.5" -ENV ANDROID_NDK_VERSION "r12b" - -# NOTE(@aguestuser|4.23.17) -# We woud like to use te current version of Android NDK () - -ENV ANDROID_HOME /opt/android-sdk-linux -ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} - -ENV ANDROID_SDK_URL https://dl.google.com/android/repository/tools_r${ANDROID_SDK_VERSION}-linux.zip -ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip - # ------------------------------------------------------ # --- Install System Dependencies @@ -31,8 +15,8 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ curl unzip git locales \ # java stuff openjdk-8-jdk maven \ - # c libraries - make gcc lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) + # ndk dependencies + make gcc file lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) # Set Locale RUN locale-gen en_US.UTF-8 @@ -41,6 +25,9 @@ RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 # ------------------------------------------------------ # --- Install Android SDK Tools +ENV ANDROID_SDK_VERSION "25.2.5" +ENV ANDROID_HOME /opt/android-sdk-linux +ENV ANDROID_SDK_URL https://dl.google.com/android/repository/tools_r${ANDROID_SDK_VERSION}-linux.zip # Install SDK Tools RUN curl -L $ANDROID_SDK_URL -o sdk-tools.zip \ @@ -53,36 +40,22 @@ ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME} # ------------------------------------------------------ # --- Install Android NDK (for running C code) +# NOTE(@aguestuser|4.23.17) +# We woud like to use te current version of Android NDK (r14b) but cannot +# due to pinned dependency on year-old version of `ics-openvpn` +# which has transitive dependency on `openssl` which will not compile with `clang` +# (starting in 13b, android ndk uses `clang` isntead of `gcc`) +# Upon rebasing onto to current HEAD of `ics-openvpn` and resolving conflicts, we +# should update to current version of `ndk` (if possible). + +ENV ANDROID_NDK_VERSION "r12b" +ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} +ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip + RUN curl -L $ANDROID_NDK_URL -o ndk.zip \ && unzip ndk.zip -d $ANDROID_HOME \ && rm -rf ndk.zip -# HACK (@aguestuser|4.23.17): - -# BUG: -# when installed on a 64-bit machine, ndk r12b -# fails to cross-compile for *some* (not all) target architectures -# because it looks for prebuilt packages in /prebuilt/linux-x86 -# instead of /prebuilt/linux-x86_64 (which is where it installed them) - -# PENDING: -# (1) a cleaner solution -# (2) upgrading to ndk r14b (pending openssl/clang bugfix: https://github.com/openssl/openssl/pull/2229) - -# WORKAROUND: -# we simply rename all such directories so the cross-compiler can find them - -ENV TARGETS "aarch64-linux-android-4.9 \ - arm-linux-androideabi-4.9 \ - mipsel-linux-android-4.9 \ - x86-4.9 \ - x86_64-4.9" - -RUN for target in $TARGETS; do \ - cd ${ANDROID_NDK_HOME}/toolchains/${target}/prebuilt \ - && mv linux-x86_64/ linux-x86/; \ - done - ENV PATH ${PATH}:${ANDROID_NDK_HOME} # ------------------------------------------------------ -- cgit v1.2.3 From 7ed7d62015fafe5b9a11097c04419d2ffd0826c1 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 23 Apr 2017 20:58:42 -0400 Subject: [ag] use self-contained docker registry in ci build * for greater compartmentalization and self-documentation, use docker registry in this repo to host image used in its build rather than registry in `leap/gitlab-buildpackage` as before --- .gitlab-ci.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 920f65d0..5321f64d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,4 @@ -# NOTE(@aguestuser|4.23.17): -# - we would prefer 0xacab.org:4567/leap/bitmask_android:android-sdk -# as the build image, but cant do that presently b/c: -# (1) i do not have permissions to create docker repositories in this repo -# (2) we need to add whatever image we use to gitlab ci's whitelist -# or else we get a message like: -# `ERROR: The 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 is not present on list of allowed images` - -image: "0xacab.org:4567/leap/gitlab-buildpackage:android" +image: "0xacab.org:4567/leap/bitmask_android/android-sdk:latest" stages: - build -- cgit v1.2.3 From 9278f4680d9fdd34803089be875d16d667c0579e Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 23 Apr 2017 21:32:48 -0400 Subject: [ag] use canonical format for 0xacab docker registry images * this change was necessitated by prior format failing a whitelisted images check here: https://0xacab.org/aguestuser/bitmask_android/builds/9406 * NOTE: this format means we can't label `android-sdk` images by version because the tag is reserved for the image name, not the version :( * ie: the whitelist forces us to specify `bimtask_android:android-sdk` rather than `bitmask_android/android-sdk:0.0.1` -- is there a reason for this? --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5321f64d..8bbe684b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: "0xacab.org:4567/leap/bitmask_android/android-sdk:latest" +image: "0xacab.org:4567/leap/bitmask_android:android-sdk" stages: - build -- cgit v1.2.3 From 27b25ef2ea2baed320f7aed7b7e16a4a454d5f64 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 23 Apr 2017 21:35:38 -0400 Subject: [ag] clean up README --- README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d827bd6e..70ff6dcd 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,6 @@ These are necessary to make sure the program cross-compiles to 32-bit architectu sudo apt install lib32stdc++ lib32z1 ``` -lib64stdc++ - ### Android SDK #### With Android Studio @@ -142,9 +140,7 @@ sdkmanager ndk-bundle #### Updating Your Path -Once you've installed Android SDK & NDK packages, you need to modify your PATH so you can invoke all the programs you just installed. (On GNU/Linux, machines, this is generally `~/Android/Sdk`.) - -You can do that with something like the following in your `~/.shellrc` or `~/.bash_profile`: +Once you've installed Android SDK & NDK packages, you need to modify your PATH so you can invoke all the programs you just installed. You can do that with something like the following in your `~/.shellrc` or `~/.bash_profile`: ```shell export ANDROID_HOME= @@ -154,6 +150,8 @@ export PATH=$ANDROID_HOME/platform-tools:$PATH export PATH=$ANDROID_HOME/tools/bin:$PATH ``` +NOTE: On GNU/Linux machines, Android Studio installs the Android SDK in `~/Android/Sdk/`. Our dockerfile installs it in `/opt/android-sdk-linux`. You can install it wherever you want! Just be sure to remember where so you can add it to your PATH! :) + #### With Docker Geesh! If all that above seems like a lot, it is! @@ -389,8 +387,6 @@ You have a couple options. The second is more robust: function emulator { pushd `pwd`; cd "$(dirname "$(which emulator)")" && ./emulator "$@"; popd;} ``` -*** PROBLEM 2: OUTDATED VERSIONS OF GL LIBRARIES - #### 3. Outdated GL Libraries **Symptoms:** If you have this bug, you will see something like the following: -- cgit v1.2.3 From d1594edf30c4d6f171682b527ebffbb489d6481b Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 23 Apr 2017 23:29:01 -0400 Subject: [ag] use external docker registry to demonstrate state of build --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8bbe684b..7d2875ac 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,5 @@ -image: "0xacab.org:4567/leap/bitmask_android:android-sdk" +#image: "0xacab.org:4567/leap/bitmask_android:android-sdk" +image: "0xacab.org:4567/leap/gitlab-buildpackage:android" stages: - build -- cgit v1.2.3 From 7ed71d793c24b0b074cf61a85ea96c45c21f07f1 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 30 Apr 2017 15:35:42 -0400 Subject: [ag] generate all locales in android-sdk dockerfile to pass build --- docker/android-sdk.dockerfile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docker/android-sdk.dockerfile b/docker/android-sdk.dockerfile index 468546cf..753ac6a9 100644 --- a/docker/android-sdk.dockerfile +++ b/docker/android-sdk.dockerfile @@ -18,9 +18,16 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ # ndk dependencies make gcc file lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) -# Set Locale -RUN locale-gen en_US.UTF-8 +# ------------------------------------------------------ +# --- Set Locales + +# Generate All Locales +RUN cp /usr/share/i18n/SUPPORTED /etc/locale.gen +RUN locale-gen + +# Set Default Locale RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 +ENV LANG en_US.UTF-8 # ------------------------------------------------------ # --- Install Android SDK Tools -- cgit v1.2.3 From 690364e6debe88ae052d93808d715b9ac79d4bc1 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 30 Apr 2017 17:09:41 -0400 Subject: [ag] extract sdk, ndk, emulator configs to separate dockerfiles --- docker/android-emulator.dockerfile | 24 ++++++++++++++++++++ docker/android-ndk.dockerfile | 32 ++++++++++++++++++++++++++ docker/android-sdk.dockerfile | 46 +++----------------------------------- 3 files changed, 59 insertions(+), 43 deletions(-) create mode 100644 docker/android-emulator.dockerfile create mode 100644 docker/android-ndk.dockerfile diff --git a/docker/android-emulator.dockerfile b/docker/android-emulator.dockerfile new file mode 100644 index 00000000..0201312b --- /dev/null +++ b/docker/android-emulator.dockerfile @@ -0,0 +1,24 @@ +FROM 0xacab.org:4567/leap/bitmask_android/android-sdk:latest + +MAINTAINER LEAP Encryption Access Project +LABEL Description="Android SDK baseimage based on debian:stretch" Vendor="LEAP" Version="25" + +# ------------------------------------------------------ +# --- System Dependencies + +# ensure GL compatibility + +RUN apt-get update -qq +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y mesa-utils +ENV ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 + +# ------------------------------------------------------ +# --- Install Android Emulator + +# Install Android SDK emulator package +RUN echo y | sdkmanager "emulator" + +# Install System Images for emulators +RUN echo y | sdkmanager "system-images;android-25;google_apis;x86_64" +RUN echo y | sdkmanager "system-images;android-24;google_apis;x86_64" +RUN echo y | sdkmanager "system-images;android-23;google_apis;x86_64" diff --git a/docker/android-ndk.dockerfile b/docker/android-ndk.dockerfile new file mode 100644 index 00000000..0a3eabfd --- /dev/null +++ b/docker/android-ndk.dockerfile @@ -0,0 +1,32 @@ +FROM 0xacab.org:4567/leap/bitmask_android/android-sdk:latest + +MAINTAINER LEAP Encryption Access Project +LABEL Description="Android NDK image based on android-sdk baseimage" Vendor="LEAP" Version="r12b" + +# ------------------------------------------------------ +# --- Install System Dependencies + +RUN apt-get update -qq +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ + make gcc file lib32stdc++6 lib32z1 # JNI build dependencies w/ 32-bit compatible C libs + +# ------------------------------------------------------ +# --- Install Android NDK (for running C code) + +# NOTE(@aguestuser|4.23.17) +# We woud like to use te current version of Android NDK (r14b) but cannot +# due to pinned dependency on year-old version of `ics-openvpn` +# which has transitive dependency on `openssl` which will not compile with `clang` +# (starting in 13b, android ndk uses `clang` isntead of `gcc`) +# Upon rebasing onto to current HEAD of `ics-openvpn` and resolving conflicts, we +# should update to current version of `ndk`. + +ENV ANDROID_NDK_VERSION "r12b" +ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} +ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip + +RUN curl -L $ANDROID_NDK_URL -o ndk.zip \ + && unzip ndk.zip -d $ANDROID_HOME \ + && rm -rf ndk.zip + +ENV PATH ${PATH}:${ANDROID_NDK_HOME} diff --git a/docker/android-sdk.dockerfile b/docker/android-sdk.dockerfile index 753ac6a9..1007735d 100644 --- a/docker/android-sdk.dockerfile +++ b/docker/android-sdk.dockerfile @@ -1,22 +1,17 @@ FROM debian:stretch MAINTAINER LEAP Encryption Access Project -LABEL Description="Android SDK baseimage based on debian:stretch" Vendor="LEAP" Version="0.0.1" +LABEL Description="Android SDK baseimage based on debian:stretch" Vendor="LEAP" Version="25.2.5" # ------------------------------------------------------ # --- Install System Dependencies -# Update Debian RUN apt-get update -qq - -# Install Debian Packages RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ # the basics curl unzip git locales \ # java stuff - openjdk-8-jdk maven \ - # ndk dependencies - make gcc file lib32stdc++6 lib32z1 # (incl. 32-bit compatible versions) + openjdk-8-jdk maven # ------------------------------------------------------ # --- Set Locales @@ -44,31 +39,9 @@ RUN curl -L $ANDROID_SDK_URL -o sdk-tools.zip \ # Update PATH ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME}/platform-tools -# ------------------------------------------------------ -# --- Install Android NDK (for running C code) - -# NOTE(@aguestuser|4.23.17) -# We woud like to use te current version of Android NDK (r14b) but cannot -# due to pinned dependency on year-old version of `ics-openvpn` -# which has transitive dependency on `openssl` which will not compile with `clang` -# (starting in 13b, android ndk uses `clang` isntead of `gcc`) -# Upon rebasing onto to current HEAD of `ics-openvpn` and resolving conflicts, we -# should update to current version of `ndk` (if possible). - -ENV ANDROID_NDK_VERSION "r12b" -ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} -ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip - -RUN curl -L $ANDROID_NDK_URL -o ndk.zip \ - && unzip ndk.zip -d $ANDROID_HOME \ - && rm -rf ndk.zip - -ENV PATH ${PATH}:${ANDROID_NDK_HOME} - # ------------------------------------------------------ # --- Install Android SDK Tools Packages - # Install Platform Tools Package RUN echo y | sdkmanager "platform-tools" # echo y to accept google licenses @@ -86,20 +59,7 @@ RUN echo y | sdkmanager "build-tools;25.0.0" RUN echo y | sdkmanager "build-tools;24.0.3" RUN echo y | sdkmanager "build-tools;23.0.3" -# ------------------------------------------------------ -# --- Install Android Emulator - - -# RUN echo y | sdkmanager "emulator" - -# System Images for emulators -# RUN echo y | sdkmanager "system-images;android-25;google_apis;armeabi-v7a" -# RUN echo y | sdkmanager "system-images;android-24;google_apis;armeabi-v7a" -# RUN echo y | sdkmanager "system-images;android-23;google_apis;armeabi-v7a" -# RUN echo y | sdkmanager "system-images;android-23;google_apis;arm64-v8a" - # ------------------------------------------------------ # --- Cleanup -RUN apt-get clean - +RUN apt clean -- cgit v1.2.3 From 1e8da8edc94a552511e740f9d6a52a0d522432aa Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 30 Apr 2017 17:12:59 -0400 Subject: [ag] use ndk container from repo registry in build --- .gitlab-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7d2875ac..6f8f92c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,4 @@ -#image: "0xacab.org:4567/leap/bitmask_android:android-sdk" -image: "0xacab.org:4567/leap/gitlab-buildpackage:android" +image: "0xacab.org:4567/leap/bitmask_android/android-ndk:latest" stages: - build -- cgit v1.2.3 From 730ab74a2a38cdbe8ac735f2d641d3d19055bf34 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 30 Apr 2017 19:03:59 -0400 Subject: [ag] modify sdk dockerfile to ensure android-23 platform installs * on remote builds, failure of Android SDK Platform 23 to properly install was causing build failures undetected in local container. see: * to fix this, tweak order of `sdkmanager` calls and remove `echo -y` flags to ensure platform installation completes successfully and build step never tries to install Platform 23 --- docker/android-sdk.dockerfile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docker/android-sdk.dockerfile b/docker/android-sdk.dockerfile index 1007735d..4044a7ec 100644 --- a/docker/android-sdk.dockerfile +++ b/docker/android-sdk.dockerfile @@ -46,18 +46,18 @@ ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME} RUN echo y | sdkmanager "platform-tools" # echo y to accept google licenses # Install Android Support Repositories -RUN echo y | sdkmanager "extras;android;m2repository" - -# Install Target SDK Packages (Please keep in descending order) -RUN echo y | sdkmanager "platforms;android-25" -RUN echo y | sdkmanager "platforms;android-24" -RUN echo y | sdkmanager "platforms;android-23" +RUN sdkmanager "extras;android;m2repository" # Install Build Tools (Please keep in descending order) -RUN echo y | sdkmanager "build-tools;25.0.2" -RUN echo y | sdkmanager "build-tools;25.0.0" -RUN echo y | sdkmanager "build-tools;24.0.3" -RUN echo y | sdkmanager "build-tools;23.0.3" +RUN sdkmanager "build-tools;25.0.2" +RUN sdkmanager "build-tools;25.0.0" +RUN sdkmanager "build-tools;24.0.3" +RUN sdkmanager "build-tools;23.0.3" + +# Install Target SDK Packages (Please keep in descending order) +RUN sdkmanager "platforms;android-25" +RUN sdkmanager "platforms;android-24" +RUN sdkmanager "platforms;android-23" # ------------------------------------------------------ # --- Cleanup -- cgit v1.2.3 From 8de794f75268a38b35a9b080d37dad83285da6d8 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 30 Apr 2017 19:27:00 -0400 Subject: [ag] update README to reflect correct versions, install process --- README.md | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 70ff6dcd..dfd66af0 100644 --- a/README.md +++ b/README.md @@ -48,16 +48,16 @@ The Bitmask Android Client has the following system-level dependencies: * JDK v. 1.8 * Assorted 32-bit C libraries -* Android SDK Tools, v. 25.0.2, with these packages: +* Android SDK Tools, v. 25.2.5, with these packages: * Platform-Tools, v. 25.0.2 * Build-Tools, API v. 23-25 * Platforms 23-25 * Android Support Repository * Google Support Repository - * NDK v. r14b (enables C code in Android) + * NDK v. r12b (enables C code in Android) * For running the app in an emulator, you will also need these packages: * Android Emulator - * ARMEABI System Images for Adnroid APIs 23-25 + * System Images for Android APIs 23-25 * The ICS-OpenVpn submodule You can install them as follows: @@ -75,7 +75,7 @@ sudo apt install default-jdk These are necessary to make sure the program cross-compiles to 32-bit architectures successfully from 64-bit GNU/Linux machines: ``` -sudo apt install lib32stdc++ lib32z1 +sudo apt make gcc file install lib32stdc++ lib32z1 ``` ### Android SDK @@ -92,13 +92,20 @@ Once you've got it installed, use the `SDK Manager` tool (Android figure Icon wi #### With Bash -Alternatley (eg: for build machines), you may download the `android-sdk` tarball from Google as follows: +Alternatley (eg: for build machines), you may download and unzip the `android-sdk` bundle from Google as follows (assuming an install location of `/opt/android-sdk-linux`: ``` -cd -wget -q https://dl.google.com/android/android-sdk_r23.0.3-linux.tgz -O android-sdk.tgz -tar -xvzf android-sdk.tgz -rm -f android-sdk.tgz +curl -L https://dl.google.com/android/android-sdk_r25.2.5-linux.zip -o sdk-tools.zip \ + && unzip -q sdk-tools.zip -d /opt/android-sdk-linux \ + && rm -f sdk-tools.zip +``` + +To download the NDK (for cross-compiling and running the C code used in `ics-openvpn`), use: + +``` +curl -L http://dl.google.com/android/repository/android-ndk-r12b-linux-x86_64.zip -o ndk.zip \ + && unzip ndk.zip -d /opt/android-sdk-linux/android-ndk-r12b \ + && rm -rf ndk.zip ``` After updating your PATH (see next step), you may now use the `sdkmanager` tool bundled with `android-sdk` to browse and install new sdk packages from Google. @@ -118,24 +125,16 @@ sdkmanager --list | grep tools To install all of the dependencies listed above (targetting SDK versions 23 - 25), run: ```shell -# update sdk tools sdkmanager tools - -# get supporting packages sdkmanager platform-tools sdkmanager extras;android;m2repository sdkmanager extras;google;m2repository - -# get build tools and sdk platforms for api v 23 - 25 sdkmanager build-tools;25.0.2 sdkmanager build-tools;24.0.3 sdkmanager build-tools;23.0.3 sdkmanager platforms;android-25 sdkmanager platforms;android-24 sdkmanager platforms;android-23 - -# install NDK (for C code) -sdkmanager ndk-bundle ``` #### Updating Your Path @@ -161,22 +160,21 @@ To keep ourselves from messing it up all the time everyone someone new joins the Assuming you've already [installed docker](https://docs.docker.com/engine/installation/), you can pull the image with: ``` shell -docker pull 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 +docker pull 0xacab.org:4567/aguestuser/bitmask_android:android-ndk:latest ``` Run the image with: ``` shell -docker run -i -t 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 +docker run --rm -it 0xacab.org:4567/aguestuser/bitmask_android:android-ndk:latest ``` More likely than not, you'll want to run the image with the source code mounted. You can do that with: ``` shell cd -docker run -i -v`pwd`:/bitmask_android -t 0xacab.org:4567/aguestuser/bitmask_android:android-sdk-25 +docker run --rm -it -v`pwd`:/bitmask_android -t 0xacab.org:4567/aguestuser/bitmask_android:android-ndk:latest ``` -*TODO(@aguestuser|04.16.17): move docker registry to 0xacab.org/leap (pending permissions)* ### Submodules @@ -241,7 +239,7 @@ If you want to make sure the environment you use to build APKs matches exactly t ``` shell $ cd -$ sudo docker run -i -t `pwd`:/bitmask_android 0xacab.org/aguestuser/bitmask_android:android-sdk-25 +$ sudo docker run --rm -it -v `pwd`:/bitmask_android 0xacab.org/leap/bitmask_android/android-ndk:latest # cd /bitmask_android # ./gradlew assembleRelease ``` -- cgit v1.2.3 From 4333fd93e3a1c64f6c0fb42be9ae29879ea2c7f0 Mon Sep 17 00:00:00 2001 From: aguestuser Date: Sun, 30 Apr 2017 20:14:58 -0400 Subject: [ag] change issues link in readme to point to 0xacab not github --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfd66af0..20711e63 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository contains the source code for the [Bitmask](https://bitmask.net/) To lean about the stack, visit [leap.se](https://leap.se). -Please see the [issues](https://github.com/leapcode/bitmask_android/issues) section to report any bugs or feature requests, and to see the list of known issues. +Please see the [issues](https://0xacab.org/leap/bitmask_android/issues) section to report any bugs or feature requests, and to see the list of known issues. # Table Of Contents -- cgit v1.2.3