From 11528c3f7124090ef44675cf613a949ed07ad9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 14 Oct 2014 18:39:03 +0200 Subject: Start EIP after downloading an authed certificate. Always. Previously we didn't do so if EIP hadn't been started before. Fix a small bug introduced during latest refactoring, authentication did not work because the final result variable wasn't assigned. --- app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java | 2 +- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 6 ++---- app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'app/src') diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index b83f33a1..f51099a3 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -260,7 +260,7 @@ public class ProviderAPI extends IntentService { if(validUserLoginData(username, password)) { String server = (String) task.get(Provider.API_URL); - authenticate(username, password, server); + result = authenticate(username, password, server); broadcast_progress(progress++); } else { if(!wellFormedPassword(password)) { diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 761afc0a..16e4cf03 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -65,6 +65,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf public static final String START_ON_BOOT = "dashboard start on boot"; final public static String ON_BOOT = "dashboard on boot"; public static final String APP_VERSION = "bitmask version"; + final public static String TAG = Dashboard.class.getSimpleName(); private EipServiceFragment eipFragment; @@ -498,10 +499,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf changeStatusMessage(resultCode); if(mProgressBar != null) mProgressBar.setVisibility(ProgressBar.GONE); - if(EipServiceFragment.isEipSwitchChecked()) - eipStart(); - else - eipStatus.setText(R.string.eip_state_not_connected); + eipStart(); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { setResult(RESULT_CANCELED); changeStatusMessage(resultCode); diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index 3c8ec607..549eee0d 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -255,7 +255,7 @@ public class ProviderAPI extends IntentService { String server = (String) task.get(Provider.API_URL); - authenticate(username, password, server); + result = authenticate(username, password, server); broadcast_progress(progress++); } else { if(!wellFormedPassword(password)) { -- cgit v1.2.3 From 6bc3d7da8fdf32cdbd934831f2385f5098c7f979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 14 Oct 2014 22:14:08 +0200 Subject: Big refactor, ProviderAPI looks better. --- .../se/leap/bitmaskclient/ConfigurationWizard.java | 2 +- .../java/se/leap/bitmaskclient/ProviderAPI.java | 135 ++++---- .../main/java/se/leap/bitmaskclient/Dashboard.java | 366 +++++++++------------ app/src/main/java/se/leap/bitmaskclient/EIP.java | 1 + .../se/leap/bitmaskclient/EipServiceFragment.java | 2 +- .../java/se/leap/bitmaskclient/LogInDialog.java | 15 +- .../bitmaskclient/ProviderAPIResultReceiver.java | 2 +- .../leap/bitmaskclient/SessionDialogInterface.java | 39 +++ .../java/se/leap/bitmaskclient/SignUpDialog.java | 11 +- app/src/main/res/values/strings.xml | 1 + .../se/leap/bitmaskclient/ConfigurationWizard.java | 2 +- .../java/se/leap/bitmaskclient/ProviderAPI.java | 65 ++-- 12 files changed, 316 insertions(+), 325 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java (limited to 'app/src') diff --git a/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java index c405d06f..7fc5150b 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -571,7 +571,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD @Override public void login() { Intent ask_login = new Intent(); - ask_login.putExtra(LogInDialog.VERB, LogInDialog.VERB); + ask_login.putExtra(LogInDialog.TAG, LogInDialog.TAG); setResult(RESULT_OK, ask_login); setting_up_provider = false; finish(); diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index f51099a3..93014dc9 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -93,8 +93,6 @@ public class ProviderAPI extends IntentService { PARAMETERS = "parameters", RESULT_KEY = "result", RECEIVER_KEY = "receiver", - SESSION_ID_COOKIE_KEY = "session_id_cookie_key", - SESSION_ID_KEY = "session_id", ERRORS = "errors", UPDATE_PROGRESSBAR = "update_progressbar", CURRENT_PROGRESS = "current_progress", @@ -127,6 +125,7 @@ public class ProviderAPI extends IntentService { private static boolean last_danger_on = false; private static boolean setting_up_provider = true; private static SharedPreferences preferences; + private static String provider_api_url; public static void stop() { setting_up_provider = false; @@ -174,7 +173,7 @@ public class ProviderAPI extends IntentService { } } } else if (action.equalsIgnoreCase(SRP_REGISTER)) { - Bundle session_id_bundle = tryToRegisterWithSRP(parameters); + Bundle session_id_bundle = tryToRegister(parameters); if(session_id_bundle.getBoolean(RESULT_KEY)) { receiver.send(SRP_REGISTRATION_SUCCESSFUL, session_id_bundle); } else { @@ -188,7 +187,7 @@ public class ProviderAPI extends IntentService { receiver.send(SRP_AUTHENTICATION_FAILED, session_id_bundle); } } else if (action.equalsIgnoreCase(LOG_OUT)) { - if(logOut(parameters)) { + if(logOut()) { receiver.send(LOGOUT_SUCCESSFUL, Bundle.EMPTY); } else { receiver.send(LOGOUT_FAILED, Bundle.EMPTY); @@ -202,44 +201,45 @@ public class ProviderAPI extends IntentService { } } - private Bundle tryToRegisterWithSRP(Bundle task) { + private Bundle tryToRegister(Bundle task) { Bundle session_id_bundle = new Bundle(); int progress = 0; - String username = (String) task.get(LogInDialog.USERNAME); - String password = (String) task.get(LogInDialog.PASSWORD); - String authentication_server = (String) task.get(Provider.API_URL); + String username = (String) task.get(SessionDialogInterface.USERNAME); + String password = (String) task.get(SessionDialogInterface.PASSWORD); + if(validUserLoginData(username, password)) { - session_id_bundle = registerWithSRP(username, password, authentication_server); + session_id_bundle = register(username, password); broadcast_progress(progress++); } 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); + session_id_bundle.putString(SessionDialogInterface.USERNAME, username); + session_id_bundle.putBoolean(SessionDialogInterface.PASSWORD_INVALID_LENGTH, true); } if(username.isEmpty()) { session_id_bundle.putBoolean(RESULT_KEY, false); - session_id_bundle.putBoolean(LogInDialog.USERNAME_MISSING, true); + session_id_bundle.putBoolean(SessionDialogInterface.USERNAME_MISSING, true); } } return session_id_bundle; } - private Bundle registerWithSRP(String username, String password, String server) { + private Bundle register(String username, String password) { LeapSRPSession client = new LeapSRPSession(username, password); byte[] salt = client.calculateNewSalt(); BigInteger password_verifier = client.calculateV(username, password, salt); - JSONObject api_result = sendNewUserDataToSRPServer(server, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16)); + + JSONObject api_result = sendNewUserDataToSRPServer(provider_api_url, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16)); Bundle result = new Bundle(); if(api_result.has(ERRORS)) result = authFailedNotification(api_result, username); else { - result.putString(LogInDialog.USERNAME, username); - result.putString(LogInDialog.PASSWORD, password); + result.putString(SessionDialogInterface.USERNAME, username); + result.putString(SessionDialogInterface.PASSWORD, password); result.putBoolean(RESULT_KEY, true); } @@ -251,26 +251,24 @@ public class ProviderAPI extends IntentService { * @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 tryToAuthenticateBySRP(Bundle task) { + private Bundle tryToAuthenticate(Bundle task) { Bundle result = new Bundle(); int progress = 0; - String username = (String) task.get(LogInDialog.USERNAME); - String password = (String) task.get(LogInDialog.PASSWORD); - if(validUserLoginData(username, password)) { - String server = (String) task.get(Provider.API_URL); - - result = authenticate(username, password, server); + String username = (String) task.get(SessionDialogInterface.USERNAME); + String password = (String) task.get(SessionDialogInterface.PASSWORD); + if(validUserLoginData(username, password)) { + result = authenticate(username, password); broadcast_progress(progress++); } else { if(!wellFormedPassword(password)) { result.putBoolean(RESULT_KEY, false); - result.putString(LogInDialog.USERNAME, username); - result.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true); + result.putString(SessionDialogInterface.USERNAME, username); + result.putBoolean(SessionDialogInterface.PASSWORD_INVALID_LENGTH, true); } if(username.isEmpty()) { result.putBoolean(RESULT_KEY, false); - result.putBoolean(LogInDialog.USERNAME_MISSING, true); + result.putBoolean(SessionDialogInterface.USERNAME_MISSING, true); } } @@ -278,19 +276,19 @@ public class ProviderAPI extends IntentService { } - private Bundle authenticate(String username, String password, String server) { + private Bundle authenticate(String username, String password) { Bundle result = new Bundle(); LeapSRPSession client = new LeapSRPSession(username, password); byte[] A = client.exponential(); - JSONObject step_result = sendAToSRPServer(server, username, new BigInteger(1, A).toString(16)); + JSONObject step_result = sendAToSRPServer(provider_api_url, username, new BigInteger(1, A).toString(16)); try { String salt = step_result.getString(LeapSRPSession.SALT); byte[] Bbytes = new BigInteger(step_result.getString("B"), 16).toByteArray(); byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); if(M1 != null) { - step_result = sendM1ToSRPServer(server, username, M1); + step_result = sendM1ToSRPServer(provider_api_url, username, M1); setTokenIfAvailable(step_result); byte[] M2 = new BigInteger(step_result.getString(LeapSRPSession.M2), 16).toByteArray(); if(client.verify(M2)) { @@ -300,7 +298,7 @@ public class ProviderAPI extends IntentService { } } else { result.putBoolean(RESULT_KEY, false); - result.putString(LogInDialog.USERNAME, username); + result.putString(SessionDialogInterface.USERNAME, username); result.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message)); } } catch (JSONException e) { @@ -331,7 +329,7 @@ public class ProviderAPI extends IntentService { } catch(JSONException e) {} if(!username.isEmpty()) - user_notification_bundle.putString(LogInDialog.USERNAME, username); + user_notification_bundle.putString(SessionDialogInterface.USERNAME, username); user_notification_bundle.putBoolean(RESULT_KEY, false); return user_notification_bundle; @@ -619,6 +617,7 @@ public class ProviderAPI extends IntentService { try { JSONObject provider_json = new JSONObject(provider_dot_json_string); + provider_api_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION); String name = provider_json.getString(Provider.NAME); //TODO setProviderName(name); @@ -860,46 +859,46 @@ public class ProviderAPI extends IntentService { * @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"; - int progress = 0; + private boolean logOut() { + try { + String delete_url = provider_api_url + "/logout"; + int progress = 0; - HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); - urlConnection.setRequestMethod("DELETE"); - urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); + HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); + urlConnection.setRequestMethod("DELETE"); + urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); - int responseCode = urlConnection.getResponseCode(); - broadcast_progress(progress++); - LeapSRPSession.setToken(""); - Log.d(TAG, 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; + int responseCode = urlConnection.getResponseCode(); + broadcast_progress(progress++); + LeapSRPSession.setToken(""); + Log.d(TAG, 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; + } private boolean updateVpnCertificate() { getNewCert(); diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 16e4cf03..286d88c3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -75,8 +75,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected static SharedPreferences preferences; private static Provider provider; - private TextView providerNameTV; - private boolean authed_eip = false; public ProviderAPIResultReceiver providerAPI_result_receiver; @@ -143,7 +141,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startService(updateEIP); buildDashboard(false); invalidateOptionsMenu(); - if(data != null && data.hasExtra(LogInDialog.VERB)) { + if(data != null && data.hasExtra(LogInDialog.TAG)) { View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); logInDialog(Bundle.EMPTY); } @@ -190,7 +188,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf setContentView(R.layout.client_dashboard); - providerNameTV = (TextView) findViewById(R.id.providerName); + TextView providerNameTV = (TextView) findViewById(R.id.providerName); providerNameTV.setText(provider.getDomain()); providerNameTV.setTextSize(28); @@ -269,14 +267,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); return true; case R.id.login_button: - View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); logInDialog(Bundle.EMPTY); return true; case R.id.logout_button: logOut(); return true; case R.id.signup_button: - signUpDialog(((ViewGroup)findViewById(android.R.id.content)).getChildAt(0), Bundle.EMPTY); + signUpDialog(Bundle.EMPTY); return true; default: return super.onOptionsItemSelected(item); @@ -284,38 +281,59 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } - @Override - public void authenticate(String username, String password) { - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - eipStatus = (TextView) findViewById(R.id.eipStatus); + private Intent prepareProviderAPICommand() { + mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + eipStatus = (TextView) findViewById(R.id.eipStatus); - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); + providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + providerAPI_result_receiver.setReceiver(this); - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - parameters.putString(LogInDialog.USERNAME, username); - parameters.putString(LogInDialog.PASSWORD, password); + Intent command = new Intent(this, ProviderAPI.class); - JSONObject provider_json; - try { - 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(); - } + command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); + return command; + } - provider_API_command.setAction(ProviderAPI.SRP_AUTH); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - - mProgressBar.setVisibility(ProgressBar.VISIBLE); - eipStatus.setText(R.string.authenticating_message); - //mProgressBar.setMax(4); - startService(provider_API_command); + private FragmentTransaction removePreviousFragment(String tag) { + FragmentTransaction transaction = getFragmentManager().beginTransaction(); + Fragment previous_fragment = getFragmentManager().findFragmentByTag(tag); + if (previous_fragment != null) { + transaction.remove(previous_fragment); } + transaction.addToBackStack(null); + + return transaction; + } + + /** + * Shows the log in dialog. + */ + public void logInDialog(Bundle resultData) { + FragmentTransaction transaction = removePreviousFragment(LogInDialog.TAG); + + DialogFragment newFragment = LogInDialog.newInstance(); + if(resultData != null && !resultData.isEmpty()) + newFragment.setArguments(resultData); + newFragment.show(transaction, LogInDialog.TAG); + } + + @Override + public void logIn(String username, String password) { + Intent provider_API_command = prepareProviderAPICommand(); + Bundle parameters = provider_API_command.getExtras().getBundle(ProviderAPI.PARAMETERS); + if(parameters == null) + parameters = new Bundle(); + + parameters.putString(SessionDialogInterface.USERNAME, username); + parameters.putString(SessionDialogInterface.PASSWORD, password); + + mProgressBar.setVisibility(ProgressBar.VISIBLE); + eipStatus.setText(R.string.authenticating_message); + + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.setAction(ProviderAPI.SRP_AUTH); + startService(provider_API_command); + } public void cancelAuthedEipOn() { EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); @@ -323,125 +341,59 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } public void cancelLoginOrSignup() { - if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - if(mProgressBar != null) { - mProgressBar.setVisibility(ProgressBar.GONE); - if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); - if(eipStatus != null) eipStatus.setText(""); - } - cancelAuthedEipOn(); + hideProgressBar(); } - /** - * Asks ProviderAPI to log out. - */ - public void logOut() { - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - - JSONObject provider_json; - try { - 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.setAction(ProviderAPI.LOG_OUT); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - - if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - mProgressBar.setVisibility(ProgressBar.VISIBLE); - if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); - eipStatus.setText(R.string.logout_message); - // eipStatus.setText("Starting to logout"); - - startService(provider_API_command); - //mProgressBar.setMax(1); - - } - - /** - * Shows the log in dialog. - */ - public void logInDialog(Bundle resultData) { - Log.d("Dashboard", "Log In Dialog"); - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - 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(resultData != null && !resultData.isEmpty()) { - newFragment.setArguments(resultData); - } - newFragment.show(fragment_transaction, LogInDialog.TAG); - } - - @Override - public void signUp(String username, String password) { - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - eipStatus = (TextView) findViewById(R.id.eipStatus); - - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); - - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - parameters.putString(SignUpDialog.USERNAME, username); - parameters.putString(SignUpDialog.PASSWORD, password); - - JSONObject provider_json; - try { - 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.setAction(ProviderAPI.SRP_REGISTER); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); + /** + * Asks ProviderAPI to log out. + */ + public void logOut() { + Intent provider_API_command = prepareProviderAPICommand(); + + if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + mProgressBar.setVisibility(ProgressBar.VISIBLE); + if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); + eipStatus.setText(R.string.logout_message); - mProgressBar.setVisibility(ProgressBar.VISIBLE); - eipStatus.setText(R.string.signingup_message); - //mProgressBar.setMax(4); - startService(provider_API_command); - } + provider_API_command.setAction(ProviderAPI.LOG_OUT); + startService(provider_API_command); + } - /** - * Shows the sign up dialog. - * @param view from which the dialog is created. - */ - public void signUpDialog(View view, Bundle resultData) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_sign_up_dialog = getFragmentManager().findFragmentByTag(SignUpDialog.TAG); - if (previous_sign_up_dialog != null) { - fragment_transaction.remove(previous_sign_up_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = SignUpDialog.newInstance(); - if(resultData != null && !resultData.isEmpty()) { - newFragment.setArguments(resultData); - } - newFragment.show(fragment_transaction, SignUpDialog.TAG); + /** + * Shows the sign up dialog. + */ + public void signUpDialog(Bundle resultData) { + FragmentTransaction transaction = removePreviousFragment(SignUpDialog.TAG); + + DialogFragment newFragment = SignUpDialog.newInstance(); + if(resultData != null && !resultData.isEmpty()) { + newFragment.setArguments(resultData); } + newFragment.show(transaction, SignUpDialog.TAG); + } + + @Override + public void signUp(String username, String password) { + Intent provider_API_command = prepareProviderAPICommand(); + Bundle parameters = provider_API_command.getExtras().getBundle(ProviderAPI.PARAMETERS); + if(parameters == null) + parameters = new Bundle(); + + parameters.putString(SessionDialogInterface.USERNAME, username); + parameters.putString(SessionDialogInterface.PASSWORD, password); + + mProgressBar.setVisibility(ProgressBar.VISIBLE); + eipStatus.setText(R.string.signingup_message); + + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.setAction(ProviderAPI.SRP_REGISTER); + startService(provider_API_command); + } /** * 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() { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); @@ -449,8 +401,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf 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.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); @@ -461,50 +411,55 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf @Override public void onReceiveResult(int resultCode, Bundle resultData) { - if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL){ - authenticate(resultData.getString(LogInDialog.USERNAME), resultData.getString(LogInDialog.PASSWORD)); - } else if(resultCode == ProviderAPI.SRP_REGISTRATION_FAILED){ - signUpDialog(((ViewGroup)findViewById(android.R.id.content)).getChildAt(0), resultData); - } else 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_eip = true; - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - - invalidateOptionsMenu(); - mProgressBar.setVisibility(ProgressBar.GONE); - changeStatusMessage(resultCode); + if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL) { + String username = resultData.getString(SessionDialogInterface.USERNAME); + String password = resultData.getString(SessionDialogInterface.PASSWORD); + logIn(username, password); + } else if(resultCode == ProviderAPI.SRP_REGISTRATION_FAILED) { + changeStatusMessage(resultCode); + hideProgressBar(); + + signUpDialog(resultData); + } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL) { + changeStatusMessage(resultCode); + hideProgressBar(); + + invalidateOptionsMenu(); + + authed_eip = true; + preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - //Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string); - downloadAuthedUserCertificate(/*session_id*/); - } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { - logInDialog(resultData); - } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { - authed_eip = false; - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - mProgressBar.setVisibility(ProgressBar.GONE); - mProgressBar.setProgress(0); - invalidateOptionsMenu(); - setResult(RESULT_OK); - changeStatusMessage(resultCode); - - } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { - setResult(RESULT_CANCELED); - changeStatusMessage(resultCode); - mProgressBar.setVisibility(ProgressBar.GONE); - } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { - setResult(RESULT_OK); + downloadAuthedUserCertificate(); + } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { + changeStatusMessage(resultCode); + hideProgressBar(); + + logInDialog(resultData); + } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { + changeStatusMessage(resultCode); + hideProgressBar(); + + invalidateOptionsMenu(); + + authed_eip = false; + preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + + } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { + changeStatusMessage(resultCode); + hideProgressBar(); + + setResult(RESULT_CANCELED); + } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); - if(mProgressBar != null) - mProgressBar.setVisibility(ProgressBar.GONE); + hideProgressBar(); + + setResult(RESULT_OK); eipStart(); - } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { - setResult(RESULT_CANCELED); + } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); - mProgressBar.setVisibility(ProgressBar.GONE); - } + hideProgressBar(); + setResult(RESULT_CANCELED); + } } private void changeStatusMessage(final int previous_result_code) { @@ -513,6 +468,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected void onReceiveResult(int resultCode, Bundle resultData){ super.onReceiveResult(resultCode, resultData); String request = resultData.getString(EIP.REQUEST_TAG); + if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); if (request.equalsIgnoreCase(EIP.ACTION_IS_EIP_RUNNING)){ if (resultCode == Activity.RESULT_OK){ @@ -532,6 +488,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eipStatus.setText(R.string.succesful_authentication_message); break; case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; + case ProviderAPI.SRP_REGISTRATION_FAILED: eipStatus.setText(R.string.registration_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break; case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.logged_out_message); break; @@ -545,6 +502,14 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf eipIsRunning(eip_status_receiver); } + private void hideProgressBar() { + if(mProgressBar == null) + mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + + mProgressBar.setProgress(0); + mProgressBar.setVisibility(ProgressBar.GONE); + } + /** * For retrieving the base application Context in classes that don't extend * Android's Activity class @@ -556,11 +521,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } - @Override + @Override public void startActivityForResult(Intent intent, int requestCode) { intent.putExtra(Dashboard.REQUEST_CODE, requestCode); super.startActivityForResult(intent, requestCode); } + /** * Send a command to EIP * @@ -575,30 +541,22 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startService(eip_intent); } - /** - * Send a command to EIP - * - */ - private void eipStop(){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_STOP_EIP); - // eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver);fi - startService(eip_intent); - - } + private void eipStop(){ + // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? + Intent eip_intent = new Intent(this, EIP.class); + eip_intent.setAction(EIP.ACTION_STOP_EIP); + startService(eip_intent); + } - private void eipStart(){ + private void eipStart() { Intent eip_intent = new Intent(this, EIP.class); eip_intent.setAction(EIP.ACTION_START_EIP); - eip_intent.putExtra(EIP.RECEIVER_TAG, EipServiceFragment.getReceiver()); - startService(eip_intent); - + startService(eip_intent); } - protected void setProgressBarVisibility(int visibility) { + protected void showProgressBar() { if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - mProgressBar.setVisibility(visibility); + mProgressBar.setVisibility(ProgressBar.VISIBLE); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 4a8bae46..1b34ac21 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -155,6 +155,7 @@ public final class EIP extends IntentService { activeGateway = selectGateway(); if(activeGateway != null && activeGateway.mVpnProfile != null) { + mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 18ee0262..57e009dc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -380,7 +380,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe case Activity.RESULT_CANCELED: Dashboard dashboard = (Dashboard) getActivity(); - dashboard.setProgressBarVisibility(ProgressBar.VISIBLE); + dashboard.showProgressBar(); String status = getResources().getString(R.string.updating_certificate_message); setEipStatus(status); diff --git a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java index 45d3a373..5a0c9a6d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java @@ -42,15 +42,10 @@ import android.widget.TextView; * @author parmegv * */ -public class LogInDialog extends DialogFragment { +public class LogInDialog extends SessionDialogInterface { - 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"; + final public static String TAG = LogInDialog.class.getSimpleName(); private static boolean is_eip_pending = false; @@ -93,7 +88,7 @@ public class LogInDialog extends DialogFragment { String username = username_field.getText().toString(); String password = password_field.getText().toString(); dialog.dismiss(); - interface_with_Dashboard.authenticate(username, password); + interface_with_Dashboard.logIn(username, password); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @@ -120,7 +115,7 @@ public class LogInDialog extends DialogFragment { * */ public interface LogInDialogInterface { - public void authenticate(String username, String password); + public void logIn(String username, String password); public void cancelAuthedEipOn(); public void signUp(String username, String password); public void cancelLoginOrSignup(); @@ -149,8 +144,8 @@ public class LogInDialog extends DialogFragment { @Override public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); if(is_eip_pending) interface_with_Dashboard.cancelAuthedEipOn(); - super.onCancel(dialog); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java b/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java index 7b256124..7e4e95d3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java +++ b/app/src/main/java/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 . */ - package se.leap.bitmaskclient; +package se.leap.bitmaskclient; import android.os.Bundle; import android.os.Handler; diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java new file mode 100644 index 00000000..7b08a4d1 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java @@ -0,0 +1,39 @@ +/** + * 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 . + */ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.os.Bundle; + +/** + * @author parmegv + */ +public abstract class SessionDialogInterface extends DialogFragment { + 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"; + + @Override + public void onAttach(Activity activity) { super.onAttach(activity); } + + @Override + public void onCancel(DialogInterface dialog) { super.onCancel(dialog); } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java index 120d4eec..3cb41f4f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java @@ -42,14 +42,9 @@ import android.widget.TextView; * @author parmegv * */ -public class SignUpDialog extends DialogFragment { - - final public static String TAG = "signUpDialog"; - 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 class SignUpDialog extends SessionDialogInterface { + + final public static String TAG = SignUpDialog.class.getSimpleName(); private static boolean is_eip_pending = false; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8c815786..3666b39c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,6 +63,7 @@ Didn\'t logged out. Authentication succeeded. Authentication failed. + Registration failed.. Your own cert has been correctly downloaded. Your own cert has incorrectly been downloaded. Initiating connection diff --git a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java index b5a57234..f844989b 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -564,7 +564,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD @Override public void login() { Intent ask_login = new Intent(); - ask_login.putExtra(LogInDialog.VERB, LogInDialog.VERB); + ask_login.putExtra(LogInDialog.TAG, LogInDialog.TAG); setResult(RESULT_OK, ask_login); setting_up_provider = false; finish(); diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index 549eee0d..189289ec 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -92,8 +92,6 @@ public class ProviderAPI extends IntentService { PARAMETERS = "parameters", RESULT_KEY = "result", RECEIVER_KEY = "receiver", - SESSION_ID_COOKIE_KEY = "session_id_cookie_key", - SESSION_ID_KEY = "session_id", ERRORS = "errors", UPDATE_PROGRESSBAR = "update_progressbar", CURRENT_PROGRESS = "current_progress", @@ -125,6 +123,7 @@ public class ProviderAPI extends IntentService { private static String last_provider_main_url; private static boolean setting_up_provider = true; private static SharedPreferences preferences; + private static String provider_api_url; public static void stop() { setting_up_provider = false; @@ -140,6 +139,12 @@ public class ProviderAPI extends IntentService { super.onCreate(); preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER)); + if(provider_api_url == null && preferences.contains(Provider.KEY)) { + try { + JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); + provider_api_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION); + } catch (JSONException e) {} + } } public static String lastProviderMainUrl() { @@ -181,7 +186,7 @@ public class ProviderAPI extends IntentService { receiver.send(SRP_AUTHENTICATION_FAILED, result); } } else if (action.equalsIgnoreCase(LOG_OUT)) { - if(logOut(parameters)) { + if(logOut()) { receiver.send(LOGOUT_SUCCESSFUL, Bundle.EMPTY); } else { receiver.send(LOGOUT_FAILED, Bundle.EMPTY); @@ -199,40 +204,41 @@ public class ProviderAPI extends IntentService { Bundle session_id_bundle = new Bundle(); int progress = 0; - String username = (String) task.get(LogInDialog.USERNAME); - String password = (String) task.get(LogInDialog.PASSWORD); - String authentication_server = (String) task.get(Provider.API_URL); + String username = (String) task.get(SessionDialogInterface.USERNAME); + String password = (String) task.get(SessionDialogInterface.PASSWORD); + if(validUserLoginData(username, password)) { - session_id_bundle = register(username, password, authentication_server); + session_id_bundle = register(username, password); broadcast_progress(progress++); } 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); + session_id_bundle.putString(SessionDialogInterface.USERNAME, username); + session_id_bundle.putBoolean(SessionDialogInterface.PASSWORD_INVALID_LENGTH, true); } if(username.isEmpty()) { session_id_bundle.putBoolean(RESULT_KEY, false); - session_id_bundle.putBoolean(LogInDialog.USERNAME_MISSING, true); + session_id_bundle.putBoolean(SessionDialogInterface.USERNAME_MISSING, true); } } return session_id_bundle; } - private Bundle register(String username, String password, String server) { + private Bundle register(String username, String password) { LeapSRPSession client = new LeapSRPSession(username, password); byte[] salt = client.calculateNewSalt(); BigInteger password_verifier = client.calculateV(username, password, salt); - JSONObject api_result = sendNewUserDataToSRPServer(server, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16)); + + JSONObject api_result = sendNewUserDataToSRPServer(provider_api_url, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16)); Bundle result = new Bundle(); if(api_result.has(ERRORS)) result = authFailedNotification(api_result, username); else { - result.putString(LogInDialog.USERNAME, username); - result.putString(LogInDialog.PASSWORD, password); + result.putString(SessionDialogInterface.USERNAME, username); + result.putString(SessionDialogInterface.PASSWORD, password); result.putBoolean(RESULT_KEY, true); } @@ -249,42 +255,39 @@ public class ProviderAPI extends IntentService { Bundle result = new Bundle(); int progress = 0; - String username = (String) task.get(LogInDialog.USERNAME); - String password = (String) task.get(LogInDialog.PASSWORD); + String username = (String) task.get(SessionDialogInterface.USERNAME); + String password = (String) task.get(SessionDialogInterface.PASSWORD); if(validUserLoginData(username, password)) { - - String server = (String) task.get(Provider.API_URL); - - result = authenticate(username, password, server); + result = authenticate(username, password); broadcast_progress(progress++); } else { if(!wellFormedPassword(password)) { result.putBoolean(RESULT_KEY, false); - result.putString(LogInDialog.USERNAME, username); - result.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true); + result.putString(SessionDialogInterface.USERNAME, username); + result.putBoolean(SessionDialogInterface.PASSWORD_INVALID_LENGTH, true); } if(username.isEmpty()) { result.putBoolean(RESULT_KEY, false); - result.putBoolean(LogInDialog.USERNAME_MISSING, true); + result.putBoolean(SessionDialogInterface.USERNAME_MISSING, true); } } return result; } - private Bundle authenticate(String username, String password, String server) { + private Bundle authenticate(String username, String password) { Bundle result = new Bundle(); LeapSRPSession client = new LeapSRPSession(username, password); byte[] A = client.exponential(); - JSONObject step_result = sendAToSRPServer(server, username, new BigInteger(1, A).toString(16)); + JSONObject step_result = sendAToSRPServer(provider_api_url, username, new BigInteger(1, A).toString(16)); try { String salt = step_result.getString(LeapSRPSession.SALT); byte[] Bbytes = new BigInteger(step_result.getString("B"), 16).toByteArray(); byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); if(M1 != null) { - step_result = sendM1ToSRPServer(server, username, M1); + step_result = sendM1ToSRPServer(provider_api_url, username, M1); setTokenIfAvailable(step_result); byte[] M2 = new BigInteger(step_result.getString(LeapSRPSession.M2), 16).toByteArray(); if(client.verify(M2)) { @@ -294,7 +297,7 @@ public class ProviderAPI extends IntentService { } } else { result.putBoolean(RESULT_KEY, false); - result.putString(LogInDialog.USERNAME, username); + result.putString(SessionDialogInterface.USERNAME, username); result.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message)); } } catch (JSONException e) { @@ -325,7 +328,7 @@ public class ProviderAPI extends IntentService { } catch(JSONException e) {} if(!username.isEmpty()) - user_notification_bundle.putString(LogInDialog.USERNAME, username); + user_notification_bundle.putString(SessionDialogInterface.USERNAME, username); user_notification_bundle.putBoolean(RESULT_KEY, false); return user_notification_bundle; @@ -614,6 +617,7 @@ public class ProviderAPI extends IntentService { try { JSONObject provider_json = new JSONObject(provider_dot_json_string); + provider_api_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION); String name = provider_json.getString(Provider.NAME); //TODO setProviderName(name); @@ -847,12 +851,11 @@ public class ProviderAPI extends IntentService { /** * 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) { + private boolean logOut() { try { - String delete_url = task.getString(Provider.API_URL) + "/logout"; + String delete_url = provider_api_url + "/logout"; int progress = 0; HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); -- cgit v1.2.3 From 5e1d89482034c94f22547a12298bdf956761c0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 16 Oct 2014 10:22:27 +0200 Subject: Move blocking code to thread's run. --- .../java/se/leap/bitmaskclient/VoidVpnService.java | 36 +++++++++------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java index b7289c23..7b597554 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java @@ -1,10 +1,11 @@ package se.leap.bitmaskclient; import android.content.Intent; +import android.os.Process; import android.net.VpnService; import android.util.Log; -public class VoidVpnService extends VpnService { +public class VoidVpnService extends VpnService { static final String START_BLOCKING_VPN_PROFILE = "se.leap.bitmaskclient.START_BLOCKING_VPN_PROFILE"; static final String TAG = VoidVpnService.class.getSimpleName(); @@ -14,29 +15,22 @@ public class VoidVpnService extends VpnService { String action = intent.getAction(); if (action == START_BLOCKING_VPN_PROFILE) { new Thread(new Runnable() { - public void run() { - blockConnections(); + public void run() { + Builder builder = new Builder(); + builder.setSession("Blocking until running"); + builder.addAddress("10.42.0.8",16); + builder.addRoute("0.0.0.0", 1); + builder.addRoute("192.168.1.0", 24); + builder.addDnsServer("10.42.0.1"); + try { + builder.establish(); + } catch (Exception e) { + e.printStackTrace(); + } + android.util.Log.d(TAG, "VoidVpnService set up"); } }).run(); } return 0; } - - public void blockConnections() { - Builder builder = new Builder(); - builder.setSession("Blocking until running"); - builder.addAddress("10.42.0.8",16); - builder.addRoute("0.0.0.0", 1); - builder.addRoute("128.0.0.0", 1); - builder.addRoute("192.168.1.0", 24); - builder.addDnsServer("10.42.0.1"); - builder.establish(); - android.util.Log.d(TAG, "VoidVpnService set up"); - try { - new java.net.Socket("sdf.org", 80); - Log.d(TAG, "VoidVpnService doesn's stop traffic"); - } catch (Exception e) { - e.printStackTrace(); - } - } } -- cgit v1.2.3 From 575bc1293070bfa90ed3ba0f558e564b1fc2c9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 16 Oct 2014 18:41:57 +0200 Subject: A bit of refactoring for ConfigurationWizard. Fix a typo in the debug source of ProviderAPI. --- .../se/leap/bitmaskclient/ConfigurationWizard.java | 1014 ++++++++++---------- .../java/se/leap/bitmaskclient/ProviderAPI.java | 2 +- .../main/java/se/leap/bitmaskclient/Dashboard.java | 25 +- .../bitmaskclient/FragmentManagerEnhanced.java | 51 + .../se/leap/bitmaskclient/ConfigurationWizard.java | 996 ++++++++++--------- 5 files changed, 1051 insertions(+), 1037 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java (limited to 'app/src') diff --git a/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java index 7fc5150b..78fcda56 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -1,281 +1,376 @@ -/** - * 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 . - */ - package se.leap.bitmaskclient; - - - - - - -import android.app.Activity; -import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.res.AssetManager; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -import android.view.Display; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View.MeasureSpec; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.ProgressBar; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import java.io.IOException; +/** + * 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 . + */ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.app.DialogFragment; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.res.AssetManager; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import android.view.Display; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View.MeasureSpec; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import java.util.Iterator; -import org.json.JSONException; -import org.json.JSONObject; +import java.util.Iterator; +import org.json.JSONException; +import org.json.JSONObject; + import se.leap.bitmaskclient.DownloadFailedDialog.DownloadFailedDialogInterface; import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; import se.leap.bitmaskclient.ProviderDetailFragment.ProviderDetailFragmentInterface; import se.leap.bitmaskclient.ProviderListContent.ProviderItem; +import se.leap.bitmaskclient.FragmentManagerEnhanced; + import se.leap.bitmaskclient.R; - -/** - * Activity that builds and shows the list of known available providers. - * - * It also allows the user to enter custom providers with a button. - * - * @author parmegv - * - */ -public class ConfigurationWizard extends Activity -implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderDetailFragmentInterface, DownloadFailedDialogInterface, Receiver { - - private ProgressBar mProgressBar; - private TextView progressbar_description; - private ProviderListFragment provider_list_fragment; - private Intent mConfigState = new Intent(); - - final public static String TAG = "se.leap.bitmaskclient.ConfigurationWizard"; - final public static String TYPE_OF_CERTIFICATE = "type_of_certificate"; - final public static String ANON_CERTIFICATE = "anon_certificate"; - final public static String AUTHED_CERTIFICATE = "authed_certificate"; - - final protected static String PROVIDER_SET = "PROVIDER SET"; - final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; + +/** + * Activity that builds and shows the list of known available providers. + * + * It also allows the user to enter custom providers with a button. + * + * @author parmegv + * + */ +public class ConfigurationWizard extends Activity +implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderDetailFragmentInterface, DownloadFailedDialogInterface, Receiver { + + private ProgressBar mProgressBar; + private TextView progressbar_description; + private ProviderListFragment provider_list_fragment; + private Intent mConfigState = new Intent(); + + final public static String TAG = ConfigurationWizard.class.getSimpleName(); + 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"; + + final protected static String PROVIDER_SET = "PROVIDER SET"; + final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; final protected static String ASSETS_URL_FOLDER = "urls"; - - public ProviderAPIResultReceiver providerAPI_result_receiver; + + public ProviderAPIResultReceiver providerAPI_result_receiver; private ProviderAPIBroadcastReceiver_Update providerAPI_broadcast_receiver_update; - private static SharedPreferences preferences; + private static SharedPreferences preferences; + FragmentManagerEnhanced fragment_manager; private static boolean setting_up_provider = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); - - setContentView(R.layout.configuration_wizard_activity); - mProgressBar = (ProgressBar) findViewById(R.id.progressbar_configuration_wizard); - mProgressBar.setVisibility(ProgressBar.INVISIBLE); - progressbar_description = (TextView) findViewById(R.id.progressbar_description); - progressbar_description.setVisibility(TextView.INVISIBLE); - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); - providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update(); - IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR); - update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT); - registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter); - - loadPreseededProviders(); - - // Only create our fragments if we're not restoring a saved instance - if ( savedInstanceState == null ){ - // TODO Some welcome screen? - // We will need better flow control when we have more Fragments (e.g. user auth) - provider_list_fragment = ProviderListFragment.newInstance(); - Bundle arguments = new Bundle(); - int configuration_wizard_request_code = getIntent().getIntExtra(Dashboard.REQUEST_CODE, -1); - if(configuration_wizard_request_code == Dashboard.SWITCH_PROVIDER) { - arguments.putBoolean(ProviderListFragment.SHOW_ALL_PROVIDERS, true); - } - provider_list_fragment.setArguments(arguments); - - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction() - .replace(R.id.configuration_wizard_layout, provider_list_fragment, ProviderListFragment.TAG) - .commit(); - } - - // TODO: If exposing deep links into your app, handle intents here. - } - - @Override - protected void onDestroy() { - super.onDestroy(); - unregisterReceiver(providerAPI_broadcast_receiver_update); - } - - public void refreshProviderList(int top_padding) { - ProviderListFragment new_provider_list_fragment = new ProviderListFragment(); - Bundle top_padding_bundle = new Bundle(); - top_padding_bundle.putInt(ProviderListFragment.TOP_PADDING, top_padding); - new_provider_list_fragment.setArguments(top_padding_bundle); - - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction() - .replace(R.id.configuration_wizard_layout, new_provider_list_fragment, ProviderListFragment.TAG) - .commit(); - } - - @Override - public void onReceiveResult(int resultCode, Bundle resultData) { - if(resultCode == ProviderAPI.PROVIDER_OK) { - mConfigState.setAction(PROVIDER_SET); - - if (preferences.getBoolean(EIP.ALLOWED_ANON, false)){ - mConfigState.putExtra(SERVICES_RETRIEVED, true); - downloadAnonCert(); - } else { - mProgressBar.incrementProgressBy(1); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - setResult(RESULT_OK); - showProviderDetails(getCurrentFocus()); - } - } else if(resultCode == ProviderAPI.PROVIDER_NOK) { - //refreshProviderList(0); - String reason_to_fail = resultData.getString(ProviderAPI.ERRORS); - showDownloadFailedDialog(getCurrentFocus(), reason_to_fail); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - preferences.edit().remove(Provider.KEY).commit(); - setting_up_provider = false; - setResult(RESULT_CANCELED, mConfigState); - } - else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { - mProgressBar.incrementProgressBy(1); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - //refreshProviderList(0); - setResult(RESULT_OK); - showProviderDetails(getCurrentFocus()); - } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { - //refreshProviderList(0); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - //Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_certificate_message, Toast.LENGTH_LONG).show(); - setResult(RESULT_CANCELED, mConfigState); - } else if(resultCode == AboutActivity.VIEWED) { - // Do nothing, right now - // I need this for CW to wait for the About activity to end before going back to Dashboard. - } - } - - /** - * Callback method from {@link ProviderListFragment.Callbacks} - * indicating that the item with the given ID was selected. - */ - @Override - public void onItemSelected(String id) { - //TODO Code 2 pane view - // resetOldConnection(); - ProviderItem selected_provider = getProvider(id); - int provider_index = getProviderIndex(id); - - - startProgressBar(provider_index+1); - provider_list_fragment.hideAllBut(provider_index); - - boolean danger_on = true; - if(preferences.contains(ProviderItem.DANGER_ON)) - danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, false); - setUpProvider(selected_provider.providerMainUrl(), danger_on); - } - - @Override - public void onBackPressed() { + fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); + + setUpInitialUI(); + + loadPreseededProviders(); + + setUpProviderAPIResultReceiver(); + + // Only create our fragments if we're not restoring a saved instance + if ( savedInstanceState == null ){ + // TODO Some welcome screen? + // We will need better flow control when we have more Fragments (e.g. user auth) + setUpProviderList(); + } + + // TODO: If exposing deep links into your app, handle intents here. + } + + private void setUpInitialUI() { + setContentView(R.layout.configuration_wizard_activity); + + hideProgressBar(); + } + + private void hideProgressBar() { + mProgressBar = (ProgressBar) findViewById(R.id.progressbar_configuration_wizard); + mProgressBar.setVisibility(ProgressBar.INVISIBLE); + + progressbar_description = (TextView) findViewById(R.id.progressbar_description); + progressbar_description.setVisibility(TextView.INVISIBLE); + } + + private void setUpProviderList() { + provider_list_fragment = ProviderListFragment.newInstance(); + + Bundle arguments = new Bundle(); + int configuration_wizard_request_code = getIntent().getIntExtra(Dashboard.REQUEST_CODE, -1); + if(configuration_wizard_request_code == Dashboard.SWITCH_PROVIDER) + arguments.putBoolean(ProviderListFragment.SHOW_ALL_PROVIDERS, true); + + provider_list_fragment.setArguments(arguments); + + putProviderListFragment(provider_list_fragment); + } + + private void putProviderListFragment(ProviderListFragment fragment) { + + fragment_manager.replace(R.id.configuration_wizard_layout, provider_list_fragment, ProviderListFragment.TAG); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(providerAPI_broadcast_receiver_update); + } + + private void setUpProviderAPIResultReceiver() { + providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + providerAPI_result_receiver.setReceiver(this); + providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update(); + + IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR); + update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT); + registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter); + } + + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + if(resultCode == ProviderAPI.PROVIDER_OK) { + mConfigState.setAction(PROVIDER_SET); + + if (preferences.getBoolean(EIP.ALLOWED_ANON, false)){ + mConfigState.putExtra(SERVICES_RETRIEVED, true); + + downloadAnonCert(); + } else { + mProgressBar.incrementProgressBy(1); + hideProgressBar(); + + setResult(RESULT_OK); + + showProviderDetails(); + } + } else if(resultCode == ProviderAPI.PROVIDER_NOK) { + hideProgressBar(); + preferences.edit().remove(Provider.KEY).commit(); + setting_up_provider = false; + + setResult(RESULT_CANCELED, mConfigState); + + String reason_to_fail = resultData.getString(ProviderAPI.ERRORS); + showDownloadFailedDialog(getCurrentFocus(), reason_to_fail); + } + else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { + mProgressBar.incrementProgressBy(1); + hideProgressBar(); + + setResult(RESULT_OK); + + showProviderDetails(); + } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { + hideProgressBar(); + + setResult(RESULT_CANCELED, mConfigState); + } else if(resultCode == AboutActivity.VIEWED) { + // Do nothing, right now + // I need this for CW to wait for the About activity to end before going back to Dashboard. + } + } + + /** + * Callback method from {@link ProviderListFragment.Callbacks} + * indicating that the item with the given ID was selected. + */ + @Override + public void onItemSelected(String id) { + //TODO Code 2 pane view + ProviderItem selected_provider = getProvider(id); + int provider_index = getProviderIndex(id); + + startProgressBar(provider_index+1); + provider_list_fragment.hideAllBut(provider_index); + + boolean danger_on = true; + if(preferences.contains(ProviderItem.DANGER_ON)) + danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, false); + setUpProvider(selected_provider.providerMainUrl(), danger_on); + } + + @Override + public void onBackPressed() { if(setting_up_provider) { stopSettingUpProvider(); - } else { + } else { usualBackButton(); } } - - private void stopSettingUpProvider() { - ProviderAPI.stop(); - mProgressBar.setVisibility(ProgressBar.GONE); - mProgressBar.setProgress(0); - progressbar_description.setVisibility(TextView.GONE); - preferences.edit().remove(Provider.KEY).commit(); - setting_up_provider = false; + + private void stopSettingUpProvider() { + ProviderAPI.stop(); + mProgressBar.setVisibility(ProgressBar.GONE); + mProgressBar.setProgress(0); + progressbar_description.setVisibility(TextView.GONE); + preferences.edit().remove(Provider.KEY).commit(); + setting_up_provider = false; showAllProviders(); - } - - private void usualBackButton() { - try { - boolean is_provider_set_up = new JSONObject(preferences.getString(Provider.KEY, "no provider")) != null ? true : false; - boolean is_provider_set_up_truly = new JSONObject(preferences.getString(Provider.KEY, "no provider")).length() != 0 ? true : false; - if(!is_provider_set_up || !is_provider_set_up_truly) { - askDashboardToQuitApp(); - } else { - setResult(RESULT_OK); - } - } catch (JSONException e) { - askDashboardToQuitApp(); - super.onBackPressed(); - e.printStackTrace(); - } - super.onBackPressed(); - } - private void askDashboardToQuitApp() { - Intent ask_quit = new Intent(); - ask_quit.putExtra(Dashboard.ACTION_QUIT, Dashboard.ACTION_QUIT); - setResult(RESULT_CANCELED, ask_quit); - } - - private ProviderItem getProvider(String name) { - Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); - while(providers_iterator.hasNext()) { - ProviderItem provider = providers_iterator.next(); - if(provider.name().equalsIgnoreCase(name)) { - return provider; - } - } - return null; - } - - private String getId(String provider_main_url_string) { + } + + private void usualBackButton() { + try { + boolean is_provider_set_up = new JSONObject(preferences.getString(Provider.KEY, "no provider")) != null ? true : false; + boolean is_provider_set_up_truly = new JSONObject(preferences.getString(Provider.KEY, "no provider")).length() != 0 ? true : false; + if(!is_provider_set_up || !is_provider_set_up_truly) { + askDashboardToQuitApp(); + } else { + setResult(RESULT_OK); + } + } catch (JSONException e) { + askDashboardToQuitApp(); + super.onBackPressed(); + e.printStackTrace(); + } + super.onBackPressed(); + } + private void askDashboardToQuitApp() { + Intent ask_quit = new Intent(); + ask_quit.putExtra(Dashboard.ACTION_QUIT, Dashboard.ACTION_QUIT); + setResult(RESULT_CANCELED, ask_quit); + } + + private ProviderItem getProvider(String name) { + Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); + while(providers_iterator.hasNext()) { + ProviderItem provider = providers_iterator.next(); + if(provider.name().equalsIgnoreCase(name)) { + return provider; + } + } + return null; + } + + private void startProgressBar() { + mProgressBar.setVisibility(ProgressBar.VISIBLE); + progressbar_description.setVisibility(TextView.VISIBLE); + mProgressBar.setProgress(0); + mProgressBar.setMax(3); + } + + private void startProgressBar(int list_item_index) { + startProgressBar(); + int measured_height = listItemHeight(list_item_index); + mProgressBar.setTranslationY(measured_height); + progressbar_description.setTranslationY(measured_height + mProgressBar.getHeight()); + } + + private int getProviderIndex(String id) { + int index = 0; + Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); + while(providers_iterator.hasNext()) { + ProviderItem provider = providers_iterator.next(); + if(provider.name().equalsIgnoreCase(id)) { + break; + } else index++; + } + return index; + } + + private int listItemHeight(int list_item_index) { + ListView provider_list_view = (ListView)findViewById(android.R.id.list); + ListAdapter provider_list_adapter = provider_list_view.getAdapter(); + View listItem = provider_list_adapter.getView(0, null, provider_list_view); + listItem.setLayoutParams(new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT)); + WindowManager wm = (WindowManager) getApplicationContext() + .getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + int screenWidth = display.getWidth(); // deprecated + + int listViewWidth = screenWidth - 10 - 10; + int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth, + MeasureSpec.AT_MOST); + listItem.measure(widthSpec, 0); + + return listItem.getMeasuredHeight(); +} + + /** + * Loads providers data from url files contained in the assets folder + * @return true if the files were correctly read + */ + private boolean loadPreseededProviders() { + boolean loaded_preseeded_providers = true; + try { + //TODO Put that folder in a better place (also inside the "for") + String[] urls_filepaths = getAssets().list(ASSETS_URL_FOLDER); + for(String url_filepath : urls_filepaths) { + addNewProviderToList(url_filepath); + } + } catch (IOException e) { + loaded_preseeded_providers = false; + } + + return loaded_preseeded_providers; + } + + private void addNewProviderToList(String url_filepath) { + String provider_main_url = extractProviderMainUrlFromAssetsFile(ASSETS_URL_FOLDER + "/" + url_filepath); + if(getId(provider_main_url).isEmpty()) { + String provider_name = url_filepath.subSequence(0, url_filepath.lastIndexOf(".")).toString(); + ProviderListContent.addItem(new ProviderItem(provider_name, provider_main_url)); + } + } + + private String extractProviderMainUrlFromAssetsFile(String filepath) { + String provider_main_url = ""; + try { + InputStream input_stream_file_contents = getAssets().open(filepath); + byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; + input_stream_file_contents.read(urls_file_bytes); + String urls_file_content = new String(urls_file_bytes); + JSONObject file_contents = new JSONObject(urls_file_content); + provider_main_url = file_contents.getString(Provider.MAIN_URL); + } catch (JSONException e) { + } catch (IOException e) { + } + return provider_main_url; + } + + private String getId(String provider_main_url) { try { - URL provider_url = new URL(provider_main_url_string); - URL aux_provider_url; + URL provider_url = new URL(provider_main_url); Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); while(providers_iterator.hasNext()) { ProviderItem provider = providers_iterator.next(); - aux_provider_url = new URL(provider.providerMainUrl()); + URL aux_provider_url = new URL(provider.providerMainUrl()); if(isSameURL(provider_url, aux_provider_url)) { return provider.name(); } @@ -284,7 +379,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD e.printStackTrace(); } return ""; - } + } /** * Checks, whether 2 urls are pointing to the same location. @@ -306,218 +401,109 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD } return true; } - - private void startProgressBar() { - mProgressBar.setVisibility(ProgressBar.VISIBLE); - mProgressBar.setProgress(0); - mProgressBar.setMax(3); - } - - private void startProgressBar(int list_item_index) { - mProgressBar.setVisibility(ProgressBar.VISIBLE); - progressbar_description.setVisibility(TextView.VISIBLE); - mProgressBar.setProgress(0); - mProgressBar.setMax(3); - int measured_height = listItemHeight(list_item_index); - mProgressBar.setTranslationY(measured_height); - progressbar_description.setTranslationY(measured_height + mProgressBar.getHeight()); - } - - private int getProviderIndex(String id) { - int index = 0; - Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); - while(providers_iterator.hasNext()) { - ProviderItem provider = providers_iterator.next(); - if(provider.name().equalsIgnoreCase(id)) { - break; - } else index++; - } - return index; - } - - private int listItemHeight(int list_item_index) { - ListView provider_list_view = (ListView)findViewById(android.R.id.list); - ListAdapter provider_list_adapter = provider_list_view.getAdapter(); - View listItem = provider_list_adapter.getView(0, null, provider_list_view); - listItem.setLayoutParams(new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.WRAP_CONTENT, - RelativeLayout.LayoutParams.WRAP_CONTENT)); - WindowManager wm = (WindowManager) getApplicationContext() - .getSystemService(Context.WINDOW_SERVICE); - Display display = wm.getDefaultDisplay(); - int screenWidth = display.getWidth(); // deprecated - - int listViewWidth = screenWidth - 10 - 10; - int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth, - MeasureSpec.AT_MOST); - listItem.measure(widthSpec, 0); - - return listItem.getMeasuredHeight(); -} - - /** - * Loads providers data from url files contained in the assets folder - * @return true if the files were correctly read - */ - private boolean loadPreseededProviders() { - boolean loaded_preseeded_providers = false; - String[] urls_filepaths = null; - try { - //TODO Put that folder in a better place (also inside the "for") - urls_filepaths = getAssets().list(ASSETS_URL_FOLDER); - String provider_name = ""; - for(String url_filepath : urls_filepaths) { - provider_name = url_filepath.subSequence(0, url_filepath.lastIndexOf(".")).toString(); - String provider_main_url = extractProviderMainUrlFromAssetsFile(ASSETS_URL_FOLDER + "/" + url_filepath); - if(getId(provider_main_url).isEmpty()) - ProviderListContent.addItem(new ProviderItem(provider_name, provider_main_url)); - loaded_preseeded_providers = true; - } - } catch (IOException e) { - loaded_preseeded_providers = false; + + /** + * Asks ProviderAPI to download an anonymous (anon) VPN certificate. + */ + private void downloadAnonCert() { + Intent provider_API_command = new Intent(this, ProviderAPI.class); + + Bundle parameters = new Bundle(); + + parameters.putString(TYPE_OF_CERTIFICATE, ANON_CERTIFICATE); + + 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); } - return loaded_preseeded_providers; - } + /** + * Open the new provider dialog + */ + public void addAndSelectNewProvider() { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(NewProviderDialog.TAG); + DialogFragment newFragment = NewProviderDialog.newInstance(); + newFragment.show(fragment_transaction, NewProviderDialog.TAG); + } + + /** + * Open the new provider dialog with data + */ + public void addAndSelectNewProvider(String main_url, boolean danger_on) { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(NewProviderDialog.TAG); + + DialogFragment newFragment = NewProviderDialog.newInstance(); + Bundle data = new Bundle(); + data.putString(Provider.MAIN_URL, main_url); + data.putBoolean(ProviderItem.DANGER_ON, danger_on); + newFragment.setArguments(data); + newFragment.show(fragment_transaction, NewProviderDialog.TAG); + } + + /** + * Once selected a provider, this fragment offers the user to log in, + * use it anonymously (if possible) + * or cancel his/her election pressing the back button. + * @param view + * @param reason_to_fail + */ + public void showDownloadFailedDialog(View view, String reason_to_fail) { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(DownloadFailedDialog.TAG); + + DialogFragment newFragment = DownloadFailedDialog.newInstance(reason_to_fail); + newFragment.show(fragment_transaction, DownloadFailedDialog.TAG); + } + + /** + * Once selected a provider, this fragment offers the user to log in, + * use it anonymously (if possible) + * or cancel his/her election pressing the back button. + */ + private void showProviderDetails() { + if(setting_up_provider) { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(ProviderDetailFragment.TAG); - private String extractProviderMainUrlFromAssetsFile(String filepath) { - String provider_main_url = ""; - try { - InputStream input_stream_file_contents = getAssets().open(filepath); - byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; - input_stream_file_contents.read(urls_file_bytes); - String urls_file_content = new String(urls_file_bytes); - JSONObject file_contents = new JSONObject(urls_file_content); - provider_main_url = file_contents.getString(Provider.MAIN_URL); - } catch (JSONException e) { - } catch (IOException e) { + DialogFragment newFragment = ProviderDetailFragment.newInstance(); + newFragment.show(fragment_transaction, ProviderDetailFragment.TAG); + } } - return provider_main_url; - } - - /** - * Asks ProviderAPI to download an anonymous (anon) VPN certificate. - */ - private void downloadAnonCert() { - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - - parameters.putString(TYPE_OF_CERTIFICATE, ANON_CERTIFICATE); - - 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); - } - - /** - * Open the new provider dialog - */ - public void addAndSelectNewProvider() { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG); - if (previous_new_provider_dialog != null) { - fragment_transaction.remove(previous_new_provider_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = NewProviderDialog.newInstance(); - newFragment.show(fragment_transaction, NewProviderDialog.TAG); - } - - /** - * Open the new provider dialog with data - */ - public void addAndSelectNewProvider(String main_url, boolean danger_on) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG); - if (previous_new_provider_dialog != null) { - fragment_transaction.remove(previous_new_provider_dialog); - } - - DialogFragment newFragment = NewProviderDialog.newInstance(); - Bundle data = new Bundle(); - data.putString(Provider.MAIN_URL, main_url); - data.putBoolean(ProviderItem.DANGER_ON, danger_on); - newFragment.setArguments(data); - newFragment.show(fragment_transaction, NewProviderDialog.TAG); - } - - /** - * Once selected a provider, this fragment offers the user to log in, - * use it anonymously (if possible) - * or cancel his/her election pressing the back button. - * @param view - * @param reason_to_fail - */ - public void showDownloadFailedDialog(View view, String reason_to_fail) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(DownloadFailedDialog.TAG); - if (previous_provider_details_dialog != null) { - fragment_transaction.remove(previous_provider_details_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = DownloadFailedDialog.newInstance(reason_to_fail); - newFragment.show(fragment_transaction, DownloadFailedDialog.TAG); - } - - /** - * Once selected a provider, this fragment offers the user to log in, - * use it anonymously (if possible) - * or cancel his/her election pressing the back button. - * @param view - */ - public void showProviderDetails(View view) { - if(setting_up_provider) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - 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, ProviderDetailFragment.TAG); - } - } - - public void showAndSelectProvider(String provider_main_url, boolean danger_on) { + + public void showAndSelectProvider(String provider_main_url, boolean danger_on) { if(getId(provider_main_url).isEmpty()) - showProvider(provider_main_url, danger_on); + showProvider(provider_main_url, danger_on); autoSelectProvider(provider_main_url, danger_on); - } - - private void showProvider(final String provider_main_url, final boolean danger_on) { - String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); - ProviderItem added_provider = new ProviderItem(provider_name, provider_main_url); - provider_list_fragment.addItem(added_provider); - } - - private void autoSelectProvider(String provider_main_url, boolean danger_on) { - preferences.edit().putBoolean(ProviderItem.DANGER_ON, danger_on).commit(); - onItemSelected(getId(provider_main_url)); - } - - /** - * Asks ProviderAPI to download a new provider.json file - * @param provider_name - * @param provider_main_url - * @param danger_on tells if HTTPS client should bypass certificate errors - */ - public void setUpProvider(String provider_main_url, boolean danger_on) { - Intent provider_API_command = new Intent(this, ProviderAPI.class); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider_main_url); - parameters.putBoolean(ProviderItem.DANGER_ON, danger_on); - - provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + } + + private void showProvider(final String provider_main_url, final boolean danger_on) { + String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); + ProviderItem added_provider = new ProviderItem(provider_name, provider_main_url); + provider_list_fragment.addItem(added_provider); + } + + private void autoSelectProvider(String provider_main_url, boolean danger_on) { + preferences.edit().putBoolean(ProviderItem.DANGER_ON, danger_on).commit(); + onItemSelected(getId(provider_main_url)); + } + + /** + * Asks ProviderAPI to download a new provider.json file + * @param provider_name + * @param provider_main_url + * @param danger_on tells if HTTPS client should bypass certificate errors + */ + public void setUpProvider(String provider_main_url, boolean danger_on) { + Intent provider_API_command = new Intent(this, ProviderAPI.class); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider_main_url); + parameters.putBoolean(ProviderItem.DANGER_ON, danger_on); + + provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER); + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - startService(provider_API_command); + startService(provider_API_command); setting_up_provider = true; } @@ -534,62 +520,62 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD startService(provider_API_command); } } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item){ - switch (item.getItemId()){ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item){ + switch (item.getItemId()){ case R.id.about_leap: startActivityForResult(new Intent(this, AboutActivity.class), 0); return true; - case R.id.new_provider: - addAndSelectNewProvider(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - public void showAllProviders() { - provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG); - if(provider_list_fragment != null) - provider_list_fragment.unhideAll(); - } - - public void cancelSettingUpProvider() { - provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG); - if(provider_list_fragment != null && preferences.contains(ProviderItem.DANGER_ON)) { - provider_list_fragment.removeLastItem(); - } - preferences.edit().remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit(); - } - - @Override - public void login() { - Intent ask_login = new Intent(); + case R.id.new_provider: + addAndSelectNewProvider(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void showAllProviders() { + provider_list_fragment = (ProviderListFragment) fragment_manager.findFragmentByTag(ProviderListFragment.TAG); + if(provider_list_fragment != null) + provider_list_fragment.unhideAll(); + } + + public void cancelSettingUpProvider() { + provider_list_fragment = (ProviderListFragment) fragment_manager.findFragmentByTag(ProviderListFragment.TAG); + if(provider_list_fragment != null && preferences.contains(ProviderItem.DANGER_ON)) { + provider_list_fragment.removeLastItem(); + } + preferences.edit().remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit(); + } + + @Override + public void login() { + Intent ask_login = new Intent(); ask_login.putExtra(LogInDialog.TAG, LogInDialog.TAG); - setResult(RESULT_OK, ask_login); - setting_up_provider = false; - finish(); - } - - @Override - public void use_anonymously() { - setResult(RESULT_OK); - setting_up_provider = false; - finish(); - } - - public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - int update = intent.getIntExtra(ProviderAPI.CURRENT_PROGRESS, 0); - mProgressBar.setProgress(update); - } - } -} + setResult(RESULT_OK, ask_login); + setting_up_provider = false; + finish(); + } + + @Override + public void use_anonymously() { + setResult(RESULT_OK); + setting_up_provider = false; + finish(); + } + + public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + int update = intent.getIntExtra(ProviderAPI.CURRENT_PROGRESS, 0); + mProgressBar.setProgress(update); + } + } +} diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index 93014dc9..6445a599 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -180,7 +180,7 @@ public class ProviderAPI extends IntentService { receiver.send(SRP_REGISTRATION_FAILED, session_id_bundle); } } else if (action.equalsIgnoreCase(SRP_AUTH)) { - Bundle session_id_bundle = tryToAuthenticateBySRP(parameters); + Bundle session_id_bundle = tryToAuthenticate(parameters); if(session_id_bundle.getBoolean(RESULT_KEY)) { receiver.send(SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); } else { diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 286d88c3..d80755aa 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -21,13 +21,14 @@ import org.json.JSONObject; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; +import se.leap.bitmaskclient.FragmentManagerEnhanced; import se.leap.bitmaskclient.SignUpDialog; + import de.blinkt.openvpn.activities.LogWindow; + import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Context; import android.content.DialogInterface; @@ -78,6 +79,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private boolean authed_eip = false; public ProviderAPIResultReceiver providerAPI_result_receiver; + private FragmentManagerEnhanced fragment_manager; @Override protected void onCreate(Bundle savedInstanceState) { @@ -90,6 +92,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); @@ -194,7 +197,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - FragmentManager fragMan = getFragmentManager(); if ( provider.hasEIP()){ eipFragment = new EipServiceFragment(); if (hide_and_turn_on_eip) { @@ -203,7 +205,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); eipFragment.setArguments(arguments); } - fragMan.beginTransaction().replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG).commit(); + fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); if (hide_and_turn_on_eip) { onBackPressed(); @@ -293,23 +295,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); return command; } - - private FragmentTransaction removePreviousFragment(String tag) { - FragmentTransaction transaction = getFragmentManager().beginTransaction(); - Fragment previous_fragment = getFragmentManager().findFragmentByTag(tag); - if (previous_fragment != null) { - transaction.remove(previous_fragment); - } - transaction.addToBackStack(null); - - return transaction; - } /** * Shows the log in dialog. */ public void logInDialog(Bundle resultData) { - FragmentTransaction transaction = removePreviousFragment(LogInDialog.TAG); + FragmentTransaction transaction = fragment_manager.removePreviousFragment(LogInDialog.TAG); DialogFragment newFragment = LogInDialog.newInstance(); if(resultData != null && !resultData.isEmpty()) @@ -363,7 +354,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * Shows the sign up dialog. */ public void signUpDialog(Bundle resultData) { - FragmentTransaction transaction = removePreviousFragment(SignUpDialog.TAG); + FragmentTransaction transaction = fragment_manager.removePreviousFragment(SignUpDialog.TAG); DialogFragment newFragment = SignUpDialog.newInstance(); if(resultData != null && !resultData.isEmpty()) { diff --git a/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java b/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java new file mode 100644 index 00000000..c4844be9 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java @@ -0,0 +1,51 @@ +/** + * 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 . + */ +package se.leap.bitmaskclient; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; + +public class FragmentManagerEnhanced { + + private FragmentManager generic_fragment_manager; + + public FragmentManagerEnhanced(FragmentManager generic_fragment_manager) { + this.generic_fragment_manager = generic_fragment_manager; + } + + public FragmentTransaction removePreviousFragment(String tag) { + FragmentTransaction transaction = generic_fragment_manager.beginTransaction(); + Fragment previous_fragment = generic_fragment_manager.findFragmentByTag(tag); + if (previous_fragment != null) { + transaction.remove(previous_fragment); + } + transaction.addToBackStack(null); + + return transaction; + } + + public void replace(int containerViewId, Fragment fragment, String tag) { + FragmentTransaction transaction = generic_fragment_manager.beginTransaction(); + + transaction.replace(containerViewId, fragment, tag).commit(); + } + + public Fragment findFragmentByTag(String tag) { + return generic_fragment_manager.findFragmentByTag(tag); + } +} diff --git a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java index f844989b..03930c61 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -1,278 +1,372 @@ -/** - * 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 . - */ - package se.leap.bitmaskclient; - - - - - - -import android.app.Activity; -import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.res.AssetManager; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -import android.view.Display; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View.MeasureSpec; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.ProgressBar; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import java.io.IOException; +/** + * 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 . + */ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.app.DialogFragment; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.res.AssetManager; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import android.view.Display; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View.MeasureSpec; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import java.util.Iterator; -import org.json.JSONException; -import org.json.JSONObject; +import java.util.Iterator; +import org.json.JSONException; +import org.json.JSONObject; + import se.leap.bitmaskclient.DownloadFailedDialog.DownloadFailedDialogInterface; import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; import se.leap.bitmaskclient.ProviderDetailFragment.ProviderDetailFragmentInterface; import se.leap.bitmaskclient.ProviderListContent.ProviderItem; +import se.leap.bitmaskclient.FragmentManagerEnhanced; + import se.leap.bitmaskclient.R; - -/** - * Activity that builds and shows the list of known available providers. - * - * It also allows the user to enter custom providers with a button. - * - * @author parmegv - * - */ -public class ConfigurationWizard extends Activity -implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderDetailFragmentInterface, DownloadFailedDialogInterface, Receiver { - - private ProgressBar mProgressBar; - private TextView progressbar_description; - private ProviderListFragment provider_list_fragment; - private Intent mConfigState = new Intent(); - - final public static String TAG = "se.leap.bitmaskclient.ConfigurationWizard"; - final public static String TYPE_OF_CERTIFICATE = "type_of_certificate"; - final public static String ANON_CERTIFICATE = "anon_certificate"; - final public static String AUTHED_CERTIFICATE = "authed_certificate"; - - final protected static String PROVIDER_SET = "PROVIDER SET"; - final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; + +/** + * Activity that builds and shows the list of known available providers. + * + * It also allows the user to enter custom providers with a button. + * + * @author parmegv + * + */ +public class ConfigurationWizard extends Activity +implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderDetailFragmentInterface, DownloadFailedDialogInterface, Receiver { + + private ProgressBar mProgressBar; + private TextView progressbar_description; + private ProviderListFragment provider_list_fragment; + private Intent mConfigState = new Intent(); + + final public static String TAG = ConfigurationWizard.class.getSimpleName(); + 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"; + + final protected static String PROVIDER_SET = "PROVIDER SET"; + final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; final protected static String ASSETS_URL_FOLDER = "urls"; - - public ProviderAPIResultReceiver providerAPI_result_receiver; + + public ProviderAPIResultReceiver providerAPI_result_receiver; private ProviderAPIBroadcastReceiver_Update providerAPI_broadcast_receiver_update; - private static SharedPreferences preferences; + private static SharedPreferences preferences; + FragmentManagerEnhanced fragment_manager; private static boolean setting_up_provider = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); - - setContentView(R.layout.configuration_wizard_activity); - mProgressBar = (ProgressBar) findViewById(R.id.progressbar_configuration_wizard); - mProgressBar.setVisibility(ProgressBar.INVISIBLE); - progressbar_description = (TextView) findViewById(R.id.progressbar_description); - progressbar_description.setVisibility(TextView.INVISIBLE); - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); - providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update(); - IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR); - update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT); - registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter); - - loadPreseededProviders(); - - // Only create our fragments if we're not restoring a saved instance - if ( savedInstanceState == null ){ - // TODO Some welcome screen? - // We will need better flow control when we have more Fragments (e.g. user auth) - provider_list_fragment = ProviderListFragment.newInstance(); - Bundle arguments = new Bundle(); - int configuration_wizard_request_code = getIntent().getIntExtra(Dashboard.REQUEST_CODE, -1); - if(configuration_wizard_request_code == Dashboard.SWITCH_PROVIDER) { - arguments.putBoolean(ProviderListFragment.SHOW_ALL_PROVIDERS, true); - } - provider_list_fragment.setArguments(arguments); - - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction() - .replace(R.id.configuration_wizard_layout, provider_list_fragment, ProviderListFragment.TAG) - .commit(); - } - - // TODO: If exposing deep links into your app, handle intents here. - } - - @Override - protected void onDestroy() { - super.onDestroy(); - unregisterReceiver(providerAPI_broadcast_receiver_update); - } - - public void refreshProviderList(int top_padding) { - ProviderListFragment new_provider_list_fragment = new ProviderListFragment(); - Bundle top_padding_bundle = new Bundle(); - top_padding_bundle.putInt(ProviderListFragment.TOP_PADDING, top_padding); - new_provider_list_fragment.setArguments(top_padding_bundle); - - FragmentManager fragmentManager = getFragmentManager(); - fragmentManager.beginTransaction() - .replace(R.id.configuration_wizard_layout, new_provider_list_fragment, ProviderListFragment.TAG) - .commit(); - } - - @Override - public void onReceiveResult(int resultCode, Bundle resultData) { - if(resultCode == ProviderAPI.PROVIDER_OK) { - mConfigState.setAction(PROVIDER_SET); - - if (preferences.getBoolean(EIP.ALLOWED_ANON, false)){ - mConfigState.putExtra(SERVICES_RETRIEVED, true); - downloadAnonCert(); - } else { - mProgressBar.incrementProgressBy(1); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - setResult(RESULT_OK); - showProviderDetails(getCurrentFocus()); - } - } else if(resultCode == ProviderAPI.PROVIDER_NOK) { - //refreshProviderList(0); - String reason_to_fail = resultData.getString(ProviderAPI.ERRORS); - showDownloadFailedDialog(getCurrentFocus(), reason_to_fail); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - preferences.edit().remove(Provider.KEY).commit(); - setting_up_provider = false; - setResult(RESULT_CANCELED, mConfigState); - } - else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { - mProgressBar.incrementProgressBy(1); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - //refreshProviderList(0); - setResult(RESULT_OK); - showProviderDetails(getCurrentFocus()); - } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { - //refreshProviderList(0); - mProgressBar.setVisibility(ProgressBar.GONE); - progressbar_description.setVisibility(TextView.GONE); - //Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_certificate_message, Toast.LENGTH_LONG).show(); - setResult(RESULT_CANCELED, mConfigState); - } else if(resultCode == AboutActivity.VIEWED) { - // Do nothing, right now - // I need this for CW to wait for the About activity to end before going back to Dashboard. - } - } - - /** - * Callback method from {@link ProviderListFragment.Callbacks} - * indicating that the item with the given ID was selected. - */ - @Override - public void onItemSelected(String id) { - //TODO Code 2 pane view - // resetOldConnection(); - ProviderItem selected_provider = getProvider(id); - int provider_index = getProviderIndex(id); - - - startProgressBar(provider_index+1); - provider_list_fragment.hideAllBut(provider_index); - - setUpProvider(selected_provider.providerMainUrl()); - } - - @Override - public void onBackPressed() { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); + fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); + + setUpInitialUI(); + + loadPreseededProviders(); + + setUpProviderAPIResultReceiver(); + + // Only create our fragments if we're not restoring a saved instance + if ( savedInstanceState == null ) { + // TODO Some welcome screen? + // We will need better flow control when we have more Fragments (e.g. user auth) + setUpProviderList(); + } + + // TODO: If exposing deep links into your app, handle intents here. + } + + private void setUpInitialUI() { + setContentView(R.layout.configuration_wizard_activity); + + hideProgressBar(); + } + + private void hideProgressBar() { + mProgressBar = (ProgressBar) findViewById(R.id.progressbar_configuration_wizard); + mProgressBar.setVisibility(ProgressBar.INVISIBLE); + + progressbar_description = (TextView) findViewById(R.id.progressbar_description); + progressbar_description.setVisibility(TextView.INVISIBLE); + } + + private void setUpProviderList() { + provider_list_fragment = ProviderListFragment.newInstance(); + + Bundle arguments = new Bundle(); + int configuration_wizard_request_code = getIntent().getIntExtra(Dashboard.REQUEST_CODE, -1); + if(configuration_wizard_request_code == Dashboard.SWITCH_PROVIDER) + arguments.putBoolean(ProviderListFragment.SHOW_ALL_PROVIDERS, true); + + provider_list_fragment.setArguments(arguments); + + putProviderListFragment(provider_list_fragment); + } + + private void putProviderListFragment(ProviderListFragment fragment) { + fragment_manager.replace(R.id.configuration_wizard_layout, provider_list_fragment, ProviderListFragment.TAG); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(providerAPI_broadcast_receiver_update); + } + + private void setUpProviderAPIResultReceiver() { + providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + providerAPI_result_receiver.setReceiver(this); + providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update(); + + IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR); + update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT); + registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter); + } + + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + if(resultCode == ProviderAPI.PROVIDER_OK) { + mConfigState.setAction(PROVIDER_SET); + + if (preferences.getBoolean(EIP.ALLOWED_ANON, false)){ + mConfigState.putExtra(SERVICES_RETRIEVED, true); + + downloadAnonCert(); + } else { + mProgressBar.incrementProgressBy(1); + hideProgressBar(); + + setResult(RESULT_OK); + + showProviderDetails(); + } + } else if(resultCode == ProviderAPI.PROVIDER_NOK) { + hideProgressBar(); + preferences.edit().remove(Provider.KEY).commit(); + setting_up_provider = false; + + setResult(RESULT_CANCELED, mConfigState); + + String reason_to_fail = resultData.getString(ProviderAPI.ERRORS); + showDownloadFailedDialog(getCurrentFocus(), reason_to_fail); + } + else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { + mProgressBar.incrementProgressBy(1); + hideProgressBar(); + + setResult(RESULT_OK); + + showProviderDetails(); + } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { + hideProgressBar(); + + setResult(RESULT_CANCELED, mConfigState); + } else if(resultCode == AboutActivity.VIEWED) { + // Do nothing, right now + // I need this for CW to wait for the About activity to end before going back to Dashboard. + } + } + + /** + * Callback method from {@link ProviderListFragment.Callbacks} + * indicating that the item with the given ID was selected. + */ + @Override + public void onItemSelected(String id) { + //TODO Code 2 pane view + ProviderItem selected_provider = getProvider(id); + int provider_index = getProviderIndex(id); + + startProgressBar(provider_index+1); + provider_list_fragment.hideAllBut(provider_index); + + setUpProvider(selected_provider.providerMainUrl()); + } + + @Override + public void onBackPressed() { if(setting_up_provider) { stopSettingUpProvider(); - } else { + } else { usualBackButton(); } } - - private void stopSettingUpProvider() { - ProviderAPI.stop(); - mProgressBar.setVisibility(ProgressBar.GONE); - mProgressBar.setProgress(0); - progressbar_description.setVisibility(TextView.GONE); - preferences.edit().remove(Provider.KEY).commit(); - setting_up_provider = false; + + private void stopSettingUpProvider() { + ProviderAPI.stop(); + mProgressBar.setVisibility(ProgressBar.GONE); + mProgressBar.setProgress(0); + progressbar_description.setVisibility(TextView.GONE); + preferences.edit().remove(Provider.KEY).commit(); + setting_up_provider = false; showAllProviders(); - } - - private void usualBackButton() { - try { - boolean is_provider_set_up = new JSONObject(preferences.getString(Provider.KEY, "no provider")) != null ? true : false; - boolean is_provider_set_up_truly = new JSONObject(preferences.getString(Provider.KEY, "no provider")).length() != 0 ? true : false; - if(!is_provider_set_up || !is_provider_set_up_truly) { - askDashboardToQuitApp(); - } else { - setResult(RESULT_OK); - } - } catch (JSONException e) { - askDashboardToQuitApp(); - super.onBackPressed(); - e.printStackTrace(); - } - super.onBackPressed(); - } - private void askDashboardToQuitApp() { - Intent ask_quit = new Intent(); - ask_quit.putExtra(Dashboard.ACTION_QUIT, Dashboard.ACTION_QUIT); - setResult(RESULT_CANCELED, ask_quit); - } - - private ProviderItem getProvider(String name) { - Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); - while(providers_iterator.hasNext()) { - ProviderItem provider = providers_iterator.next(); - if(provider.name().equalsIgnoreCase(name)) { - return provider; - } - } - return null; - } - - private String getId(String provider_main_url_string) { + } + + private void usualBackButton() { + try { + boolean is_provider_set_up = new JSONObject(preferences.getString(Provider.KEY, "no provider")) != null ? true : false; + boolean is_provider_set_up_truly = new JSONObject(preferences.getString(Provider.KEY, "no provider")).length() != 0 ? true : false; + if(!is_provider_set_up || !is_provider_set_up_truly) { + askDashboardToQuitApp(); + } else { + setResult(RESULT_OK); + } + } catch (JSONException e) { + askDashboardToQuitApp(); + super.onBackPressed(); + e.printStackTrace(); + } + super.onBackPressed(); + } + private void askDashboardToQuitApp() { + Intent ask_quit = new Intent(); + ask_quit.putExtra(Dashboard.ACTION_QUIT, Dashboard.ACTION_QUIT); + setResult(RESULT_CANCELED, ask_quit); + } + + private ProviderItem getProvider(String name) { + Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); + while(providers_iterator.hasNext()) { + ProviderItem provider = providers_iterator.next(); + if(provider.name().equalsIgnoreCase(name)) { + return provider; + } + } + return null; + } + + private void startProgressBar() { + mProgressBar.setVisibility(ProgressBar.VISIBLE); + progressbar_description.setVisibility(TextView.VISIBLE); + mProgressBar.setProgress(0); + mProgressBar.setMax(3); + } + + private void startProgressBar(int list_item_index) { + startProgressBar(); + int measured_height = listItemHeight(list_item_index); + mProgressBar.setTranslationY(measured_height); + progressbar_description.setTranslationY(measured_height + mProgressBar.getHeight()); + } + + private int getProviderIndex(String id) { + int index = 0; + Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); + while(providers_iterator.hasNext()) { + ProviderItem provider = providers_iterator.next(); + if(provider.name().equalsIgnoreCase(id)) { + break; + } else index++; + } + return index; + } + + private int listItemHeight(int list_item_index) { + ListView provider_list_view = (ListView)findViewById(android.R.id.list); + ListAdapter provider_list_adapter = provider_list_view.getAdapter(); + View listItem = provider_list_adapter.getView(0, null, provider_list_view); + listItem.setLayoutParams(new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT)); + WindowManager wm = (WindowManager) getApplicationContext() + .getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + int screenWidth = display.getWidth(); // deprecated + + int listViewWidth = screenWidth - 10 - 10; + int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth, + MeasureSpec.AT_MOST); + listItem.measure(widthSpec, 0); + + return listItem.getMeasuredHeight(); +} + + /** + * Loads providers data from url files contained in the assets folder + * @return true if the files were correctly read + */ + private boolean loadPreseededProviders() { + boolean loaded_preseeded_providers = true; + try { + //TODO Put that folder in a better place (also inside the "for") + String[] urls_filepaths = getAssets().list(ASSETS_URL_FOLDER); + for(String url_filepath : urls_filepaths) { + addNewProviderToList(url_filepath); + } + } catch (IOException e) { + loaded_preseeded_providers = false; + } + + return loaded_preseeded_providers; + } + + private void addNewProviderToList(String url_filepath) { + String provider_main_url = extractProviderMainUrlFromAssetsFile(ASSETS_URL_FOLDER + "/" + url_filepath); + if(getId(provider_main_url).isEmpty()) { + String provider_name = url_filepath.subSequence(0, url_filepath.lastIndexOf(".")).toString(); + ProviderListContent.addItem(new ProviderItem(provider_name, provider_main_url)); + } + } + + private String extractProviderMainUrlFromAssetsFile(String filepath) { + String provider_main_url = ""; + try { + InputStream input_stream_file_contents = getAssets().open(filepath); + byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; + input_stream_file_contents.read(urls_file_bytes); + String urls_file_content = new String(urls_file_bytes); + JSONObject file_contents = new JSONObject(urls_file_content); + provider_main_url = file_contents.getString(Provider.MAIN_URL); + } catch (JSONException e) { + } catch (IOException e) { + } + return provider_main_url; + } + + private String getId(String provider_main_url) { try { - URL provider_url = new URL(provider_main_url_string); - URL aux_provider_url; + URL provider_url = new URL(provider_main_url); Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); while(providers_iterator.hasNext()) { ProviderItem provider = providers_iterator.next(); - aux_provider_url = new URL(provider.providerMainUrl()); + URL aux_provider_url = new URL(provider.providerMainUrl()); if(isSameURL(provider_url, aux_provider_url)) { return provider.name(); } @@ -281,7 +375,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD e.printStackTrace(); } return ""; - } + } /** * Checks, whether 2 urls are pointing to the same location. @@ -303,214 +397,106 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD } return true; } - - private void startProgressBar() { - mProgressBar.setVisibility(ProgressBar.VISIBLE); - mProgressBar.setProgress(0); - mProgressBar.setMax(3); - } - - private void startProgressBar(int list_item_index) { - mProgressBar.setVisibility(ProgressBar.VISIBLE); - progressbar_description.setVisibility(TextView.VISIBLE); - mProgressBar.setProgress(0); - mProgressBar.setMax(3); - int measured_height = listItemHeight(list_item_index); - mProgressBar.setTranslationY(measured_height); - progressbar_description.setTranslationY(measured_height + mProgressBar.getHeight()); - } - - private int getProviderIndex(String id) { - int index = 0; - Iterator providers_iterator = ProviderListContent.ITEMS.iterator(); - while(providers_iterator.hasNext()) { - ProviderItem provider = providers_iterator.next(); - if(provider.name().equalsIgnoreCase(id)) { - break; - } else index++; - } - return index; - } - - private int listItemHeight(int list_item_index) { - ListView provider_list_view = (ListView)findViewById(android.R.id.list); - ListAdapter provider_list_adapter = provider_list_view.getAdapter(); - View listItem = provider_list_adapter.getView(0, null, provider_list_view); - listItem.setLayoutParams(new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.WRAP_CONTENT, - RelativeLayout.LayoutParams.WRAP_CONTENT)); - WindowManager wm = (WindowManager) getApplicationContext() - .getSystemService(Context.WINDOW_SERVICE); - Display display = wm.getDefaultDisplay(); - int screenWidth = display.getWidth(); // deprecated - - int listViewWidth = screenWidth - 10 - 10; - int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth, - MeasureSpec.AT_MOST); - listItem.measure(widthSpec, 0); - - return listItem.getMeasuredHeight(); -} - - /** - * Loads providers data from url files contained in the assets folder - * @return true if the files were correctly read - */ - private boolean loadPreseededProviders() { - boolean loaded_preseeded_providers = false; - String[] urls_filepaths = null; - try { - //TODO Put that folder in a better place (also inside the "for") - urls_filepaths = getAssets().list(ASSETS_URL_FOLDER); - String provider_name = ""; - for(String url_filepath : urls_filepaths) { - provider_name = url_filepath.subSequence(0, url_filepath.lastIndexOf(".")).toString(); - String provider_main_url = extractProviderMainUrlFromAssetsFile(ASSETS_URL_FOLDER + "/" + url_filepath); - if(getId(provider_main_url).isEmpty()) - ProviderListContent.addItem(new ProviderItem(provider_name, provider_main_url)); - loaded_preseeded_providers = true; - } - } catch (IOException e) { - loaded_preseeded_providers = false; + + /** + * Asks ProviderAPI to download an anonymous (anon) VPN certificate. + */ + private void downloadAnonCert() { + Intent provider_API_command = new Intent(this, ProviderAPI.class); + + Bundle parameters = new Bundle(); + + parameters.putString(TYPE_OF_CERTIFICATE, ANON_CERTIFICATE); + + 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); } - return loaded_preseeded_providers; - } - - private String extractProviderMainUrlFromAssetsFile(String filepath) { - String provider_main_url = ""; - try { - InputStream input_stream_file_contents = getAssets().open(filepath); - byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; - input_stream_file_contents.read(urls_file_bytes); - String urls_file_content = new String(urls_file_bytes); - JSONObject file_contents = new JSONObject(urls_file_content); - provider_main_url = file_contents.getString(Provider.MAIN_URL); - } catch (JSONException e) { - } catch (IOException e) { + /** + * Open the new provider dialog + */ + public void addAndSelectNewProvider() { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(NewProviderDialog.TAG); + DialogFragment newFragment = NewProviderDialog.newInstance(); + newFragment.show(fragment_transaction, NewProviderDialog.TAG); } - return provider_main_url; - } - - /** - * Asks ProviderAPI to download an anonymous (anon) VPN certificate. - */ - private void downloadAnonCert() { - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - - parameters.putString(TYPE_OF_CERTIFICATE, ANON_CERTIFICATE); - - 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); - } - - /** - * Open the new provider dialog - */ - public void addAndSelectNewProvider() { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG); - if (previous_new_provider_dialog != null) { - fragment_transaction.remove(previous_new_provider_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = NewProviderDialog.newInstance(); - newFragment.show(fragment_transaction, NewProviderDialog.TAG); - } - - /** - * Open the new provider dialog with data - */ + + /** + * Open the new provider dialog with data + */ public void addAndSelectNewProvider(String main_url) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG); - if (previous_new_provider_dialog != null) { - fragment_transaction.remove(previous_new_provider_dialog); - } - - DialogFragment newFragment = NewProviderDialog.newInstance(); - Bundle data = new Bundle(); - data.putString(Provider.MAIN_URL, main_url); - newFragment.setArguments(data); - newFragment.show(fragment_transaction, NewProviderDialog.TAG); - } - - /** - * Once selected a provider, this fragment offers the user to log in, - * use it anonymously (if possible) - * or cancel his/her election pressing the back button. - * @param view - * @param reason_to_fail - */ - public void showDownloadFailedDialog(View view, String reason_to_fail) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(DownloadFailedDialog.TAG); - if (previous_provider_details_dialog != null) { - fragment_transaction.remove(previous_provider_details_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = DownloadFailedDialog.newInstance(reason_to_fail); - newFragment.show(fragment_transaction, DownloadFailedDialog.TAG); - } - - /** - * Once selected a provider, this fragment offers the user to log in, - * use it anonymously (if possible) - * or cancel his/her election pressing the back button. - * @param view - */ - public void showProviderDetails(View view) { - if(setting_up_provider) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - 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, ProviderDetailFragment.TAG); - } - } - - public void showAndSelectProvider(String provider_main_url) { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(NewProviderDialog.TAG); + + DialogFragment newFragment = NewProviderDialog.newInstance(); + Bundle data = new Bundle(); + data.putString(Provider.MAIN_URL, main_url); + newFragment.setArguments(data); + newFragment.show(fragment_transaction, NewProviderDialog.TAG); + } + + /** + * Once selected a provider, this fragment offers the user to log in, + * use it anonymously (if possible) + * or cancel his/her election pressing the back button. + * @param view + * @param reason_to_fail + */ + public void showDownloadFailedDialog(View view, String reason_to_fail) { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(DownloadFailedDialog.TAG); + + DialogFragment newFragment = DownloadFailedDialog.newInstance(reason_to_fail); + newFragment.show(fragment_transaction, DownloadFailedDialog.TAG); + } + + /** + * Once selected a provider, this fragment offers the user to log in, + * use it anonymously (if possible) + * or cancel his/her election pressing the back button. + * @param view + */ + private void showProviderDetails() { + if(setting_up_provider) { + FragmentTransaction fragment_transaction = fragment_manager.removePreviousFragment(ProviderDetailFragment.TAG); + + DialogFragment newFragment = ProviderDetailFragment.newInstance(); + newFragment.show(fragment_transaction, ProviderDetailFragment.TAG); + } + } + + public void showAndSelectProvider(String provider_main_url) { if(getId(provider_main_url).isEmpty()) - showProvider(provider_main_url); + showProvider(provider_main_url); autoSelectProvider(provider_main_url); - } - + } + private void showProvider(final String provider_main_url) { - String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); - ProviderItem added_provider = new ProviderItem(provider_name, provider_main_url); - provider_list_fragment.addItem(added_provider); - } - + String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); + ProviderItem added_provider = new ProviderItem(provider_name, provider_main_url); + provider_list_fragment.addItem(added_provider); + } + private void autoSelectProvider(String provider_main_url) { - onItemSelected(getId(provider_main_url)); - } - - /** - * Asks ProviderAPI to download a new provider.json file - * @param provider_name - * @param provider_main_url - */ - public void setUpProvider(String provider_main_url) { - Intent provider_API_command = new Intent(this, ProviderAPI.class); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider_main_url); - - provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + onItemSelected(getId(provider_main_url)); + } + + /** + * Asks ProviderAPI to download a new provider.json file + * @param provider_name + * @param provider_main_url + */ + public void setUpProvider(String provider_main_url) { + Intent provider_API_command = new Intent(this, ProviderAPI.class); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider_main_url); + + provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER); + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - startService(provider_API_command); + startService(provider_API_command); setting_up_provider = true; } @@ -527,62 +513,62 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD startService(provider_API_command); } } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item){ - switch (item.getItemId()){ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item){ + switch (item.getItemId()){ case R.id.about_leap: startActivityForResult(new Intent(this, AboutActivity.class), 0); return true; - case R.id.new_provider: - addAndSelectNewProvider(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - public void showAllProviders() { - provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG); - if(provider_list_fragment != null) - provider_list_fragment.unhideAll(); - } - - public void cancelSettingUpProvider() { - provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG); + case R.id.new_provider: + addAndSelectNewProvider(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void showAllProviders() { + provider_list_fragment = (ProviderListFragment) fragment_manager.findFragmentByTag(ProviderListFragment.TAG); + if(provider_list_fragment != null) + provider_list_fragment.unhideAll(); + } + + public void cancelSettingUpProvider() { + provider_list_fragment = (ProviderListFragment) fragment_manager.findFragmentByTag(ProviderListFragment.TAG); if(provider_list_fragment != null) { - provider_list_fragment.removeLastItem(); - } - preferences.edit().remove(Provider.KEY).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit(); - } - - @Override - public void login() { - Intent ask_login = new Intent(); + provider_list_fragment.removeLastItem(); + } + preferences.edit().remove(Provider.KEY).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit(); + } + + @Override + public void login() { + Intent ask_login = new Intent(); ask_login.putExtra(LogInDialog.TAG, LogInDialog.TAG); - setResult(RESULT_OK, ask_login); - setting_up_provider = false; - finish(); - } - - @Override - public void use_anonymously() { - setResult(RESULT_OK); - setting_up_provider = false; - finish(); - } - - public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - int update = intent.getIntExtra(ProviderAPI.CURRENT_PROGRESS, 0); - mProgressBar.setProgress(update); - } - } -} + setResult(RESULT_OK, ask_login); + setting_up_provider = false; + finish(); + } + + @Override + public void use_anonymously() { + setResult(RESULT_OK); + setting_up_provider = false; + finish(); + } + + public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + int update = intent.getIntExtra(ProviderAPI.CURRENT_PROGRESS, 0); + mProgressBar.setProgress(update); + } + } +} -- cgit v1.2.3 From e54f0cf39cce1c27b7baca77d777c7c271e4d108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 00:20:31 +0100 Subject: Don't update eip service oncreate eip. Reuse EipServiceFragment's stopEip and startEipFromScratch in Dashboard. --- .../java/se/leap/bitmaskclient/ProviderAPI.java | 3 +- .../main/java/se/leap/bitmaskclient/Dashboard.java | 63 +++++++++++----------- app/src/main/java/se/leap/bitmaskclient/EIP.java | 26 ++++----- .../se/leap/bitmaskclient/EipServiceFragment.java | 7 ++- .../java/se/leap/bitmaskclient/ProviderAPI.java | 12 ++--- 5 files changed, 56 insertions(+), 55 deletions(-) (limited to 'app/src') diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index 6445a599..07e0e2fe 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -96,7 +96,7 @@ public class ProviderAPI extends IntentService { ERRORS = "errors", UPDATE_PROGRESSBAR = "update_progressbar", CURRENT_PROGRESS = "current_progress", - TAG = "provider_api_tag" + TAG = ProviderAPI.class.getSimpleName(); ; final public static int @@ -903,7 +903,6 @@ public class ProviderAPI extends IntentService { private boolean updateVpnCertificate() { getNewCert(); - preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit(); Intent updateEIP = new Intent(getApplicationContext(), EIP.class); updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); startService(updateEIP); diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index d80755aa..3ae1d81a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -213,31 +213,35 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } } - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - JSONObject provider_json; - try { - provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); - JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); - boolean authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); - boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); - preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, allow_registered_eip); - if(allow_registered_eip) { - if(authed_eip) { - menu.findItem(R.id.login_button).setVisible(false); - menu.findItem(R.id.logout_button).setVisible(true); - } else { - menu.findItem(R.id.login_button).setVisible(true); - menu.findItem(R.id.logout_button).setVisible(false); - } - menu.findItem(R.id.signup_button).setVisible(true); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return true; + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + JSONObject provider_json; + try { + String provider_json_string = preferences.getString(Provider.KEY, ""); + if(provider_json_string.isEmpty() == false) { + provider_json = new JSONObject(provider_json_string); + JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); + boolean authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); + boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); + preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, allow_registered_eip); + + if(allow_registered_eip) { + if(authed_eip) { + menu.findItem(R.id.login_button).setVisible(false); + menu.findItem(R.id.logout_button).setVisible(true); + } else { + menu.findItem(R.id.login_button).setVisible(true); + menu.findItem(R.id.logout_button).setVisible(false); + } + menu.findItem(R.id.signup_button).setVisible(true); + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + return true; + } @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -533,16 +537,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } private void eipStop(){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_STOP_EIP); - startService(eip_intent); + EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); + eipFragment.stopEIP(); } private void eipStart() { - Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_START_EIP); - startService(eip_intent); + EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); + eipFragment.startEipFromScratch(); } protected void showProgressBar() { diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 1b34ac21..a2a06fbd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -87,7 +87,7 @@ public final class EIP extends IntentService { 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"; - public final static String TAG = "se.leap.bitmaskclient.EIP"; + public final static String TAG = EIP.class.getSimpleName(); public final static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); @@ -113,8 +113,9 @@ public final class EIP extends IntentService { super.onCreate(); context = getApplicationContext(); - - updateEIPService(); + + // Log.d(TAG, "Update EIP Service onCreate EIP"); + // updateEIPService(); } @Override @@ -130,7 +131,7 @@ public final class EIP extends IntentService { protected void onHandleIntent(Intent intent) { String action = intent.getAction(); mReceiver = intent.getParcelableExtra(RECEIVER_TAG); - + if ( action == ACTION_START_EIP ) startEIP(); else if ( action == ACTION_STOP_EIP ) @@ -319,8 +320,11 @@ public final class EIP extends IntentService { */ private void updateEIPService() { try { - eipDefinition = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, "")); - parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); + String eip_definition_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, ""); + if(eip_definition_string.isEmpty() == false) { + eipDefinition = new JSONObject(eip_definition_string); + } + parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -328,16 +332,14 @@ public final class EIP extends IntentService { if(parsedEipSerial == 0) { deleteAllVpnProfiles(); } - if (eipDefinition != null && eipDefinition.optInt("serial") > parsedEipSerial) + if (eipDefinition != null && eipDefinition.optInt("serial") >= parsedEipSerial) updateGateways(); } private void deleteAllVpnProfiles() { ProfileManager vpl = ProfileManager.getInstance(context); - VpnProfile[] profiles = (VpnProfile[]) vpl.getProfiles().toArray(new VpnProfile[vpl.getProfiles().size()]); - for (int current_profile = 0; current_profile < profiles.length; current_profile++){ - vpl.removeProfile(context, profiles[current_profile]); - } + Collection profiles = vpl.getProfiles(); + profiles.removeAll(profiles); } /** @@ -347,7 +349,6 @@ public final class EIP extends IntentService { */ private void updateGateways(){ JSONArray gatewaysDefined = null; - try { gatewaysDefined = eipDefinition.getJSONArray("gateways"); for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ @@ -361,7 +362,6 @@ public final class EIP extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } - getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 57e009dc..a7d68198 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -195,7 +195,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe eipCommand(EIP.ACTION_START_EIP); } - private void stopEIP() { + protected void stopEIP() { EIP.mIsStarting = false; View eipProgressBar = getActivity().findViewById(R.id.eipProgress); if(eipProgressBar != null) @@ -236,7 +236,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe } else if(justDecidedOnDisconnect && level == ConnectionStatus.LEVEL_CONNECTED) { EIP.lastConnectionStatusLevel = ConnectionStatus.LEVEL_NOTCONNECTED; updateState(state, logmessage, localizedResId, level); - } + } // else if(isNewLevel || level == ConnectionStatus.LEVEL_AUTH_FAILED) + // handleNewState(state, logmessage, localizedResId, level); } private void handleNewState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { @@ -248,6 +249,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe setNoServerReplyUI(localizedResId, logmessage); else if (level == ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) setServerReplyUI(state, localizedResId, logmessage); + // else if (level == ConnectionStatus.LEVEL_AUTH_FAILED) + // handleSwitchOn(); } private boolean isDisconnectedLevel(final ConnectionStatus level) { diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index 189289ec..749457e4 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -95,7 +95,7 @@ public class ProviderAPI extends IntentService { ERRORS = "errors", UPDATE_PROGRESSBAR = "update_progressbar", CURRENT_PROGRESS = "current_progress", - TAG = "provider_api_tag" + TAG = ProviderAPI.class.getSimpleName(); ; final public static int @@ -897,7 +897,6 @@ public class ProviderAPI extends IntentService { private boolean updateVpnCertificate() { getNewCert(); - preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit(); Intent updateEIP = new Intent(getApplicationContext(), EIP.class); updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); startService(updateEIP); @@ -919,7 +918,6 @@ public class ProviderAPI extends IntentService { URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE); String cert_string = downloadWithProviderCA(new_cert_string_url.toString()); - if(!cert_string.isEmpty()) { if(ConfigHelper.checkErroneousDownload(cert_string)) { String reason_to_fail = provider_json.getString(ERRORS); @@ -940,12 +938,12 @@ public class ProviderAPI extends IntentService { } } try { - RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString); - keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT ); + RSAPrivateKey key = ConfigHelper.parseRsaKeyFromString(keyString); + keyString = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT); preferences.edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit(); - X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); - certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); + X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certificateString); + certificateString = Base64.encodeToString(certificate.getEncoded(), Base64.DEFAULT); preferences.edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit(); preferences.edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit(); return true; -- cgit v1.2.3 From a137eccdde9349dc52b29fdadcb44cf317465c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 18:46:27 +0100 Subject: Gradle 2.1 and retry connection on auth-failure --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 1 + 1 file changed, 1 insertion(+) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index a2a06fbd..cf02f32f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -484,6 +484,7 @@ public final class EIP extends IntentService { cp.parseConfig(new StringReader(certSecretFromSharedPreferences())); cp.parseConfig(new StringReader("remote-cert-tls server")); cp.parseConfig(new StringReader("persist-tun")); + cp.parseConfig(new StringReader("auth-retry nointeract")); VpnProfile vp = cp.convertProfile(); //vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; mVpnProfile = vp; -- cgit v1.2.3 From 195f0bc8f11792781bb828b0ff088314de322e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 19:22:18 +0100 Subject: Rebuild profiles on versionCode 94. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 2 ++ app/src/main/java/se/leap/bitmaskclient/EIP.java | 1 + 2 files changed, 3 insertions(+) (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 3ae1d81a..547e4179 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -112,11 +112,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(versionCode) { case 91: // 0.6.0 without Bug #5999 + case 94: // 0.8.0 with if(!preferences.getString(EIP.KEY, "").isEmpty()) { Intent rebuildVpnProfiles = new Intent(getApplicationContext(), EIP.class); rebuildVpnProfiles.setAction(EIP.ACTION_REBUILD_PROFILES); startService(rebuildVpnProfiles); } + break; } } catch (NameNotFoundException e) { } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index cf02f32f..ad7552c8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -350,6 +350,7 @@ public final class EIP extends IntentService { private void updateGateways(){ JSONArray gatewaysDefined = null; try { + if(eipDefinition == null) updateEIPService(); gatewaysDefined = eipDefinition.getJSONArray("gateways"); for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ JSONObject gw = null; -- cgit v1.2.3 From 5304543ebd60778ad46123cd63142e27627fa150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 20:45:42 +0100 Subject: Update ics-openvpn to rev 906. --- app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 39 +-- .../main/java/de/blinkt/openvpn/VpnProfile.java | 62 ++++- .../blinkt/openvpn/activities/DisconnectVPN.java | 5 + .../de/blinkt/openvpn/activities/LogWindow.java | 5 + .../main/java/de/blinkt/openvpn/core/CIDRIP.java | 5 + .../java/de/blinkt/openvpn/core/ConfigParser.java | 12 +- .../blinkt/openvpn/core/DeviceStateReceiver.java | 5 + .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 5 + .../java/de/blinkt/openvpn/core/NativeUtils.java | 5 + .../java/de/blinkt/openvpn/core/NetworkSpace.java | 5 + .../de/blinkt/openvpn/core/OpenVPNManagement.java | 5 + .../de/blinkt/openvpn/core/OpenVPNService.java | 62 +++-- .../java/de/blinkt/openvpn/core/OpenVPNThread.java | 30 ++- .../openvpn/core/OpenVpnManagementThread.java | 5 + .../java/de/blinkt/openvpn/core/PRNGFixes.java | 5 + .../de/blinkt/openvpn/core/ProfileManager.java | 21 +- .../de/blinkt/openvpn/core/ProxyDetection.java | 5 + .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 7 +- .../java/de/blinkt/openvpn/core/VpnStatus.java | 5 + .../java/de/blinkt/openvpn/core/X509Utils.java | 5 + .../de/blinkt/openvpn/fragments/LogFragment.java | 5 + .../java/de/blinkt/openvpn/views/SeekBarTicks.java | 5 + .../main/res/layout-sw600dp-port/log_fragment.xml | 5 + app/src/main/res/layout-sw600dp/log_fragment.xml | 5 + app/src/main/res/layout/log_fragment.xml | 5 + app/src/main/res/layout/log_silders.xml | 5 + app/src/main/res/layout/log_window.xml | 5 + app/src/main/res/layout/vpnstatus.xml | 5 + app/src/main/res/menu/logmenu.xml | 5 + app/src/main/res/values-ca/strings-icsopenvpn.xml | 4 + app/src/main/res/values-cs/strings-icsopenvpn.xml | 11 +- app/src/main/res/values-de/strings-icsopenvpn.xml | 9 + app/src/main/res/values-es/strings-icsopenvpn.xml | 8 + app/src/main/res/values-et/strings-icsopenvpn.xml | 11 +- app/src/main/res/values-fr/strings-icsopenvpn.xml | 5 +- app/src/main/res/values-hu/strings-icsopenvpn.xml | 6 +- app/src/main/res/values-in/strings-icsopenvpn.xml | 7 +- app/src/main/res/values-it/strings-icsopenvpn.xml | 19 +- app/src/main/res/values-ja/strings-icsopenvpn.xml | 27 ++- app/src/main/res/values-ko/strings-icsopenvpn.xml | 6 +- app/src/main/res/values-nl/strings-icsopenvpn.xml | 6 +- app/src/main/res/values-no/strings-icsopenvpn.xml | 29 ++- app/src/main/res/values-pl/strings-icsopenvpn.xml | 6 +- app/src/main/res/values-pt/strings-icsopenvpn.xml | 266 +++++++++++++++------ app/src/main/res/values-ro/strings-icsopenvpn.xml | 6 +- app/src/main/res/values-ru/strings-icsopenvpn.xml | 4 + app/src/main/res/values-sv/strings-icsopenvpn.xml | 6 +- app/src/main/res/values-tr/strings-icsopenvpn.xml | 7 +- app/src/main/res/values-uk/strings-icsopenvpn.xml | 6 +- .../main/res/values-zh-rCN/strings-icsopenvpn.xml | 12 +- .../main/res/values-zh-rTW/strings-icsopenvpn.xml | 57 +++-- app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings-icsopenvpn.xml | 7 +- app/src/main/res/values/styles.xml | 18 +- app/src/main/res/values/untranslatable.xml | 20 ++ 55 files changed, 702 insertions(+), 209 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index a424a489..d7f3e110 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn; import se.leap.bitmaskclient.R; @@ -113,27 +118,25 @@ public class LaunchVPN extends Activity { } } - @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if(requestCode==START_VPN_PROFILE) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - boolean showlogwindow = prefs.getBoolean("showlogwindow", true); - - if(!mhideLog && showlogwindow) - showLogWindow(); - new startOpenVpnThread().start(); - } else if (resultCode == Activity.RESULT_CANCELED) { - // User does not want us to start, so we just vanish - VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, - ConnectionStatus.LEVEL_NOTCONNECTED); - - finish(); - } + super.onActivityResult(requestCode, resultCode, data); + + if(requestCode==START_VPN_PROFILE) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean showLogWindow = prefs.getBoolean("showlogwindow", true); + + if(!mhideLog && showLogWindow) + showLogWindow(); + new startOpenVpnThread().start(); + } else if (resultCode == Activity.RESULT_CANCELED) { + // User does not want us to start, so we just vanish + VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); + + finish(); + } } - void showLogWindow() { Intent startLW = new Intent(getBaseContext(),LogWindow.class); diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index 6fec5f46..65214c4f 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn; import se.leap.bitmaskclient.R; @@ -40,6 +45,7 @@ import java.util.Collection; import java.util.Locale; import java.util.UUID; import java.util.Vector; +import java.util.concurrent.Future; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -166,6 +172,12 @@ public class VpnProfile implements Serializable { return VpnProfile.MININONPIEVPN; } + public static String[] replacePieWithNoPie(String[] mArgv) + { + mArgv[0] = mArgv[0].replace(MINIPIEVPN, MININONPIEVPN); + return mArgv; + } + public static String openVpnEscape(String unescaped) { if (unescaped == null) return null; @@ -174,7 +186,8 @@ public class VpnProfile implements Serializable { escapedString = escapedString.replace("\n", "\\n"); if (escapedString.equals(unescaped) && !escapedString.contains(" ") && - !escapedString.contains("#") && !escapedString.contains(";")) + !escapedString.contains("#") && !escapedString.contains(";") + && !escapedString.equals("")) return unescaped; else return '"' + escapedString + '"'; @@ -579,21 +592,15 @@ public class VpnProfile implements Serializable { - public Intent prepareIntent(Context context) { - String prefix = context.getPackageName(); + public Intent prepareStartService(Context context) { + Intent intent = getStartServiceIntent(context); - Intent intent = new Intent(context, OpenVPNService.class); if (mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { if (getKeyStoreCertificates(context) == null) return null; } - intent.putExtra(prefix + ".ARGV", buildOpenvpnArgv(context.getCacheDir())); - intent.putExtra(prefix + ".profileUUID", mUuid.toString()); - - ApplicationInfo info = context.getApplicationInfo(); - intent.putExtra(prefix + ".nativelib", info.nativeLibraryDir); try { FileWriter cfg = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); @@ -607,6 +614,18 @@ public class VpnProfile implements Serializable { return intent; } + public Intent getStartServiceIntent(Context context) { + String prefix = context.getPackageName(); + + Intent intent = new Intent(context, OpenVPNService.class); + intent.putExtra(prefix + ".ARGV", buildOpenvpnArgv(context.getCacheDir())); + intent.putExtra(prefix + ".profileUUID", mUuid.toString()); + + ApplicationInfo info = context.getApplicationInfo(); + intent.putExtra(prefix + ".nativelib", info.nativeLibraryDir); + return intent; + } + public String[] getKeyStoreCertificates(Context context) { return getKeyStoreCertificates(context, 5); } @@ -635,6 +654,21 @@ public class VpnProfile implements Serializable { return false; } + public void checkForRestart(final Context context) { + /* This method is called when OpenVPNService is restarted */ + + if ((mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) + && mPrivateKey==null) { + new Thread( new Runnable() { + @Override + public void run() { + getKeyStoreCertificates(context); + + } + }).start(); + } + } + class NoCertReturnedException extends Exception { public NoCertReturnedException (String msg) { @@ -841,21 +875,23 @@ public class VpnProfile implements Serializable { return false; } - public int needUserPWInput() { + public int needUserPWInput(boolean ignoreTransient) { if ((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) && (mPKCS12Password == null || mPKCS12Password.equals(""))) { - if (mTransientPCKS12PW == null) + if (ignoreTransient || mTransientPCKS12PW == null) return R.string.pkcs12_file_encryption_key; } if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) { if (requireTLSKeyPassword() && TextUtils.isEmpty(mKeyPassword)) - if (mTransientPCKS12PW == null) { + if (ignoreTransient || mTransientPCKS12PW == null) { return R.string.private_key_password; } } - if (isUserPWAuth() && !(!TextUtils.isEmpty(mUsername) && (!TextUtils.isEmpty(mPassword) || mTransientPW != null))) { + if (isUserPWAuth() && + (TextUtils.isEmpty(mUsername) || + (TextUtils.isEmpty(mPassword) && (mTransientPW == null || ignoreTransient)))) { return R.string.password; } return 0; diff --git a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java index 5910173a..e6b73a48 100644 --- a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.activities; import android.app.Activity; diff --git a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java index 7ed09dd2..5e4f9517 100644 --- a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java +++ b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.activities; import android.app.Activity; diff --git a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java index 960e7d11..ac9a8ccb 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java +++ b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.util.Locale; diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 9c3621e0..0d8230b7 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.io.BufferedReader; @@ -553,8 +558,13 @@ public class ConfigParser { noauthtypeset=false; } + Vector cryptoapicert = getOption("cryptoapicert",1,1); + if(cryptoapicert!=null) { + np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; + noauthtypeset=false; + } - Vector compatnames = getOption("compat-names",1,2); + Vector compatnames = getOption("compat-names",1,2); Vector nonameremapping = getOption("no-name-remapping",1,1); Vector tlsremote = getOption("tls-remote",1,1); if(tlsremote!=null){ diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java index 0126d08e..0d75ae51 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.BroadcastReceiver; diff --git a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java index 485e5369..83e760ca 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.app.Application; diff --git a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java index a2c4796d..6d7ffdf2 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.security.InvalidKeyException; diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java index 8c6cb1f5..35f46513 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.os.Build; diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java index a5a3e9f4..e90c16d1 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; public interface OpenVPNManagement { diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 743e7cc5..ada065ba 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.Manifest.permission; @@ -19,6 +24,7 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; import android.text.TextUtils; +import android.util.Log; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -309,26 +315,32 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac return START_REDELIVER_INTENT; } - String UUID = "UUID"; + /* The intent is null when the service has been restarted */ if (intent == null) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - android.util.Log.d("bitmaskclient", "UUID is " + prefs.getString(UUID, "")); - mProfile = ProfileManager.get(this, prefs.getString(UUID, "")); - android.util.Log.d("bitmaskclient", "mProfile is null? " + (mProfile == null)); - if(mProfile != null) - intent = mProfile.prepareIntent(getBaseContext()); - else + mProfile = ProfileManager.getLastConnectedProfile(this, false); + + /* Got no profile, just stop */ + if (mProfile==null) { + Log.d("OpenVPN", "Got no last connected profile on null intent. Stopping"); + stopSelf(startId); return START_NOT_STICKY; - } - if(mProfile != null) - android.util.Log.d("bitmaskclient", "mProfile != null"); + } + /* Do the asynchronous keychain certificate stuff */ + mProfile.checkForRestart(this); + + /* Recreate the intent */ + intent = mProfile.getStartServiceIntent(this); + + } else { + String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID"); + mProfile = ProfileManager.get(this, profileUUID); + } + + // Extract information from the intent. String prefix = getPackageName(); String[] argv = intent.getStringArrayExtra(prefix + ".ARGV"); - String nativelibdir = intent.getStringExtra(prefix + ".nativelib"); - String profileUUID = intent.getStringExtra(prefix + ".profileUUID"); - - mProfile = ProfileManager.get(this, profileUUID); + String nativeLibraryDirectory = intent.getStringExtra(prefix + ".nativelib"); String startTitle = getString(R.string.start_vpn_title, mProfile.mName); String startTicker = getString(R.string.start_vpn_ticker, mProfile.mName); @@ -361,13 +373,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // Start a new session by creating a new thread. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - + mOvpn3 = prefs.getBoolean("ovpn3", false); if (!"ovpn3".equals(BuildConfig.FLAVOR)) mOvpn3 = false; - prefs.edit().putString(UUID, profileUUID).commit(); // Open the Management Interface if (!mOvpn3) { @@ -395,7 +406,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } else { HashMap env = new HashMap(); - processThread = new OpenVPNThread(this, argv, env, nativelibdir); + processThread = new OpenVPNThread(this, argv, env, nativeLibraryDirectory); } synchronized (mProcessLock) { @@ -409,11 +420,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac ProfileManager.setConnectedVpnProfile(this, mProfile); + /* TODO: At the moment we have no way to handle asynchronous PW input + * Fixing will also allow to handle challenge/responsee authentication */ + if (mProfile.needUserPWInput(true) != 0) + return START_NOT_STICKY; - if (mProfile.mPersistTun) - return START_STICKY; - else - return START_NOT_STICKY; + return START_STICKY; } private OpenVPNManagement instantiateOpenVPN3Core() { @@ -517,7 +529,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if ((Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !release.startsWith("4.4.3") && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6")) && mMtu < 1280) { - VpnStatus.logInfo(String.format("Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", mMtu)); + VpnStatus.logInfo(String.format(Locale.US, "Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", mMtu)); builder.setMtu(1280); } else { builder.setMtu(mMtu); @@ -690,7 +702,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.logWarning(R.string.ip_not_cidr, local, netmask, mode); } } - if (("p2p".equals(mode)) && mLocalIP.len < 32 || "net30".equals("net30") && mLocalIP.len < 30) { + if (("p2p".equals(mode) && mLocalIP.len < 32) || ("net30".equals(mode) && mLocalIP.len < 30)) { VpnStatus.logWarning(R.string.ip_looks_like_subnet, local, netmask, mode); } @@ -738,7 +750,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac String ticker = msg; showNotification(msg, ticker, lowpriority , 0, level); return; - } else { + } else { mDisplayBytecount = false; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java index 5fa2ab9e..e3c60854 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.util.Log; @@ -25,6 +30,7 @@ import de.blinkt.openvpn.core.VpnStatus.LogItem; public class OpenVPNThread implements Runnable { private static final String DUMP_PATH_STRING = "Dump path: "; + private static final String BROKEN_PIE_SUPPORT = "/data/data/de.blinkt.openvpn/cache/pievpn[1]: syntax error:"; private static final String TAG = "OpenVPN"; public static final int M_FATAL = (1 << 4); public static final int M_NONFATAL = (1 << 5); @@ -36,8 +42,9 @@ public class OpenVPNThread implements Runnable { private OpenVPNService mService; private String mDumpPath; private Map mProcessEnv; + private boolean mBrokenPie=false; - public OpenVPNThread(OpenVPNService service,String[] argv, Map processEnv, String nativelibdir) + public OpenVPNThread(OpenVPNService service,String[] argv, Map processEnv, String nativelibdir) { mArgv = argv; mNativeDir = nativelibdir; @@ -68,8 +75,22 @@ public class OpenVPNThread implements Runnable { } catch (InterruptedException ie) { VpnStatus.logError("InterruptedException: " + ie.getLocalizedMessage()); } - if( exitvalue != 0) - VpnStatus.logError("Process exited with exit value " + exitvalue); + if( exitvalue != 0) { + VpnStatus.logError("Process exited with exit value " + exitvalue); + if (mBrokenPie) { + String[] noPieArgv = VpnProfile.replacePieWithNoPie(mArgv); + + // We are already noPIE, nothing to gain + if (!noPieArgv.equals(mArgv)) { + mArgv = noPieArgv; + VpnStatus.logInfo("PIE Version could not be executed. Trying no PIE version"); + run(); + return; + } + + } + + } VpnStatus.updateStateString("NOPROCESS", "No process running.", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); if(mDumpPath!=null) { @@ -123,6 +144,9 @@ public class OpenVPNThread implements Runnable { if (logline.startsWith(DUMP_PATH_STRING)) mDumpPath = logline.substring(DUMP_PATH_STRING.length()); + + if (logline.startsWith(BROKEN_PIE_SUPPORT)) + mBrokenPie = true; // 1380308330.240114 18000002 Send to HTTP proxy: 'X-Online-Host: bla.blabla.com' diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index e200f210..37094a1b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.Context; diff --git a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java index dd420371..bca0a4ab 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java +++ b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core;/* * This software is provided 'as-is', without any express or implied * warranty. In no event will Google be held liable for any damages diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java index 4cfbcc8e..2a26152e 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.io.FileNotFoundException; @@ -23,7 +28,7 @@ public class ProfileManager { - private static final String ONBOOTPROFILE = "onBootProfile"; + private static final String LAST_CONNECTED_PROFILE = "lastConnectedProfile"; @@ -65,7 +70,7 @@ public class ProfileManager { public static void setConntectedVpnProfileDisconnected(Context c) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); Editor prefsedit = prefs.edit(); - prefsedit.putString(ONBOOTPROFILE, null); + prefsedit.putString(LAST_CONNECTED_PROFILE, null); prefsedit.apply(); } @@ -74,21 +79,23 @@ public class ProfileManager { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); Editor prefsedit = prefs.edit(); - prefsedit.putString(ONBOOTPROFILE, connectedrofile.getUUIDString()); + prefsedit.putString(LAST_CONNECTED_PROFILE, connectedrofile.getUUIDString()); prefsedit.apply(); mLastConnectedVpn=connectedrofile; } - public static VpnProfile getOnBootProfile(Context c) { + public static VpnProfile getLastConnectedProfile(Context c, boolean onBoot) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false); + if (onBoot && !useStartOnBoot) + return null; - String mBootProfileUUID = prefs.getString(ONBOOTPROFILE,null); - if(useStartOnBoot && mBootProfileUUID!=null) - return get(c, mBootProfileUUID); + String lastConnectedProfile = prefs.getString(LAST_CONNECTED_PROFILE, null); + if(lastConnectedProfile!=null) + return get(c, lastConnectedProfile); else return null; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java index 47d88279..cf953863 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.net.InetSocketAddress; diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java index 57a94ee7..40f9742b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.Context; @@ -70,7 +75,7 @@ public class VPNLaunchHelper { VpnStatus.logInfo(R.string.building_configration); - Intent startVPN = startprofile.prepareIntent(context); + Intent startVPN = startprofile.prepareStartService(context); if(startVPN!=null) context.startService(startVPN); diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index c19daeb0..25558f13 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.annotation.SuppressLint; diff --git a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java index 35e53c08..ff383e0f 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.Context; diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index ca850533..77fc21e6 100644 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.fragments; import se.leap.bitmaskclient.R; diff --git a/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java b/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java index 88e8e164..e25c2859 100644 --- a/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java +++ b/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.views; import android.content.Context; diff --git a/app/src/main/res/layout-sw600dp-port/log_fragment.xml b/app/src/main/res/layout-sw600dp-port/log_fragment.xml index ddf0506b..2f5c774d 100644 --- a/app/src/main/res/layout-sw600dp-port/log_fragment.xml +++ b/app/src/main/res/layout-sw600dp-port/log_fragment.xml @@ -1,4 +1,9 @@ + + + + + + + + + + + diff --git a/app/src/main/res/menu/logmenu.xml b/app/src/main/res/menu/logmenu.xml index c8c9e815..a1d2a7b5 100644 --- a/app/src/main/res/menu/logmenu.xml +++ b/app/src/main/res/menu/logmenu.xml @@ -1,4 +1,9 @@ + + diff --git a/app/src/main/res/values-ca/strings-icsopenvpn.xml b/app/src/main/res/values-ca/strings-icsopenvpn.xml index 7e74c198..b18766ca 100755 --- a/app/src/main/res/values-ca/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ca/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ + diff --git a/app/src/main/res/values-cs/strings-icsopenvpn.xml b/app/src/main/res/values-cs/strings-icsopenvpn.xml index b13bfcdd..6ae5a3f0 100755 --- a/app/src/main/res/values-cs/strings-icsopenvpn.xml +++ b/app/src/main/res/values-cs/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + @@ -319,4 +323,9 @@ Některé soubory nemohly být nalezeny. Prosím vyber profil, který chceš importovat: Pro používání této aplikace je potřeba VPN poskytovatel/brána, která podporuje OpenVPN (často je to zaměstnavatel). Pro více informací a návod na nastavení OpenVPN serveru navštiv http://community.openvpn.net/ Import logu: + Vpn topologie \"%3$s\" soecifikována, ale ifconfig %1$s %2$s vypadá spíše jako IP adresa se síťovou maskou. Předpokládám \"podsíťovou\" topologii. + mssfix hodnota musí být celé číslo mezi 0 a 9000 + Oznámit TCP sezením běžícím skrze tunel, že mají limitovat velikost odesílaných paketů tak, aby poté, co je OpenVPN zabalí, byla výsledná velikost UDP paketu, které OpenVPN posílá menší než tento počet bytů. (výchozí je 1450) + Přepsat hodnotu MSS pro TCP obsah + Nastavit MSS pro TCP obsah diff --git a/app/src/main/res/values-de/strings-icsopenvpn.xml b/app/src/main/res/values-de/strings-icsopenvpn.xml index 5ece9326..cebb9646 100755 --- a/app/src/main/res/values-de/strings-icsopenvpn.xml +++ b/app/src/main/res/values-de/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ + @@ -319,4 +323,9 @@ Einige Dateien konnten nicht gefunden werden. Bitte wählen Sie diese manuell aus: Um diese Anwendung nutzen zu können brauchen Sie einen OpenVPN fähigen Server. Diese werden häufig von Ihrer Firma oder Universität bereitgestellt. Besuchen Sie http://community.openvpn.net/ um mehr über OpenVPN zu erfahren und wie Sie Ihren eigenen Server aufsetzen können. Import-Protokoll: + VPN-Topologie \"%3$s\" wurde angegeben, die Interface Konfiguration \'ifconfig %1$s %2$s sieht wie eine IP-Adresse mit einer Netzwerkmaske. Topologie \"subnet\" wird angenommen. + mssfix Wert muss eine Zahl zwischen 0 und 9000 sein + Ändere TCP-Verbindungen, die über den Tunnel laufen, so dass die resultierende UDP-Paketgröße nach der Enkapsulierung durch OpenVPN auf diesen Wert beschränkt bleibt. (Standardwert ist 1450) + Überschreiben des MSS-Wert von TCP-Nutzlast + Setze MSS von TCP-Nutzlast diff --git a/app/src/main/res/values-es/strings-icsopenvpn.xml b/app/src/main/res/values-es/strings-icsopenvpn.xml index 399392bf..92995c6f 100755 --- a/app/src/main/res/values-es/strings-icsopenvpn.xml +++ b/app/src/main/res/values-es/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ + @@ -319,4 +323,8 @@ Algunos archivos no se pudo encontrar. Por favor, seleccione los archivos que desea importar el perfil: Para utilizar esta aplicación usted necesita un proveedor de servicio VPN / es un apoyo OpenVPN (a menudo proporcionados por su empleador). Echa un vistazo a http://community.openvpn.net/ para más información sobre OpenVPN y cómo configurar su propio servidor OpenVPN. Importar registros: + Topología de VPN \"%3$s\" especificado pero ifconfig %1$s %2$s se parece más a una dirección IP con una máscara de red. Asumiendo una topología de \"subred\". + El valor de mssfix debe ser un número entero entre 0 y 9000 + Reemplazar el valor MSS de la carga TCP + Establecer MSS de la carga TCP diff --git a/app/src/main/res/values-et/strings-icsopenvpn.xml b/app/src/main/res/values-et/strings-icsopenvpn.xml index 478483ec..7761726e 100755 --- a/app/src/main/res/values-et/strings-icsopenvpn.xml +++ b/app/src/main/res/values-et/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + @@ -319,4 +323,9 @@ Mõningaid faile ei leitud. Palun valige importimiseks profiili failid: Selle rakenduse kasutamiseks vajate OpenVPN toega VPN teenusepakkujat/VPN lüüsi (mida sageli pakub teie tööandja). Lisainfo saamiseks OpenVPN kohta ja oma isikliku OpenVPN serveri seadistamise kohta tutvuge veebilehega http://community.openvpn.net/ . Impordi logi: + Valitud on \"%3$s\" Vpn topoloogia, kuid ifconfig %1$s %2$s sarnaneb rohkem maskiga IP aadressile. Määratakse \"alamvõrgu\" topoloogia. + mssfix väärtus peab olema täisarv vahemikus 0 kuni 9000 + Informeeri tunneldatud TCP sessioone et nad piiraksid saadetavate pakettide suuruse nii, et peale OpenVPN kapseldatud paketi partnerile saatmist ei oleks saadud UDP pakett suurem kui ette antud baitide arv. (vaikeväärtus on 1450) + Ignoreeri TCP lasti MSS väärtust + Sea TCP lasti MSS väärtus diff --git a/app/src/main/res/values-fr/strings-icsopenvpn.xml b/app/src/main/res/values-fr/strings-icsopenvpn.xml index a26ce445..15bc7aa4 100755 --- a/app/src/main/res/values-fr/strings-icsopenvpn.xml +++ b/app/src/main/res/values-fr/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ + @@ -216,7 +220,6 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces "Utilisez l\'icône <img src=\"ic_menu_archive\"/> pour importer un fichier profil (.opvpn ou .conf) de votre carte SD." "Veillez également à consulter la FAQ. Il s\'y trouve un guide de démarrage rapide." "Redirections / Configuration de l\'interface" - The Routing and interface configuration is not done via traditional ifconfig/route commands but by using the VPNService API. This results in a different routing configuration than on other OSes. The configuration for the VPN tunnel consists of the IP address and the networks that should be routed over this interface. Especially no peer partner address or gateway address is needed. Special routes to reach the VPN Server (for example added when using redirect-gateway) are not needed either. The application will consequently ignore these settings when importing a configuration. The app ensures with the VPNService API that the connection to the server is not routed through the VPN tunnel. Only specifying networks to be routed via tunnel is supported. The app tries to detect networks that should not be routed over tunnel (e.g. route x.x.x.x y.y.y.y net_gateway) and calculates a route set that excludes this routes to emulate the behaviour of other platforms. The log windows shows the configuration of the VPNService upon establishing a connection. Ne pas couper la connexion VPN lors de la reconnexion d\'OpenVPN. Persistance de l\'interface TUN Log OpenVPN diff --git a/app/src/main/res/values-hu/strings-icsopenvpn.xml b/app/src/main/res/values-hu/strings-icsopenvpn.xml index 99c5201f..504ab893 100755 --- a/app/src/main/res/values-hu/strings-icsopenvpn.xml +++ b/app/src/main/res/values-hu/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-in/strings-icsopenvpn.xml b/app/src/main/res/values-in/strings-icsopenvpn.xml index ccb60754..c111cbb5 100755 --- a/app/src/main/res/values-in/strings-icsopenvpn.xml +++ b/app/src/main/res/values-in/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + @@ -85,6 +89,7 @@ Gunakan rute standar Masukkan rute butan sendiri. Masukkan tujuan dalam format CIDR. \"10.0.0.0/8 2002:: / 16\" akan mengarahkan jaringan 10.0.0.0/8 dan 2002:: / 16 melalui jaringan VPN Rute buatan sendiri + Jaringan Dikecualikan Tingkat rincian catatan Ijinkan paket terotentifikasi dari semua IP Ijinkan server mengambang diff --git a/app/src/main/res/values-it/strings-icsopenvpn.xml b/app/src/main/res/values-it/strings-icsopenvpn.xml index 61d09818..29d48904 100755 --- a/app/src/main/res/values-it/strings-icsopenvpn.xml +++ b/app/src/main/res/values-it/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + @@ -86,6 +90,7 @@ Inserisci instradamenti personalizzati. Usare il formato CIDR. \"10.0.0.0/8 2002::/16\" reindirizza le reti 10.0.0.0/8 e 2002::/16 sulla VPN. Itinerari che dovrebbero non essere instradati su VPN. Utilizzare la stessa sintassi per quanto riguarda le rotte incluse. Routing personalizzati + Reti escluse Livello di dettaglio del registro Permette pacchetti autenticati da qualsiasi IP (consente che l\'IP del server possa cambiare) Modalità float @@ -99,6 +104,9 @@ Apertura interfaccia tun in corso: Indirizzi locali - IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d DNS Server: %1$s, Dominio: %2$s + Instradamenti: %1$s %2$s + Instradamenti esclusi: %1$s %2$s + Instradamenti VpnService installati: %1$s %2$s Ottenute le informazioni sulle interfacce %1$s e %2$s, assumendo che il secondo indirizzo sia il peer remoto. Utilizzata la maschera /32 per l\'IP locale. La modalità impostata da OpenVPN è \"%3$s\". Impossibile utilizzare %1$s e %2$s come reindirizzamenti IP con la maschera CIDR, è stata quindi usata la maschera /32. Instradamento %1$s/%2$s corretto con %3$s/%2$s @@ -213,6 +221,7 @@ Effettuata la lettura del file di configurazione Usa l\'icona <img src=\"ic_menu_archive\"/> per importare il profilo (.ovpn o .conf) dalla tua scheda SD. Si raccomanda di leggere anche le FAQ. C\'è anche una guida rapida. Configurazione dei reindirizzamenti e dell\'interfaccia + Il routing e la configurazione dell\'interfaccia non vengono fatti tramite i comandi ifconfig/route tradizionali ma utilizzando l\'API VPNService. Ciò si traduce in una configurazione di routing diversa rispetto ad altri sistemi operativi. La configurazione del tunnel VPN è composta dall\'indirizzo IP e dalle reti che devono essere instradate su tale interfaccia. Soprattutto non è necessario alcun indirizzo peer o gateway. Percorsi speciali per raggiungere il server VPN (ad esempio aggiunti quando si utilizza redirect-gateway) non sono neanche necessari. L\'applicazione pertanto ignorerà queste impostazioni durante l\'importazione di una configurazione. L\'applicazione garantisce con l\'API VPNService che la connessione al server non venga instradata attraverso il tunnel VPN. E\' supportato solo la specifica delle reti che devono essere instradate tramite il tunnel. L\'applicazione cerca di rilevare le reti che non devono essere instradate sul tunnel (ad esempio, route x.x.x.x y.y.y.y net_gateway) e calcola una serie di itinerari che escludono questi percorsi per emulare il comportamento di altre piattaforme. Le schermate del registro mostrano la configurazione del VPNService finché si stabilisce una connessione. Non passa allo stato di \"Nessuna connessione VPN\" quando OpenVPN sta eseguendo un tentativo di riconnessione. tun persistente Log di OpenVPN @@ -307,5 +316,13 @@ Effettuata la lettura del file di configurazione Visualizza opzioni Eccezione non gestita: %1$s\n\n%2$s %3$s: %1$s\n\n%2$s + Se il tuo dispositivo Android ha il root allora è possibile installare il <a href=\"http://xposed.info/\">framework Xposed</a> e il <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">modulo di conferma VPN Dialog</a> a proprio rischio e pericolo\" Licenze complete + Le reti direttamente collegate alle interfacce locali non verranno instradate attraverso la VPN. Deselezionando questa opzione si inoltrerà tutto il traffico dalle reti locali alla VPN. + Ignora VPN per le reti locali + File nome utente/password + [Importato da: %s] + Alcuni file non possono essere trovati. Si prega di selezionare i file da importare nel profilo: + Per utilizzare questa applicazione è necessario un provider VPN/gateway VPN che supportino OpenVPN (spesso forniti dal datore di lavoro). Vai a http://community.openvpn.net/ per ulteriori informazioni su OpenVPN e come configurare il proprio server OpenVPN. + Registro importazione: diff --git a/app/src/main/res/values-ja/strings-icsopenvpn.xml b/app/src/main/res/values-ja/strings-icsopenvpn.xml index d537e3d8..79474f2d 100755 --- a/app/src/main/res/values-ja/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ja/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ + @@ -23,7 +27,7 @@ プロファイル 種別 PKCS12のパスワード - 選択 + 選択… ファイルを選択する必要があります。 TLS認証を使用します。 TLS Direction @@ -99,7 +103,7 @@ DNSサーバ: %1$s, ドメイン: %2$s 経路: %1$s %2$s 除外された経路: %1$s %2$s - インターフェース情報として[%1$s]と[%2$s]を取得しました。2つめのアドレスはリモート側のピアアドレスです。32ビットマスクをローカルIPに使用します。 OpenVPNのモードは[%3$s]です。 + インターフェース情報として %1$s と %2$s を取得しました。2つ目のアドレスはリモート側のピアアドレスです。32ビットマスクをローカルIPに使用します。 OpenVPNのモードは \"%3$s\" です。 %1$sと%2$sではCIDR形式のIP経路情報として意味をなしません。32ビットマスクを使用します。 経路情報%1$s/%2$sを%3$s/%2$sに修正しました。 Androidの証明書管理にアクセスできません。(ファームウェアの更新、アプリケーションまたはその設定のリストアによって発生する場合があります)。VPNの設定で証明書の選択を再度行ってください。 @@ -107,12 +111,11 @@ ログ ファイルを送信します。 送信 ICS OpenVPN ログ ファイル - クリップ ボードにコピーされたログ エントリ + ログ エントリをクリップボードにコピーしました TAPモード TAPモードは非root化環境では動作しません。よってこのアプリケーションではTAPをサポートできません。 またですか?TAPモードはサポートされていませんし、サポートされるかどうかメールを送ることは何の役にも立ちません。 - 3回目です。本当のところ、TUN上で動くレイヤ2エミュレータを書くことはできました。(送信時の情報追加と受信時の情報削除で)。しかしこのエミュレータはARPやおそらくはDHCPをも実装しなければならないでしょう。誰もこのことに気がついていません。もしあなたがこの機能を作る気になったのであれば、どうぞ私に連絡してください。 - + 3回目です。本当のところ、TUN上で動くレイヤ2エミュレータを書くことはできました。(送信時の情報追加と受信時の情報削除で)。しかしこのエミュレータはARPやおそらくはDHCPをも実装しなければならないでしょう。誰もこのことに気がついていません。もしあなたがこの機能を作る気になったのであれば、どうぞ私に連絡してください。 よくある質問 ログ エントリのコピー 1行のログエントリをコピーするには、そのエントリをタッチし続けます。コピー/送信するには「ログエントリを送信」を使用します。GUIで表示されない場合はハードウェアのメニューボタンを使用してください。 @@ -138,7 +141,7 @@ インポートされた構成ファイルに記載されたファイル %1$s が見つかりません。 構成ファイルを%1$sからインポートしています。 ユーザインターフェースにマッピングされていないいくつかの設定項目があります。それらの設定はカスタムオプションとして追加されます。カスタムオプションを以下に表示します。 - 構成ファイルの読み取り終了。 + 構成ファイルの読み込みを完了しました。 ローカル アドレスとポートにバインドを行いません。 ローカルバインドしない 構成ファイルのインポート @@ -200,8 +203,7 @@ Androidはあなた自身の安全性のために、これらを迂回できな <p>もしファイルが足りないというエラーが表示されたら、足りなかったファイルをSDカード上に格納してください。</p> <p>インポートされたVPN設定をリストに追加するには、保存アイコンをクリックします。</p> <p>VPNを接続するには、VPNの名称をクリックします。</p> -<p>もし警告やエラーがログエントリに表示されたら、それらを調べて解決してください。</p> - +<p>もし警告やエラーがログエントリに表示されたら、それらを調べて解決してください。</p> クイックスタート 接続の試行前にTUNデバイスモジュール(tun.ko)を読み込みます。デバイスのroot化が必要です。 TUNモジュールをロード @@ -217,8 +219,7 @@ Androidはあなた自身の安全性のために、これらを迂回できな 再起動 設定の変更はVPNの再起動後に反映されます。VPNを(再)起動しますか? 設定が変更されました - 編集されたため、最後に接続したプロファイルを確認できませんでした - + 編集されたため、最後に接続したプロファイルを確認できませんでした 重複した通知 もしAndroidがメモリ不足に陥った場合、その時点で必要とされないアプリケーションやサービスはアクティブなメモリから排除されます。 この処理に伴い、VPN接続は終了されます。 @@ -292,7 +293,7 @@ OpenVPNの接続を保証するためには、アプリケーションを高い 許可アプリ: %s 許可アプリの一覧をクリアしますか?\n現在の許可アプリ一覧:\n\n%s スクリーンがオフかつ60秒で64kB以下のデータ転送量の場合、VPN通信を中断します。「永続的なTUN」設定が有効な場合、VPN接続が中断されると通信ができなくなります。「永続的なTUN」を無効にすると、VPNによる接続保護は行われなくなります。 - 画面オフ後にVPN接続を中断する + 画面オフ後にVPN接続を中断 警告: このVPN接続には永続的なTUNが設定されていません。スクリーンオフ後の通信は通常のインターネット接続を使用します。 パスワードを保存 VPN一時停止 @@ -322,10 +323,10 @@ OpenVPNの接続を保証するためには、アプリケーションを高い 未処理の例外: %1$s\n\n%2$s %3$s: %1$s\n\n%2$s もしあなたがデバイスをroot化しているのであれば、 <a href=\"http://xposed.info/\">Xposed framework</a>と<a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm module</a> を自己責任においてインストールできます - フルライセンス + 完全なライセンス告知 ローカルインターフェイスに直接接続されているネットワークはVPNを経由しません。 このオプションを外すとローカルネットワーク宛のすべての通信をVPNにリダイレクトします。 - ローカルネットワークはVPNを経由しない + ローカルはVPNを経由しない ユーザー名/パスワードファイル [インポート元: %s] いくつかのファイルが見つかりませんでした。プロファイルをインポートするファイルを選択してください: diff --git a/app/src/main/res/values-ko/strings-icsopenvpn.xml b/app/src/main/res/values-ko/strings-icsopenvpn.xml index cd8bc176..b05e4f51 100755 --- a/app/src/main/res/values-ko/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ko/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-nl/strings-icsopenvpn.xml b/app/src/main/res/values-nl/strings-icsopenvpn.xml index f553449b..2a000195 100755 --- a/app/src/main/res/values-nl/strings-icsopenvpn.xml +++ b/app/src/main/res/values-nl/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-no/strings-icsopenvpn.xml b/app/src/main/res/values-no/strings-icsopenvpn.xml index 7a7dd124..66391eb5 100755 --- a/app/src/main/res/values-no/strings-icsopenvpn.xml +++ b/app/src/main/res/values-no/strings-icsopenvpn.xml @@ -1,11 +1,16 @@ - + + Server adresse: Server port: Plassering + Kan ikke lese katalogen velg Avbryt Ingen Data @@ -15,32 +20,54 @@ Klientsertifikat nøkkel PKCS12 fil CA-sertifikat + Du må velge et sertifikat + Kildekode og problemsøkersporing er tilgjengelig på http://code.google.com/p/ics-openvpn/ + Dette programmet bruker følgende komponenter; se kildekoden for detaljer om lisensene Om + Profiler Type PKCS12 passord Velg… + Du må velge en fil Bruke TLS-godkjenning TLS-retning Angi IPv6-adresse/nettmaske i CIDR format (f.eks 2000:dd::23/64) Angi IPv6-adresse/nettmaske i CIDR format (f.eks 1.2.3.4/24) IPv4-adresse IPv6-adresse + Angi egendefinerte OpenVPN-alternativer. Bør brukes med forsiktighet. Vær også oppmerksom på at mange av de tun-relaterte OpenVPN-innstillingene ikke støttes i henhold til utformingen av VPNSettings. Hvis du tror at et viktig alternativ mangler kan du kontakte forfatteren Brukernavn Passord + For den statiske konfigurasjonen vil TLS Auth Keys-ene bli brukt som statiske nøkler Konfigurer VPN Legge til profil Angi et navn som identifiserer den nye profilen + Skriv inn et unikt profilnavn Profilnavn + Du må velge et brukersertifikat Ingen feil funnet Feil i konfigurasjonen + Feil ved analyse av IPv4-adressen + Feil ved analyse av egendefinerte ruter + (La stå tomt for å søke på forespørsel) OpenVPN snarvei Koble til VPN + Profilen som er angitt i snarveien ble ikke funnet Tilfeldig vert prefiks + Legger til 6 tilfeldige tegn foran vertsnavn Aktiver egendefinerte valg + Angi egendefinerte alternativer. Brukes med forsiktighet! + Route avvist av Android Koble fra + Koble fra VPN Tøm logg Avbryt bekreftelse + Koble fra tilkoblet VPN-forbindelse / avbryt oppkoblingsforsøket ? Fjern VPN + Kontrollerer om tjeneren bruker et sertifikat med TLS-servertillegg (--remote-cert-TLS-server) + Forvent TLS-serversertifikat + Kontrollerer eksternt tjenersertifikatemne DN + Sjekk av vertsnavn i sertifikat TLS-Auth-fil DNS Bruk din egen DNS-server diff --git a/app/src/main/res/values-pl/strings-icsopenvpn.xml b/app/src/main/res/values-pl/strings-icsopenvpn.xml index d628da6c..495eb00e 100755 --- a/app/src/main/res/values-pl/strings-icsopenvpn.xml +++ b/app/src/main/res/values-pl/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-pt/strings-icsopenvpn.xml b/app/src/main/res/values-pt/strings-icsopenvpn.xml index 30bf569e..d0058c68 100755 --- a/app/src/main/res/values-pt/strings-icsopenvpn.xml +++ b/app/src/main/res/values-pt/strings-icsopenvpn.xml @@ -1,139 +1,255 @@ + Endereço do Servidor: - Porta: + Porta do Servidor: Localização - Não foi possível ler o diretório + Não é possível ler o diretório Selecionar Cancelar Não há dados Compressão LZO - Sem Certificado - Certificado do Cliente - Chave do Certificado do Cliente - Arquivo PKCS12 - Certificado CA - Você deve selecionar um certificado - O código fonte e o rastreamento de incidentes estão disponíveis em http://code.google.com/p/ics-openvpn/ - Este programa utiliza os seguintes componentes; veja o código fonte para mais detalhes das licenças + Nenhum certificado + Certificado de cliente + Chave de certificado de cliente + Ficheiro PKCS12 + Certificado de CA + Deve selecionar um certificado + Código fonte e controlo de problemas disponível em http://code.google.com/p/ics-openvpn/ + Este programa utiliza os seguintes componentes; Para mais detalhes sobre as licenças consultar o código-fonte Sobre Perfis Tipo - Senha do PKCS12 + Password PKCS12 Selecionar… - Você deve selecionar um arquivo - Utilizar Autenticação TLS + É necessário selecionar um ficheiro + Usar autenticação TLS Direção TLS - Entre o Endereço IPv6/CIDR (ex: 2000:dd::23/64) - Entre o endereço IPv4/CIDR (ex: 1.2.3.4/24) + Digite o endereço de IPv6/máscara de rede no formato CIDR (por exemplo, 2000:dd::23 / 64) + Digite o endereço de IPv4/máscara de rede no formato CIDR (por exemplo, 1.2.3.4/24) Endereço IPv4 Endereço IPv6 - Insira as opções personalizadas para o OpenVPN. Utilize com cuidado. Observe também que muitas das opções relacionadas ao tun do OpenVPN não podem ser suportadas pelo design do VPNSettings. Contate o autor se você acha que uma opção importante está faltando. - Usuário - Senha - Para a configuração estática as chaves de autenticação de TLS serão utilizadas como chaves estáticas - Configurar VPN - Adicionar Perfil - Digite um nome que identifica o novo perfil - Por favor, digite um nome de perfil único + Insira opções personalizadas para a ligação OpenVPN. Este opções devem ser usadas com precaução. Note-se também que muitas das opções para OpenVPN relacionados com tun não não suportadas propositadamente. Se achar que uma opção importante está falta entre em contato com o autor + Utilizador + Password + Para a configuração estática as chaves de autenticação TLS serão usadas como chaves estáticas + Configurar a VPN + Adicionar perfil + Digite um nome que identifique o novo perfil + Por favor, digite um nome de perfil que não esteja já em uso Nome do perfil - Você deve selecionar um certificado de usuário + Tem de selecionar um certificado de utilizador Nenhum erro encontrado Erro na configuração Erro ao analisar o endereço IPv4 Erro ao analisar as rotas personalizadas - (deixe em branco para consulta sob demanda) + (deixe em branco para consulta a pedido) Atalho do OpenVPN - Conectar a VPN - O perfil especificado no atalho não foi encontrado + Ligar à VPN + Perfil especificado no atalho não encontrado Prefixo de Host aleatório - Adiciona 6 caracteres aleatórios na frente do hostname - Habilitar opções personalizadas - Opções personalizadas. Use com cuidado! + Adiciona 6 caracteres aleatórios ao nome do host + Ativar opções personalizadas + Especifique as opções personalizadas. Use com cuidado! Rota rejeitada pelo Android Desconectar Desconectar VPN - limpar log - Cancelar confirmação - Desconectar a VPN conectada/cancelar a tentativa de conexão? + Limpar registo + Cancelar Confirmação Remover VPN - Verifica se o servidor usa um certificado com as extensões de servidor TLS (- servidor remoto-cert-TLS) Esperar certificado do servidor TLS - Verifica o DN Subject do certificado do servidor remoto - Verificar o Hostname do Certificado - Especificar a conta usada para verificar o certificado remoto DN (por exemplo, C = DE, L = Paderborn, UO = aviária operadoras IP, CN=openvpn.blinkt.de)\n\Especificar o DN completo ou o RDN (openvpn.blinkt.de no exemplo) ou um prefixo RDN para verification.\n\nWhen usando o prefixo RDN \"Servidor\" corresponde a \"Server-1\" e \"Server-2\" \n\nDeixando vazio, o campo de texto irá verificar o RDN contra o servidor hostname.\n\nPara mais detalhes consulte a página principal do 2.3.1+ OpenVPN sob — verificar-X509-nome - Subject do certificado remoto - Permite a Autenticação de Chave TLS - Arquivo de Auth TLS - Solicitações de endereços de IP, rotas e opções de sincronização do servidor. - Nenhuma informação é solicitada do servidor. Configurações precisam ser especificadas abaixo. + Verificar nome de host do certificado + Assunto do certificado remoto + Ativa a autenticação de chave TLS + Ficheiro de autenticação TLS + Solicita endereços IP, rotas e tempo do servidor. Obter Configurações DNS - Substituir as configurações de DNS pelo servidor - Use seus próprios servidores de DNS + Substituir configurações de DNS pelo servidor + Use seus próprios servidores DNS Domínio de pesquisa - Servidor DNS a ser usado. + Servidor de DNS a utilizar. Servidor DNS Servidor DNS secundário utilizado caso o servidor primário esteja inacessível. Servidor DNS alternativo - Ignorar rotas empurradas - Ignorar rota empurrada pelo servidor. Redireccionar todo o tráfego pela VPN Usar rota padrão - Digite rotas personalizadas. Apenas indique destino em formato CIDR. \"10.0.0.0 / 8 2002 :: / 16\" iria dirigir as redes 10.0.0.0 / 8 e 2002 :: / 16 sobre a VPN. - As rotas que não devem ser encaminhados pelo VPN. Use a mesma sintaxe para rotas incluídas. Rotas personalizadas Redes excluídas - Nível de complexidade do log - Permite pacotes autenticados a partir de qualquer IP + Nível de verbosidade do log Permitir servidor flutuante Opções personalizadas - Editar configurações de VPN - Remover o perfil VPN \'%s\'? - Em algumas imagens ICS personalizado a permissão em / dev / tun pode estar errada, ou o módulo tun pode estar faltando completamente. Para imagens CM9 tente a opção correção propriedade sobre as configurações gerais - Falha ao abrir a interface de tun - "Erro:" - Claro - Abrindo a interface tun: - Local IPv4: %1$s/%2$d IPv6:%3$s MTU:%4$d - Servidor DNS: %1$s, domínio: %2$s + Editar definições VPN + Remova o perfil VPN \'%s\'? + Falha ao abrir a interface tun + "Erro: " + Limpar + A abrir a interface tun: + Local IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d + Servidor DNS: %1$s, Dominio: %2$s Rotas: %1$s %2$s Rotas excluídas: %1$s %2$s - Rotas VpnService instaladas: %1$s %2$s + Rotas VpnService instaladas: %1$s %2$s Existem múltiplas informações de interface, %1$s e %2$s, a aplicação assume que o segundo endereço é um endereço \'peer\' do endereço remoto. Será usada uma máscara de rede /32 para o IP local. O modo estabelecido pela OpenVPN é \"%3$s\". - Não consigo entender %1$s e %2$s como uma rota IP com máscara de rede CIDR, usando /32 como máscara de rede. + não é possível fazer sentido de %1$s e %2$s como rotas de IP, com máscara de rede CIDR, será usada uma máscara de rede /32. A rota %1$s/%2$s foi corrigida para %3$s/%2$s - Não é possível aceder aos certificados \'Keychain Android\'. Isso pode ter sido causado por uma atualização de firmware ou uma restauração das configurações da app/app. Será necessário editar o perfil VPN e selecionar novamente o certificado nas configurações básicas para recriar a permissão e possibilitar o acesso ao certificado. + Não é possível aceder aos certificados \'Keychain Android\'. Isto pode ser causado por uma atualização de firmware ou um restauro das configurações da app/app. Será necessário editar o perfil VPN e selecionar novamente o certificado nas configurações básicas para recriar a permissão e possibilitar o acesso ao certificado. %1$s %2$s - Enviar arquivo de log + Enviar o ficheiro de registo Enviar Ficheiro de registo do ICS OpenVPN Entrada de registo copiada para a área de transferência - Entrada de registo copiada para a área de transferência + Modo Tap A API VPN não permite o modo Tap em dispositivos sem acesso root. Desta forma não é possível oferecer suporte Tap nesta aplicação - Novamente? Você está brincando? Não, o modo tap não é suportado de maneira nenhuma e enviar mais emails a perguntar se eventualmente será, não irá ajudar. - Perguntas frequentes + Novamente? Estamos a brincar? Não, o modo tap não é suportado de maneira nenhuma e enviar mais emails a perguntar se eventualmente será, não ai ajudar a que seja. + Uma terceira vez? Na verdade, se poderia escrever um um emulador de torneira baseado no tun que adicionar layer2 informações sobre envio e tira informações layer2 em receber. Mas este emulador de torneira também teria que implementar ARP e, possivelmente, um cliente DHCP. Eu não conheço ninguém fazer nenhum trabalho nesse sentido. Contacte-me se você deseja iniciar a codificação sobre isso. Mas este emulador tap também teria que implementar ARP e, possivelmente, um cliente DHCP. Eu não conheço ninguém a fazer nenhum trabalho nesse sentido. Contacte-me se conhece alguém ou deseja a escrever código nesse sentido. + Perguntas Frequentes + Copia entradas de registo + Para copiar uma única entrada do registo selecione e mantenha seleciona a respetiva entrada. Para copiar/enviar o registo completo use a opção enviar registo. Use o botão de menu do equipamento caso não esteja visível no GUI. + Atalho para iniciar + A imagem não suporta a API VPNService, lamentamos :( Encriptação + Digite o método de encriptação + Autenticação/encriptação + Explorador de ficheiros + Ficheiro embutido + Erro ao importar ficheiro + Não foi possível importar o ficheiro + [[Dados do ficheiro embutido]] + Impossível abrir dispositivo tun sem informações de IP + Importar Perfil a partir de um ficheiro ovpn Importar + Não foi possível ler o perfil a importação + Erro ao ler o ficheiro de configuração + Adicionar perfil + Não foi possível encontrar o ficheiro %1$s mencionado no ficheiro de configuração importado + A importar ficheiro configuração a partir de %1$s + Terminou a leitura do ficheiro de configuração. + Não ligar a endereço e porta local + Não permitir ligações \'locais\' + Importar o ficheiro de configuração + Considerações de segurança + "Como OpenVPN é segurança sensíveis algumas notas sobre segurança são sensatas. Todos os dados no sdcard é inerentemente inseguro. Cada aplicativo pode lê-lo (por exemplo, este programa não requer direitos especiais cartão SD). Os dados desta aplicação só pode ser lido pelo próprio aplicativo. Ao usar a opção de importação para cacert / cert / chave no diálogo os dados do arquivo é armazenado no perfil de VPN. Os perfis de VPN são acessíveis apenas por esta aplicação. (Não se esqueça de apagar as cópias no sd cartão depois). Mesmo com acesso apenas por este aplicativo os dados ainda não é criptografado. torcendo por telefone ou outros exploits pode ser possível recuperar os dados. senhas salvas são armazenadas em texto simples assim. Para arquivos PKCS12 é altamente recomendável que você importá-los para o armazenamento de chaves android. " Importar IPv4 IPv6 + A esperar mensagem de estado... + perfil importado + Perfil importado %d + Imagens quebradas + Senha de chave privada Senha + ícone de ficheiro + Autenticação TLS + Config gerado Configurações + Corrija a propriedade de /dev/tun + A editar \"%s\" + A preparar a configuração... + Volte a ligar na mudança de rede + Estado da rede: %s + Selecione + Mostrar a janela de log + Aviso de ligação e som de notificação + IP e DNS + Básico + Encaminhamento Avançado + Início Rápido + A utilizar proxy %1$s %2$d + Usar a proxy do sistema + Volte a ligar na reinicialização Ignorar Reiniciar - Conectando + As alterações de configuração são aplicadas depois de reiniciar a VPN. Reiniciar a VPN agora? + Configuração alterada + Notificações duplicadas + Não há perfis de VPN definidos. + Use o < img src = \"ic_menu_add\" / > ícone para adicionar uma nova VPN + Use o < img src = \"ic_menu_archive\" / > ícone para importar um perfil existente (ovpn ou conf) do seu sdcard. + Configuração de roteamento/Interface + Tun Persistente + OpenVPN Log + Importar configuração OpenVPN + Consumo de bateria + VPN e Tethering + Tentativas de ligação + Configurações de religação + Segundos entre ligações + Enviar Minidump para desenvolvedor + OpenVPN - %s + %1$s - %2$s + %1$s - %3$s, %2$s + A ligar + A esperar pela resposta do servidor Autenticando - Conectado - Add - Pausa VPN + A obter a configuração do cliente + Atribuindo endereços IP + Adicionando rotas + Ligado + Desligado + A religar + A sair + Parado + A resolver nomes de host + A ligar (TCP) + Falha na autenticação + A aguardar rede utilizável + ↓%2$s/s %1$s - ↑%4$s/s %3$s + Não ligado + A ligar a VPN %s + A ligar a VPN %s + Cifra de encriptação + Autenticação de pacotes + Selecione o método de autenticação de pacotes + Feito por %s + compilação de debug + compilação oficial + Copiar para o perfil + Crashdump + Adicionar + Enviar ficheiro de configuração + DN completo + RDN (nome comum) + Prefixo RDN + TLS-remoto (obsoleto) + Pode ajudar a traduzir, visite http://crowdin.net/project/ics-openvpn/invite + %1$s tenta controlar %2$s + Confio nesta aplicação. + Nenhuma app pode usar a API externa + Aplicações permitidas:%s + Guardar senha + Pausar VPN Retomar VPN - Upload - Download - Vpn Status - Ver opções + VPN pausado por solicitação do utilizador + Não é possível mostrar as informações de certificado + Comportamento da aplicação + Comportamento VPN + Permitir alterações aos perfis de VPN + Como alternativa, pode enviar uma doação pela Play Store: + Obrigado por doar %s! + Log limpo. + Mostrar a senha + Erro de acesso às chaves: %s + Curto + ISO + Carimbos de hora + Nenhum + Fazer upload + Transferir + Estado da VPN + Opções de visualização + Unhandled exception: %1$s\n\n%2$s + %3$s: %1$s\n\n%2$s + Licenças completas + Ignorar VPN para redes locais + Ficheiro de utilizador/senha + [Importado de: %s] + Log de importação: diff --git a/app/src/main/res/values-ro/strings-icsopenvpn.xml b/app/src/main/res/values-ro/strings-icsopenvpn.xml index 8ae2770e..ef4e3a75 100755 --- a/app/src/main/res/values-ro/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ro/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-ru/strings-icsopenvpn.xml b/app/src/main/res/values-ru/strings-icsopenvpn.xml index 400269ec..e2bc930c 100755 --- a/app/src/main/res/values-ru/strings-icsopenvpn.xml +++ b/app/src/main/res/values-ru/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ + diff --git a/app/src/main/res/values-sv/strings-icsopenvpn.xml b/app/src/main/res/values-sv/strings-icsopenvpn.xml index 1e4f3635..9b974522 100755 --- a/app/src/main/res/values-sv/strings-icsopenvpn.xml +++ b/app/src/main/res/values-sv/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-tr/strings-icsopenvpn.xml b/app/src/main/res/values-tr/strings-icsopenvpn.xml index a40df5bf..90ad068d 100755 --- a/app/src/main/res/values-tr/strings-icsopenvpn.xml +++ b/app/src/main/res/values-tr/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + @@ -86,6 +90,7 @@ Varsayılan Yolu kullan Özel yolları girin. CIDR biçimde tek hedef girin. \"10.0.0.0 / 8 2002 :: / 16\" ağlar VPN üzerinden 10.0.0.0 / 8 ve 2002 :: / 16 doğrudan. Özel Yollar + Dışlanan Ağlar Ayrıntı düzeyi Log Herhangi bir IP kimlik doğrulaması paketlerini sağlar Herhangi bir IP kimlik doğrulaması paketlerini sağlar diff --git a/app/src/main/res/values-uk/strings-icsopenvpn.xml b/app/src/main/res/values-uk/strings-icsopenvpn.xml index 97a1e9a4..92637b74 100755 --- a/app/src/main/res/values-uk/strings-icsopenvpn.xml +++ b/app/src/main/res/values-uk/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + diff --git a/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml b/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml index e49a2240..93e0cbb1 100755 --- a/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml +++ b/app/src/main/res/values-zh-rCN/strings-icsopenvpn.xml @@ -1,5 +1,9 @@ - + + @@ -23,7 +27,7 @@ 配置文件 类型 PKCS12 密码 - 请选择... + 请选择… 您必须选择一个文件 使用 TLS 身份验证 TLS 方向 @@ -85,7 +89,6 @@ 使用默认路由 输入自定义路由。输入 CIDR 格式地址。 自定义路由 - just 日志详细级别 允许来自任何 IP 的认证数据包 允许浮服务器 @@ -100,7 +103,6 @@ 本地 IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d DNS 服务器: %1$s, 域名: %2$s 排除的路由: %1$s %2$s - China 已获得接口信息 %1$s 以及 %2$s,将第二个地址作为远程地址。使用 /32 作为本地掩码。OpenVPN 给出的模式是 \"%3$s\"。 无法将 %1$s 和 %2$s 作为 CIDR 形式的路由,将使用 /32 的子网掩码。 纠正路由 %1$s/%2$s 为 %3$s/%2$s @@ -292,7 +294,7 @@ 感谢捐赠 %s! 日志已清除。 显示密码 - 钥匙串访问错误: %s + 钥匙串访问错误: %s ISO 时间戳 diff --git a/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml b/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml index e467dd5b..bd155362 100755 --- a/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml +++ b/app/src/main/res/values-zh-rTW/strings-icsopenvpn.xml @@ -1,5 +1,10 @@ - + + + 伺服器地址: @@ -19,9 +24,10 @@ 取得原始碼與個案追蹤,可上 http://code.google.com/p/ics-openvpn/ 本程序使用了以下元件,其作者和授權資訊如下 關於 + 設定檔 類型 PKCS12 密碼 - 選擇… + 選擇… 你必須選擇一個檔案 使用傳輸層防火牆(TLS-Auth) TLS方向 @@ -43,19 +49,22 @@ 解析IPv4地址時發生錯誤 解析自訂路由時發生錯誤 OpenVPN捷徑 - 連接到VPN + 連線到VPN 在快捷方式找不到指定的設定檔 隨機主機名稱字首 在主機名稱前加入6個隨機字符 啟用自訂選項 自訂選項,使用時請小心! 路由被Android拒絕 - 斷線 + 中斷連線 + 中斷VPN連線 清除記錄檔 確認取消 + 中斷已連接的VPN/取消正在嘗試的連線? 移除VPN - 檢查對方出示的是否TLS伺服器憑證 - 預期對方出示TLS伺服器憑證 + 預計TLS服務器證書 + 檢查遠程服務器證書的主題DN + 證書的主機名檢查 啟用傳輸層防火牆(TLS-Auth) TLS驗證檔 向伺服器請求IP地址, 路由和時間資訊 @@ -117,7 +126,9 @@ 匯入 IPv4 IPv6 - 等待狀態訊息… + 等待狀態訊息… + 匯入設定檔 + 匯入設定檔%d PKCS12檔加密金鑰 私密金鑰密碼 密碼 @@ -128,45 +139,55 @@ 修正 /dev/tun 的擁有者 顯示本程序生成的設定檔 正在編輯\"%s\" - 正在生成設定檔… - 當網絡狀況變更時強制重新連接(例如從WiFi變成手機網絡,反之亦然) - 網絡異動時重新連接 + 正在生成設定檔… + 若切換此選項當網絡狀況變更時將強制重新連線(例如從WiFi變成手機網絡,反之亦然) + 網絡異動時重新連線 網絡狀態: %s 選擇 + 連接時顯示記錄檔視窗。記錄檔視窗可以隨時從通知欄中進入。 顯示記錄視窗 於 %1$s (%2$s) %3$s 上運行, Android API 版本: %4$d 連線警告和通知時發出音效 - 繁體中文 由 羊羊@自由網絡研究中心 <sora8964@gmail.com> 翻譯 + 繁體中文 IP和DNS 基本 路由 鮮為人知的OpenVPN設定,一般情況下不需要派上用場。 進階 ICS Openvpn 設定 - 沒有任何DNS伺服器可用,可能無法進行網域名稱解析。請考慮設置自訂的DNS伺服器 快速入門 在連線前嘗試載入Tun模組,需要Root。 載入Tun模組 取得代理伺服器資訊時發生錯誤: %s 使用代理伺服器 %1$s %2$d 使用系統代理 - 使用系統配置的 HTTP/HTTPS 代理伺服器進行連接。 + 使用系統配置的 HTTP/HTTPS 代理伺服器進行連線。 你可以透過 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal</a> 提供捐助 - 如果在重新開機或關機前正連接VPN,開機時自動重新連接。在使用這個選項之前請先閱讀連線警告FAQ。 - 開機時重新連接 + 如果在重新開機或關機前正連線VPN,開機時自動重新連線。在使用這個選項之前請先閱讀連線警告FAQ。 + 開機時重新連線 忽略 重置 配置變更只會在重新啟動VPN時才生效,現在要(重新)啟動VPN嗎? 設定已變更 + 無法判斷最後一次連線使用的設定檔,因此無法編輯設定檔。 重複的通知 路由/網絡介面 設定 OpenVPN 運作記錄 匯入 OpenVPN 配置 電池消耗 VPN與可攜式無線基地台 - 連線重試次數 - 嘗試重新連線之間的等待秒數 - 重新連接間隔時間 + 重新連線次數 + 重新連線設定 + 嘗試重新連線之間的等待秒數。 + 重新連線的間隔時間 OpenVPN非預期地崩潰,你或者會考慮在主選單下傳送Minidump給開發人員。 向開發人員傳送Minidump + 連線中 + 已連線 + 中斷連線 + 正在重新連線 + 連線中 (TCP) + 未連線 + 正在連接至 VPN %s + 正在連接至 VPN %s diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 4f325078..9a53fe4c 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,4 +1,9 @@ + + 20dp 8dp diff --git a/app/src/main/res/values/strings-icsopenvpn.xml b/app/src/main/res/values/strings-icsopenvpn.xml index aadbff32..15bf8142 100755 --- a/app/src/main/res/values/strings-icsopenvpn.xml +++ b/app/src/main/res/values/strings-icsopenvpn.xml @@ -1,4 +1,7 @@ - + @@ -323,5 +326,7 @@ Announce to TCP sessions running over the tunnel that they should limit their send packet sizes such that after OpenVPN has encapsulated them, the resulting UDP packet size that OpenVPN sends to its peer will not exceed this number of bytes. (default is 1450) Override MSS value of TCP payload Set MSS of TCP payload + Client behaviour + Clear allowed external apps diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 95e709b3..7b26a4a7 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,20 +1,8 @@ + ~ Copyright (c) 2012-2014 Arne Schwabe + ~ Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + --> diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml index b45d5ae7..619a550f 100644 --- a/app/src/main/res/values/untranslatable.xml +++ b/app/src/main/res/values/untranslatable.xml @@ -2429,6 +2429,26 @@ + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3