summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java196
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java5
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java39
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java122
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java52
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Constants.java25
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Dashboard.java135
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipFragment.java216
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivity.java67
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java7
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Provider.java131
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java16
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderAPICommand.java68
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java364
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java58
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java128
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/StartActivity.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java43
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java33
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java66
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java179
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java31
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java184
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java35
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java260
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java2
28 files changed, 1142 insertions, 1336 deletions
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
index 8ca971e0..83a3044e 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
@@ -48,13 +48,11 @@ import okhttp3.OkHttpClient;
import se.leap.bitmaskclient.eip.EIP;
import static android.text.TextUtils.isEmpty;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.DownloadFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
import static se.leap.bitmaskclient.ProviderAPI.ERRORS;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY;
import static se.leap.bitmaskclient.R.string.certificate_error;
import static se.leap.bitmaskclient.R.string.malformed_url;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
@@ -64,6 +62,9 @@ import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
*/
public class ProviderApiManager extends ProviderApiManagerBase {
+
+ private static final String TAG = ProviderApiManagerBase.class.getName();
+
protected static boolean lastDangerOn = true;
@@ -79,83 +80,58 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* 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.
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if the update was successful.
*/
@Override
- protected Bundle setUpProvider(Bundle task) {
- int progress = 0;
+ protected Bundle setUpProvider(Provider provider, Bundle task) {
Bundle currentDownload = new Bundle();
if (task != null) {
lastDangerOn = task.containsKey(ProviderListContent.ProviderItem.DANGER_ON) && task.getBoolean(ProviderListContent.ProviderItem.DANGER_ON);
- lastProviderMainUrl = task.containsKey(Provider.MAIN_URL) ?
- task.getString(Provider.MAIN_URL) :
- "";
-
- if (isEmpty(lastProviderMainUrl)) {
- setErrorResult(currentDownload, malformed_url, null);
- return currentDownload;
- }
-
- providerCaCertFingerprint = task.containsKey(Provider.CA_CERT_FINGERPRINT) ?
- task.getString(Provider.CA_CERT_FINGERPRINT) :
- "";
- providerCaCert = task.containsKey(Provider.CA_CERT) ?
- task.getString(Provider.CA_CERT) :
- "";
+ }
- try {
- providerDefinition = task.containsKey(Provider.KEY) ?
- new JSONObject(task.getString(Provider.KEY)) :
- new JSONObject();
- } catch (JSONException e) {
- e.printStackTrace();
- providerDefinition = new JSONObject();
- }
- providerApiUrl = getApiUrlWithVersion(providerDefinition);
+ if (isEmpty(provider.getMainUrlString()) || provider.getMainUrl().isDefault()) {
+ setErrorResult(currentDownload, malformed_url, null);
+ currentDownload.putParcelable(PROVIDER_KEY, provider);
+ return currentDownload;
+ }
- checkPersistedProviderUpdates();
- currentDownload = validateProviderDetails();
+ getPersistedProviderUpdates(provider);
+ currentDownload = validateProviderDetails(provider);
- //provider details invalid
- if (currentDownload.containsKey(ERRORS)) {
- return currentDownload;
- }
-
- //no provider certificate available
- if (currentDownload.containsKey(RESULT_KEY) && !currentDownload.getBoolean(RESULT_KEY)) {
- resetProviderDetails();
- }
+ //provider details invalid
+ if (currentDownload.containsKey(ERRORS)) {
+ currentDownload.putParcelable(PROVIDER_KEY, provider);
+ return currentDownload;
+ }
- EIP_SERVICE_JSON_DOWNLOADED = false;
- go_ahead = true;
+ //no provider certificate available
+ if (currentDownload.containsKey(BROADCAST_RESULT_KEY) && !currentDownload.getBoolean(BROADCAST_RESULT_KEY)) {
+ resetProviderDetails(provider);
}
- if (!PROVIDER_JSON_DOWNLOADED)
- currentDownload = getAndSetProviderJson(lastProviderMainUrl, lastDangerOn, providerCaCert, providerDefinition);
- if (PROVIDER_JSON_DOWNLOADED || (currentDownload.containsKey(RESULT_KEY) && currentDownload.getBoolean(RESULT_KEY))) {
- broadcastProgress(progress++);
- PROVIDER_JSON_DOWNLOADED = true;
-
- if (!CA_CERT_DOWNLOADED)
- currentDownload = downloadCACert(lastDangerOn);
- if (CA_CERT_DOWNLOADED || (currentDownload.containsKey(RESULT_KEY) && currentDownload.getBoolean(RESULT_KEY))) {
- broadcastProgress(progress++);
- CA_CERT_DOWNLOADED = true;
- currentDownload = getAndSetEipServiceJson();
- if (currentDownload.containsKey(RESULT_KEY) && currentDownload.getBoolean(RESULT_KEY)) {
- broadcastProgress(progress++);
- EIP_SERVICE_JSON_DOWNLOADED = true;
- }
+ go_ahead = true;
+
+ if (!provider.hasDefinition())
+ currentDownload = getAndSetProviderJson(provider, lastDangerOn);
+ if (provider.hasDefinition() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) {
+ if (!provider.hasCaCert())
+ currentDownload = downloadCACert(provider, lastDangerOn);
+ if (provider.hasCaCert() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) {
+ currentDownload = getAndSetEipServiceJson(provider);
}
}
-
+ currentDownload.putParcelable(PROVIDER_KEY, provider);
return currentDownload;
}
- private Bundle getAndSetProviderJson(String providerMainUrl, boolean dangerOn, String caCert, JSONObject providerDefinition) {
+ private Bundle getAndSetProviderJson(Provider provider, boolean dangerOn) {
Bundle result = new Bundle();
+ JSONObject providerDefinition = provider.getDefinition();
+ String caCert = provider.getCaCert();
+ String providerMainUrl = provider.getMainUrlString();
+
if (go_ahead) {
String providerDotJsonString;
if(providerDefinition.length() == 0 || caCert.isEmpty())
@@ -165,56 +141,53 @@ public class ProviderApiManager extends ProviderApiManagerBase {
if (!isValidJson(providerDotJsonString)) {
result.putString(ERRORS, resources.getString(malformed_url));
- result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
return result;
}
try {
JSONObject providerJson = new JSONObject(providerDotJsonString);
- String providerDomain = getDomainFromMainURL(lastProviderMainUrl);
- providerApiUrl = getApiUrlWithVersion(providerJson);
- //String name = providerJson.getString(Provider.NAME);
- //TODO setProviderName(name);
-
- preferences.edit().putString(Provider.KEY, providerJson.toString()).
- putBoolean(PROVIDER_ALLOW_ANONYMOUS, providerJson.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOW_ANONYMOUS)).
- putBoolean(PROVIDER_ALLOWED_REGISTERED, providerJson.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOWED_REGISTERED)).
- putString(Provider.KEY + "." + providerDomain, providerJson.toString()).commit();
- result.putBoolean(RESULT_KEY, true);
+
+ provider.define(providerJson);
+
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} catch (JSONException e) {
String reason_to_fail = pickErrorMessage(providerDotJsonString);
result.putString(ERRORS, reason_to_fail);
- result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
}
}
+ result.putParcelable(PROVIDER_KEY, provider);
return result;
}
/**
* Downloads the eip-service.json from a given URL, and saves eip service capabilities including the offered gateways
- * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the download was successful.
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if the download was successful.
*/
@Override
- protected Bundle getAndSetEipServiceJson() {
+ protected Bundle getAndSetEipServiceJson(Provider provider) {
Bundle result = new Bundle();
- String eip_service_json_string = "";
+ String eipServiceJsonString = "";
if (go_ahead) {
try {
- JSONObject provider_json = new JSONObject(preferences.getString(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, lastDangerOn);
- JSONObject eip_service_json = new JSONObject(eip_service_json_string);
- eip_service_json.getInt(Provider.API_RETURN_SERIAL);
+ JSONObject providerDefinition = provider.getDefinition();
+ String eipServiceUrl = providerDefinition.getString(Provider.API_URL) + "/" + providerDefinition.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
+ eipServiceJsonString = downloadWithProviderCA(provider.getCaCert(), eipServiceUrl, lastDangerOn);
+ JSONObject eipServiceJson = new JSONObject(eipServiceJsonString);
+ eipServiceJson.getInt(Provider.API_RETURN_SERIAL);
- preferences.edit().putString(PROVIDER_KEY, eip_service_json.toString()).commit();
+ //preferences.edit().putString(PROVIDER_KEY, eipServiceJson.toString()).commit();
+ provider.setEipServiceJson(eipServiceJson);
- result.putBoolean(RESULT_KEY, true);
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} catch (NullPointerException | JSONException e) {
- String reason_to_fail = pickErrorMessage(eip_service_json_string);
- result.putString(ERRORS, reason_to_fail);
- result.putBoolean(RESULT_KEY, false);
+ String reasonToFail = pickErrorMessage(eipServiceJsonString);
+ result.putString(ERRORS, reasonToFail);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
}
}
+ result.putParcelable(PROVIDER_KEY, provider);
return result;
}
@@ -224,19 +197,19 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* @return true if certificate was downloaded correctly, false if provider.json is not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error.
*/
@Override
- protected boolean updateVpnCertificate() {
+ protected boolean updateVpnCertificate(Provider provider) {
try {
- JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
+ JSONObject providerDefinition = provider.getDefinition();
- 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) + "/" + PROVIDER_VPN_CERTIFICATE);
+ String providerMainUrl = providerDefinition.getString(Provider.API_URL);
+ URL newCertStringUrl = new URL(providerMainUrl + "/" + providerDefinition.getString(Provider.API_VERSION) + "/" + PROVIDER_VPN_CERTIFICATE);
- String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), lastDangerOn);
+ String certString = downloadWithProviderCA(provider.getCaCert(), newCertStringUrl.toString(), lastDangerOn);
- if (cert_string == null || cert_string.isEmpty() || ConfigHelper.checkErroneousDownload(cert_string))
+ if (certString == null || certString.isEmpty() || ConfigHelper.checkErroneousDownload(certString))
return false;
else
- return loadCertificate(cert_string);
+ return loadCertificate(certString);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -249,19 +222,18 @@ public class ProviderApiManager extends ProviderApiManagerBase {
}
- private Bundle downloadCACert(boolean dangerOn) {
+ private Bundle downloadCACert(Provider provider, boolean dangerOn) {
Bundle result = new Bundle();
try {
- JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, ""));
- String caCertUrl = providerJson.getString(Provider.CA_CERT_URI);
- String providerDomain = providerJson.getString(Provider.DOMAIN);
+ String caCertUrl = provider.getDefinition().getString(Provider.CA_CERT_URI);
+ String providerDomain = provider.getDomain();
String certString = downloadWithCommercialCA(caCertUrl, dangerOn);
- if (validCertificate(certString) && go_ahead) {
- preferences.edit().putString(Provider.CA_CERT, certString).commit();
- preferences.edit().putString(Provider.CA_CERT + "." + providerDomain, certString).commit();
- result.putBoolean(RESULT_KEY, true);
+ if (validCertificate(provider, certString) && go_ahead) {
+ provider.setCaCert(certString);
+ preferences.edit().putString(Provider.CA_CERT + "." + providerDomain, certString).apply();
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} else {
setErrorResult(result, warning_corrupted_provider_cert, ERROR_CERTIFICATE_PINNING.toString());
}
@@ -275,13 +247,13 @@ public class ProviderApiManager extends ProviderApiManagerBase {
/**
* Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider.
* <p/>
- * If danger_on flag is true, SSL exceptions will be managed by futher methods that will try to use some bypass methods.
+ * If dangerOn flag is true, SSL exceptions will be managed by futher methods that will try to use some bypass methods.
*
- * @param string_url
- * @param danger_on if the user completely trusts this provider
+ * @param stringUrl
+ * @param dangerOn if the user completely trusts this provider
* @return
*/
- private String downloadWithCommercialCA(String string_url, boolean danger_on) {
+ private String downloadWithCommercialCA(String stringUrl, boolean dangerOn) {
String responseString;
JSONObject errorJson = new JSONObject();
@@ -292,14 +264,14 @@ public class ProviderApiManager extends ProviderApiManagerBase {
List<Pair<String, String>> headerArgs = getAuthorizationHeader();
- responseString = sendGetStringToServer(string_url, headerArgs, okHttpClient);
+ responseString = sendGetStringToServer(stringUrl, headerArgs, okHttpClient);
if (responseString != null && responseString.contains(ERRORS)) {
try {
// try to download with provider CA on certificate error
JSONObject responseErrorJson = new JSONObject(responseString);
- if (danger_on && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
- responseString = downloadWithoutCA(string_url);
+ if (dangerOn && responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
+ responseString = downloadWithoutCA(stringUrl);
}
} catch (JSONException e) {
e.printStackTrace();
@@ -344,11 +316,11 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* @param dangerOn 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(String urlString, boolean dangerOn) {
+ private String downloadWithProviderCA(String caCert, String urlString, boolean dangerOn) {
JSONObject initError = new JSONObject();
String responseString;
- OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(initError);
+ OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(caCert, initError);
if (okHttpClient == null) {
return initError.toString();
}
@@ -376,7 +348,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* Downloads the string that's in the url with any certificate.
*/
// This method is totally insecure anyways. So no need to refactor that in order to use okHttpClient, force modern TLS etc.. DO NOT USE IN PRODUCTION!
- private String downloadWithoutCA(String url_string) {
+ private String downloadWithoutCA(String urlString) {
String string = "";
try {
@@ -406,7 +378,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
SSLContext context = SSLContext.getInstance("TLS");
context.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
- URL url = new URL(url_string);
+ URL url = new URL(urlString);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(hostnameVerifier);
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
index 6977753f..cf9ee5f5 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
@@ -2,15 +2,12 @@ package se.leap.bitmaskclient;
import android.content.SharedPreferences;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
-import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
-
public class ProviderDetailActivity extends AbstractProviderDetailActivity {
@Override
public void onBackPressed() {
SharedPreferences.Editor editor = preferences.edit();
- editor.remove(Provider.KEY).remove(ProviderListContent.ProviderItem.DANGER_ON).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply();
+ editor.remove(ProviderListContent.ProviderItem.DANGER_ON).apply();
super.onBackPressed();
}
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java
index 823b5635..554085b1 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java
@@ -16,7 +16,6 @@
*/
package se.leap.bitmaskclient;
-import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentTransaction;
@@ -26,6 +25,8 @@ import java.net.URL;
import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
+import static se.leap.bitmaskclient.ProviderAPI.SET_UP_PROVIDER;
+
/**
* Activity that builds and shows the list of known available providers.
* <p/>
@@ -51,12 +52,12 @@ public class ProviderListActivity extends ProviderListBaseActivity {
/**
* Open the new provider dialog with data
*/
- public void addAndSelectNewProvider(String main_url, boolean danger_on) {
+ public void addAndSelectNewProvider(String mainUrl, boolean danger_on) {
FragmentTransaction fragment_transaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG);
DialogFragment newFragment = new NewProviderDialog();
Bundle data = new Bundle();
- data.putString(Provider.MAIN_URL, main_url);
+ data.putString(Provider.MAIN_URL, mainUrl);
data.putBoolean(ProviderItem.DANGER_ON, danger_on);
newFragment.setArguments(data);
newFragment.show(fragment_transaction, NewProviderDialog.TAG);
@@ -87,45 +88,25 @@ public class ProviderListActivity extends ProviderListBaseActivity {
*/
public void setUpProvider(boolean danger_on) {
mConfigState.setAction(SETTING_UP_PROVIDER);
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
+
Bundle parameters = new Bundle();
- parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString());
parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
- if (provider.hasCertificatePin()){
- parameters.putString(Provider.CA_CERT_FINGERPRINT, provider.certificatePin());
- }
- if (provider.hasCaCert()) {
- parameters.putString(Provider.CA_CERT, provider.getCaCert());
- }
- if (provider.hasDefinition()) {
- parameters.putString(Provider.KEY, provider.getDefinition().toString());
- }
-
- providerAPICommand.setAction(ProviderAPI.SET_UP_PROVIDER);
- providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters);
- startService(providerAPICommand);
+ ProviderAPICommand.execute(this, SET_UP_PROVIDER, parameters, provider);
}
/**
* Retrys setup of last used provider, allows bypassing ca certificate validation.
*/
@Override
- public void retrySetUpProvider() {
+ public void retrySetUpProvider(Provider provider) {
cancelSettingUpProvider();
- if (!ProviderAPI.caCertDownloaded()) {
- addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl(), ProviderAPI.lastDangerOn());
+ if (!provider.hasCaCert()) {
+ addAndSelectNewProvider(provider.getMainUrlString(), ProviderAPI.lastDangerOn());
} else {
showProgressBar();
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
-
- providerAPICommand.setAction(ProviderAPI.SET_UP_PROVIDER);
- Bundle parameters = new Bundle();
- parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString());
- providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters);
-
- startService(providerAPICommand);
+ ProviderAPICommand.execute(this, SET_UP_PROVIDER, provider);
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
index fbb27b58..9826b89b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
@@ -1,7 +1,6 @@
package se.leap.bitmaskclient;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatTextView;
@@ -12,14 +11,10 @@ import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import java.util.ArrayList;
import butterknife.InjectView;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;
@@ -36,56 +31,58 @@ public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseAct
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ provider = getIntent().getParcelableExtra(PROVIDER_KEY);
setContentView(R.layout.a_provider_detail);
- try {
- JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, ""));
- setProviderHeaderText(ConfigHelper.getProviderName(preferences));
- description.setText(ConfigHelper.getDescription(preferences));
+ if (provider == null) {
+ return;
+ }
- // Show only the options allowed by the provider
- ArrayList<String> optionsList = new ArrayList<>();
- if (registrationAllowed(providerJson)) {
- optionsList.add(getString(R.string.login_to_profile));
- optionsList.add(getString(R.string.create_profile));
- }
- if (anonAllowed(providerJson)) {
- optionsList.add(getString(R.string.use_anonymously_button));
- }
- options.setAdapter(new ArrayAdapter<>(
- this,
- android.R.layout.simple_list_item_activated_1,
- android.R.id.text1,
- optionsList.toArray(new String[optionsList.size()])
- ));
- options.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- String text = ((TextView) view).getText().toString();
- Intent intent;
- if (text.equals(getString(R.string.login_to_profile))) {
- Log.d(TAG, "login selected");
- intent = new Intent(getApplicationContext(), LoginActivity.class);
- } else if (text.equals(getString(R.string.create_profile))) {
- Log.d(TAG, "signup selected");
- intent = new Intent(getApplicationContext(), SignupActivity.class);
- } else {
- Log.d(TAG, "use anonymously selected");
- intent = new Intent();
- intent.putExtra(Provider.KEY, provider);
- setResult(RESULT_OK, intent);
- finish();
- return;
- }
- intent.putExtra(PROVIDER_KEY, provider);
- intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP);
- }
- });
- } catch (JSONException e) {
- // TODO show error and return
+ setProviderHeaderText(provider.getName());
+ description.setText(provider.getDescription());
+
+ // Show only the options allowed by the provider
+ ArrayList<String> optionsList = new ArrayList<>();
+ if (provider.allowsRegistered()) {
+ optionsList.add(getString(R.string.login_to_profile));
+ optionsList.add(getString(R.string.create_profile));
+ }
+ if (provider.allowsAnonymous()) {
+ optionsList.add(getString(R.string.use_anonymously_button));
}
+
+ options.setAdapter(new ArrayAdapter<>(
+ this,
+ android.R.layout.simple_list_item_activated_1,
+ android.R.id.text1,
+ optionsList.toArray(new String[optionsList.size()])
+ ));
+ options.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String text = ((TextView) view).getText().toString();
+ Intent intent;
+ if (text.equals(getString(R.string.login_to_profile))) {
+ Log.d(TAG, "login selected");
+ intent = new Intent(getApplicationContext(), LoginActivity.class);
+ } else if (text.equals(getString(R.string.create_profile))) {
+ Log.d(TAG, "signup selected");
+ intent = new Intent(getApplicationContext(), SignupActivity.class);
+ } else {
+ Log.d(TAG, "use anonymously selected");
+ intent = new Intent();
+ intent.putExtra(Provider.KEY, provider);
+ setResult(RESULT_OK, intent);
+ finish();
+ return;
+ }
+ intent.putExtra(PROVIDER_KEY, provider);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP);
+ }
+ });
}
@Override
@@ -104,29 +101,4 @@ public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseAct
}
}
- private boolean anonAllowed(JSONObject providerJson) {
- try {
- JSONObject serviceDescription = providerJson.getJSONObject(Provider.SERVICE);
- return serviceDescription.has(PROVIDER_ALLOW_ANONYMOUS) && serviceDescription.getBoolean(PROVIDER_ALLOW_ANONYMOUS);
- } catch (JSONException e) {
- return false;
- }
- }
-
- private boolean registrationAllowed(JSONObject providerJson) {
- try {
- JSONObject serviceDescription = providerJson.getJSONObject(Provider.SERVICE);
- return serviceDescription.has(Provider.ALLOW_REGISTRATION) && serviceDescription.getBoolean(Provider.ALLOW_REGISTRATION);
- } catch (JSONException e) {
- return false;
- }
- }
-
- @Override
- public void onBackPressed() {
- SharedPreferences.Editor editor = preferences.edit();
- editor.remove(Provider.KEY).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply();
- super.onBackPressed();
- }
-
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java
index 741a6f56..5a97624d 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java
@@ -21,7 +21,6 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
-import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.spongycastle.util.encoders.Base64;
@@ -47,10 +46,15 @@ import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import static android.R.attr.name;
+import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION;
import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
+import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
/**
* Stores constants, and implements auxiliary methods used across all Bitmask Android classes.
@@ -98,14 +102,14 @@ public class ConfigHelper {
return ret;
}
- public static X509Certificate parseX509CertificateFromString(String certificate_string) {
+ public static X509Certificate parseX509CertificateFromString(String certificateString) {
java.security.cert.Certificate certificate = null;
CertificateFactory cf;
try {
cf = CertificateFactory.getInstance("X.509");
- certificate_string = certificate_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim();
- byte[] cert_bytes = Base64.decode(certificate_string);
+ certificateString = certificateString.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim();
+ byte[] cert_bytes = Base64.decode(certificateString);
InputStream caInput = new ByteArrayInputStream(cert_bytes);
try {
certificate = cf.generateCertificate(caInput);
@@ -271,9 +275,9 @@ public class ConfigHelper {
public static Provider getSavedProviderFromSharedPreferences(@NonNull SharedPreferences preferences) {
Provider provider = new Provider();
try {
- provider.setUrl(new URL(preferences.getString(Provider.MAIN_URL, "")));
+ provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, "")));
provider.define(new JSONObject(preferences.getString(Provider.KEY, "")));
- provider.setCACert(preferences.getString(Provider.CA_CERT, ""));
+ provider.setCaCert(preferences.getString(Provider.CA_CERT, ""));
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
}
@@ -349,6 +353,40 @@ public class ConfigHelper {
putString(Provider.MAIN_URL, provider.getMainUrlString()).
putString(Provider.KEY, provider.getDefinitionString()).
putString(Provider.CA_CERT, provider.getCaCert()).
- apply();
+ putString(PROVIDER_KEY, provider.getEipServiceJsonString()).
+ commit();
}
+
+
+ public static void clearDataOfLastProvider(SharedPreferences preferences) {
+ clearDataOfLastProvider(preferences, false);
+ }
+
+ public static void clearDataOfLastProvider(SharedPreferences preferences, boolean commit) {
+ Map<String, ?> allEntries = preferences.getAll();
+ List<String> lastProvidersKeys = new ArrayList<>();
+ for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
+ //sort out all preferences that don't belong to the last provider
+ if (entry.getKey().startsWith(Provider.KEY + ".") ||
+ entry.getKey().startsWith(Provider.CA_CERT + ".") ||
+ entry.getKey().startsWith(Provider.CA_CERT_FINGERPRINT + "." )||
+ entry.getKey().equals(PREFERENCES_APP_VERSION)
+ ) {
+ continue;
+ }
+ lastProvidersKeys.add(entry.getKey());
+ }
+
+ SharedPreferences.Editor preferenceEditor = preferences.edit();
+ for (String key : lastProvidersKeys) {
+ preferenceEditor.remove(key);
+ }
+ if (commit) {
+ preferenceEditor.commit();
+ } else {
+ preferenceEditor.apply();
+ }
+ }
+
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java
index 79a78fe1..7fcb5816 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java
@@ -56,19 +56,22 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity {
@Override
public void setContentView(View view) {
super.setContentView(view);
- setProviderHeaderText(ConfigHelper.getProviderName(preferences));
+ if (provider != null)
+ setProviderHeaderText(provider.getName());
}
@Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
- setProviderHeaderText(ConfigHelper.getProviderName(preferences));
+ if (provider != null)
+ setProviderHeaderText(provider.getName());
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
super.setContentView(view, params);
- setProviderHeaderText(ConfigHelper.getProviderName(preferences));
+ if (provider != null)
+ setProviderHeaderText(provider.getName());
}
protected void setProviderHeaderLogo(@DrawableRes int providerHeaderLogo) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java
index 7ee3adab..23c5e805 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java
@@ -17,6 +17,7 @@ public interface Constants {
String REQUEST_CODE_KEY = "request_code";
int REQUEST_CODE_CONFIGURE_LEAP = 0;
int REQUEST_CODE_SWITCH_PROVIDER = 1;
+ int REQUEST_CODE_LOG_IN = 2;
//////////////////////////////////////////////
@@ -50,10 +51,34 @@ public interface Constants {
//////////////////////////////////////////////
// PROVIDER CONSTANTS
/////////////////////////////////////////////
+
String PROVIDER_ALLOW_ANONYMOUS = "allow_anonymous";
String PROVIDER_ALLOWED_REGISTERED = "allow_registration";
String PROVIDER_VPN_CERTIFICATE = "cert";
String PROVIDER_PRIVATE_KEY = "Constants.PROVIDER_PRIVATE_KEY";
String PROVIDER_KEY = "Constants.PROVIDER_KEY";
String PROVIDER_CONFIGURED = "Constants.PROVIDER_CONFIGURED";
+
+ //////////////////////////////////////////////
+ // CREDENTIAL CONSTANTS
+ /////////////////////////////////////////////
+
+ String CREDENTIALS_USERNAME = "username";
+ String CREDENTIALS_PASSWORD = "password";
+
+ enum CREDENTIAL_ERRORS {
+ USERNAME_MISSING,
+ PASSWORD_INVALID_LENGTH,
+ RISEUP_WARNING
+ }
+
+ //////////////////////////////////////////////
+ // BROADCAST CONSTANTS
+ /////////////////////////////////////////////
+
+ String BROADCAST_EIP_EVENT = "BROADCAST.EIP_EVENT";
+ String BROADCAST_PROVIDER_API_EVENT = "BROADCAST.PROVIDER_API_EVENT";
+ String BROADCAST_RESULT_CODE = "BROADCAST.RESULT_CODE";
+ String BROADCAST_RESULT_KEY = "BROADCAST.RESULT_KEY";
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
index a4db5f84..2f129d02 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
@@ -23,8 +23,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -36,14 +34,11 @@ import org.json.JSONObject;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
import butterknife.InjectView;
import de.blinkt.openvpn.core.VpnStatus;
+import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.fragments.AboutFragment;
-import se.leap.bitmaskclient.userstatus.SessionDialog;
import se.leap.bitmaskclient.userstatus.User;
import se.leap.bitmaskclient.userstatus.UserStatusFragment;
@@ -51,8 +46,6 @@ import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PRO
import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT;
import static se.leap.bitmaskclient.Constants.EIP_IS_ALWAYS_ON;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
-import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;
@@ -91,20 +84,15 @@ public class Dashboard extends ButterKnifeActivity {
private UserStatusFragment user_status_fragment;
private static Provider provider = new Provider();
- public static ProviderAPIResultReceiver providerAPI_result_receiver;
- private static boolean switching_provider;
private boolean handledVersion;
- public static DashboardReceiver dashboardReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- dashboardReceiver = new DashboardReceiver(this);
preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
fragment_manager = new FragmentManagerEnhanced(getSupportFragmentManager());
- providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler(), dashboardReceiver);
if (!handledVersion) {
handleVersion();
@@ -112,7 +100,6 @@ public class Dashboard extends ButterKnifeActivity {
}
// initialize app necessities
- ProviderAPICommand.initialize(this);
VpnStatus.initLogCache(getApplicationContext().getCacheDir());
User.init(getString(R.string.default_username));
@@ -157,9 +144,9 @@ public class Dashboard extends ButterKnifeActivity {
private Provider getSavedProviderFromSharedPreferences() {
Provider provider = new Provider();
try {
- provider.setUrl(new URL(preferences.getString(Provider.MAIN_URL, "")));
+ provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, "")));
provider.define(new JSONObject(preferences.getString(Provider.KEY, "")));
- provider.setCACert(preferences.getString(Provider.CA_CERT, ""));
+ provider.setCaCert(preferences.getString(Provider.CA_CERT, ""));
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
}
@@ -175,7 +162,7 @@ public class Dashboard extends ButterKnifeActivity {
case 91: // 0.6.0 without Bug #5999
case 101: // 0.8.0
if (!preferences.getString(PROVIDER_KEY, "").isEmpty())
- eip_fragment.updateEipService();
+ EipCommand.updateEipService(this);
break;
}
} catch (NameNotFoundException e) {
@@ -211,9 +198,9 @@ public class Dashboard extends ButterKnifeActivity {
buildDashboard(false);
invalidateOptionsMenuOnUiThread();
- if (data.hasExtra(SessionDialog.TAG)) {
- sessionDialog(Bundle.EMPTY);
- }
+ //if (data.hasExtra(SessionDialog.TAG)) {
+ // sessionDialog(Bundle.EMPTY);
+ //}
} else if (resultCode == RESULT_CANCELED && data != null && data.hasExtra(APP_ACTION_QUIT)) {
finish();
@@ -304,14 +291,14 @@ public class Dashboard extends ButterKnifeActivity {
user_status_fragment.setArguments(bundle);
fragment_manager.replace(R.id.user_status_fragment, user_status_fragment, UserStatusFragment.TAG);
- if (provider.hasEIP()) {
- fragment_manager.removePreviousFragment(EipFragment.TAG);
- eip_fragment = prepareEipFragment(hideAndTurnOnEipOnBoot);
- fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG);
- if (hideAndTurnOnEipOnBoot) {
- onBackPressed();
- }
- }
+// if (provider.hasEIP()) {
+// fragment_manager.removePreviousFragment(EipFragment.TAG);
+// eip_fragment = prepareEipFragment(hideAndTurnOnEipOnBoot);
+// fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG);
+// if (hideAndTurnOnEipOnBoot) {
+// onBackPressed();
+// }
+// }
}
/**
@@ -367,12 +354,11 @@ public class Dashboard extends ButterKnifeActivity {
showLog();
return true;
case R.id.switch_provider:
- switching_provider = true;
if (User.loggedIn()) user_status_fragment.logOut();
else switchProvider();
return true;
case R.id.signup_button:
- sessionDialog(Bundle.EMPTY);
+ //sessionDialog(Bundle.EMPTY);
return true;
default:
return super.onOptionsItemSelected(item);
@@ -389,99 +375,14 @@ public class Dashboard extends ButterKnifeActivity {
log_window_wrapper.showLog();
}
-
- // TODO MOVE TO VPNManager(?)
- public static void downloadVpnCertificate() {
- boolean is_authenticated = User.loggedIn();
- boolean allowed_anon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false);
- if (allowed_anon || is_authenticated)
- ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_CERTIFICATE, providerAPI_result_receiver);
- else
- sessionDialog(Bundle.EMPTY);
- }
-
- // TODO how can we replace this
- public static void sessionDialog(Bundle resultData) {
- try {
- FragmentTransaction transaction = fragment_manager.removePreviousFragment(SessionDialog.TAG);
- SessionDialog.getInstance(provider, resultData).show(transaction, SessionDialog.TAG);
- } catch (IllegalStateException e) {
- e.printStackTrace();
- }
- }
-
private void switchProvider() {
- if (provider.hasEIP()) eip_fragment.stopEipIfPossible();
-
- clearDataOfLastProvider();
-
- switching_provider = false;
- startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
- }
+// if (provider.hasEIP()) eip_fragment.stopEipIfPossible();
- private void clearDataOfLastProvider() {
- Map<String, ?> allEntries = preferences.getAll();
- List<String> lastProvidersKeys = new ArrayList<>();
- for (Map.Entry<String, ?> entry : allEntries.entrySet()) {
- //sort out all preferences that don't belong to the last provider
- if (entry.getKey().startsWith(Provider.KEY + ".") ||
- entry.getKey().startsWith(Provider.CA_CERT + ".") ||
- entry.getKey().startsWith(Provider.CA_CERT_FINGERPRINT + "." )||
- entry.getKey().equals(PREFERENCES_APP_VERSION)
- ) {
- continue;
- }
- lastProvidersKeys.add(entry.getKey());
- }
+ ConfigHelper.clearDataOfLastProvider(preferences);
- SharedPreferences.Editor preferenceEditor = preferences.edit();
- for (String key : lastProvidersKeys) {
- preferenceEditor.remove(key);
- }
- preferenceEditor.apply();
-
- switching_provider = false;
startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
}
- private static class DashboardReceiver implements ProviderAPIResultReceiver.Receiver{
-
- private Dashboard dashboard;
-
- DashboardReceiver(Dashboard dashboard) {
- this.dashboard = dashboard;
- }
-
- @Override
- public void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == ProviderAPI.SUCCESSFUL_SIGNUP) {
- String username = resultData.getString(SessionDialog.USERNAME);
- String password = resultData.getString(SessionDialog.PASSWORD);
- dashboard.user_status_fragment.logIn(username, password);
- } else if (resultCode == ProviderAPI.FAILED_SIGNUP) {
- MainActivity.sessionDialog(resultData);
- } else if (resultCode == ProviderAPI.SUCCESSFUL_LOGIN) {
- Dashboard.downloadVpnCertificate();
- } else if (resultCode == ProviderAPI.FAILED_LOGIN) {
- MainActivity.sessionDialog(resultData);
- } else if (resultCode == ProviderAPI.SUCCESSFUL_LOGOUT) {
- if (switching_provider) dashboard.switchProvider();
- } else if (resultCode == ProviderAPI.LOGOUT_FAILED) {
- dashboard.setResult(RESULT_CANCELED);
- } else if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
- dashboard.eip_fragment.updateEipService();
- dashboard.setResult(RESULT_OK);
- } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) {
- dashboard.setResult(RESULT_CANCELED);
- } else if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) {
- dashboard.eip_fragment.updateEipService();
- dashboard.setResult(RESULT_OK);
- } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE) {
- dashboard.setResult(RESULT_CANCELED);
- }
- }
- }
-
public static Provider getProvider() { return provider; }
@Override
diff --git a/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java b/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java
index dde71642..1a0c85ad 100644
--- a/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/DownloadFailedDialog.java
@@ -89,7 +89,7 @@ public class DownloadFailedDialog extends DialogFragment {
dialog.dismiss();
}
});
- switch (downloadError) {
+switch (downloadError) {
case ERROR_CORRUPTED_PROVIDER_JSON:
builder.setPositiveButton(R.string.update_provider_details, new DialogInterface.OnClickListener() {
@Override
@@ -113,7 +113,7 @@ public class DownloadFailedDialog extends DialogFragment {
builder.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
- interface_with_ConfigurationWizard.retrySetUpProvider();
+ interface_with_ConfigurationWizard.retrySetUpProvider(null);
}
});
break;
@@ -124,7 +124,7 @@ public class DownloadFailedDialog extends DialogFragment {
}
public interface DownloadFailedDialogInterface {
- void retrySetUpProvider();
+ void retrySetUpProvider(Provider provider);
void cancelSettingUpProvider();
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
index 4027bc14..a86afd78 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
@@ -18,10 +18,12 @@ package se.leap.bitmaskclient;
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.ColorMatrix;
@@ -50,26 +52,33 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.ProfileManager;
import de.blinkt.openvpn.core.VpnStatus;
-import se.leap.bitmaskclient.eip.EIP;
+import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.eip.EipStatus;
import se.leap.bitmaskclient.eip.VoidVpnService;
+import se.leap.bitmaskclient.userstatus.User;
+import static android.app.Activity.RESULT_OK;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK;
+import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE;
import static se.leap.bitmaskclient.Constants.EIP_NOTIFICATION;
-import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED;
import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
+import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN;
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
+import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_CERTIFICATE;
public class EipFragment extends Fragment implements Observer {
@@ -79,6 +88,7 @@ public class EipFragment extends Fragment implements Observer {
public static final String START_EIP_ON_BOOT = "start on boot";
private SharedPreferences preferences;
+ private Provider provider;
@InjectView(R.id.background)
AppCompatImageView background;
@@ -102,6 +112,9 @@ public class EipFragment extends Fragment implements Observer {
private EipStatus eipStatus;
private boolean wantsToConnect;
+ private ProviderAPIResultReceiver providerAPIResultReceiver;
+ private EIPBroadcastReceiver eipBroadcastReceiver;
+
private IOpenVPNServiceInternal mService;
private ServiceConnection openVpnConnection = new ServiceConnection() {
@@ -123,7 +136,18 @@ public class EipFragment extends Fragment implements Observer {
public void onAttach(Context context) {
super.onAttach(context);
- downloadEIPServiceConfig();
+ Bundle arguments = getArguments();
+ if (arguments != null) {
+ provider = getArguments().getParcelable(PROVIDER_KEY);
+ if (provider == null) {
+ getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
+ } else {
+ Log.d(TAG, provider.getName() + " configured as provider");
+ }
+ } else {
+ Log.e(TAG, "no provider given - starting ProviderListActivity");
+ getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
+ }
}
@Override
@@ -131,6 +155,8 @@ public class EipFragment extends Fragment implements Observer {
super.onCreate(savedInstanceState);
eipStatus = EipStatus.getInstance();
eipReceiver = new EIPReceiver(new Handler());
+ eipBroadcastReceiver = new EIPBroadcastReceiver();
+ providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), new EipFragmentReceiver());
preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
}
@@ -152,6 +178,7 @@ public class EipFragment extends Fragment implements Observer {
super.onResume();
//FIXME: avoid race conditions while checking certificate an logging in at about the same time
//eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY);
+ setUpBroadcastReceiver();
handleNewState();
bindOpenVpnService();
}
@@ -160,6 +187,8 @@ public class EipFragment extends Fragment implements Observer {
public void onPause() {
super.onPause();
getActivity().unbindService(openVpnConnection);
+ getActivity().unregisterReceiver(eipBroadcastReceiver);
+ Log.d(TAG, "broadcast unregistered");
}
@Override
@@ -205,8 +234,8 @@ public class EipFragment extends Fragment implements Observer {
startEipFromScratch();
else if (canLogInToStartEIP()) {
wantsToConnect = true;
- Bundle bundle = new Bundle();
- MainActivity.sessionDialog(bundle);
+ Intent intent = new Intent(getContext(), LoginActivity.class);
+ getActivity().startActivityForResult(intent, REQUEST_CODE_LOG_IN);
} else {
Log.d(TAG, "WHAT IS GOING ON HERE?!");
// TODO: implement a fallback: check if vpncertificate was not downloaded properly or give
@@ -256,7 +285,7 @@ public class EipFragment extends Fragment implements Observer {
public void startEipFromScratch() {
wantsToConnect = false;
saveStatus(true);
- eipCommand(EIP_ACTION_START);
+ EipCommand.startVPN(getContext(), eipReceiver);
}
private void stop() {
@@ -288,13 +317,7 @@ public class EipFragment extends Fragment implements Observer {
protected void stopEipIfPossible() {
//FIXME: no need to start a service here!
- eipCommand(EIP_ACTION_STOP);
- }
-
- private void downloadEIPServiceConfig() {
- ProviderAPIResultReceiver provider_api_receiver = new ProviderAPIResultReceiver(new Handler(), Dashboard.dashboardReceiver);
- if(eipReceiver != null)
- ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_EIP_SERVICE, provider_api_receiver);
+ EipCommand.stopVPN(getContext(), eipReceiver);
}
protected void askToStopEIP() {
@@ -316,25 +339,6 @@ public class EipFragment extends Fragment implements Observer {
.show();
}
- protected void updateEipService() {
- eipCommand(EIP_ACTION_UPDATE);
- }
-
- /**
- * Send a command to EIP
- *
- * @param action A valid String constant from EIP class representing an Intent
- * filter for the EIP class
- */
- private void eipCommand(String action) {
- Activity activity = getActivity();
- // TODO validate "action"...how do we get the list of intent-filters for a class via Android API?
- Intent vpn_intent = new Intent(activity.getApplicationContext(), EIP.class);
- vpn_intent.setAction(action);
- vpn_intent.putExtra(EIP_RECEIVER, eipReceiver);
- activity.startService(vpn_intent);
- }
-
@Override
public void update(Observable observable, Object data) {
if (observable instanceof EipStatus) {
@@ -407,58 +411,81 @@ public class EipFragment extends Fragment implements Observer {
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
- String request = resultData.getString(EIP_REQUEST);
+ handleEIPEvent(resultCode, resultData);
+ }
+ }
+
+ private class EIPBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "received Broadcast");
- if (request == null) {
+ String action = intent.getAction();
+ if (action == null || !action.equalsIgnoreCase(BROADCAST_EIP_EVENT)) {
return;
}
- switch (request) {
- case EIP_ACTION_START:
- switch (resultCode) {
- case Activity.RESULT_OK:
- break;
- case Activity.RESULT_CANCELED:
- break;
- }
- break;
- case EIP_ACTION_STOP:
- switch (resultCode) {
- case Activity.RESULT_OK:
- stop();
- break;
- case Activity.RESULT_CANCELED:
- break;
- }
- break;
- case EIP_NOTIFICATION:
- switch (resultCode) {
- case Activity.RESULT_OK:
- break;
- case Activity.RESULT_CANCELED:
- break;
- }
- break;
- case EIP_ACTION_CHECK_CERT_VALIDITY:
- switch (resultCode) {
- case Activity.RESULT_OK:
- break;
- case Activity.RESULT_CANCELED:
- Dashboard.downloadVpnCertificate();
- break;
- }
- break;
- case EIP_ACTION_UPDATE:
- switch (resultCode) {
- case Activity.RESULT_OK:
- if (wantsToConnect)
- startEipFromScratch();
- break;
- case Activity.RESULT_CANCELED:
- handleNewState();
- break;
- }
- }
+ int resultCode = intent.getIntExtra(BROADCAST_RESULT_KEY, -1);
+ Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY);
+ Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode));
+
+ handleEIPEvent(resultCode, resultData);
+
+ }
+ }
+
+ private void handleEIPEvent(int resultCode, Bundle resultData) {
+ String request = resultData.getString(EIP_REQUEST);
+
+ if (request == null) {
+ return;
+ }
+
+ switch (request) {
+ case EIP_ACTION_START:
+ switch (resultCode) {
+ case RESULT_OK:
+ break;
+ case Activity.RESULT_CANCELED:
+ break;
+ }
+ break;
+ case EIP_ACTION_STOP:
+ switch (resultCode) {
+ case RESULT_OK:
+ stop();
+ break;
+ case Activity.RESULT_CANCELED:
+ break;
+ }
+ break;
+ case EIP_NOTIFICATION:
+ switch (resultCode) {
+ case RESULT_OK:
+ break;
+ case Activity.RESULT_CANCELED:
+ break;
+ }
+ break;
+ case EIP_ACTION_CHECK_CERT_VALIDITY:
+ switch (resultCode) {
+ case RESULT_OK:
+ break;
+ case Activity.RESULT_CANCELED:
+ downloadVpnCertificate();
+ break;
+ }
+ break;
+ case EIP_ACTION_UPDATE:
+ switch (resultCode) {
+ case RESULT_OK:
+ if (wantsToConnect)
+ startEipFromScratch();
+ break;
+ case Activity.RESULT_CANCELED:
+ handleNewState();
+ break;
+ }
}
}
@@ -480,4 +507,33 @@ public class EipFragment extends Fragment implements Observer {
background.setImageAlpha(255);
}
+ private class EipFragmentReceiver implements ProviderAPIResultReceiver.Receiver{
+
+ @Override
+ public void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) {
+ provider = resultData.getParcelable(PROVIDER_KEY);
+ EipCommand.updateEipService(getContext(), eipReceiver);
+ } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE) {
+ //dashboard.setResult(RESULT_CANCELED);
+ // TODO CATCH ME IF YOU CAN
+ }
+ }
+ }
+
+ private void downloadVpnCertificate() {
+ boolean is_authenticated = User.loggedIn();
+ boolean allowed_anon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false);
+ if (allowed_anon || is_authenticated) {
+ ProviderAPICommand.execute(getContext(), DOWNLOAD_CERTIFICATE, provider, providerAPIResultReceiver);
+ }
+ }
+
+ private void setUpBroadcastReceiver() {
+ IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_EIP_EVENT);
+ updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);
+ getActivity().registerReceiver(eipBroadcastReceiver, updateIntentFilter);
+ Log.d(TAG, "broadcast registered");
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
index 7629f0b7..d3865559 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
@@ -5,15 +5,17 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import se.leap.bitmaskclient.drawer.NavigationDrawerFragment;
-import se.leap.bitmaskclient.userstatus.SessionDialog;
+import se.leap.bitmaskclient.eip.EipCommand;
+import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN;
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
@@ -23,6 +25,8 @@ public class MainActivity extends AppCompatActivity {
private static FragmentManagerEnhanced fragmentManager;
private SharedPreferences preferences;
+ private NavigationDrawerFragment navigationDrawerFragment;
+
public final static String ACTION_SHOW_VPN_FRAGMENT = "action_show_vpn_fragment";
/**
@@ -33,13 +37,14 @@ public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
-
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
- NavigationDrawerFragment navigationDrawerFragment = (NavigationDrawerFragment)
+ navigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ provider = ConfigHelper.getSavedProviderFromSharedPreferences(preferences);
+
fragmentManager = new FragmentManagerEnhanced(getSupportFragmentManager());
// Set up the drawer.
navigationDrawerFragment.setUp(
@@ -49,15 +54,6 @@ public class MainActivity extends AppCompatActivity {
handleIntentAction(getIntent());
}
- public static void sessionDialog(Bundle resultData) {
- try {
- FragmentTransaction transaction = fragmentManager.removePreviousFragment(SessionDialog.TAG);
- SessionDialog.getInstance(provider, resultData).show(transaction, SessionDialog.TAG);
- } catch (IllegalStateException e) {
- e.printStackTrace();
- }
- }
-
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -70,35 +66,54 @@ public class MainActivity extends AppCompatActivity {
return;
}
- Fragment fragment = null;
-
switch (intent.getAction()) {
case ACTION_SHOW_VPN_FRAGMENT:
- fragment = new EipFragment();
+ showEipFragment();
break;
default:
break;
}
-
- if (fragment != null) {
- fragmentManager.beginTransaction()
- .replace(R.id.container, fragment)
- .commit();
- }
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
if (data == null) {
return;
}
- if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) {
- if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) {
- Provider provider = data.getParcelableExtra(Provider.KEY);
- ConfigHelper.storeProviderInPreferences(preferences, provider);
+ if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) {
+ provider = data.getParcelableExtra(Provider.KEY);
+
+ if (provider == null) {
+ return;
}
+
+ ConfigHelper.storeProviderInPreferences(preferences, provider);
+ navigationDrawerFragment.refresh();
+ switch (requestCode) {
+ case REQUEST_CODE_SWITCH_PROVIDER:
+ EipCommand.stopVPN(this);
+ break;
+ case REQUEST_CODE_CONFIGURE_LEAP:
+ break;
+ case REQUEST_CODE_LOG_IN:
+ EipCommand.startVPN(this);
+ break;
+
+ }
+ showEipFragment();
}
}
+ private void showEipFragment() {
+ Fragment fragment = new EipFragment();
+ Bundle arguments = new Bundle();
+ arguments.putParcelable(PROVIDER_KEY, provider);
+ fragment.setArguments(arguments);
+ fragmentManager.beginTransaction()
+ .replace(R.id.container, fragment)
+ .commit();
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
index 1bf679f8..6d554b0e 100644
--- a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java
@@ -59,11 +59,9 @@ import static se.leap.bitmaskclient.R.string.server_unreachable_message;
public class OkHttpClientGenerator {
- SharedPreferences preferences;
Resources resources;
public OkHttpClientGenerator(SharedPreferences preferences, Resources resources) {
- this.preferences = preferences;
this.resources = resources;
}
@@ -71,9 +69,8 @@ public class OkHttpClientGenerator {
return initHttpClient(initError, null);
}
- public OkHttpClient initSelfSignedCAHttpClient(JSONObject initError) {
- String certificate = preferences.getString(Provider.CA_CERT, "");
- return initHttpClient(initError, certificate);
+ public OkHttpClient initSelfSignedCAHttpClient(String caCert, JSONObject initError) {
+ return initHttpClient(initError, caCert);
}
public OkHttpClient initSelfSignedCAHttpClient(JSONObject initError, String certificate) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java
index 5ff1949c..9595b147 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java
@@ -16,18 +16,22 @@
*/
package se.leap.bitmaskclient;
-import android.content.SharedPreferences;
-import android.os.*;
+import android.os.Parcel;
+import android.os.Parcelable;
import com.google.gson.Gson;
-import org.json.*;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
-import java.io.Serializable;
-import java.net.*;
-import java.util.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Locale;
-import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
+import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED;
+import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
/**
* @author Sean Leonard <meanderingcode@aetherislands.net>
@@ -36,11 +40,17 @@ import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
public final class Provider implements Parcelable {
private JSONObject definition = new JSONObject(); // Represents our Provider's provider.json
+ private JSONObject eipServiceJson = new JSONObject(); // Represents our Provider's provider.json
private DefaultedURL mainUrl = new DefaultedURL();
private DefaultedURL apiUrl = new DefaultedURL();
private String certificatePin = "";
private String certificatePinEncoding = "";
private String caCert = "";
+ private String caCertFingerprint = "";
+ private String apiVerson = "";
+
+ private boolean allowAnonymous;
+ private boolean allowRegistered;
final public static String
API_URL = "api_uri",
@@ -69,6 +79,14 @@ public final class Provider implements Parcelable {
public Provider() { }
+ public Provider(String mainUrl) {
+ try {
+ this.mainUrl.setUrl(new URL(mainUrl));
+ } catch (MalformedURLException e) {
+ this.mainUrl = new DefaultedURL();
+ }
+ }
+
public Provider(URL mainUrl) {
this.mainUrl.setUrl(mainUrl);
}
@@ -108,12 +126,20 @@ public final class Provider implements Parcelable {
!caCert.isEmpty();
}
- protected void setUrl(URL url) {
+ public void setMainUrl(URL url) {
mainUrl.setUrl(url);
}
- protected void define(JSONObject provider_json) {
- definition = provider_json;
+ public void setMainUrl(String url) {
+ try {
+ mainUrl.setUrl(new URL(url));
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void define(JSONObject providerJson) {
+ definition = providerJson;
parseDefinition(definition);
}
@@ -141,6 +167,19 @@ public final class Provider implements Parcelable {
return apiUrl;
}
+ protected String getApiUrlWithVersion() {
+ return getApiUrlString() + "/" + getApiVersion();
+ }
+
+
+ protected String getApiUrlString() {
+ return getApiUrl().toString();
+ }
+
+ public String getApiVersion() {
+ return apiVerson;
+ }
+
protected String certificatePin() { return certificatePin; }
protected boolean hasCertificatePin() {
@@ -160,6 +199,10 @@ public final class Provider implements Parcelable {
return caCert;
}
+ public String getCaCertFingerprint() {
+ return caCertFingerprint;
+ }
+
public String getName() {
// Should we pass the locale in, or query the system here?
String lang = Locale.getDefault().getLanguage();
@@ -200,26 +243,7 @@ public final class Provider implements Parcelable {
}
protected boolean hasEIP() {
- try {
- JSONArray services = definition.getJSONArray(API_TERM_SERVICES); // returns ["openvpn"]
- for (int i = 0; i < API_EIP_TYPES.length + 1; i++) {
- try {
- // Walk the EIP types array looking for matches in provider's service definitions
- if (Arrays.asList(API_EIP_TYPES).contains(services.getString(i)))
- return true;
- } catch (NullPointerException e) {
- e.printStackTrace();
- return false;
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return false;
- }
- }
- } catch (Exception e) {
- // TODO: handle exception
- }
- return false;
+ return getEipServiceJson() != null && getEipServiceJson().length() > 0;
}
public boolean allowsRegistration() {
@@ -237,12 +261,11 @@ public final class Provider implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int i) {
- if(mainUrl != null)
- parcel.writeString(mainUrl.toString());
- if (definition != null)
- parcel.writeString(definition.toString());
- if (caCert != null)
- parcel.writeString(caCert);
+ parcel.writeString(getMainUrlString());
+ parcel.writeString(getDefinitionString());
+ parcel.writeString(getCaCert());
+ parcel.writeString(getCaCertFingerprint());
+ parcel.writeString(getEipServiceJsonString());
}
@Override
@@ -289,6 +312,14 @@ public final class Provider implements Parcelable {
if (!caCert.isEmpty()) {
this.caCert = caCert;
}
+ String caCertFingerprint = in.readString();
+ if (!caCertFingerprint.isEmpty()) {
+ this.caCertFingerprint = caCertFingerprint;
+ }
+ String eipServiceJson = in.readString();
+ if (!eipServiceJson.isEmpty()) {
+ this.setEipServiceJson(new JSONObject(eipServiceJson));
+ }
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
}
@@ -300,15 +331,41 @@ public final class Provider implements Parcelable {
this.certificatePin = pin.split(":")[1].trim();
this.certificatePinEncoding = pin.split(":")[0].trim();
this.apiUrl.setUrl(new URL(definition.getString(API_URL)));
+ this.allowAnonymous = definition.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOW_ANONYMOUS);
+ this.allowRegistered = definition.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOWED_REGISTERED);
+ this.apiVerson = getDefinition().getString(Provider.API_VERSION);
} catch (JSONException | ArrayIndexOutOfBoundsException | MalformedURLException e) {
e.printStackTrace();
}
}
- public void setCACert(String cert) {
+ public void setCaCert(String cert) {
this.caCert = cert;
}
+ public void setCaCertFingerprint(String certFingerprint) {
+ this.caCertFingerprint = certFingerprint;
+ }
+
+ public boolean allowsAnonymous() {
+ return allowAnonymous;
+ }
+
+ public boolean allowsRegistered() {
+ return allowRegistered;
+ }
+
+ public void setEipServiceJson(JSONObject eipServiceJson) {
+ this.eipServiceJson = eipServiceJson;
+ }
+
+ public JSONObject getEipServiceJson() {
+ return eipServiceJson;
+ }
+
+ public String getEipServiceJsonString() {
+ return getEipServiceJson().toString();
+ }
public boolean isDefault() {
return getMainUrl().isDefault() &&
getApiUrl().isDefault() &&
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
index ccc71a67..73f5c530 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
@@ -40,22 +40,18 @@ public class ProviderAPI extends IntentService implements ProviderApiManagerBase
TAG = ProviderAPI.class.getSimpleName(),
SET_UP_PROVIDER = "setUpProvider",
UPDATE_PROVIDER_DETAILS = "updateProviderDetails",
- DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON",
SIGN_UP = "srpRegister",
LOG_IN = "srpAuth",
LOG_OUT = "logOut",
DOWNLOAD_CERTIFICATE = "downloadUserAuthedCertificate",
PARAMETERS = "parameters",
- RESULT_KEY = "result",
- RESULT_CODE = "RESULT CODE",
RECEIVER_KEY = "receiver",
ERRORS = "errors",
ERRORID = "errorId",
UPDATE_PROGRESSBAR = "update_progressbar",
CURRENT_PROGRESS = "current_progress",
DOWNLOAD_EIP_SERVICE = TAG + ".DOWNLOAD_EIP_SERVICE",
- PROVIDER_SET_UP = TAG + ".PROVIDER_SET_UP",
- PROVIDER_API_EVENT = "PROVIDER_API_EVENT";
+ PROVIDER_SET_UP = TAG + ".PROVIDER_SET_UP";
final public static int
SUCCESSFUL_LOGIN = 3,
@@ -85,16 +81,6 @@ public class ProviderAPI extends IntentService implements ProviderApiManagerBase
}
//TODO: refactor me, please!
- public static boolean caCertDownloaded() {
- return ProviderApiManager.caCertDownloaded();
- }
-
- //TODO: refactor me, please!
- public static String lastProviderMainUrl() {
- return ProviderApiManager.lastProviderMainUrl();
- }
-
- //TODO: refactor me, please!
//used in insecure flavor only
@SuppressLint("unused")
public static boolean lastDangerOn() {
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderAPICommand.java b/app/src/main/java/se/leap/bitmaskclient/ProviderAPICommand.java
index 0e4cfe8a..65d01b22 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderAPICommand.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderAPICommand.java
@@ -6,40 +6,74 @@ import android.os.*;
import org.jetbrains.annotations.*;
public class ProviderAPICommand {
- private static Context context;
+ private Context context;
- private static String action;
- private static Bundle parameters;
- private static ResultReceiver result_receiver;
+ private String action;
+ private Bundle parameters;
+ private ResultReceiver resultReceiver;
+ private Provider provider;
- public static void initialize(Context context) {
- ProviderAPICommand.context = context;
+ private ProviderAPICommand(@NotNull Context context, @NotNull String action, @NotNull Provider provider, ResultReceiver resultReceiver) {
+ this(context, action, Bundle.EMPTY, provider, resultReceiver);
+ }
+ private ProviderAPICommand(@NotNull Context context, @NotNull String action, @NotNull Provider provider) {
+ this(context, action, Bundle.EMPTY, provider);
}
- private static boolean isInitialized() {
- return context != null;
+ private ProviderAPICommand(@NotNull Context context, @NotNull String action, @NotNull Bundle parameters, @NotNull Provider provider) {
+ this(context, action, parameters, provider, null);
}
- public static void execute(Bundle parameters, @NotNull String action, @NotNull ResultReceiver result_receiver) throws IllegalStateException {
- if(!isInitialized()) throw new IllegalStateException();
+ private ProviderAPICommand(@NotNull Context context, @NotNull String action, @NotNull Bundle parameters, @NotNull Provider provider, @Nullable ResultReceiver resultReceiver) {
+ super();
+ this.context = context;
+ this.action = action;
+ this.parameters = parameters;
+ this.resultReceiver = resultReceiver;
+ this.provider = provider;
+ }
- ProviderAPICommand.action = action;
- ProviderAPICommand.parameters = parameters;
- ProviderAPICommand.result_receiver = result_receiver;
+ private boolean isInitialized() {
+ return context != null;
+ }
- Intent intent = setUpIntent();
- context.startService(intent);
+ private void execute() {
+ if (isInitialized()) {
+ Intent intent = setUpIntent();
+ context.startService(intent);
+ }
}
- private static Intent setUpIntent() {
+ private Intent setUpIntent() {
Intent command = new Intent(context, ProviderAPI.class);
command.setAction(action);
command.putExtra(ProviderAPI.PARAMETERS, parameters);
- command.putExtra(ProviderAPI.RECEIVER_KEY, result_receiver);
+ if (resultReceiver != null) {
+ command.putExtra(ProviderAPI.RECEIVER_KEY, resultReceiver);
+ }
+ command.putExtra(Constants.PROVIDER_KEY, provider);
return command;
}
+ public static void execute(Context context, String action, Provider provider) {
+ ProviderAPICommand command = new ProviderAPICommand(context, action, provider);
+ command.execute();
+ }
+ public static void execute(Context context, String action, Bundle parameters, Provider provider) {
+ ProviderAPICommand command = new ProviderAPICommand(context, action, parameters, provider);
+ command.execute();
+ }
+
+ public static void execute(Context context, String action, Bundle parameters, Provider provider, ResultReceiver resultReceiver) {
+ ProviderAPICommand command = new ProviderAPICommand(context, action, parameters, provider, resultReceiver);
+ command.execute();
+ }
+
+ public static void execute(Context context, String action, Provider provider, ResultReceiver resultReceiver) {
+ ProviderAPICommand command = new ProviderAPICommand(context, action, provider, resultReceiver);
+ command.execute();
+ }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
index 8117fb99..000dd164 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
@@ -24,6 +24,7 @@ import android.os.Bundle;
import android.os.ResultReceiver;
import android.support.annotation.NonNull;
import android.util.Base64;
+import android.util.Log;
import android.util.Pair;
import org.json.JSONException;
@@ -49,19 +50,20 @@ import java.util.List;
import javax.net.ssl.SSLHandshakeException;
import okhttp3.OkHttpClient;
-import se.leap.bitmaskclient.userstatus.SessionDialog;
-import se.leap.bitmaskclient.userstatus.User;
-import se.leap.bitmaskclient.userstatus.UserStatus;
+import se.leap.bitmaskclient.Constants.CREDENTIAL_ERRORS;
import static se.leap.bitmaskclient.ConfigHelper.getFingerprintFromCertificate;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
+import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.CREDENTIALS_PASSWORD;
+import static se.leap.bitmaskclient.Constants.CREDENTIALS_USERNAME;
+import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.DownloadFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
import static se.leap.bitmaskclient.DownloadFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON;
import static se.leap.bitmaskclient.DownloadFailedDialog.DOWNLOAD_ERRORS.ERROR_INVALID_CERTIFICATE;
-import static se.leap.bitmaskclient.Provider.MAIN_URL;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE;
import static se.leap.bitmaskclient.ProviderAPI.CURRENT_PROGRESS;
@@ -73,17 +75,14 @@ import static se.leap.bitmaskclient.ProviderAPI.FAILED_LOGIN;
import static se.leap.bitmaskclient.ProviderAPI.FAILED_SIGNUP;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE;
-import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT;
-import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP;
import static se.leap.bitmaskclient.ProviderAPI.LOGOUT_FAILED;
import static se.leap.bitmaskclient.ProviderAPI.LOG_IN;
import static se.leap.bitmaskclient.ProviderAPI.LOG_OUT;
import static se.leap.bitmaskclient.ProviderAPI.PARAMETERS;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK;
+import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP;
import static se.leap.bitmaskclient.ProviderAPI.RECEIVER_KEY;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY;
import static se.leap.bitmaskclient.ProviderAPI.SET_UP_PROVIDER;
import static se.leap.bitmaskclient.ProviderAPI.SIGN_UP;
import static se.leap.bitmaskclient.ProviderAPI.SUCCESSFUL_LOGIN;
@@ -109,36 +108,24 @@ import static se.leap.bitmaskclient.R.string.warning_expired_provider_cert;
public abstract class ProviderApiManagerBase {
+ private final static String TAG = ProviderApiManagerBase.class.getName();
+
public interface ProviderApiServiceCallback {
void broadcastEvent(Intent intent);
}
private ProviderApiServiceCallback serviceCallback;
- protected static volatile boolean
- CA_CERT_DOWNLOADED = false,
- PROVIDER_JSON_DOWNLOADED = false,
- EIP_SERVICE_JSON_DOWNLOADED = false;
-
- protected static String lastProviderMainUrl;
- protected static boolean go_ahead = true;
- protected static SharedPreferences preferences;
- protected static String providerApiUrl;
- protected static String providerCaCertFingerprint;
- protected static String providerCaCert;
- protected static JSONObject providerDefinition;
+ static boolean go_ahead = true;
+ protected SharedPreferences preferences;
protected Resources resources;
- protected OkHttpClientGenerator clientGenerator;
+ OkHttpClientGenerator clientGenerator;
public static void stop() {
go_ahead = false;
}
- public static String lastProviderMainUrl() {
- return lastProviderMainUrl;
- }
-
- public ProviderApiManagerBase(SharedPreferences preferences, Resources resources, OkHttpClientGenerator clientGenerator, ProviderApiServiceCallback callback) {
+ ProviderApiManagerBase(SharedPreferences preferences, Resources resources, OkHttpClientGenerator clientGenerator, ProviderApiServiceCallback callback) {
this.preferences = preferences;
this.resources = resources;
this.serviceCallback = callback;
@@ -150,96 +137,88 @@ public abstract class ProviderApiManagerBase {
String action = command.getAction();
Bundle parameters = command.getBundleExtra(PARAMETERS);
- if (providerApiUrl == null && preferences.contains(Provider.KEY)) {
- try {
- JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
- providerApiUrl = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION);
- go_ahead = true;
- } catch (JSONException e) {
- go_ahead = false;
- }
+ Provider provider = command.getParcelableExtra(PROVIDER_KEY);
+
+ if (provider == null) {
+ Log.e(TAG, action +" called without provider!");
+ return;
+ }
+ if (action == null) {
+ Log.e(TAG, "Intent without action sent!");
+ return;
}
if (action.equals(UPDATE_PROVIDER_DETAILS)) {
- resetProviderDetails();
+ resetProviderDetails(provider);
Bundle task = new Bundle();
- String mainUrl = parameters.getString(Provider.MAIN_URL);
- if (mainUrl == null) {
- mainUrl = lastProviderMainUrl;
- }
- task.putString(MAIN_URL, mainUrl);
- Bundle result = setUpProvider(task);
- if (result.getBoolean(RESULT_KEY)) {
- sendToReceiverOrBroadcast(receiver, PROVIDER_OK, result);
+ Bundle result = setUpProvider(provider, task);
+ if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ sendToReceiverOrBroadcast(receiver, PROVIDER_OK, result, provider);
} else {
- sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result);
+ sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result, provider);
}
} else if (action.equalsIgnoreCase(SET_UP_PROVIDER)) {
- Bundle result = setUpProvider(parameters);
+ Bundle result = setUpProvider(provider, parameters);
if (go_ahead) {
- if (result.getBoolean(RESULT_KEY)) {
- sendToReceiverOrBroadcast(receiver, PROVIDER_OK, result);
+ if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ sendToReceiverOrBroadcast(receiver, PROVIDER_OK, result, provider);
} else {
- sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result);
+ sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result, provider);
}
}
} else if (action.equalsIgnoreCase(SIGN_UP)) {
- UserStatus.updateStatus(UserStatus.SessionStatus.SIGNING_UP, resources);
Bundle result = tryToRegister(parameters);
- if (result.getBoolean(RESULT_KEY)) {
- sendToReceiverOrBroadcast(receiver, SUCCESSFUL_SIGNUP, result);
+ if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ sendToReceiverOrBroadcast(receiver, SUCCESSFUL_SIGNUP, result, provider);
} else {
- sendToReceiverOrBroadcast(receiver, FAILED_SIGNUP, result);
+ sendToReceiverOrBroadcast(receiver, FAILED_SIGNUP, result, provider);
}
} else if (action.equalsIgnoreCase(LOG_IN)) {
- UserStatus.updateStatus(UserStatus.SessionStatus.LOGGING_IN, resources);
- Bundle result = tryToAuthenticate(parameters);
- if (result.getBoolean(RESULT_KEY)) {
- sendToReceiverOrBroadcast(receiver, SUCCESSFUL_LOGIN, result);
- UserStatus.updateStatus(UserStatus.SessionStatus.LOGGED_IN, resources);
+ Bundle result = tryToAuthenticate(provider, parameters);
+ if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ sendToReceiverOrBroadcast(receiver, SUCCESSFUL_LOGIN, result, provider);
} else {
- sendToReceiverOrBroadcast(receiver, FAILED_LOGIN, result);
- UserStatus.updateStatus(UserStatus.SessionStatus.NOT_LOGGED_IN, resources);
+ sendToReceiverOrBroadcast(receiver, FAILED_LOGIN, result, provider);
}
} else if (action.equalsIgnoreCase(LOG_OUT)) {
- UserStatus.updateStatus(UserStatus.SessionStatus.LOGGING_OUT, resources);
- if (logOut()) {
- sendToReceiverOrBroadcast(receiver, SUCCESSFUL_LOGOUT, Bundle.EMPTY);
- UserStatus.updateStatus(UserStatus.SessionStatus.LOGGED_OUT, resources);
+ if (logOut(provider)) {
+ sendToReceiverOrBroadcast(receiver, SUCCESSFUL_LOGOUT, Bundle.EMPTY, provider);
} else {
- sendToReceiverOrBroadcast(receiver, LOGOUT_FAILED, Bundle.EMPTY);
- UserStatus.updateStatus(UserStatus.SessionStatus.DIDNT_LOG_OUT, resources);
+ sendToReceiverOrBroadcast(receiver, LOGOUT_FAILED, Bundle.EMPTY, provider);
}
} else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) {
- if (updateVpnCertificate()) {
- sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY);
+ if (updateVpnCertificate(provider)) {
+ sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY, provider);
} else {
- sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY);
+ sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY, provider);
}
} else if (action.equalsIgnoreCase(DOWNLOAD_EIP_SERVICE)) {
- Bundle result = getAndSetEipServiceJson();
- if (result.getBoolean(RESULT_KEY)) {
- sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_EIP_SERVICE, result);
+ Bundle result = getAndSetEipServiceJson(provider);
+ if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_EIP_SERVICE, result, provider);
} else {
- sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_EIP_SERVICE, result);
+ sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_EIP_SERVICE, result, provider);
}
} else if (action.equalsIgnoreCase(PROVIDER_SET_UP)) {
- if(EIP_SERVICE_JSON_DOWNLOADED && CA_CERT_DOWNLOADED && PROVIDER_JSON_DOWNLOADED ) {
+ if(provider.hasEIP() && provider.hasCaCert() && provider.hasDefinition()) {
if(receiver!= null) {
- sendToReceiverOrBroadcast(receiver, PROVIDER_OK, Bundle.EMPTY);
+ Bundle result = new Bundle();
+ result.putParcelable(PROVIDER_KEY, provider);
+ receiver.send(PROVIDER_OK, result);
}
}
}
}
- protected void resetProviderDetails() {
- CA_CERT_DOWNLOADED = PROVIDER_JSON_DOWNLOADED = false;
- deleteProviderDetailsFromPreferences(providerDefinition);
- providerCaCert = "";
- providerDefinition = new JSONObject();
+ void resetProviderDetails(Provider provider) {
+ provider.setCaCert("");
+ provider.define(new JSONObject());
+ provider.setEipServiceJson(new JSONObject());
+
+ deleteProviderDetailsFromPreferences(provider.getDomain());
}
- protected String formatErrorMessage(final int toastStringId) {
+ String formatErrorMessage(final int toastStringId) {
return formatErrorMessage(resources.getString(toastStringId));
}
@@ -256,7 +235,7 @@ public abstract class ProviderApiManagerBase {
}
}
- protected void addErrorMessageToJson(JSONObject jsonObject, String errorMessage) {
+ private void addErrorMessageToJson(JSONObject jsonObject, String errorMessage) {
try {
jsonObject.put(ERRORS, errorMessage);
} catch (JSONException e) {
@@ -264,7 +243,7 @@ public abstract class ProviderApiManagerBase {
}
}
- protected void addErrorMessageToJson(JSONObject jsonObject, String errorMessage, String errorId) {
+ private void addErrorMessageToJson(JSONObject jsonObject, String errorMessage, String errorId) {
try {
jsonObject.put(ERRORS, errorMessage);
jsonObject.put(ERRORID, errorId);
@@ -278,32 +257,37 @@ public abstract class ProviderApiManagerBase {
private Bundle tryToRegister(Bundle task) {
Bundle result = new Bundle();
- int progress = 0;
- String username = User.userName();
- String password = task.getString(SessionDialog.PASSWORD);
+ String username = task.getString(CREDENTIALS_USERNAME);
+ String password = task.getString(CREDENTIALS_PASSWORD);
+ Provider provider = task.getParcelable(PROVIDER_KEY);
+
+ if(provider == null) {
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ Log.e(TAG, "no provider when trying to register");
+ return result;
+ }
if (validUserLoginData(username, password)) {
- result = register(username, password);
- broadcastProgress(progress++);
+ result = register(provider, username, password);
} else {
if (!wellFormedPassword(password)) {
- result.putBoolean(RESULT_KEY, false);
- result.putString(SessionDialog.USERNAME, username);
- result.putBoolean(SessionDialog.ERRORS.PASSWORD_INVALID_LENGTH.toString(), true);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ result.putString(CREDENTIALS_USERNAME, username);
+ result.putBoolean(CREDENTIAL_ERRORS.PASSWORD_INVALID_LENGTH.toString(), true);
}
if (!validUsername(username)) {
- result.putBoolean(RESULT_KEY, false);
- result.putBoolean(SessionDialog.ERRORS.USERNAME_MISSING.toString(), true);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ result.putBoolean(CREDENTIAL_ERRORS.USERNAME_MISSING.toString(), true);
}
}
return result;
}
- private Bundle register(String username, String password) {
+ private Bundle register(Provider provider, String username, String password) {
JSONObject stepResult = null;
- OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(stepResult);
+ OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), stepResult);
if (okHttpClient == null) {
return authFailedNotification(stepResult, username);
}
@@ -313,15 +297,15 @@ public abstract class ProviderApiManagerBase {
BigInteger password_verifier = client.calculateV(username, password, salt);
- JSONObject api_result = sendNewUserDataToSRPServer(providerApiUrl, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16), okHttpClient);
+ JSONObject api_result = sendNewUserDataToSRPServer(provider.getApiUrlString(), username, new BigInteger(1, salt).toString(16), password_verifier.toString(16), okHttpClient);
Bundle result = new Bundle();
if (api_result.has(ERRORS))
result = authFailedNotification(api_result, username);
else {
- result.putString(SessionDialog.USERNAME, username);
- result.putString(SessionDialog.PASSWORD, password);
- result.putBoolean(RESULT_KEY, true);
+ result.putString(CREDENTIALS_USERNAME, username);
+ result.putString(CREDENTIALS_PASSWORD, password);
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
}
return result;
@@ -330,37 +314,39 @@ public abstract class ProviderApiManagerBase {
/**
* Starts the authentication process using SRP protocol.
*
- * @param task containing: username, password and api url.
- * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if authentication was successful.
+ * @param task containing: username, password and provider
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if authentication was successful.
*/
- private Bundle tryToAuthenticate(Bundle task) {
+ private Bundle tryToAuthenticate(Provider provider, Bundle task) {
Bundle result = new Bundle();
- int progress = 0;
- String username = User.userName();
- String password = task.getString(SessionDialog.PASSWORD);
+ String username = task.getString(CREDENTIALS_USERNAME);
+ String password = task.getString(CREDENTIALS_PASSWORD);
+
if (validUserLoginData(username, password)) {
- result = authenticate(username, password);
- broadcastProgress(progress++);
+ result = authenticate(provider, username, password);
} else {
if (!wellFormedPassword(password)) {
- result.putBoolean(RESULT_KEY, false);
- result.putString(SessionDialog.USERNAME, username);
- result.putBoolean(SessionDialog.ERRORS.PASSWORD_INVALID_LENGTH.toString(), true);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ result.putString(CREDENTIALS_USERNAME, username);
+ result.putBoolean(CREDENTIAL_ERRORS.PASSWORD_INVALID_LENGTH.toString(), true);
}
if (!validUsername(username)) {
- result.putBoolean(RESULT_KEY, false);
- result.putBoolean(SessionDialog.ERRORS.USERNAME_MISSING.toString(), true);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ result.putBoolean(CREDENTIAL_ERRORS.USERNAME_MISSING.toString(), true);
}
}
return result;
}
- private Bundle authenticate(String username, String password) {
+ private Bundle authenticate(Provider provider, String username, String password) {
Bundle result = new Bundle();
JSONObject stepResult = new JSONObject();
- OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(stepResult);
+
+ String providerApiUrl = provider.getApiUrlWithVersion();
+
+ OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), stepResult);
if (okHttpClient == null) {
return authFailedNotification(stepResult, username);
}
@@ -378,13 +364,13 @@ public abstract class ProviderApiManagerBase {
setTokenIfAvailable(step_result);
byte[] M2 = new BigInteger(step_result.getString(LeapSRPSession.M2), 16).toByteArray();
if (client.verify(M2)) {
- result.putBoolean(RESULT_KEY, true);
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} else {
authFailedNotification(step_result, username);
}
} else {
- result.putBoolean(RESULT_KEY, false);
- result.putString(SessionDialog.USERNAME, username);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ result.putString(CREDENTIALS_USERNAME, username);
result.putString(resources.getString(R.string.user_message), resources.getString(R.string.error_srp_math_error_user_message));
}
} catch (JSONException e) {
@@ -428,38 +414,29 @@ public abstract class ProviderApiManagerBase {
}
if (!username.isEmpty())
- userNotificationBundle.putString(SessionDialog.USERNAME, username);
- userNotificationBundle.putBoolean(RESULT_KEY, false);
+ userNotificationBundle.putString(CREDENTIALS_USERNAME, username);
+ userNotificationBundle.putBoolean(BROADCAST_RESULT_KEY, false);
return userNotificationBundle;
}
- void sendToReceiverOrBroadcast(ResultReceiver receiver, int resultCode, Bundle resultData) {
+ void sendToReceiverOrBroadcast(ResultReceiver receiver, int resultCode, Bundle resultData, Provider provider) {
+ if (resultData == null || resultData == Bundle.EMPTY) {
+ resultData = new Bundle();
+ }
+ resultData.putParcelable(PROVIDER_KEY, provider);
if (receiver != null) {
receiver.send(resultCode, resultData);
} else {
- broadcastEvent(PROVIDER_API_EVENT, resultCode, resultData);
+ broadcastEvent(resultCode, resultData);
}
}
- /**
- * Sets up an intent with the progress value passed as a parameter
- * and sends it as a broadcast.
- *
- * @param progress
- */
- void broadcastProgress(int progress) {
- Intent intentUpdate = new Intent(UPDATE_PROGRESSBAR);
- intentUpdate.addCategory(Intent.CATEGORY_DEFAULT);
- intentUpdate.putExtra(CURRENT_PROGRESS, progress);
- serviceCallback.broadcastEvent(intentUpdate);
- }
-
- void broadcastEvent(String action, int resultCode , Bundle resultData) {
- Intent intentUpdate = new Intent(action);
+ private void broadcastEvent(int resultCode , Bundle resultData) {
+ Intent intentUpdate = new Intent(BROADCAST_PROVIDER_API_EVENT);
intentUpdate.addCategory(Intent.CATEGORY_DEFAULT);
- intentUpdate.putExtra(RESULT_CODE, resultCode);
- intentUpdate.putExtra(RESULT_KEY, resultData);
+ intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode);
+ intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData);
serviceCallback.broadcastEvent(intentUpdate);
}
@@ -627,29 +604,25 @@ public abstract class ProviderApiManagerBase {
/**
* 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.
+ * @param task containing a boolean meaning if the provider is custom or not, another boolean meaning if the user completely trusts this provider
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if the update was successful.
*/
- protected abstract Bundle setUpProvider(Bundle task);
+ protected abstract Bundle setUpProvider(Provider provider, Bundle task);
/**
* Downloads the eip-service.json from a given URL, and saves eip service capabilities including the offered gateways
- * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the download was successful.
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if the download was successful.
*/
- protected abstract Bundle getAndSetEipServiceJson();
+ protected abstract Bundle getAndSetEipServiceJson(Provider provider);
/**
* Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate.
*
* @return true if certificate was downloaded correctly, false if provider.json is not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error.
*/
- protected abstract boolean updateVpnCertificate();
+ protected abstract boolean updateVpnCertificate(Provider provider);
- protected static boolean caCertDownloaded() {
- return CA_CERT_DOWNLOADED;
- }
-
protected boolean isValidJson(String jsonString) {
try {
new JSONObject(jsonString);
@@ -662,19 +635,19 @@ public abstract class ProviderApiManagerBase {
}
}
- protected boolean validCertificate(String cert_string) {
+ protected boolean validCertificate(Provider provider, String certString) {
boolean result = false;
- if (!ConfigHelper.checkErroneousDownload(cert_string)) {
- X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(cert_string);
+ if (!ConfigHelper.checkErroneousDownload(certString)) {
+ X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certString);
try {
if (certificate != null) {
- JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
- String fingerprint = provider_json.getString(Provider.CA_CERT_FINGERPRINT);
+ JSONObject providerJson = provider.getDefinition();
+ String fingerprint = providerJson.getString(Provider.CA_CERT_FINGERPRINT);
String encoding = fingerprint.split(":")[0];
- String expected_fingerprint = fingerprint.split(":")[1];
- String real_fingerprint = getFingerprintFromCertificate(certificate, encoding);
+ String expectedFingerprint = fingerprint.split(":")[1];
+ String realFingerprint = getFingerprintFromCertificate(certificate, encoding);
- result = real_fingerprint.trim().equalsIgnoreCase(expected_fingerprint.trim());
+ result = realFingerprint.trim().equalsIgnoreCase(expectedFingerprint.trim());
} else
result = false;
} catch (JSONException | NoSuchAlgorithmException | CertificateEncodingException e) {
@@ -685,50 +658,41 @@ public abstract class ProviderApiManagerBase {
return result;
}
- protected void checkPersistedProviderUpdates() {
- String providerDomain = getDomainFromMainURL(lastProviderMainUrl);
+ protected void getPersistedProviderUpdates(Provider provider) {
+ String providerDomain = getDomainFromMainURL(provider.getMainUrlString());
if (hasUpdatedProviderDetails(providerDomain)) {
- providerCaCert = getPersistedProviderCA(providerDomain);
- providerDefinition = getPersistedProviderDefinition(providerDomain);
- providerCaCertFingerprint = getPersistedCaCertFingerprint(providerDomain);
- providerApiUrl = getApiUrlWithVersion(providerDefinition);
+ provider.setCaCert(getPersistedProviderCA(providerDomain));
+ provider.define(getPersistedProviderDefinition(providerDomain));
+ provider.setCaCertFingerprint(getPersistedCaCertFingerprint(providerDomain));
}
}
- protected Bundle validateProviderDetails() {
- Bundle result = validateCertificateForProvider(providerCaCert, providerDefinition, lastProviderMainUrl);
+ Bundle validateProviderDetails(Provider provider) {
+ Bundle result = validateCertificateForProvider(provider);
//invalid certificate or no certificate
- if (result.containsKey(ERRORS) || (result.containsKey(RESULT_KEY) && !result.getBoolean(RESULT_KEY)) ) {
+ if (result.containsKey(ERRORS) || (result.containsKey(BROADCAST_RESULT_KEY) && !result.getBoolean(BROADCAST_RESULT_KEY)) ) {
return result;
}
- //valid certificate: skip download, save loaded provider CA cert and provider definition directly
- try {
- preferences.edit().putString(Provider.KEY, providerDefinition.toString()).
- putBoolean(PROVIDER_ALLOW_ANONYMOUS, providerDefinition.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOW_ANONYMOUS)).
- putBoolean(PROVIDER_ALLOWED_REGISTERED, providerDefinition.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOWED_REGISTERED)).
- putString(Provider.CA_CERT, providerCaCert).commit();
- CA_CERT_DOWNLOADED = true;
- PROVIDER_JSON_DOWNLOADED = true;
- result.putBoolean(RESULT_KEY, true);
- } catch (JSONException e) {
- e.printStackTrace();
- setErrorResult(result, warning_corrupted_provider_details, ERROR_CORRUPTED_PROVIDER_JSON.toString());
- }
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
return result;
}
- protected Bundle validateCertificateForProvider(String cert_string, JSONObject providerDefinition, String mainUrl) {
+ protected Bundle validateCertificateForProvider(Provider provider) {
Bundle result = new Bundle();
- result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+
+ String caCert = provider.getCaCert();
+ JSONObject providerDefinition = provider.getDefinition();
+ String mainUrl = provider.getMainUrlString();
- if (ConfigHelper.checkErroneousDownload(cert_string)) {
+ if (ConfigHelper.checkErroneousDownload(caCert)) {
return result;
}
- X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(cert_string);
+ X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(caCert);
if (certificate == null) {
return setErrorResult(result, warning_corrupted_provider_cert, ERROR_INVALID_CERTIFICATE.toString());
}
@@ -736,9 +700,9 @@ public abstract class ProviderApiManagerBase {
certificate.checkValidity();
String fingerprint = getCaCertFingerprint(providerDefinition);
String encoding = fingerprint.split(":")[0];
- String expected_fingerprint = fingerprint.split(":")[1];
- String real_fingerprint = getFingerprintFromCertificate(certificate, encoding);
- if (!real_fingerprint.trim().equalsIgnoreCase(expected_fingerprint.trim())) {
+ String expectedFingerprint = fingerprint.split(":")[1];
+ String realFingerprint = getFingerprintFromCertificate(certificate, encoding);
+ if (!realFingerprint.trim().equalsIgnoreCase(expectedFingerprint.trim())) {
return setErrorResult(result, warning_corrupted_provider_cert, ERROR_CERTIFICATE_PINNING.toString());
}
@@ -747,7 +711,7 @@ public abstract class ProviderApiManagerBase {
return setErrorResult(result, warning_corrupted_provider_details, ERROR_CORRUPTED_PROVIDER_JSON.toString());
}
- if (!canConnect(cert_string, providerDefinition, result)) {
+ if (!canConnect(caCert, providerDefinition, result)) {
return result;
}
} catch (NoSuchAlgorithmException e ) {
@@ -758,11 +722,11 @@ public abstract class ProviderApiManagerBase {
return setErrorResult(result, warning_expired_provider_cert, ERROR_INVALID_CERTIFICATE.toString());
}
- result.putBoolean(RESULT_KEY, true);
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
return result;
}
- protected Bundle setErrorResult(Bundle result, int errorMessageId, String errorId) {
+ Bundle setErrorResult(Bundle result, int errorMessageId, String errorId) {
JSONObject errorJson = new JSONObject();
if (errorId != null) {
addErrorMessageToJson(errorJson, resources.getString(errorMessageId), errorId);
@@ -770,7 +734,7 @@ public abstract class ProviderApiManagerBase {
addErrorMessageToJson(errorJson, resources.getString(errorMessageId));
}
result.putString(ERRORS, errorJson.toString());
- result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
return result;
}
@@ -811,17 +775,7 @@ public abstract class ProviderApiManagerBase {
return "";
}
- protected String getApiUrlWithVersion(JSONObject providerDefinition) {
- try {
- return providerDefinition.getString(Provider.API_URL) + "/" + providerDefinition.getString(Provider.API_VERSION);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return "";
- }
-
- protected void deleteProviderDetailsFromPreferences(JSONObject providerDefinition) {
- String providerDomain = getProviderDomain(providerDefinition);
+ protected void deleteProviderDetailsFromPreferences(String providerDomain) {
if (preferences.contains(Provider.KEY + "." + providerDomain)) {
preferences.edit().remove(Provider.KEY + "." + providerDomain).apply();
@@ -907,17 +861,15 @@ public abstract class ProviderApiManagerBase {
return headerArgs;
}
- private boolean logOut() {
- OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(new JSONObject());
+ private boolean logOut(Provider provider) {
+ OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), new JSONObject());
if (okHttpClient == null) {
return false;
}
- String deleteUrl = providerApiUrl + "/logout";
- int progress = 0;
+ String deleteUrl = provider.getApiUrlString() + "/logout";
if (ProviderApiConnector.delete(okHttpClient, deleteUrl)) {
- broadcastProgress(progress++);
LeapSRPSession.setToken("");
return true;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
index 25dca4e0..a309bdf9 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
@@ -20,17 +20,20 @@ import android.widget.TextView;
import butterknife.InjectView;
import butterknife.OnClick;
-import se.leap.bitmaskclient.userstatus.SessionDialog;
-import se.leap.bitmaskclient.userstatus.SessionDialog.ERRORS;
+import se.leap.bitmaskclient.Constants.CREDENTIAL_ERRORS;
import se.leap.bitmaskclient.userstatus.User;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
-import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY;
-import static se.leap.bitmaskclient.userstatus.SessionDialog.USERNAME;
+import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.CREDENTIALS_PASSWORD;
+import static se.leap.bitmaskclient.Constants.CREDENTIALS_USERNAME;
+import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.LOG_IN;
+import static se.leap.bitmaskclient.ProviderAPI.SIGN_UP;
/**
* Base Activity for activities concerning a provider interaction
@@ -84,7 +87,7 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
setContentView(R.layout.a_provider_credentials);
providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver();
- IntentFilter updateIntentFilter = new IntentFilter(PROVIDER_API_EVENT);
+ IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_PROVIDER_API_EVENT);
updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(providerAPIBroadcastReceiver, updateIntentFilter);
@@ -178,34 +181,27 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
void login(String username, String password) {
User.setUserName(username);
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
- Bundle parameters = bundlePassword(password);
- providerAPICommand.setAction(ProviderAPI.LOG_IN);
- providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters);
- startService(providerAPICommand);
+ Bundle parameters = bundleUsernameAndPassword(username, password);
+ ProviderAPICommand.execute(this, LOG_IN, parameters, provider);
}
public void signUp(String username, String password) {
User.setUserName(username);
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
- Bundle parameters = bundlePassword(password);
- providerAPICommand.setAction(ProviderAPI.SIGN_UP);
- providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters);
- startService(providerAPICommand);
+ Bundle parameters = bundleUsernameAndPassword(username, password);
+ ProviderAPICommand.execute(this, SIGN_UP, parameters, provider);
}
void downloadVpnCertificate() {
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
- providerAPICommand.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE);
- providerAPICommand.putExtra(ProviderAPI.PARAMETERS, Bundle.EMPTY);
- startService(providerAPICommand);
+ ProviderAPICommand.execute(this, DOWNLOAD_CERTIFICATE, provider);
}
- protected Bundle bundlePassword(String password) {
+ protected Bundle bundleUsernameAndPassword(String username, String password) {
Bundle parameters = new Bundle();
+ if (!username.isEmpty())
+ parameters.putString(CREDENTIALS_USERNAME, username);
if (!password.isEmpty())
- parameters.putString(SessionDialog.PASSWORD, password);
+ parameters.putString(CREDENTIALS_PASSWORD, password);
return parameters;
}
@@ -316,17 +312,17 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
}
private void handleReceivedErrors(Bundle arguments) {
- if (arguments.containsKey(ERRORS.PASSWORD_INVALID_LENGTH.toString()))
+ if (arguments.containsKey(CREDENTIAL_ERRORS.PASSWORD_INVALID_LENGTH.toString()))
passwordError.setError(getString(R.string.error_not_valid_password_user_message));
- else if (arguments.containsKey(ERRORS.RISEUP_WARNING.toString())) {
+ else if (arguments.containsKey(CREDENTIAL_ERRORS.RISEUP_WARNING.toString())) {
userMessage.setVisibility(VISIBLE);
userMessage.setText(R.string.login_riseup_warning);
}
- if (arguments.containsKey(USERNAME)) {
- String username = arguments.getString(USERNAME);
+ if (arguments.containsKey(CREDENTIALS_USERNAME)) {
+ String username = arguments.getString(CREDENTIALS_USERNAME);
usernameField.setText(username);
}
- if (arguments.containsKey(ERRORS.USERNAME_MISSING.toString())) {
+ if (arguments.containsKey(CREDENTIAL_ERRORS.USERNAME_MISSING.toString())) {
usernameError.setError(getString(R.string.username_ask));
}
if (arguments.containsKey(getString(R.string.user_message))) {
@@ -356,11 +352,11 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
Log.d(TAG, "received Broadcast");
String action = intent.getAction();
- if (action == null || !action.equalsIgnoreCase(PROVIDER_API_EVENT)) {
+ if (action == null || !action.equalsIgnoreCase(BROADCAST_PROVIDER_API_EVENT)) {
return;
}
- int resultCode = intent.getIntExtra(RESULT_CODE, -1);
+ int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, -1);
switch (resultCode) {
case ProviderAPI.SUCCESSFUL_SIGNUP:
case ProviderAPI.SUCCESSFUL_LOGIN:
@@ -368,7 +364,7 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
break;
case ProviderAPI.FAILED_LOGIN:
case ProviderAPI.FAILED_SIGNUP:
- handleReceivedErrors((Bundle) intent.getParcelableExtra(RESULT_KEY));
+ handleReceivedErrors((Bundle) intent.getParcelableExtra(BROADCAST_RESULT_KEY));
break;
case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE:
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java
index aee00765..c89e7a49 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java
@@ -32,6 +32,7 @@ import android.widget.ListView;
import com.pedrogomez.renderers.Renderer;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
@@ -46,18 +47,19 @@ import se.leap.bitmaskclient.fragments.AboutFragment;
import static android.view.View.GONE;
import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
+import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.ERRORS;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE;
-import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY;
+import static se.leap.bitmaskclient.ProviderAPI.UPDATE_PROVIDER_DETAILS;
/**
* abstract base Activity that builds and shows the list of known available providers.
@@ -100,7 +102,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
private boolean isActivityShowing;
private String reasonToFail;
- public abstract void retrySetUpProvider();
+ public abstract void retrySetUpProvider(Provider provider);
protected abstract void onItemSelectedLogic();
@@ -116,7 +118,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
@Override
protected void onSaveInstanceState(@NotNull Bundle outState) {
outState.putString(ACTIVITY_STATE, mConfigState.getAction());
- outState.putParcelable(Provider.KEY, provider);
+ outState.putParcelable(PROVIDER_KEY, provider);
DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag(DownloadFailedDialog.TAG);
if (dialogFragment != null) {
@@ -139,7 +141,6 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
if (savedInstanceState != null)
restoreState(savedInstanceState);
- setUpProviderAPIResultReceiver();
}
private void restoreState(Bundle savedInstanceState) {
@@ -163,6 +164,7 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
protected void onResume() {
Log.d(TAG, "resuming with ConfigState: " + mConfigState.getAction());
super.onResume();
+ setUpProviderAPIResultReceiver();
hideProgressBar();
isActivityShowing = true;
if (SETTING_UP_PROVIDER.equals(mConfigState.getAction())) {
@@ -185,13 +187,13 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
protected void onPause() {
super.onPause();
isActivityShowing = false;
+ if (providerAPIBroadcastReceiver != null)
+ unregisterReceiver(providerAPIBroadcastReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
- if (providerAPIBroadcastReceiver != null)
- unregisterReceiver(providerAPIBroadcastReceiver);
providerAPIResultReceiver = null;
}
@@ -208,25 +210,17 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
private void setUpProviderAPIResultReceiver() {
providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), this);
providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver();
- IntentFilter updateIntentFilter = new IntentFilter(PROVIDER_API_EVENT);
+
+ IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_PROVIDER_API_EVENT);
updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(providerAPIBroadcastReceiver, updateIntentFilter);
}
- void handleProviderSetUp() {
- try {
- String providerJsonString = preferences.getString(Provider.KEY, "");
- if (!providerJsonString.isEmpty())
- provider.define(new JSONObject(providerJsonString));
- String caCert = preferences.getString(Provider.CA_CERT, "");
- provider.setCACert(caCert);
- } catch (JSONException e) {
- e.printStackTrace();
- }
+ void handleProviderSetUp(Provider handledProvider) {
+ this.provider = handledProvider;
- if (preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false)) {
+ if (provider.allowsAnonymous()) {
mConfigState.putExtra(SERVICES_RETRIEVED, true);
-
downloadVpnCertificate();
} else {
showProviderDetails();
@@ -235,7 +229,6 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
void handleProviderSetupFailed(Bundle resultData) {
mConfigState.setAction(PROVIDER_NOT_SET);
- preferences.edit().remove(Provider.KEY).apply();
setResult(RESULT_CANCELED, mConfigState);
@@ -256,7 +249,8 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == ProviderAPI.PROVIDER_OK) {
- handleProviderSetUp();
+ Provider provider = resultData.getParcelable(PROVIDER_KEY);
+ handleProviderSetUp(provider);
} else if (resultCode == AboutFragment.VIEWED) {
// Do nothing, right now
// I need this for CW to wait for the About activity to end before going back to Dashboard.
@@ -304,27 +298,20 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
public void cancelSettingUpProvider() {
hideProgressBar();
mConfigState.setAction(PROVIDER_NOT_SET);
- preferences.edit().remove(Provider.KEY).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply();
}
@Override
public void updateProviderDetails() {
mConfigState.setAction(SETTING_UP_PROVIDER);
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
- providerAPICommand.setAction(ProviderAPI.UPDATE_PROVIDER_DETAILS);
Bundle parameters = new Bundle();
parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString());
- providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters);
- startService(providerAPICommand);
+ ProviderAPICommand.execute(this, UPDATE_PROVIDER_DETAILS, parameters, provider);
}
public void checkProviderSetUp() {
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
- providerAPICommand.setAction(PROVIDER_SET_UP);
- providerAPICommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver);
- startService(providerAPICommand);
+ ProviderAPICommand.execute(this, PROVIDER_SET_UP, provider, providerAPIResultReceiver);
}
private void askDashboardToQuitApp() {
@@ -337,29 +324,30 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
* Asks ProviderApiService to download an anonymous (anon) VPN certificate.
*/
private void downloadVpnCertificate() {
- Intent providerAPICommand = new Intent(this, ProviderAPI.class);
- providerAPICommand.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE);
- startService(providerAPICommand);
+ ProviderAPICommand.execute(this, DOWNLOAD_CERTIFICATE, provider);
}
/**
* Open the new provider dialog
*/
public void addAndSelectNewProvider() {
- FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG);
- new NewProviderDialog().show(fragmentTransaction, NewProviderDialog.TAG);
+ addAndSelectNewProvider(null);
}
/**
- * Open the new provider dialog with data
+ * Open the new provider dialog
+ * @param mainUrl - the main url of the provider to add - if null add a new provider
*/
- public void addAndSelectNewProvider(String main_url) {
+ public void addAndSelectNewProvider(@Nullable String mainUrl) {
FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG);
DialogFragment newFragment = new NewProviderDialog();
- Bundle data = new Bundle();
- data.putString(Provider.MAIN_URL, main_url);
- newFragment.setArguments(data);
+
+ if (mainUrl != null) {
+ Bundle data = new Bundle();
+ data.putString(Provider.MAIN_URL, mainUrl);
+ newFragment.setArguments(data);
+ }
newFragment.show(fragmentTransaction, NewProviderDialog.TAG);
}
@@ -422,51 +410,33 @@ public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity
Log.d(TAG, "received Broadcast");
String action = intent.getAction();
- if (action == null || !action.equalsIgnoreCase(PROVIDER_API_EVENT)) {
+ if (action == null || !action.equalsIgnoreCase(BROADCAST_PROVIDER_API_EVENT)) {
return;
}
if (mConfigState.getAction() != null &&
mConfigState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) {
- int resultCode = intent.getIntExtra(RESULT_CODE, -1);
+ int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, -1);
Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode));
- Bundle resultData = intent.getParcelableExtra(RESULT_KEY);
- String handledProvider = resultData.getString(Provider.KEY);
-
- String providerName = ConfigHelper.getProviderName(handledProvider);
- String providerDomain = ConfigHelper.getProviderDomain(handledProvider);
-
- //FIXME: remove that lines as soon as Provider gets sent via broadcast
- // and make sure providers are the same - remove providersMatch
- if (resultCode == PROVIDER_OK && handledProvider == null) {
- providerName = ConfigHelper.getProviderName(preferences);
- providerDomain = ConfigHelper.getProviderDomain(preferences);
- }
- boolean providersMatch = true;
- if (providerDomain != null) {
- providersMatch = providerDomain.equalsIgnoreCase(provider.getDomain());
- }
- if (providerName != null && !providersMatch) {
- providersMatch = providerName.equalsIgnoreCase(provider.getName());
- }
-
+ Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY);
+ Provider handledProvider = resultData.getParcelable(PROVIDER_KEY);
- switch (resultCode) {
- case PROVIDER_OK:
- if (providersMatch)
- handleProviderSetUp();
- break;
- case PROVIDER_NOK:
- if(providersMatch)
+ if (handledProvider != null && handledProvider.getDomain().equalsIgnoreCase(provider.getDomain())) {
+ switch (resultCode) {
+ case PROVIDER_OK:
+ handleProviderSetUp(handledProvider);
+ break;
+ case PROVIDER_NOK:
handleProviderSetupFailed(resultData);
- break;
- case CORRECTLY_DOWNLOADED_CERTIFICATE:
- handleCorrectlyDownloadedCertificate();
- break;
- case INCORRECTLY_DOWNLOADED_CERTIFICATE:
- handleIncorrectlyDownloadedCertificate();
- break;
+ break;
+ case CORRECTLY_DOWNLOADED_CERTIFICATE:
+ handleCorrectlyDownloadedCertificate();
+ break;
+ case INCORRECTLY_DOWNLOADED_CERTIFICATE:
+ handleIncorrectlyDownloadedCertificate();
+ break;
+ }
}
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
index f5991538..616264f9 100644
--- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
@@ -69,7 +69,6 @@ public class StartActivity extends Activity {
}
// initialize app necessities
- ProviderAPICommand.initialize(getApplicationContext());
VpnStatus.initLogCache(getApplicationContext().getCacheDir());
User.init(getString(R.string.default_username));
diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
index 090e8d26..64d1bb72 100644
--- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
@@ -1,7 +1,6 @@
package se.leap.bitmaskclient.drawer;
-import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@@ -137,19 +136,11 @@ public class NavigationDrawerFragment extends Fragment {
}
});
-
-
accountListAdapter = new ArrayAdapter<>(actionBar.getThemedContext(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1);
- String providerName = ConfigHelper.getProviderName(preferences);
- if (providerName == null) {
- //TODO: ADD A header to the ListView containing a useful message.
- //TODO 2: disable switchProvider
- } else {
- accountListAdapter.add(providerName);
- }
+ createListAdapterData();
mDrawerAccountsListView.setAdapter(accountListAdapter);
@@ -226,16 +217,6 @@ public class NavigationDrawerFragment extends Fragment {
}
@Override
- public void onAttach(Context context) {
- super.onAttach(context);
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- }
-
- @Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@@ -301,10 +282,7 @@ public class NavigationDrawerFragment extends Fragment {
Log.d("Drawer", String.format("Selected position %d", position));
switch (position) {
case 0:
- // TODO STOP VPN
- // if (provider.hasEIP()) eip_fragment.stopEipIfPossible();
- preferences.edit().clear().apply();
- startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
+ getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
break;
case 1:
mTitle = getString(R.string.log_fragment_title);
@@ -337,4 +315,21 @@ public class NavigationDrawerFragment extends Fragment {
}
+ public void refresh() {
+ createListAdapterData();
+ accountListAdapter.notifyDataSetChanged();
+ mDrawerAccountsListView.setAdapter(accountListAdapter);
+ }
+
+ private void createListAdapterData() {
+ accountListAdapter.clear();
+ String providerName = ConfigHelper.getProviderName(preferences);
+ if (providerName == null) {
+ //TODO: ADD A header to the ListView containing a useful message.
+ //TODO 2: disable switchProvider
+ } else {
+ accountListAdapter.add(providerName);
+ }
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index eca5b881..e53d81d9 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -30,6 +30,9 @@ import org.json.JSONObject;
import de.blinkt.openvpn.LaunchVPN;
import se.leap.bitmaskclient.OnBootReceiver;
+import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_IS_RUNNING;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
@@ -123,9 +126,9 @@ public final class EIP extends IntentService {
gateway = gatewaysManager.select();
if (gateway != null && gateway.getProfile() != null) {
launchActiveGateway();
- tellToReceiver(EIP_ACTION_START, Activity.RESULT_OK);
+ tellToReceiverOrBroadcast(EIP_ACTION_START, Activity.RESULT_OK);
} else
- tellToReceiver(EIP_ACTION_START, Activity.RESULT_CANCELED);
+ tellToReceiverOrBroadcast(EIP_ACTION_START, Activity.RESULT_CANCELED);
}
/**
@@ -173,7 +176,7 @@ public final class EIP extends IntentService {
if (eipStatus.isConnected() || eipStatus.isConnecting())
resultCode = Activity.RESULT_OK;
- tellToReceiver(EIP_ACTION_STOP, resultCode);
+ tellToReceiverOrBroadcast(EIP_ACTION_STOP, resultCode);
}
/**
@@ -186,7 +189,7 @@ public final class EIP extends IntentService {
int resultCode = (eipStatus.isConnected()) ?
Activity.RESULT_OK :
Activity.RESULT_CANCELED;
- tellToReceiver(EIP_ACTION_IS_RUNNING, resultCode);
+ tellToReceiverOrBroadcast(EIP_ACTION_IS_RUNNING, resultCode);
}
/**
@@ -197,7 +200,7 @@ public final class EIP extends IntentService {
eipDefinition = eipDefinitionFromPreferences();
if (eipDefinition.length() > 0)
updateGateways();
- tellToReceiver(EIP_ACTION_UPDATE, Activity.RESULT_OK);
+ tellToReceiverOrBroadcast(EIP_ACTION_UPDATE, Activity.RESULT_OK);
}
private JSONObject eipDefinitionFromPreferences() {
@@ -237,14 +240,26 @@ public final class EIP extends IntentService {
int resultCode = validator.isValid() ?
Activity.RESULT_OK :
Activity.RESULT_CANCELED;
- tellToReceiver(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode);
+ tellToReceiverOrBroadcast(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode);
}
- private void tellToReceiver(String action, int resultCode) {
+ private void tellToReceiverOrBroadcast(String action, int resultCode) {
+ Bundle resultData = new Bundle();
+ resultData.putString(EIP_REQUEST, action);
if (mReceiver != null) {
- Bundle resultData = new Bundle();
- resultData.putString(EIP_REQUEST, action);
mReceiver.send(resultCode, resultData);
+ } else {
+ broadcastEvent(resultCode, resultData);
}
}
+
+ private void broadcastEvent(int resultCode , Bundle resultData) {
+ Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT);
+ intentUpdate.addCategory(Intent.CATEGORY_DEFAULT);
+ intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode);
+ intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData);
+ Log.d(TAG, "sending broadcast");
+ sendBroadcast(intentUpdate);
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
new file mode 100644
index 00000000..35599ab4
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
@@ -0,0 +1,66 @@
+package se.leap.bitmaskclient.eip;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.ResultReceiver;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE;
+import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
+
+/**
+ * Use this class to send commands to EIP
+ */
+
+public class EipCommand {
+
+ public static void execute(@NotNull Context context, @NotNull String action) {
+ execute(context, action, null);
+ }
+
+ /**
+ * Send a command to EIP
+ * @param context the context to start the command from
+ * @param action A valid String constant from EIP class representing an Intent
+ * filter for the EIP class
+ * @param resultReceiver The resultreceiver to reply to
+ */
+ public static void execute(@NotNull Context context, @NotNull String action, @Nullable ResultReceiver resultReceiver) {
+ // TODO validate "action"...how do we get the list of intent-filters for a class via Android API?
+ Intent vpnIntent = new Intent(context.getApplicationContext(), EIP.class);
+ vpnIntent.setAction(action);
+ if (resultReceiver != null)
+ vpnIntent.putExtra(EIP_RECEIVER, resultReceiver);
+ context.startService(vpnIntent);
+ }
+
+ public static void updateEipService(Context context, ResultReceiver resultReceiver) {
+ execute(context, EIP_ACTION_UPDATE, resultReceiver);
+ }
+
+ public static void updateEipService(Context context) {
+ execute(context, EIP_ACTION_UPDATE);
+ }
+
+ public static void startVPN(Context context) {
+ execute(context, EIP_ACTION_START);
+ }
+
+ public static void startVPN(Context context, ResultReceiver resultReceiver) {
+ execute(context, EIP_ACTION_START, resultReceiver);
+ }
+
+
+ public static void stopVPN(Context context) {
+ execute(context, EIP_ACTION_STOP);
+ }
+
+ public static void stopVPN(Context context, ResultReceiver resultReceiver) {
+ execute(context, EIP_ACTION_STOP, resultReceiver);
+ }
+
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java
deleted file mode 100644
index 29d4f01d..00000000
--- a/app/src/main/java/se/leap/bitmaskclient/userstatus/SessionDialog.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * Copyright (c) 2013 LEAP Encryption Access Project and contributers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-package se.leap.bitmaskclient.userstatus;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.support.v7.app.AppCompatActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import butterknife.ButterKnife;
-import butterknife.InjectView;
-import se.leap.bitmaskclient.Provider;
-import se.leap.bitmaskclient.R;
-
-import static android.view.View.VISIBLE;
-
-/**
- * Implements the log in dialog, currently without progress dialog.
- * <p/>
- * It returns to the previous fragment when finished, and sends username and password to the authenticate method.
- * <p/>
- * It also notifies the user if the password is not valid.
- *
- * @author parmegv
- */
-public class SessionDialog extends DialogFragment {
-
-
- final public static String TAG = SessionDialog.class.getSimpleName();
-
- final public static String USERNAME = "username";
- final public static String PASSWORD = "password";
-
- public enum ERRORS {
- USERNAME_MISSING,
- PASSWORD_INVALID_LENGTH,
- RISEUP_WARNING
- }
-
- @InjectView(R.id.user_message)
- TextView userMessage;
- @InjectView(R.id.username_entered)
- EditText usernameField;
- @InjectView(R.id.password_entered)
- EditText passwordField;
-
- public static SessionDialog getInstance(Provider provider, Bundle arguments) {
- SessionDialog dialog = new SessionDialog();
- if (provider.getName().equalsIgnoreCase("riseup")) {
- arguments =
- arguments == Bundle.EMPTY ?
- new Bundle() : arguments;
- arguments.putBoolean(SessionDialog.ERRORS.RISEUP_WARNING.toString(), true);
- }
- if (arguments != null && !arguments.isEmpty()) {
- dialog.setArguments(arguments);
- }
- return dialog;
- }
-
- public AlertDialog onCreateDialog(Bundle savedInstanceState) {
-
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View view = inflater.inflate(R.layout.session_dialog, null);
- ButterKnife.inject(this, view);
-
- Bundle arguments = getArguments();
- if (arguments != Bundle.EMPTY && arguments != null) {
- setUp(arguments);
- }
-
- builder.setView(view)
- .setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- String username = getEnteredUsername();
- String password = getEnteredPassword();
- dialog.dismiss();
- interface_with_Dashboard.logIn(username, password);
- }
- })
- .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- })
- .setNeutralButton(R.string.signup_button, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- String username = getEnteredUsername();
- String password = getEnteredPassword();
- dialog.dismiss();
- interface_with_Dashboard.signUp(username, password);
- }
- });
-
- return builder.create();
- }
-
- private void setUp(Bundle arguments) {
- if (arguments.containsKey(ERRORS.PASSWORD_INVALID_LENGTH.toString()))
- passwordField.setError(getString(R.string.error_not_valid_password_user_message));
- else if (arguments.containsKey(ERRORS.RISEUP_WARNING.toString())) {
- userMessage.setVisibility(VISIBLE);
- userMessage.setText(R.string.login_riseup_warning);
- }
- if (arguments.containsKey(USERNAME)) {
- String username = arguments.getString(USERNAME);
- usernameField.setText(username);
- }
- if (arguments.containsKey(ERRORS.USERNAME_MISSING.toString())) {
- usernameField.setError(getString(R.string.username_ask));
- }
- if (arguments.containsKey(getString(R.string.user_message))) {
- userMessage.setText(arguments.getString(getString(R.string.user_message)));
- userMessage.setVisibility(VISIBLE);
- } else if (userMessage.getVisibility() != VISIBLE)
- userMessage.setVisibility(View.GONE);
-
- if (!usernameField.getText().toString().isEmpty() && passwordField.isFocusable())
- passwordField.requestFocus();
-
- }
-
- private String getEnteredUsername() {
- return usernameField.getText().toString();
- }
-
- private String getEnteredPassword() {
- return passwordField.getText().toString();
- }
-
-
- /**
- * Interface used to communicate SessionDialog with Dashboard.
- *
- * @author parmegv
- */
- public interface SessionDialogInterface {
- void logIn(String username, String password);
-
- void signUp(String username, String password);
-
- }
-
- SessionDialogInterface interface_with_Dashboard;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
-
- try {
- interface_with_Dashboard = (SessionDialogInterface) ((AppCompatActivity) context).getSupportFragmentManager().getFragments().get(0);
- } catch (ClassCastException e) {
- throw new ClassCastException(context.toString()
- + " must implement LogInDialogListener");
- }
- }
-
-}
diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java
index 0f1d0cdb..70da20ac 100644
--- a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java
@@ -17,18 +17,19 @@ import java.util.Observer;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
-import se.leap.bitmaskclient.MainActivity;
import se.leap.bitmaskclient.Provider;
import se.leap.bitmaskclient.ProviderAPI;
import se.leap.bitmaskclient.ProviderAPICommand;
import se.leap.bitmaskclient.ProviderAPIResultReceiver;
import se.leap.bitmaskclient.R;
-public class UserStatusFragment extends Fragment implements Observer, SessionDialog.SessionDialogInterface {
+public class UserStatusFragment extends Fragment implements Observer {
public static String TAG = UserStatusFragment.class.getSimpleName();
private ProviderAPIResultReceiver providerAPI_result_receiver;
+ private Provider provider;
+
@InjectView(R.id.user_status_username)
TextView username;
@InjectView(R.id.user_status_icon)
@@ -87,8 +88,8 @@ public class UserStatusFragment extends Fragment implements Observer, SessionDia
android.util.Log.d(TAG, status.toString());
if(status.isLoggedIn())
logOut();
- else if(status.isLoggedOut())
- MainActivity.sessionDialog(Bundle.EMPTY);
+ //else if(status.isLoggedOut())
+ //MainActivity.sessionDialog(Bundle.EMPTY);
else if(status.inProgress())
cancelLoginOrSignup();
}
@@ -143,33 +144,13 @@ public class UserStatusFragment extends Fragment implements Observer, SessionDia
}
- @Override
- public void signUp(String username, String password) {
- User.setUserName(username);
- Bundle parameters = bundlePassword(password);
- ProviderAPICommand.execute(parameters, ProviderAPI.SIGN_UP, providerAPI_result_receiver);
- }
-
- @Override
- public void logIn(String username, String password) {
- User.setUserName(username);
- Bundle parameters = bundlePassword(password);
- ProviderAPICommand.execute(parameters, ProviderAPI.LOG_IN, providerAPI_result_receiver);
- }
-
public void logOut() {
android.util.Log.d(TAG, "Log out");
- ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.LOG_OUT, providerAPI_result_receiver);
+ ProviderAPICommand.execute(getActivity(), ProviderAPI.LOG_OUT, provider, providerAPI_result_receiver);
}
public void cancelLoginOrSignup() {
//EipStatus.getInstance().setConnectedOrDisconnected();
}
- private Bundle bundlePassword(String password) {
- Bundle parameters = new Bundle();
- if (!password.isEmpty())
- parameters.putString(SessionDialog.PASSWORD, password);
- return parameters;
- }
}
diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
index a30c9615..a4b3e491 100644
--- a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
+++ b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
@@ -33,13 +33,10 @@ import okhttp3.OkHttpClient;
import se.leap.bitmaskclient.eip.EIP;
import static android.text.TextUtils.isEmpty;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED;
-import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
-import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.DownloadFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
import static se.leap.bitmaskclient.ProviderAPI.ERRORS;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY;
import static se.leap.bitmaskclient.R.string.malformed_url;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
@@ -66,76 +63,42 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* 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.
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if the update was successful.
*/
@Override
- protected Bundle setUpProvider(Bundle task) {
+ protected Bundle setUpProvider(Provider provider, Bundle task) {
int progress = 0;
Bundle currentDownload = new Bundle();
- if (task != null) {
- //FIXME: this should be refactored in order to avoid static variables all over here
- lastProviderMainUrl = task.containsKey(Provider.MAIN_URL) ?
- task.getString(Provider.MAIN_URL) :
- "";
-
- if (isEmpty(lastProviderMainUrl)) {
- currentDownload.putBoolean(RESULT_KEY, false);
- setErrorResult(currentDownload, malformed_url, null);
- return currentDownload;
- }
-
- //TODO: remove that
- providerCaCertFingerprint = task.containsKey(Provider.CA_CERT_FINGERPRINT) ?
- task.getString(Provider.CA_CERT_FINGERPRINT) :
- "";
- providerCaCert = task.containsKey(Provider.CA_CERT) ?
- task.getString(Provider.CA_CERT) :
- "";
+ if (isEmpty(provider.getMainUrlString()) || provider.getMainUrl().isDefault()) {
+ currentDownload.putBoolean(BROADCAST_RESULT_KEY, false);
+ setErrorResult(currentDownload, malformed_url, null);
+ return currentDownload;
+ }
- try {
- providerDefinition = task.containsKey(Provider.KEY) ?
- new JSONObject(task.getString(Provider.KEY)) :
- new JSONObject();
- } catch (JSONException e) {
- e.printStackTrace();
- providerDefinition = new JSONObject();
- }
- providerApiUrl = getApiUrlWithVersion(providerDefinition);
+ getPersistedProviderUpdates(provider);
+ currentDownload = validateProviderDetails(provider);
- checkPersistedProviderUpdates();
- currentDownload = validateProviderDetails();
+ //provider details invalid
+ if (currentDownload.containsKey(ERRORS)) {
+ return currentDownload;
+ }
- //provider details invalid
- if (currentDownload.containsKey(ERRORS)) {
- return currentDownload;
- }
+ //no provider certificate available
+ if (currentDownload.containsKey(BROADCAST_RESULT_KEY) && !currentDownload.getBoolean(BROADCAST_RESULT_KEY)) {
+ resetProviderDetails(provider);
+ }
- //no provider certificate available
- if (currentDownload.containsKey(RESULT_KEY) && !currentDownload.getBoolean(RESULT_KEY)) {
- resetProviderDetails();
- }
+ go_ahead = true;
- EIP_SERVICE_JSON_DOWNLOADED = false;
- go_ahead = true;
+ if (!provider.hasDefinition()) {
+ currentDownload = getAndSetProviderJson(provider);
}
-
- if (!PROVIDER_JSON_DOWNLOADED)
- currentDownload = getAndSetProviderJson(lastProviderMainUrl, providerCaCert, providerDefinition);
- if (PROVIDER_JSON_DOWNLOADED || (currentDownload.containsKey(RESULT_KEY) && currentDownload.getBoolean(RESULT_KEY))) {
- broadcastProgress(++progress);
- PROVIDER_JSON_DOWNLOADED = true;
-
- if (!CA_CERT_DOWNLOADED)
- currentDownload = downloadCACert();
- if (CA_CERT_DOWNLOADED || (currentDownload.containsKey(RESULT_KEY) && currentDownload.getBoolean(RESULT_KEY))) {
- broadcastProgress(++progress);
- CA_CERT_DOWNLOADED = true;
- currentDownload = getAndSetEipServiceJson();
- if (currentDownload.containsKey(RESULT_KEY) && currentDownload.getBoolean(RESULT_KEY)) {
- broadcastProgress(++progress);
- EIP_SERVICE_JSON_DOWNLOADED = true;
- }
+ if (provider.hasDefinition() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) {
+ if (!provider.hasCaCert())
+ currentDownload = downloadCACert(provider);
+ if (provider.hasCaCert() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) {
+ currentDownload = getAndSetEipServiceJson(provider);
}
}
@@ -143,14 +106,18 @@ public class ProviderApiManager extends ProviderApiManagerBase {
}
- private Bundle getAndSetProviderJson(String providerMainUrl, String caCert, JSONObject providerDefinition) {
+ private Bundle getAndSetProviderJson(Provider provider) {
Bundle result = new Bundle();
+ String caCert = provider.getCaCert();
+ JSONObject providerDefinition = provider.getDefinition();
+
if (go_ahead) {
String providerDotJsonString;
- if(providerDefinition.length() == 0 || caCert.isEmpty())
- providerDotJsonString = downloadWithCommercialCA(providerMainUrl + "/provider.json");
- else {
+ if(providerDefinition.length() == 0 || caCert.isEmpty()) {
+ String providerJsonUrl = provider.getMainUrlString() + "/provider.json";
+ providerDotJsonString = downloadWithCommercialCA(providerJsonUrl, provider);
+ } else {
providerDotJsonString = downloadFromApiUrlWithProviderCA("/provider.json", caCert, providerDefinition);
}
@@ -161,20 +128,13 @@ public class ProviderApiManager extends ProviderApiManagerBase {
try {
JSONObject providerJson = new JSONObject(providerDotJsonString);
- String providerDomain = getDomainFromMainURL(lastProviderMainUrl);
- providerApiUrl = getApiUrlWithVersion(providerJson);
- //String name = providerJson.getString(Provider.NAME);
- //TODO setProviderName(name);
-
- preferences.edit().putString(Provider.KEY, providerJson.toString()).
- putBoolean(PROVIDER_ALLOW_ANONYMOUS, providerJson.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOW_ANONYMOUS)).
- putBoolean(PROVIDER_ALLOWED_REGISTERED, providerJson.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOWED_REGISTERED)).
- putString(Provider.KEY + "." + providerDomain, providerJson.toString()).commit();
- result.putBoolean(RESULT_KEY, true);
+ provider.define(providerJson);
+
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} catch (JSONException e) {
String reason_to_fail = pickErrorMessage(providerDotJsonString);
result.putString(ERRORS, reason_to_fail);
- result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
}
}
return result;
@@ -182,27 +142,27 @@ public class ProviderApiManager extends ProviderApiManagerBase {
/**
* Downloads the eip-service.json from a given URL, and saves eip service capabilities including the offered gateways
- * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the download was successful.
+ * @return a bundle with a boolean value mapped to a key named BROADCAST_RESULT_KEY, and which is true if the download was successful.
*/
@Override
- protected Bundle getAndSetEipServiceJson() {
+ protected Bundle getAndSetEipServiceJson(Provider provider) {
Bundle result = new Bundle();
- String eip_service_json_string = "";
+ String eipServiceJsonString = "";
if (go_ahead) {
try {
- JSONObject provider_json = new JSONObject(preferences.getString(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);
- JSONObject eip_service_json = new JSONObject(eip_service_json_string);
- eip_service_json.getInt(Provider.API_RETURN_SERIAL);
+ JSONObject provider_json = provider.getDefinition();
+ String eipServiceUrl = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
+ eipServiceJsonString = downloadWithProviderCA(provider.getCaCert(), eipServiceUrl);
+ JSONObject eipServiceJson = new JSONObject(eipServiceJsonString);
+ eipServiceJson.getInt(Provider.API_RETURN_SERIAL);
- preferences.edit().putString(PROVIDER_KEY, eip_service_json.toString()).commit();
+ provider.setEipServiceJson(eipServiceJson);
- result.putBoolean(RESULT_KEY, true);
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} catch (NullPointerException | JSONException e) {
- String reason_to_fail = pickErrorMessage(eip_service_json_string);
+ String reason_to_fail = pickErrorMessage(eipServiceJsonString);
result.putString(ERRORS, reason_to_fail);
- result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
}
}
return result;
@@ -214,14 +174,13 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* @return true if certificate was downloaded correctly, false if provider.json is not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error.
*/
@Override
- protected boolean updateVpnCertificate() {
+ protected boolean updateVpnCertificate(Provider provider) {
try {
- JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
+ JSONObject providerJson = provider.getDefinition();
+ String provider_main_url = providerJson.getString(Provider.API_URL);
+ URL newCertStringUrl = new URL(provider_main_url + "/" + providerJson.getString(Provider.API_VERSION) + "/" + PROVIDER_VPN_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) + "/" + PROVIDER_VPN_CERTIFICATE);
-
- String cert_string = downloadWithProviderCA(new_cert_string_url.toString());
+ String cert_string = downloadWithProviderCA(provider.getCaCert(), newCertStringUrl.toString());
if (ConfigHelper.checkErroneousDownload(cert_string))
return false;
@@ -238,23 +197,22 @@ public class ProviderApiManager extends ProviderApiManagerBase {
}
}
- private Bundle downloadCACert() {
+ private Bundle downloadCACert(Provider provider) {
Bundle result = new Bundle();
try {
- JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, ""));
- String caCertUrl = providerJson.getString(Provider.CA_CERT_URI);
- String providerDomain = getDomainFromMainURL(lastProviderMainUrl);
- String cert_string = downloadWithCommercialCA(caCertUrl);
-
- if (validCertificate(cert_string) && go_ahead) {
- preferences.edit().putString(Provider.CA_CERT, cert_string).commit();
- preferences.edit().putString(Provider.CA_CERT + "." + providerDomain, cert_string).commit();
- result.putBoolean(RESULT_KEY, true);
+ String caCertUrl = provider.getDefinition().getString(Provider.CA_CERT_URI);
+ String providerDomain = getDomainFromMainURL(provider.getMainUrlString());
+ String certString = downloadWithCommercialCA(caCertUrl, provider);
+
+ if (validCertificate(provider, certString) && go_ahead) {
+ provider.setCaCert(certString);
+ preferences.edit().putString(Provider.CA_CERT + "." + providerDomain, certString).apply();
+ result.putBoolean(BROADCAST_RESULT_KEY, true);
} else {
setErrorResult(result, warning_corrupted_provider_cert, ERROR_CERTIFICATE_PINNING.toString());
}
} catch (JSONException e) {
- setErrorResult(result, malformed_url, null);
+ e.printStackTrace();
}
return result;
@@ -263,10 +221,8 @@ public class ProviderApiManager extends ProviderApiManagerBase {
/**
* Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider.
*
- * @param string_url
- * @return
*/
- private String downloadWithCommercialCA(String string_url) {
+ private String downloadWithCommercialCA(String stringUrl, Provider provider) {
String responseString;
JSONObject errorJson = new JSONObject();
@@ -277,14 +233,14 @@ public class ProviderApiManager extends ProviderApiManagerBase {
List<Pair<String, String>> headerArgs = getAuthorizationHeader();
- responseString = sendGetStringToServer(string_url, headerArgs, okHttpClient);
+ responseString = sendGetStringToServer(stringUrl, headerArgs, okHttpClient);
if (responseString != null && responseString.contains(ERRORS)) {
try {
// try to download with provider CA on certificate error
JSONObject responseErrorJson = new JSONObject(responseString);
if (responseErrorJson.getString(ERRORS).equals(resources.getString(R.string.certificate_error))) {
- responseString = downloadWithProviderCA(string_url);
+ responseString = downloadWithProviderCA(provider.getCaCert(), stringUrl);
}
} catch (JSONException e) {
e.printStackTrace();
@@ -324,11 +280,11 @@ public class ProviderApiManager extends ProviderApiManagerBase {
* @param urlString as a string
* @return an empty string if it fails, the url content if not.
*/
- private String downloadWithProviderCA(String urlString) {
+ private String downloadWithProviderCA(String caCert, String urlString) {
JSONObject initError = new JSONObject();
String responseString;
- OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(initError);
+ OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(caCert, initError);
if (okHttpClient == null) {
return initError.toString();
}
diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java b/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java
index 8403b046..67c04f13 100644
--- a/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java
+++ b/app/src/production/java/se/leap/bitmaskclient/ProviderListActivity.java
@@ -22,6 +22,8 @@ import android.os.Bundle;
import java.net.MalformedURLException;
import java.net.URL;
+import static se.leap.bitmaskclient.ProviderAPI.SET_UP_PROVIDER;
+
/**
* Activity that builds and shows the list of known available providers.
* <p/>
@@ -61,41 +63,18 @@ public class ProviderListActivity extends ProviderListBaseActivity {
*/
public void setUpProvider() {
mConfigState.setAction(SETTING_UP_PROVIDER);
- Intent providerApiCommand = new Intent(this, ProviderAPI.class);
- Bundle parameters = new Bundle();
- parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString());
- if (provider.hasCertificatePin()){
- parameters.putString(Provider.CA_CERT_FINGERPRINT, provider.certificatePin());
- }
- if (provider.hasCaCert()) {
- parameters.putString(Provider.CA_CERT, provider.getCaCert());
- }
- if (provider.hasDefinition()) {
- parameters.putString(Provider.KEY, provider.getDefinition().toString());
- }
-
- providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
- providerApiCommand.putExtra(ProviderAPI.PARAMETERS, parameters);
-
- startService(providerApiCommand);
+ ProviderAPICommand.execute(this, SET_UP_PROVIDER, provider);
}
@Override
- public void retrySetUpProvider() {
+ public void retrySetUpProvider(Provider provider) {
cancelSettingUpProvider();
- if (!ProviderAPI.caCertDownloaded()) {
- addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl());
+ if (!provider.hasCaCert()) {
+ addAndSelectNewProvider(provider.getMainUrlString());
} else {
showProgressBar();
- Intent providerApiCommand = new Intent(this, ProviderAPI.class);
- providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
- providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver);
- Bundle parameters = new Bundle();
- parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString());
- providerApiCommand.putExtra(ProviderAPI.PARAMETERS, parameters);
-
- startService(providerApiCommand);
+ ProviderAPICommand.execute(this, SET_UP_PROVIDER, provider);
}
}
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
index c23e4f49..3ebf6201 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
@@ -24,6 +24,8 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.text.TextUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,6 +36,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.IOException;
+import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
@@ -45,13 +48,13 @@ import se.leap.bitmaskclient.ProviderApiManager;
import se.leap.bitmaskclient.ProviderApiManagerBase;
import se.leap.bitmaskclient.testutils.MockSharedPreferences;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.ProviderAPI.ERRORS;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK;
import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK;
-import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY;
import static se.leap.bitmaskclient.testutils.BackendMockResponses.BackendMockProvider.TestBackendErrorCase.ERROR_CASE_UPDATED_CERTIFICATE;
import static se.leap.bitmaskclient.testutils.BackendMockResponses.BackendMockProvider.TestBackendErrorCase.NO_ERROR;
-import static se.leap.bitmaskclient.testutils.TestSetupHelper.getInputAsString;
import static se.leap.bitmaskclient.testutils.MockHelper.mockBundle;
import static se.leap.bitmaskclient.testutils.MockHelper.mockClientGenerator;
import static se.leap.bitmaskclient.testutils.MockHelper.mockFingerprintForCertificate;
@@ -60,6 +63,7 @@ import static se.leap.bitmaskclient.testutils.MockHelper.mockProviderApiConnecto
import static se.leap.bitmaskclient.testutils.MockHelper.mockResources;
import static se.leap.bitmaskclient.testutils.MockHelper.mockResultReceiver;
import static se.leap.bitmaskclient.testutils.MockHelper.mockTextUtils;
+import static se.leap.bitmaskclient.testutils.TestSetupHelper.getInputAsString;
/**
@@ -103,235 +107,273 @@ public class ProviderApiManagerTest {
mockResources = mockResources(getClass().getClassLoader().getResourceAsStream("error_messages.json"));
}
+ private Provider getConfiguredProvider() throws IOException, JSONException {
+ return getProvider(null, null, null);
+ }
+
+ private Provider getProvider(String domain, String caCertFile, String jsonFile) {
+ if (domain == null)
+ domain = "https://riseup.net";
+ if (caCertFile == null)
+ caCertFile = "riseup.net.pem";
+ if (jsonFile == null)
+ jsonFile = "riseup.net.json";
+
+ try {
+ return new Provider(
+ new URL(domain),
+ getInputAsString(getClass().getClassLoader().getResourceAsStream(caCertFile)),
+ getInputAsString(getClass().getClassLoader().getResourceAsStream(jsonFile))
+
+ );
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
@Test
- public void test_handleIntentSetupProvider_noProviderMainURL() {
+ public void test_handleIntentSetupProvider_noProviderMainURL() throws IOException, JSONException {
+ Provider provider = new Provider("");
+
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
- expectedResult.putString(ERRORS, "{\"errors\":\"It doesn't seem to be a Bitmask provider.\"}");
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "");
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
+ expectedResult.putString(ERRORS, "{\"errors\":\"It doesn't seem to be a Bitmask provider.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ Intent providerApiCommand = mockIntent();
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_happyPath_preseededProviderAndCA() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_happyPath_preseededProviderAndCA() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = getConfiguredProvider();
+
mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, true);
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
- parameters.putString(Provider.CA_CERT, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem")));
- parameters.putString(Provider.KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json")));
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, true);
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_OK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_OK, expectedResult));
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_happyPath_no_preseededProviderAndCA() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_happyPath_no_preseededProviderAndCA() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = new Provider("https://riseup.net");
+
mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, true);
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, true);
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_OK, expectedResult));
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_OK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_happyPath_storedProviderAndCAFromPreviousSetup() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_happyPath_storedProviderAndCAFromPreviousSetup() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = new Provider("https://riseup.net");
mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
mockPreferences.edit().putString(Provider.KEY + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json"))).apply();
mockPreferences.edit().putString(Provider.CA_CERT + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem"))).apply();
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, true);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, true);
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
+ Intent providerApiCommand = mockIntent();
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_OK, expectedResult));
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_OK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_preseededProviderAndCA_failedCAPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_preseededProviderAndCA_failedCAPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = getConfiguredProvider();
mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_CERTIFICATE_PINNING\",\"errors\":\"Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
- parameters.putString(Provider.CA_CERT, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem")));
- parameters.putString(Provider.KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json")));
+ Intent providerApiCommand = mockIntent();
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- providerApiManager.handleIntent(provider_API_command);
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
+
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_no_preseededProviderAndCA_failedPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_no_preseededProviderAndCA_failedPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = new Provider("https://riseup.net");
mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_CERTIFICATE_PINNING\",\"errors\":\"Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
+ Intent providerApiCommand = mockIntent();
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- providerApiManager.handleIntent(provider_API_command);
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
+
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
public void test_handleIntentSetupProvider_storedProviderAndCAFromPreviousSetup_failedPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ Provider provider = new Provider("https://riseup.net");
+
mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
mockProviderApiConnector(NO_ERROR);
mockPreferences.edit().putString(Provider.KEY + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json"))).apply();
mockPreferences.edit().putString(Provider.CA_CERT + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem"))).apply();
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_CERTIFICATE_PINNING\",\"errors\":\"Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_preseededProviderAndCA_outdatedCertificate() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_preseededProviderAndCA_outdatedCertificate() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = getProvider(null ,"outdated_cert.pem", null);
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_INVALID_CERTIFICATE\",\"errors\":\"Stored provider certificate is expired. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
- parameters.putString(Provider.CA_CERT, getInputAsString(getClass().getClassLoader().getResourceAsStream("outdated_cert.pem")));
- parameters.putString(Provider.KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json")));
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_storedProviderAndCAFromPreviousSetup_outdatedCertificate() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_storedProviderAndCAFromPreviousSetup_outdatedCertificate() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = new Provider("https://riseup.net");
mockProviderApiConnector(NO_ERROR);
mockPreferences.edit().putString(Provider.KEY + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json"))).apply();
mockPreferences.edit().putString(Provider.CA_CERT + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("outdated_cert.pem"))).apply();
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_INVALID_CERTIFICATE\",\"errors\":\"Stored provider certificate is expired. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_preseededProviderAndCA_ValidCertificateButUpdatedCertificateOnServerSide() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_preseededProviderAndCA_ValidCertificateButUpdatedCertificateOnServerSide() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = getConfiguredProvider();
+
mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_CASE_UPDATED_CERTIFICATE);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_INVALID_CERTIFICATE\",\"errors\":\"Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
- parameters.putString(Provider.CA_CERT, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem")));
- parameters.putString(Provider.KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json")));
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
@Test
- public void test_handleIntentSetupProvider_storedProviderAndCAFromPreviousSetup_ValidCertificateButUpdatedCertificateOnServerSide() throws IOException, CertificateEncodingException, NoSuchAlgorithmException {
+ public void test_handleIntentSetupProvider_storedProviderAndCAFromPreviousSetup_ValidCertificateButUpdatedCertificateOnServerSide() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+ Provider provider = new Provider("https://riseup.net");
+
mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_CASE_UPDATED_CERTIFICATE);
mockPreferences.edit().putString(Provider.KEY + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json"))).apply();
mockPreferences.edit().putString(Provider.CA_CERT + ".riseup.net", getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem"))).apply();
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
Bundle expectedResult = mockBundle();
- expectedResult.putBoolean(RESULT_KEY, false);
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
expectedResult.putString(ERRORS, "{\"errorId\":\"ERROR_INVALID_CERTIFICATE\",\"errors\":\"Stored provider certificate is invalid. You can either update Bitmask (recommended) or update the provider certificate using a commercial CA certificate.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+ Intent providerApiCommand = mockIntent();
- Intent provider_API_command = mockIntent();
- Bundle parameters = mockBundle();
- parameters.putString(Provider.MAIN_URL, "https://riseup.net");
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
- provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
- provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
- provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
- providerApiManager.handleIntent(provider_API_command);
+ providerApiManager.handleIntent(providerApiCommand);
}
}
diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
index 8372c9bc..ea7f9aae 100644
--- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
+++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
@@ -353,7 +353,7 @@ public class MockHelper {
OkHttpClientGenerator mockClientGenerator = mock(OkHttpClientGenerator.class);
OkHttpClient mockedOkHttpClient = mock(OkHttpClient.class);
when(mockClientGenerator.initCommercialCAHttpClient(any(JSONObject.class))).thenReturn(mockedOkHttpClient);
- when(mockClientGenerator.initSelfSignedCAHttpClient(any(JSONObject.class))).thenReturn(mockedOkHttpClient);
+ when(mockClientGenerator.initSelfSignedCAHttpClient(anyString(), any(JSONObject.class))).thenReturn(mockedOkHttpClient);
when(mockClientGenerator.initSelfSignedCAHttpClient(any(JSONObject.class), anyString())).thenReturn(mockedOkHttpClient);
return mockClientGenerator;
}