summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/urls/bitmask.url3
-rw-r--r--hosts-for-android-emulator1
-rw-r--r--src/se/leap/leapclient/ConfigHelper.java21
-rw-r--r--src/se/leap/leapclient/ConfigurationWizard.java5
-rw-r--r--src/se/leap/leapclient/Dashboard.java4
-rw-r--r--src/se/leap/leapclient/LogInDialog.java2
-rw-r--r--src/se/leap/leapclient/ProviderAPI.java193
-rw-r--r--src/se/leap/leapclient/ProviderListContent.java16
8 files changed, 163 insertions, 82 deletions
diff --git a/assets/urls/bitmask.url b/assets/urls/bitmask.url
index 910f0400..bc4d59db 100644
--- a/assets/urls/bitmask.url
+++ b/assets/urls/bitmask.url
@@ -3,5 +3,6 @@
"assets_json_provider" : "providers/bitmask.net_provider.json",
"json_provider" : "https://bitmask.net/provider.json",
"cert" : "https://bitmask.net/ca.crt",
- "json_eip_service" : "https://api.bitmask.net:4430/1/config/eip-service.json"
+ "json_eip_service_antiguo" : "https://api.bitmask.net:4430/1/config/eip-service.json",
+ "json_eip_service" : "https://api.bitmask.net:4430/config/eip-service.json"
} \ No newline at end of file
diff --git a/hosts-for-android-emulator b/hosts-for-android-emulator
index b10103ef..ab0cf906 100644
--- a/hosts-for-android-emulator
+++ b/hosts-for-android-emulator
@@ -1,5 +1,6 @@
127.0.0.1 localhost
10.0.2.2 api.lvh.me
+10.0.2.2 lvh.me
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java
index 78c71cc4..7c52629b 100644
--- a/src/se/leap/leapclient/ConfigHelper.java
+++ b/src/se/leap/leapclient/ConfigHelper.java
@@ -16,6 +16,7 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -44,7 +45,7 @@ public class ConfigHelper {
public static final String user_directory = "leap_android";
final public static String provider_main_url = "provider_main_url";
final public static String danger_on = "danger_on";
- final public static String api_url_key = "srp_server_url";
+ final public static String api_url_key = "api_uri";
final public static String username_key = "username";
final public static String password_key = "password";
final public static String eip_service_api_path = "/config/eip-service.json";
@@ -63,6 +64,20 @@ public class ConfigHelper {
final public static int LOGOUT_SUCCESSFUL = 7;
final public static int LOGOUT_FAILED = 8;
+ static String getStringFromSharedPref(String shared_preferences_key) {
+ String value = "";
+ String content = shared_preferences.getString(shared_preferences_key, "");
+ try {
+ JSONObject json_object = new JSONObject(content);
+ JSONArray names = json_object.names();
+ String key = names.getString(0);
+ value = json_object.getString(key);
+ } catch (JSONException e) {
+ value = content;
+ }
+ return value;
+ }
+
static void saveSharedPref(String shared_preferences_key, JSONObject content) {
SharedPreferences.Editor shared_preferences_editor = shared_preferences
@@ -164,8 +179,8 @@ public class ConfigHelper {
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
- keystore_trusted.load(leap_keystore, "uer92jf".toCharArray());
- //keystore_trusted.load(null, null);
+ //keystore_trusted.load(leap_keystore, "uer92jf".toCharArray());
+ keystore_trusted.load(null, null);
} finally {
leap_keystore.close();
}
diff --git a/src/se/leap/leapclient/ConfigurationWizard.java b/src/se/leap/leapclient/ConfigurationWizard.java
index 9edaa288..3d165211 100644
--- a/src/se/leap/leapclient/ConfigurationWizard.java
+++ b/src/se/leap/leapclient/ConfigurationWizard.java
@@ -95,7 +95,7 @@ public class ConfigurationWizard extends Activity
boolean custom = false;
provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString();
if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list
- ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath), custom));
+ ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath), custom, true)); // By default, it trusts the provider
}
} catch (IOException e) {
// TODO Auto-generated catch block
@@ -163,6 +163,7 @@ public class ConfigurationWizard extends Activity
method_and_parameters.putString(ConfigHelper.provider_key, current_provider_item.name);
method_and_parameters.putString(ConfigHelper.cert_key, current_provider_item.cert_json_url);
method_and_parameters.putString(ConfigHelper.eip_service_key, current_provider_item.eip_service_json_url);
+ method_and_parameters.putBoolean(ConfigHelper.danger_on, current_provider_item.danger_on);
provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters);
provider_API_command.putExtra("receiver", providerAPI_result_receiver);
@@ -191,9 +192,9 @@ public class ConfigurationWizard extends Activity
Bundle method_and_parameters = new Bundle();
method_and_parameters.putString(ConfigHelper.provider_main_url, provider_main_url);
+ method_and_parameters.putBoolean(ConfigHelper.danger_on, danger_on);
provider_API_command.putExtra(ConfigHelper.downloadNewProviderDotJSON, method_and_parameters);
- provider_API_command.putExtra(ConfigHelper.danger_on, danger_on);
provider_API_command.putExtra("receiver", providerAPI_result_receiver);
startService(provider_API_command);
diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java
index a169c9d4..577092bb 100644
--- a/src/se/leap/leapclient/Dashboard.java
+++ b/src/se/leap/leapclient/Dashboard.java
@@ -23,6 +23,7 @@ import android.view.ViewStub;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
+import android.widget.Toast;
public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface, Receiver {
@@ -195,11 +196,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
public void onReceiveResult(int resultCode, Bundle resultData) {
if(resultCode == ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL){
setResult(RESULT_OK);
+ Toast.makeText(getApplicationContext(), "Authentication succeeded", Toast.LENGTH_LONG).show();
//TODO What should we do know?
}
else if(resultCode == ConfigHelper.SRP_AUTHENTICATION_FAILED) {
setResult(RESULT_CANCELED);
- finish();
+ Toast.makeText(getApplicationContext(), "Authentication failed", Toast.LENGTH_LONG).show();
}
}
diff --git a/src/se/leap/leapclient/LogInDialog.java b/src/se/leap/leapclient/LogInDialog.java
index 61526c69..74db92ea 100644
--- a/src/se/leap/leapclient/LogInDialog.java
+++ b/src/se/leap/leapclient/LogInDialog.java
@@ -68,6 +68,6 @@ public class LogInDialog extends DialogFragment {
}
boolean validPassword(String entered_password) {
- return entered_password.length() > 8;
+ return entered_password.length() > 4;
}
}
diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java
index 63db18e1..04185eda 100644
--- a/src/se/leap/leapclient/ProviderAPI.java
+++ b/src/se/leap/leapclient/ProviderAPI.java
@@ -1,17 +1,26 @@
package se.leap.leapclient;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.math.BigInteger;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
import java.util.List;
import java.net.MalformedURLException;
import java.net.URL;
-import java.net.UnknownHostException;
import java.util.Scanner;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManagerFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@@ -36,6 +45,7 @@ import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
+import android.util.Base64;
import android.util.Log;
public class ProviderAPI extends IntentService {
@@ -58,7 +68,7 @@ public class ProviderAPI extends IntentService {
}
else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) {
if(downloadNewProviderDotJSON(task))
- receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);
+ receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY);
else
receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);
}
@@ -77,25 +87,21 @@ public class ProviderAPI extends IntentService {
}
private boolean downloadJsonFiles(Bundle task) {
- String cert_url = (String) task.get(ConfigHelper.cert_key);
- String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key);
+ String provider_name = task.getString(ConfigHelper.provider_key);
+ String cert_url = task.getString(ConfigHelper.cert_key);
+ String eip_service_json_url = task.getString(ConfigHelper.eip_service_key);
+ boolean danger_on = task.getBoolean(ConfigHelper.danger_on);
try {
- String cert_string = getStringFromProvider(cert_url);
+ String cert_string = getStringFromProvider(cert_url, danger_on);
+ ConfigHelper.addTrustedCertificate(provider_name, cert_string);
JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}");
ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json);
- JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url);
+ JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on);
ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json);
return true;
- } catch (IOException e) {
- // TODO
- e.printStackTrace();
- return false;
} catch (JSONException e) {
ConfigHelper.rescueJSONException(e);
return false;
- } catch(Exception e) {
- e.printStackTrace();
- return false;
}
}
@@ -135,7 +141,8 @@ public class ProviderAPI extends IntentService {
byte[] M1 = client.response(Bbytes);
byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1);
if( client.verify(M2) == false )
- throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16));
+ //throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16));
+ return false;
return true;
}
else return false;
@@ -199,17 +206,14 @@ public class ProviderAPI extends IntentService {
private boolean downloadNewProviderDotJSON(Bundle task) {
boolean custom = true;
- boolean danger_on = ((Boolean)task.get(ConfigHelper.danger_on)).booleanValue();
+ boolean danger_on = task.getBoolean(ConfigHelper.danger_on);
String provider_main_url = (String) task.get(ConfigHelper.provider_main_url);
String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_");
String provider_json_url = guessURL(provider_main_url);
JSONObject provider_json = null;
try {
- provider_json = getJSONFromProvider(provider_json_url);
- } catch (IOException e) {
- // It could happen that an https site used a certificate not trusted.
- provider_json = downloadNewProviderDotJsonWithoutCert(provider_json_url, danger_on);
+ provider_json = getJSONFromProvider(provider_json_url, danger_on);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -223,75 +227,128 @@ public class ProviderAPI extends IntentService {
ConfigHelper.saveFile(filename, provider_json.toString());
ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json);
- ProviderListContent.addItem(new ProviderItem(provider_name, ConfigHelper.openFileInputStream(filename), custom));
+ ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, ConfigHelper.openFileInputStream(filename), custom, danger_on));
return true;
}
}
- private JSONObject downloadNewProviderDotJsonWithoutCert(
- String provider_json_url, boolean danger_on) {
- JSONObject provider_json = null;
- try {
- URL provider_url = new URL(provider_json_url);
- String provider_json_string = new Scanner(provider_url.openStream()).useDelimiter("\\A").next();
- provider_json = new JSONObject(provider_json_string);
- } catch (MalformedURLException e1) {
- e1.printStackTrace();
- } catch (UnknownHostException e1) {
- e1.printStackTrace();
- } catch (IOException e1) {
- if(danger_on) {
- provider_json = downloadNewProviderDotJsonWithoutValidate(provider_json_url);
- }
- else {
- //TODO Show error message advising to check the checkbox if the url is completely trusted.
- }
- e1.printStackTrace();
- } catch (JSONException e1) {
- e1.printStackTrace();
- }
- return provider_json;
- }
-
- private JSONObject downloadNewProviderDotJsonWithoutValidate(
- String provider_json_url) {
- JSONObject provider_json = null;
+ private String getStringFromProviderWithoutValidate(
+ URL provider_json_url) {
+
+ String json_string = "";
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- HostnameVerifier hostname_verifier =
- HttpsURLConnection.getDefaultHostnameVerifier();
- return hostname_verifier.verify("", session);
- }
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
};
// Tell the URLConnection to use our HostnameVerifier
try {
- URL url = new URL(provider_json_url);
HttpsURLConnection urlConnection =
- (HttpsURLConnection)url.openConnection();
- urlConnection.setHostnameVerifier(hostnameVerifier);
- String provider_json_string = new Scanner(url.openStream()).useDelimiter("\\A").next();
- provider_json = new JSONObject(provider_json_string);
+ (HttpsURLConnection)provider_json_url.openConnection();
+ urlConnection.setHostnameVerifier(hostnameVerifier);
+ json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
- e.printStackTrace();
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ json_string = getStringFromProviderWithCACertAdded(provider_json_url);
+ //e.printStackTrace();
}
- return provider_json;
-
+ return json_string;
}
private String guessURL(String provider_main_url) {
return provider_main_url + "/provider.json";
}
+
+ private String getStringFromProvider(String string_url, boolean danger_on) {
+
+ String json_file_content = "";
+
+ URL provider_url = null;
+ try {
+ provider_url = new URL(string_url);
+ json_file_content = new Scanner(provider_url.openStream()).useDelimiter("\\A").next();
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO SSLHandshakeException
+ // This means that we have not added ca.crt to the trusted certificates.
+ if(provider_url != null && danger_on) {
+ json_file_content = getStringFromProviderWithoutValidate(provider_url);
+ }
+ //json_file_content = downloadStringFromProviderWithCACertAdded(string_url);
+ e.printStackTrace();
+ }
+
+ return json_file_content;
+ }
+
+ private String getStringFromProviderWithCACertAdded(URL url) {
+ String json_file_content = "";
+
+ // Load CAs from an InputStream
+ // (could be from a resource or ByteArrayInputStream or ...)
+ CertificateFactory cf;
+ try {
+ cf = CertificateFactory.getInstance("X.509");
+
+ String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.cert_key);
+ cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim();
+ byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT);
+ InputStream caInput = new ByteArrayInputStream(cert_bytes);
+ java.security.cert.Certificate ca;
+ try {
+ ca = cf.generateCertificate(caInput);
+ System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
+ } finally {
+ caInput.close();
+ }
+
+ // Create a KeyStore containing our trusted CAs
+ String keyStoreType = KeyStore.getDefaultType();
+ KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+ keyStore.load(null, null);
+ keyStore.setCertificateEntry("ca", ca);
+
+ // Create a TrustManager that trusts the CAs in our KeyStore
+ String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+ tmf.init(keyStore);
+
+ // Create an SSLContext that uses our TrustManager
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, tmf.getTrustManagers(), null);
+
+ // Tell the URLConnection to use a SocketFactory from our SSLContext
+ HttpsURLConnection urlConnection =
+ (HttpsURLConnection)url.openConnection();
+ urlConnection.setSSLSocketFactory(context.getSocketFactory());
+ json_file_content = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next();
+ } catch (CertificateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (KeyStoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchAlgorithmException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (KeyManagementException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return json_file_content;
+ }
- private String getStringFromProvider(String string_url) throws IOException {
+ private String getStringFromProvider_2(String string_url) throws IOException {
String json_file_content = "";
@@ -306,8 +363,8 @@ public class ProviderAPI extends IntentService {
return json_file_content;
}
- private JSONObject getJSONFromProvider(String json_url) throws IOException, JSONException {
- String json_file_content = getStringFromProvider(json_url);
+ private JSONObject getJSONFromProvider(String json_url, boolean danger_on) throws JSONException {
+ String json_file_content = getStringFromProvider(json_url, danger_on);
return new JSONObject(json_file_content);
}
diff --git a/src/se/leap/leapclient/ProviderListContent.java b/src/se/leap/leapclient/ProviderListContent.java
index dd227bfd..9ed7e9bf 100644
--- a/src/se/leap/leapclient/ProviderListContent.java
+++ b/src/se/leap/leapclient/ProviderListContent.java
@@ -44,6 +44,7 @@ public class ProviderListContent {
public String provider_json_filename;
public String eip_service_json_url;
public String cert_json_url;
+ public boolean danger_on = false;
public ProviderItem(String id, String name, String provider_json_url, String eip_service_json_url, String cert_json_url) {
this.id = id;
@@ -53,7 +54,7 @@ public class ProviderListContent {
this.cert_json_url = cert_json_url;
}
- public ProviderItem(String name, InputStream urls_file_input_stream, boolean custom) {
+ public ProviderItem(String name, InputStream urls_file_input_stream, boolean custom, boolean danger_on) {
try {
byte[] urls_file_bytes = new byte[urls_file_input_stream.available()];
@@ -62,11 +63,12 @@ public class ProviderListContent {
JSONObject file_contents = new JSONObject(urls_file_content);
id = name;
this.name = name;
- provider_json_url = (String) file_contents.get("json_provider");
- provider_json_filename = (String) file_contents.get("assets_json_provider");
- eip_service_json_url = (String) file_contents.get("json_eip_service");
- cert_json_url = (String) file_contents.get("cert");
+ provider_json_url = file_contents.getString("json_provider");
+ provider_json_filename = file_contents.getString("assets_json_provider");
+ eip_service_json_url = file_contents.getString("json_eip_service");
+ cert_json_url = file_contents.getString("cert");
this.custom = custom;
+ this.danger_on = danger_on;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -76,7 +78,7 @@ public class ProviderListContent {
}
}
- public ProviderItem(String name, FileInputStream provider_json, boolean custom) {
+ public ProviderItem(String name, String provider_json_url, FileInputStream provider_json, boolean custom, boolean danger_on) {
try {
byte[] urls_file_bytes = new byte[provider_json.available()];
@@ -85,9 +87,11 @@ public class ProviderListContent {
JSONObject file_contents = new JSONObject(urls_file_content);
id = name;
this.name = name;
+ this.provider_json_url = provider_json_url;
eip_service_json_url = (String) file_contents.get("api_uri") + ConfigHelper.eip_service_api_path;
cert_json_url = (String) file_contents.get("ca_cert_uri");
this.custom = custom;
+ this.danger_on = danger_on;
if(custom)
provider_json_filename = name + "_provider.json".replaceFirst("__", "_");
} catch (JSONException e) {