diff options
19 files changed, 287 insertions, 220 deletions
diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java index aef968b8..3e572c31 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/BaseTestDashboardFragment.java @@ -1,13 +1,15 @@ package se.leap.bitmaskclient.test; -import android.content.*; -import android.graphics.*; -import android.test.*; -import android.view.*; +import android.content.Context; +import android.graphics.Rect; +import android.test.ActivityInstrumentationTestCase2; +import android.view.View; -import com.robotium.solo.*; +import com.robotium.solo.Solo; -import se.leap.bitmaskclient.*; +import se.leap.bitmaskclient.ConfigurationWizard; +import se.leap.bitmaskclient.Dashboard; +import se.leap.bitmaskclient.R; public abstract class BaseTestDashboardFragment extends ActivityInstrumentationTestCase2<Dashboard> { @@ -28,8 +30,9 @@ public abstract class BaseTestDashboardFragment extends ActivityInstrumentationT 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"); + if (solo.searchText(solo.getString(R.string.configuration_wizard_title))) { + toDashboardAnonymously("demo.bitmask.net"); + } } void changeProviderAndLogIn(String provider) { @@ -60,4 +63,32 @@ public abstract class BaseTestDashboardFragment extends ActivityInstrumentationT view.getHitRect(scrollBounds); return view.getLocalVisibleRect(scrollBounds); } + + + private void toDashboardAnonymously(String provider) { + selectProvider(provider); + useAnonymously(); + } + + private void useAnonymously() { + String text = solo.getString(R.string.use_anonymously_button); + clickAndWaitForDashboard(text); + } + + + private void selectProvider(String provider) { + solo.clickOnText(provider); + Screenshot.setTimeToSleep(1); + Screenshot.take("Configuring provider"); + waitForProviderDetails(); + } + + private void waitForProviderDetails() { + String text = solo.getString(R.string.provider_details_fragment_title); + assertTrue("Provider details dialog did not appear", solo.waitForText(text, 1, 60*1000)); + Screenshot.take("Provider details"); + } + + + } diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestCalendarProvider.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestCalendarProvider.java new file mode 100644 index 00000000..82ea8b59 --- /dev/null +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestCalendarProvider.java @@ -0,0 +1,26 @@ +package se.leap.bitmaskclient.test; + +import java.util.Calendar; + +import se.leap.bitmaskclient.eip.CalendarProviderInterface; + +/** + * Created by cyberta on 13.09.17. + */ + +class TestCalendarProvider implements CalendarProviderInterface { + + private long currentTimeInMillis = 0; + + public TestCalendarProvider(long currentTimeInMillis) { + this.currentTimeInMillis = currentTimeInMillis; + } + + @Override + public Calendar getCalendar() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(currentTimeInMillis); + return calendar; + } + +} 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 8b897b96..90b8b839 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestConfigurationWizard.java @@ -1,42 +1,36 @@ package se.leap.bitmaskclient.test; -import android.test.*; -import android.widget.*; +import android.test.ActivityInstrumentationTestCase2; +import android.widget.ListView; -import com.robotium.solo.*; +import com.robotium.solo.Solo; -import java.io.*; +import java.io.IOException; -import se.leap.bitmaskclient.*; +import se.leap.bitmaskclient.AboutActivity; +import se.leap.bitmaskclient.ConfigurationWizard; +import se.leap.bitmaskclient.R; -public class testConfigurationWizard extends ActivityInstrumentationTestCase2<ConfigurationWizard> { +public class TestConfigurationWizard extends ActivityInstrumentationTestCase2<ConfigurationWizard> { private Solo solo; private static int added_providers; - private boolean executing_from_dashboard = false; - public testConfigurationWizard() { + public TestConfigurationWizard() { super(ConfigurationWizard.class); } - public testConfigurationWizard(Solo solo) { - super(ConfigurationWizard.class); - this.solo = solo; - executing_from_dashboard = true; - } @Override protected void setUp() throws Exception { super.setUp(); solo = new Solo(getInstrumentation(), getActivity()); Screenshot.initialize(solo); - //ConnectionManager.setMobileDataEnabled(true, solo.getCurrentActivity().getApplicationContext()); } @Override protected void tearDown() throws Exception { - if(!executing_from_dashboard) - solo.finishOpenedActivities(); + solo.finishOpenedActivities(); super.tearDown(); } @@ -81,7 +75,8 @@ public class testConfigurationWizard extends ActivityInstrumentationTestCase2<Co } public void testAddNewProvider() { - addProvider("calyx.net"); + //addProvider("calyx.net"); + addProvider("riseup.net"); } private void addProvider(String url) { @@ -91,7 +86,9 @@ public class testConfigurationWizard extends ActivityInstrumentationTestCase2<Co added_providers = added_providers + 1; solo.clickOnActionBarItem(R.id.new_provider); solo.enterText(0, url); - solo.clickOnCheckBox(0); + if ( BuildConfig.FLAVOR.equals("insecure")) { + solo.clickOnCheckBox(0); + } solo.clickOnText(solo.getString(R.string.save)); waitForProviderDetails(); solo.goBack(); @@ -107,18 +104,4 @@ public class testConfigurationWizard extends ActivityInstrumentationTestCase2<Co assertTrue("Provider details dialog did not appear", solo.waitForActivity(AboutActivity.class)); } - protected void toDashboardAnonymously(String provider) { - selectProvider(provider); - useAnonymously(); - } - - private void useAnonymously() { - String text = solo.getString(R.string.use_anonymously_button); - clickAndWaitForDashboard(text); - } - - private void clickAndWaitForDashboard(String click_text) { - solo.clickOnText(click_text); - assertTrue(solo.waitForActivity(Dashboard.class, 5000)); - } } diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboardIntegration.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestDashboardIntegration.java index ece70c59..faeb1791 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboardIntegration.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestDashboardIntegration.java @@ -4,7 +4,7 @@ import java.io.*; import se.leap.bitmaskclient.*; -public class testDashboardIntegration extends BaseTestDashboardFragment { +public class TestDashboardIntegration extends BaseTestDashboardFragment { @Override protected void tearDown() throws Exception { diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testEIP.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEIP.java index b504af99..1a32e1c9 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testEIP.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestEIP.java @@ -27,13 +27,13 @@ import se.leap.bitmaskclient.eip.*; /** * @author parmegv */ -public class testEIP extends ServiceTestCase<EIP> { +public class TestEIP extends ServiceTestCase<EIP> { private Context context; private Intent intent; private SharedPreferences preferences; - public testEIP(Class<EIP> activityClass) { + public TestEIP(Class<EIP> activityClass) { super(activityClass); context = getSystemContext(); intent = new Intent(context, EIP.class); diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testGatewaysManager.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java index 086c060f..4817adbb 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testGatewaysManager.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java @@ -29,7 +29,7 @@ import se.leap.bitmaskclient.eip.*; /** * @author parmegv */ -public class testGatewaysManager extends InstrumentationTestCase { +public class TestGatewaysManager extends InstrumentationTestCase { GatewaysManager gateways_manager; Gateway gateway; diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testLeapSRPSession.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestLeapSRPSession.java index 149c2c7f..8d0df59b 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testLeapSRPSession.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestLeapSRPSession.java @@ -11,9 +11,9 @@ import se.leap.bitmaskclient.*; import junit.framework.*; -public class testLeapSRPSession extends TestCase { +public class TestLeapSRPSession extends TestCase { - public testLeapSRPSession(String name) { + public TestLeapSRPSession(String name) { super(name); } diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testUserStatusFragment.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestUserStatusFragment.java index 2031f365..d77b9796 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testUserStatusFragment.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestUserStatusFragment.java @@ -1,8 +1,8 @@ package se.leap.bitmaskclient.test; -public class testUserStatusFragment extends BaseTestDashboardFragment { +public class TestUserStatusFragment extends BaseTestDashboardFragment { - public final String TAG = testUserStatusFragment.class.getName(); + public final String TAG = TestUserStatusFragment.class.getName(); private final String provider = "demo.bitmask.net"; private final String test_username = "parmegvtest1"; @@ -27,7 +27,7 @@ public class testUserStatusFragment extends BaseTestDashboardFragment { public void testFailedLogIn() { user_status_controller.clickUserSessionButton(); - user_status_controller.logIn(test_username, TAG); + user_status_controller.logIn(test_username, TAG, false); if(!user_status_controller.assertErrorLogInDialogAppears()) throw new IllegalStateException(); } diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnCertificateValidator.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnCertificateValidator.java new file mode 100644 index 00000000..97a0e36d --- /dev/null +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnCertificateValidator.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2013, 2014, 2015 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package se.leap.bitmaskclient.test; + +import android.content.Context; +import android.test.InstrumentationTestCase; + +import org.json.JSONObject; + +import java.util.Calendar; + +import se.leap.bitmaskclient.Provider; +import se.leap.bitmaskclient.eip.VpnCertificateValidator; + +/** + * @author parmegv + * //FIXME: The class VpnCertificateValidator should be tested with unit tests! + */ +public class TestVpnCertificateValidator extends InstrumentationTestCase { + + String certificate_valid_from_nov2012_to_nov2022 = ""; + + Context context; + FromAssets assets; + + @Override + protected void setUp() throws Exception { + context = getInstrumentation().getContext(); + assets = new FromAssets(context); + JSONObject secrets = new JSONObject(assets.toString(TestConstants.SECRETS_FILE)); + certificate_valid_from_nov2012_to_nov2022 = secrets.getString(Provider.CA_CERT); + super.setUp(); + } + + + public void testIsValid() { + VpnCertificateValidator validator = new VpnCertificateValidator(certificate_valid_from_nov2012_to_nov2022); + Calendar calendar = Calendar.getInstance(); + + calendar.set(Calendar.YEAR, 2006); + calendar.set(Calendar.MONTH, Calendar.NOVEMBER); + calendar.set(Calendar.DAY_OF_MONTH, 6); calendar.set(Calendar.YEAR, 2006); + validator.setCalendarProvider(new TestCalendarProvider(calendar.getTimeInMillis())); + assertFalse(validator.isValid()); + + calendar.set(Calendar.YEAR, 2011); + calendar.set(Calendar.MONTH, Calendar.NOVEMBER); + calendar.set(Calendar.DAY_OF_MONTH, 6); + validator.setCalendarProvider(new TestCalendarProvider(calendar.getTimeInMillis())); + assertFalse(validator.isValid()); + + calendar.set(Calendar.YEAR, 2012); + calendar.set(Calendar.MONTH, Calendar.NOVEMBER); + calendar.set(Calendar.DAY_OF_MONTH, 6); + validator.setCalendarProvider(new TestCalendarProvider(calendar.getTimeInMillis())); + assertTrue(validator.isValid()); + + calendar.set(Calendar.YEAR, 2022); + calendar.set(Calendar.MONTH, Calendar.OCTOBER); + calendar.set(Calendar.DAY_OF_MONTH, 21); + validator.setCalendarProvider(new TestCalendarProvider(calendar.getTimeInMillis())); + assertTrue(validator.isValid()); + + calendar.set(Calendar.YEAR, 2022); + calendar.set(Calendar.MONTH, Calendar.OCTOBER); + calendar.set(Calendar.DAY_OF_MONTH, 22); + validator.setCalendarProvider(new TestCalendarProvider(calendar.getTimeInMillis())); + assertFalse(validator.isValid()); + + } + +} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testVpnFragment.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnFragment.java index 12cb8c14..b16bcf4f 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testVpnFragment.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestVpnFragment.java @@ -1,6 +1,6 @@ package se.leap.bitmaskclient.test; -public class testVpnFragment extends BaseTestDashboardFragment { +public class TestVpnFragment extends BaseTestDashboardFragment { /** * This test will fail if Android does not trust VPN connection. @@ -8,7 +8,7 @@ public class testVpnFragment extends BaseTestDashboardFragment { */ public void testOnOffOpenVpn() { vpn_controller.clickVpnButton(); - Screenshot.setTimeToSleep(8); + Screenshot.setTimeToSleep(2); Screenshot.takeWithSleep("Turning VPN on"); vpn_controller.turningEipOn(); Screenshot.setTimeToSleep(0.5); @@ -24,13 +24,6 @@ public class testVpnFragment extends BaseTestDashboardFragment { vpn_controller.clickVpnButton(); vpn_controller.turningEipOff(); - /*clickVpnButton();; - turningEipOn(); - - turnNetworkOff(); - restartAdbServer(); // This doesn't work - */ - } /** @@ -47,27 +40,27 @@ public class testVpnFragment extends BaseTestDashboardFragment { } public void testVpnEveryProvider() { - testDemoBitmaskNet(); - testRiseupNet(); - testCalyxNet(); + checkDemoBitmaskNet(); + checkRiseupNet(); + checkCalyxNet(); } - private void testDemoBitmaskNet() { - testProvider("demo.bitmask.net"); + private void checkDemoBitmaskNet() { + checkProvider("demo.bitmask.net"); } - private void testRiseupNet() { - testProvider("riseup.net"); + private void checkRiseupNet() { + checkProvider("riseup.net"); } - private void testCalyxNet() { - testProvider("calyx.net"); + private void checkCalyxNet() { + checkProvider("calyx.net"); } - private void testProvider(String provider) { + private void checkProvider(String provider) { changeProviderAndLogIn(provider); vpn_controller.sleepSeconds(1); - vpn_controller.turnVpnOndAndOff(provider); + vpn_controller.turnVpnOndAndOff(); vpn_controller.sleepSeconds(1); } diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/UserStatusTestController.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/UserStatusTestController.java index 138dfa71..821a23fd 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/UserStatusTestController.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/UserStatusTestController.java @@ -6,6 +6,8 @@ import com.robotium.solo.*; import se.leap.bitmaskclient.*; +import static junit.framework.Assert.assertTrue; + public class UserStatusTestController { private final Solo solo; @@ -25,22 +27,32 @@ public class UserStatusTestController { return view; } - void logIn(String username, String password) { + void logIn(String username, String password, boolean expectSuccess) { solo.enterText(0, username); solo.enterText(1, password); solo.clickOnText(solo.getString(R.string.login_button)); - solo.waitForDialogToClose(); - assertLoggedIn(); + assertTrue(solo.waitForDialogToClose()); + + if (expectSuccess) { + assertLoggedIn(); + } else { + solo.waitForText(solo.getString(R.string.cancel)); + assertTrue(solo.waitForText(solo.getString(R.string.login_button))); + } + } + + void logIn(String username, String password) { + logIn(username, password, true); } private void assertLoggedIn() { String log_out = solo.getString(R.string.logout_button); - solo.waitForText(log_out); + assertTrue(solo.waitForText(log_out)); } void assertLoggedOut() { String log_in = solo.getString(R.string.login_button); - solo.waitForText(log_in); + assertTrue(solo.waitForText(log_in)); } void logOut() { @@ -53,7 +65,7 @@ public class UserStatusTestController { } boolean assertErrorLogInDialogAppears() { - solo.waitForDialogToOpen(); + assertTrue(solo.waitForDialogToOpen()); String username_hint = solo.getEditText(0).getHint().toString(); String correct_username_hint = solo.getString(R.string.username_hint); 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 39ab37dd..b0996032 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java @@ -1,18 +1,18 @@ package se.leap.bitmaskclient.test; -import android.graphics.*; -import android.graphics.drawable.*; -import android.view.*; -import android.widget.*; +import android.view.View; +import android.widget.Button; -import com.robotium.solo.*; +import com.robotium.solo.Condition; +import com.robotium.solo.Solo; -import junit.framework.AssertionFailedError; - -import de.blinkt.openvpn.activities.*; -import mbanje.kurt.fabbutton.*; +import de.blinkt.openvpn.activities.DisconnectVPN; +import mbanje.kurt.fabbutton.FabButton; +import mbanje.kurt.fabbutton.ProgressRingView; import se.leap.bitmaskclient.R; +import static junit.framework.Assert.assertTrue; + public class VpnTestController { private final Solo solo; @@ -21,7 +21,7 @@ public class VpnTestController { this.solo = solo; } - protected void turnVpnOndAndOff(String provider) { + protected void turnVpnOndAndOff() { clickVpnButton(); turningEipOn(); clickVpnButton(); @@ -36,19 +36,15 @@ public class VpnTestController { } protected Button getVpnButton() { - try { - View button_view = solo.getView(R.id.vpn_main_button); - if (button_view != null) - return (Button) button_view; - else - return new Button(solo.getCurrentActivity()); - } catch (AssertionFailedError e) { - return new Button(solo.getCurrentActivity()); - } + View button_view = solo.getView(R.id.vpn_main_button); + if (button_view != null) + return (Button) button_view; + else + return null; } private boolean isVpnButton(Button button) { - return !button.getText().toString().isEmpty(); + return button != null && !button.getText().toString().isEmpty(); } protected FabButton getVpnWholeIcon() { @@ -69,7 +65,7 @@ public class VpnTestController { return iconShowsConnected(); } }; - solo.waitForCondition(condition, max_seconds_until_connected * 1000); + assertTrue("condition iconShowsConnected not fulfilled within " + max_seconds_until_connected + " seconds." , solo.waitForCondition(condition, max_seconds_until_connected * 1000)); sleepSeconds(2); } @@ -83,43 +79,13 @@ public class VpnTestController { } private boolean iconShowsConnected() { - return iconEquals(iconConnectedDrawable()); + View vpnIconView = getVpnWholeIcon(); + return vpnIconView.getTag().equals(R.drawable.ic_stat_vpn); } protected boolean iconShowsDisconnected() { - return iconEquals(iconDisconnectedDrawable()); - } - - private boolean iconEquals(Drawable drawable) { - Bitmap inside_icon = getVpnInsideIcon(); - if(inside_icon != null) - return inside_icon.equals(drawable); - else - return false; - - } - - private Drawable iconConnectedDrawable() { - return getDrawable(R.drawable.ic_stat_vpn); - } - - private Drawable iconDisconnectedDrawable() { - return getDrawable(R.drawable.ic_stat_vpn_offline); - } - - private Drawable getDrawable(int resId) { - return solo.getCurrentActivity().getResources().getDrawable(resId); - } - - private Bitmap getVpnInsideIcon() { - FabButton whole_icon = getVpnWholeIcon(); - - CircleImageView a; - a = whole_icon != null ? - (CircleImageView) getVpnWholeIcon().findViewById(R.id.fabbutton_circle) - : new CircleImageView(solo.getCurrentActivity()); - a.setDrawingCacheEnabled(true); - return a.getDrawingCache(); + View vpnIconView = getVpnWholeIcon(); + return vpnIconView.getTag().equals(R.drawable.ic_stat_vpn_offline); } protected void turningEipOff() { @@ -134,12 +100,12 @@ public class VpnTestController { return iconShowsDisconnected(); } }; - solo.waitForCondition(condition, max_seconds_until_connected * 1000); + assertTrue(solo.waitForCondition(condition, max_seconds_until_connected * 1000)); sleepSeconds(2); } private void okToBrowserWarning() { - solo.waitForDialogToOpen(); + assertTrue(solo.waitForDialogToOpen()); clickYes(); } diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testVpnCertificateValidator.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/testVpnCertificateValidator.java deleted file mode 100644 index 672607be..00000000 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testVpnCertificateValidator.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2013, 2014, 2015 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package se.leap.bitmaskclient.test; - -import android.content.*; -import android.os.*; -import android.test.*; - -import org.json.*; - -import java.io.*; -import java.util.*; - -import se.leap.bitmaskclient.*; -import se.leap.bitmaskclient.eip.*; - -/** - * @author parmegv - */ -public class testVpnCertificateValidator extends InstrumentationTestCase { - - String certificate_valid_from_jan2015_to_nov2022 = ""; - - Context context; - FromAssets assets; - - @Override - protected void setUp() throws Exception { - context = getInstrumentation().getContext(); - assets = new FromAssets(context); - JSONObject secrets = new JSONObject(assets.toString(TestConstants.SECRETS_FILE)); - certificate_valid_from_jan2015_to_nov2022 = secrets.getString(Provider.CA_CERT); - super.setUp(); - } - - public void testIsValid() { - VpnCertificateValidator validator = new VpnCertificateValidator(certificate_valid_from_jan2015_to_nov2022); - setTime(2015, 1, 6); - assertTrue(validator.isValid()); - setTime(2020, 1, 6); - assertFalse(validator.isValid()); - } - - private void setTime(int year, int month, int day) { - shellCommand("adb shell chmod 666 /dev/alarm"); - Calendar c = Calendar.getInstance(); - c.set(year, month, day, 12, 00, 00); - SystemClock.setCurrentTimeMillis(c.getTimeInMillis()); - shellCommand("adb shell chmod 664 /dev/alarm"); - } - - private int shellCommand(String command) { - int result = 0; - try { - Runtime.getRuntime().exec(command); - } catch (IOException e) { - e.printStackTrace(); - } - return result; - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java index 9210c6ec..6ffeacc1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java @@ -49,6 +49,7 @@ public class VpnFragment extends Fragment implements Observer { private static EipStatus eip_status; private boolean wants_to_connect; + //FIXME: replace with onAttach(Context context) public void onAttach(Activity activity) { super.onAttach(activity); @@ -254,12 +255,15 @@ public class VpnFragment extends Fragment implements Observer { if(eip_status.isConnecting()) { vpn_status_image.showProgress(true); vpn_status_image.setIcon(R.drawable.ic_stat_vpn_empty_halo, R.drawable.ic_stat_vpn_empty_halo); + vpn_status_image.setTag(R.drawable.ic_stat_vpn_empty_halo); } else { vpn_status_image.showProgress(false); vpn_status_image.setIcon(R.drawable.ic_stat_vpn, R.drawable.ic_stat_vpn); + vpn_status_image.setTag(R.drawable.ic_stat_vpn); } } else { vpn_status_image.setIcon(R.drawable.ic_stat_vpn_offline, R.drawable.ic_stat_vpn_offline); + vpn_status_image.setTag(R.drawable.ic_stat_vpn_offline); vpn_status_image.showProgress(false); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/CalendarProvider.java b/app/src/main/java/se/leap/bitmaskclient/eip/CalendarProvider.java new file mode 100644 index 00000000..a9aec6b8 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/CalendarProvider.java @@ -0,0 +1,14 @@ +package se.leap.bitmaskclient.eip; + +import java.util.Calendar; + +/** + * Created by cyberta on 13.09.17. + */ + +class CalendarProvider implements CalendarProviderInterface { + + public Calendar getCalendar() { + return Calendar.getInstance(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/CalendarProviderInterface.java b/app/src/main/java/se/leap/bitmaskclient/eip/CalendarProviderInterface.java new file mode 100644 index 00000000..a20f5fab --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/CalendarProviderInterface.java @@ -0,0 +1,11 @@ +package se.leap.bitmaskclient.eip; + +import java.util.Calendar; + +/** + * Created by cyberta on 13.09.17. + */ + +public interface CalendarProviderInterface { + Calendar getCalendar(); +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java index 8fce6a37..28099f06 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnCertificateValidator.java @@ -25,22 +25,35 @@ public class VpnCertificateValidator { public final static String TAG = VpnCertificateValidator.class.getSimpleName(); private String certificate; + private CalendarProviderInterface calendarProvider; public VpnCertificateValidator(String certificate) { this.certificate = certificate; + this.calendarProvider = new CalendarProvider(); } + public void setCalendarProvider(CalendarProviderInterface calendarProvider) { + this.calendarProvider = calendarProvider; + } + + /** + * + * @return true if there's a certificate that is valid for more than 15 more days + */ public boolean isValid() { - if (!certificate.isEmpty()) { - X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate); - return isValid(certificate_x509); - } else return true; + if (certificate.isEmpty()) { + return false; + } + + X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate); + return isValid(certificate_x509); } + private boolean isValid(X509Certificate certificate) { - Calendar offset_date = calculateOffsetCertificateValidity(certificate); + Calendar offsetDate = calculateOffsetCertificateValidity(certificate); try { - certificate.checkValidity(offset_date.getTime()); + certificate.checkValidity(offsetDate.getTime()); return true; } catch (CertificateExpiredException e) { return false; @@ -50,11 +63,15 @@ public class VpnCertificateValidator { } private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { - long preventive_time = Math.abs(certificate.getNotBefore().getTime() - certificate.getNotAfter().getTime()) / 2; - long current_date_millis = Calendar.getInstance().getTimeInMillis(); + Calendar limitDate = calendarProvider.getCalendar(); + Date startDate = certificate.getNotBefore(); + // if certificates start date is before current date just return the current date without an offset + if (startDate.getTime() >= limitDate.getTime().getTime()) { + return limitDate; + } + // else add an offset of 15 days to the current date + limitDate.add(Calendar.DAY_OF_YEAR, 15); - Calendar limit_date = Calendar.getInstance(); - limit_date.setTimeInMillis(current_date_millis + preventive_time); - return limit_date; + return limitDate; } } diff --git a/app/src/main/res/drawable-ldpi/ic_stat_vpn.png b/app/src/main/res/drawable-ldpi/ic_stat_vpn.png Binary files differindex 65fc6db7..008aaf63 100644 --- a/app/src/main/res/drawable-ldpi/ic_stat_vpn.png +++ b/app/src/main/res/drawable-ldpi/ic_stat_vpn.png diff --git a/app/src/main/res/layout/eip_service_fragment.xml b/app/src/main/res/layout/eip_service_fragment.xml index 06b514d3..7df82b19 100644 --- a/app/src/main/res/layout/eip_service_fragment.xml +++ b/app/src/main/res/layout/eip_service_fragment.xml @@ -30,14 +30,13 @@ android:textSize="12sp" /> - <view + <mbanje.kurt.fabbutton.FabButton android:id="@+id/vpn.Status.Image" android:layout_width="32dp" android:layout_height="32dp" android:layout_marginLeft="3dp" android:layout_marginStart="3dp" android:color="@android:color/holo_blue_dark" - class="mbanje.kurt.fabbutton.FabButton" android:layout_gravity="center" android:visibility="visible" android:indeterminate="true" |