summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--AndroidManifest.xml7
-rw-r--r--CHANGELOG13
-rwxr-xr-xcompile.sh2
-rw-r--r--res/menu/client_dashboard.xml3
-rwxr-xr-xres/values-ca/strings.xml3
-rwxr-xr-xres/values-cs/strings.xml5
-rwxr-xr-xres/values-de/strings.xml5
-rwxr-xr-xres/values-es/strings.xml3
-rwxr-xr-xres/values-et/strings.xml3
-rwxr-xr-xres/values-fr/strings.xml3
-rwxr-xr-xres/values-id/strings.xml5
-rwxr-xr-xres/values-it/strings.xml3
-rwxr-xr-xres/values-ja/strings.xml5
-rwxr-xr-xres/values-ko/strings.xml3
-rwxr-xr-xres/values-nl/strings.xml3
-rwxr-xr-xres/values-no/strings.xml3
-rwxr-xr-xres/values-ro/strings.xml3
-rwxr-xr-xres/values-ru/strings.xml5
-rwxr-xr-xres/values-uk/strings.xml5
-rwxr-xr-xres/values-zh-rCN/strings.xml3
-rwxr-xr-xres/values-zh-rTW/strings.xml3
-rwxr-xr-xres/values/strings.xml27
-rw-r--r--res/values/untranslatable.xml4
-rw-r--r--src/se/leap/bitmaskclient/ConfigHelper.java3
-rw-r--r--src/se/leap/bitmaskclient/ConfigurationWizard.java13
-rw-r--r--src/se/leap/bitmaskclient/Dashboard.java47
-rw-r--r--src/se/leap/bitmaskclient/EIP.java35
-rw-r--r--src/se/leap/bitmaskclient/EipServiceFragment.java14
-rw-r--r--src/se/leap/bitmaskclient/LogInDialog.java4
-rw-r--r--src/se/leap/bitmaskclient/NewProviderDialog.java13
-rw-r--r--src/se/leap/bitmaskclient/Provider.java2
-rw-r--r--src/se/leap/bitmaskclient/ProviderAPI.java5
-rw-r--r--src/se/leap/bitmaskclient/ProviderListFragment.java17
-rw-r--r--src/se/leap/openvpn/ConfigParser.java6
-rw-r--r--src/se/leap/openvpn/OpenVPN.java5
-rw-r--r--src/se/leap/openvpn/OpenVPNThread.java2
-rw-r--r--src/se/leap/openvpn/OpenVpnManagementThread.java28
-rw-r--r--src/se/leap/openvpn/OpenVpnService.java13
-rw-r--r--src/se/leap/openvpn/VpnProfile.java1
-rw-r--r--tests/.classpath10
-rw-r--r--tests/.project34
-rw-r--r--tests/AndroidManifest.xml18
-rw-r--r--tests/ant.properties18
-rw-r--r--tests/build.xml92
-rwxr-xr-xtests/compile.sh1
-rw-r--r--tests/libs/robotium-solo-4.3.1.jarbin0 -> 106789 bytes
-rw-r--r--tests/lint.xml3
-rw-r--r--tests/proguard-project.txt20
-rw-r--r--tests/project.properties14
-rwxr-xr-xtests/run.sh2
-rw-r--r--tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java65
-rw-r--r--tests/src/se/leap/bitmaskclient/test/testDashboard.java140
-rw-r--r--tests/src/se/leap/bitmaskclient/test/testLeapSRPSession.java636
-rwxr-xr-xtests/testClass.sh17
55 files changed, 1294 insertions, 104 deletions
diff --git a/.gitignore b/.gitignore
index 9aa5a039..9773f598 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ obj
bin
gen
libs
+.settings
openvpn/.git
openvpn/autom4te.cache
openvpn/aclocal.m4
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d2818125..bb788109 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,12 +17,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="se.leap.bitmaskclient"
- android:versionCode="62"
- android:versionName="0.2.2" >
+ android:versionCode="64"
+ android:versionName="0.2.3" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <!-- if you want to run the unit test for Dashboard you will need that you uncomment the following line -->
+ <!-- <uses-permission android:name="android.permission.WRITE_SETTINGS" /> -->
+
<!-- <uses-permission android:name="com.android.vending.BILLING" /> -->
diff --git a/CHANGELOG b/CHANGELOG
index 09ad9761..b0f0d8e0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+0.2.3-rc1 Nov 29 2013
+Features
+- Begin integrating tests into repository
+- Clearer wording in some places
+- Show VPN Gateway location in notification
+Bugs Fixed
+- URL parsing error if http entered for custom provider
+- Issues with certificates and gateways when switching providers
+- SEVERE: Routes were not set on VPN connection and traffic was routed in the clear
+
+
0.2.2 - Nov 15 2013 - the "rampant growth" release:
Features
- Rebranded to Bitmask
@@ -11,6 +22,8 @@ Bugs Fixed
- Complex certificate verification
- Remember authentication status
- Widget shortcut crashes app
+
+
0.2.1 - Oct 21 2013 - the "get on that rolling bandwagon" release:
Bugs Fixed
- SRP tests should be runnable localhost
diff --git a/compile.sh b/compile.sh
index c557e371..32d36267 100755
--- a/compile.sh
+++ b/compile.sh
@@ -9,3 +9,5 @@ fi
android update project --path . --name "Bitmask for Android" --target android-17
ant debug
+
+cd tests/ && ./compile.sh && cd ..
diff --git a/res/menu/client_dashboard.xml b/res/menu/client_dashboard.xml
index 2ce8b87c..8f4a7ba8 100644
--- a/res/menu/client_dashboard.xml
+++ b/res/menu/client_dashboard.xml
@@ -17,11 +17,10 @@
<item
android:id="@+id/switch_provider"
android:orderInCategory="501"
- android:title="@string/switch_provider_menu_option"/>
+ android:title="@string/switch_provider_menu_option"/>
<item
android:id="@+id/login_button"
android:showAsAction="ifRoom"
- android:icon="@drawable/ic_menu_login"
android:title="@string/login_button"
android:visible="false">
</item>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 5131250a..0840c365 100755
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP per Android</string>
<string name="address">Adreá del servidor:</string>
<string name="port">Port del servidor:</string>
<string name="location">Lloc</string>
@@ -15,7 +14,7 @@
<string name="client_pkcs12_title">Fitxer PKCS12</string>
<string name="ca_title">Certificat CA</string>
<string name="about">Quan a</string>
- <string name="about_summary">Quan a LEAP per Android</string>
+ <string name="about_summary">Quan a Bitmask per Android</string>
<string name="vpn_list_summary">Llista de VPNs configurades</string>
<string name="vpn_list_title">Perfils VPN</string>
<string name="vpn_type">Tipus</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 37ae7f40..3bb898d6 100755
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP pro Android</string>
<string name="address">Adresa serveru:</string>
<string name="port">Port serveru:</string>
<string name="location">Lokace</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Zdrojové kódy a seznam problémů je na https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Tento program používá následující komponenty; viz zdrojový kód pro detaily o licenci</string>
<string name="about">O programu</string>
- <string name="about_summary">O programu LEAP pro Android</string>
+ <string name="about_summary">O programu Bitmask pro Android</string>
<string name="vpn_list_summary">Seznam všech nakonfigurovaných VPN</string>
<string name="vpn_list_title">Všechny VPN</string>
<string name="vpn_type">Typ</string>
@@ -235,7 +234,7 @@
<string name="minidump_generated">OpenVPN neočekávaně havarovalo. Zvaž možnost použití volby poslat Minidump z hlavního menu</string>
<string name="send_minidump">Poslat Minidump vývojáři</string>
<string name="send_minidump_summary">Poslat ladící informace o poslední havárii vývojáři</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$s - %2$s</string>
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">Připojuji se</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index df50b594..46a7322e 100755
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP für Android</string>
<string name="address">Server:</string>
<string name="port">Server Port:</string>
<string name="location">Ort</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Quellcode und Issue Tracker sind verfügbar unter https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Dieses Programm nutzt die folgenden Komponenten. Die kompletten Lizenzdetails sind im Quelltext verfügbar.</string>
<string name="about">Über</string>
- <string name="about_summary">Über LEAP für Android</string>
+ <string name="about_summary">Über Bitmask für Android</string>
<string name="vpn_list_summary">Alle konfigurierten VPN Profile</string>
<string name="vpn_list_title">VPN Liste</string>
<string name="vpn_type">Typ</string>
@@ -235,7 +234,7 @@
<string name="minidump_generated">Der OpenVPN Prozess ist unerwartet abgestürzt. Bitte erwägen Sie die Option \"Minidump senden\" im Hauptmenü</string>
<string name="send_minidump">Minidump an Entwickler senden</string>
<string name="send_minidump_summary">Sendet Debugging Informationen des letzten Absturzes an den Entwickler</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$s - %2$s</string>
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">Verbinde</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 36fcc199..e8398560 100755
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP para Android</string>
<string name="address">Dirección del servidor:</string>
<string name="port">Puerto del servidor:</string>
<string name="location">Ubicación</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Codigo fuente y sistema de reporte de errores disponibles en https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">El programa utiliza los siguientes componentes. Vea los códigos fuentes para obtener más información sobre las licencias</string>
<string name="about">Acerca de</string>
- <string name="about_summary">Acerca de LEAP para Android</string>
+ <string name="about_summary">Acerca de Bitmask para Android</string>
<string name="vpn_list_summary">Lista de todas las VPN configuradas</string>
<string name="vpn_list_title">Perfiles VPN</string>
<string name="vpn_type">Tipo</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index b0758d74..dba6caa4 100755
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP Androidile</string>
<string name="address">Serveri aadress:</string>
<string name="port">Serveri port:</string>
<string name="location">Asukoht</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Lähtetekst ja probleemihaldur asuvad veebilehel https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Programmis kasutatakse järgnevaid komponente. Detailse litsenseerimisinfo leiate lähtekoodist</string>
<string name="about">Lähemalt</string>
- <string name="about_summary">Täpsemalt programmist LEAP Androidile</string>
+ <string name="about_summary">Täpsemalt programmist Bitmask Androidile</string>
<string name="vpn_list_summary">Kõigi seadistatud VPN kanalite nimekiri</string>
<string name="vpn_list_title">VPN profiilid</string>
<string name="vpn_type">Tüüp</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index ec36bc8b..6ed418ff 100755
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">"LEAP pour Android"</string>
<string name="address">"Adresse du serveur:"</string>
<string name="port">"Port:"</string>
<string name="location">"Emplacement"</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">"Le code source et le tracker de bugs est disponible ici: https://github.com/leapcode/bitmask_android/ "</string>
<string name="copyright_others">"Le programme utilise les composants suivants. Voir le code source pour plus de détails sur les licences."</string>
<string name="about">"À propos"</string>
- <string name="about_summary">"À propos d\'LEAP pour Android"</string>
+ <string name="about_summary">"À propos d\'Bitmask pour Android"</string>
<string name="vpn_list_summary">"Liste de tous les VPN configurés"</string>
<string name="vpn_list_title">"Vos VPNs"</string>
<string name="vpn_type">"Type"</string>
diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml
index 0166b7ea..43b36768 100755
--- a/res/values-id/strings.xml
+++ b/res/values-id/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP untuk Android</string>
<string name="address">Alamat Server:</string>
<string name="port">Port server:</string>
<string name="location">Lokasi</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Kode program dan perekam masalah tersedia di</string>
<string name="copyright_others">Aplikasi memakai komponen berikut; lihat kode program untuk lebih jelas mengenai lisensi</string>
<string name="about">Tentang...</string>
- <string name="about_summary">Tentang LEAP untuk Android</string>
+ <string name="about_summary">Tentang Bitmask untuk Android</string>
<string name="vpn_list_summary">Daftar konfigurasi VPN</string>
<string name="vpn_list_title">Profil VPN</string>
<string name="vpn_type">Tipe</string>
@@ -235,7 +234,7 @@
<string name="minidump_generated">OpenVPN crash tak terduga. Silakan mempertimbangkan mengirim menggunakan pilihan Minidump di Menu Utama</string>
<string name="send_minidump">Mengirim MiniDump untuk pengembang</string>
<string name="send_minidump_summary">Kirim informasi kesalahan tentang kegagalan aplikasi yang terakhir ke pengembang</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$ s - %2$ s</string>
<string name="session_ipv6string">%1$ s - %3$ s, %2$ s</string>
<string name="state_connecting">Menghubungkan</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 1e935bf2..341d4d50 100755
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP per Android</string>
<string name="address">Indirizzo server:</string>
<string name="port">Porta del server:</string>
<string name="location">Posizione</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Il codice sorgente e il bug tracker sono disponibili all\'indirizzo https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Questo programma usa i seguenti componenti; guarda il codice sorgente per i dettagli completi sulle licenze</string>
<string name="about">Informazioni</string>
- <string name="about_summary">Informazioni su LEAP per Android</string>
+ <string name="about_summary">Informazioni su Bitmask per Android</string>
<string name="vpn_list_summary">Elenco connessioni VPN configurate</string>
<string name="vpn_list_title">Profili VPN</string>
<string name="vpn_type">Tipo</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index db7602f7..a85dc726 100755
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP Android</string>
<string name="address">サーバアドレス</string>
<string name="port">ポート番号</string>
<string name="location">場所</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">ソースコードと問題管理は以下で: https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">プログラムは、次のコンポーネントを使用します。完全な詳細についてはソース上のライセンスを参照してください。</string>
<string name="about">バージョン情報</string>
- <string name="about_summary">LEAP Androidについて</string>
+ <string name="about_summary">Bitmask Androidについて</string>
<string name="vpn_list_summary">設定されたすべてのVPN</string>
<string name="vpn_list_title">VPNプロファイル</string>
<string name="vpn_type">種別</string>
@@ -274,7 +273,7 @@ TCP keepaliveと長いタイムアウト時間は動作しますが、TCP over T
<string name="minidump_generated">OpenVPN は予期せず終了しました。メイン メニューでミニダンプの送信オプションを検討してください。</string>
<string name="send_minidump">ミニダンプを開発者に送信</string>
<string name="send_minidump_summary">最後にクラッシュした時のデバッグ情報を作者に送信します。</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$s - %2$s</string>
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">接続中</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 4cd9da70..08c1bc26 100755
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">안드로이드용 LEAP</string>
<string name="address">서버 주소:</string>
<string name="port">서버 포트:</string>
<string name="location">위치</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">소스 코드와 문제 추적기는 https://github.com/leapcode/bitmask_android/에서 사용할 수 있습니다</string>
<string name="copyright_others">프로그램은 다음 구성 요소를 사용합니다. 라이선스에 대 한 자세한 내용은 소스를 참조 하십시오</string>
<string name="about">소개</string>
- <string name="about_summary">안드로이드용 LEAP 소개</string>
+ <string name="about_summary">안드로이드용 Bitmask 소개</string>
<string name="vpn_list_summary">설정된 VPN의 목록</string>
<string name="vpn_list_title">VPN 프로파일</string>
<string name="vpn_type">유형</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 459c80ec..01eefb86 100755
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP voor Android</string>
<string name="address">Server Adres:</string>
<string name="port">Server Poort:</string>
<string name="location">Locatie</string>
@@ -15,7 +14,7 @@
<string name="client_pkcs12_title">PKCS12 Bestand</string>
<string name="ca_title">CA Certificaat</string>
<string name="about">Over</string>
- <string name="about_summary">Over LEAP voor Android</string>
+ <string name="about_summary">Over Bitmask voor Android</string>
<string name="vpn_list_summary">Lijst van alle geconfigureerde VPN verbindingen</string>
<string name="vpn_list_title">VPN Profielen</string>
<string name="vpn_type">Type</string>
diff --git a/res/values-no/strings.xml b/res/values-no/strings.xml
index 99b97277..a5551578 100755
--- a/res/values-no/strings.xml
+++ b/res/values-no/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP Android</string>
<string name="address">Server adresse:</string>
<string name="port">Server port:</string>
<string name="location">Plassering</string>
@@ -15,7 +14,7 @@
<string name="client_pkcs12_title">PKCS12 fil</string>
<string name="ca_title">CA-sertifikat</string>
<string name="about">Om</string>
- <string name="about_summary">Om LEAP Android</string>
+ <string name="about_summary">Om Bitmask Android</string>
<string name="vpn_list_summary">Liste over alle konfigurerte VPN-tilkoblinger</string>
<string name="vpn_list_title">VPN-profiler</string>
<string name="vpn_type">Type</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 308a47ac..0b669803 100755
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP pentru Android</string>
<string name="address">Adresa server:</string>
<string name="port">Port server:</string>
<string name="location">Locaţie</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Cod sursă şi tracker probleme disponibile la https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Acest program utilizează următoarele componente; a se vedea codul sursă pentru mai multe detalii despre licente</string>
<string name="about">Despre</string>
- <string name="about_summary">Despre LEAP pentru Android</string>
+ <string name="about_summary">Despre Bitmask pentru Android</string>
<string name="vpn_list_summary">Lista tuturor VPN-urilor configurate</string>
<string name="vpn_list_title">Profile VPN</string>
<string name="vpn_type">Tip</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 1d3c10a3..596bd913 100755
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP для Android</string>
<string name="address">Адрес сервера:</string>
<string name="port">Порт сервера:</string>
<string name="location">Расположение</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Исходники и информация о версиях находятся по адресу https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Данная программа использует следующие компоненты; смотрите исходный код для получения подробной информации о лицензии</string>
<string name="about">О программе</string>
- <string name="about_summary">Описание LEAP для Android</string>
+ <string name="about_summary">Описание Bitmask для Android</string>
<string name="vpn_list_summary">Список всех туннелей VPN</string>
<string name="vpn_list_title">Профили VPN</string>
<string name="vpn_type">Тип</string>
@@ -234,7 +233,7 @@
<string name="minidump_generated">OpenVPN завершилась неожиданно. Пожалуйста, посмотрите опцию \"Отправить Minidump\" в главном меню</string>
<string name="send_minidump">Отправить Minidump разработчику</string>
<string name="send_minidump_summary">Отправка отладочной информации разработчику о последнем неудачном завершении</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$s - %2$s</string>
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">Подключение</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 14d9ce90..0a668bf9 100755
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP для Android</string>
<string name="address">Адреса сервера:</string>
<string name="port">Порт сервера:</string>
<string name="location">Розташування</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">Початковий код і відстеження проблем доступні по https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">Ця програма використовує такі компоненти; перегляньте вихідний код для повної інформації про ліцензії</string>
<string name="about">Про</string>
- <string name="about_summary">Про LEAP для Android</string>
+ <string name="about_summary">Про Bitmask для Android</string>
<string name="vpn_list_summary">Список всіх налаштованих VPN</string>
<string name="vpn_list_title">VPN профілі</string>
<string name="vpn_type">Тип</string>
@@ -235,7 +234,7 @@
<string name="minidump_generated">OpenVPN впав несподівано. Будь ласка, розгляньте використання параметру \"Надіслати Мінідамп\" в головному меню</string>
<string name="send_minidump">Надіслати мінідамп розробнику</string>
<string name="send_minidump_summary">Надіслати налагоджувальну інформацію про останній збій розробнику</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$s - %2$s</string>
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">Підключення</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 89d3aeab..5dfc1b68 100755
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP Android版</string>
<string name="address">服务器地址:</string>
<string name="port">服务器端口:</string>
<string name="location">地点</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">请前往 https://github.com/leapcode/bitmask_android/ 源码或提供问题反馈</string>
<string name="copyright_others">本程序使用以下组件,请在 Licenses 查看源码获取更详细内容。</string>
<string name="about">关于</string>
- <string name="about_summary">关于 LEAP Android</string>
+ <string name="about_summary">关于 Bitmask Android</string>
<string name="vpn_list_summary">已完成配置的 VPN 列表</string>
<string name="vpn_list_title">VPN 配置文件</string>
<string name="vpn_type">类型</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 2d2f31ca..3d178545 100755
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
- <string name="app">LEAP Android</string>
<string name="address">伺服器地址:</string>
<string name="port">伺服器端口:</string>
<string name="location">位置</string>
@@ -19,7 +18,7 @@
<string name="repository_url_text">取得原始碼與個案追蹤,可上 https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">本程序使用了以下元件,其作者和授權資訊如下</string>
<string name="about">關於</string>
- <string name="about_summary">關於 LEAP Android</string>
+ <string name="about_summary">關於 Bitmask Android</string>
<string name="vpn_list_summary">列出所有已設置的VPN</string>
<string name="vpn_list_title">VPN設定檔</string>
<string name="vpn_type">類型</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b4839763..8a5bb49f 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2,8 +2,6 @@
<!-- Generated by crowdin.net -->
<resources>
- <string name="app">Bitmask for Android</string>
- <string name="app_name">Bitmask</string>
<string name="address">Server Address:</string>
<string name="port">Server Port:</string>
<string name="location">Location</string>
@@ -21,7 +19,7 @@
<string name="no_certificate">You must select a certificate</string>
<string name="repository_url_text">Source code and issue tracker available at https://github.com/leapcode/bitmask_android/</string>
<string name="copyright_others">This program uses the following components; see the source code for full details on the licenses</string>
- <string name="about">About</string>
+ <string name="about">About Bitmask</string>
<string name="switch_provider_menu_option">Switch provider</string>
<string name="about_summary">About Bitmask for Android</string>
<string name="vpn_list_summary">List of all configured VPNs</string>
@@ -239,7 +237,7 @@
<string name="minidump_generated">OpenVPN crashed unexpectedly. Please consider using the send Minidump option in the main menu</string>
<string name="send_minidump">Send Minidump to developer</string>
<string name="send_minidump_summary">Send debugging information about last crash to developer</string>
- <string name="notifcation_title">OpenVPN - %s</string>
+ <string name="notifcation_title">Bitmask - %s</string>
<string name="session_ipv4string">%1$s - %2$s</string>
<string name="session_ipv6string">%1$s - %3$s, %2$s</string>
<string name="state_connecting">Connecting</string>
@@ -257,7 +255,7 @@
<string name="state_auth_failed">Authentication failed</string>
<string name="state_nonetwork">Waiting for usable network</string>
<string name="menu_settings">Settings</string>
- <string name="title_activity_dashboard">Bitmask Dashboard</string>
+ <string name="title_activity_dashboard">Bitmask</string>
<string name="provider_label">Provider:</string>
<string name="provider_label_none">No provider configured</string>
<string name="eip_settings_button_description">Access EIP connection settings</string>
@@ -268,13 +266,12 @@
<string name="future_authed_secured_status">Connection will be secure using your own certificate.</string>
<string name="authed_secured_status">Connection secure using your own certificate.</string>
<string name="eip_service_label">Encrypted Internet</string>
- <string name="title_activity_configuration_wizard">Configure Bitmask</string>
- <string name="provider_list_fragment_tag">Provider list fragment</string>
+ <string name="title_activity_configuration_wizard">Select a service provider</string>
<string name="top_padding">Top padding</string>
- <string name="new_provider_button">Select new Provider</string>
- <string name="introduce_new_provider">Introduce new provider</string>
+ <string name="new_provider_button">Add new Provider</string>
+ <string name="introduce_new_provider">Add a new service provider</string>
<string name="save">Save</string>
- <string name="new_provider_uri">New provider\'s main URL</string>
+ <string name="new_provider_uri">Domain name</string>
<string name="valid_url_entered">It seems your URL is well formed</string>
<string name="not_valid_url_entered">It seems your URL is not well formed</string>
<string name="provider_details_fragment_title">Provider details</string>
@@ -286,8 +283,8 @@
<string name="username_ask">Please enter your username</string>
<string name="password_hint">password</string>
<string name="user_message">User message</string>
- <string name="error_srp_math_error_user_message">Try again: server math error.</string>
- <string name="error_bad_user_password_user_message">Not valid username and/or password.</string>
+ <string name="error_srp_math_error_user_message">Try again: server math error.</string>
+ <string name="error_bad_user_password_user_message">Incorrect username or password.</string>
<string name="error_not_valid_password_user_message">It should have at least 8 characters.</string>
<string name="error_client_http_user_message">Try again: Client HTTP error</string>
<string name="error_io_exception_user_message">Try again: I/O error</string>
@@ -295,7 +292,7 @@
<string name="error_no_such_algorithm_exception_user_message">Update the app</string>
<string name="login_button">Log In</string>
<string name="logout_button">Log Out</string>
- <string name="danger_checkbox">Trust completely</string>
+ <string name="danger_checkbox">Skip security check</string>
<string name="setup_error_title">Configuration Error</string>
<string name="setup_error_configure_button">Configure</string>
<string name="setup_error_close_button">Exit</string>
@@ -314,10 +311,10 @@
<string name="certificate_error">This is not a trusted Bitmask provider.</string>
<string name="configuring_provider">Configuring provider</string>
<string name="authenticating_title">Authenticating</string>
- <string name="authenticating_message">Authenticating with entered login and password.</string>
+ <string name="authenticating_message">Logging in</string>
<string name="logout_title">Log out</string>
<string name="logout_message">Logging out from this session.</string>
- <string name="not_valid_password_message">Your password is not well-formed: it should have at least 8 characters.</string>
+ <string name="not_valid_password_message">Invalid password: must be at least 8 characters.</string>
<string name="succesful_authentication_message">Authentication succeeded.</string>
<string name="authentication_failed_message">Authentication failed.</string>
<string name="successful_log_out_message">Logged out.</string>
diff --git a/res/values/untranslatable.xml b/res/values/untranslatable.xml
index fe620aa8..8c15a213 100644
--- a/res/values/untranslatable.xml
+++ b/res/values/untranslatable.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
-
+ <string name="app" translatable="false">Bitmask</string>
+ <string name="app_name" translatable="false">Bitmask</string>
+
<string name="copyright_leapgui" translatable="false">Copyright 2012\nLEAP Encryption Access Project &lt;info@leap.se></string>
<string name="opevpn_copyright" translatable="false">Copyright © 2002–2010 OpenVPN Technologies, Inc. &lt;sales@openvpn.net>\n
diff --git a/src/se/leap/bitmaskclient/ConfigHelper.java b/src/se/leap/bitmaskclient/ConfigHelper.java
index a29ff301..dd7049a7 100644
--- a/src/se/leap/bitmaskclient/ConfigHelper.java
+++ b/src/se/leap/bitmaskclient/ConfigHelper.java
@@ -58,7 +58,8 @@ public class ConfigHelper {
private static boolean checkSharedPrefs() {
try {
- shared_preferences = Dashboard.getAppContext().getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE);
+ if(shared_preferences == null)
+ shared_preferences = Dashboard.getAppContext().getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE);
} catch (Exception e) {
return false;
}
diff --git a/src/se/leap/bitmaskclient/ConfigurationWizard.java b/src/se/leap/bitmaskclient/ConfigurationWizard.java
index 267fcd42..694dbf7c 100644
--- a/src/se/leap/bitmaskclient/ConfigurationWizard.java
+++ b/src/se/leap/bitmaskclient/ConfigurationWizard.java
@@ -25,7 +25,6 @@ import org.json.JSONObject;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver;
import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
-
import android.app.Activity;
import android.app.DialogFragment;
import android.app.Fragment;
@@ -38,6 +37,7 @@ import android.content.IntentFilter;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Handler;
+import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
@@ -68,6 +68,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
private ProviderListFragment provider_list_fragment;
private Intent mConfigState = new Intent();
+ final public static String TAG = "se.leap.bitmaskclient.ConfigurationWizard";
final public static String TYPE_OF_CERTIFICATE = "type_of_certificate";
final public static String ANON_CERTIFICATE = "anon_certificate";
final public static String AUTHED_CERTIFICATE = "authed_certificate";
@@ -185,9 +186,10 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
@Override
public void onItemSelected(String id) {
//TODO Code 2 pane view
+ // resetOldConnection();
ProviderItem selected_provider = getProvider(id);
int provider_index = getProviderIndex(id);
- startProgressBar(provider_index);
+ startProgressBar(provider_index);
provider_list_fragment.hideAllBut(provider_index);
setUpProvider(selected_provider.providerMainUrl(), true);
}
@@ -397,7 +399,6 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
*/
public void setUpProvider(String provider_main_url, boolean danger_on) {
Intent provider_API_command = new Intent(this, ProviderAPI.class);
-
Bundle parameters = new Bundle();
parameters.putString(Provider.MAIN_URL, provider_main_url);
parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
@@ -405,10 +406,10 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
-
+
startService(provider_API_command);
}
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu);
@@ -445,7 +446,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
fragment_transaction.replace(R.id.configuration_wizard_layout, newFragment, AboutFragment.TAG).commit();
}
}
-
+
public void showAllProviders() {
provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG);
if(provider_list_fragment != null)
diff --git a/src/se/leap/bitmaskclient/Dashboard.java b/src/se/leap/bitmaskclient/Dashboard.java
index 2f4c78a0..01a9c20a 100644
--- a/src/se/leap/bitmaskclient/Dashboard.java
+++ b/src/se/leap/bitmaskclient/Dashboard.java
@@ -35,6 +35,7 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -54,12 +55,16 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
protected static final int CONFIGURE_LEAP = 0;
protected static final int SWITCH_PROVIDER = 1;
+
private static final String TAG_EIP_FRAGMENT = "EIP_DASHBOARD_FRAGMENT";
final public static String SHARED_PREFERENCES = "LEAPPreferences";
final public static String ACTION_QUIT = "quit";
public static final String REQUEST_CODE = "request_code";
+
+
+
private ProgressBar mProgressBar;
private TextView eipStatus;
private static Context app;
@@ -79,14 +84,16 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
app = this;
PRNGFixes.apply();
- //mProgressBar = (ProgressBar) findViewById(R.id.progressbar_dashboard);
+ // mProgressBar = (ProgressBar) findViewById(R.id.progressbar_dashboard);
+ // mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);
+ // eipStatus = (TextView) findViewById(R.id.eipStatus);
mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);
ConfigHelper.setSharedPreferences(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE));
preferences = ConfigHelper.shared_preferences;
-
+
authed_eip = ConfigHelper.getBoolFromSharedPref(EIP.AUTHED_EIP);
if (ConfigHelper.getStringFromSharedPref(Provider.KEY).isEmpty())
startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP);
@@ -101,11 +108,14 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
- if ( requestCode == CONFIGURE_LEAP ) {
- if ( resultCode == RESULT_OK){
+ if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) {
+ // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) {
+ if ( resultCode == RESULT_OK ){
+ ConfigHelper.saveSharedPref(EIP.PARSED_SERIAL, 0);
ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip);
startService( new Intent(EIP.ACTION_UPDATE_EIP_SERVICE) );
buildDashboard();
+
if(data != null && data.hasExtra(LogInDialog.VERB)) {
View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
logInDialog(view, Bundle.EMPTY);
@@ -116,7 +126,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
configErrorDialog();
}
}
-
+
/**
* Dialog shown when encountering a configuration error. Such errors require
* reconfiguring LEAP or aborting the application.
@@ -209,6 +219,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
startActivity(intent);
return true;
case R.id.switch_provider:
+ if (Provider.getInstance().hasEIP()){
+ if (ConfigHelper.getBoolFromSharedPref(EIP.AUTHED_EIP)){
+ logOut();
+ }
+ eipStop();
+ }
ConfigHelper.removeFromSharedPref(Provider.KEY);
startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER);
return true;
@@ -281,12 +297,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
- //if(mProgressDialog != null) mProgressDialog.dismiss();
- //mProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.logout_title), getResources().getString(R.string.logout_message), true);
+ if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);
mProgressBar.setVisibility(ProgressBar.VISIBLE);
+ if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus);
eipStatus.setText("Starting to logout");
- //mProgressBar.setMax(1);
startService(provider_API_command);
+ //mProgressBar.setMax(1);
+
}
/**
@@ -436,4 +453,18 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver);
startService(eip_intent);
}
+
+ /**
+ * Send a command to EIP
+ *
+ */
+ private void eipStop(){
+ // TODO validate "action"...how do we get the list of intent-filters for a class via Android API?
+ Intent eip_intent = new Intent(this, EIP.class);
+ eip_intent.setAction(EIP.ACTION_STOP_EIP);
+ // eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver);
+ startService(eip_intent);
+
+ }
+
}
diff --git a/src/se/leap/bitmaskclient/EIP.java b/src/se/leap/bitmaskclient/EIP.java
index f9384ff6..edd73e83 100644
--- a/src/se/leap/bitmaskclient/EIP.java
+++ b/src/se/leap/bitmaskclient/EIP.java
@@ -214,8 +214,7 @@ public final class EIP extends IntentService {
* Intent to {@link se.leap.openvpn.LaunchVPN}
*/
private void startEIP() {
- if (activeGateway==null)
- activeGateway = selectGateway();
+ activeGateway = selectGateway();
Intent intent = new Intent(this,LaunchVPN.class);
intent.setAction(Intent.ACTION_MAIN);
@@ -252,10 +251,19 @@ public final class EIP extends IntentService {
private void updateEIPService() {
try {
eipDefinition = ConfigHelper.getJsonFromSharedPref(EIP.KEY);
+ parsedEipSerial = ConfigHelper.getIntFromSharedPref(PARSED_SERIAL);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
+ if(parsedEipSerial == 0) {
+ // Delete all vpn profiles
+ ProfileManager vpl = ProfileManager.getInstance(context);
+ Collection<VpnProfile> profiles = vpl.getProfiles();
+ for (VpnProfile profile : profiles){
+ vpl.removeProfile(context, profile);
+ }
+ }
if (eipDefinition.optInt("serial") > parsedEipSerial)
updateGateways();
}
@@ -431,6 +439,8 @@ public final class EIP extends IntentService {
String ports = "ports";
String protos = "protocols";
String capabilities = "capabilities";
+ String location_key = "location";
+ String locations = "locations";
Vector<String> arg = new Vector<String>();
Vector<Vector<String>> args = new Vector<Vector<String>>();
@@ -447,7 +457,6 @@ public final class EIP extends IntentService {
arg.add(word);
value.add( (Vector<String>) arg.clone() );
options.put(key, (Vector<Vector<String>>) value.clone());
-
value.clear();
arg.clear();
}
@@ -457,7 +466,7 @@ public final class EIP extends IntentService {
}
try {
- arg.add("remote");
+ arg.add(remote);
arg.add(mGateway.getString(remote));
} catch (JSONException e) {
// TODO Auto-generated catch block
@@ -467,7 +476,25 @@ public final class EIP extends IntentService {
options.put("remote", (Vector<Vector<String>>) args.clone() );
arg.clear();
args.clear();
+
+
+ try {
+
+ arg.add(location_key);
+ String locationText = "";
+ locationText = eipDefinition.getJSONObject(locations).getJSONObject(mGateway.getString(location_key)).getString("name");
+ arg.add(locationText);
+
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ args.add((Vector<String>) arg.clone());
+ options.put("location", (Vector<Vector<String>>) args.clone() );
+
+ arg.clear();
+ args.clear();
JSONArray protocolsJSON = null;
arg.add("proto");
try {
diff --git a/src/se/leap/bitmaskclient/EipServiceFragment.java b/src/se/leap/bitmaskclient/EipServiceFragment.java
index 4d778b1a..b409394b 100644
--- a/src/se/leap/bitmaskclient/EipServiceFragment.java
+++ b/src/se/leap/bitmaskclient/EipServiceFragment.java
@@ -12,6 +12,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -38,6 +39,9 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli
private EIPReceiver mEIPReceiver;
+
+ public static String TAG = "se.leap.bitmask.EipServiceFragment";
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -57,6 +61,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli
eipStatus.setOnClickListener(this);
eipSwitch = (Switch) eipFragment.findViewById(R.id.eipSwitch);
+
+
eipSwitch.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -66,6 +72,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli
});
eipSwitch.setOnCheckedChangeListener(this);
+
return eipFragment;
}
@@ -152,6 +159,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli
eipAutoSwitched = true;
}
+
+
/**
* Send a command to EIP
*
@@ -186,13 +195,15 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli
statusMessage = getString(R.string.eip_state_connected); getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE);
mEipStartPending = false;
- } else if ( (state.equals("NOPROCESS") && !mEipStartPending ) || state.equals("EXITING")) {
+ } else if ( (state.equals("NOPROCESS") && !mEipStartPending ) || state.equals("EXITING") || state.equals("FATAL")) {
statusMessage = getString(R.string.eip_state_not_connected);
getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE);
mEipStartPending = false;
switchState = false;
} else if (state.equals("NOPROCESS")){
statusMessage = logmessage;
+ } else if (state.equals("ASSIGN_IP")){ //don't show assigning message in eipStatus
+ statusMessage = (String) eipStatus.getText();
}
else {
statusMessage = prefix + " " + logmessage;
@@ -207,6 +218,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli
});
}
+
/**
* Inner class for handling messages related to EIP status and control requests
*
diff --git a/src/se/leap/bitmaskclient/LogInDialog.java b/src/se/leap/bitmaskclient/LogInDialog.java
index 3651e9ba..81a3f764 100644
--- a/src/se/leap/bitmaskclient/LogInDialog.java
+++ b/src/se/leap/bitmaskclient/LogInDialog.java
@@ -86,8 +86,8 @@ public class LogInDialog extends DialogFragment {
builder.setView(log_in_dialog_view)
.setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- String username = username_field.getText().toString().trim();
- String password = password_field.getText().toString().trim();
+ String username = username_field.getText().toString();
+ String password = password_field.getText().toString();
dialog.dismiss();
interface_with_Dashboard.authenticate(username, password);
}
diff --git a/src/se/leap/bitmaskclient/NewProviderDialog.java b/src/se/leap/bitmaskclient/NewProviderDialog.java
index 16d46c67..98686bd2 100644
--- a/src/se/leap/bitmaskclient/NewProviderDialog.java
+++ b/src/se/leap/bitmaskclient/NewProviderDialog.java
@@ -22,6 +22,7 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
+import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -38,7 +39,7 @@ import android.widget.Toast;
public class NewProviderDialog extends DialogFragment {
final public static String TAG = "newProviderDialog";
-
+
public interface NewProviderDialogInterface {
public void showAndSelectProvider(String url_provider, boolean danger_on);
}
@@ -71,13 +72,15 @@ public class NewProviderDialog extends DialogFragment {
View new_provider_dialog_view = inflater.inflate(R.layout.new_provider_dialog, null);
final EditText url_input_field = (EditText)new_provider_dialog_view.findViewById(R.id.new_provider_url);
final CheckBox danger_checkbox = (CheckBox)new_provider_dialog_view.findViewById(R.id.danger_checkbox);
-
builder.setView(new_provider_dialog_view)
.setMessage(R.string.introduce_new_provider)
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String entered_url = url_input_field.getText().toString().trim();
if(!entered_url.startsWith("https://")) {
+ if (entered_url.startsWith("http://")){
+ entered_url = entered_url.substring("http://".length());
+ }
entered_url = "https://".concat(entered_url);
}
boolean danger_on = danger_checkbox.isChecked();
@@ -86,7 +89,8 @@ public class NewProviderDialog extends DialogFragment {
Toast.makeText(getActivity().getApplicationContext(), R.string.valid_url_entered, Toast.LENGTH_LONG).show();
} else {
url_input_field.setText("");
- Toast.makeText(getActivity().getApplicationContext(), R.string.not_valid_url_entered, Toast.LENGTH_LONG).show();
+ danger_checkbox.setChecked(false);
+ Toast.makeText(getActivity().getApplicationContext(), R.string.not_valid_url_entered, Toast.LENGTH_LONG).show();;
}
}
})
@@ -105,6 +109,7 @@ public class NewProviderDialog extends DialogFragment {
* @return true if it's not empty nor contains only the protocol.
*/
boolean validURL(String entered_url) {
- return !entered_url.isEmpty() && entered_url.matches("http[s]?://.+") && !entered_url.replaceFirst("http[s]?://", "").isEmpty();
+ //return !entered_url.isEmpty() && entered_url.matches("http[s]?://.+") && !entered_url.replaceFirst("http[s]?://", "").isEmpty();
+ return android.util.Patterns.WEB_URL.matcher(entered_url).matches();
}
}
diff --git a/src/se/leap/bitmaskclient/Provider.java b/src/se/leap/bitmaskclient/Provider.java
index 3c029702..598999fd 100644
--- a/src/se/leap/bitmaskclient/Provider.java
+++ b/src/se/leap/bitmaskclient/Provider.java
@@ -166,6 +166,8 @@ public final class Provider implements Serializable {
// Walk the EIP types array looking for matches in provider's service definitions
if ( Arrays.asList(API_EIP_TYPES).contains( services.getString(i) ) )
return true;
+ } catch (NullPointerException e){
+ e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
diff --git a/src/se/leap/bitmaskclient/ProviderAPI.java b/src/se/leap/bitmaskclient/ProviderAPI.java
index 83afd95c..cc94edff 100644
--- a/src/se/leap/bitmaskclient/ProviderAPI.java
+++ b/src/se/leap/bitmaskclient/ProviderAPI.java
@@ -452,7 +452,7 @@ public class ProviderAPI extends IntentService {
private boolean validCertificate(String cert_string) {
boolean result = false;
- if(!cert_string.isEmpty()) {
+ if(!ConfigHelper.checkErroneousDownload(cert_string)) {
X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string);
try {
Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
@@ -723,6 +723,9 @@ public class ProviderAPI extends IntentService {
URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE);
boolean danger_on = ConfigHelper.getBoolFromSharedPref(ProviderItem.DANGER_ON);
+//<<<<<<< HEAD
+// String cert_string = downloadWithProviderCA(new_cert_string_url, true);
+//=======
String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), danger_on);
if(!cert_string.isEmpty()) {
if(ConfigHelper.checkErroneousDownload(cert_string)) {
diff --git a/src/se/leap/bitmaskclient/ProviderListFragment.java b/src/se/leap/bitmaskclient/ProviderListFragment.java
index 862177a2..f074e665 100644
--- a/src/se/leap/bitmaskclient/ProviderListFragment.java
+++ b/src/se/leap/bitmaskclient/ProviderListFragment.java
@@ -156,11 +156,14 @@ public class ProviderListFragment extends ListFragment {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(ProviderListContent.ITEMS.get(position).name());
+//<<<<<<< HEAD
+//=======
for(int item_position = 0; item_position < listView.getCount(); item_position++) {
if(item_position != position)
content_adapter.hide(item_position);
}
+//>>>>>>> feature/token-based-auth
}
@Override
@@ -203,11 +206,23 @@ public class ProviderListFragment extends ListFragment {
}
public void hideAllBut(int position) {
- for(int i = 0; i < content_adapter.getCount(); i++)
+//<<<<<<< HEAD
+ int real_count = content_adapter.getCount();
+ for(int i = 0; i < real_count;)
+ if(i != position) {
+ content_adapter.hide(i);
+ position--;
+ real_count--;
+ } else {
+ i++;
+ }
+//=======
+/* for(int i = 0; i < content_adapter.getCount(); i++)
if(i != position)
content_adapter.hide(i);
else
content_adapter.unHide(i);
+*///>>>>>>> feature/token-based-auth
}
public void unhideAll() {
diff --git a/src/se/leap/openvpn/ConfigParser.java b/src/se/leap/openvpn/ConfigParser.java
index 3d369fa6..36585d29 100644
--- a/src/se/leap/openvpn/ConfigParser.java
+++ b/src/se/leap/openvpn/ConfigParser.java
@@ -355,6 +355,12 @@ public class ConfigParser {
np.mServerName = remote.get(1);
}
}
+
+ // Parse remote config
+ Vector<String> location = getOption("location",1,2);
+ if(location != null && location.size() == 2){
+ np.mLocation = location.get(1).replace("__", ", ");
+ }
Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2);
if(dhcpoptions!=null) {
diff --git a/src/se/leap/openvpn/OpenVPN.java b/src/se/leap/openvpn/OpenVPN.java
index d7d17b4f..8acdc423 100644
--- a/src/se/leap/openvpn/OpenVPN.java
+++ b/src/se/leap/openvpn/OpenVPN.java
@@ -25,6 +25,7 @@ public class OpenVPN {
private static String mLaststate;
private static int mLastStateresid=R.string.state_noprocess;
+ public static String TAG="se.leap.openvpn.OpenVPN";
static {
logbuffer = new LinkedList<LogItem>();
@@ -166,6 +167,8 @@ public class OpenVPN {
return R.string.state_resolve;
else if (state.equals("TCP_CONNECT"))
return R.string.state_tcp_connect;
+ else if (state.equals("FATAL"))
+ return R.string.eip_state_not_connected;
else
return R.string.unknown_state;
@@ -197,7 +200,7 @@ public class OpenVPN {
}
- public static void updateStateString (String state, String msg) {
+ public static void updateStateString (String state, String msg) {
int rid = getLocalizedState(state);
updateStateString(state, msg,rid);
}
diff --git a/src/se/leap/openvpn/OpenVPNThread.java b/src/se/leap/openvpn/OpenVPNThread.java
index 0c383ab0..ffd21732 100644
--- a/src/se/leap/openvpn/OpenVPNThread.java
+++ b/src/se/leap/openvpn/OpenVPNThread.java
@@ -56,7 +56,7 @@ public class OpenVPNThread implements Runnable {
if( exitvalue != 0)
OpenVPN.logError("Process exited with exit value " + exitvalue);
- OpenVPN.updateStateString("NOPROCESS","No process running.", R.string.state_noprocess);
+// OpenVPN.updateStateString("NOPROCESS","No process running.", R.string.state_noprocess); fixes bug #4565
if(mDumpPath!=null) {
try {
BufferedWriter logout = new BufferedWriter(new FileWriter(mDumpPath + ".log"));
diff --git a/src/se/leap/openvpn/OpenVpnManagementThread.java b/src/se/leap/openvpn/OpenVpnManagementThread.java
index 78ce5a2b..27a3db65 100644
--- a/src/se/leap/openvpn/OpenVpnManagementThread.java
+++ b/src/se/leap/openvpn/OpenVpnManagementThread.java
@@ -19,7 +19,6 @@ import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import se.leap.bitmaskclient.R;
-
import android.content.SharedPreferences;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
@@ -177,11 +176,12 @@ public class OpenVpnManagementThread implements Runnable {
private void processCommand(String command) {
+ Log.d(TAG, "processCommand: " + command);
+
if (command.startsWith(">") && command.contains(":")) {
String[] parts = command.split(":",2);
String cmd = parts[0].substring(1);
String argument = parts[1];
-
if(cmd.equals("INFO")) {
// Ignore greeting from mgmt
//logStatusMessage(command);
@@ -195,6 +195,8 @@ public class OpenVpnManagementThread implements Runnable {
processByteCount(argument);
} else if (cmd.equals("STATE")) {
processState(argument);
+ } else if (cmd.equals("FATAL")){
+ processState(","+cmd+","); //handles FATAL as state
} else if (cmd.equals("PROXY")) {
processProxyCMD(argument);
} else if (cmd.equals("LOG")) {
@@ -209,8 +211,11 @@ public class OpenVpnManagementThread implements Runnable {
OpenVPN.logMessage(0, "MGMT:", "Got unrecognized command" + command);
Log.i(TAG, "Got unrecognized command" + command);
}
- } else if (command.startsWith("SUCCESS:")) {
- // ignore
+ } else if (command.startsWith("SUCCESS:")) { //Fixes bug LEAP #4565
+ if (command.equals("SUCCESS: signal SIGINT thrown")){
+ Log.d(TAG, "SUCCESS: signal SIGINT thrown");
+ processState(",EXITING,SIGINT,,");
+ }
} else {
Log.i(TAG, "Got unrecognized line from managment" + command);
OpenVPN.logMessage(0, "MGMT:", "Got unrecognized line from management:" + command);
@@ -272,11 +277,17 @@ public class OpenVpnManagementThread implements Runnable {
private void processState(String argument) {
String[] args = argument.split(",",3);
String currentstate = args[1];
- Log.d("OpenVPN log", argument);
- if(args[2].equals(",,"))
+ if(args[2].equals(",,")){
OpenVPN.updateStateString(currentstate,"");
- else
+ }
+ else if (args[2].endsWith(",,")){ //fixes LEAP Bug #4546
+ args[2] = (String) args[2].subSequence(0, args[2].length()-2);
+ Log.d(TAG, "processState() STATE: "+ currentstate + " msg: " + args[2]);
+ OpenVPN.updateStateString(currentstate,args[2]);
+ }
+ else{
OpenVPN.updateStateString(currentstate,args[2]);
+ }
}
private static int repeated_byte_counts = 0;
@@ -333,8 +344,7 @@ public class OpenVpnManagementThread implements Runnable {
mOpenVPNService.setDomain(extra);
} else if (needed.equals("ROUTE")) {
String[] routeparts = extra.split(" ");
- if(!mOpenVPNService.isRunning()) // We cannot add routes to an existing openvpn session
- mOpenVPNService.addRoute(routeparts[0], routeparts[1]);
+ mOpenVPNService.addRoute(routeparts[0], routeparts[1]);
} else if (needed.equals("ROUTE6")) {
mOpenVPNService.addRoutev6(extra);
} else if (needed.equals("IFCONFIG")) {
diff --git a/src/se/leap/openvpn/OpenVpnService.java b/src/se/leap/openvpn/OpenVpnService.java
index 620de204..b5c9c798 100644
--- a/src/se/leap/openvpn/OpenVpnService.java
+++ b/src/se/leap/openvpn/OpenVpnService.java
@@ -106,7 +106,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
String ns = Context.NOTIFICATION_SERVICE;
mNotificationManager = (NotificationManager) getSystemService(ns);
int icon;
- if (state.equals("NOPROCESS") || state.equals("AUTH_FAILED") || state.equals("NONETWORK")){
+ if (state.equals("NOPROCESS") || state.equals("AUTH_FAILED") || state.equals("NONETWORK") || state.equals("EXITING")){
icon = R.drawable.ic_vpn_disconnected;
}else{
icon = R.drawable.ic_stat_vpn;
@@ -114,7 +114,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
android.app.Notification.Builder nbuilder = new Notification.Builder(this);
- nbuilder.setContentTitle(getString(R.string.notifcation_title,mProfile.mName));
+ nbuilder.setContentTitle(getString(R.string.notifcation_title,mProfile.mLocation));
nbuilder.setContentText(msg);
nbuilder.setOnlyAlertOnce(true);
nbuilder.setOngoing(persistant);
@@ -350,12 +350,13 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
bconfig[4] = getString(R.string.routes_info, joinString(mRoutes));
bconfig[5] = getString(R.string.routes_info6, joinString(mRoutesv6));
- String session = mProfile.mName;
+ String session = mProfile.mLocation;
+ /* we don't want the IP address in the notification bar
if(mLocalIP!=null && mLocalIPv6!=null)
session = getString(R.string.session_ipv6string,session, mLocalIP, mLocalIPv6);
else if (mLocalIP !=null)
session= getString(R.string.session_ipv4string, session, mLocalIP);
-
+ */
builder.setSession(session);
@@ -478,9 +479,11 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
// CONNECTED
String ticker = getString(resid);
boolean persist = false;
- if (("NOPROCESS".equals(state) ) || ("EXIT").equals(state)){
+ if (("NOPROCESS".equals(state) ) || ("EXITING").equals(state)){
showNotification(state, getString(R.string.eip_state_not_connected), ticker, false, 0, persist);
}
+ else if (state.equals("GET_CONFIG") || state.equals("ASSIGN_IP")){ //don't show them in the notification message
+ }
else{
persist = true;
showNotification(state, getString(resid) +" " + logmessage,ticker,false,0,persist);
diff --git a/src/se/leap/openvpn/VpnProfile.java b/src/se/leap/openvpn/VpnProfile.java
index 41cf574b..99e1c676 100644
--- a/src/se/leap/openvpn/VpnProfile.java
+++ b/src/se/leap/openvpn/VpnProfile.java
@@ -68,6 +68,7 @@ public class VpnProfile implements Serializable{
private UUID mUuid;
public int mAuthenticationType = TYPE_CERTIFICATES ;
public String mName;
+ public String mLocation;
public String mAlias;
public String mClientCertFilename;
public String mTLSAuthDirection="";
diff --git a/tests/.classpath b/tests/.classpath
new file mode 100644
index 00000000..c50720af
--- /dev/null
+++ b/tests/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/bitmask_for_android"/>
+ <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/tests/.project b/tests/.project
new file mode 100644
index 00000000..2b5ac5d8
--- /dev/null
+++ b/tests/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>bitmask_for_androidTest</name>
+ <comment></comment>
+ <projects>
+ <project>leap_android</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100644
index 00000000..ec055dc3
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="se.leap.bitmaskclient.test"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+
+ <uses-sdk android:minSdkVersion="14" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="se.leap.bitmaskclient" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+</manifest>
diff --git a/tests/ant.properties b/tests/ant.properties
new file mode 100644
index 00000000..16244024
--- /dev/null
+++ b/tests/ant.properties
@@ -0,0 +1,18 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
+tested.project.dir=..
diff --git a/tests/build.xml b/tests/build.xml
new file mode 100644
index 00000000..7da0cf51
--- /dev/null
+++ b/tests/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Bitmask_for_Android_tests" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/tests/compile.sh b/tests/compile.sh
new file mode 100755
index 00000000..a6d3534a
--- /dev/null
+++ b/tests/compile.sh
@@ -0,0 +1 @@
+android update test-project -m .. -p .
diff --git a/tests/libs/robotium-solo-4.3.1.jar b/tests/libs/robotium-solo-4.3.1.jar
new file mode 100644
index 00000000..56af9985
--- /dev/null
+++ b/tests/libs/robotium-solo-4.3.1.jar
Binary files differ
diff --git a/tests/lint.xml b/tests/lint.xml
new file mode 100644
index 00000000..ee0eead5
--- /dev/null
+++ b/tests/lint.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint> \ No newline at end of file
diff --git a/tests/proguard-project.txt b/tests/proguard-project.txt
new file mode 100644
index 00000000..f2fe1559
--- /dev/null
+++ b/tests/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/tests/project.properties b/tests/project.properties
new file mode 100644
index 00000000..a3ee5ab6
--- /dev/null
+++ b/tests/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-17
diff --git a/tests/run.sh b/tests/run.sh
new file mode 100755
index 00000000..7705cd8f
--- /dev/null
+++ b/tests/run.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+ant test
diff --git a/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java b/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java
new file mode 100644
index 00000000..34d2ae26
--- /dev/null
+++ b/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java
@@ -0,0 +1,65 @@
+package se.leap.bitmaskclient.test;
+
+import java.io.IOException;
+
+import se.leap.bitmaskclient.AboutFragment;
+import se.leap.bitmaskclient.ConfigurationWizard;
+import se.leap.bitmaskclient.ProviderDetailFragment;
+import se.leap.bitmaskclient.R;
+import android.test.ActivityInstrumentationTestCase2;
+import android.widget.ListView;
+
+import com.jayway.android.robotium.solo.Solo;
+
+public class testConfigurationWizard extends ActivityInstrumentationTestCase2<ConfigurationWizard> {
+
+ private Solo solo;
+ private static int added_providers;
+
+ public testConfigurationWizard() {
+ super(ConfigurationWizard.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ solo = new Solo(getInstrumentation(), getActivity());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ solo.finishOpenedActivities();
+ }
+
+ public void testListProviders() throws IOException {
+ assertEquals(solo.getCurrentViews(ListView.class).size(), 1);
+
+ int number_of_available_providers = solo.getCurrentViews(ListView.class).get(0).getCount();
+
+ assertEquals("Number of available providers differ", solo.getCurrentActivity().getAssets().list("urls").length + added_providers, number_of_available_providers);
+ }
+
+ public void testSelectProvider() {
+ solo.clickOnText("bitmask");
+ assertTrue("Provider details dialog did not appear", solo.waitForFragmentByTag(ProviderDetailFragment.TAG, 60*1000));
+ }
+
+ public void testAddNewProvider() {
+ solo.clickOnActionBarItem(R.id.new_provider);
+ solo.enterText(0, "dev.bitmask.net");
+ solo.clickOnCheckBox(0);
+ solo.clickOnText(solo.getString(R.string.save));
+ added_providers = added_providers+1;
+ assertTrue("Provider details dialog did not appear", solo.waitForFragmentByTag(ProviderDetailFragment.TAG, 60*1000));
+ solo.goBack();
+ }
+
+ public void testShowAbout() {
+ solo.clickOnMenuItem(solo.getString(R.string.about));
+ assertTrue("Provider details dialog did not appear", solo.waitForFragmentByTag(AboutFragment.TAG));
+ }
+
+ public void testShowSettings() {
+ //TODO We still don't have the settings button
+ }
+}
diff --git a/tests/src/se/leap/bitmaskclient/test/testDashboard.java b/tests/src/se/leap/bitmaskclient/test/testDashboard.java
new file mode 100644
index 00000000..31039797
--- /dev/null
+++ b/tests/src/se/leap/bitmaskclient/test/testDashboard.java
@@ -0,0 +1,140 @@
+package se.leap.bitmaskclient.test;
+
+import se.leap.bitmaskclient.ConfigurationWizard;
+import se.leap.bitmaskclient.Dashboard;
+import se.leap.bitmaskclient.R;
+import se.leap.openvpn.MainActivity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import com.jayway.android.robotium.solo.Solo;
+
+public class testDashboard extends ActivityInstrumentationTestCase2<Dashboard> {
+
+ private Solo solo;
+
+ public testDashboard() {
+ super(Dashboard.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ solo = new Solo(getInstrumentation(), getActivity());
+ setAirplaneMode(false);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ solo.finishOpenedActivities();
+ }
+
+ /**
+ * This test will fail if Android does not trust VPN connection.
+ * I cannot automate that dialog.
+ */
+ public void testOnOffOpenVpn() {
+ solo.clickOnView(solo.getView(R.id.eipSwitch));
+ if(!solo.waitForText("Initiating connection"))
+ fail();
+ if(!solo.waitForText("Authenticating"))
+ fail();
+ if(!solo.waitForText("Connection Secure", 1, 30*1000))
+ fail();
+
+ solo.clickOnView(solo.getView(R.id.eipSwitch));
+ if(!solo.waitForText("Not running! Connection not secure"))
+ fail();
+ /* setAirplaneMode isn't working right now.
+ setAirplaneMode(true);
+ if(!solo.waitForLogMessage("Service state changed"))
+ fail();
+
+ solo.clickOnView(solo.getView(R.id.eipSwitch));
+ if(!solo.waitForText("Initiating connection"))
+ fail();
+ if(!solo.waitForText("Waiting for usable network"))
+ fail();
+ */
+ }
+
+ public void testLogInAndOut() {
+ long miliseconds_to_log_in = 40 * 1000;
+ solo.clickOnActionBarItem(R.id.login_button);
+ solo.enterText(0, "parmegvtest1");
+ solo.enterText(1, " S_Zw3'-");
+ solo.clickOnText("Log In");
+ solo.waitForDialogToClose();
+ solo.waitForDialogToClose(miliseconds_to_log_in);
+ if(!solo.waitForText("Your own cert has been correctly downloaded."))
+ fail();
+
+ solo.clickOnActionBarItem(R.string.logout_button);
+ if(!solo.waitForDialogToClose())
+ fail();
+ }
+
+ public void testShowSettings() {
+ solo.clickOnActionBarItem(R.id.menu_settings);
+ }
+
+ public void testShowAbout() {
+ solo.clickOnMenuItem("About");
+ solo.waitForText(getActivity().getString(R.string.repository_url_text));
+ solo.goBack();
+
+ solo.clickOnMenuItem("About");
+ solo.waitForText(getActivity().getString(R.string.repository_url_text));
+ solo.goBack();
+ }
+
+ public void testSwitchProvider() {
+ solo.clickOnMenuItem("Switch provider");
+ solo.waitForActivity(ConfigurationWizard.class);
+ solo.goBack();
+
+ solo.clickOnMenuItem("Switch provider");
+ solo.waitForActivity(ConfigurationWizard.class);
+ solo.goBack();
+ }
+
+ public void testIcsOpenVpnInterface() {
+ solo.clickOnMenuItem("ICS OpenVPN Interface");
+ solo.waitForActivity(MainActivity.class);
+
+ solo.goBack();
+
+ solo.clickOnMenuItem("ICS OpenVPN Interface");
+ solo.waitForActivity(MainActivity.class);
+ }
+
+ private void setAirplaneMode(boolean airplane_mode) {
+ Context context = solo.getCurrentActivity().getApplicationContext();
+ boolean isEnabled = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ Log.d("AirplaneMode", "Service state: " + isEnabled);
+ Settings.System.putInt(context.getContentResolver(),Settings.System.AIRPLANE_MODE_ON, airplane_mode ? 1 : 0);
+
+ // Post an intent to reload
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", airplane_mode);
+ Log.d("AirplaneMode", "New Service state: " + !isEnabled);
+ solo.getCurrentActivity().sendBroadcast(intent);
+
+ IntentFilter intentFilter = new IntentFilter("android.intent.action.SERVICE_STATE");
+
+ BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ boolean isEnabled = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ Log.d("AirplaneMode", "Service state changed: " + isEnabled);
+ }
+ };
+
+ context.registerReceiver(receiver, intentFilter);
+ }
+}
diff --git a/tests/src/se/leap/bitmaskclient/test/testLeapSRPSession.java b/tests/src/se/leap/bitmaskclient/test/testLeapSRPSession.java
new file mode 100644
index 00000000..88d70da4
--- /dev/null
+++ b/tests/src/se/leap/bitmaskclient/test/testLeapSRPSession.java
@@ -0,0 +1,636 @@
+package se.leap.bitmaskclient.test;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+import org.jboss.security.srp.SRPParameters;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import se.leap.bitmaskclient.ConfigHelper;
+import se.leap.bitmaskclient.LeapSRPSession;
+
+import junit.framework.TestCase;
+
+public class testLeapSRPSession extends TestCase {
+
+ public testLeapSRPSession(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testExponential() {
+ byte[] expected_A;
+ byte[] a_byte;
+ SRPParameters params;
+ LeapSRPSession client;
+
+ /* Test 1: abytes = 4 */
+ expected_A = new BigInteger("44eba0239ddfcc5a488d208df32a89eb00e93e6576b22ba2e4410085a413cf64e9c2f08ebc36a788a0761391150ad4a0507ca43f9ca659e2734f0457a85358c0bb39fa87183c9d3f9f8a3b148dab6303a4e796294f3e956472ba0e2ea5697382acd93c8b8f1b3a7a9d8517eebffd6301bfc8de7f7b701f0878a71faae1e25ad4", 16).toByteArray();
+ String username = "username",
+ password = "password",
+ salt = "64c3289d04a6ecad",
+ a = "3565fdc2";
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ byte[] A = client.exponential();
+
+ assertTrue(Arrays.equals(A, expected_A));
+
+ /* Test 1: abytes = 5 */
+ a = "67c152a3";
+ expected_A = new BigInteger("11acfacc08178d48f95c0e69adb11f6d144dd0980ee6e44b391347592e3bd5e9cb841d243b3d9ac2adb25b367a2558e8829b22dcef96c0934378412383ccf95141c3cb5f17ada20f53a0225f56a07f2b0c0469ed6bbad3646f7b71bdd4bedf5cc6fac244b26d3195d8f55877ff94a925b0c0c8f7273eca733c0355b38360442e", 16).toByteArray();
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ A = client.exponential();
+
+ assertTrue(Arrays.equals(A, expected_A));
+ }
+
+ public void testResponse() throws NoSuchAlgorithmException {
+ /* Test 1: with intermediate checks */
+ byte[] expected_A = trim(new BigInteger("884380f70a62193bbe3589c4e1dbdc4467b6b5a1b4486e4b779023506fc1f885ae26fa4a5d817b3f38a35f3487b147b82d4bd0069faa64fdc845f7494a78251709e212698e42ced44b0f3849adc73f467afcb26983bd13bdc38906b178003373ddd0ac1d38ce8a39ffa3a7795787207a129a784f4b65ce0b302eb1bcf4045883", 16).toByteArray());
+ byte[] expected_x = new BigInteger("4cb937fd74ee3bb53b79a3174d0c07c14131de9c825897cbca52154e74200602", 16).toByteArray();
+ byte[] expected_M1 = trim(new BigInteger("e6a8efca2c07ef24e0b69be2d4d4a7e74742a4db7a92228218fec0008f7cc94b", 16).toByteArray());
+ String username = "username",
+ password = "password",
+ salt = "64c3289d04a6ecad",
+ a = "8c911355";
+ byte[] a_byte = new BigInteger(a, 16).toByteArray();
+ SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ LeapSRPSession client = new LeapSRPSession(username, password, params, a_byte);
+
+ byte[] x = client.calculatePasswordHash(username, password, new BigInteger(salt, 16).toByteArray());
+ assertTrue(Arrays.equals(x, expected_x));
+
+ byte[] A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ String B = "bc745ba25564fc312f44ea09fb663aa6d95867772e412a6a23f1bc24183e54b32f134372c560f4b3fda19ba7a56b0f84fdcdecc22be6fd256639e918e019691c40a39aa5c9631820e42b28da61b8c75b45afae9d77d63ac8f4dda093762be4a890fbd86061dbd7e5e7c03c4dacde769e0f564df00403e449c0535537f1ba7263";
+
+ byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ /* Test 2: no intermediate checks */
+ expected_A = trim(new BigInteger("9ffc407afd7e7ecd32a8ea68aa782b0254a7e2197a955b5aa646fc1fc43ff6ef2239f01b7d5b82f152c870d3e69f3321878ca2acda06dd8fb6ce02f41c7ed48061c78697b01cf353f4222311334c707358b6ec067e317527316bfa85b5ec74537e38b5b14c1100d14c96320f385e5b1dcccde07e728c7ef624353167a29ae461", 16).toByteArray());
+ expected_M1 = trim(new BigInteger("c3203ec1dd55c96038276456c18c447fb4d2a2f896c73c31d56da1781cae79a8", 16).toByteArray());
+ a = "38d5b211";
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+ x = client.calculatePasswordHash(username, password, new BigInteger(salt, 16).toByteArray());
+ A = client.exponential();
+
+ B = "b8ca7d93dbe2478966ffe025a9f2fb43b9995ce04af9523ea9a3fa4b132136076aa66ead1597c3da23f477ce1cfaf68b5dcc94e146db06cf8391d14a76ce53aab86067b13c93b135d7be6275669b3f51afec6cc41f19e0afca7c3ad5c4d6ee4c09d4b11bcd12e26c727ee56d173b92eea6926e72cc73deebe12dd6f30f44db8a";
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ /* Test 3: With intermediate values */
+ expected_M1 = new BigInteger("4c01f65a9bb00f95e435593083040ae1e59e59800c598b42de821c21f3a35223", 16).toByteArray();
+ expected_A = new BigInteger("1bceab3047a6f84495fdd5b4dbe891f0b30f870d7d4e38eaef728f6a7d4e9342d8dae8502fdae4f16b718d2e916a38b16b6def45559a5ebae417a1b115ba6b6a0451c7ff174c3e2507d7d1f18ef646fd065bc9ba165a2a0ae4d6da54f060427178b95b0eff745f5c3f8c4f19ea35addc3ce0daf2aca3328c98bafcf98286d115", 16).toByteArray();
+ B = "41a7b384f2f52312fa79b9dc650ae894f543aea49800cf9477fbcf63e39cbfe6d422f7126777d645cdf749276a3ae9eb6dfcfdb887f8f60ac4094a343013fcebbd40e95b3153f403ab7bb21ea1315aa018bab6ab84017fcb084b3870a8bf1cb717b39c9a28177c61ce7d1738379be9d192dd9793b50ebc3afabe5e78b0a4b017";
+ a = "36ee80ec";
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+ x = client.calculatePasswordHash(username, password, new BigInteger(salt, 16).toByteArray());
+ A = client.exponential();
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+ }
+
+ public void testCalculateV() throws NoSuchAlgorithmException {
+ String expected_v = "502f3ffddc78b866330550c2c60ebd68427c1793237d770e6390d1f794abd47b6786fa5025728d1ca4ec24cfc7a89808278330099ad66456a7c9c88be570b928f9825ac2ecdee31792335f7fa5fc9a78b692c487aa400c7d5cc5c1f2a3a74634c4afa0159600bbf22bf6dfb1e0d85061e55ce8df6243758066503bcf51c83848cf7184209731f89a90d888934c75798828859babe73c17009bf827723fc1bcd0";
+
+ BigInteger k = new BigInteger("bf66c44a428916cad64aa7c679f3fd897ad4c375e9bbb4cbf2f5de241d618ef0", 16);
+ BigInteger g = new BigInteger("2", 16);
+ BigInteger N = new BigInteger(ConfigHelper.NG_1024, 16);
+ BigInteger x = new BigInteger("4cb937fd74ee3bb53b79a3174d0c07c14131de9c825897cbca52154e74200602", 16);
+
+ BigInteger v = k.multiply(g.modPow(x, N)); // g^x % N
+
+ assertEquals(v.toString(16), expected_v);
+ assertTrue(Arrays.equals(v.toByteArray(), new BigInteger(expected_v, 16).toByteArray()));
+ }
+
+ public void testGetU() throws NoSuchAlgorithmException {
+ /* Test 1 */
+ String Astr = "46b1d1fe038a617966821bd5bb6af967be1bcd6f54c2db5a474cb80b625870e4616953271501a82198d0c14e72b95cdcfc9ec867027b0389aacb313319d4e81604ccf09ce7841dc333be2e03610ae46ec0c8e06b8e86975e0984cae4d0b61c51f1fe5499a4d4d42460261a3e134f841f2cef4d68a583130ee8d730e0b51a858f";
+ String Bstr = "5e1a9ac84b1d9212a0d8f8fe444a34e7da4556a1ef5aebc043ae7276099ccdb305fd7e1c179729e24b484a35c0e33b6a898477590b93e9a4044fc1b8d6bc73db8ac7778f546b25ec3f22e92ab7144e5b974dc58e82a333262063062b6944a2e4393d2a087e4906e6a8cfa0fdfd8a5e5930b7cdb45435cbee7c49dfa1d1216881";
+ String ustr = "759c3cfb6bfaccf07eeb8e46fe6ea290291d4d32faca0681830a372983ab0a61";
+
+ byte[] Abytes = new BigInteger(Astr, 16).toByteArray();
+ byte[] Bbytes = new BigInteger(Bstr, 16).toByteArray();
+ byte[] expected_u = new BigInteger(ustr, 16).toByteArray();
+
+ MessageDigest u_digest = MessageDigest.getInstance("SHA256");
+ u_digest.update(trim(Abytes));
+ u_digest.update(trim(Bbytes));
+ byte[] u = new BigInteger(1, u_digest.digest()).toByteArray();
+
+ assertTrue(Arrays.equals(expected_u, u));
+
+ /* Test 2 */
+ Astr = "c4013381bdb2fdd901944b9d823360f367c52635b576b9a50d2db77141d357ed391c3ac5fa452c2bbdc35f96bfed21df61627b40aed8f67f21ebf81e5621333f44049d6c9f6ad36464041438350e1f86000a8e3bfb63d4128c18322d2517b0d3ead63fd504a9c8f2156d46e64268110cec5f3ccab54a21559c7ab3ad67fedf90";
+ Bstr = "e5d988752e8f265f01b98a1dcdecc4b685bd512e7cd9507f3c29f206c27dac91e027641eed1765c4603bbd7a9aa7fac300ef67dafe611ba2dbe29a32d83d486296f328d38b44c0c211d01d3fe422aac168b6850c87782338969c54594fc87804d4db34910ad4b5452a81027842ac8d8d8288fd44872e4c719ac8fb971d0a33e1";
+ ustr = "6510328f913b81ba662e564ee5afb7c395ea27c3c0276fc5ca51f0edecd4baf1";
+
+ Abytes = new BigInteger(Astr, 16).toByteArray();
+ Bbytes = new BigInteger(Bstr, 16).toByteArray();
+ expected_u = new BigInteger(ustr, 16).toByteArray();
+ expected_u = trim(expected_u);
+
+ u_digest = MessageDigest.getInstance("SHA-256");
+ u_digest.update(trim(Abytes));
+ u_digest.update(trim(Bbytes));
+ u = new BigInteger(1, u_digest.digest()).toByteArray();
+ u = trim(u);
+
+ assertTrue(Arrays.equals(expected_u, u));
+
+ /* Test 3 */
+ Astr = "d13973fe4e0e13423cd036caf0912e23a1f9b0c23966f5a5897c8ff17c5cbac8bab7f07d9ac4ee47396a7c68e80ce854c84f243148521277900aaa132a7b93b61e54d742d7f36edb4cdef54bc78cca69ac72653a7ae0fc47ec1e9a84024ea9487a61357e28eddc185e4fe01388e64e6b8f688dd74471d56dd244204522e08483";
+ Bstr = "a6701686d9d987a43f06e8497330c8add8febd191a7a975bced0d058eb03ccc6805263349363b2d54ac435b01155dc41c6067287d9b93e3637ab3b7e8bc7d9cf38d9fdbb2ca9ee8ba1946a46cb555cb7dafcc177fcf7a4b0eb1e5db2249949c1fd15e0b7c1b3616f9e2649bdf074ed841efbdc9f29ee8c8bfcedeaed3dc49378";
+ ustr = "78414ec80cf44225e7ed386dcf2ceb89837327ccae11b761fc77d48c0307977";
+
+ Abytes = new BigInteger(Astr, 16).toByteArray();
+ Bbytes = new BigInteger(Bstr, 16).toByteArray();
+ expected_u = new BigInteger(ustr, 16).toByteArray();
+ expected_u = trim(expected_u);
+
+ u_digest = MessageDigest.getInstance("SHA-256");
+ u_digest.update(trim(Abytes));
+ u_digest.update(trim(Bbytes));
+ u = new BigInteger(1, u_digest.digest()).toByteArray();
+ u = trim(u);
+
+ assertTrue(Arrays.equals(expected_u, u));
+
+ /* Test 4 */
+ Astr = "ee8bc0cb97dd9c9937759658ff9d791df1dd57b48c5febc2e98af028d0e36eaddf1a3fc555f2bcd6456827e8c7b07ec02a1f365457843bda226bfc1a55c4776879f9df6c916810131ec65a3a4cf473c6a34299d64c91cf26542ea0fc059d24422fc783460c3fafe26bf6f7c24904ae1c5a6421e2f5315030ab007ce8f2c2fd97";
+ Bstr = "95ecbd13b28c7f38318fd664ee97d9e853b0d6e9cbff9a3775a3cc5d5077ffc146aec70d9439e75c19a34b67368b8bd7035ba6254e0a260d99b1e253aae2e0d8f4a13e1ed472f3ef0e3086300cd15d059f6be7d7141ee09071b1c5e5d1c83b250a3c8f1a587f8fe59d49aaeb2cfc7e13a5a58bc76cc8baf7f6a647982c67ee49";
+ ustr = "e28737c7307c84e4d0866b7cf882f22852a764b109634f77a5eb986a96ffcf9a";
+
+ Abytes = new BigInteger(Astr, 16).toByteArray();
+ Bbytes = new BigInteger(Bstr, 16).toByteArray();
+ expected_u = new BigInteger(ustr, 16).toByteArray();
+ expected_u = trim(expected_u);
+ assertEquals(new BigInteger(1, expected_u).toString(16), ustr);
+
+ u_digest = MessageDigest.getInstance("SHA-256");
+ u_digest.update(trim(Abytes));
+ u_digest.update(trim(Bbytes));
+ u = new BigInteger(1, u_digest.digest()).toByteArray();
+ u = trim(u);
+
+ assertTrue(Arrays.equals(expected_u, u));
+ }
+
+ @SmallTest
+ public void testCalculatePasswordHash() throws UnsupportedEncodingException, NoSuchAlgorithmException {
+ String salt_str = "", username_str = "", password_str = "";
+ String expected_inner = "cfb9ae3ec5433076889c4fe5663926e20bf570cc7950a51c889a314fab2f5ed716bde9c1cc91be14",
+ expected_x = "9736a5e386a18f35bb08cac0f7c70bdbe120f2efe019874d0eb23b85b1955858";
+
+ /* Test 1 */
+ salt_str = "cfb9ae3ec5433076"; username_str = "nostradamus"; password_str = "$[[//jjiilajfewahug43a89y¿";
+ password_str = password_str.replaceAll("\\\\", "\\\\\\\\");
+ // Calculate x = H(s | H(U | ':' | password))
+ MessageDigest x_digest = MessageDigest.getInstance("SHA-256");
+
+ // Try to convert the username to a byte[] using UTF-8
+ byte[] user = null;
+ byte[] password_bytes = null;
+ byte[] colon = {};
+
+ String encoding = "UTF-8";
+ encoding = "ISO-8859-1";
+ user = ConfigHelper.trim(username_str.getBytes(encoding));
+ colon = ConfigHelper.trim(":".getBytes(encoding));
+ password_bytes = ConfigHelper.trim(password_str.getBytes(encoding));
+
+ // Build the hash
+ x_digest.update(user);
+ x_digest.update(colon);
+ x_digest.update(password_bytes);
+ byte[] h = x_digest.digest();
+ byte[] salt_bytes = ConfigHelper.trim(new BigInteger(salt_str, 16).toByteArray());
+
+ x_digest.reset();
+ x_digest.update(salt_bytes);
+ x_digest.update(h);
+ byte[] x_digest_bytes = x_digest.digest();
+ assertTrue(new BigInteger(1, x_digest_bytes).toString(16).equalsIgnoreCase(expected_x));
+ }
+
+ public void testCalculateS() throws NoSuchAlgorithmException {
+ String expected_S = "34d71467d0a30c5787e6b4384c7176a724df28f6c1d3b0b7738238621be19080942ca5d4454ab3e5664d42970ea2d42d1188ab246afb1475c481111f30886c79cc99ddd1d711034bc4ac57a0c134fef40470e1ac3386f39abcd1bf9d0cc758a1f38a87b2f7261018cdc6191cd941292c77c320b3c664a9bb1325dd7a2bf62db4";
+
+ String B_string = "d390da0991b84e20918764aed9bccf36fc70863f08a1d3fa0aecd9610d8c40d1895afaf3aa9b4582fb5bc673037dfc1bf0ca7d3d190a807dec563fe57d596b3551ec8a6461e0621b77fabfaa29234187063e715e2706522c65f35d89f3914a7cdf40ddd240ef3d22b5534469cf6b3b31e158f817dcf5b6b44b0914d4787d027e";
+ String A_string = "c6385e56b9cb8987df3c58ffe6c47bfcd9f9d52f02b68048d72135a8522a0919b41683e3c732a0874e0555b8f288fa067842b1c40a56f1a7d910ad125e71238cb14ba47838f881cabf735d5414f4fcdd6855943621c271c5f013753d439fb124674c79e30d849e9178c780f7c25aded12f053ae41be68289787caf7c3cbb07a4";
+ String a_string = "fc1c2d8d";
+
+ BigInteger A = new BigInteger(A_string, 16);
+ byte[] Bbytes = new BigInteger(B_string, 16).toByteArray();
+ BigInteger a = new BigInteger(a_string, 16);
+ BigInteger g = ConfigHelper.G;
+ BigInteger N = new BigInteger(ConfigHelper.NG_1024, 16);
+ BigInteger k = new BigInteger("bf66c44a428916cad64aa7c679f3fd897ad4c375e9bbb4cbf2f5de241d618ef0", 16);
+ BigInteger x = new BigInteger("4cb937fd74ee3bb53b79a3174d0c07c14131de9c825897cbca52154e74200602", 16);
+
+ /* GetU */
+ MessageDigest u_digest = MessageDigest.getInstance("SHA256");
+ u_digest.update(trim(A.toByteArray()));
+ u_digest.update(trim(Bbytes));
+ byte[] ub = new BigInteger(1, u_digest.digest()).toByteArray();
+
+ BigInteger v = k.multiply(g.modPow(x, N)); // g^x % N
+ String expected_v = "502f3ffddc78b866330550c2c60ebd68427c1793237d770e6390d1f794abd47b6786fa5025728d1ca4ec24cfc7a89808278330099ad66456a7c9c88be570b928f9825ac2ecdee31792335f7fa5fc9a78b692c487aa400c7d5cc5c1f2a3a74634c4afa0159600bbf22bf6dfb1e0d85061e55ce8df6243758066503bcf51c83848cf7184209731f89a90d888934c75798828859babe73c17009bf827723fc1bcd0";
+ String v_string = v.toString(16);
+
+ BigInteger B = new BigInteger(1, Bbytes);
+ BigInteger u = new BigInteger(1, ub);
+ String expected_u_string = "2d36f816df24da7b904c904a7e2a2500511df118ced26bda92a63aca792c93b";
+ String u_string = u.toString(16);
+
+ BigInteger B_v = B.subtract(v);
+ BigInteger a_ux = a.add(u.multiply(x));
+ byte[] a_ux_byte= a_ux.toByteArray();
+ String expected_a_aux_string = "d8d0843a60d471ab46a761b775f8fd28bbbd8affbc704424c79b822ac36b1177925404db910072737df3c5083cf20ebd2f08e1381d80d91e4f6fc99f592203";
+ byte[] expected_a_aux_byte = new BigInteger(expected_a_aux_string, 16).toByteArray();
+
+ BigInteger S = B_v.modPow(a_ux, N);
+
+ byte[] expected_S_bytes = new BigInteger(expected_S, 16).toByteArray();
+ byte[] S_bytes = S.toByteArray();
+ assertTrue(Arrays.equals(S_bytes, expected_S_bytes));
+ assertEquals(S.toString(16), expected_S);
+ }
+
+ public void testXor() throws Exception {
+ String expected_xor_string = "928ade491bc87bba9eb578701d44d30ed9080e60e542ba0d3b9c20ded9f592bf";
+ byte[] expected_xor = new BigInteger(expected_xor_string, 16).toByteArray();
+
+ byte[] nbytes = trim(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray());
+ byte[] gbytes = trim(ConfigHelper.G.toByteArray());
+
+ byte[] ndigest = trim(MessageDigest.getInstance("SHA-256").digest(nbytes));
+ byte[] gdigest = MessageDigest.getInstance("SHA-256").digest(gbytes);
+
+ BigInteger ndigest_bigInteger = new BigInteger(1, ndigest);
+ String expected_ndigest_string = "494b6a801b379f37c9ee25d5db7cd70ffcfe53d01b7c9e4470eaca46bda24b39";
+ String ndigest_string = ndigest_bigInteger.toString(16);
+ assertEquals(ndigest_string, expected_ndigest_string);
+
+ BigInteger gdigest_bigInteger = new BigInteger(1, gdigest);
+ String xor_string = ndigest_bigInteger.xor(gdigest_bigInteger).toString(16);
+
+ byte[] xor = new BigInteger(xor_string, 16).toByteArray();
+
+ assertTrue(Arrays.equals(expected_xor, xor));
+ }
+
+ public void testVerify() throws NoSuchAlgorithmException {
+ byte[] expected_A = trim(new BigInteger("884380f70a62193bbe3589c4e1dbdc4467b6b5a1b4486e4b779023506fc1f885ae26fa4a5d817b3f38a35f3487b147b82d4bd0069faa64fdc845f7494a78251709e212698e42ced44b0f3849adc73f467afcb26983bd13bdc38906b178003373ddd0ac1d38ce8a39ffa3a7795787207a129a784f4b65ce0b302eb1bcf4045883", 16).toByteArray());
+ byte[] expected_x = new BigInteger("4cb937fd74ee3bb53b79a3174d0c07c14131de9c825897cbca52154e74200602", 16).toByteArray();
+ byte[] expected_M1 = trim(new BigInteger("e6a8efca2c07ef24e0b69be2d4d4a7e74742a4db7a92228218fec0008f7cc94b", 16).toByteArray());
+ byte[] expected_M2 = trim(new BigInteger("6402e108415ab4a7cd223ec435570614c8aacc09fcf081ade2dc00275e90ceee", 16).toByteArray());
+ String username = "username",
+ password = "password",
+ salt = "64c3289d04a6ecad",
+ a = "8c911355";
+ byte[] a_byte = new BigInteger(a, 16).toByteArray();
+ SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ LeapSRPSession client = new LeapSRPSession(username, password, params, a_byte);
+
+ byte[] x = client.calculatePasswordHash(username, password, new BigInteger(salt, 16).toByteArray());
+ assertTrue(Arrays.equals(x, expected_x));
+
+ byte[] A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ String B = "bc745ba25564fc312f44ea09fb663aa6d95867772e412a6a23f1bc24183e54b32f134372c560f4b3fda19ba7a56b0f84fdcdecc22be6fd256639e918e019691c40a39aa5c9631820e42b28da61b8c75b45afae9d77d63ac8f4dda093762be4a890fbd86061dbd7e5e7c03c4dacde769e0f564df00403e449c0535537f1ba7263";
+
+ byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ boolean verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 2 */
+ expected_A = trim(new BigInteger("180a1caf84efe93610a56772edea7b2d20ef3e9f34e578147b5402a898982f33131708233f9ddd2946246703c5db705f0859cca9cfc5b72ad5a05ec0c748545aa083d5b7b1bf06efe6737e9e0fd81b832b5cba983f1b9717041df8114385b93c8c669db06d62c5773b8e8a8f07e98a840a33d04d3448d4bcd2c042387c316750", 16).toByteArray());
+ expected_M1 = trim(new BigInteger("a47782f23057a7e06704ea94389589b3c70971a63268acef2aefd74e234dd3c2", 16).toByteArray());
+ a = "d89f0e33";
+ expected_M2 = trim(new BigInteger("517278a03a0320a52dcb391caf5264d76149d7d9b71ed2b65536233344c550cf", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+ x = client.calculatePasswordHash(username, password, new BigInteger(salt, 16).toByteArray());
+ A = client.exponential();
+
+ B = "5f86fe2f7b7455e877e1760db8d3da1fcd4df0d10ec2a40298f87287bdb2f22c0ea54ff9b1f660cc1666459a7e2fd5501970b317490c3dfd3ba2e18f7be7526b72ea4d01e8f064754b935b107ced0892ce86112cbe32282f929907985fcb29f42c5d4dc32adeb29d12a611cac49cca3fefd2227efadc3989c2e72dd64a003141";
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 3 */
+ expected_A = trim(new BigInteger("a9c556c30bf4c1b1fdc1bc9e672ab4751806acc8581042b3779faaf25f85f47dfc58828742e2d2a06c51acbbb9f3fae0e01f64df0775a269f5ee4a6e71bc37b8a368e04b9053d399bc5b809ffd6ecab775a577804f2a5ed2e829f15e6af13bf0b78b6b108cf591bc9960992904fd1433698a51e0d05ee954cf98cbfe7995621e", 16).toByteArray());
+ expected_M1 = trim(new BigInteger("0afca3583c4146990ec7312f9f4b4d9cceebc43a19f96709bf3d0a17b11dcc1e", 16).toByteArray());
+ a = "50e662d6";
+ expected_M2 = trim(new BigInteger("3bfb91c7d04b6da6381fe3d2648d992cdc6bc67b8ee16d1cfa733f786d492261", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+ x = client.calculatePasswordHash(username, password, new BigInteger(salt, 16).toByteArray());
+ A = client.exponential();
+
+ B = "6fe41e8262f4f8bc4ed9f4e1b4802ae3adac9c348e6efc07f16c6f5704b95a1f12325097489372c3936584a37301ebab400a32ac6699f4556da84f076489060527bd50578a317a3ec8b814bf2f4dd9c4adad368610eb638aa81663a205ba26d8f0b9654bf3940357b867cd42725e8532b97a2410a557d291aa55c0b44f249361";
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 4: user abc, password abcdefghi */
+ username = "abc";
+ password = "abcdefghi";
+ salt = "be26aac449a093e5";
+ expected_A = trim(new BigInteger("c4013381bdb2fdd901944b9d823360f367c52635b576b9a50d2db77141d357ed391c3ac5fa452c2bbdc35f96bfed21df61627b40aed8f67f21ebf81e5621333f44049d6c9f6ad36464041438350e1f86000a8e3bfb63d4128c18322d2517b0d3ead63fd504a9c8f2156d46e64268110cec5f3ccab54a21559c7ab3ad67fedf90", 16).toByteArray());
+ expected_x = trim(new BigInteger("6325967f1a161efd4e2d6e6fabbfccc32be05139cf82b08fb59c0a0db3f34bcf", 16).toByteArray());
+ a = "5d4cde29";
+ B = "e5d988752e8f265f01b98a1dcdecc4b685bd512e7cd9507f3c29f206c27dac91e027641eed1765c4603bbd7a9aa7fac300ef67dafe611ba2dbe29a32d83d486296f328d38b44c0c211d01d3fe422aac168b6850c87782338969c54594fc87804d4db34910ad4b5452a81027842ac8d8d8288fd44872e4c719ac8fb971d0a33e1";
+ expected_M1 = trim(new BigInteger("e5972ddc53e6190735fc79cd823053a65ffb6041d69480adcba2f6a2dc2f2e86", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("8f4552b1021a4de621d8f50f0921c4d20651e702d9d71276f8f6c15b838de018", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(trim(new BigInteger(salt, 16).toByteArray()), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 5: user abc, password abcdefghi */
+ username = "abc";
+ password = "abcdefghi";
+ salt = "be26aac449a093e5";
+ expected_A = trim(new BigInteger("d13973fe4e0e13423cd036caf0912e23a1f9b0c23966f5a5897c8ff17c5cbac8bab7f07d9ac4ee47396a7c68e80ce854c84f243148521277900aaa132a7b93b61e54d742d7f36edb4cdef54bc78cca69ac72653a7ae0fc47ec1e9a84024ea9487a61357e28eddc185e4fe01388e64e6b8f688dd74471d56dd244204522e08483", 16).toByteArray());
+ expected_x = trim(new BigInteger("6325967f1a161efd4e2d6e6fabbfccc32be05139cf82b08fb59c0a0db3f34bcf", 16).toByteArray());
+ a = "fc57e4b1";
+ B = "a6701686d9d987a43f06e8497330c8add8febd191a7a975bced0d058eb03ccc6805263349363b2d54ac435b01155dc41c6067287d9b93e3637ab3b7e8bc7d9cf38d9fdbb2ca9ee8ba1946a46cb555cb7dafcc177fcf7a4b0eb1e5db2249949c1fd15e0b7c1b3616f9e2649bdf074ed841efbdc9f29ee8c8bfcedeaed3dc49378";
+ expected_M1 = trim(new BigInteger("0b590fde631566d0d3420a898a9b469656e64bfaff165c146b78964eee7920b8", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("04cf3ab3b75dbc4b116ca2fec949bf3deca1e360e016d7ab2b8a49904c534a27", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(trim(new BigInteger(salt, 16).toByteArray()), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 6: user and password of real use */
+ username = "parmegv";
+ password = "wR\"P}x@_,:k$`Y<i7PH9\\\\zubHtn[-4MoL+$(?k>Yd*s T`-n.";
+ salt = "40c3f47b99ce8dc9";
+ expected_A = trim(new BigInteger("490b5de7a287c59cefe267441a186ec24f63210fbf28877305f5896eaec5a7245d304ecb2b09d91066e627d7b2c8bf9e5271d882361a435355d1c2d1ac9d3069877189a01d64b2dd73a569e9e96b9a99767dbc02e04c839b09444f48430b113c1827c20b684ae33f5018051169f5acf4913ebd76a205c6f1aa2cc75747687d56", 16).toByteArray());
+ String x_string = "9665839759b4fb9684e7438daecbd6e7129b4ebd3e4a107916e9a64bbbf399c9";
+ expected_x = trim(new BigInteger(x_string, 16).toByteArray());
+ assertEquals(new BigInteger(1, expected_x).toString(16), x_string);
+ a = "a72111a2";
+ B = "6574ddce3e33c44a77198fa8b3656627e4a24c8786948e79f0c2588febaa485c94b1deb5e420bd3b46f9a34c7862525452ca7a0542c52f939d9f277a013aeceef7353a7741440f6dd2f6c2f1dc07fa5ca003e305c89c876a3035bd04f546b711d44da06a3ba827bc8affbf9ed46de1bfbc670ef9ed7c0bb8cdc588285d13849e";
+ expected_M1 = trim(new BigInteger("03bbcf57aeaec89a3a254bb9650a924ea86aa0fdd83fd7274a75b7083f221cf0", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("082cf49ad5a34cc5ca571e3d063aec4bd96e7b96a6d951295180631650a84587", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+ assertEquals(new BigInteger(1, expected_x).toString(16), new BigInteger(1, x).toString(16));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 7: password with ! */
+ username = "parmegvtest3";
+ password = "holahola!";
+ salt = "1bf48d42b9a7ed32";
+ expected_A = trim(new BigInteger("4e2fbe8db5d07f33ff1f4303959b5396dcffc1460b6ce8866fd388415f27fe10f9042986ab8682cdcf9a033e651bca89173688989adad854c91bc1918f98d5c82525fb6f328a8cf74ce1436b23821cba5337aaa20a3e5631e4b957053d542f2b5fc456e888371c9d6b94360b37adb2793eca8db100c24887c459e36d729a98e1", 16).toByteArray());
+ x_string = "363d1d62dda07b2d987a9739ddb5ec32fcad9c7322fb64e87937f2da86c45d9f";
+ expected_x = trim(new BigInteger(x_string, 16).toByteArray());
+ assertEquals(new BigInteger(1, expected_x).toString(16), x_string);
+ a = "16dd0cf5";
+ B = "dd5c9c5e13eb5daa6e7303928b3c826cec520ccef429c0dcb785be34c330d5bb89c99d7d94842b6b5c19cac600f884c50b26989b105f397115df7f3d13c5c7c2f6327cc547fc854ae40f09f1f6a104968bd510243feb104eb559e085fe1d720770be2887a1f424c534a3ab962d82e92458f652328bcf9878f95fdcf463d06193";
+ expected_M1 = trim(new BigInteger("a7ffbff753a547b877f8944339b707b3ce1998da27badf253d56bf39f35308a6", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("5cc3d7f0077e978c83acdef14a725af01488c1728f0cf32cd7013d24faf5d901", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+ assertEquals(new BigInteger(1, expected_x).toString(16), new BigInteger(1, x).toString(16));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 8: username and password *was* failing in localhost testProviderAPI*/
+ username = "gg";
+ password = "password";
+ a = "bc925bfb";
+ salt = "ff9ebb44e947cf59";
+ expected_A = trim(new BigInteger("8f434633414faeaf035a0dea8c1cb7876bb1f8ee80d6fee8ea43ae60c4f9658550d825c25f1ed5c6a5543358bbcb559b76958c8047a2e7e5fe0072bc1f16401bcfa77b57651ff50dd665c6f28c302b37c98495eff397a56befead2e5ceffaace45f2ec200520258adb66df751e815e464656d869454e360d98cbc70f9c64fd4c", 16).toByteArray());
+ x_string = "9cad2eca264380dd0b48e3b405e109c1be0615ee6ec92e7105eff5bc3a309fd9";
+ expected_x = trim(new BigInteger(x_string, 16).toByteArray());
+ assertEquals(new BigInteger(1, expected_x).toString(16), x_string);
+ B = "9ca2cd50b4c41047e4aa9e4fac9078ae21175e51e04a23877d6c2044765e39959e9a6a3ede99d08a556c196f51a2be12117681b1ef9d0b0498fb2fa4e88649ab9403e743504e3aaefbce8c5cb474eef8f4724ccd076fd33857de510d8509b67f166d986443bc262d776ec20985f617a7aa86e490290ce5d66332c8b45742a527";
+ expected_M1 = trim(new BigInteger("7a2f768791abaeb954eb7f001bb60d91e6f61e959c8fcdefb58de857af9edaac", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("d78da7e0a23c9b87a2f09cdee05c510c105b4a8d471b47402c38f4cdfa49fe6d", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+ assertEquals(new BigInteger(1, expected_x).toString(16), new BigInteger(1, x).toString(16));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 9: username and password *was* failing in localhost testProviderAPI*/
+ username = "oo";
+ password = "password";
+ a = "1322ec50";
+ salt = "a93c74934dcadd90";
+ expected_A = trim(new BigInteger("c8e9f30a2f67977ee7e61e9ca5af8bd854b6cc98fe01dbe1b1a4cf002c1e2523b7e49f373a600ff85a84867817ec60fec532857812a07f5c6189f6172f133023af75ca4cb98b758bb84620d0aa3cfc74dc69e0507114c0aeab5a75c3ae3f07a919c5729420f03266c26ed41d1846e07de023ec68dd6830e9ebf129cf51abb571", 16).toByteArray());
+ x_string = "20470538560c4beb4908e6bfe5b0e00da94223e361302a25c898cbdd3724020";
+ expected_x = trim(new BigInteger(x_string, 16).toByteArray());
+ assertEquals(new BigInteger(1, expected_x).toString(16), x_string);
+ B = "24f98ede155212bea8b1d8bacf8153735ee8114faa824c57c84df55f8d6072ab87f5ae885ce1062939dbaa68ca6e63147c1d2dc1f751e8be20d8a6f87287a2a83fcb1dc9b85dd406d438aeee5ccbc873603cb399627e26e6444e94b3d5d26764e866776c8960fe206bd33febeca9f55f6291dd2cb832eab69e5373f548adeefb";
+ expected_M1 = trim(new BigInteger("1b35c705e563bd5239cdccc6627aa877c3023286f49b4b7c21341d2949ca2d15", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("a382025452bad8a6ccd0f703253fda90e7ea7bd0c2d466a389455080a4bd015d", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+ assertEquals(new BigInteger(1, expected_x).toString(16), new BigInteger(1, x).toString(16));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 10: derived from test 11, discovered that password bytes should be in ISO-8859-1*/
+ username = "nostradamus";
+ password = "$[[//jjiilajfewahug43a89y¿";
+ a = "800f0819";
+ salt = "cfb9ae3ec5433076";
+ expected_A = trim(new BigInteger("2ab09ee2fa01058f2f72fd2142b129f2ec26313801052889bcc4af57ee2e4d5b92c90cdfd6ecd660e82c635b2a091ba1b164e5b371c911ce0c4e69686baa120c58e2e0af84b2adc10da6cdfb0b579a1685032c57fd6ed1306d9713a562eddf5c833725042e825fa1abc7017f74760cb53d8c755ffe628c510022c296d1cd3584", 16).toByteArray());
+ x_string = "9736a5e386a18f35bb08cac0f7c70bdbe120f2efe019874d0eb23b85b1955858";
+ expected_x = trim(new BigInteger(x_string, 16).toByteArray());
+ assertEquals(new BigInteger(1, expected_x).toString(16), x_string);
+ B = "2d19fe17dca1bda01044a0f406547895c32a10df2b0e69676de911273a8685d294763c4d16b3663f722b8980126e2c659efd33ffc6435a9594a2539e726c48e365893b3374670bd1958c13f55c2defa8ea9c0f9ba1345a5dca0e78debba434c8b755353d066d42bc5dfe0403fdcacfe5efd25c685f883ee6766c710b775c50f2";
+ expected_M1 = trim(new BigInteger("a33feada1771c6f53e9343f5b9e69d51d4f15043c95fb663b6dd5b1c7af6f66b", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("9e99f9adfbfaa7add3626ed6e6aea94c9fa60dab6b8d56ad0cc950548f577d32", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+ assertEquals(new BigInteger(1, expected_x).toString(16), new BigInteger(1, x).toString(16));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+
+ /* Test 11: username and password failing in localhost testProviderAPI*/
+ username = "nostradamus";
+ password = "$[['//\"jjiilajfewahug43a89y¿";
+ a = "5bfbc968";
+ salt = "1bcae1065951bbf5";
+ expected_A = trim(new BigInteger("7a74c254d46dd6010a7090e574817a03f32ba13f98ed3c695d96f09c9d334e591771541400e68b6d27a19e734baccf3965ca79c0294ffbf553716b41fbca627c7cd3ea4a0d1c640c22411881696f59ad7ed8ce6ef7010e43f57fb3858aa4c3479dd41e4073afadb6a516c41f649b8cf30dea6366efa711c5106c83ea71b00da4", 16).toByteArray());
+ x_string = "9834210874c883db35785ee6648079e13d22450c472d6469192ea775ff50c646";
+ expected_x = trim(new BigInteger(x_string, 16).toByteArray());
+ assertEquals(new BigInteger(1, expected_x).toString(16), x_string);
+ B = "285b00c034da5676dd8938ce6a7b717968fef2e5f479ecca6d95828a6ce809dd37893752c956245b5d13315987c50e57cc68aa4f770ff9ce977ddfd65052f278b90545286cf32b3d18307140514e0fe2269fc0437fb16104358f6fa127dc97281a017582759644862d736f48025f2b35cb1662067c11f2fcf0753e2f72c9e028";
+ expected_M1 = trim(new BigInteger("fedbaff9d9a19efc4eea949b045297a6a3121cf371e2acdda85a2a1ca61c929d", 16).toByteArray());
+ expected_M2 = trim(new BigInteger("ffccafa0febc1771a428082b30b7ce409856de4581c7d7d986f5b80015aba0d3", 16).toByteArray());
+
+ a_byte = new BigInteger(a, 16).toByteArray();
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256");
+ client = new LeapSRPSession(username, password, params, a_byte);
+
+ x = client.calculatePasswordHash(username, password, trim(new BigInteger(salt, 16).toByteArray()));
+ assertTrue(Arrays.equals(x, expected_x));
+ assertEquals(new BigInteger(1, expected_x).toString(16), new BigInteger(1, x).toString(16));
+
+ A = client.exponential();
+ assertTrue(Arrays.equals(A, expected_A));
+
+ M1 = client.response(new BigInteger(salt, 16).toByteArray(), new BigInteger(B, 16).toByteArray());
+
+ assertTrue(Arrays.equals(M1, expected_M1));
+
+ verified = client.verify(expected_M2);
+ assertTrue(verified);
+ }
+
+ public byte[] trim(byte[] in) {
+ if(in.length == 0 || in[0] != 0)
+ return in;
+
+ int len = in.length;
+ int i = 1;
+ while(in[i] == 0 && i < len)
+ ++i;
+ byte[] ret = new byte[len - i];
+ System.arraycopy(in, i, ret, 0, len - i);
+ return ret;
+ }
+
+}
diff --git a/tests/testClass.sh b/tests/testClass.sh
new file mode 100755
index 00000000..1889d32d
--- /dev/null
+++ b/tests/testClass.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+classfile=$1
+classline=`grep " class" $classfile`
+next=0
+for word in $classline
+do
+ if [ $word == "class" ]
+ then
+ next=1
+ elif [ $next -eq 1 ]
+ then
+ classname=$word
+ next=0
+ fi
+done
+
+adb shell am instrument -w -e class se.leap.bitmaskclient.test.$classname se.leap.bitmaskclient.test/android.test.InstrumentationTestRunner