diff options
Diffstat (limited to 'src/se/leap')
44 files changed, 1122 insertions, 1040 deletions
diff --git a/src/se/leap/leapclient/AboutFragment.java b/src/se/leap/bitmaskclient/AboutFragment.java index a3fbbf93..d751dc2f 100644 --- a/src/se/leap/leapclient/AboutFragment.java +++ b/src/se/leap/bitmaskclient/AboutFragment.java @@ -1,4 +1,4 @@ -package se.leap.leapclient; +package se.leap.bitmaskclient; import android.app.Fragment; import android.content.pm.PackageInfo; @@ -11,9 +11,11 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class AboutFragment extends Fragment { + + final public static String TAG = "aboutFragment"; public static Fragment newInstance() { AboutFragment provider_detail_fragment = new AboutFragment(); diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/bitmaskclient/ConfigHelper.java index 62ebf8f1..b916a9ac 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/bitmaskclient/ConfigHelper.java @@ -14,28 +14,29 @@ * 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.leapclient; +package se.leap.bitmaskclient; import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.math.BigInteger; import java.io.InputStream; +import java.security.KeyFactory; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.content.SharedPreferences; -import android.os.Environment; import android.util.Base64; /** @@ -49,88 +50,15 @@ public class ConfigHelper { public static SharedPreferences shared_preferences; private static KeyStore keystore_trusted; - - final public static String - ABOUT_FRAGMENT = "aboutFragment", - DOWNLOAD_JSON_FILES_BUNDLE_EXTRA = "downloadJSONFiles", - UPDATE_PROVIDER_DOTJSON = "updateProviderDotJSON", - DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON", - LOG_IN_DIALOG = "logInDialog", - NEW_PROVIDER_DIALOG = "logInDialog", - SRP_REGISTER = "srpRegister", - SRP_AUTH = "srpAuth", - M1_KEY = "M1", - M2_KEY = "M2", - LOG_IN = "logIn", - LOG_OUT = "logOut", - DOWNLOAD_CERTIFICATE = "downloadUserAuthedCertificate", - API_VERSION_KEY = "api_version", - API_RETURN_SERIAL_KEY = "serial", - RESULT_KEY = "result", - RECEIVER_KEY = "receiver", - PROVIDER_KEY = "provider", - SERVICE_KEY = "service", - ALLOWED_ANON = "allow_anonymous", - MAIN_CERT_KEY = "main_cert", - CERT_KEY = "cert", - KEY_KEY = "key", - EIP_SERVICE_KEY = "eip", - EIP_PARSED_SERIAL = "eip_parsed_serial", - TYPE_OF_CERTIFICATE = "type_of_certificate", - ANON_CERTIFICATE = "anon_certificate", - AUTHED_CERTIFICATE = "authed_certificate", - SALT_KEY = "salt", - SESSION_ID_COOKIE_KEY = "session_id_cookie_key", - SESSION_ID_KEY = "session_id", - PREFERENCES_KEY = "LEAPPreferences", - USER_DIRECTORY = "leap_android", - PROVIDER_NAME = "provider_name", - PROVIDER_ID = "provider_id", - PROVIDER_MAIN_URL = "provider_main_url", - PROVIDER_JSON_URL = "provider_json_url", - CUSTOM = "custom", - DANGER_ON = "danger_on", - API_URL_KEY = "api_uri", - USERNAME_KEY = "username", - PASSWORD_KEY = "password", - ALLOW_REGISTRATION_KEY = "allow_registration", - EIP_SERVICE_API_PATH = "config/eip-service.json", - ERRORS_KEY = "errors", - RECEIVER_TAG = "receiverTag", - REQUEST_TAG = "requestTag", - PROVIDER_DETAILS_DIALOG = "providerDetailsFragment", - DOMAIN = "domain", - NAME = "name", - DESCRIPTION = "description", - QUIT = "quit" - ; - + final public static String NG_1024 = "eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3"; final public static BigInteger G = new BigInteger("2"); - - final public static int - CUSTOM_PROVIDER_ADDED = 0, - CORRECTLY_DOWNLOADED_JSON_FILES = 1, - INCORRECTLY_DOWNLOADED_JSON_FILES = 2, - SRP_AUTHENTICATION_SUCCESSFUL = 3, - SRP_AUTHENTICATION_FAILED = 4, - SRP_REGISTRATION_SUCCESSFUL = 5, - SRP_REGISTRATION_FAILED = 6, - LOGOUT_SUCCESSFUL = 7, - LOGOUT_FAILED = 8, - CORRECTLY_DOWNLOADED_CERTIFICATE = 9, - INCORRECTLY_DOWNLOADED_CERTIFICATE = 10, - CORRECTLY_UPDATED_PROVIDER_DOT_JSON = 11, - INCORRECTLY_UPDATED_PROVIDER_DOT_JSON = 12, - CORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 13, - INCORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 14 - ; private static boolean checkSharedPrefs() { try { - shared_preferences = Dashboard.getAppContext().getSharedPreferences(PREFERENCES_KEY,Context.MODE_PRIVATE); + shared_preferences = Dashboard.getAppContext().getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); } catch (Exception e) { return false; } @@ -252,24 +180,6 @@ public class ConfigHelper { } /** - * Opens a FileInputStream from the user directory of the external storage directory. - * @param filename - * @return a file input stream - */ - public static FileInputStream openFileInputStream(String filename) { - FileInputStream input_stream = null; - File root = Environment.getExternalStorageDirectory(); - File leap_dir = new File(root.getAbsolutePath() + File.separator + USER_DIRECTORY); - try { - input_stream = new FileInputStream(leap_dir + File.separator + filename); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return input_stream; - } - - /** * Treat the input as the MSB representation of a number, * and lop off leading zero elements. For efficiency, the * input is simply returned if no leading zeroes are found. @@ -322,6 +232,31 @@ public class ConfigHelper { return (X509Certificate) certificate; } + + protected static RSAPrivateKey parseRsaKeyFromString(String RsaKeyString) { + RSAPrivateKey key = null; + try { + KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); + + RsaKeyString = RsaKeyString.replaceFirst("-----BEGIN RSA PRIVATE KEY-----", "").replaceFirst("-----END RSA PRIVATE KEY-----", ""); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( Base64.decode(RsaKeyString, Base64.DEFAULT) ); + key = (RSAPrivateKey) kf.generatePrivate(keySpec); + } catch (InvalidKeySpecException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } catch (NoSuchProviderException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + + return key; + } /** * Adds a new X509 certificate given its input stream and its provider name diff --git a/src/se/leap/leapclient/ConfigurationWizard.java b/src/se/leap/bitmaskclient/ConfigurationWizard.java index 934e2ea0..bcb4fa9f 100644 --- a/src/se/leap/leapclient/ConfigurationWizard.java +++ b/src/se/leap/bitmaskclient/ConfigurationWizard.java @@ -14,7 +14,7 @@ * 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.leapclient;
+ package se.leap.bitmaskclient;
import java.io.IOException;
import java.util.Iterator;
@@ -22,10 +22,9 @@ import java.util.Iterator; import org.json.JSONException;
import org.json.JSONObject;
-import se.leap.leapclient.ProviderAPIResultReceiver.Receiver;
-import se.leap.leapclient.ProviderListContent.ProviderItem;
-import se.leap.leapclient.R;
-import se.leap.openvpn.MainActivity;
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver;
+import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.Fragment;
@@ -39,7 +38,6 @@ import android.os.Handler; import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
/**
* Activity that builds and shows the list of known available providers.
@@ -55,9 +53,13 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn private ProviderItem mSelectedProvider;
private ProgressDialog mProgressDialog;
private Intent mConfigState = new Intent();
+
+ final public static String TYPE_OF_CERTIFICATE = "type_of_certificate";
+ final public static String ANON_CERTIFICATE = "anon_certificate";
+ final public static String AUTHED_CERTIFICATE = "authed_certificate";
- protected static final String PROVIDER_SET = "PROVIDER SET";
- protected static final String SERVICES_RETRIEVED = "SERVICES RETRIEVED";
+ final protected static String PROVIDER_SET = "PROVIDER SET";
+ final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED";
public ProviderAPIResultReceiver providerAPI_result_receiver;
@@ -70,7 +72,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler());
providerAPI_result_receiver.setReceiver(this);
- ConfigHelper.setSharedPreferences(getSharedPreferences(ConfigHelper.PREFERENCES_KEY, MODE_PRIVATE));
+ ConfigHelper.setSharedPreferences(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE));
loadPreseededProviders();
@@ -91,21 +93,21 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn @Override
public void onReceiveResult(int resultCode, Bundle resultData) {
- if(resultCode == ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
+ if(resultCode == ProviderAPI.CORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
JSONObject provider_json;
try {
- provider_json = new JSONObject(resultData.getString(ConfigHelper.PROVIDER_KEY));
- boolean danger_on = resultData.getBoolean(ConfigHelper.DANGER_ON);
- ConfigHelper.saveSharedPref(ConfigHelper.PROVIDER_KEY, provider_json);
- ConfigHelper.saveSharedPref(ConfigHelper.DANGER_ON, danger_on);
- ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON));
+ provider_json = new JSONObject(resultData.getString(Provider.KEY));
+ boolean danger_on = resultData.getBoolean(ProviderItem.DANGER_ON);
+ ConfigHelper.saveSharedPref(Provider.KEY, provider_json);
+ ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on);
+ ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
mConfigState.setAction(PROVIDER_SET);
if(mProgressDialog != null) mProgressDialog.dismiss();
mProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.config_wait_title), getResources().getString(R.string.config_connecting_provider), true);
mProgressDialog.setMessage(getResources().getString(R.string.config_downloading_services));
- if(resultData.containsKey(ConfigHelper.PROVIDER_ID))
- mSelectedProvider = getProvider(resultData.getString(ConfigHelper.PROVIDER_ID));
+ if(resultData.containsKey(Provider.NAME))
+ mSelectedProvider = getProvider(resultData.getString(Provider.NAME));
ProviderListFragment providerList = new ProviderListFragment();
@@ -123,12 +125,12 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn setResult(RESULT_CANCELED, mConfigState);
}
}
- else if(resultCode == ConfigHelper.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
+ else if(resultCode == ProviderAPI.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
mProgressDialog.dismiss();
setResult(RESULT_CANCELED, mConfigState);
}
- else if(resultCode == ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES) {
- if (ConfigHelper.getBoolFromSharedPref(ConfigHelper.ALLOWED_ANON)){
+ else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_JSON_FILES) {
+ if (ConfigHelper.getBoolFromSharedPref(EIP.ALLOWED_ANON)){
mProgressDialog.setMessage(getResources().getString(R.string.config_downloading_certificates));
mConfigState.putExtra(SERVICES_RETRIEVED, true);
downloadAnonCert();
@@ -139,15 +141,16 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn finish();
}
}
- else if(resultCode == ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES) {
+ else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_JSON_FILES) {
//Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_json_files_message, Toast.LENGTH_LONG).show();
+ mProgressDialog.dismiss();
setResult(RESULT_CANCELED, mConfigState);
}
- else if(resultCode == ConfigHelper.CORRECTLY_DOWNLOADED_CERTIFICATE) {
+ else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
mProgressDialog.dismiss();
setResult(RESULT_OK);
showProviderDetails(getCurrentFocus());
- } else if(resultCode == ConfigHelper.INCORRECTLY_DOWNLOADED_CERTIFICATE) {
+ } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) {
mProgressDialog.dismiss();
//Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_certificate_message, Toast.LENGTH_LONG).show();
setResult(RESULT_CANCELED, mConfigState);
@@ -170,7 +173,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn @Override
public void onBackPressed() {
try {
- if(ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY) == null || ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY).length() == 0) {
+ if(ConfigHelper.getJsonFromSharedPref(Provider.KEY) == null || ConfigHelper.getJsonFromSharedPref(Provider.KEY).length() == 0) {
askDashboardToQuitApp();
} else {
setResult(RESULT_OK);
@@ -183,7 +186,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn private void askDashboardToQuitApp() {
Intent ask_quit = new Intent();
- ask_quit.putExtra(ConfigHelper.QUIT, ConfigHelper.QUIT);
+ ask_quit.putExtra(Dashboard.ACTION_QUIT, Dashboard.ACTION_QUIT);
setResult(RESULT_CANCELED, ask_quit);
}
@@ -216,7 +219,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn boolean custom = false;
provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString();
if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list
- ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath), custom, true)); // By default, it trusts the provider
+ ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath), custom, false));
loaded_preseeded_providers = true;
}
} catch (IOException e) {
@@ -243,9 +246,9 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn // I think yes, but if so, where does this list live? leap.se, as it's the non-profit project for the software?
// If not, we should just be getting names/urls, and fetching the provider.json like in custom entries
provider_json = provider.provider_json;
- ConfigHelper.saveSharedPref(ConfigHelper.PROVIDER_KEY, provider_json);
- ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON));
- ConfigHelper.saveSharedPref(ConfigHelper.DANGER_ON, provider.danger_on);
+ ConfigHelper.saveSharedPref(Provider.KEY, provider_json);
+ ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
+ ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, provider.danger_on);
mProgressDialog.setMessage(getResources().getString(R.string.config_downloading_services));
downloadJSONFiles(mSelectedProvider);
@@ -265,15 +268,16 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn private void downloadJSONFiles(ProviderItem provider) {
Intent provider_API_command = new Intent(this, ProviderAPI.class);
- Bundle method_and_parameters = new Bundle();
+ Bundle parameters = new Bundle();
- method_and_parameters.putString(ConfigHelper.PROVIDER_KEY, provider.name);
- method_and_parameters.putString(ConfigHelper.MAIN_CERT_KEY, provider.cert_json_url);
- method_and_parameters.putString(ConfigHelper.EIP_SERVICE_KEY, provider.eip_service_json_url);
- method_and_parameters.putBoolean(ConfigHelper.DANGER_ON, provider.danger_on);
+ parameters.putString(Provider.KEY, provider.name);
+ parameters.putString(Provider.CA_CERT, provider.cert_json_url);
+ parameters.putString(EIP.KEY, provider.eip_service_json_url);
+ parameters.putBoolean(ProviderItem.DANGER_ON, provider.danger_on);
- provider_API_command.putExtra(ConfigHelper.DOWNLOAD_JSON_FILES_BUNDLE_EXTRA, method_and_parameters);
- provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver);
+ provider_API_command.setAction(ProviderAPI.DOWNLOAD_JSON_FILES_BUNDLE_EXTRA);
+ provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
+ provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
startService(provider_API_command);
}
@@ -284,12 +288,13 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn private void downloadAnonCert() {
Intent provider_API_command = new Intent(this, ProviderAPI.class);
- Bundle method_and_parameters = new Bundle();
+ Bundle parameters = new Bundle();
- method_and_parameters.putString(ConfigHelper.TYPE_OF_CERTIFICATE, ConfigHelper.ANON_CERTIFICATE);
+ parameters.putString(TYPE_OF_CERTIFICATE, ANON_CERTIFICATE);
- provider_API_command.putExtra(ConfigHelper.DOWNLOAD_CERTIFICATE, method_and_parameters);
- provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver);
+ provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE);
+ provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
+ provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
startService(provider_API_command);
}
@@ -300,14 +305,14 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn */
public void addAndSelectNewProvider(View view) {
FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
- Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(ConfigHelper.NEW_PROVIDER_DIALOG);
+ Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG);
if (previous_new_provider_dialog != null) {
fragment_transaction.remove(previous_new_provider_dialog);
}
fragment_transaction.addToBackStack(null);
DialogFragment newFragment = NewProviderDialog.newInstance();
- newFragment.show(fragment_transaction, ConfigHelper.NEW_PROVIDER_DIALOG);
+ newFragment.show(fragment_transaction, NewProviderDialog.TAG);
}
/**
@@ -318,26 +323,27 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn */
public void showProviderDetails(View view) {
FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
- Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(ConfigHelper.PROVIDER_DETAILS_DIALOG);
+ Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(ProviderDetailFragment.TAG);
if (previous_provider_details_dialog != null) {
fragment_transaction.remove(previous_provider_details_dialog);
}
fragment_transaction.addToBackStack(null);
DialogFragment newFragment = ProviderDetailFragment.newInstance();
- newFragment.show(fragment_transaction, ConfigHelper.PROVIDER_DETAILS_DIALOG);
+ newFragment.show(fragment_transaction, ProviderDetailFragment.TAG);
}
@Override
public void saveAndSelectProvider(String provider_main_url, boolean danger_on) {
Intent provider_API_command = new Intent(this, ProviderAPI.class);
- Bundle 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);
+ Bundle parameters = new Bundle();
+ parameters.putString(Provider.MAIN_URL, provider_main_url);
+ parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
- provider_API_command.putExtra(ConfigHelper.DOWNLOAD_NEW_PROVIDER_DOTJSON, method_and_parameters);
- provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver);
+ provider_API_command.setAction(ProviderAPI.DOWNLOAD_NEW_PROVIDER_DOTJSON);
+ provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
+ provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
startService(provider_API_command);
}
@@ -351,13 +357,14 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn public void updateProviderDotJson(String provider_name, String provider_json_url, boolean danger_on) {
Intent provider_API_command = new Intent(this, ProviderAPI.class);
- Bundle method_and_parameters = new Bundle();
- method_and_parameters.putString(ConfigHelper.PROVIDER_NAME, provider_name);
- method_and_parameters.putString(ConfigHelper.PROVIDER_JSON_URL, provider_json_url);
- method_and_parameters.putBoolean(ConfigHelper.DANGER_ON, danger_on);
+ Bundle parameters = new Bundle();
+ parameters.putString(Provider.NAME, provider_name);
+ parameters.putString(Provider.DOT_JSON_URL, provider_json_url);
+ parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
- provider_API_command.putExtra(ConfigHelper.UPDATE_PROVIDER_DOTJSON, method_and_parameters);
- provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver);
+ provider_API_command.setAction(ProviderAPI.UPDATE_PROVIDER_DOTJSON);
+ provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
+ provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
startService(provider_API_command);
}
@@ -386,19 +393,19 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn */
public void showAboutFragment(View view) {
FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
- Fragment previous_about_fragment = getFragmentManager().findFragmentByTag(ConfigHelper.ABOUT_FRAGMENT);
+ Fragment previous_about_fragment = getFragmentManager().findFragmentByTag(AboutFragment.TAG);
if (previous_about_fragment == null) {
fragment_transaction.addToBackStack(null);
Fragment newFragment = AboutFragment.newInstance();
- fragment_transaction.replace(R.id.configuration_wizard_layout, newFragment, ConfigHelper.ABOUT_FRAGMENT).commit();
+ fragment_transaction.replace(R.id.configuration_wizard_layout, newFragment, AboutFragment.TAG).commit();
}
}
@Override
public void login() {
Intent ask_login = new Intent();
- ask_login.putExtra(ConfigHelper.LOG_IN, ConfigHelper.LOG_IN);
+ ask_login.putExtra(LogInDialog.VERB, LogInDialog.VERB);
setResult(RESULT_OK, ask_login);
finish();
}
diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/bitmaskclient/Dashboard.java index 063cd3cd..97367e25 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/bitmaskclient/Dashboard.java @@ -14,14 +14,15 @@ * 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.leapclient; + package se.leap.bitmaskclient; import org.apache.http.cookie.Cookie; import org.apache.http.impl.cookie.BasicClientCookie; import org.json.JSONException; import org.json.JSONObject; -import se.leap.leapclient.ProviderAPIResultReceiver.Receiver; +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; import se.leap.openvpn.MainActivity; import android.app.Activity; import android.app.AlertDialog; @@ -54,6 +55,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected static final int CONFIGURE_LEAP = 0; private static final String TAG_EIP_FRAGMENT = "EIP_DASHBOARD_FRAGMENT"; + final public static String SHARED_PREFERENCES = "LEAPPreferences"; + final public static String ACTION_QUIT = "quit"; private ProgressDialog mProgressDialog; @@ -73,10 +76,10 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf app = this; - ConfigHelper.setSharedPreferences(getSharedPreferences(ConfigHelper.PREFERENCES_KEY, MODE_PRIVATE)); + ConfigHelper.setSharedPreferences(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE)); preferences = ConfigHelper.shared_preferences; - if (ConfigHelper.getStringFromSharedPref(ConfigHelper.PROVIDER_KEY).isEmpty()) + if (ConfigHelper.getStringFromSharedPref(Provider.KEY).isEmpty()) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(); @@ -88,11 +91,11 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( resultCode == RESULT_OK ){ startService( new Intent(EIP.ACTION_UPDATE_EIP_SERVICE) ); buildDashboard(); - if(data != null && data.hasExtra(ConfigHelper.LOG_IN)) { + if(data != null && data.hasExtra(LogInDialog.VERB)) { View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); - logInDialog(view, ""); + logInDialog(view, Bundle.EMPTY); } - } else if(resultCode == RESULT_CANCELED && data.hasExtra(ConfigHelper.QUIT)) { + } else if(resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { finish(); } else configErrorDialog(); @@ -118,8 +121,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - SharedPreferences.Editor prefsEdit = getSharedPreferences(ConfigHelper.PREFERENCES_KEY, MODE_PRIVATE).edit(); - prefsEdit.remove(ConfigHelper.PROVIDER_KEY).commit(); + SharedPreferences.Editor prefsEdit = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE).edit(); + prefsEdit.remove(Provider.KEY).commit(); finish(); } }) @@ -141,9 +144,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf providerNameTV.setTextSize(28); FragmentManager fragMan = getFragmentManager(); - if ( provider.hasEIP() && fragMan.findFragmentByTag(TAG_EIP_FRAGMENT) == null){ + if ( provider.hasEIP()){ EipServiceFragment eipFragment = new EipServiceFragment(); - fragMan.beginTransaction().add(R.id.servicesCollection, eipFragment, TAG_EIP_FRAGMENT).commit(); + fragMan.beginTransaction().replace(R.id.servicesCollection, eipFragment, TAG_EIP_FRAGMENT).commit(); } } @@ -151,9 +154,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf public boolean onPrepareOptionsMenu(Menu menu) { JSONObject provider_json; try { - provider_json = ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY); - JSONObject service_description = provider_json.getJSONObject(ConfigHelper.SERVICE_KEY); - if(service_description.getBoolean(ConfigHelper.ALLOW_REGISTRATION_KEY)) { + provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); + JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); + if(service_description.getBoolean(Provider.ALLOW_REGISTRATION)) { if(authed) { menu.findItem(R.id.login_button).setVisible(false); menu.findItem(R.id.logout_button).setVisible(true); @@ -195,7 +198,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf return true; case R.id.login_button: View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); - logInDialog(view, ""); + logInDialog(view, Bundle.EMPTY); return true; case R.id.logout_button: logOut(); @@ -213,21 +216,22 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf Intent provider_API_command = new Intent(this, ProviderAPI.class); - Bundle method_and_parameters = new Bundle(); - method_and_parameters.putString(ConfigHelper.USERNAME_KEY, username); - method_and_parameters.putString(ConfigHelper.PASSWORD_KEY, password); + Bundle parameters = new Bundle(); + parameters.putString(LogInDialog.USERNAME, username); + parameters.putString(LogInDialog.PASSWORD, password); JSONObject provider_json; try { - provider_json = new JSONObject(preferences.getString(ConfigHelper.PROVIDER_KEY, "")); - method_and_parameters.putString(ConfigHelper.API_URL_KEY, provider_json.getString(ConfigHelper.API_URL_KEY) + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY)); + provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); + parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } - provider_API_command.putExtra(ConfigHelper.SRP_AUTH, method_and_parameters); - provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver); + provider_API_command.setAction(ProviderAPI.SRP_AUTH); + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); if(mProgressDialog != null) mProgressDialog.dismiss(); mProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.authenticating_title), getResources().getString(R.string.authenticating_message), true); @@ -242,19 +246,20 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf providerAPI_result_receiver.setReceiver(this); Intent provider_API_command = new Intent(this, ProviderAPI.class); - Bundle method_and_parameters = new Bundle(); + Bundle parameters = new Bundle(); JSONObject provider_json; try { - provider_json = new JSONObject(preferences.getString(ConfigHelper.PROVIDER_KEY, "")); - method_and_parameters.putString(ConfigHelper.API_URL_KEY, provider_json.getString(ConfigHelper.API_URL_KEY) + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY)); + provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); + parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } - provider_API_command.putExtra(ConfigHelper.LOG_OUT, method_and_parameters); - provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver); + provider_API_command.setAction(ProviderAPI.LOG_OUT); + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); if(mProgressDialog != null) mProgressDialog.dismiss(); mProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.logout_title), getResources().getString(R.string.logout_message), true); @@ -265,72 +270,71 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * Shows the log in dialog. * @param view from which the dialog is created. */ - public void logInDialog(View view, String user_message) { + public void logInDialog(View view, Bundle resultData) { FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_log_in_dialog = getFragmentManager().findFragmentByTag(ConfigHelper.LOG_IN_DIALOG); + Fragment previous_log_in_dialog = getFragmentManager().findFragmentByTag(LogInDialog.TAG); if (previous_log_in_dialog != null) { fragment_transaction.remove(previous_log_in_dialog); } fragment_transaction.addToBackStack(null); DialogFragment newFragment = LogInDialog.newInstance(); - if(user_message != null && !user_message.isEmpty()) { - Bundle user_message_bundle = new Bundle(); - user_message_bundle.putString(getResources().getString(R.string.user_message), user_message); - newFragment.setArguments(user_message_bundle); + if(resultData != null && !resultData.isEmpty()) { + newFragment.setArguments(resultData); } - newFragment.show(fragment_transaction, ConfigHelper.LOG_IN_DIALOG); + newFragment.show(fragment_transaction, LogInDialog.TAG); } /** * Asks ProviderAPI to download an authenticated OpenVPN certificate. * @param session_id cookie for the server to allow us to download the certificate. */ - private void downloadAuthedUserCertificate(Cookie session_id) { + private void downloadAuthedUserCertificate(/*Cookie session_id*/) { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); Intent provider_API_command = new Intent(this, ProviderAPI.class); - Bundle method_and_parameters = new Bundle(); - method_and_parameters.putString(ConfigHelper.TYPE_OF_CERTIFICATE, ConfigHelper.AUTHED_CERTIFICATE); - method_and_parameters.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id.getName()); - method_and_parameters.putString(ConfigHelper.SESSION_ID_KEY, session_id.getValue()); + Bundle parameters = new Bundle(); + parameters.putString(ConfigurationWizard.TYPE_OF_CERTIFICATE, ConfigurationWizard.AUTHED_CERTIFICATE); + /*parameters.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id.getName()); + parameters.putString(ConfigHelper.SESSION_ID_KEY, session_id.getValue());*/ - provider_API_command.putExtra(ConfigHelper.DOWNLOAD_CERTIFICATE, method_and_parameters); - provider_API_command.putExtra(ConfigHelper.RECEIVER_KEY, providerAPI_result_receiver); + provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); startService(provider_API_command); } @Override public void onReceiveResult(int resultCode, Bundle resultData) { - if(resultCode == ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL){ - String session_id_cookie_key = resultData.getString(ConfigHelper.SESSION_ID_COOKIE_KEY); - String session_id_string = resultData.getString(ConfigHelper.SESSION_ID_KEY); + if(resultCode == ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL){ + String session_id_cookie_key = resultData.getString(ProviderAPI.SESSION_ID_COOKIE_KEY); + String session_id_string = resultData.getString(ProviderAPI.SESSION_ID_KEY); setResult(RESULT_OK); authed = true; invalidateOptionsMenu(); - Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string); - downloadAuthedUserCertificate(session_id); - } else if(resultCode == ConfigHelper.SRP_AUTHENTICATION_FAILED) { + //Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string); + downloadAuthedUserCertificate(/*session_id*/); + } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { mProgressDialog.dismiss(); - logInDialog(getCurrentFocus(), resultData.getString(getResources().getString(R.string.user_message))); - } else if(resultCode == ConfigHelper.LOGOUT_SUCCESSFUL) { + logInDialog(getCurrentFocus(), resultData); + } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { authed = false; invalidateOptionsMenu(); setResult(RESULT_OK); mProgressDialog.dismiss(); - } else if(resultCode == ConfigHelper.LOGOUT_FAILED) { + } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { setResult(RESULT_CANCELED); mProgressDialog.dismiss(); Toast.makeText(getApplicationContext(), R.string.log_out_failed_message, Toast.LENGTH_LONG).show(); - } else if(resultCode == ConfigHelper.CORRECTLY_DOWNLOADED_CERTIFICATE) { + } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { setResult(RESULT_OK); mProgressDialog.dismiss(); Toast.makeText(getApplicationContext(), R.string.successful_authed_cert_downloaded_message, Toast.LENGTH_LONG).show(); - } else if(resultCode == ConfigHelper.INCORRECTLY_DOWNLOADED_CERTIFICATE) { + } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { setResult(RESULT_CANCELED); mProgressDialog.dismiss(); Toast.makeText(getApplicationContext(), R.string.authed_cert_download_failed_message, Toast.LENGTH_LONG).show(); diff --git a/src/se/leap/leapclient/EIP.java b/src/se/leap/bitmaskclient/EIP.java index e0685c15..c643d501 100644 --- a/src/se/leap/leapclient/EIP.java +++ b/src/se/leap/bitmaskclient/EIP.java @@ -14,7 +14,7 @@ * 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.leapclient; + package se.leap.bitmaskclient; import java.util.Collection; import java.util.HashMap; @@ -26,6 +26,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import se.leap.bitmaskclient.R; import se.leap.openvpn.ConfigParser; import se.leap.openvpn.ConfigParser.ConfigParseError; import se.leap.openvpn.LaunchVPN; @@ -57,11 +58,19 @@ import android.util.Log; */ public final class EIP extends IntentService { - public final static String ACTION_START_EIP = "se.leap.leapclient.START_EIP"; - public final static String ACTION_STOP_EIP = "se.leap.leapclient.STOP_EIP"; - public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.leapclient.UPDATE_EIP_SERVICE"; - public final static String ACTION_IS_EIP_RUNNING = "se.leap.leapclient.IS_RUNNING"; + public final static String ACTION_START_EIP = "se.leap.bitmaskclient.START_EIP"; + public final static String ACTION_STOP_EIP = "se.leap.bitmaskclient.STOP_EIP"; + public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.bitmaskclient.UPDATE_EIP_SERVICE"; + public final static String ACTION_IS_EIP_RUNNING = "se.leap.bitmaskclient.IS_RUNNING"; public final static String EIP_NOTIFICATION = "EIP_NOTIFICATION"; + public final static String ALLOWED_ANON = "allow_anonymous"; + public final static String CERTIFICATE = "cert"; + public final static String PRIVATE_KEY = "private_key"; + public final static String KEY = "eip"; + public final static String PARSED_SERIAL = "eip_parsed_serial"; + public final static String SERVICE_API_PATH = "config/eip-service.json"; + public final static String RECEIVER_TAG = "receiverTag"; + public final static String REQUEST_TAG = "requestTag"; private static Context context; private static ResultReceiver mReceiver; @@ -86,8 +95,8 @@ public final class EIP extends IntentService { context = getApplicationContext(); try { - eipDefinition = ConfigHelper.getJsonFromSharedPref(ConfigHelper.EIP_SERVICE_KEY); - parsedEipSerial = ConfigHelper.getIntFromSharedPref(ConfigHelper.EIP_PARSED_SERIAL); + eipDefinition = ConfigHelper.getJsonFromSharedPref(KEY); + parsedEipSerial = ConfigHelper.getIntFromSharedPref(PARSED_SERIAL); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -107,7 +116,7 @@ public final class EIP extends IntentService { @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); - mReceiver = intent.getParcelableExtra(ConfigHelper.RECEIVER_TAG); + mReceiver = intent.getParcelableExtra(RECEIVER_TAG); if ( action == ACTION_IS_EIP_RUNNING ) this.isRunning(); @@ -150,7 +159,7 @@ public final class EIP extends IntentService { resultCode = (running) ? Activity.RESULT_CANCELED : Activity.RESULT_OK; Bundle resultData = new Bundle(); - resultData.putString(ConfigHelper.REQUEST_TAG, EIP_NOTIFICATION); + resultData.putString(REQUEST_TAG, EIP_NOTIFICATION); mReceiver.send(resultCode, resultData); mPending = null; @@ -163,7 +172,7 @@ public final class EIP extends IntentService { if (mReceiver != null){ Bundle resultData = new Bundle(); - resultData.putString(ConfigHelper.REQUEST_TAG, EIP_NOTIFICATION); + resultData.putString(REQUEST_TAG, EIP_NOTIFICATION); mReceiver.send(Activity.RESULT_CANCELED, resultData); } } @@ -181,7 +190,7 @@ public final class EIP extends IntentService { */ private void isRunning() { Bundle resultData = new Bundle(); - resultData.putString(ConfigHelper.REQUEST_TAG, ACTION_IS_EIP_RUNNING); + resultData.putString(REQUEST_TAG, ACTION_IS_EIP_RUNNING); int resultCode = Activity.RESULT_CANCELED; if (mBound) { resultCode = (mVpnService.isRunning()) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; @@ -208,7 +217,7 @@ public final class EIP extends IntentService { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); - intent.putExtra(ConfigHelper.RECEIVER_TAG, mReceiver); + intent.putExtra(RECEIVER_TAG, mReceiver); startActivity(intent); mPending = ACTION_START_EIP; } @@ -225,7 +234,7 @@ public final class EIP extends IntentService { if (mReceiver != null){ Bundle resultData = new Bundle(); - resultData.putString(ConfigHelper.REQUEST_TAG, ACTION_STOP_EIP); + resultData.putString(REQUEST_TAG, ACTION_STOP_EIP); mReceiver.send(Activity.RESULT_OK, resultData); } } @@ -237,7 +246,7 @@ public final class EIP extends IntentService { */ private void updateEIPService() { try { - eipDefinition = ConfigHelper.getJsonFromSharedPref(ConfigHelper.EIP_SERVICE_KEY); + eipDefinition = ConfigHelper.getJsonFromSharedPref(EIP.KEY); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -294,7 +303,7 @@ public final class EIP extends IntentService { } } - ConfigHelper.saveSharedPref(ConfigHelper.EIP_PARSED_SERIAL, eipDefinition.optInt(ConfigHelper.API_RETURN_SERIAL_KEY)); + ConfigHelper.saveSharedPref(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)); } /** diff --git a/src/se/leap/leapclient/EipServiceFragment.java b/src/se/leap/bitmaskclient/EipServiceFragment.java index c18f83da..daf446a5 100644 --- a/src/se/leap/leapclient/EipServiceFragment.java +++ b/src/se/leap/bitmaskclient/EipServiceFragment.java @@ -1,5 +1,6 @@ -package se.leap.leapclient; +package se.leap.bitmaskclient; +import se.leap.bitmaskclient.R; import se.leap.openvpn.LogWindow; import se.leap.openvpn.OpenVPN; import se.leap.openvpn.OpenVPN.StateListener; @@ -159,7 +160,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli private void eipCommand(String action){ // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? Intent vpnIntent = new Intent(action); - vpnIntent.putExtra(ConfigHelper.RECEIVER_TAG, mEIPReceiver); + vpnIntent.putExtra(EIP.RECEIVER_TAG, mEIPReceiver); getActivity().startService(vpnIntent); } @@ -214,7 +215,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnCli protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(ConfigHelper.REQUEST_TAG); + String request = resultData.getString(EIP.REQUEST_TAG); boolean checked = false; if (request == EIP.ACTION_IS_EIP_RUNNING) { diff --git a/src/se/leap/leapclient/LeapHttpClient.java b/src/se/leap/bitmaskclient/LeapHttpClient.java index 686d3cc0..837da236 100644 --- a/src/se/leap/leapclient/LeapHttpClient.java +++ b/src/se/leap/bitmaskclient/LeapHttpClient.java @@ -14,7 +14,7 @@ * 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.leapclient; + package se.leap.bitmaskclient; import java.security.KeyStore; @@ -46,9 +46,9 @@ public class LeapHttpClient extends DefaultHttpClient { public static LeapHttpClient getInstance(Context context) { if(client == null) { client = new LeapHttpClient(context); - String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); + String cert_string = ConfigHelper.getStringFromSharedPref(Provider.CA_CERT); if(cert_string != null) { - ConfigHelper.addTrustedCertificate("recovered_certificate", cert_string); + ConfigHelper.addTrustedCertificate("provider_ca_certificate", cert_string); } } return client; @@ -65,15 +65,12 @@ public class LeapHttpClient extends DefaultHttpClient { /** * Uses keystore from ConfigHelper for the SSLSocketFactory. - * - * Sets hostname verifier to allow all hostname verifier. * @return */ private SSLSocketFactory newSslSocketFactory() { try { KeyStore trusted = ConfigHelper.getKeystore(); SSLSocketFactory sf = new SSLSocketFactory(trusted); - sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); return sf; } catch (Exception e) { diff --git a/src/se/leap/leapclient/LeapSRPSession.java b/src/se/leap/bitmaskclient/LeapSRPSession.java index 9451c1be..9260c81f 100644 --- a/src/se/leap/leapclient/LeapSRPSession.java +++ b/src/se/leap/bitmaskclient/LeapSRPSession.java @@ -14,7 +14,7 @@ * 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.leapclient; + package se.leap.bitmaskclient; import java.io.UnsupportedEncodingException; import java.math.BigInteger; @@ -34,6 +34,10 @@ import org.jboss.security.srp.SRPParameters; * */ public class LeapSRPSession { + + final public static String SALT = "salt"; + final public static String M1 = "M1"; + final public static String M2 = "M2"; private SRPParameters params; private String username; diff --git a/src/se/leap/leapclient/LogInDialog.java b/src/se/leap/bitmaskclient/LogInDialog.java index 8b3f9e80..3651e9ba 100644 --- a/src/se/leap/leapclient/LogInDialog.java +++ b/src/se/leap/bitmaskclient/LogInDialog.java @@ -14,16 +14,21 @@ * 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.leapclient; + package se.leap.bitmaskclient; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; +import android.R.color; import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; import android.content.DialogInterface; +import android.content.res.ColorStateList; import android.os.Bundle; +import android.provider.CalendarContract.Colors; import android.view.LayoutInflater; import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.BounceInterpolator; import android.widget.EditText; import android.widget.TextView; @@ -38,7 +43,16 @@ import android.widget.TextView; * */ public class LogInDialog extends DialogFragment { - + + + final public static String TAG = "logInDialog"; + final public static String VERB = "log in"; + final public static String USERNAME = "username"; + final public static String PASSWORD = "password"; + final public static String USERNAME_MISSING = "username missing"; + final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; + + public AlertDialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); @@ -47,15 +61,34 @@ public class LogInDialog extends DialogFragment { final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); if(getArguments() != null && getArguments().containsKey(getResources().getString(R.string.user_message))) { user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); - } else user_message.setVisibility(View.GONE); + } else { + user_message.setVisibility(View.GONE); + } + final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); + if(getArguments() != null && getArguments().containsKey(USERNAME)) { + String username = getArguments().getString(USERNAME); + username_field.setText(username); + } + if (getArguments() != null && getArguments().containsKey(USERNAME_MISSING)) { + username_field.setError(getResources().getString(R.string.username_ask)); + } + final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); + if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { + password_field.requestFocus(); + } + if (getArguments() != null && getArguments().containsKey(PASSWORD_INVALID_LENGTH)) { + password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); + } + builder.setView(log_in_dialog_view) .setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { String username = username_field.getText().toString().trim(); String password = password_field.getText().toString().trim(); + dialog.dismiss(); interface_with_Dashboard.authenticate(username, password); } }) diff --git a/src/se/leap/leapclient/NewProviderDialog.java b/src/se/leap/bitmaskclient/NewProviderDialog.java index 0b9d8fd0..f77cb6d4 100644 --- a/src/se/leap/leapclient/NewProviderDialog.java +++ b/src/se/leap/bitmaskclient/NewProviderDialog.java @@ -14,9 +14,9 @@ * 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.leapclient; + package se.leap.bitmaskclient; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -36,7 +36,9 @@ import android.widget.Toast; * */ public class NewProviderDialog extends DialogFragment { - + + final public static String TAG = "newProviderDialog"; + public interface NewProviderDialogInterface { public void saveAndSelectProvider(String url_provider, boolean danger_on); } diff --git a/src/se/leap/leapclient/Provider.java b/src/se/leap/bitmaskclient/Provider.java index cdcd56c5..e462829f 100644 --- a/src/se/leap/leapclient/Provider.java +++ b/src/se/leap/bitmaskclient/Provider.java @@ -14,7 +14,7 @@ * 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.leapclient; +package se.leap.bitmaskclient; import java.io.Serializable; import java.util.Arrays; @@ -42,7 +42,21 @@ public final class Provider implements Serializable { private static SharedPreferences preferences = null; // Represents our Provider's provider.json private static JSONObject definition = null; - + + final public static String + API_URL = "api_uri", + API_VERSION = "api_version", + ALLOW_REGISTRATION = "allow_registration", + API_RETURN_SERIAL = "serial", + SERVICE = "service", + KEY = "provider", + CA_CERT = "ca_cert", + NAME = "name", + DESCRIPTION = "description", + DOMAIN = "domain", + MAIN_URL = "main_url", + DOT_JSON_URL = "provider_json_url" + ; // Array of what API versions we understand protected static final String[] API_VERSIONS = {"1"}; // I assume we might encounter arbitrary version "numbers" @@ -82,7 +96,7 @@ public final class Provider implements Serializable { //preferences = context.getgetPreferences(0); // 0 == MODE_PRIVATE, but we don't extend Android's classes... // Load SharedPreferences - preferences = activity.getSharedPreferences(ConfigHelper.PREFERENCES_KEY,Context.MODE_PRIVATE); + preferences = activity.getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); // Inflate our provider.json data try { definition = new JSONObject( preferences.getString("provider", "") ); diff --git a/src/se/leap/bitmaskclient/ProviderAPI.java b/src/se/leap/bitmaskclient/ProviderAPI.java new file mode 100644 index 00000000..39b44e24 --- /dev/null +++ b/src/se/leap/bitmaskclient/ProviderAPI.java @@ -0,0 +1,780 @@ +/** + * 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; + +import java.io.DataOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.MalformedURLException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Scanner; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.client.ClientProtocolException; +import org.jboss.security.srp.SRPParameters; +import org.json.JSONException; +import org.json.JSONObject; + +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.ProviderListContent.ProviderItem; +import android.app.IntentService; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.ResultReceiver; +import android.util.Base64; +import android.util.Log; +import android.widget.Toast; + +/** + * Implements HTTP api methods used to manage communications with the provider server. + * + * It's an IntentService because it downloads data from the Internet, so it operates in the background. + * + * @author parmegv + * @author MeanderingCode + * + */ +public class ProviderAPI extends IntentService { + + private Handler mHandler; + + final public static String + DOWNLOAD_JSON_FILES_BUNDLE_EXTRA = "downloadJSONFiles", + UPDATE_PROVIDER_DOTJSON = "updateProviderDotJSON", + DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON", + SRP_REGISTER = "srpRegister", + SRP_AUTH = "srpAuth", + LOG_OUT = "logOut", + DOWNLOAD_CERTIFICATE = "downloadUserAuthedCertificate", + PARAMETERS = "parameters", + RESULT_KEY = "result", + RECEIVER_KEY = "receiver", + SESSION_ID_COOKIE_KEY = "session_id_cookie_key", + SESSION_ID_KEY = "session_id", + ERRORS = "errors" + ; + + final public static int + CUSTOM_PROVIDER_ADDED = 0, + CORRECTLY_DOWNLOADED_JSON_FILES = 1, + INCORRECTLY_DOWNLOADED_JSON_FILES = 2, + SRP_AUTHENTICATION_SUCCESSFUL = 3, + SRP_AUTHENTICATION_FAILED = 4, + SRP_REGISTRATION_SUCCESSFUL = 5, + SRP_REGISTRATION_FAILED = 6, + LOGOUT_SUCCESSFUL = 7, + LOGOUT_FAILED = 8, + CORRECTLY_DOWNLOADED_CERTIFICATE = 9, + INCORRECTLY_DOWNLOADED_CERTIFICATE = 10, + CORRECTLY_UPDATED_PROVIDER_DOT_JSON = 11, + INCORRECTLY_UPDATED_PROVIDER_DOT_JSON = 12, + CORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 13, + INCORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 14 + ; + + public ProviderAPI() { + super("ProviderAPI"); + Log.v("ClassName", "Provider API"); + } + + @Override + public void onCreate() { + super.onCreate(); + mHandler = new Handler(); + CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) ); + } + + private void displayToast(final int toast_string_id) { + mHandler.post(new Runnable() { + + @Override + public void run() { + Toast.makeText(ProviderAPI.this, toast_string_id, Toast.LENGTH_LONG).show(); + } + }); + } + + @Override + protected void onHandleIntent(Intent command) { + final ResultReceiver receiver = command.getParcelableExtra("receiver"); + String action = command.getAction(); + Bundle parameters = command.getBundleExtra(PARAMETERS); + + if(action.equalsIgnoreCase(DOWNLOAD_JSON_FILES_BUNDLE_EXTRA)) { + if(!downloadJsonFiles(parameters)) { + receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + } else { + receiver.send(CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + } + } else if(action.equalsIgnoreCase(UPDATE_PROVIDER_DOTJSON)) { + Bundle result = updateProviderDotJSON(parameters); + if(result.getBoolean(RESULT_KEY)) { + receiver.send(CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); + } else { + receiver.send(INCORRECTLY_UPDATED_PROVIDER_DOT_JSON, Bundle.EMPTY); + } + } else if (action.equalsIgnoreCase(DOWNLOAD_NEW_PROVIDER_DOTJSON)) { + Bundle result = downloadNewProviderDotJSON(parameters); + if(result.getBoolean(RESULT_KEY)) { + receiver.send(CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); + } else { + receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + } + } else if (action.equalsIgnoreCase(SRP_AUTH)) { + Bundle session_id_bundle = authenticateBySRP(parameters); + if(session_id_bundle.getBoolean(RESULT_KEY)) { + receiver.send(SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); + } else { + receiver.send(SRP_AUTHENTICATION_FAILED, session_id_bundle); + } + } else if (action.equalsIgnoreCase(LOG_OUT)) { + if(logOut(parameters)) { + receiver.send(LOGOUT_SUCCESSFUL, Bundle.EMPTY); + } else { + receiver.send(LOGOUT_FAILED, Bundle.EMPTY); + } + } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { + if(getNewCert(parameters)) { + receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); + } else { + receiver.send(INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); + } + } + } + + /** + * Downloads the main cert and the eip-service.json files given through the task parameter + * @param task + * @return true if eip-service.json was parsed as a JSON object correctly. + */ + private boolean downloadJsonFiles(Bundle task) { + String cert_url = task.getString(Provider.CA_CERT); + String eip_service_json_url = task.getString(EIP.KEY); + boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); + try { + String cert_string = downloadWithCommercialCA(cert_url, danger_on); + if(cert_string.isEmpty()) return false; + X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string); + cert_string = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); + ConfigHelper.saveSharedPref(Provider.CA_CERT, "-----BEGIN CERTIFICATE-----\n"+cert_string+"-----END CERTIFICATE-----"); + + String eip_service_string = downloadWithCommercialCA(eip_service_json_url, danger_on); + ConfigHelper.saveSharedPref(EIP.KEY, new JSONObject(eip_service_string)); + + return true; + } catch (JSONException e) { + return false; + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + } + + /** + * 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. + */ + private Bundle authenticateBySRP(Bundle task) { + Bundle session_id_bundle = new Bundle(); + + String username = (String) task.get(LogInDialog.USERNAME); + String password = (String) task.get(LogInDialog.PASSWORD); + if(validUserLoginData(username, password)) { + String authentication_server = (String) task.get(Provider.API_URL); + + SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); + LeapSRPSession client = new LeapSRPSession(username, password, params); + byte[] A = client.exponential(); + try { + JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); + if(saltAndB.length() > 0) { + String salt = saltAndB.getString(LeapSRPSession.SALT); + byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); + byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); + JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); + if(session_idAndM2.has(LeapSRPSession.M2) && client.verify((byte[])session_idAndM2.get(LeapSRPSession.M2))) { + session_id_bundle.putBoolean(RESULT_KEY, true); + } else { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); + session_id_bundle.putString(LogInDialog.USERNAME, username); + } + } else { + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); + session_id_bundle.putString(LogInDialog.USERNAME, username); + session_id_bundle.putBoolean(RESULT_KEY, false); + } + } catch (ClientProtocolException e) { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_client_http_user_message)); + session_id_bundle.putString(LogInDialog.USERNAME, username); + } catch (IOException e) { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_io_exception_user_message)); + session_id_bundle.putString(LogInDialog.USERNAME, username); + } catch (JSONException e) { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_json_exception_user_message)); + session_id_bundle.putString(LogInDialog.USERNAME, username); + } catch (NoSuchAlgorithmException e) { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_no_such_algorithm_exception_user_message)); + session_id_bundle.putString(LogInDialog.USERNAME, username); + } catch (KeyManagementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + if(!wellFormedPassword(password)) { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putString(LogInDialog.USERNAME, username); + session_id_bundle.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true); + } + if(username.isEmpty()) { + session_id_bundle.putBoolean(RESULT_KEY, false); + session_id_bundle.putBoolean(LogInDialog.USERNAME_MISSING, true); + } + } + + return session_id_bundle; + } + + /** + * Validates parameters entered by the user to log in + * @param entered_username + * @param entered_password + * @return true if both parameters are present and the entered password length is greater or equal to eight (8). + */ + private boolean validUserLoginData(String entered_username, String entered_password) { + return !(entered_username.isEmpty()) && wellFormedPassword(entered_password); + } + + /** + * Validates a password + * @param entered_password + * @return true if the entered password length is greater or equal to eight (8). + */ + private boolean wellFormedPassword(String entered_password) { + return entered_password.length() >= 8; + } + + /** + * Sends an HTTP POST request to the authentication server with the SRP Parameter A. + * @param server_url + * @param username + * @param clientA First SRP parameter sent + * @return response from authentication server + * @throws ClientProtocolException + * @throws IOException + * @throws JSONException + * @throws CertificateException + * @throws NoSuchAlgorithmException + * @throws KeyStoreException + * @throws KeyManagementException + */ + private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException { + Map<String, String> parameters = new HashMap<String, String>(); + parameters.put("login", username); + parameters.put("A", clientA); + return sendToServer(server_url + "/sessions.json", "POST", parameters); + + /*HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + "login=" + username + "&&" + "A=" + clientA); + return sendToServer(post);*/ + } + + /** + * Sends an HTTP PUT request to the authentication server with the SRP Parameter M1 (or simply M). + * @param server_url + * @param username + * @param m1 Second SRP parameter sent + * @return response from authentication server + * @throws ClientProtocolException + * @throws IOException + * @throws JSONException + * @throws CertificateException + * @throws NoSuchAlgorithmException + * @throws KeyStoreException + * @throws KeyManagementException + */ + private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException { + Map<String, String> parameters = new HashMap<String, String>(); + parameters.put("client_auth", new BigInteger(1, ConfigHelper.trim(m1)).toString(16)); + + //HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, ConfigHelper.trim(m1)).toString(16)); + JSONObject json_response = sendToServer(server_url + "/sessions/" + username +".json", "PUT", parameters); + + JSONObject session_idAndM2 = new JSONObject(); + if(json_response.length() > 0) { + byte[] M2_not_trimmed = new BigInteger(json_response.getString(LeapSRPSession.M2), 16).toByteArray(); + /*Cookie session_id_cookie = LeapHttpClient.getInstance(getApplicationContext()).getCookieStore().getCookies().get(0); + session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName()); + session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue());*/ + session_idAndM2.put(LeapSRPSession.M2, ConfigHelper.trim(M2_not_trimmed)); + } + return session_idAndM2; + } + + /** + * Executes an HTTP request expecting a JSON response. + * @param url + * @param request_method + * @param parameters + * @return response from authentication server + * @throws IOException + * @throws JSONException + * @throws MalformedURLException + * @throws CertificateException + * @throws NoSuchAlgorithmException + * @throws KeyStoreException + * @throws KeyManagementException + */ + private JSONObject sendToServer(String url, String request_method, Map<String, String> parameters) throws JSONException, MalformedURLException, IOException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException { + JSONObject json_response; + InputStream is = null; + HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(url).openConnection(); + urlConnection.setRequestMethod(request_method); + urlConnection.setChunkedStreamingMode(0); + urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); + try { + + DataOutputStream writer = new DataOutputStream(urlConnection.getOutputStream()); + writer.writeBytes(formatHttpParameters(parameters)); + writer.close(); + + is = urlConnection.getInputStream(); + String plain_response = new Scanner(is).useDelimiter("\\A").next(); + json_response = new JSONObject(plain_response); + } finally { + InputStream error_stream = urlConnection.getErrorStream(); + if(error_stream != null) { + String error_response = new Scanner(error_stream).useDelimiter("\\A").next(); + urlConnection.disconnect(); + Log.d("Error", error_response); + json_response = new JSONObject(error_response); + if(!json_response.isNull(ERRORS) || json_response.has(ERRORS)) { + return new JSONObject(); + } + } + } + + return json_response; + } + + private String formatHttpParameters(Map<String, String> parameters) throws UnsupportedEncodingException { + StringBuilder result = new StringBuilder(); + boolean first = true; + + Iterator<String> parameter_iterator = parameters.keySet().iterator(); + while(parameter_iterator.hasNext()) { + if(first) + first = false; + else + result.append("&&"); + + String key = parameter_iterator.next(); + String value = parameters.get(key); + + result.append(URLEncoder.encode(key, "UTF-8")); + result.append("="); + result.append(URLEncoder.encode(value, "UTF-8")); + } + + return result.toString(); + } + /** + * Downloads a provider.json from a given URL, adding a new provider using the given name. + * @param task containing a boolean meaning if the provider is custom or not, another boolean meaning if the user completely trusts this provider, the provider name and its provider.json url. + * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the update was successful. + */ + private Bundle updateProviderDotJSON(Bundle task) { + Bundle result = new Bundle(); + boolean custom = task.getBoolean(ProviderItem.CUSTOM); + boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); + String provider_json_url = task.getString(Provider.DOT_JSON_URL); + String provider_name = task.getString(Provider.NAME); + + try { + String provider_dot_json_string = downloadWithCommercialCA(provider_json_url, danger_on); + if(provider_dot_json_string.isEmpty()) { + result.putBoolean(RESULT_KEY, false); + } else { + JSONObject provider_json = new JSONObject(provider_dot_json_string); + ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)); + + //ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); + result.putBoolean(RESULT_KEY, true); + result.putString(Provider.KEY, provider_json.toString()); + result.putBoolean(ProviderItem.DANGER_ON, danger_on); + } + } catch (JSONException e) { + result.putBoolean(RESULT_KEY, false); + } + + return result; + } + + /** + * Downloads a custom provider provider.json file + * @param task containing a boolean meaning if the user completely trusts this provider, and the provider main url entered in the new custom provider dialog. + * @return true if provider.json file was successfully parsed as a JSON object. + */ + private Bundle downloadNewProviderDotJSON(Bundle task) { + Bundle result = new Bundle(); + boolean custom = true; + boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); + + String provider_main_url = (String) task.get(Provider.MAIN_URL); + String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); + String provider_json_url = guessProviderDotJsonURL(provider_main_url); + + String provider_json_string = downloadWithCommercialCA(provider_json_url, danger_on); + try { + if(provider_json_string.isEmpty()) { + result.putBoolean(RESULT_KEY, false); + } else { + JSONObject provider_json = new JSONObject(provider_json_string); + + ConfigHelper.saveSharedPref(Provider.KEY, provider_json); + ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on); + ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)); + ProviderItem added_provider = new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on); + ProviderListContent.addItem(added_provider); + + result.putString(Provider.NAME, added_provider.getName()); + result.putBoolean(RESULT_KEY, true); + result.putString(Provider.KEY, provider_json.toString()); + result.putBoolean(ProviderItem.DANGER_ON, danger_on); + } + } catch (JSONException e) { + result.putBoolean(RESULT_KEY, false); + } + + return result; + } + + /** + * Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider. + * + * If danger_on 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 + * @return + */ + private String downloadWithCommercialCA(String string_url, boolean danger_on) { + + String json_file_content = ""; + + URL provider_url = null; + int seconds_of_timeout = 1; + try { + provider_url = new URL(string_url); + URLConnection url_connection = provider_url.openConnection(); + url_connection.setConnectTimeout(seconds_of_timeout*1000); + json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next(); + } catch (MalformedURLException e) { + displayToast(R.string.malformed_url); + } catch(SocketTimeoutException e) { + displayToast(R.string.server_is_down_message); + } catch (FileNotFoundException e) { + e.printStackTrace(); + displayToast(R.string.server_is_down_message); + } catch (IOException e) { + if(provider_url != null) { + json_file_content = downloadWithProviderCA(provider_url, danger_on); + } else { + displayToast(R.string.certificate_error); + } + } catch (Exception e) { + if(provider_url != null && danger_on) { + json_file_content = downloadWithProviderCA(provider_url, danger_on); + } + } + + return json_file_content; + } + + /** + * Tries to download the contents of the provided url using not commercially validated CA certificate from chosen provider. + * @param url + * @param danger_on true to download CA certificate in case it has not been downloaded. + * @return an empty string if it fails, the url content if not. + */ + private String downloadWithProviderCA(URL url, boolean danger_on) { + String json_file_content = ""; + + try { + // Tell the URLConnection to use a SocketFactory from our SSLContext + HttpsURLConnection urlConnection = + (HttpsURLConnection)url.openConnection(); + urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); + json_file_content = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (UnknownHostException e) { + displayToast(R.string.server_is_down_message); + } catch (FileNotFoundException e) { + e.printStackTrace(); + displayToast(R.string.server_is_down_message); + } catch (IOException e) { + // The downloaded certificate doesn't validate our https connection. + if(danger_on) { + json_file_content = downloadWithoutCA(url); + } else { + displayToast(R.string.certificate_error); + } + } 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 javax.net.ssl.SSLSocketFactory getProviderSSLSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException { + String provider_cert_string = ConfigHelper.getStringFromSharedPref(Provider.CA_CERT); + + java.security.cert.Certificate provider_certificate = ConfigHelper.parseX509CertificateFromString(provider_cert_string); + + // Create a KeyStore containing our trusted CAs + String keyStoreType = KeyStore.getDefaultType(); + KeyStore keyStore = KeyStore.getInstance(keyStoreType); + keyStore.load(null, null); + keyStore.setCertificateEntry("provider_ca_certificate", provider_certificate); + + // 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); + + return context.getSocketFactory(); + } + + /** + * Downloads the string that's in the url with any certificate. + */ + private String downloadWithoutCA(URL url) { + String string = ""; + try { + + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + class DefaultTrustManager implements X509TrustManager { + + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} + + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + } + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); + + HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); + urlConnection.setSSLSocketFactory(context.getSocketFactory()); + urlConnection.setHostnameVerifier(hostnameVerifier); + string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); + System.out.println("String ignoring certificate = " + string); + } catch (FileNotFoundException e) { + e.printStackTrace(); + displayToast(R.string.server_is_down_message); + } catch (IOException e) { + // The downloaded certificate doesn't validate our https connection. + e.printStackTrace(); + displayToast(R.string.certificate_error); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyManagementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return string; + } + + /** + * Tries to guess the provider.json url given the main provider url. + * @param provider_main_url + * @return the guessed provider.json url + */ + private String guessProviderDotJsonURL(String provider_main_url) { + return provider_main_url + "/provider.json"; + } + + /** + * Logs out from the api url retrieved from the task. + * @param task containing api url from which the user will log out + * @return true if there were no exceptions + */ + private boolean logOut(Bundle task) { + try { + String delete_url = task.getString(Provider.API_URL) + "/logout"; + + HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); + urlConnection.setRequestMethod("DELETE"); + urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); + + int responseCode = urlConnection.getResponseCode(); + Log.d("logout", Integer.toString(responseCode)); + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (IndexOutOfBoundsException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (KeyManagementException 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 (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return true; + } + + /** + * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. + * + * @param task containing the type of the certificate to be downloaded + * @return true if certificate was downloaded correctly, false if provider.json or danger_on flag are not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error. + */ + private boolean getNewCert(Bundle task) { + + try { + String type_of_certificate = task.getString(ConfigurationWizard.TYPE_OF_CERTIFICATE); + JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); + URL provider_main_url = new URL(provider_json.getString(Provider.API_URL)); + String new_cert_string_url = provider_main_url.toString() + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE; + + boolean danger_on = ConfigHelper.getBoolFromSharedPref(ProviderItem.DANGER_ON); + String cert_string = downloadWithCommercialCA(new_cert_string_url, danger_on); + if(!cert_string.isEmpty()) { + // API returns concatenated cert & key. Split them for OpenVPN options + String certificateString = null, keyString = null; + String[] certAndKey = cert_string.split("(?<=-\n)"); + for (int i=0; i < certAndKey.length-1; i++){ + if ( certAndKey[i].contains("KEY") ) { + keyString = certAndKey[i++] + certAndKey[i]; + } + else if ( certAndKey[i].contains("CERTIFICATE") ) { + certificateString = certAndKey[i++] + certAndKey[i]; + } + } + try { + RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString); + keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT ); + ConfigHelper.saveSharedPref(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----"); + + X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); + certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); + ConfigHelper.saveSharedPref(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----"); + + return true; + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + } else { + return false; + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } /*catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + }*/ + } +} diff --git a/src/se/leap/leapclient/ProviderAPIResultReceiver.java b/src/se/leap/bitmaskclient/ProviderAPIResultReceiver.java index d82484c8..7b256124 100644 --- a/src/se/leap/leapclient/ProviderAPIResultReceiver.java +++ b/src/se/leap/bitmaskclient/ProviderAPIResultReceiver.java @@ -14,7 +14,7 @@ * 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.leapclient;
+ package se.leap.bitmaskclient;
import android.os.Bundle;
import android.os.Handler;
diff --git a/src/se/leap/leapclient/ProviderDetailFragment.java b/src/se/leap/bitmaskclient/ProviderDetailFragment.java index 600be58f..4006a76c 100644 --- a/src/se/leap/leapclient/ProviderDetailFragment.java +++ b/src/se/leap/bitmaskclient/ProviderDetailFragment.java @@ -1,8 +1,11 @@ -package se.leap.leapclient;
+package se.leap.bitmaskclient;
import org.json.JSONException;
import org.json.JSONObject;
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -14,6 +17,9 @@ import android.view.View; import android.widget.TextView;
public class ProviderDetailFragment extends DialogFragment {
+
+ final public static String TAG = "providerDetailFragment";
+
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
@@ -22,14 +28,14 @@ public class ProviderDetailFragment extends DialogFragment { LayoutInflater inflater = getActivity().getLayoutInflater();
View provider_detail_view = inflater.inflate(R.layout.provider_detail_fragment, null);
- JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY);
+ JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY);
final TextView domain = (TextView)provider_detail_view.findViewById(R.id.provider_detail_domain);
- domain.setText(provider_json.getString(ConfigHelper.DOMAIN));
+ domain.setText(provider_json.getString(Provider.DOMAIN));
final TextView name = (TextView)provider_detail_view.findViewById(R.id.provider_detail_name);
- name.setText(provider_json.getJSONObject(ConfigHelper.NAME).getString("en"));
+ name.setText(provider_json.getJSONObject(Provider.NAME).getString("en"));
final TextView description = (TextView)provider_detail_view.findViewById(R.id.provider_detail_description);
- description.setText(provider_json.getJSONObject(ConfigHelper.DESCRIPTION).getString("en"));
+ description.setText(provider_json.getJSONObject(Provider.DESCRIPTION).getString("en"));
builder.setView(provider_detail_view);
builder.setTitle(R.string.provider_details_fragment_title);
@@ -58,8 +64,8 @@ public class ProviderDetailFragment extends DialogFragment { private boolean anon_allowed(JSONObject provider_json) {
try {
- JSONObject service_description = provider_json.getJSONObject(ConfigHelper.SERVICE_KEY);
- return service_description.has(ConfigHelper.ALLOWED_ANON) && service_description.getBoolean(ConfigHelper.ALLOWED_ANON);
+ JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE);
+ return service_description.has(EIP.ALLOWED_ANON) && service_description.getBoolean(EIP.ALLOWED_ANON);
} catch (JSONException e) {
return false;
}
@@ -67,8 +73,8 @@ public class ProviderDetailFragment extends DialogFragment { private boolean registration_allowed(JSONObject provider_json) {
try {
- JSONObject service_description = provider_json.getJSONObject(ConfigHelper.SERVICE_KEY);
- return service_description.has(ConfigHelper.ALLOW_REGISTRATION_KEY) && service_description.getBoolean(ConfigHelper.ALLOW_REGISTRATION_KEY);
+ JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE);
+ return service_description.has(Provider.ALLOW_REGISTRATION) && service_description.getBoolean(Provider.ALLOW_REGISTRATION);
} catch (JSONException e) {
return false;
}
@@ -77,10 +83,10 @@ public class ProviderDetailFragment extends DialogFragment { @Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
- ConfigHelper.removeFromSharedPref(ConfigHelper.PROVIDER_KEY);
- ConfigHelper.removeFromSharedPref(ConfigHelper.DANGER_ON);
- ConfigHelper.removeFromSharedPref(ConfigHelper.ALLOWED_ANON);
- ConfigHelper.removeFromSharedPref(ConfigHelper.EIP_SERVICE_KEY);
+ ConfigHelper.removeFromSharedPref(Provider.KEY);
+ ConfigHelper.removeFromSharedPref(ProviderItem.DANGER_ON);
+ ConfigHelper.removeFromSharedPref(EIP.ALLOWED_ANON);
+ ConfigHelper.removeFromSharedPref(EIP.KEY);
}
public static DialogFragment newInstance() {
diff --git a/src/se/leap/leapclient/ProviderListContent.java b/src/se/leap/bitmaskclient/ProviderListContent.java index 714ed5f4..940a594d 100644 --- a/src/se/leap/leapclient/ProviderListContent.java +++ b/src/se/leap/bitmaskclient/ProviderListContent.java @@ -14,7 +14,7 @@ * 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.leapclient;
+ package se.leap.bitmaskclient;
import java.io.IOException;
import java.io.InputStream;
@@ -52,7 +52,12 @@ public class ProviderListContent { /**
* A provider item.
*/
- public static class ProviderItem {
+ public static class ProviderItem {
+
+
+ final public static String CUSTOM = "custom";
+ final public static String DANGER_ON = "danger_on";
+
public boolean custom = false;
public String id;
public String name;
@@ -79,11 +84,11 @@ public class ProviderListContent { JSONObject file_contents = new JSONObject(urls_file_content);
id = name;
this.name = name;
- provider_json_url = file_contents.getString(ConfigHelper.PROVIDER_JSON_URL);
+ provider_json_url = file_contents.getString(Provider.DOT_JSON_URL);
domain = new URL(provider_json_url).getHost();
//provider_json_filename = file_contents.getString("assets_json_provider");
eip_service_json_url = file_contents.getString("json_eip_service");
- cert_json_url = file_contents.getString(ConfigHelper.CERT_KEY);
+ cert_json_url = file_contents.getString(EIP.CERTIFICATE);
this.custom = custom;
this.danger_on = danger_on;
} catch (MalformedURLException e) {
@@ -114,7 +119,7 @@ public class ProviderListContent { this.provider_json = provider_json;
this.name = provider_json.getJSONObject("name").getString("en");
domain = new URL(provider_json_url).getHost();
- eip_service_json_url = provider_json.getString(ConfigHelper.API_URL_KEY) + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.EIP_SERVICE_API_PATH;
+ eip_service_json_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
cert_json_url = provider_json.getString("ca_cert_uri");
this.custom = custom;
this.danger_on = danger_on;
@@ -134,7 +139,7 @@ public class ProviderListContent { return name;
}
- public String getId() {
+ public String getName() {
return id;
}
}
diff --git a/src/se/leap/leapclient/ProviderListFragment.java b/src/se/leap/bitmaskclient/ProviderListFragment.java index 2fca20e2..82c4bdc8 100644 --- a/src/se/leap/leapclient/ProviderListFragment.java +++ b/src/se/leap/bitmaskclient/ProviderListFragment.java @@ -14,9 +14,10 @@ * 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.leapclient;
+ package se.leap.bitmaskclient;
-import se.leap.leapclient.ProviderListContent.ProviderItem;
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
import android.app.Activity;
import android.app.ListFragment;
import android.os.Bundle;
diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java deleted file mode 100644 index 944a0e7f..00000000 --- a/src/se/leap/leapclient/ProviderAPI.java +++ /dev/null @@ -1,733 +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.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.security.SecureRandom; -import javax.net.ssl.KeyManager; -import java.net.CookieHandler; -import java.net.CookieManager; -import java.net.HttpCookie; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -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 javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.protocol.ClientContext; -import org.apache.http.cookie.Cookie; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; -import org.jboss.security.srp.SRPParameters; -import org.json.JSONException; -import org.json.JSONObject; - -import se.leap.leapclient.ProviderListContent.ProviderItem; - -import android.app.IntentService; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.util.Base64; -import android.util.Log; -import android.widget.Toast; - -/** - * Implements HTTP api methods used to manage communications with the provider server. - * - * It's an IntentService because it downloads data from the Internet, so it operates in the background. - * - * @author parmegv - * @author MeanderingCode - * - */ -public class ProviderAPI extends IntentService { - - private Handler mHandler; - - public ProviderAPI() { - super("ProviderAPI"); - Log.v("ClassName", "Provider API"); - } - - @Override - public void onCreate() { - super.onCreate(); - mHandler = new Handler(); - } - - private void displayToast(final int toast_string_id) { - mHandler.post(new Runnable() { - - @Override - public void run() { - Toast.makeText(ProviderAPI.this, toast_string_id, Toast.LENGTH_LONG).show(); - } - }); - } - - @Override - protected void onHandleIntent(Intent task_for) { - final ResultReceiver receiver = task_for.getParcelableExtra("receiver"); - - Bundle task; - if((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_JSON_FILES_BUNDLE_EXTRA)) != null) { - if(!downloadJsonFiles(task)) { - receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - } else { - receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - } - } - else if ((task = task_for.getBundleExtra(ConfigHelper.UPDATE_PROVIDER_DOTJSON)) != null) { - Bundle result = updateProviderDotJSON(task); - if(result.getBoolean(ConfigHelper.RESULT_KEY)) { - receiver.send(ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); - } else { - receiver.send(ConfigHelper.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON, Bundle.EMPTY); - } - } - else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_NEW_PROVIDER_DOTJSON)) != null) { - Bundle result = downloadNewProviderDotJSON(task); - if(result.getBoolean(ConfigHelper.RESULT_KEY)) { - receiver.send(ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); - } else { - receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - } - } - else if ((task = task_for.getBundleExtra(ConfigHelper.SRP_AUTH)) != null) { - Bundle session_id_bundle = authenticateBySRP(task); - if(session_id_bundle.getBoolean(ConfigHelper.RESULT_KEY)) { - receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); - } else { - Bundle user_message_bundle = new Bundle(); - String user_message_key = getResources().getString(R.string.user_message); - user_message_bundle.putString(user_message_key, session_id_bundle.getString(user_message_key)); - receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, user_message_bundle); - } - } - else if ((task = task_for.getBundleExtra(ConfigHelper.LOG_OUT)) != null) { - if(logOut(task)) { - receiver.send(ConfigHelper.LOGOUT_SUCCESSFUL, Bundle.EMPTY); - } else { - receiver.send(ConfigHelper.LOGOUT_FAILED, Bundle.EMPTY); - } - } - else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_CERTIFICATE)) != null) { - if(getNewCert(task)) { - receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); - } else { - receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); - } - } - } - - /** - * Downloads the main cert and the eip-service.json files given through the task parameter - * @param task - * @return true if eip-service.json was parsed as a JSON object correctly. - */ - private boolean downloadJsonFiles(Bundle task) { - String cert_url = task.getString(ConfigHelper.MAIN_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, danger_on); - ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); - JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); - ConfigHelper.saveSharedPref(ConfigHelper.EIP_SERVICE_KEY, eip_service_json); - return true; - } catch (JSONException e) { - return false; - } - } - - /** - * 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 ConfigHelper.RESULT_KEY, and which is true if authentication was successful. - */ - private Bundle authenticateBySRP(Bundle task) { - Bundle session_id_bundle = new Bundle(); - - String username = (String) task.get(ConfigHelper.USERNAME_KEY); - String password = (String) task.get(ConfigHelper.PASSWORD_KEY); - if(wellFormedPassword(password)) { - String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); - - SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); - LeapSRPSession client = new LeapSRPSession(username, password, params); - byte[] A = client.exponential(); - try { - JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); - if(saltAndB.length() > 0) { - String salt = saltAndB.getString(ConfigHelper.SALT_KEY); - byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); - byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); - JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); - if(session_idAndM2.has("M2") && client.verify((byte[])session_idAndM2.get("M2"))) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); - session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); - session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); - } else { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); - } - } else { - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } - } catch (ClientProtocolException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_client_http_user_message)); - } catch (IOException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_io_exception_user_message)); - } catch (JSONException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_json_exception_user_message)); - } catch (NoSuchAlgorithmException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_no_such_algorithm_exception_user_message)); - } - } else { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_not_valid_password_user_message)); - } - - return session_id_bundle; - } - - /** - * Validates a password - * @param entered_password - * @return true if the entered password length is greater or equal to eight (8). - */ - private boolean wellFormedPassword(String entered_password) { - return entered_password.length() >= 8; - } - - /** - * Sends an HTTP POST request to the authentication server with the SRP Parameter A. - * @param server_url - * @param username - * @param clientA First SRP parameter sent - * @return response from authentication server - * @throws ClientProtocolException - * @throws IOException - * @throws JSONException - */ - private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException { - HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + "login=" + username + "&&" + "A=" + clientA); - return sendToServer(post); - } - - /** - * Sends an HTTP PUT request to the authentication server with the SRP Parameter M1 (or simply M). - * @param server_url - * @param username - * @param m1 Second SRP parameter sent - * @return response from authentication server - * @throws ClientProtocolException - * @throws IOException - * @throws JSONException - */ - private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { - HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, ConfigHelper.trim(m1)).toString(16)); - JSONObject json_response = sendToServer(put); - - JSONObject session_idAndM2 = new JSONObject(); - if(json_response.length() > 0) { - byte[] M2_not_trimmed = new BigInteger(json_response.getString(ConfigHelper.M2_KEY), 16).toByteArray(); - Cookie session_id_cookie = LeapHttpClient.getInstance(getApplicationContext()).getCookieStore().getCookies().get(0); - session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName()); - session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue()); - session_idAndM2.put(ConfigHelper.M2_KEY, ConfigHelper.trim(M2_not_trimmed)); - } - return session_idAndM2; - } - - /** - * Executes an HTTP request expecting a JSON response. - * @param request - * @return response from authentication server - * @throws ClientProtocolException - * @throws IOException - * @throws JSONException - */ - private JSONObject sendToServer(HttpUriRequest request) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); - HttpContext localContext = new BasicHttpContext(); - localContext.setAttribute(ClientContext.COOKIE_STORE, client.getCookieStore()); - - HttpResponse getResponse = client.execute(request, localContext); - HttpEntity responseEntity = getResponse.getEntity(); - String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull(ConfigHelper.ERRORS_KEY) || json_response.has(ConfigHelper.ERRORS_KEY)) { - return new JSONObject(); - } - - return json_response; - } - - /** - * 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 ConfigHelper.RESULT_KEY, and which is true if the update was successful. - */ - private Bundle updateProviderDotJSON(Bundle task) { - Bundle result = new Bundle(); - boolean custom = task.getBoolean(ConfigHelper.CUSTOM); - boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); - String provider_json_url = task.getString(ConfigHelper.PROVIDER_JSON_URL); - String provider_name = task.getString(ConfigHelper.PROVIDER_NAME); - - try { - JSONObject provider_json = getJSONFromProvider(provider_json_url, danger_on); - if(provider_json == null) { - result.putBoolean(ConfigHelper.RESULT_KEY, false); - } else { - ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); - - //ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); - result.putBoolean(ConfigHelper.RESULT_KEY, true); - result.putString(ConfigHelper.PROVIDER_KEY, provider_json.toString()); - result.putBoolean(ConfigHelper.DANGER_ON, danger_on); - } - } catch (JSONException e) { - result.putBoolean(ConfigHelper.RESULT_KEY, false); - } - - return result; - } - - /** - * Downloads a custom provider provider.json file - * @param task containing a boolean meaning if the user completely trusts this provider, and the provider main url entered in the new custom provider dialog. - * @return true if provider.json file was successfully parsed as a JSON object. - */ - private Bundle downloadNewProviderDotJSON(Bundle task) { - Bundle result = new Bundle(); - boolean custom = true; - boolean danger_on = task.getBoolean(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 = guessProviderDotJsonURL(provider_main_url); - - JSONObject provider_json; - try { - provider_json = getJSONFromProvider(provider_json_url, danger_on); - if(provider_json == null) { - result.putBoolean(ConfigHelper.RESULT_KEY, false); - } else { - - ConfigHelper.saveSharedPref(ConfigHelper.PROVIDER_KEY, provider_json); - ConfigHelper.saveSharedPref(ConfigHelper.DANGER_ON, danger_on); - ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); - ProviderItem added_provider = new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on); - ProviderListContent.addItem(added_provider); - - result.putString(ConfigHelper.PROVIDER_ID, added_provider.getId()); - result.putBoolean(ConfigHelper.RESULT_KEY, true); - result.putString(ConfigHelper.PROVIDER_KEY, provider_json.toString()); - result.putBoolean(ConfigHelper.DANGER_ON, danger_on); - } - } catch (JSONException e) { - result.putBoolean(ConfigHelper.RESULT_KEY, false); - } - - return result; - } - - /** - * Tries to download whatever is pointed by the string_url. - * - * If danger_on 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 - * @return - */ - private String getStringFromProvider(String string_url, boolean danger_on) { - - String json_file_content = ""; - - URL provider_url = null; - int seconds_of_timeout = 1; - try { - provider_url = new URL(string_url); - URLConnection url_connection = provider_url.openConnection(); - url_connection.setConnectTimeout(seconds_of_timeout*1000); - json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next(); - } catch (MalformedURLException e) { - displayToast(R.string.malformed_url); - } catch(SocketTimeoutException e) { - displayToast(R.string.server_is_down_message); - } catch (IOException e) { - if(provider_url != null) { - json_file_content = getStringFromProviderWithCACertAdded(provider_url, danger_on); - } else { - displayToast(R.string.certificate_error); - } - } catch (Exception e) { - if(provider_url != null && danger_on) { - json_file_content = getStringFromProviderWithCACertAdded(provider_url, danger_on); - } - } - - return json_file_content; - } - - /** - * Tries to download a string from given url without verifying the hostname. - * - * If a IOException still occurs, it tries with another bypass method: getStringFromProviderWithCACertAdded. - * @param string_url - * @return an empty string if everything fails, the url content if not. - */ - private String getStringFromProviderWithoutValidate( - URL string_url) { - - String json_string = ""; - HostnameVerifier hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - - try { - HttpsURLConnection urlConnection = - (HttpsURLConnection)string_url.openConnection(); - urlConnection.setHostnameVerifier(hostnameVerifier); - json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); - } catch (MalformedURLException e) { - displayToast(R.string.malformed_url); - } catch (IOException e) { - json_string = getStringFromProviderIgnoringCertificate(string_url); - } - - return json_string; - } - - /** - * Tries to download the contents of the provided url using main certificate from choosen provider. - * @param url - * @param danger_on true to download CA certificate in case it has not been downloaded. - * @return an empty string if it fails, the url content if not. - */ - private String getStringFromProviderWithCACertAdded(URL url, boolean danger_on) { - String json_file_content = ""; - - // Load CAs from an InputStream - // (could be from a resource or ByteArrayInputStream or ...) - String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); - if(cert_string.isEmpty() && danger_on) { - cert_string = downloadCertificateWithoutTrusting(url.getProtocol() + "://" + url.getHost() + "/" + "ca.crt"); - ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); - } - - try { - java.security.cert.Certificate dangerous_certificate = ConfigHelper.parseX509CertificateFromString(cert_string); - - // Create a KeyStore containing our trusted CAs - String keyStoreType = KeyStore.getDefaultType(); - KeyStore keyStore = KeyStore.getInstance(keyStoreType); - keyStore.load(null, null); - keyStore.setCertificateEntry("provider_ca_certificate", dangerous_certificate); - - // 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 (UnknownHostException e) { - displayToast(R.string.server_is_down_message); - } catch (IOException e) { - // The downloaded certificate doesn't validate our https connection. - if(danger_on) { - json_file_content = getStringFromProviderWithoutValidate(url); - } else { - displayToast(R.string.certificate_error); - } - } 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; - } - - /** - * Downloads the string that's in the url without regarding certificate validity - */ - private String getStringFromProviderIgnoringCertificate(URL url) { - String string = ""; - try { - class DefaultTrustManager implements X509TrustManager { - - @Override - public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} - - @Override - public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} - - @Override - public X509Certificate[] getAcceptedIssuers() { - return null; - } - } - - SSLContext context = SSLContext.getInstance("TLS"); - context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); - - HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); - urlConnection.setSSLSocketFactory(context.getSocketFactory()); - urlConnection.setHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String arg0, SSLSession arg1) { - return true; - } - }); - string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); - System.out.println("String ignoring certificate = " + string); - } catch (IOException e) { - // The downloaded certificate doesn't validate our https connection. - e.printStackTrace(); - displayToast(R.string.certificate_error); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (KeyManagementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return string; - } - - /** - * Downloads the certificate from the parameter url bypassing self signed certificate SSL errors. - * @param certificate_url_string - * @return the certificate, as a string - */ - private String downloadCertificateWithoutTrusting(String certificate_url_string) { - - String cert_string = ""; - HostnameVerifier hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - - TrustManager[] trustAllCerts = new TrustManager[]{ - new X509TrustManager() { - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; - } - public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { - } - public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { - } - } - }; - - try { - URL certificate_url = new URL(certificate_url_string); - HttpsURLConnection urlConnection = - (HttpsURLConnection)certificate_url.openConnection(); - urlConnection.setHostnameVerifier(hostnameVerifier); - - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - - urlConnection.setSSLSocketFactory(sc.getSocketFactory()); - - cert_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); - - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // This should never happen - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (KeyManagementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return cert_string; - } - - /** - * Downloads a JSON object from the given url. - * - * It first downloads the JSON object as a String, and then parses it to JSON object. - * @param json_url - * @param danger_on if the user completely trusts the certificate of the url address. - * @return - * @throws JSONException - */ - 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); - } - - /** - * Tries to guess the provider.json url given the main provider url. - * @param provider_main_url - * @return the guessed provider.json url - */ - private String guessProviderDotJsonURL(String provider_main_url) { - return provider_main_url + "/provider.json"; - } - - /** - * Logs out from the api url retrieved from the task. - * @param task containing api url from which the user will log out - * @return true if there were no exceptions - */ - private boolean logOut(Bundle task) { - DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); - int session_id_index = 0; - //String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/sessions/" + client.getCookieStore().getCookies().get(0).getValue(); - try { - String delete_url = task.getString(ConfigHelper.API_URL_KEY) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); - HttpDelete delete = new HttpDelete(delete_url); - HttpResponse getResponse = client.execute(delete); - HttpEntity responseEntity = getResponse.getEntity(); - responseEntity.consumeContent(); - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (IndexOutOfBoundsException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } - return true; - } - - /** - * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. - * - * @param task containing the type of the certificate to be downloaded - * @return true if certificate was downloaded correctly, false if provider.json or danger_on flag are not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error. - */ - private boolean getNewCert(Bundle task) { - String type_of_certificate = task.getString(ConfigHelper.TYPE_OF_CERTIFICATE); - try { - JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY); - URL provider_main_url = new URL(provider_json.getString(ConfigHelper.API_URL_KEY)); - String new_cert_string_url = provider_main_url.toString() + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.CERT_KEY; - - if(type_of_certificate.equalsIgnoreCase(ConfigHelper.AUTHED_CERTIFICATE)) { - HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.SESSION_ID_COOKIE_KEY), task.getString(ConfigHelper.SESSION_ID_KEY)); - - CookieManager cookieManager = new CookieManager(); - cookieManager.getCookieStore().add(provider_main_url.toURI(), session_id_cookie); - CookieHandler.setDefault(cookieManager); - } - - boolean danger_on = ConfigHelper.getBoolFromSharedPref(ConfigHelper.DANGER_ON); - String cert_string = getStringFromProvider(new_cert_string_url, danger_on); - if(!cert_string.isEmpty()) { - // API returns concatenated cert & key. Split them for OpenVPN options - String certificate = null, key = null; - String[] certAndKey = cert_string.split("(?<=-\n)"); - for (int i=0; i < certAndKey.length-1; i++){ - if ( certAndKey[i].contains("KEY") ) - key = certAndKey[i++] + certAndKey[i]; - else if ( certAndKey[i].contains("CERTIFICATE") ) - certificate = certAndKey[i++] + certAndKey[i]; - } - ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, certificate); - ConfigHelper.saveSharedPref(ConfigHelper.KEY_KEY, key); - return true; - } else { - return false; - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } - } -} diff --git a/src/se/leap/openvpn/ConfigConverter.java b/src/se/leap/openvpn/ConfigConverter.java index 8b5f316d..3c6bf91e 100644 --- a/src/se/leap/openvpn/ConfigConverter.java +++ b/src/se/leap/openvpn/ConfigConverter.java @@ -9,7 +9,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; import java.util.Vector; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.app.Activity; import android.app.AlertDialog; diff --git a/src/se/leap/openvpn/FaqFragment.java b/src/se/leap/openvpn/FaqFragment.java index 2b9f02eb..dc498087 100644 --- a/src/se/leap/openvpn/FaqFragment.java +++ b/src/se/leap/openvpn/FaqFragment.java @@ -8,7 +8,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class FaqFragment extends Fragment { diff --git a/src/se/leap/openvpn/FileSelect.java b/src/se/leap/openvpn/FileSelect.java index 4abf6c31..4b88e7a7 100644 --- a/src/se/leap/openvpn/FileSelect.java +++ b/src/se/leap/openvpn/FileSelect.java @@ -6,7 +6,8 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.app.ActionBar; import android.app.ActionBar.Tab; diff --git a/src/se/leap/openvpn/FileSelectLayout.java b/src/se/leap/openvpn/FileSelectLayout.java index 2ca4490d..ec5f3636 100644 --- a/src/se/leap/openvpn/FileSelectLayout.java +++ b/src/se/leap/openvpn/FileSelectLayout.java @@ -10,7 +10,7 @@ import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class FileSelectLayout extends LinearLayout implements OnClickListener { diff --git a/src/se/leap/openvpn/FileSelectionFragment.java b/src/se/leap/openvpn/FileSelectionFragment.java index 5bc981fe..80cb2c62 100644 --- a/src/se/leap/openvpn/FileSelectionFragment.java +++ b/src/se/leap/openvpn/FileSelectionFragment.java @@ -5,7 +5,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.TreeMap; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.app.AlertDialog; import android.app.ListFragment; diff --git a/src/se/leap/openvpn/GeneralSettings.java b/src/se/leap/openvpn/GeneralSettings.java index 34657914..93e4818e 100644 --- a/src/se/leap/openvpn/GeneralSettings.java +++ b/src/se/leap/openvpn/GeneralSettings.java @@ -1,6 +1,7 @@ package se.leap.openvpn; import java.io.File; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.os.Bundle; import android.preference.Preference; diff --git a/src/se/leap/openvpn/InlineFileTab.java b/src/se/leap/openvpn/InlineFileTab.java index 40995ceb..9e8041c0 100644 --- a/src/se/leap/openvpn/InlineFileTab.java +++ b/src/se/leap/openvpn/InlineFileTab.java @@ -9,7 +9,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class InlineFileTab extends Fragment { diff --git a/src/se/leap/openvpn/LaunchVPN.java b/src/se/leap/openvpn/LaunchVPN.java index 1df6be96..89f2d372 100644 --- a/src/se/leap/openvpn/LaunchVPN.java +++ b/src/se/leap/openvpn/LaunchVPN.java @@ -20,9 +20,9 @@ import java.io.IOException; import java.util.Collection; import java.util.Vector; -import se.leap.leapclient.ConfigHelper; -import se.leap.leapclient.EIP; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.ConfigHelper; +import se.leap.bitmaskclient.EIP; +import se.leap.bitmaskclient.R; import android.app.Activity; import android.app.AlertDialog; @@ -106,7 +106,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { final String action = intent.getAction(); // If something wants feedback, they sent us a Receiver - mReceiver = intent.getParcelableExtra(ConfigHelper.RECEIVER_TAG); + mReceiver = intent.getParcelableExtra(EIP.RECEIVER_TAG); // If the intent is a request to create a shortcut, we'll do that and exit @@ -285,7 +285,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { // User does not want us to start, so we just vanish (well, now we tell our receiver, then vanish) Bundle resultData = new Bundle(); // For now, nothing else is calling, so this "request" string is good enough - resultData.putString(ConfigHelper.REQUEST_TAG, EIP.ACTION_START_EIP); + resultData.putString(EIP.REQUEST_TAG, EIP.ACTION_START_EIP); mReceiver.send(RESULT_CANCELED, resultData); finish(); } @@ -373,7 +373,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { // Tell whom-it-may-concern that we started VPN Bundle resultData = new Bundle(); // For now, nothing else is calling, so this "request" string is good enough - resultData.putString(ConfigHelper.REQUEST_TAG, EIP.ACTION_START_EIP); + resultData.putString(EIP.REQUEST_TAG, EIP.ACTION_START_EIP); mReceiver.send(RESULT_OK, resultData); finish(); diff --git a/src/se/leap/openvpn/LogWindow.java b/src/se/leap/openvpn/LogWindow.java index abd1acd6..c3ce8424 100644 --- a/src/se/leap/openvpn/LogWindow.java +++ b/src/se/leap/openvpn/LogWindow.java @@ -1,7 +1,8 @@ package se.leap.openvpn; import java.util.Vector; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.app.AlertDialog; import android.app.AlertDialog.Builder; diff --git a/src/se/leap/openvpn/MainActivity.java b/src/se/leap/openvpn/MainActivity.java index d33fd832..0a769b4d 100644 --- a/src/se/leap/openvpn/MainActivity.java +++ b/src/se/leap/openvpn/MainActivity.java @@ -1,7 +1,8 @@ package se.leap.openvpn; import java.util.List; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.content.Intent; import android.preference.PreferenceActivity; diff --git a/src/se/leap/openvpn/NetworkSateReceiver.java b/src/se/leap/openvpn/NetworkSateReceiver.java index 301803b6..777402b4 100644 --- a/src/se/leap/openvpn/NetworkSateReceiver.java +++ b/src/se/leap/openvpn/NetworkSateReceiver.java @@ -8,7 +8,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.preference.PreferenceManager;
-import se.leap.leapclient.R;
+import se.leap.bitmaskclient.R;
public class NetworkSateReceiver extends BroadcastReceiver {
private int lastNetwork=-1;
diff --git a/src/se/leap/openvpn/OpenVPN.java b/src/se/leap/openvpn/OpenVPN.java index 3ffc47cb..c6055abd 100644 --- a/src/se/leap/openvpn/OpenVPN.java +++ b/src/se/leap/openvpn/OpenVPN.java @@ -3,7 +3,8 @@ package se.leap.openvpn; import java.util.LinkedList; import java.util.Locale; import java.util.Vector; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.content.Context; diff --git a/src/se/leap/openvpn/OpenVPNThread.java b/src/se/leap/openvpn/OpenVPNThread.java index 3f9a0d91..0c383ab0 100644 --- a/src/se/leap/openvpn/OpenVPNThread.java +++ b/src/se/leap/openvpn/OpenVPNThread.java @@ -7,7 +7,8 @@ import java.io.IOException; import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
-import se.leap.leapclient.R;
+
+import se.leap.bitmaskclient.R;
import android.util.Log;
import se.leap.openvpn.OpenVPN.LogItem;
diff --git a/src/se/leap/openvpn/OpenVpnManagementThread.java b/src/se/leap/openvpn/OpenVpnManagementThread.java index 43d4f701..028c6ec7 100644 --- a/src/se/leap/openvpn/OpenVpnManagementThread.java +++ b/src/se/leap/openvpn/OpenVpnManagementThread.java @@ -17,7 +17,8 @@ import javax.crypto.BadPaddingException; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
-import se.leap.leapclient.R;
+
+import se.leap.bitmaskclient.R;
import android.content.SharedPreferences;
import android.net.LocalServerSocket;
diff --git a/src/se/leap/openvpn/OpenVpnPreferencesFragment.java b/src/se/leap/openvpn/OpenVpnPreferencesFragment.java index 31746332..190a48fe 100644 --- a/src/se/leap/openvpn/OpenVpnPreferencesFragment.java +++ b/src/se/leap/openvpn/OpenVpnPreferencesFragment.java @@ -2,7 +2,7 @@ package se.leap.openvpn; import android.os.Bundle;
import android.preference.PreferenceFragment;
-import se.leap.leapclient.R;
+import se.leap.bitmaskclient.R;
public abstract class OpenVpnPreferencesFragment extends PreferenceFragment {
diff --git a/src/se/leap/openvpn/OpenVpnService.java b/src/se/leap/openvpn/OpenVpnService.java index 3ac80497..bec7dcee 100644 --- a/src/se/leap/openvpn/OpenVpnService.java +++ b/src/se/leap/openvpn/OpenVpnService.java @@ -5,8 +5,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Vector; -import se.leap.leapclient.Dashboard; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.Dashboard; +import se.leap.bitmaskclient.R; import android.annotation.TargetApi; import android.app.Notification; @@ -161,7 +161,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac PendingIntent getLogPendingIntent() { // Let the configure Button show the Dashboard Intent intent = new Intent(Dashboard.getAppContext(),Dashboard.class); - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent startLW = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); return startLW; diff --git a/src/se/leap/openvpn/ProxyDetection.java b/src/se/leap/openvpn/ProxyDetection.java index 7114857d..c7b3d196 100644 --- a/src/se/leap/openvpn/ProxyDetection.java +++ b/src/se/leap/openvpn/ProxyDetection.java @@ -8,7 +8,8 @@ import java.net.SocketAddress; import java.net.URISyntaxException; import java.net.URL; import java.util.List; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; public class ProxyDetection { static SocketAddress detectProxy(VpnProfile vp) { diff --git a/src/se/leap/openvpn/Settings_Authentication.java b/src/se/leap/openvpn/Settings_Authentication.java index 00f4c08a..7824d790 100644 --- a/src/se/leap/openvpn/Settings_Authentication.java +++ b/src/se/leap/openvpn/Settings_Authentication.java @@ -11,7 +11,7 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.SwitchPreference; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class Settings_Authentication extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener, OnPreferenceClickListener { diff --git a/src/se/leap/openvpn/Settings_Basic.java b/src/se/leap/openvpn/Settings_Basic.java index f3510da9..014c71a1 100644 --- a/src/se/leap/openvpn/Settings_Basic.java +++ b/src/se/leap/openvpn/Settings_Basic.java @@ -39,8 +39,8 @@ import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.ToggleButton; -import se.leap.leapclient.R.id; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.R.id; public class Settings_Basic extends Fragment implements View.OnClickListener, OnItemSelectedListener, Callback { private static final int CHOOSE_FILE_OFFSET = 1000; diff --git a/src/se/leap/openvpn/Settings_IP.java b/src/se/leap/openvpn/Settings_IP.java index df2efb40..bb605937 100644 --- a/src/se/leap/openvpn/Settings_IP.java +++ b/src/se/leap/openvpn/Settings_IP.java @@ -6,7 +6,7 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceManager; import android.preference.SwitchPreference; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class Settings_IP extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { private EditTextPreference mIPv4; diff --git a/src/se/leap/openvpn/Settings_Obscure.java b/src/se/leap/openvpn/Settings_Obscure.java index ffbce971..6ba98606 100644 --- a/src/se/leap/openvpn/Settings_Obscure.java +++ b/src/se/leap/openvpn/Settings_Obscure.java @@ -6,7 +6,7 @@ import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { private CheckBoxPreference mUseRandomHostName; diff --git a/src/se/leap/openvpn/Settings_Routing.java b/src/se/leap/openvpn/Settings_Routing.java index 48c09ff0..3cbdac0f 100644 --- a/src/se/leap/openvpn/Settings_Routing.java +++ b/src/se/leap/openvpn/Settings_Routing.java @@ -4,7 +4,7 @@ import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class Settings_Routing extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { diff --git a/src/se/leap/openvpn/ShowConfigFragment.java b/src/se/leap/openvpn/ShowConfigFragment.java index 9bce67a6..194f87d4 100644 --- a/src/se/leap/openvpn/ShowConfigFragment.java +++ b/src/se/leap/openvpn/ShowConfigFragment.java @@ -10,7 +10,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.R; public class ShowConfigFragment extends Fragment { diff --git a/src/se/leap/openvpn/VPNLaunchHelper.java b/src/se/leap/openvpn/VPNLaunchHelper.java index 59303748..418cf7e9 100644 --- a/src/se/leap/openvpn/VPNLaunchHelper.java +++ b/src/se/leap/openvpn/VPNLaunchHelper.java @@ -4,7 +4,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.content.Context; import android.content.Intent; diff --git a/src/se/leap/openvpn/VPNPreferences.java b/src/se/leap/openvpn/VPNPreferences.java index 81d854ce..e3052050 100644 --- a/src/se/leap/openvpn/VPNPreferences.java +++ b/src/se/leap/openvpn/VPNPreferences.java @@ -1,7 +1,8 @@ package se.leap.openvpn; import java.util.List; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.app.AlertDialog; import android.content.DialogInterface; diff --git a/src/se/leap/openvpn/VPNProfileList.java b/src/se/leap/openvpn/VPNProfileList.java index a7132c9e..0ef611df 100644 --- a/src/se/leap/openvpn/VPNProfileList.java +++ b/src/se/leap/openvpn/VPNProfileList.java @@ -3,7 +3,8 @@ package se.leap.openvpn; import java.util.Collection; import java.util.Comparator; import java.util.TreeSet; -import se.leap.leapclient.R; + +import se.leap.bitmaskclient.R; import android.app.Activity; import android.app.AlertDialog; diff --git a/src/se/leap/openvpn/VpnProfile.java b/src/se/leap/openvpn/VpnProfile.java index 2262f565..8eebb763 100644 --- a/src/se/leap/openvpn/VpnProfile.java +++ b/src/se/leap/openvpn/VpnProfile.java @@ -21,8 +21,10 @@ import java.util.Vector; import org.spongycastle.util.io.pem.PemObject; import org.spongycastle.util.io.pem.PemWriter; -import se.leap.leapclient.ConfigHelper; -import se.leap.leapclient.R; +import se.leap.bitmaskclient.ConfigHelper; +import se.leap.bitmaskclient.EIP; +import se.leap.bitmaskclient.Provider; +import se.leap.bitmaskclient.R; import android.content.Context; import android.content.Intent; @@ -48,7 +50,7 @@ public class VpnProfile implements Serializable{ public static final int TYPE_USERPASS_KEYSTORE = 7; // Don't change this, not all parts of the program use this constant - public static final String EXTRA_PROFILEUUID = "se.leap.leapclient.profileUUID"; // TODO this feels wrong. See Issue #1494 + public static final String EXTRA_PROFILEUUID = "se.leap.bitmaskclient.profileUUID"; // TODO this feels wrong. See Issue #1494 public static final String INLINE_TAG = "[[INLINE]]"; private static final String OVPNCONFIGFILE = "android.conf"; @@ -246,9 +248,9 @@ public class VpnProfile implements Serializable{ cfg+=insertFileData("cert",mClientCertFilename); */ // FIXME This is all we need...The whole switch statement can go... - cfg+="<ca>\n"+ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY)+"\n</ca>\n"; - cfg+="<key>\n"+ConfigHelper.getStringFromSharedPref(ConfigHelper.KEY_KEY)+"\n</key>\n"; - cfg+="<cert>\n"+ConfigHelper.getStringFromSharedPref(ConfigHelper.CERT_KEY)+"\n</cert>\n"; + cfg+="<ca>\n"+ConfigHelper.getStringFromSharedPref(Provider.CA_CERT)+"\n</ca>\n"; + cfg+="<key>\n"+ConfigHelper.getStringFromSharedPref(EIP.PRIVATE_KEY)+"\n</key>\n"; + cfg+="<cert>\n"+ConfigHelper.getStringFromSharedPref(EIP.CERTIFICATE)+"\n</cert>\n"; break; case VpnProfile.TYPE_USERPASS_PKCS12: |