diff options
37 files changed, 529 insertions, 509 deletions
diff --git a/assets/urls/bitmask.url b/assets/urls/bitmask.url index a17a5ff8..f924301e 100644 --- a/assets/urls/bitmask.url +++ b/assets/urls/bitmask.url @@ -1,7 +1,3 @@  {
 -	"name" : "bitmask",
 -	"assets_json_provider" : "providers/bitmask.net_provider.json",
 -	"provider_json_url" : "https://bitmask.net/provider.json",
 -	"cert" : "https://bitmask.net/ca.crt",
 -	"json_eip_service" : "https://api.bitmask.net:4430/1/config/eip-service.json"
 +	"main_url" : "https://bitmask.net/"
  }
\ No newline at end of file diff --git a/res/layout/client_dashboard.xml b/res/layout/client_dashboard.xml index 16e152be..9bda6d2e 100644 --- a/res/layout/client_dashboard.xml +++ b/res/layout/client_dashboard.xml @@ -5,7 +5,7 @@      android:layout_height="match_parent"      android:orientation="vertical"      tools:context=".Dashboard" > - +          <LinearLayout          android:id="@+id/providerLine"          android:layout_width="match_parent" @@ -68,4 +68,4 @@          android:orientation="vertical" >      </LinearLayout> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/res/menu/client_dashboard.xml b/res/menu/client_dashboard.xml index 0b3ad6f6..806147eb 100644 --- a/res/menu/client_dashboard.xml +++ b/res/menu/client_dashboard.xml @@ -15,11 +15,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 2598d452..609310b8 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2,8 +2,6 @@  <!-- Generated by crowdin.net -->  <resources> -    <string name="app">Bitmask</string> -    <string name="app_name">Bitmask</string>      <string name="address">Server Address:</string>      <string name="port">Server Port:</string>      <string name="location">Location</string> @@ -11,6 +9,7 @@      <string name="select">Select</string>      <string name="cancel">Cancel</string>      <string name="ok">OK</string> +    <string name="retry">Retry</string>      <string name="no_data">No Data</string>      <string name="useLZO">LZO Compression</string>      <string name="client_no_certificate">No Certificate</string> @@ -21,7 +20,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 LEAP</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 +238,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> 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 <info@leap.se></string>      <string name="opevpn_copyright" translatable="false">Copyright © 2002–2010 OpenVPN Technologies, Inc. <sales@openvpn.net>\n diff --git a/src/se/leap/bitmaskclient/AboutFragment.java b/src/se/leap/bitmaskclient/AboutFragment.java index d751dc2f..4d03a44b 100644 --- a/src/se/leap/bitmaskclient/AboutFragment.java +++ b/src/se/leap/bitmaskclient/AboutFragment.java @@ -4,9 +4,6 @@ import android.app.Fragment;  import android.content.pm.PackageInfo;  import android.content.pm.PackageManager.NameNotFoundException;  import android.os.Bundle; -import android.text.Html; -import android.text.Spanned; -import android.text.method.LinkMovementMethod;  import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup; diff --git a/src/se/leap/bitmaskclient/ConfigHelper.java b/src/se/leap/bitmaskclient/ConfigHelper.java index dd7049a7..6b49d7d7 100644 --- a/src/se/leap/bitmaskclient/ConfigHelper.java +++ b/src/se/leap/bitmaskclient/ConfigHelper.java @@ -168,6 +168,9 @@ public class ConfigHelper {  		return shared_preferences.getInt(shared_preferences_key, 0);  	} +	protected static boolean sharedPrefContainsKey(String shared_preferences_key) { +		return shared_preferences.contains(shared_preferences_key); +	}  	/*  	 * This method defaults to false.  	 * If you use this method, be sure to fail-closed on false! diff --git a/src/se/leap/bitmaskclient/ConfigurationWizard.java b/src/se/leap/bitmaskclient/ConfigurationWizard.java index 4a3bb12b..2467c52f 100644 --- a/src/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/src/se/leap/bitmaskclient/ConfigurationWizard.java @@ -22,17 +22,24 @@ import java.util.Iterator;  import org.json.JSONException;
  import org.json.JSONObject;
 -import se.leap.bitmaskclient.R;
 -import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver;
 -import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
 + +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; +import se.leap.bitmaskclient.ProviderListContent.ProviderItem; + +import se.leap.bitmaskclient.DownloadFailedDialog.DownloadFailedDialogInterface; +import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; +import se.leap.bitmaskclient.ProviderDetailFragment.ProviderDetailFragmentInterface; +  import android.app.Activity;
  import android.app.DialogFragment;
  import android.app.Fragment;
  import android.app.FragmentManager;
  import android.app.FragmentTransaction;
 -import android.app.ListFragment;
 +import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
 +import android.content.IntentFilter;
  import android.content.res.AssetManager;
  import android.os.Bundle;
  import android.os.Handler;
 @@ -60,9 +67,8 @@ import android.widget.TextView;   *
   */
  public class ConfigurationWizard extends Activity
 -implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogInterface, ProviderDetailFragment.ProviderDetailFragmentInterface, Receiver {
 +implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderDetailFragmentInterface, DownloadFailedDialogInterface, Receiver {
 -	private ProviderItem mSelectedProvider;
  	private ProgressBar mProgressBar;
  	private TextView progressbar_description;
  	private ProviderListFragment provider_list_fragment;
 @@ -77,6 +83,8 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  	final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED";
      public ProviderAPIResultReceiver providerAPI_result_receiver;
 +    private ProviderAPIBroadcastReceiver_Update providerAPI_broadcast_receiver_update;
 +      @Override
      protected void onCreate(Bundle savedInstanceState) {
 @@ -89,7 +97,11 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  	    progressbar_description.setVisibility(TextView.INVISIBLE);
          providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler());
          providerAPI_result_receiver.setReceiver(this);
 -        
 +	    providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update();
 +	    IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR);
 +	    update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT);
 +	    registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter);
 +	    
          ConfigHelper.setSharedPreferences(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE));
          loadPreseededProviders();
 @@ -115,6 +127,12 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn          // TODO: If exposing deep links into your app, handle intents here.
      }
 +	@Override
 +	protected void onDestroy() {
 +		super.onDestroy();
 +		unregisterReceiver(providerAPI_broadcast_receiver_update);
 +	}
 +
      public void refreshProviderList(int top_padding) {
      	ProviderListFragment new_provider_list_fragment = new ProviderListFragment();
  		Bundle top_padding_bundle = new Bundle();
 @@ -126,87 +144,29 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  		.replace(R.id.configuration_wizard_layout, new_provider_list_fragment, ProviderListFragment.TAG)
  		.commit();
      }
 -
 -	private void setProviderList(ProviderListFragment new_provider_list_fragment) {
 -		FragmentManager fragmentManager = getFragmentManager();
 -		fragmentManager.beginTransaction()
 -		.replace(R.id.configuration_wizard_layout, new_provider_list_fragment, ProviderListFragment.TAG)
 -		.commit();
 -	}
  	@Override
  	public void onReceiveResult(int resultCode, Bundle resultData) {
 -		if(resultCode == ProviderAPI.CORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
 -			JSONObject provider_json;
 -			try {
 -				provider_json = new JSONObject(resultData.getString(Provider.KEY));
 -				boolean danger_on = resultData.getBoolean(ProviderItem.DANGER_ON);
 -				ConfigHelper.saveSharedPref(Provider.KEY, provider_json);
 -				ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on);
 -				ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
 +		if(resultCode == ProviderAPI.PROVIDER_OK) {
  				mConfigState.setAction(PROVIDER_SET);
 -				if(resultData.containsKey(Provider.NAME)) {
 -					String provider_id = resultData.getString(Provider.NAME);
 -					mSelectedProvider = getProvider(provider_id);
 -					provider_list_fragment.addItem(mSelectedProvider);
 -					ProviderListContent.removeItem(mSelectedProvider);
 -
 -					if(mSelectedProvider.custom)
 -						refreshProviderList(0);
 -					
 -					if(!mProgressBar.isShown()) {
 -						int provider_index = getProviderIndex(provider_id);
 -						startProgressBar(provider_index);
 -						provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG);
 -						provider_list_fragment.hide(provider_index-2);
 -						//setProviderList(provider_list_fragment);
 -					}
 +				if (ConfigHelper.getBoolFromSharedPref(EIP.ALLOWED_ANON)){
 +					mConfigState.putExtra(SERVICES_RETRIEVED, true);
 +					downloadAnonCert();
 +				} else {
  					mProgressBar.incrementProgressBy(1);
 -				}
 -
 -				downloadJSONFiles(mSelectedProvider);
 -			} catch (JSONException e) {
 -				// TODO Auto-generated catch block
 -				e.printStackTrace();
 -			    mProgressBar.setVisibility(ProgressBar.GONE);
 -			    progressbar_description.setVisibility(TextView.GONE);
 -				refreshProviderList(0);
 -				//Toast.makeText(this, getResources().getString(R.string.config_error_parsing), Toast.LENGTH_LONG);
 -				setResult(RESULT_CANCELED, mConfigState);
 -			}
 -		}
 -		else if(resultCode == ProviderAPI.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
 -			String reason_to_fail = resultData.getString(ProviderAPI.ERRORS);
 -			showDownloadFailedDialog(getCurrentFocus(), reason_to_fail);
 -			refreshProviderList(0);
 -			mProgressBar.setVisibility(ProgressBar.GONE);
 -		    progressbar_description.setVisibility(TextView.GONE);
 -			setResult(RESULT_CANCELED, mConfigState);
 -		}
 -		else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_JSON_FILES) {
 -			mProgressBar.incrementProgressBy(1);
 -			if (ConfigHelper.getBoolFromSharedPref(EIP.ALLOWED_ANON)){
 -				mConfigState.putExtra(SERVICES_RETRIEVED, true);
 -				downloadAnonCert();
 -			} else {
 -				mProgressBar.incrementProgressBy(1);
 -			    mProgressBar.setVisibility(ProgressBar.GONE);
 -			    progressbar_description.setVisibility(TextView.GONE);
 -			    refreshProviderList(0);
 -				//Toast.makeText(getApplicationContext(), R.string.success, Toast.LENGTH_LONG).show();
 -				setResult(RESULT_OK);
 -				showProviderDetails(getCurrentFocus());
 -			}
 -		}
 -		else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_JSON_FILES) {
 -			//Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_json_files_message, Toast.LENGTH_LONG).show();
 +				    mProgressBar.setVisibility(ProgressBar.GONE);
 +				    progressbar_description.setVisibility(TextView.GONE);
 +					setResult(RESULT_OK);
 +					showProviderDetails(getCurrentFocus());
 +				} +		} else if(resultCode == ProviderAPI.PROVIDER_NOK) {
 +			//refreshProviderList(0);  			String reason_to_fail = resultData.getString(ProviderAPI.ERRORS);
  			showDownloadFailedDialog(getCurrentFocus(), reason_to_fail);
 -			refreshProviderList(0);
 -			//Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_json_files_message, 
  			mProgressBar.setVisibility(ProgressBar.GONE);
 -		    progressbar_description.setVisibility(TextView.GONE);
 +			progressbar_description.setVisibility(TextView.GONE);
 +			ConfigHelper.removeFromSharedPref(Provider.KEY);  			setResult(RESULT_CANCELED, mConfigState);
  		}
  		else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
 @@ -235,10 +195,15 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  	//	resetOldConnection();
  	    ProviderItem selected_provider = getProvider(id);
  	    int provider_index = getProviderIndex(id);
 -	    startProgressBar(provider_index);
 -	    mSelectedProvider = selected_provider;
 -	    
 -	    saveProviderJson(mSelectedProvider);
 + + +	    startProgressBar(provider_index+1); +	    provider_list_fragment.hideAllBut(provider_index); + +	    boolean danger_on = true; +	    if(ConfigHelper.sharedPrefContainsKey(ProviderItem.DANGER_ON)) +		danger_on = ConfigHelper.getBoolFromSharedPref(ProviderItem.DANGER_ON); +	    setUpProvider(selected_provider.providerMainUrl(), danger_on);      }
      @Override
 @@ -261,16 +226,34 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  		setResult(RESULT_CANCELED, ask_quit);
      }
 -    private ProviderItem getProvider(String id) {
 +    private ProviderItem getProvider(String name) {
  	    Iterator<ProviderItem> providers_iterator = ProviderListContent.ITEMS.iterator();
  	    while(providers_iterator.hasNext()) {
  		    ProviderItem provider = providers_iterator.next();
 -		    if(provider.id.equalsIgnoreCase(id)) {
 +		    if(provider.name().equalsIgnoreCase(name)) {
  			    return provider;
  		    }
  	    }
  	    return null;
      }
 +    
 +    private String getId(String provider_main_url) {
 +	    Iterator<ProviderItem> providers_iterator = ProviderListContent.ITEMS.iterator();
 +	    while(providers_iterator.hasNext()) {
 +		    ProviderItem provider = providers_iterator.next();
 +		    if(provider.providerMainUrl().equalsIgnoreCase(provider_main_url)) {
 +			    return provider.name();
 +		    }
 +	    }
 +	    return "";
 +    }
 + +	
 +	private void startProgressBar() {
 +	    mProgressBar.setVisibility(ProgressBar.VISIBLE);
 +	    mProgressBar.setProgress(0);
 +	    mProgressBar.setMax(3);
 +	}
  	private void startProgressBar(int list_item_index) {
  	    mProgressBar.setVisibility(ProgressBar.VISIBLE);
 @@ -287,10 +270,14 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  	    Iterator<ProviderItem> providers_iterator = ProviderListContent.ITEMS.iterator();
  	    while(providers_iterator.hasNext()) {
  		    ProviderItem provider = providers_iterator.next();
 -		    index++;
 -		    if(provider.id.equalsIgnoreCase(id)) {
 +		    if(provider.name().equalsIgnoreCase(id)) {
  			    break;
 -		    }
 +//<<<<<<< HEAD +//		    }
 +//		    index++;
 +//======= +		    } else index++;
 +//>>>>>>> bug/more-detailed-response-to-CW-errors  	    }
  	    return index;
      }
 @@ -333,7 +320,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  	        	boolean custom = false;
  	        	provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString();
  	        	if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list
 -	        		ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath), custom, false));
 +	        		ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath)));  	        	loaded_preseeded_providers = true;
  	        }
  		} catch (IOException e) {
 @@ -342,59 +329,6 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  		return loaded_preseeded_providers;
  	}
 -
 -    /**
 -     * Saves provider.json file associated with provider.
 -     * 
 -     * If the provider is custom, the file has already been downloaded so we load it from memory.
 -     * If not, the file is updated using the provider's URL.
 -     * @param provider
 -     */
 -    private void saveProviderJson(ProviderItem provider) {
 -    	JSONObject provider_json = new JSONObject();
 -    	try {
 -    		if(!provider.custom) {
 -    			updateProviderDotJson(provider.name, provider.provider_json_url, provider.danger_on);
 -    		} else {
 -    			// FIXME!! We should we be updating our seeded providers list at ConfigurationWizard onStart() ?
 -    			// I think yes, but if so, where does this list live? leap.se, as it's the non-profit project for the software?
 -    			// If not, we should just be getting names/urls, and fetching the provider.json like in custom entries
 -    			provider_json = provider.provider_json;
 -    			ConfigHelper.saveSharedPref(Provider.KEY, provider_json);
 -    			ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
 -    			ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, provider.danger_on);
 -
 -    			mProgressBar.incrementProgressBy(1);
 -    			downloadJSONFiles(mSelectedProvider);
 -    		}
 -    	} catch (JSONException e) {
 -    		setResult(RESULT_CANCELED);
 -    		finish();
 -    	}
 -    }
 -
 -    /**
 -     * Asks ProviderAPI to download provider site's certificate and eip-service.json
 -     * 
 -     * URLs are fetched from the provider parameter
 -     * @param provider from which certificate and eip-service.json files are going to be downloaded
 -     */
 -	private void downloadJSONFiles(ProviderItem provider) {
 -		Intent provider_API_command = new Intent(this, ProviderAPI.class);
 -		
 -		Bundle parameters = new Bundle();
 -		
 -		parameters.putString(Provider.KEY, provider.name);
 -		parameters.putString(Provider.CA_CERT, provider.cert_json_url);
 -		parameters.putString(EIP.KEY, provider.eip_service_json_url);
 -		parameters.putBoolean(ProviderItem.DANGER_ON, provider.danger_on);
 -		
 -		provider_API_command.setAction(ProviderAPI.DOWNLOAD_JSON_FILES_BUNDLE_EXTRA);
 -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
 -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
 -
 -		startService(provider_API_command);
 -	}
  	/**
  	 * Asks ProviderAPI to download an anonymous (anon) VPN certificate.
 @@ -429,6 +363,24 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  	}
  	/**
 +	 * Open the new provider dialog with data
 +	 */
 +	public void addAndSelectNewProvider(String main_url, boolean danger_on) {
 +		FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
 +		Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG);
 +		if (previous_new_provider_dialog != null) {
 +			fragment_transaction.remove(previous_new_provider_dialog);
 +		}
 +		
 +		DialogFragment newFragment = NewProviderDialog.newInstance();
 +		Bundle data = new Bundle();
 +		data.putString(Provider.MAIN_URL, main_url);
 +		data.putBoolean(ProviderItem.DANGER_ON, danger_on);
 +		newFragment.setArguments(data);
 +		newFragment.show(fragment_transaction, NewProviderDialog.TAG);
 +	}
 +	
 +	/**
  	 * Once selected a provider, this fragment offers the user to log in, 
  	 * use it anonymously (if possible) 
  	 * or cancel his/her election pressing the back button.
 @@ -465,43 +417,56 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  		newFragment.show(fragment_transaction, ProviderDetailFragment.TAG);
  	}
 -	@Override
 -	public void saveAndSelectProvider(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);
 -
 -		provider_API_command.setAction(ProviderAPI.DOWNLOAD_NEW_PROVIDER_DOTJSON);
 -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
 -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
 -		
 -		startService(provider_API_command);
 +	public void showAndSelectProvider(String provider_main_url, boolean danger_on) {
 +		showProvider(provider_main_url, danger_on);
 +		autoSelectProvider(provider_main_url, danger_on);
 +	}
 +	
 +	private void showProvider(final String provider_main_url, final boolean danger_on) {
 +		String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_");
 +		ProviderItem added_provider = new ProviderItem(provider_name, provider_main_url);
 +		provider_list_fragment.addItem(added_provider);
 +	}
 +	
 +	private void autoSelectProvider(String provider_main_url, boolean danger_on) {
 + +		ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on);
 +		onItemSelected(getId(provider_main_url));
  	}
  	/**
  	 * Asks ProviderAPI to download a new provider.json file
  	 * @param provider_name
 -	 * @param provider_json_url
 +	 * @param provider_main_url
  	 * @param danger_on tells if HTTPS client should bypass certificate errors
  	 */
 -	public void updateProviderDotJson(String provider_name, String provider_json_url, boolean danger_on) {
 -		
 -		
 +	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.NAME, provider_name);
 -		parameters.putString(Provider.DOT_JSON_URL, provider_json_url);
 +		parameters.putString(Provider.MAIN_URL, provider_main_url);
  		parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
 -		provider_API_command.setAction(ProviderAPI.UPDATE_PROVIDER_DOTJSON);
 +		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);
 -	}
 -
 + +		startService(provider_API_command); +	} + +	public void retrySetUpProvider() { +		cancelSettingUpProvider(); +		if(!ProviderAPI.caCertDownloaded()) { +			addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl(), ProviderAPI.lastDangerOn()); +		} else { +			Intent provider_API_command = new Intent(this, ProviderAPI.class); + +			provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER); +			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);
 @@ -544,6 +509,18 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  		if(provider_list_fragment != null)
  			provider_list_fragment.unhideAll();
  	}
 +	
 +	public void cancelSettingUpProvider() {
 +		provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG);
 +		if(provider_list_fragment != null && ConfigHelper.sharedPrefContainsKey(ProviderItem.DANGER_ON)) {
 +			provider_list_fragment.removeLastItem();
 +		}
 +
 +		ConfigHelper.removeFromSharedPref(Provider.KEY);
 +		ConfigHelper.removeFromSharedPref(ProviderItem.DANGER_ON);
 +		ConfigHelper.removeFromSharedPref(EIP.ALLOWED_ANON);
 +		ConfigHelper.removeFromSharedPref(EIP.KEY);
 +	}
  	@Override
  	public void login() {
 @@ -558,4 +535,13 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn  		setResult(RESULT_OK);
  		finish();
  	}
 +
 +	public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver {
 +
 +		@Override
 +		public void onReceive(Context context, Intent intent) {
 +			int update = intent.getIntExtra(ProviderAPI.CURRENT_PROGRESS, 0);
 +			mProgressBar.setProgress(update);
 +		}
 +	}
  }
 diff --git a/src/se/leap/bitmaskclient/Dashboard.java b/src/se/leap/bitmaskclient/Dashboard.java index 65ff2800..d37479a2 100644 --- a/src/se/leap/bitmaskclient/Dashboard.java +++ b/src/se/leap/bitmaskclient/Dashboard.java @@ -16,8 +16,6 @@   */   package se.leap.bitmaskclient; -import org.apache.http.cookie.Cookie; -import org.apache.http.impl.cookie.BasicClientCookie;  import org.json.JSONException;  import org.json.JSONObject; @@ -30,12 +28,9 @@ import android.app.DialogFragment;  import android.app.Fragment;  import android.app.FragmentManager;  import android.app.FragmentTransaction; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver;  import android.content.Context;  import android.content.DialogInterface;  import android.content.Intent; -import android.content.IntentFilter;  import android.content.SharedPreferences;  import android.os.Bundle;  import android.os.Handler; @@ -45,11 +40,7 @@ import android.view.Menu;  import android.view.MenuItem;  import android.view.View;  import android.view.ViewGroup; -import android.view.ViewStub; -import android.widget.CompoundButton;  import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.Switch;  import android.widget.TextView;  import android.widget.Toast; @@ -76,7 +67,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  	private ProgressBar mProgressBar;  	private TextView eipStatus; -	private ProviderAPIBroadcastReceiver_Update providerAPI_broadcast_receiver_update;  	private static Context app;  	private static SharedPreferences preferences;  	private static Provider provider; @@ -98,10 +88,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  	//    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);  	//	eipStatus = (TextView) findViewById(R.id.eipStatus); -	    providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update(); -	    IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_ACTION); -	    update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT); -	    registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter); +	    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);  		ConfigHelper.setSharedPreferences(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE));  		preferences = ConfigHelper.shared_preferences; @@ -116,7 +103,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  	@Override  	protected void onDestroy() {  		super.onDestroy(); -		unregisterReceiver(providerAPI_broadcast_receiver_update);  	}  	@Override @@ -126,6 +112,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  			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(); @@ -176,15 +163,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  		provider.init( this );  		setContentView(R.layout.client_dashboard); - -	    providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update(); -	    IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_ACTION); -	    update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT); -	    registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter);  		providerNameTV = (TextView) findViewById(R.id.providerName);  		providerNameTV.setText(provider.getDomain());  		providerNameTV.setTextSize(28); +		 +	    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);  		FragmentManager fragMan = getFragmentManager();  		if ( provider.hasEIP()){ @@ -243,6 +227,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  				}  				eipStop();  			} +			ConfigHelper.removeFromSharedPref(Provider.KEY);  			startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER);  			return true;  		case R.id.login_button: @@ -483,13 +468,4 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf  		startService(eip_intent);  	} -	 -	public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver { - -		@Override -		public void onReceive(Context context, Intent intent) { -			int update = intent.getIntExtra(ProviderAPI.UPDATE_DATA, 0); -			//mProgressBar.setProgress(update); -		} -	}  } diff --git a/src/se/leap/bitmaskclient/DownloadFailedDialog.java b/src/se/leap/bitmaskclient/DownloadFailedDialog.java index 3ce101a6..f78002b0 100644 --- a/src/se/leap/bitmaskclient/DownloadFailedDialog.java +++ b/src/se/leap/bitmaskclient/DownloadFailedDialog.java @@ -14,9 +14,12 @@   * You should have received a copy of the GNU General Public License   * along with this program. If not, see <http://www.gnu.org/licenses/>.   */ - package se.leap.bitmaskclient; +package se.leap.bitmaskclient;  import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; +import se.leap.bitmaskclient.ProviderListContent.ProviderItem; +import android.app.Activity;  import android.app.AlertDialog;  import android.app.Dialog;  import android.app.DialogFragment; @@ -42,18 +45,50 @@ public class DownloadFailedDialog extends DialogFragment {  		return dialog_fragment;  	} -    @Override +	@Override  	public Dialog onCreateDialog(Bundle savedInstanceState) {  		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); -		 +  		builder.setMessage(reason_to_fail) -		.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { +		.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() { +			public void onClick(DialogInterface dialog, int id) { +				dismiss(); +				interface_with_ConfigurationWizard.retrySetUpProvider(); +			} +		}) +		.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {  			public void onClick(DialogInterface dialog, int id) { +				interface_with_ConfigurationWizard.cancelSettingUpProvider();  				dialog.dismiss();  			}  		}); -			 +  		// Create the AlertDialog object and return it  		return builder.create();  	} + +	public interface DownloadFailedDialogInterface { +		public void retrySetUpProvider(); +		public void cancelSettingUpProvider(); +	} + +	DownloadFailedDialogInterface interface_with_ConfigurationWizard; + +	@Override +	public void onAttach(Activity activity) { +		super.onAttach(activity); +		try { +			interface_with_ConfigurationWizard = (DownloadFailedDialogInterface) activity; +		} catch (ClassCastException e) { +			throw new ClassCastException(activity.toString() +					+ " must implement NoticeDialogListener"); +		} +	} + +	@Override +	public void onCancel(DialogInterface dialog) { +		interface_with_ConfigurationWizard.cancelSettingUpProvider(); +		dialog.dismiss(); +	} +  } diff --git a/src/se/leap/bitmaskclient/EIP.java b/src/se/leap/bitmaskclient/EIP.java index ec2f6972..2b7fd39f 100644 --- a/src/se/leap/bitmaskclient/EIP.java +++ b/src/se/leap/bitmaskclient/EIP.java @@ -58,10 +58,10 @@ import android.util.Log;   */  public final class EIP extends IntentService { +	public final static String AUTHED_EIP = "authed eip";  	public final static String ACTION_START_EIP = "se.leap.bitmaskclient.START_EIP";  	public final static String ACTION_STOP_EIP = "se.leap.bitmaskclient.STOP_EIP";  	public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.bitmaskclient.UPDATE_EIP_SERVICE"; -	public final static String AUTHED_EIP = "authed_eip";  	public final static String ACTION_IS_EIP_RUNNING = "se.leap.bitmaskclient.IS_RUNNING";  	public final static String EIP_NOTIFICATION = "EIP_NOTIFICATION";  	public final static String ALLOWED_ANON = "allow_anonymous"; @@ -439,7 +439,8 @@ public final class EIP extends IntentService {  			String ports = "ports";  			String protos = "protocols";  			String capabilities = "capabilities"; -			String location = "location"; +			String location_key = "location"; +			String locations = "locations";  			Vector<String> arg = new Vector<String>();  			Vector<Vector<String>> args = new Vector<Vector<String>>(); @@ -456,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();  				} @@ -477,16 +477,22 @@ public final class EIP extends IntentService {  			arg.clear();  			args.clear(); +  			try { -				arg.add(location); -				arg.add(mGateway.getString(location)); +				 +				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; diff --git a/src/se/leap/bitmaskclient/EipServiceFragment.java b/src/se/leap/bitmaskclient/EipServiceFragment.java index e182b3fd..b409394b 100644 --- a/src/se/leap/bitmaskclient/EipServiceFragment.java +++ b/src/se/leap/bitmaskclient/EipServiceFragment.java @@ -202,7 +202,10 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli  						switchState = false;  					} else if (state.equals("NOPROCESS")){  						statusMessage = logmessage; -					} else { +					} else if (state.equals("ASSIGN_IP")){ //don't show assigning message in eipStatus +						statusMessage = (String) eipStatus.getText(); +					} +					else {  						statusMessage = prefix + " " + logmessage;  					} diff --git a/src/se/leap/bitmaskclient/LeapSRPSession.java b/src/se/leap/bitmaskclient/LeapSRPSession.java index 14a8bff2..0849f777 100644 --- a/src/se/leap/bitmaskclient/LeapSRPSession.java +++ b/src/se/leap/bitmaskclient/LeapSRPSession.java @@ -35,9 +35,12 @@ import org.jboss.security.srp.SRPParameters;   */  public class LeapSRPSession { +	private static String token = ""; +	  	final public static String SALT = "salt";  	final public static String M1 = "M1";  	final public static String M2 = "M2"; +	final public static String TOKEN = "token";  	private SRPParameters params;  	private String username; @@ -312,6 +315,14 @@ public class LeapSRPSession {  		boolean valid = Arrays.equals(M2, myM2);  		return valid;  	} +	 +	protected static void setToken(String token) { +		LeapSRPSession.token = token; +	} +	 +	protected static String getToken() { +		return token; +	}  	/**  	 * @return a new SHA-256 digest. diff --git a/src/se/leap/bitmaskclient/NewProviderDialog.java b/src/se/leap/bitmaskclient/NewProviderDialog.java index a0b8a763..cf09c64b 100644 --- a/src/se/leap/bitmaskclient/NewProviderDialog.java +++ b/src/se/leap/bitmaskclient/NewProviderDialog.java @@ -16,6 +16,7 @@   */   package se.leap.bitmaskclient; +import se.leap.bitmaskclient.ProviderListContent.ProviderItem;  import se.leap.bitmaskclient.R;  import android.app.Activity;  import android.app.AlertDialog; @@ -41,7 +42,7 @@ public class NewProviderDialog extends DialogFragment {      final public static String TAG = "newProviderDialog";  	public interface NewProviderDialogInterface { -        public void saveAndSelectProvider(String url_provider, boolean danger_on); +        public void showAndSelectProvider(String url_provider, boolean danger_on);      }  	NewProviderDialogInterface interface_with_ConfigurationWizard; @@ -71,7 +72,14 @@ public class NewProviderDialog extends DialogFragment {  		LayoutInflater inflater = getActivity().getLayoutInflater();  		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); +		if(getArguments() != null && getArguments().containsKey(Provider.MAIN_URL)) { +			url_input_field.setText(getArguments().getString(Provider.MAIN_URL)); +		}  		final CheckBox danger_checkbox = (CheckBox)new_provider_dialog_view.findViewById(R.id.danger_checkbox); +		if(getArguments() != null && getArguments().containsKey(ProviderItem.DANGER_ON)) { +			danger_checkbox.setActivated(getArguments().getBoolean(ProviderItem.DANGER_ON)); +		} +		  		builder.setView(new_provider_dialog_view)  			.setMessage(R.string.introduce_new_provider)  			.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() { @@ -85,7 +93,7 @@ public class NewProviderDialog extends DialogFragment {  					}  					boolean danger_on = danger_checkbox.isChecked();  					if(validURL(entered_url)) { -						interface_with_ConfigurationWizard.saveAndSelectProvider(entered_url, danger_on); +						interface_with_ConfigurationWizard.showAndSelectProvider(entered_url, danger_on);  						Toast.makeText(getActivity().getApplicationContext(), R.string.valid_url_entered, Toast.LENGTH_LONG).show();  					} else {  						url_input_field.setText(""); diff --git a/src/se/leap/bitmaskclient/Provider.java b/src/se/leap/bitmaskclient/Provider.java index f36e5946..598999fd 100644 --- a/src/se/leap/bitmaskclient/Provider.java +++ b/src/se/leap/bitmaskclient/Provider.java @@ -99,7 +99,7 @@ public final class Provider implements Serializable {  		preferences = activity.getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE);  		// Inflate our provider.json data  		try { -			definition = new JSONObject( preferences.getString("provider", "") ); +			definition = new JSONObject( preferences.getString(Provider.KEY, "") );  		} catch (JSONException e) {  			// TODO: handle exception diff --git a/src/se/leap/bitmaskclient/ProviderAPI.java b/src/se/leap/bitmaskclient/ProviderAPI.java index 871a20dd..ff6dd852 100644 --- a/src/se/leap/bitmaskclient/ProviderAPI.java +++ b/src/se/leap/bitmaskclient/ProviderAPI.java @@ -27,6 +27,7 @@ import java.net.CookieManager;  import java.net.CookiePolicy;  import java.net.MalformedURLException;  import java.net.SocketTimeoutException; +import java.net.URISyntaxException;  import java.net.URL;  import java.net.URLConnection;  import java.net.URLEncoder; @@ -36,6 +37,7 @@ import java.security.KeyStore;  import java.security.KeyStoreException;  import java.security.NoSuchAlgorithmException;  import java.security.SecureRandom; +import java.security.cert.CertificateEncodingException;  import java.security.cert.CertificateException;  import java.security.cert.X509Certificate;  import java.security.interfaces.RSAPrivateKey; @@ -57,7 +59,6 @@ import org.apache.http.client.ClientProtocolException;  import org.jboss.security.srp.SRPParameters;  import org.json.JSONException;  import org.json.JSONObject; -import org.json.JSONStringer;  import se.leap.bitmaskclient.R;  import se.leap.bitmaskclient.ProviderListContent.ProviderItem; @@ -68,8 +69,7 @@ import android.os.Handler;  import android.os.ResultReceiver;  import android.util.Base64;  import android.util.Log; -import android.widget.ProgressBar; -import android.widget.Toast; +  /**   * Implements HTTP api methods used to manage communications with the provider server. @@ -85,8 +85,7 @@ public class ProviderAPI extends IntentService {  	private Handler mHandler;      final public static String -    DOWNLOAD_JSON_FILES_BUNDLE_EXTRA = "downloadJSONFiles",	 -    UPDATE_PROVIDER_DOTJSON = "updateProviderDotJSON", +    SET_UP_PROVIDER = "setUpProvider",      DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON",      SRP_REGISTER = "srpRegister",      SRP_AUTH = "srpAuth", @@ -98,14 +97,13 @@ public class ProviderAPI extends IntentService {      SESSION_ID_COOKIE_KEY = "session_id_cookie_key",      SESSION_ID_KEY = "session_id",      ERRORS = "errors", -    UPDATE_ACTION = "update_action", -    UPDATE_DATA = "update data" +    UPDATE_PROGRESSBAR = "update_progressbar", +    CURRENT_PROGRESS = "current_progress", +    TAG = "provider_api_tag"      ;      final public static int      CUSTOM_PROVIDER_ADDED = 0, -    CORRECTLY_DOWNLOADED_JSON_FILES = 1, -    INCORRECTLY_DOWNLOADED_JSON_FILES = 2,      SRP_AUTHENTICATION_SUCCESSFUL = 3,      SRP_AUTHENTICATION_FAILED = 4,      SRP_REGISTRATION_SUCCESSFUL = 5, @@ -114,12 +112,21 @@ public class ProviderAPI extends IntentService {      LOGOUT_FAILED = 8,      CORRECTLY_DOWNLOADED_CERTIFICATE = 9,      INCORRECTLY_DOWNLOADED_CERTIFICATE = 10, -    CORRECTLY_UPDATED_PROVIDER_DOT_JSON = 11, -    INCORRECTLY_UPDATED_PROVIDER_DOT_JSON = 12, +    PROVIDER_OK = 11, +    PROVIDER_NOK = 12,      CORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 13,      INCORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 14      ; +    private static boolean  +    CA_CERT_DOWNLOADED = false, +    PROVIDER_JSON_DOWNLOADED = false, +    EIP_SERVICE_JSON_DOWNLOADED = false +    ; +     +    private static String last_provider_main_url; +    private static boolean last_danger_on = false; +      	public ProviderAPI() {  		super("ProviderAPI");  		Log.v("ClassName", "Provider API"); @@ -132,36 +139,30 @@ public class ProviderAPI extends IntentService {  		CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) );  	} +	public static String lastProviderMainUrl() { +		return last_provider_main_url; +	} +	 +    public static boolean lastDangerOn() { +    	return last_danger_on; +    } +      	private String formatErrorMessage(final int toast_string_id) {  		return "{ \"" + ERRORS + "\" : \""+getResources().getString(toast_string_id)+"\" }";  	}  	@Override  	protected void onHandleIntent(Intent command) { -		final ResultReceiver receiver = command.getParcelableExtra("receiver"); +		final ResultReceiver receiver = command.getParcelableExtra(RECEIVER_KEY);  		String action = command.getAction();  		Bundle parameters = command.getBundleExtra(PARAMETERS); -		if(action.equalsIgnoreCase(DOWNLOAD_JSON_FILES_BUNDLE_EXTRA)) { -			Bundle result = downloadJsonFiles(parameters); +		if(action.equalsIgnoreCase(SET_UP_PROVIDER)) { +			Bundle result = setUpProvider(parameters);  			if(result.getBoolean(RESULT_KEY)) { -				receiver.send(CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); -			} else { -				receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, result); -			} -		} else if(action.equalsIgnoreCase(UPDATE_PROVIDER_DOTJSON)) { -			Bundle result = updateProviderDotJSON(parameters); -			if(result.getBoolean(RESULT_KEY)) { -				receiver.send(CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); +				receiver.send(PROVIDER_OK, Bundle.EMPTY);  			} else {  -				receiver.send(INCORRECTLY_UPDATED_PROVIDER_DOT_JSON, Bundle.EMPTY); -			} -		} else if (action.equalsIgnoreCase(DOWNLOAD_NEW_PROVIDER_DOTJSON)) { -			Bundle result = downloadNewProviderDotJSON(parameters); -			if(result.getBoolean(RESULT_KEY)) { -				receiver.send(CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); -			} else { -				receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, result); +				receiver.send(PROVIDER_NOK, result);  			}  		} else if (action.equalsIgnoreCase(SRP_AUTH)) {  			Bundle session_id_bundle = authenticateBySRP(parameters); @@ -184,63 +185,6 @@ public class ProviderAPI extends IntentService {  			}  		}  	} - -	/** -	 * Downloads the main cert and the eip-service.json files given through the task parameter -	 * @param task -	 * @return true if eip-service.json was parsed as a JSON object correctly. -	 */ -	private Bundle downloadJsonFiles(Bundle task) { -		Bundle result = new Bundle(); -		String cert_url = task.getString(Provider.CA_CERT); -		String eip_service_json_url = task.getString(EIP.KEY); -		boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); -		try { -			String cert_string = downloadWithCommercialCA(cert_url, danger_on); - -			if(ConfigHelper.checkErroneousDownload(cert_string)) { -				JSONObject possible_errors = new JSONObject(cert_string); -				String reason_to_fail = ""; -				if(cert_string.isEmpty()) -					reason_to_fail = "Empty certificate downloaded"; -				else -				reason_to_fail = possible_errors.getString(ERRORS); -				result.putString(ERRORS, reason_to_fail); -				result.putBoolean(RESULT_KEY, false); -			} else { -				X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string); -				cert_string = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); -				ConfigHelper.saveSharedPref(Provider.CA_CERT, "-----BEGIN CERTIFICATE-----\n"+cert_string+"-----END CERTIFICATE-----"); -			} -		} catch (JSONException e) { -			e.printStackTrace(); -			result.putBoolean(RESULT_KEY, false); -		} catch (CertificateException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			result.putBoolean(RESULT_KEY, false); -		} - -		try { -			String eip_service_string = downloadWithCommercialCA(eip_service_json_url, danger_on); -			JSONObject eip_service_json = new JSONObject(eip_service_string); -			if(eip_service_json.has(ERRORS)) { -				String reason_to_fail = eip_service_json.getString(ERRORS); -				result.putString(ERRORS, reason_to_fail); -				result.putBoolean(RESULT_KEY, false); -			} -			else { -				ConfigHelper.saveSharedPref(EIP.KEY, eip_service_json); -				ConfigHelper.saveSharedPref(EIP.PARSED_SERIAL, 0); -			} - -			result.putBoolean(RESULT_KEY, true); -		} catch (JSONException e) { -			result.putBoolean(RESULT_KEY, false); -		} -		 -		return result; -	}  	/**  	 * Starts the authentication process using SRP protocol. @@ -339,9 +283,9 @@ public class ProviderAPI extends IntentService {  	 */  	private void broadcast_progress(int progress) {  		Intent intentUpdate = new Intent(); -		intentUpdate.setAction(UPDATE_ACTION); +		intentUpdate.setAction(UPDATE_PROGRESSBAR);  		intentUpdate.addCategory(Intent.CATEGORY_DEFAULT); -		intentUpdate.putExtra(UPDATE_DATA, progress); +		intentUpdate.putExtra(CURRENT_PROGRESS, progress);  		sendBroadcast(intentUpdate);  	} @@ -416,6 +360,9 @@ public class ProviderAPI extends IntentService {  			session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName());  			session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue());*/  			session_idAndM2.put(LeapSRPSession.M2, ConfigHelper.trim(M2_not_trimmed)); +			CookieHandler.setDefault(null); // we don't need cookies anymore +			String token = json_response.getString(LeapSRPSession.TOKEN); +			LeapSRPSession.setToken(token);  		}  		return session_idAndM2;  	} @@ -487,89 +434,172 @@ public class ProviderAPI extends IntentService {  	    return result.toString();  	} +	 +	 +	 +	  	/**  	 * Downloads a provider.json from a given URL, adding a new provider using the given name.    	 * @param task containing a boolean meaning if the provider is custom or not, another boolean meaning if the user completely trusts this provider, the provider name and its provider.json url.  	 * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the update was successful.   	 */ -	private Bundle updateProviderDotJSON(Bundle task) { -		Bundle result = new Bundle(); -		boolean custom = task.getBoolean(ProviderItem.CUSTOM); -		boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); -		String provider_json_url = task.getString(Provider.DOT_JSON_URL); -		String provider_name = task.getString(Provider.NAME); +	private Bundle setUpProvider(Bundle task) { +//<<<<<<< HEAD +//		Bundle result = new Bundle(); +//		int progress = 0; +//		boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); +//		String provider_main_url = task.getString(Provider.MAIN_URL); +//		if(downloadCACert(provider_main_url, danger_on)) { +//			broadcast_progress(progress++); +//			result.putBoolean(RESULT_KEY, true); +//			if(getAndSetProviderJson(provider_main_url)) { +//				broadcast_progress(progress++); +//				if(getAndSetEipServiceJson()) +//					broadcast_progress(progress++); +//			} +//		} +//		return result; +//	} +//	 +//	 +//======= +		int progress = 0; +		Bundle current_download = new Bundle(); -		try { -			String provider_dot_json_string = downloadWithCommercialCA(provider_json_url, danger_on); -			if(provider_dot_json_string.isEmpty()) { -				result.putBoolean(RESULT_KEY, false); -			} else { -				JSONObject provider_json = new JSONObject(provider_dot_json_string); -				if(provider_json.has(ERRORS)) { -					String reason_to_fail = provider_json.getString(ERRORS); -					result.putString(ERRORS, reason_to_fail); -					result.putBoolean(RESULT_KEY, false); -				} else { -					ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)); +		if(task != null && task.containsKey(ProviderItem.DANGER_ON) && task.containsKey(Provider.MAIN_URL)) { +			last_danger_on = task.getBoolean(ProviderItem.DANGER_ON); +			last_provider_main_url = task.getString(Provider.MAIN_URL); +			CA_CERT_DOWNLOADED = PROVIDER_JSON_DOWNLOADED = EIP_SERVICE_JSON_DOWNLOADED = false; +		} -					//ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); -					result.putBoolean(RESULT_KEY, true); -					result.putString(Provider.KEY, provider_json.toString()); -					result.putBoolean(ProviderItem.DANGER_ON, danger_on); +		if(!CA_CERT_DOWNLOADED) +			current_download = downloadCACert(last_provider_main_url, last_danger_on); +		if(CA_CERT_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { +			broadcast_progress(progress++); +			CA_CERT_DOWNLOADED = true; +			if(!PROVIDER_JSON_DOWNLOADED) +				current_download = getAndSetProviderJson(last_provider_main_url);  +			if(PROVIDER_JSON_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { +				broadcast_progress(progress++); +				PROVIDER_JSON_DOWNLOADED = true; +				current_download = getAndSetEipServiceJson();  +				if(current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY)) { +					broadcast_progress(progress++); +					EIP_SERVICE_JSON_DOWNLOADED = true;  				}  			} -		} catch (JSONException e) { +		} +		 +		return current_download; +	} +	 +	private Bundle downloadCACert(String provider_main_url, boolean danger_on) { +		Bundle result = new Bundle(); +		String cert_string = downloadWithCommercialCA(provider_main_url + "/ca.crt", danger_on); +		if(validCertificate(cert_string)) { +			ConfigHelper.saveSharedPref(Provider.CA_CERT, cert_string); +			result.putBoolean(RESULT_KEY, true); +		} else { +			String reason_to_fail = pickErrorMessage(cert_string); +			result.putString(ERRORS, reason_to_fail);  			result.putBoolean(RESULT_KEY, false);  		}  		return result;  	} +	 -	/** -	 * Downloads a custom provider provider.json file -	 * @param task containing a boolean meaning if the user completely trusts this provider, and the provider main url entered in the new custom provider dialog. -	 * @return true if provider.json file was successfully parsed as a JSON object. -	 */ -	private Bundle downloadNewProviderDotJSON(Bundle task) { -		Bundle result = new Bundle(); -		boolean custom = true; -		boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); -		 -		String provider_main_url = (String) task.get(Provider.MAIN_URL); -		String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); -		String provider_json_url = guessProviderDotJsonURL(provider_main_url); +	public static boolean caCertDownloaded() { +		return CA_CERT_DOWNLOADED; +	} + +	private boolean validCertificate(String cert_string) { +		boolean result = false; +		if(!ConfigHelper.checkErroneousDownload(cert_string)) { +			X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string); +			try { +				Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); +				result = true; +			} catch (CertificateEncodingException e) { +				Log.d(TAG, e.getLocalizedMessage()); +			} +		} -		String provider_json_string = downloadWithCommercialCA(provider_json_url, danger_on); +		return result; +	} +	 +	private Bundle getAndSetProviderJson(String provider_main_url) { +		Bundle result = new Bundle(); + +		String provider_dot_json_string = downloadWithProviderCA(provider_main_url + "/provider.json", true); +  		try { -			if(provider_json_string.isEmpty()) { -				result.putBoolean(RESULT_KEY, false); -			} else { -				JSONObject provider_json = new JSONObject(provider_json_string); +			JSONObject provider_json = new JSONObject(provider_dot_json_string); +			String name = provider_json.getString(Provider.NAME); +			//TODO setProviderName(name); +			 +			ConfigHelper.saveSharedPref(Provider.KEY, provider_json); +			ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)); -				if(provider_json.has(ERRORS)) { -					String reason_to_fail = provider_json.getString(ERRORS); -					result.putString(ERRORS, reason_to_fail); -					result.putBoolean(RESULT_KEY, false); -				} else { -					ConfigHelper.saveSharedPref(Provider.KEY, provider_json); -					ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on); -					ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)); -					ProviderItem added_provider = new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on); -					ProviderListContent.addItem(added_provider); - -					result.putString(Provider.NAME, added_provider.getName()); -					result.putBoolean(RESULT_KEY, true); -					result.putString(Provider.KEY, provider_json.toString()); -					result.putBoolean(ProviderItem.DANGER_ON, danger_on); -				} -			} +			result.putBoolean(RESULT_KEY, true);  		} catch (JSONException e) { +			//TODO Error message should be contained in that provider_dot_json_string +			String reason_to_fail = pickErrorMessage(provider_dot_json_string); +			result.putString(ERRORS, reason_to_fail); +			result.putBoolean(RESULT_KEY, false); +		} +		return result; +	} + + +	 +	public static boolean providerJsonDownloaded() { +		return PROVIDER_JSON_DOWNLOADED; +	} + +	private Bundle getAndSetEipServiceJson() { +		Bundle result = new Bundle(); +		String eip_service_json_string = ""; +		try { +			JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); +			String eip_service_url = provider_json.getString(Provider.API_URL) +  "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH; +			eip_service_json_string = downloadWithProviderCA(eip_service_url, true); +			JSONObject eip_service_json = new JSONObject(eip_service_json_string); +			eip_service_json.getInt(Provider.API_RETURN_SERIAL); + +			ConfigHelper.saveSharedPref(EIP.KEY, eip_service_json); + +			result.putBoolean(RESULT_KEY, true); +		} catch (JSONException e) { +			String reason_to_fail = pickErrorMessage(eip_service_json_string); +			result.putString(ERRORS, reason_to_fail);  			result.putBoolean(RESULT_KEY, false); -			result.putString(ERRORS, "Corrupt download");  		} -		  		return result;  	} + +	public static boolean eipServiceDownloaded() { +		return EIP_SERVICE_JSON_DOWNLOADED; +	} +	 +	/** +	 * Interprets the error message as a JSON object and extract the "errors" keyword pair. +	 * If the error message is not a JSON object, then it is returned untouched. +	 * @param string_json_error_message +	 * @return final error message +	 */ +	private String pickErrorMessage(String string_json_error_message) { +		String error_message = ""; +		try { +			JSONObject json_error_message = new JSONObject(string_json_error_message); +			error_message = json_error_message.getString(ERRORS); +		} catch (JSONException e) { +			// TODO Auto-generated catch block +			error_message = string_json_error_message; +		} +		 +		return error_message; +	}  	/**  	 * Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider. @@ -589,6 +619,8 @@ public class ProviderAPI extends IntentService {  			provider_url = new URL(string_url);  			URLConnection url_connection = provider_url.openConnection();  			url_connection.setConnectTimeout(seconds_of_timeout*1000); +			if(!LeapSRPSession.getToken().isEmpty()) +				url_connection.addRequestProperty(LeapSRPSession.TOKEN, LeapSRPSession.getToken());  			json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next();  		} catch (MalformedURLException e) {  			json_file_content = formatErrorMessage(R.string.malformed_url); @@ -596,13 +628,13 @@ public class ProviderAPI extends IntentService {  			json_file_content = formatErrorMessage(R.string.server_is_down_message);  		} catch (IOException e) {  			if(provider_url != null) { -				json_file_content = downloadWithProviderCA(provider_url, danger_on); +				json_file_content = downloadWithProviderCA(string_url, danger_on);  			} else {  				json_file_content = formatErrorMessage(R.string.certificate_error);  			}  		} catch (Exception e) {  			if(provider_url != null && danger_on) { -				json_file_content = downloadWithProviderCA(provider_url, danger_on); +				json_file_content = downloadWithProviderCA(string_url, danger_on);  			}  		} @@ -610,19 +642,22 @@ public class ProviderAPI extends IntentService {  	}  	/** -	 * Tries to download the contents of the provided url using not commercially validated CA certificate from chosen provider. -	 * @param url +	 * Tries to download the contents of the provided url using not commercially validated CA certificate from chosen provider.  +	 * @param url as a string  	 * @param danger_on true to download CA certificate in case it has not been downloaded.  	 * @return an empty string if it fails, the url content if not.   	 */ -	private String downloadWithProviderCA(URL url, boolean danger_on) { +	private String downloadWithProviderCA(String url_string, boolean danger_on) {  		String json_file_content = "";  		try { +			URL url = new URL(url_string);  			// Tell the URLConnection to use a SocketFactory from our SSLContext  			HttpsURLConnection urlConnection =  					(HttpsURLConnection)url.openConnection();  			urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); +			if(!LeapSRPSession.getToken().isEmpty()) +				urlConnection.addRequestProperty(LeapSRPSession.TOKEN, LeapSRPSession.getToken());  			json_file_content = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next();  		} catch (CertificateException e) {  			// TODO Auto-generated catch block @@ -632,7 +667,7 @@ public class ProviderAPI extends IntentService {  		} catch (IOException e) {  			// The downloaded certificate doesn't validate our https connection.  			if(danger_on) { -				json_file_content = downloadWithoutCA(url); +				json_file_content = downloadWithoutCA(url_string);  			} else {  				json_file_content = formatErrorMessage(R.string.certificate_error);  			} @@ -675,7 +710,7 @@ public class ProviderAPI extends IntentService {  	/**  	 * Downloads the string that's in the url with any certificate.  	 */ -	private String downloadWithoutCA(URL url) { +	private String downloadWithoutCA(String url_string) {  		String string = "";  		try { @@ -703,6 +738,7 @@ public class ProviderAPI extends IntentService {  			SSLContext context = SSLContext.getInstance("TLS");  			context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); +			URL url = new URL(url_string);  			HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();  			urlConnection.setSSLSocketFactory(context.getSocketFactory());  			urlConnection.setHostnameVerifier(hostnameVerifier); @@ -724,15 +760,6 @@ public class ProviderAPI extends IntentService {  		}  		return string;  	} - -	/** -	 * Tries to guess the provider.json url given the main provider url. -	 * @param provider_main_url -	 * @return the guessed provider.json url -	 */ -	private String guessProviderDotJsonURL(String provider_main_url) { -		return provider_main_url + "/provider.json"; -	}  	/**  	 * Logs out from the api url retrieved from the task. @@ -750,6 +777,7 @@ public class ProviderAPI extends IntentService {  			int responseCode = urlConnection.getResponseCode();  			broadcast_progress(progress++); +			LeapSRPSession.setToken("");  			Log.d("logout", Integer.toString(responseCode));  		} catch (ClientProtocolException e) {  			// TODO Auto-generated catch block @@ -790,11 +818,13 @@ public class ProviderAPI extends IntentService {  		try {  			String type_of_certificate = task.getString(ConfigurationWizard.TYPE_OF_CERTIFICATE);  			JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); -			URL provider_main_url = new URL(provider_json.getString(Provider.API_URL)); -			String new_cert_string_url = provider_main_url.toString() + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE; +			String provider_main_url = provider_json.getString(Provider.API_URL); +			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); -			String cert_string = downloadWithCommercialCA(new_cert_string_url, danger_on); + +			String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), danger_on); +  			if(!cert_string.isEmpty()) {  				if(ConfigHelper.checkErroneousDownload(cert_string)) {  					String reason_to_fail = provider_json.getString(ERRORS); diff --git a/src/se/leap/bitmaskclient/ProviderListAdapter.java b/src/se/leap/bitmaskclient/ProviderListAdapter.java index 19c4f72c..c5e8b64d 100644 --- a/src/se/leap/bitmaskclient/ProviderListAdapter.java +++ b/src/se/leap/bitmaskclient/ProviderListAdapter.java @@ -10,7 +10,6 @@ import android.widget.ArrayAdapter;  import android.widget.TwoLineListItem;  public class ProviderListAdapter<T> extends ArrayAdapter<T> { -	private T[] items = null;  	private static boolean[] hidden = null;  	public void hide(int position) { @@ -42,7 +41,7 @@ public class ProviderListAdapter<T> extends ArrayAdapter<T> {  	}  	private int getHiddenCount() {  		int count = 0; -		for(int i=0;i<items.length;i++) +		for(int i=0;i<hidden.length;i++)  			if(hidden[i])  				count++;  		return count; @@ -58,25 +57,23 @@ public class ProviderListAdapter<T> extends ArrayAdapter<T> {  	@Override  	public int getCount() { -		return (items.length - getHiddenCount()); +		return (hidden.length - getHiddenCount());  	}  	public ProviderListAdapter(Context mContext, int layout, List<T> objects) {  		super(mContext, layout, objects); -		items = objects.toArray((T[])new Object[0]);  		if(hidden == null) { -			hidden = new boolean[items.length]; -			for (int i = 0; i < items.length; i++) +			hidden = new boolean[objects.size()]; +			for (int i = 0; i < objects.size(); i++)  				hidden[i] = false;  		}  	}  	public ProviderListAdapter(Context mContext, int layout, List<T> objects, boolean show_all_providers) {  		super(mContext, layout, objects); -		items = objects.toArray((T[])new Object[0]);  		if(show_all_providers) { -			hidden = new boolean[items.length]; -			for (int i = 0; i < items.length; i++) +			hidden = new boolean[objects.size()]; +			for (int i = 0; i < objects.size(); i++)  				hidden[i] = false;  		}  	} @@ -89,6 +86,14 @@ public class ProviderListAdapter<T> extends ArrayAdapter<T> {  		new_hidden[hidden.length] = false;  		hidden = new_hidden;  	} +	 +	@Override +	public void remove(T item) { +		super.remove(item); +		boolean[] new_hidden = new boolean[hidden.length-1]; +		System.arraycopy(hidden, 0, new_hidden, 0, hidden.length-1); +		hidden = new_hidden; +	}  	@Override  	public View getView(int index, View convertView, ViewGroup parent) { @@ -101,8 +106,8 @@ public class ProviderListAdapter<T> extends ArrayAdapter<T> {  			row = (TwoLineListItem)convertView;  		}  		ProviderListContent.ProviderItem data = ProviderListContent.ITEMS.get(position); -		row.getText1().setText(data.domain); -		row.getText2().setText(data.name); +		row.getText1().setText(data.domain()); +		row.getText2().setText(data.name());  		return row;  	} diff --git a/src/se/leap/bitmaskclient/ProviderListContent.java b/src/se/leap/bitmaskclient/ProviderListContent.java index 75d91733..e1ca4f9a 100644 --- a/src/se/leap/bitmaskclient/ProviderListContent.java +++ b/src/se/leap/bitmaskclient/ProviderListContent.java @@ -55,23 +55,12 @@ public class ProviderListContent {  	/**
  	 * A provider item.
 -	 */
 +	 */  	public static class ProviderItem {
 -
 -	    
  		final public static String CUSTOM = "custom";
  		final public static String DANGER_ON = "danger_on";
 -	    
 -		public boolean custom = false;
 -		public String id;
 -		public String name;
 -		public String domain;
 -		public String provider_json_url;
 -		public JSONObject provider_json;
 -		public String provider_json_filename;
 -		public String eip_service_json_url;
 -		public String cert_json_url;
 -		public boolean danger_on = false;
 +		private String provider_main_url;
 +		private String name;  		/**
  		 * @param name of the provider
 @@ -79,25 +68,15 @@ public class ProviderListContent {  		 * @param custom if it's a new provider entered by the user or not
  		 * @param danger_on if the user trusts completely the new provider
  		 */
 -		public ProviderItem(String name, InputStream urls_file_input_stream, boolean custom, boolean danger_on) {
 +		public ProviderItem(String name, InputStream urls_file_input_stream) {
  			try {
  				byte[] urls_file_bytes = new byte[urls_file_input_stream.available()];
  				urls_file_input_stream.read(urls_file_bytes);
  				String urls_file_content = new String(urls_file_bytes);
 -				JSONObject file_contents = new JSONObject(urls_file_content);
 -				id = name;
 +				JSONObject file_contents = new JSONObject(urls_file_content); +				provider_main_url = file_contents.getString(Provider.MAIN_URL);
  				this.name = name;
 -				provider_json_url = file_contents.getString(Provider.DOT_JSON_URL);
 -				domain = new URL(provider_json_url).getHost();
 -				//provider_json_filename = file_contents.getString("assets_json_provider");
 -				eip_service_json_url = file_contents.getString("json_eip_service");
 -				cert_json_url = file_contents.getString(EIP.CERTIFICATE);
 -				this.custom = custom;
 -				this.danger_on = danger_on;
 -			} catch (MalformedURLException e) {
 -				// TODO Auto-generated catch block
 -				e.printStackTrace();
  			} catch (JSONException e) {
  				// TODO Auto-generated catch block
  				e.printStackTrace();
 @@ -109,42 +88,25 @@ public class ProviderListContent {  		/**
  		 * @param name of the provider
 -		 * @param provider_json_url used to download provider.json file of the provider
 +		 * @param provider_main_url used to download provider.json file of the provider
  		 * @param provider_json already downloaded
  		 * @param custom if it's a new provider entered by the user or not
 -		 * @param danger_on if the user trusts completely the new provider
 -		 */
 -		public ProviderItem(String name, String provider_json_url, JSONObject provider_json, boolean custom, boolean danger_on) {
 -
 +		 */ +		public ProviderItem(String name, String provider_main_url) {
 +			this.name = name;
 +			this.provider_main_url = provider_main_url; +		}
 +		
 +		public String name() { return name; }
 +		
 +		public String providerMainUrl() { return provider_main_url; }
 +		
 +		public String domain() {
  			try {
 -				id = name;
 -				//this.name = name;
 -				this.provider_json_url = provider_json_url;
 -				this.provider_json = provider_json;
 -				this.name = provider_json.getJSONObject("name").getString("en");
 -				domain = new URL(provider_json_url).getHost();
 -				eip_service_json_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
 -				cert_json_url = provider_json.getString("ca_cert_uri");
 -				this.custom = custom;
 -				this.danger_on = danger_on;
 -				if(custom)
 -					provider_json_filename = name + "_provider.json".replaceFirst("__", "_");
 +				return new URL(provider_main_url).getHost();
  			} catch (MalformedURLException e) {
 -				// TODO Auto-generated catch block
 -				e.printStackTrace();
 -			} catch (JSONException e) {
 -				// TODO Auto-generated catch block
 -				e.printStackTrace();
 +				return provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("/.*", "");
  			}
  		}
 -
 -		@Override
 -		public String toString() {
 -			return name;
 -		}
 -
 -		public String getName() {
 -			return id;
 -		}
  	}
  }
 diff --git a/src/se/leap/bitmaskclient/ProviderListFragment.java b/src/se/leap/bitmaskclient/ProviderListFragment.java index 84d46a11..45047982 100644 --- a/src/se/leap/bitmaskclient/ProviderListFragment.java +++ b/src/se/leap/bitmaskclient/ProviderListFragment.java @@ -19,7 +19,6 @@  import se.leap.bitmaskclient.R;
  import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
  import android.app.Activity;
 -import android.app.DialogFragment;
  import android.app.ListFragment;
  import android.os.Bundle;
  import android.view.LayoutInflater;
 @@ -155,8 +154,8 @@ 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).id);
 -        
 +        mCallbacks.onItemSelected(ProviderListContent.ITEMS.get(position).name());
 +
          for(int item_position = 0; item_position < listView.getCount(); item_position++) {
          	if(item_position != position)
          		content_adapter.hide(item_position);
 @@ -172,6 +171,9 @@ public class ProviderListFragment extends ListFragment {          }
      }
 +    public void notifyAdapter() {
 +    	content_adapter.notifyDataSetChanged();
 +    }
      /**
       * Turns on activate-on-click mode. When this mode is on, list items will be
       * given the 'activated' state when touched.
 @@ -194,12 +196,27 @@ public class ProviderListFragment extends ListFragment {          mActivatedPosition = position;
      }
 +    public void removeLastItem() {
 +    	unhideAll();
 +    	content_adapter.remove(content_adapter.getItem(content_adapter.getCount()-1));
 +    	content_adapter.notifyDataSetChanged();
 +    }
 +    
      public void addItem(ProviderItem provider) {
      	content_adapter.add(provider);
 +    	content_adapter.notifyDataSetChanged();
      }
 -    public void hide(int position) {
 -    	content_adapter.hide(position);
 +    public void hideAllBut(int position) {
 +    	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++;
 +    		}      }
      public void unhideAll() {
 diff --git a/src/se/leap/openvpn/OpenVpnService.java b/src/se/leap/openvpn/OpenVpnService.java index 69dd56f4..b5c9c798 100644 --- a/src/se/leap/openvpn/OpenVpnService.java +++ b/src/se/leap/openvpn/OpenVpnService.java @@ -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); @@ -482,6 +482,8 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  			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);  | 
