From 39b06f3f5f371f0ec03e20292a81cb514cb6061e Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Tue, 23 Jan 2018 11:10:40 +0100 Subject: new UI for EipFragment --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 16 +- .../java/se/leap/bitmaskclient/EipFragment.java | 477 +++++++++++++++++++++ .../java/se/leap/bitmaskclient/MainActivity.java | 2 +- .../java/se/leap/bitmaskclient/VpnFragment.java | 446 ------------------- .../drawer/NavigationDrawerFragment.java | 4 +- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 53 ++- .../java/se/leap/bitmaskclient/eip/EipStatus.java | 127 +++--- 7 files changed, 584 insertions(+), 541 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/EipFragment.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/VpnFragment.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 5ccb48b5..a14b7d2f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -87,7 +87,7 @@ public class Dashboard extends ButterKnifeActivity { @InjectView(R.id.providerName) TextView provider_name; - private VpnFragment eip_fragment; + private EipFragment eip_fragment; private UserStatusFragment user_status_fragment; private static Provider provider = new Provider(); @@ -290,8 +290,8 @@ public class Dashboard extends ButterKnifeActivity { * Inflates permanent UI elements of the View and contains logic for what * service dependent UI elements to include. */ - //TODO: REFACTOR ME! Consider implementing a manager that handles most of VpnFragment's logic about handling EIP commands. - //This way, we could avoid to create UI elements (like fragmentManager.replace(R.id.servicesCollection, eip_fragment, VpnFragment.TAG); ) + //TODO: REFACTOR ME! Consider implementing a manager that handles most of EipFragment's logic about handling EIP commands. + //This way, we could avoid to create UI elements (like fragmentManager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); ) // just to start services and destroy them afterwards private void buildDashboard(boolean hideAndTurnOnEipOnBoot) { setContentView(R.layout.dashboard); @@ -305,9 +305,9 @@ public class Dashboard extends ButterKnifeActivity { fragment_manager.replace(R.id.user_status_fragment, user_status_fragment, UserStatusFragment.TAG); if (provider.hasEIP()) { - fragment_manager.removePreviousFragment(VpnFragment.TAG); + fragment_manager.removePreviousFragment(EipFragment.TAG); eip_fragment = prepareEipFragment(hideAndTurnOnEipOnBoot); - fragment_manager.replace(R.id.servicesCollection, eip_fragment, VpnFragment.TAG); + fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); if (hideAndTurnOnEipOnBoot) { onBackPressed(); } @@ -320,13 +320,13 @@ public class Dashboard extends ButterKnifeActivity { * has caused to start Dashboard * @return the created VPNFragment */ - public VpnFragment prepareEipFragment(boolean hideAndTurnOnEipOnBoot) { - VpnFragment eip_fragment = new VpnFragment(); + public EipFragment prepareEipFragment(boolean hideAndTurnOnEipOnBoot) { + EipFragment eip_fragment = new EipFragment(); if (hideAndTurnOnEipOnBoot && !isAlwaysOn()) { preferences.edit().remove(EIP_RESTART_ON_BOOT).apply(); Bundle arguments = new Bundle(); - arguments.putBoolean(VpnFragment.START_EIP_ON_BOOT, true); + arguments.putBoolean(EipFragment.START_EIP_ON_BOOT, true); Log.d(TAG, "set START_EIP_ON_BOOT argument for eip_fragment"); eip_fragment.setArguments(arguments); diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java new file mode 100644 index 00000000..cf2f0eff --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -0,0 +1,477 @@ +/** + * 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.content.ComponentName; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ResultReceiver; +import android.support.v4.app.Fragment; +import android.support.v7.widget.AppCompatImageView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import java.util.Observable; +import java.util.Observer; + +import butterknife.ButterKnife; +import butterknife.InjectView; +import butterknife.OnClick; +import de.blinkt.openvpn.core.IOpenVPNServiceInternal; +import de.blinkt.openvpn.core.OpenVPNService; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipStatus; +import se.leap.bitmaskclient.eip.VoidVpnService; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; +import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK; +import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; +import static se.leap.bitmaskclient.Constants.EIP_ACTION_START; +import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP; +import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN; +import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE; +import static se.leap.bitmaskclient.Constants.EIP_NOTIFICATION; +import static se.leap.bitmaskclient.Constants.EIP_RECEIVER; +import static se.leap.bitmaskclient.Constants.EIP_REQUEST; +import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT; +import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED; +import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; +import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; + +public class EipFragment extends Fragment implements Observer { + + public static String TAG = EipFragment.class.getSimpleName(); + + protected static final String IS_CONNECTED = TAG + ".is_connected"; + public static final String START_EIP_ON_BOOT = "start on boot"; + + private SharedPreferences preferences; + + @InjectView(R.id.background) + AppCompatImageView background; + + @InjectView(R.id.key) + AppCompatImageView key; + + @InjectView(R.id.cirle) + AppCompatImageView circle; + + @InjectView(R.id.vpn_main_button) + Button mainButton; + + @InjectView(R.id.routed_text) + TextView routedText; + + @InjectView(R.id.vpn_route) + TextView vpnRoute; + + private EIPReceiver eipReceiver; + private EipStatus eipStatus; + private boolean wantsToConnect; + + private IOpenVPNServiceInternal mService; + private ServiceConnection openVpnConnection = new ServiceConnection() { + + + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + + mService = IOpenVPNServiceInternal.Stub.asInterface(service); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mService = null; + } + + }; + + public void onAttach(Context context) { + super.onAttach(context); + downloadEIPServiceConfig(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + eipStatus = EipStatus.getInstance(); + eipStatus.addObserver(this); + eipReceiver = new EIPReceiver(new Handler()); + preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.eip_service_fragment, container, false); + ButterKnife.inject(this, view); + + Bundle arguments = getArguments(); + if (arguments != null && arguments.containsKey(START_EIP_ON_BOOT) && arguments.getBoolean(START_EIP_ON_BOOT)) { + startEipFromScratch(); + } + return view; + } + + @Override + public void onResume() { + super.onResume(); + //FIXME: avoid race conditions while checking certificate an logging in at about the same time + //eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY); + handleNewState(); + bindOpenVpnService(); + } + + @Override + public void onPause() { + super.onPause(); + getActivity().unbindService(openVpnConnection); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putBoolean(IS_CONNECTED, eipStatus.isConnected()); + super.onSaveInstanceState(outState); + } + + private void saveStatus(boolean restartOnBoot) { + preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, restartOnBoot).apply(); + } + + @OnClick(R.id.vpn_main_button) + void onButtonClick() { + handleIcon(); + } + + @OnClick(R.id.key) + void onKeyClick() { + handleIcon(); + } + + @OnClick(R.id.cirle) + void onCircleClick() { + handleIcon(); + } + + void handleIcon() { + if (eipStatus.isConnected() || eipStatus.isConnecting()) + handleSwitchOff(); + else + handleSwitchOn(); + } + + private void handleSwitchOn() { + if (canStartEIP()) + startEipFromScratch(); + else if (canLogInToStartEIP()) { + wantsToConnect = true; + Bundle bundle = new Bundle(); + MainActivity.sessionDialog(bundle); + } else { + Log.d(TAG, "WHAT IS GOING ON HERE?!"); + // TODO: implement a fallback: check if vpncertificate was not downloaded properly or give + // a user feedback. A button that does nothing on click is not a good option + } + } + + private boolean canStartEIP() { + boolean certificateExists = !preferences.getString(PROVIDER_VPN_CERTIFICATE, "").isEmpty(); + boolean isAllowedAnon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false); + return (isAllowedAnon || certificateExists) && !eipStatus.isConnected() && !eipStatus.isConnecting(); + } + + private boolean canLogInToStartEIP() { + boolean isAllowedRegistered = preferences.getBoolean(PROVIDER_ALLOWED_REGISTERED, false); + boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); + return isAllowedRegistered && !isLoggedIn && !eipStatus.isConnecting() && !eipStatus.isConnected(); + } + + private void handleSwitchOff() { + if (eipStatus.isConnecting()) { + askPendingStartCancellation(); + } else if (eipStatus.isConnected()) { + askToStopEIP(); + } + } + + private void askPendingStartCancellation() { + Activity activity = getActivity(); + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity()); + alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title)) + .setMessage(activity.getString(R.string.eip_cancel_connect_text)) + .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + stopEipIfPossible(); + } + }) + .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }) + .show(); + } + + public void startEipFromScratch() { + wantsToConnect = false; + saveStatus(true); + eipCommand(EIP_ACTION_START); + } + + private void stop() { + saveStatus(false); + if (eipStatus.isBlockingVpnEstablished()) { + stopBlockingVpn(); + } + disconnect(); + } + + private void stopBlockingVpn() { + Log.d(TAG, "stop VoidVpn!"); + Activity activity = getActivity(); + Intent stopVoidVpnIntent = new Intent(activity, VoidVpnService.class); + stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); + activity.startService(stopVoidVpnIntent); + } + + private void disconnect() { + ProfileManager.setConntectedVpnProfileDisconnected(getActivity()); + if (mService != null) { + try { + mService.stopVPN(false); + } catch (RemoteException e) { + VpnStatus.logException(e); + } + } + } + + protected void stopEipIfPossible() { + //FIXME: no need to start a service here! + eipCommand(EIP_ACTION_STOP); + } + + private void downloadEIPServiceConfig() { + ProviderAPIResultReceiver provider_api_receiver = new ProviderAPIResultReceiver(new Handler(), Dashboard.dashboardReceiver); + if(eipReceiver != null) + ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_EIP_SERVICE, provider_api_receiver); + } + + protected void askToStopEIP() { + Activity activity = getActivity(); + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity); + alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title)) + .setMessage(activity.getString(R.string.eip_warning_browser_inconsistency)) + .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + stopEipIfPossible(); + } + }) + .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }) + .show(); + } + + protected void updateEipService() { + eipCommand(EIP_ACTION_UPDATE); + } + + /** + * Send a command to EIP + * + * @param action A valid String constant from EIP class representing an Intent + * filter for the EIP class + */ + private void eipCommand(String action) { + Activity activity = getActivity(); + // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? + Intent vpn_intent = new Intent(activity.getApplicationContext(), EIP.class); + vpn_intent.setAction(action); + vpn_intent.putExtra(EIP_RECEIVER, eipReceiver); + activity.startService(vpn_intent); + } + + @Override + public void update(Observable observable, Object data) { + if (observable instanceof EipStatus) { + eipStatus = (EipStatus) observable; + Activity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + handleNewState(); + } + }); + } else { + Log.e("EipFragment", "activity is null"); + } + } + } + + private void handleNewState() { + Activity activity = getActivity(); + if (eipStatus.isConnecting()) { + mainButton.setText(activity.getString(android.R.string.cancel)); + key.setImageResource(R.drawable.vpn_connecting); + routedText.setVisibility(GONE); + vpnRoute.setVisibility(GONE); + colorBackgroundALittle(); + } else if (eipStatus.isConnected() || isOpenVpnRunningWithoutNetwork()) { + mainButton.setText(activity.getString(R.string.vpn_button_turn_off)); + key.setImageResource(R.drawable.vpn_connected); + routedText.setVisibility(VISIBLE); + vpnRoute.setVisibility(VISIBLE); + vpnRoute.setText(ConfigHelper.getCurrentProviderName(preferences)); + colorBackground(); + } else { + mainButton.setText(activity.getString(R.string.vpn_button_turn_on)); + key.setImageResource(R.drawable.vpn_disconnected); + routedText.setVisibility(GONE); + vpnRoute.setVisibility(GONE); + greyscaleBackground(); + } + } + + private boolean isOpenVpnRunningWithoutNetwork() { + boolean isRunning = false; + try { + isRunning = eipStatus.getLevel() == LEVEL_NONETWORK && + mService.isVpnRunning(); + } catch (Exception e) { + //eat me + e.printStackTrace(); + } + + return isRunning; + } + + private void bindOpenVpnService() { + Activity activity = getActivity(); + Intent intent = new Intent(activity, OpenVPNService.class); + intent.setAction(OpenVPNService.START_SERVICE); + activity.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE); + } + + protected class EIPReceiver extends ResultReceiver { + + EIPReceiver(Handler handler) { + super(handler); + } + + @Override + protected void onReceiveResult(int resultCode, Bundle resultData) { + super.onReceiveResult(resultCode, resultData); + + String request = resultData.getString(EIP_REQUEST); + + if (request == null) { + return; + } + + switch (request) { + case EIP_ACTION_START: + switch (resultCode) { + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + break; + } + break; + case EIP_ACTION_STOP: + switch (resultCode) { + case Activity.RESULT_OK: + stop(); + break; + case Activity.RESULT_CANCELED: + break; + } + break; + case EIP_NOTIFICATION: + switch (resultCode) { + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + break; + } + break; + case EIP_ACTION_CHECK_CERT_VALIDITY: + switch (resultCode) { + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + Dashboard.downloadVpnCertificate(); + break; + } + break; + case EIP_ACTION_UPDATE: + switch (resultCode) { + case Activity.RESULT_OK: + if (wantsToConnect) + startEipFromScratch(); + break; + case Activity.RESULT_CANCELED: + handleNewState(); + break; + } + } + } + } + + private void greyscaleBackground() { + ColorMatrix matrix = new ColorMatrix(); + matrix.setSaturation(0); + ColorMatrixColorFilter cf = new ColorMatrixColorFilter(matrix); + background.setColorFilter(cf); + background.setImageAlpha(255); + } + + private void colorBackgroundALittle() { + background.setColorFilter(null); + background.setImageAlpha(144); + } + + private void colorBackground() { + background.setColorFilter(null); + background.setImageAlpha(255); + } + +} diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java index 40a9052c..4fd16a8b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java @@ -68,7 +68,7 @@ public class MainActivity extends AppCompatActivity { switch (intent.getAction()) { case ACTION_SHOW_VPN_FRAGMENT: - fragment = new VpnFragment(); + fragment = new EipFragment(); break; default: break; diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java deleted file mode 100644 index f1463029..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java +++ /dev/null @@ -1,446 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.support.v4.app.Fragment; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; - -import java.util.Observable; -import java.util.Observer; - -import butterknife.ButterKnife; -import butterknife.InjectView; -import butterknife.OnClick; -import de.blinkt.openvpn.core.IOpenVPNServiceInternal; -import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.core.VpnStatus; -import mbanje.kurt.fabbutton.FabButton; -import se.leap.bitmaskclient.eip.EIP; -import se.leap.bitmaskclient.eip.EipStatus; -import se.leap.bitmaskclient.eip.VoidVpnService; - -import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK; -import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; -import static se.leap.bitmaskclient.Constants.EIP_ACTION_START; -import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP; -import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN; -import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE; -import static se.leap.bitmaskclient.Constants.EIP_NOTIFICATION; -import static se.leap.bitmaskclient.Constants.EIP_RECEIVER; -import static se.leap.bitmaskclient.Constants.EIP_REQUEST; -import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT; -import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED; -import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; -import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; -import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; - -public class VpnFragment extends Fragment implements Observer { - - public static String TAG = VpnFragment.class.getSimpleName(); - - public static final String IS_PENDING = TAG + ".is_pending"; - protected static final String IS_CONNECTED = TAG + ".is_connected"; - public static final String START_EIP_ON_BOOT = "start on boot"; - - private SharedPreferences preferences; - - @InjectView(R.id.vpn_status_image) - FabButton vpnStatusImage; - @InjectView(R.id.vpn_main_button) - Button mainButton; - - private static EIPReceiver eipReceiver; - private static EipStatus eipStatus; - private boolean wantsToConnect; - - private IOpenVPNServiceInternal mService; - private ServiceConnection openVpnConnection = new ServiceConnection() { - - - - @Override - public void onServiceConnected(ComponentName className, - IBinder service) { - - mService = IOpenVPNServiceInternal.Stub.asInterface(service); - } - - @Override - public void onServiceDisconnected(ComponentName arg0) { - mService = null; - } - - }; - - public void onAttach(Context context) { - super.onAttach(context); - downloadEIPServiceConfig(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - eipStatus = EipStatus.getInstance(); - eipStatus.addObserver(this); - eipReceiver = new EIPReceiver(new Handler()); - preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.eip_service_fragment, container, false); - ButterKnife.inject(this, view); - - Bundle arguments = getArguments(); - if (arguments != null && arguments.containsKey(START_EIP_ON_BOOT) && arguments.getBoolean(START_EIP_ON_BOOT)) { - startEipFromScratch(); - } - return view; - } - - @Override - public void onResume() { - super.onResume(); - //FIXME: avoid race conditions while checking certificate an logging in at about the same time - //eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY); - handleNewState(); - bindOpenVpnService(); - } - - @Override - public void onPause() { - super.onPause(); - getActivity().unbindService(openVpnConnection); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putBoolean(IS_CONNECTED, eipStatus.isConnected()); - super.onSaveInstanceState(outState); - } - - private void saveStatus(boolean restartOnBoot) { - preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, restartOnBoot).apply(); - } - - @OnClick(R.id.vpn_main_button) - void handleIcon() { - if (eipStatus.isConnected() || eipStatus.isConnecting()) - handleSwitchOff(); - else - handleSwitchOn(); - } - - private void handleSwitchOn() { - if (canStartEIP()) - startEipFromScratch(); - else if (canLogInToStartEIP()) { - wantsToConnect = true; - Bundle bundle = new Bundle(); - MainActivity.sessionDialog(bundle); - } else { - Log.d(TAG, "WHAT IS GOING ON HERE?!"); - // TODO: implement a fallback: check if vpncertificate was not downloaded properly or give - // a user feedback. A button that does nothing on click is not a good option - } - } - - private boolean canStartEIP() { - boolean certificateExists = !preferences.getString(PROVIDER_VPN_CERTIFICATE, "").isEmpty(); - boolean isAllowedAnon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false); - return (isAllowedAnon || certificateExists) && !eipStatus.isConnected() && !eipStatus.isConnecting(); - } - - private boolean canLogInToStartEIP() { - boolean isAllowedRegistered = preferences.getBoolean(PROVIDER_ALLOWED_REGISTERED, false); - boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); - return isAllowedRegistered && !isLoggedIn && !eipStatus.isConnecting() && !eipStatus.isConnected(); - } - - private void handleSwitchOff() { - if (eipStatus.isConnecting()) { - askPendingStartCancellation(); - } else if (eipStatus.isConnected()) { - askToStopEIP(); - } else { - updateIcon(); - } - } - - private void askPendingStartCancellation() { - Activity activity = getActivity(); - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity()); - alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title)) - .setMessage(activity.getString(R.string.eip_cancel_connect_text)) - .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - stopEipIfPossible(); - } - }) - .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }) - .show(); - } - - public void startEipFromScratch() { - wantsToConnect = false; - saveStatus(true); - eipCommand(EIP_ACTION_START); - } - - private void stop() { - saveStatus(false); - if (eipStatus.isBlockingVpnEstablished()) { - stopBlockingVpn(); - } - disconnect(); - } - - private void stopBlockingVpn() { - Log.d(TAG, "stop VoidVpn!"); - Activity activity = getActivity(); - Intent stopVoidVpnIntent = new Intent(activity, VoidVpnService.class); - stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); - activity.startService(stopVoidVpnIntent); - } - - private void disconnect() { - ProfileManager.setConntectedVpnProfileDisconnected(getActivity()); - if (mService != null) { - try { - mService.stopVPN(false); - } catch (RemoteException e) { - VpnStatus.logException(e); - } - } - } - - protected void stopEipIfPossible() { - //FIXME: no need to start a service here! - eipCommand(EIP_ACTION_STOP); - } - - private void downloadEIPServiceConfig() { - ProviderAPIResultReceiver provider_api_receiver = new ProviderAPIResultReceiver(new Handler(), Dashboard.dashboardReceiver); - if(eipReceiver != null) - ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_EIP_SERVICE, provider_api_receiver); - } - - protected void askToStopEIP() { - Activity activity = getActivity(); - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity); - alertBuilder.setTitle(activity.getString(R.string.eip_cancel_connect_title)) - .setMessage(activity.getString(R.string.eip_warning_browser_inconsistency)) - .setPositiveButton((android.R.string.yes), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - stopEipIfPossible(); - } - }) - .setNegativeButton(activity.getString(android.R.string.no), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }) - .show(); - } - - protected void updateEipService() { - eipCommand(EIP_ACTION_UPDATE); - } - - /** - * Send a command to EIP - * - * @param action A valid String constant from EIP class representing an Intent - * filter for the EIP class - */ - private void eipCommand(String action) { - Activity activity = getActivity(); - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent vpn_intent = new Intent(activity.getApplicationContext(), EIP.class); - vpn_intent.setAction(action); - vpn_intent.putExtra(EIP_RECEIVER, eipReceiver); - activity.startService(vpn_intent); - } - - @Override - public void update(Observable observable, Object data) { - if (observable instanceof EipStatus) { - eipStatus = (EipStatus) observable; - Activity activity = getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - handleNewState(); - } - }); - } else { - Log.e("VpnFragment", "activity is null"); - } - } - } - - private void handleNewState() { - updateIcon(); - updateButton(); - } - - private void updateIcon() { - if (eipStatus.isBlocking()) { - vpnStatusImage.showProgress(false); - vpnStatusImage.setIcon(R.drawable.ic_stat_vpn_blocking, R.drawable.ic_stat_vpn_blocking); - vpnStatusImage.setTag(R.drawable.ic_stat_vpn_blocking); - } else if (eipStatus.isConnecting()) { - vpnStatusImage.showProgress(true); - vpnStatusImage.setIcon(R.drawable.ic_stat_vpn_empty_halo, R.drawable.ic_stat_vpn_empty_halo); - vpnStatusImage.setTag(R.drawable.ic_stat_vpn_empty_halo); - } else if (eipStatus.isConnected()){ - vpnStatusImage.showProgress(false); - vpnStatusImage.setIcon(R.drawable.ic_stat_vpn, R.drawable.ic_stat_vpn); - vpnStatusImage.setTag(R.drawable.ic_stat_vpn); - } else { - vpnStatusImage.setIcon(R.drawable.ic_stat_vpn_offline, R.drawable.ic_stat_vpn_offline); - vpnStatusImage.setTag(R.drawable.ic_stat_vpn_offline); - vpnStatusImage.showProgress(false); - } - } - - private void updateButton() { - Activity activity = getActivity(); - if (eipStatus.isConnecting()) { - mainButton.setText(activity.getString(android.R.string.cancel)); - } else if (eipStatus.isConnected() || isOpenVpnRunningWithoutNetwork()) { - mainButton.setText(activity.getString(R.string.vpn_button_turn_off)); - } else { - mainButton.setText(activity.getString(R.string.vpn_button_turn_on)); - } - } - - private boolean isOpenVpnRunningWithoutNetwork() { - boolean isRunning = false; - try { - isRunning = eipStatus.getLevel() == LEVEL_NONETWORK && - mService.isVpnRunning(); - } catch (Exception e) { - //eat me - e.printStackTrace(); - } - - return isRunning; - } - - private void bindOpenVpnService() { - Activity activity = getActivity(); - Intent intent = new Intent(activity, OpenVPNService.class); - intent.setAction(OpenVPNService.START_SERVICE); - activity.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE); - } - - protected class EIPReceiver extends ResultReceiver { - - EIPReceiver(Handler handler) { - super(handler); - } - - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - super.onReceiveResult(resultCode, resultData); - - String request = resultData.getString(EIP_REQUEST); - - if (request == null) { - return; - } - - switch (request) { - case EIP_ACTION_START: - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - break; - } - break; - case EIP_ACTION_STOP: - switch (resultCode) { - case Activity.RESULT_OK: - stop(); - break; - case Activity.RESULT_CANCELED: - break; - } - break; - case EIP_NOTIFICATION: - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - break; - } - break; - case EIP_ACTION_CHECK_CERT_VALIDITY: - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - Dashboard.downloadVpnCertificate(); - break; - } - break; - case EIP_ACTION_UPDATE: - switch (resultCode) { - case Activity.RESULT_OK: - if (wantsToConnect) - startEipFromScratch(); - break; - case Activity.RESULT_CANCELED: - handleNewState(); - break; - } - } - } - } - - - public static EIPReceiver getReceiver() { - return eipReceiver; - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index dbe99dce..4f2d0744 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -28,8 +28,8 @@ import android.widget.Toast; import se.leap.bitmaskclient.ConfigHelper; import se.leap.bitmaskclient.ConfigurationWizard; +import se.leap.bitmaskclient.EipFragment; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.VpnFragment; import se.leap.bitmaskclient.fragments.AboutFragment; import se.leap.bitmaskclient.fragments.LogFragment; @@ -296,7 +296,7 @@ public class NavigationDrawerFragment extends Fragment { if (parent == mDrawerAccountsListView) { mTitle = getString(R.string.vpn_fragment_title); - fragment = new VpnFragment(); + fragment = new EipFragment(); } else { Log.d("Drawer", String.format("Selected position %d", position)); switch (position) { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index a2ac9d66..118622ab 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -18,7 +18,6 @@ package se.leap.bitmaskclient.eip; import android.app.Activity; import android.app.IntentService; -import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; @@ -30,7 +29,6 @@ import org.json.JSONObject; import de.blinkt.openvpn.LaunchVPN; import se.leap.bitmaskclient.OnBootReceiver; -import se.leap.bitmaskclient.VpnFragment; import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_IS_RUNNING; @@ -59,12 +57,11 @@ public final class EIP extends IntentService { public final static String TAG = EIP.class.getSimpleName(); public final static String SERVICE_API_PATH = "config/eip-service.json"; - private static Context context; private static ResultReceiver mReceiver; private static SharedPreferences preferences; private static JSONObject eipDefinition; - private static GatewaysManager gatewaysManager = new GatewaysManager(); + private GatewaysManager gatewaysManager = new GatewaysManager(); private static Gateway gateway; public EIP() { @@ -74,7 +71,6 @@ public final class EIP extends IntentService { @Override public void onCreate() { super.onCreate(); - context = getApplicationContext(); preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); eipDefinition = eipDefinitionFromPreferences(); if (gatewaysManager.isEmpty()) @@ -86,18 +82,30 @@ public final class EIP extends IntentService { String action = intent.getAction(); mReceiver = intent.getParcelableExtra(EIP_RECEIVER); - if (action.equals(EIP_ACTION_START)) - startEIP(); - else if (action.equals(EIP_ACTION_START_ALWAYS_ON_EIP)) - startAlwaysOnEIP(); - else if (action.equals(EIP_ACTION_STOP)) - stopEIP(); - else if (action.equals(EIP_ACTION_IS_RUNNING)) - isRunning(); - else if (action.equals(EIP_ACTION_UPDATE)) - updateEIPService(); - else if (action.equals(EIP_ACTION_CHECK_CERT_VALIDITY)) - checkCertValidity(); + if (action == null) { + return; + } + + switch (action) { + case EIP_ACTION_START: + startEIP(); + break; + case EIP_ACTION_START_ALWAYS_ON_EIP: + startAlwaysOnEIP(); + break; + case EIP_ACTION_STOP: + stopEIP(); + break; + case EIP_ACTION_IS_RUNNING: + isRunning(); + break; + case EIP_ACTION_UPDATE: + updateEIPService(); + break; + case EIP_ACTION_CHECK_CERT_VALIDITY: + checkCertValidity(); + break; + } } /** @@ -114,7 +122,8 @@ public final class EIP extends IntentService { gateway = gatewaysManager.select(); if (gateway != null && gateway.getProfile() != null) { - mReceiver = VpnFragment.getReceiver(); + // TODO why is this needed? + // mReceiver = EipFragment.getReceiver(); launchActiveGateway(); tellToReceiver(EIP_ACTION_START, Activity.RESULT_OK); } else @@ -134,7 +143,7 @@ public final class EIP extends IntentService { gateway = gatewaysManager.select(); if (gateway != null && gateway.getProfile() != null) { - //mReceiver = VpnFragment.getReceiver(); + //mReceiver = EipFragment.getReceiver(); Log.d(TAG, "startAlwaysOnEIP eip launch avtive gateway vpn"); launchActiveGateway(); } else { @@ -147,7 +156,7 @@ public final class EIP extends IntentService { * VpnService is started properly. */ private void earlyRoutes() { - Intent voidVpnLauncher = new Intent(context, VoidVpnLauncher.class); + Intent voidVpnLauncher = new Intent(getApplicationContext(), VoidVpnLauncher.class); voidVpnLauncher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(voidVpnLauncher); } @@ -216,14 +225,14 @@ public final class EIP extends IntentService { private void gatewaysFromPreferences() { String gatewaysString = preferences.getString(Gateway.TAG, ""); - gatewaysManager = new GatewaysManager(context, preferences); + gatewaysManager = new GatewaysManager(getApplicationContext(), preferences); gatewaysManager.addFromString(gatewaysString); preferences.edit().remove(Gateway.TAG).apply(); } private void gatewaysToPreferences() { String gateways_string = gatewaysManager.toString(); - preferences.edit().putString(Gateway.TAG, gateways_string).commit(); + preferences.edit().putString(Gateway.TAG, gateways_string).apply(); } private void checkCertValidity() { diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java index ddf152d2..0da74872 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java @@ -16,13 +16,15 @@ */ package se.leap.bitmaskclient.eip; -import android.content.*; +import android.content.Context; import android.os.AsyncTask; import android.support.annotation.VisibleForTesting; -import java.util.*; +import java.util.Observable; -import de.blinkt.openvpn.core.*; +import de.blinkt.openvpn.core.ConnectionStatus; +import de.blinkt.openvpn.core.LogItem; +import de.blinkt.openvpn.core.VpnStatus; /** * EipStatus is a Singleton that represents a reduced set of a vpn's ConnectionStatus. @@ -31,7 +33,7 @@ import de.blinkt.openvpn.core.*; */ public class EipStatus extends Observable implements VpnStatus.StateListener { public static String TAG = EipStatus.class.getSimpleName(); - private static EipStatus current_status; + private static EipStatus currentStatus; public enum EipLevel { CONNECTING, DISCONNECTING, @@ -42,23 +44,23 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { } /** - * vpn_level holds the connection status of the openvpn vpn and the traffic blocking + * vpnLevel holds the connection status of the openvpn vpn and the traffic blocking * void vpn. LEVEL_BLOCKING is set when the latter vpn is up. All other states are set by * openvpn. */ - private ConnectionStatus vpn_level = ConnectionStatus.LEVEL_NOTCONNECTED; - private static EipLevel current_eip_level = EipLevel.DISCONNECTED; + private ConnectionStatus vpnLevel = ConnectionStatus.LEVEL_NOTCONNECTED; + private static EipLevel currentEipLevel = EipLevel.DISCONNECTED; - int last_error_line = 0; - private String state, log_message; - private int localized_res_id; + private int lastErrorLine = 0; + private String state, logMessage; + private int localizedResId; public static EipStatus getInstance() { - if (current_status == null) { - current_status = new EipStatus(); - VpnStatus.addStateListener(current_status); + if (currentStatus == null) { + currentStatus = new EipStatus(); + VpnStatus.addStateListener(currentStatus); } - return current_status; + return currentStatus; } private EipStatus() { @@ -66,16 +68,16 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { @Override public void updateState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { - ConnectionStatus tmp = current_status.getLevel(); - current_status = getInstance(); - current_status.setState(state); - current_status.setLogMessage(logmessage); - current_status.setLocalizedResId(localizedResId); - current_status.setLevel(level); - current_status.setEipLevel(level); - if (tmp != current_status.getLevel()) { - current_status.setChanged(); - current_status.notifyObservers(); + ConnectionStatus tmp = currentStatus.getLevel(); + currentStatus = getInstance(); + currentStatus.setState(state); + currentStatus.setLogMessage(logmessage); + currentStatus.setLocalizedResId(localizedResId); + currentStatus.setLevel(level); + currentStatus.setEipLevel(level); + if (tmp != currentStatus.getLevel()) { + currentStatus.setChanged(); + currentStatus.notifyObservers(); } } @@ -87,7 +89,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { private void setEipLevel(ConnectionStatus level) { switch (level) { case LEVEL_CONNECTED: - current_eip_level = EipLevel.CONNECTED; + currentEipLevel = EipLevel.CONNECTED; break; case LEVEL_VPNPAUSED: throw new IllegalStateException("Ics-Openvpn's VPNPAUSED state is not supported by Bitmask"); @@ -95,25 +97,25 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { case LEVEL_CONNECTING_NO_SERVER_REPLY_YET: case LEVEL_WAITING_FOR_USER_INPUT: case LEVEL_START: - current_eip_level = EipLevel.CONNECTING; + currentEipLevel = EipLevel.CONNECTING; break; case LEVEL_AUTH_FAILED: case LEVEL_NOTCONNECTED: - current_eip_level = EipLevel.DISCONNECTED; + currentEipLevel = EipLevel.DISCONNECTED; break; case LEVEL_NONETWORK: case LEVEL_BLOCKING: setEipLevelWithDelay(level); break; case UNKNOWN_LEVEL: - current_eip_level = EipLevel.UNKNOWN; //?? + currentEipLevel = EipLevel.UNKNOWN; //?? break; } } @VisibleForTesting EipLevel getEipLevel() { - return current_eip_level; + return currentEipLevel; } /** @@ -123,7 +125,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { * @param futureLevel */ private void setEipLevelWithDelay(ConnectionStatus futureLevel) { - new DelayTask(current_status.getLevel(), futureLevel).execute(); + new DelayTask(currentStatus.getLevel(), futureLevel).execute(); } private static class DelayTask extends AsyncTask { @@ -131,7 +133,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { private final ConnectionStatus currentLevel; private final ConnectionStatus futureLevel; - public DelayTask(ConnectionStatus currentLevel, ConnectionStatus futureLevel) { + DelayTask(ConnectionStatus currentLevel, ConnectionStatus futureLevel) { this.currentLevel = currentLevel; this.futureLevel = futureLevel; } @@ -144,38 +146,38 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { return null; } - protected void onPostExecute(Void result) {; - if (currentLevel == current_status.getLevel()) { + protected void onPostExecute(Void result) { + if (currentLevel == currentStatus.getLevel()) { switch (futureLevel) { case LEVEL_NONETWORK: - current_eip_level = EipLevel.DISCONNECTED; + currentEipLevel = EipLevel.DISCONNECTED; break; case LEVEL_BLOCKING: - current_eip_level = EipLevel.BLOCKING; + currentEipLevel = EipLevel.BLOCKING; break; default: break; } - current_status.setChanged(); - current_status.notifyObservers(); + currentStatus.setChanged(); + currentStatus.notifyObservers(); } } } public boolean isConnecting() { - return current_eip_level == EipLevel.CONNECTING; + return currentEipLevel == EipLevel.CONNECTING; } public boolean isConnected() { - return current_eip_level == EipLevel.CONNECTED; + return currentEipLevel == EipLevel.CONNECTED; } /** - * @return true if current_eip_level is for at least a second {@link EipLevel#BLOCKING}. + * @return true if currentEipLevel is for at least a second {@link EipLevel#BLOCKING}. * See {@link #setEipLevelWithDelay(ConnectionStatus)}. */ public boolean isBlocking() { - return current_eip_level == EipLevel.BLOCKING; + return currentEipLevel == EipLevel.BLOCKING; } /** @@ -183,20 +185,20 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { * @return true immediately after traffic blocking VoidVpn was established. */ public boolean isBlockingVpnEstablished() { - return vpn_level == ConnectionStatus.LEVEL_BLOCKING; + return vpnLevel == ConnectionStatus.LEVEL_BLOCKING; } public boolean isDisconnected() { - return current_eip_level == EipLevel.DISCONNECTED; + return currentEipLevel == EipLevel.DISCONNECTED; } /** * ics-openvpn's paused state is not implemented yet - * @return + * @return true if vpn is paused false if not */ @Deprecated public boolean isPaused() { - return vpn_level == ConnectionStatus.LEVEL_VPNPAUSED; + return vpnLevel == ConnectionStatus.LEVEL_VPNPAUSED; } public String getState() { @@ -204,15 +206,15 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { } public String getLogMessage() { - return log_message; + return logMessage; } - public int getLocalizedResId() { - return localized_res_id; + int getLocalizedResId() { + return localizedResId; } public ConnectionStatus getLevel() { - return vpn_level; + return vpnLevel; } private void setState(String state) { @@ -220,39 +222,40 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { } private void setLogMessage(String log_message) { - this.log_message = log_message; + this.logMessage = log_message; } private void setLocalizedResId(int localized_res_id) { - this.localized_res_id = localized_res_id; + this.localizedResId = localized_res_id; } private void setLevel(ConnectionStatus level) { - this.vpn_level = level; + this.vpnLevel = level; } public boolean errorInLast(int lines, Context context) { return !lastError(lines, context).isEmpty(); } - public String lastError(int lines, Context context) { + private String lastError(int lines, Context context) { String error = ""; String[] error_keywords = {"error", "ERROR", "fatal", "FATAL"}; LogItem[] log = VpnStatus.getlogbuffer(); - if(log.length < last_error_line) - last_error_line = 0; - String message = ""; + if(log.length < lastErrorLine) + lastErrorLine = 0; + String message; for (int i = 1; i <= lines && log.length > i; i++) { int line = log.length - i; - LogItem log_item = log[line]; - message = log_item.getString(context); - for (int j = 0; j < error_keywords.length; j++) - if (message.contains(error_keywords[j]) && line > last_error_line) { + LogItem logItem = log[line]; + message = logItem.getString(context); + for (String errorKeyword: error_keywords) { + if (message.contains(errorKeyword) && line > lastErrorLine) { error = message; - last_error_line = line; + lastErrorLine = line; } + } } return error; @@ -260,7 +263,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener { @Override public String toString() { - return "State: " + state + " Level: " + vpn_level.toString(); + return "State: " + state + " Level: " + vpnLevel.toString(); } } -- cgit v1.2.3 From 8333bd0ad9a6c4f6b07513d29ec8008e11a246dc Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Tue, 23 Jan 2018 16:12:59 +0100 Subject: check for correct provider --- .../bitmaskclient/BaseConfigurationWizard.java | 14 +++++++++----- .../bitmaskclient/ConfigWizardBaseActivity.java | 22 +++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java index 0726a785..375ef038 100644 --- a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java +++ b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java @@ -116,8 +116,6 @@ public abstract class BaseConfigurationWizard extends ConfigWizardBaseActivity @Override protected void onSaveInstanceState(@NotNull Bundle outState) { - //if (progressbarDescription != null) - // outState.putString(PROGRESSBAR_TEXT, progressbarDescription.getText().toString()); outState.putString(ACTIVITY_STATE, mConfigState.getAction()); outState.putParcelable(Provider.KEY, provider); @@ -447,15 +445,21 @@ public abstract class BaseConfigurationWizard extends ConfigWizardBaseActivity int resultCode = intent.getIntExtra(RESULT_CODE, -1); Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); + Bundle resultData = intent.getParcelableExtra(RESULT_KEY); + String handledProvider = resultData.getString(Provider.KEY); - if (getProviderName().equalsIgnoreCase(provider.getName()) && - getProviderDomain().equalsIgnoreCase(provider.getDomain())) { + String providerName = getProviderName(handledProvider); + String providerDomain = getProviderDomain(handledProvider); + + if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) && + providerDomain != null && + providerDomain.equalsIgnoreCase(provider.getDomain())) { switch (resultCode) { case PROVIDER_OK: handleProviderSetUp(); break; case PROVIDER_NOK: - handleProviderSetupFailed((Bundle) intent.getParcelableExtra(RESULT_KEY)); + handleProviderSetupFailed(resultData); break; case CORRECTLY_DOWNLOADED_CERTIFICATE: handleCorrectlyDownloadedCertificate(); diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java index 98715c1a..1ad12042 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java @@ -5,7 +5,6 @@ import android.os.Bundle; import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import android.support.annotation.StringRes; -import android.support.v4.app.FragmentTransaction; import android.support.v7.widget.AppCompatImageView; import android.support.v7.widget.AppCompatTextView; import android.view.View; @@ -18,7 +17,6 @@ import org.json.JSONObject; import java.util.Locale; import butterknife.InjectView; -import se.leap.bitmaskclient.userstatus.SessionDialog; import static android.view.View.GONE; import static android.view.View.VISIBLE; @@ -91,13 +89,20 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { } protected String getProviderName() { + return getProviderName(null); + } + + protected String getProviderName(@Nullable String provider) { + if (provider == null) { + provider = preferences.getString(Provider.KEY, ""); + } try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); + JSONObject providerJson = new JSONObject(provider); String lang = Locale.getDefault().getLanguage(); return providerJson.getJSONObject(Provider.NAME).getString(lang); } catch (JSONException e) { try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); + JSONObject providerJson = new JSONObject(provider); return providerJson.getJSONObject(Provider.NAME).getString("en"); } catch (JSONException e2) { return null; @@ -106,8 +111,15 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { } protected String getProviderDomain() { + return getProviderDomain(null); + } + + protected String getProviderDomain(@Nullable String provider) { + if (provider == null) { + provider = preferences.getString(Provider.KEY, ""); + } try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); + JSONObject providerJson = new JSONObject(provider); return providerJson.getString(Provider.DOMAIN); } catch (JSONException e) { return null; -- cgit v1.2.3 From 647ef6e32c3fdff4a29727ddc75cd97e399954af Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Thu, 25 Jan 2018 14:40:10 +0100 Subject: 8819 - fix using anonymous login --- .../java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java | 6 +++--- .../java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java index bd8ae228..b780e5f8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java @@ -22,8 +22,6 @@ import butterknife.InjectView; import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; -import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; -import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT; public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseActivity { @@ -74,7 +72,9 @@ public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseAct intent = new Intent(getApplicationContext(), SignupActivity.class); } else { Log.d(TAG, "use anonymously selected"); - setResult(RESULT_OK); + intent = new Intent(); + intent.putExtra(Provider.KEY, provider); + setResult(RESULT_OK, intent); finish(); return; } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java index f51618ad..25dca4e0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java @@ -24,8 +24,6 @@ import se.leap.bitmaskclient.userstatus.SessionDialog; import se.leap.bitmaskclient.userstatus.SessionDialog.ERRORS; import se.leap.bitmaskclient.userstatus.User; -import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT; - import static android.view.View.GONE; import static android.view.View.VISIBLE; import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE; -- cgit v1.2.3 From d8aaf3ca143a5afb71fb74675deb5be60a4204d9 Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Sat, 27 Jan 2018 04:17:38 +0100 Subject: fix first comments on merge request --- .../AbstractProviderDetailActivity.java | 4 +- .../bitmaskclient/BaseConfigurationWizard.java | 4 +- .../java/se/leap/bitmaskclient/ConfigHelper.java | 81 +++++++++++++++++++--- .../bitmaskclient/ConfigWizardBaseActivity.java | 48 +------------ .../java/se/leap/bitmaskclient/LoginActivity.java | 5 -- .../java/se/leap/bitmaskclient/MainActivity.java | 6 +- .../main/java/se/leap/bitmaskclient/Provider.java | 13 ++-- .../java/se/leap/bitmaskclient/StartActivity.java | 6 +- .../drawer/NavigationDrawerFragment.java | 2 +- 9 files changed, 97 insertions(+), 72 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java index b780e5f8..fbb27b58 100644 --- a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java @@ -40,8 +40,8 @@ public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseAct try { JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); - setProviderHeaderText(getProviderName()); - description.setText(providerJson.getJSONObject(Provider.DESCRIPTION).getString("en")); + setProviderHeaderText(ConfigHelper.getProviderName(preferences)); + description.setText(ConfigHelper.getDescription(preferences)); // Show only the options allowed by the provider ArrayList optionsList = new ArrayList<>(); diff --git a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java index 375ef038..ec4bbaec 100644 --- a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java +++ b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java @@ -448,8 +448,8 @@ public abstract class BaseConfigurationWizard extends ConfigWizardBaseActivity Bundle resultData = intent.getParcelableExtra(RESULT_KEY); String handledProvider = resultData.getString(Provider.KEY); - String providerName = getProviderName(handledProvider); - String providerDomain = getProviderDomain(handledProvider); + String providerName = ConfigHelper.getProviderName(handledProvider); + String providerDomain = ConfigHelper.getProviderDomain(handledProvider); if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) && providerDomain != null && diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index ccdf5064..f93fb36c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -18,8 +18,10 @@ package se.leap.bitmaskclient; import android.content.SharedPreferences; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.util.Log; +import org.jetbrains.annotations.NotNull; import org.json.JSONException; import org.json.JSONObject; import org.spongycastle.util.encoders.Base64; @@ -45,6 +47,7 @@ import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Locale; import static android.R.attr.name; import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; @@ -261,16 +264,6 @@ public class ConfigHelper { } - public static String getCurrentProviderName(@NonNull SharedPreferences preferences) { - try { - JSONObject providerDefintion = new JSONObject(preferences.getString(Provider.KEY, "")); - return providerDefintion.getString(Provider.DOMAIN); - } catch (JSONException e) { - e.printStackTrace(); - } - return null; - } - public static boolean providerInSharedPreferences(@NonNull SharedPreferences preferences) { return preferences.getBoolean(PROVIDER_CONFIGURED, false); } @@ -288,4 +281,72 @@ public class ConfigHelper { return provider; } + public static String getProviderName(String provider) { + return getProviderName(null, provider); + } + + public static String getProviderName(SharedPreferences preferences) { + return getProviderName(preferences,null); + } + + public static String getProviderName(SharedPreferences preferences, @Nullable String provider) { + if (provider == null) { + provider = preferences.getString(Provider.KEY, ""); + } + try { + JSONObject providerJson = new JSONObject(provider); + String lang = Locale.getDefault().getLanguage(); + return providerJson.getJSONObject(Provider.NAME).getString(lang); + } catch (JSONException e) { + try { + JSONObject providerJson = new JSONObject(provider); + return providerJson.getJSONObject(Provider.NAME).getString("en"); + } catch (JSONException e2) { + return null; + } + } + } + + public static String getProviderDomain(SharedPreferences preferences) { + return getProviderDomain(preferences, null); + } + + public static String getProviderDomain(String provider) { + return getProviderDomain(null, provider); + } + + public static String getProviderDomain(SharedPreferences preferences, @Nullable String provider) { + if (provider == null) { + provider = preferences.getString(Provider.KEY, ""); + } + try { + JSONObject providerJson = new JSONObject(provider); + return providerJson.getString(Provider.DOMAIN); + } catch (JSONException e) { + return null; + } + } + + public static String getDescription(SharedPreferences preferences) { + try { + JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); + String lang = Locale.getDefault().getLanguage(); + return providerJson.getJSONObject(Provider.DESCRIPTION).getString(lang); + } catch (JSONException e) { + try { + JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); + return providerJson.getJSONObject(Provider.DESCRIPTION).getString("en"); + } catch (JSONException e1) { + return null; + } + } + } + + public static void storeProviderInPreferences(SharedPreferences preferences, Provider provider) { + preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). + putString(Provider.MAIN_URL, provider.getMainUrlString()). + putString(Provider.KEY, provider.getDefinitionString()). + putString(Provider.CA_CERT, provider.getCaCert()). + apply(); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java index 1ad12042..79a78fe1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigWizardBaseActivity.java @@ -11,11 +11,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Locale; - import butterknife.InjectView; import static android.view.View.GONE; @@ -61,19 +56,19 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { @Override public void setContentView(View view) { super.setContentView(view); - setProviderHeaderText(getProviderName()); + setProviderHeaderText(ConfigHelper.getProviderName(preferences)); } @Override public void setContentView(int layoutResID) { super.setContentView(layoutResID); - setProviderHeaderText(getProviderName()); + setProviderHeaderText(ConfigHelper.getProviderName(preferences)); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { super.setContentView(view, params); - setProviderHeaderText(getProviderName()); + setProviderHeaderText(ConfigHelper.getProviderName(preferences)); } protected void setProviderHeaderLogo(@DrawableRes int providerHeaderLogo) { @@ -88,43 +83,6 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { this.providerHeaderText.setText(providerHeaderText); } - protected String getProviderName() { - return getProviderName(null); - } - - protected String getProviderName(@Nullable String provider) { - if (provider == null) { - provider = preferences.getString(Provider.KEY, ""); - } - try { - JSONObject providerJson = new JSONObject(provider); - String lang = Locale.getDefault().getLanguage(); - return providerJson.getJSONObject(Provider.NAME).getString(lang); - } catch (JSONException e) { - try { - JSONObject providerJson = new JSONObject(provider); - return providerJson.getJSONObject(Provider.NAME).getString("en"); - } catch (JSONException e2) { - return null; - } - } - } - - protected String getProviderDomain() { - return getProviderDomain(null); - } - - protected String getProviderDomain(@Nullable String provider) { - if (provider == null) { - provider = preferences.getString(Provider.KEY, ""); - } - try { - JSONObject providerJson = new JSONObject(provider); - return providerJson.getString(Provider.DOMAIN); - } catch (JSONException e) { - return null; - } - } protected void hideProgressBar() { loadingScreen.setVisibility(GONE); content.setVisibility(VISIBLE); diff --git a/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java b/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java index 6ae288c2..a407b0a9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/LoginActivity.java @@ -21,11 +21,6 @@ public class LoginActivity extends ProviderCredentialsBaseActivity { setProviderHeaderText(R.string.login_to_profile); } - @Override - protected void onResume() { - super.onResume(); - } - @Override @OnClick(R.id.button) void handleButton() { diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java index 3fc1637e..f4e2ac5f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java @@ -89,10 +89,14 @@ public class MainActivity extends AppCompatActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (data == null) { + return; + } + if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) { Provider provider = data.getParcelableExtra(Provider.KEY); - provider.storeInPreferences(preferences); + ConfigHelper.storeProviderInPreferences(preferences, provider); } } } diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 30504080..ae329cd1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -121,10 +121,18 @@ public final class Provider implements Parcelable { return definition; } + String getDefinitionString() { + return getDefinition().toString(); + } + protected String getDomain() { return mainUrl.getDomain(); } + String getMainUrlString() { + return getMainUrl().toString(); + } + protected DefaultedURL getMainUrl() { return mainUrl; } @@ -301,9 +309,4 @@ public final class Provider implements Parcelable { this.caCert = cert; } - public void storeInPreferences(SharedPreferences preferences) { - preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). - putString(Provider.MAIN_URL, getMainUrl().toString()). - putString(Provider.KEY, getDefinition().toString()).apply(); - } } diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java index 69079735..61e65f2d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java @@ -170,10 +170,14 @@ public class StartActivity extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (data == null) { + return; + } + if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) { Provider provider = data.getParcelableExtra(Provider.KEY); - provider.storeInPreferences(preferences); + ConfigHelper.storeProviderInPreferences(preferences, provider); showMainActivity(); } else if (resultCode == RESULT_CANCELED) { diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index dbe99dce..aae1e1ea 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -143,7 +143,7 @@ public class NavigationDrawerFragment extends Fragment { android.R.layout.simple_list_item_activated_1, android.R.id.text1); - String providerName = ConfigHelper.getCurrentProviderName(preferences); + String providerName = ConfigHelper.getProviderName(preferences); if (providerName == null) { //TODO: ADD A header to the ListView containing a useful message. //TODO 2: disable switchProvider -- cgit v1.2.3 From 0ad1b398e19a02dd725b253e15f6ded4d0cd641b Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Sat, 27 Jan 2018 04:26:20 +0100 Subject: resolve comments on merge request --- app/src/main/java/se/leap/bitmaskclient/eip/EIP.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 118622ab..eca5b881 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -122,8 +122,6 @@ public final class EIP extends IntentService { gateway = gatewaysManager.select(); if (gateway != null && gateway.getProfile() != null) { - // TODO why is this needed? - // mReceiver = EipFragment.getReceiver(); launchActiveGateway(); tellToReceiver(EIP_ACTION_START, Activity.RESULT_OK); } else @@ -143,7 +141,6 @@ public final class EIP extends IntentService { gateway = gatewaysManager.select(); if (gateway != null && gateway.getProfile() != null) { - //mReceiver = EipFragment.getReceiver(); Log.d(TAG, "startAlwaysOnEIP eip launch avtive gateway vpn"); launchActiveGateway(); } else { @@ -225,14 +222,14 @@ public final class EIP extends IntentService { private void gatewaysFromPreferences() { String gatewaysString = preferences.getString(Gateway.TAG, ""); - gatewaysManager = new GatewaysManager(getApplicationContext(), preferences); + gatewaysManager = new GatewaysManager(this, preferences); gatewaysManager.addFromString(gatewaysString); preferences.edit().remove(Gateway.TAG).apply(); } private void gatewaysToPreferences() { String gateways_string = gatewaysManager.toString(); - preferences.edit().putString(Gateway.TAG, gateways_string).apply(); + preferences.edit().putString(Gateway.TAG, gateways_string).commit(); } private void checkCertValidity() { -- cgit v1.2.3 From 3eb5405141d14a0c75c669c168b272878346cc38 Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Sat, 27 Jan 2018 16:09:38 +0100 Subject: fix comments for mergerequest --- .../bitmaskclient/BaseConfigurationWizard.java | 475 -------------------- .../java/se/leap/bitmaskclient/ConfigHelper.java | 10 +- .../main/java/se/leap/bitmaskclient/Dashboard.java | 10 +- .../bitmaskclient/ProviderListBaseActivity.java | 478 +++++++++++++++++++++ .../java/se/leap/bitmaskclient/StartActivity.java | 5 +- .../drawer/NavigationDrawerFragment.java | 4 +- 6 files changed, 492 insertions(+), 490 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java b/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java deleted file mode 100644 index ec4bbaec..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/BaseConfigurationWizard.java +++ /dev/null @@ -1,475 +0,0 @@ -/** - * Copyright (c) 2017 LEAP Encryption Access Project and contributors - * - * 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.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.os.Handler; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.ListView; - -import com.pedrogomez.renderers.Renderer; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; - -import butterknife.InjectView; -import butterknife.OnItemClick; -import se.leap.bitmaskclient.fragments.AboutFragment; - -import static android.view.View.GONE; -import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT; -import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; -import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; -import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; -import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE; -import static se.leap.bitmaskclient.ProviderAPI.ERRORS; -import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK; -import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP; -import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE; -import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY; - -/** - * abstract base Activity that builds and shows the list of known available providers. - * The implementation of BaseConfigurationWizard differ in that they may or may not allow to bypass - * secure download mechanisms including certificate validation. - *

- * It also allows the user to enter custom providers with a button. - * - * @author parmegv - * @author cyberta - */ - -public abstract class BaseConfigurationWizard extends ConfigWizardBaseActivity - implements NewProviderDialog.NewProviderDialogInterface, DownloadFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver { - - @InjectView(R.id.provider_list) - protected ListView providerListView; - @Inject - protected ProviderListAdapter adapter; - - private ProviderManager providerManager; - protected Intent mConfigState = new Intent(PROVIDER_NOT_SET); - - final public static String TAG = ConfigurationWizard.class.getSimpleName(); - - final private static String ACTIVITY_STATE = "ACTIVITY STATE"; - - final protected static String PROVIDER_NOT_SET = "PROVIDER NOT SET"; - final protected static String SETTING_UP_PROVIDER = "PROVIDER GETS SET"; - final private static String SHOWING_PROVIDER_DETAILS = "SHOWING PROVIDER DETAILS"; - final private static String PENDING_SHOW_FAILED_DIALOG = "SHOW FAILED DIALOG"; - final private static String REASON_TO_FAIL = "REASON TO FAIL"; - final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; - - public ProviderAPIResultReceiver providerAPIResultReceiver; - private ProviderAPIBroadcastReceiver providerAPIBroadcastReceiver; - - FragmentManagerEnhanced fragmentManager; - - private boolean isActivityShowing; - private String reasonToFail; - - public abstract void retrySetUpProvider(); - - protected abstract void onItemSelectedLogic(); - - - private void initProviderList() { - List> prototypes = new ArrayList<>(); - prototypes.add(new ProviderRenderer(this)); - ProviderRendererBuilder providerRendererBuilder = new ProviderRendererBuilder(prototypes); - adapter = new ProviderListAdapter(getLayoutInflater(), providerRendererBuilder, providerManager); - providerListView.setAdapter(adapter); - } - - @Override - protected void onSaveInstanceState(@NotNull Bundle outState) { - outState.putString(ACTIVITY_STATE, mConfigState.getAction()); - outState.putParcelable(Provider.KEY, provider); - - DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag(DownloadFailedDialog.TAG); - if (dialogFragment != null) { - outState.putString(REASON_TO_FAIL, reasonToFail); - dialogFragment.dismiss(); - } - - super.onSaveInstanceState(outState); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - fragmentManager = new FragmentManagerEnhanced(getSupportFragmentManager()); - providerManager = ProviderManager.getInstance(getAssets(), getExternalFilesDir(null)); - - setUpInitialUI(); - - initProviderList(); - - if (savedInstanceState != null) - restoreState(savedInstanceState); - setUpProviderAPIResultReceiver(); - } - - private void restoreState(Bundle savedInstanceState) { - - provider = savedInstanceState.getParcelable(Provider.KEY); - mConfigState.setAction(savedInstanceState.getString(ACTIVITY_STATE, PROVIDER_NOT_SET)); - - reasonToFail = savedInstanceState.getString(REASON_TO_FAIL); - if(reasonToFail != null) { - showDownloadFailedDialog(); - } - - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction()) - ) { - showProgressBar(); - } - } - - @Override - protected void onResume() { - Log.d(TAG, "resuming with ConfigState: " + mConfigState.getAction()); - super.onResume(); - hideProgressBar(); - isActivityShowing = true; - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction())) { - showProgressBar(); - adapter.hideAllBut(adapter.indexOf(provider)); - checkProviderSetUp(); - } else if (PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { - showDownloadFailedDialog(); - } else if (SHOWING_PROVIDER_DETAILS.equals(mConfigState.getAction())) { - cancelAndShowAllProviders(); - } - } - - private void setUpInitialUI() { - setContentView(R.layout.configuration_wizard_activity); - setProviderHeaderText(R.string.setup_provider); - hideProgressBar(); - } - - @Override - protected void onPause() { - super.onPause(); - isActivityShowing = false; - } - - @Override - protected void onDestroy() { - super.onDestroy(); - if (providerAPIBroadcastReceiver != null) - unregisterReceiver(providerAPIBroadcastReceiver); - providerAPIResultReceiver = null; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { - if (resultCode == RESULT_OK) { - setResult(resultCode, data); - finish(); - } - } - } - - private void setUpProviderAPIResultReceiver() { - providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), this); - providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver(); - - IntentFilter updateIntentFilter = new IntentFilter(PROVIDER_API_EVENT); - updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); - registerReceiver(providerAPIBroadcastReceiver, updateIntentFilter); - } - - void handleProviderSetUp() { - try { - String providerJsonString = preferences.getString(Provider.KEY, ""); - if (!providerJsonString.isEmpty()) - provider.define(new JSONObject(providerJsonString)); - String caCert = preferences.getString(Provider.CA_CERT, ""); - provider.setCACert(caCert); - } catch (JSONException e) { - e.printStackTrace(); - } - - if (preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false)) { - mConfigState.putExtra(SERVICES_RETRIEVED, true); - - downloadVpnCertificate(); - } else { - showProviderDetails(); - } - } - - void handleProviderSetupFailed(Bundle resultData) { - mConfigState.setAction(PROVIDER_NOT_SET); - preferences.edit().remove(Provider.KEY).apply(); - - setResult(RESULT_CANCELED, mConfigState); - - reasonToFail = resultData.getString(ERRORS); - showDownloadFailedDialog(); - } - - void handleCorrectlyDownloadedCertificate() { - showProviderDetails(); - } - - void handleIncorrectlyDownloadedCertificate() { - mConfigState.setAction(PROVIDER_NOT_SET); - hideProgressBar(); - setResult(RESULT_CANCELED, mConfigState); - } - - @Override - public void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == ProviderAPI.PROVIDER_OK) { - handleProviderSetUp(); - } else if (resultCode == AboutFragment.VIEWED) { - // Do nothing, right now - // I need this for CW to wait for the About activity to end before going back to Dashboard. - } - } - - @OnItemClick(R.id.provider_list) - void onItemSelected(int position) { - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { - return; - } - - //TODO Code 2 pane view - mConfigState.setAction(SETTING_UP_PROVIDER); - provider = adapter.getItem(position); - showProgressBar(); - onItemSelectedLogic(); - } - - @Override - public void onBackPressed() { - if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || - PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { - stopSettingUpProvider(); - } else { - askDashboardToQuitApp(); - super.onBackPressed(); - } - } - - private void stopSettingUpProvider() { - ProviderAPI.stop(); - loadingScreen.setVisibility(GONE); - - cancelSettingUpProvider(); - } - - @Override - public void cancelSettingUpProvider() { - hideProgressBar(); - mConfigState.setAction(PROVIDER_NOT_SET); - adapter.showAllProviders(); - preferences.edit().remove(Provider.KEY).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply(); - } - - @Override - public void updateProviderDetails() { - mConfigState.setAction(SETTING_UP_PROVIDER); - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - - providerAPICommand.setAction(ProviderAPI.UPDATE_PROVIDER_DETAILS); - Bundle parameters = new Bundle(); - parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); - providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); - - startService(providerAPICommand); - } - - public void checkProviderSetUp() { - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - providerAPICommand.setAction(PROVIDER_SET_UP); - providerAPICommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver); - startService(providerAPICommand); - } - - private void askDashboardToQuitApp() { - Intent askQuit = new Intent(); - askQuit.putExtra(APP_ACTION_QUIT, APP_ACTION_QUIT); - setResult(RESULT_CANCELED, askQuit); - } - - /** - * Asks ProviderApiService to download an anonymous (anon) VPN certificate. - */ - private void downloadVpnCertificate() { - Intent providerAPICommand = new Intent(this, ProviderAPI.class); - providerAPICommand.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); - startService(providerAPICommand); - } - - /** - * Open the new provider dialog - */ - public void addAndSelectNewProvider() { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); - new NewProviderDialog().show(fragmentTransaction, NewProviderDialog.TAG); - } - - /** - * Open the new provider dialog with data - */ - public void addAndSelectNewProvider(String main_url) { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); - - DialogFragment newFragment = new NewProviderDialog(); - Bundle data = new Bundle(); - data.putString(Provider.MAIN_URL, main_url); - newFragment.setArguments(data); - newFragment.show(fragmentTransaction, NewProviderDialog.TAG); - } - - /** - * Shows an error dialog, if configuring of a provider failed. - */ - public void showDownloadFailedDialog() { - try { - FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(DownloadFailedDialog.TAG); - DialogFragment newFragment; - try { - JSONObject errorJson = new JSONObject(reasonToFail); - newFragment = DownloadFailedDialog.newInstance(errorJson); - } catch (JSONException e) { - e.printStackTrace(); - newFragment = DownloadFailedDialog.newInstance(reasonToFail); - } - newFragment.show(fragmentTransaction, DownloadFailedDialog.TAG); - } catch (IllegalStateException e) { - e.printStackTrace(); - mConfigState.setAction(PENDING_SHOW_FAILED_DIALOG); - mConfigState.putExtra(REASON_TO_FAIL, reasonToFail); - } - - } - - /** - * 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. - * - * - */ - public void showProviderDetails() { - // show only if current activity is shown - if (isActivityShowing && mConfigState.getAction() != null && - !mConfigState.getAction().equalsIgnoreCase(SHOWING_PROVIDER_DETAILS)) { - mConfigState.setAction(SHOWING_PROVIDER_DETAILS); - Intent intent = new Intent(this, ProviderDetailActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - intent.putExtra(PROVIDER_KEY, provider); - startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP); - } - } - - @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, AboutFragment.class), 0); - return true; - case R.id.new_provider: - addAndSelectNewProvider(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - public void cancelAndShowAllProviders() { - mConfigState.setAction(PROVIDER_NOT_SET); - provider = null; - adapter.showAllProviders(); - } - - public class ProviderAPIBroadcastReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "received Broadcast"); - - String action = intent.getAction(); - if (action == null || !action.equalsIgnoreCase(PROVIDER_API_EVENT)) { - return; - } - - if (mConfigState.getAction() != null && - mConfigState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) { - int resultCode = intent.getIntExtra(RESULT_CODE, -1); - Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); - - Bundle resultData = intent.getParcelableExtra(RESULT_KEY); - String handledProvider = resultData.getString(Provider.KEY); - - String providerName = ConfigHelper.getProviderName(handledProvider); - String providerDomain = ConfigHelper.getProviderDomain(handledProvider); - - if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) && - providerDomain != null && - providerDomain.equalsIgnoreCase(provider.getDomain())) { - switch (resultCode) { - case PROVIDER_OK: - handleProviderSetUp(); - break; - case PROVIDER_NOK: - handleProviderSetupFailed(resultData); - break; - case CORRECTLY_DOWNLOADED_CERTIFICATE: - handleCorrectlyDownloadedCertificate(); - break; - case INCORRECTLY_DOWNLOADED_CERTIFICATE: - handleIncorrectlyDownloadedCertificate(); - break; - } - } - } - } - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index f93fb36c..3713e198 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -285,12 +285,12 @@ public class ConfigHelper { return getProviderName(null, provider); } - public static String getProviderName(SharedPreferences preferences) { + public static String getProviderName(@Nullable SharedPreferences preferences) { return getProviderName(preferences,null); } - public static String getProviderName(SharedPreferences preferences, @Nullable String provider) { - if (provider == null) { + public static String getProviderName(@Nullable SharedPreferences preferences, @Nullable String provider) { + if (provider == null && preferences != null) { provider = preferences.getString(Provider.KEY, ""); } try { @@ -315,8 +315,8 @@ public class ConfigHelper { return getProviderDomain(null, provider); } - public static String getProviderDomain(SharedPreferences preferences, @Nullable String provider) { - if (provider == null) { + public static String getProviderDomain(@Nullable SharedPreferences preferences, @Nullable String provider) { + if (provider == null && preferences != null) { provider = preferences.getString(Provider.KEY, ""); } try { diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 5ccb48b5..cb781009 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -232,7 +232,7 @@ public class Dashboard extends ButterKnifeActivity { private void handleConfigureAlwaysOn(Intent intent) { intent.removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); Log.d(TAG, "start Configuration wizard!"); - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } private void prepareEIP(Bundle savedInstanceState) { @@ -255,7 +255,7 @@ public class Dashboard extends ButterKnifeActivity { if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); } - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } @SuppressLint("CommitPrefEdits") private void providerToPreferences(Provider provider) { @@ -273,7 +273,7 @@ public class Dashboard extends ButterKnifeActivity { .setPositiveButton(getResources().getString(R.string.setup_error_configure_button), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - startActivityForResult(new Intent(Dashboard.this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(Dashboard.this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } }) .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { @@ -416,7 +416,7 @@ public class Dashboard extends ButterKnifeActivity { clearDataOfLastProvider(); switching_provider = false; - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); } private void clearDataOfLastProvider() { @@ -441,7 +441,7 @@ public class Dashboard extends ButterKnifeActivity { preferenceEditor.apply(); switching_provider = false; - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); } private static class DashboardReceiver implements ProviderAPIResultReceiver.Receiver{ diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java new file mode 100644 index 00000000..f60b5cc7 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java @@ -0,0 +1,478 @@ +/** + * Copyright (c) 2017 LEAP Encryption Access Project and contributors + * + * 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.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentTransaction; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ListView; + +import com.pedrogomez.renderers.Renderer; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.InjectView; +import butterknife.OnItemClick; +import se.leap.bitmaskclient.fragments.AboutFragment; + +import static android.view.View.GONE; +import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT; +import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; +import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; +import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; +import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.ERRORS; +import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_API_EVENT; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_OK; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_SET_UP; +import static se.leap.bitmaskclient.ProviderAPI.RESULT_CODE; +import static se.leap.bitmaskclient.ProviderAPI.RESULT_KEY; + +/** + * abstract base Activity that builds and shows the list of known available providers. + * The implementation of ProviderListBaseActivity differ in that they may or may not allow to bypass + * secure download mechanisms including certificate validation. + *

+ * It also allows the user to enter custom providers with a button. + * + * @author parmegv + * @author cyberta + */ + +public abstract class ProviderListBaseActivity extends ConfigWizardBaseActivity + implements NewProviderDialog.NewProviderDialogInterface, DownloadFailedDialog.DownloadFailedDialogInterface, ProviderAPIResultReceiver.Receiver { + + @InjectView(R.id.provider_list) + protected ListView providerListView; + @Inject + protected ProviderListAdapter adapter; + + private ProviderManager providerManager; + protected Intent mConfigState = new Intent(PROVIDER_NOT_SET); + + final public static String TAG = ProviderListActivity.class.getSimpleName(); + + final private static String ACTIVITY_STATE = "ACTIVITY STATE"; + + final protected static String PROVIDER_NOT_SET = "PROVIDER NOT SET"; + final protected static String SETTING_UP_PROVIDER = "PROVIDER GETS SET"; + final private static String SHOWING_PROVIDER_DETAILS = "SHOWING PROVIDER DETAILS"; + final private static String PENDING_SHOW_FAILED_DIALOG = "SHOW FAILED DIALOG"; + final private static String REASON_TO_FAIL = "REASON TO FAIL"; + final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; + + public ProviderAPIResultReceiver providerAPIResultReceiver; + private ProviderAPIBroadcastReceiver providerAPIBroadcastReceiver; + + FragmentManagerEnhanced fragmentManager; + + private boolean isActivityShowing; + private String reasonToFail; + + public abstract void retrySetUpProvider(); + + protected abstract void onItemSelectedLogic(); + + + private void initProviderList() { + List> prototypes = new ArrayList<>(); + prototypes.add(new ProviderRenderer(this)); + ProviderRendererBuilder providerRendererBuilder = new ProviderRendererBuilder(prototypes); + adapter = new ProviderListAdapter(getLayoutInflater(), providerRendererBuilder, providerManager); + providerListView.setAdapter(adapter); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + outState.putString(ACTIVITY_STATE, mConfigState.getAction()); + outState.putParcelable(Provider.KEY, provider); + + DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag(DownloadFailedDialog.TAG); + if (dialogFragment != null) { + outState.putString(REASON_TO_FAIL, reasonToFail); + dialogFragment.dismiss(); + } + + super.onSaveInstanceState(outState); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + fragmentManager = new FragmentManagerEnhanced(getSupportFragmentManager()); + providerManager = ProviderManager.getInstance(getAssets(), getExternalFilesDir(null)); + + setUpInitialUI(); + + initProviderList(); + + if (savedInstanceState != null) + restoreState(savedInstanceState); + setUpProviderAPIResultReceiver(); + } + + private void restoreState(Bundle savedInstanceState) { + + provider = savedInstanceState.getParcelable(Provider.KEY); + mConfigState.setAction(savedInstanceState.getString(ACTIVITY_STATE, PROVIDER_NOT_SET)); + + reasonToFail = savedInstanceState.getString(REASON_TO_FAIL); + if(reasonToFail != null) { + showDownloadFailedDialog(); + } + + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || + PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction()) + ) { + showProgressBar(); + } + } + + @Override + protected void onResume() { + Log.d(TAG, "resuming with ConfigState: " + mConfigState.getAction()); + super.onResume(); + hideProgressBar(); + isActivityShowing = true; + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction())) { + showProgressBar(); + adapter.hideAllBut(adapter.indexOf(provider)); + checkProviderSetUp(); + } else if (PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + showDownloadFailedDialog(); + } else if (SHOWING_PROVIDER_DETAILS.equals(mConfigState.getAction())) { + cancelAndShowAllProviders(); + } + } + + private void setUpInitialUI() { + setContentView(R.layout.configuration_wizard_activity); + setProviderHeaderText(R.string.setup_provider); + hideProgressBar(); + } + + @Override + protected void onPause() { + super.onPause(); + isActivityShowing = false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (providerAPIBroadcastReceiver != null) + unregisterReceiver(providerAPIBroadcastReceiver); + providerAPIResultReceiver = null; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { + if (resultCode == RESULT_OK) { + setResult(resultCode, data); + finish(); + } + } + } + + private void setUpProviderAPIResultReceiver() { + providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), this); + providerAPIBroadcastReceiver = new ProviderAPIBroadcastReceiver(); + + IntentFilter updateIntentFilter = new IntentFilter(PROVIDER_API_EVENT); + updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); + registerReceiver(providerAPIBroadcastReceiver, updateIntentFilter); + } + + void handleProviderSetUp() { + try { + String providerJsonString = preferences.getString(Provider.KEY, ""); + if (!providerJsonString.isEmpty()) + provider.define(new JSONObject(providerJsonString)); + String caCert = preferences.getString(Provider.CA_CERT, ""); + provider.setCACert(caCert); + } catch (JSONException e) { + e.printStackTrace(); + } + + if (preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false)) { + mConfigState.putExtra(SERVICES_RETRIEVED, true); + + downloadVpnCertificate(); + } else { + showProviderDetails(); + } + } + + void handleProviderSetupFailed(Bundle resultData) { + mConfigState.setAction(PROVIDER_NOT_SET); + preferences.edit().remove(Provider.KEY).apply(); + + setResult(RESULT_CANCELED, mConfigState); + + reasonToFail = resultData.getString(ERRORS); + showDownloadFailedDialog(); + } + + void handleCorrectlyDownloadedCertificate() { + showProviderDetails(); + } + + void handleIncorrectlyDownloadedCertificate() { + mConfigState.setAction(PROVIDER_NOT_SET); + hideProgressBar(); + setResult(RESULT_CANCELED, mConfigState); + } + + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + if (resultCode == ProviderAPI.PROVIDER_OK) { + handleProviderSetUp(); + } else if (resultCode == AboutFragment.VIEWED) { + // Do nothing, right now + // I need this for CW to wait for the About activity to end before going back to Dashboard. + } + } + + @OnItemClick(R.id.provider_list) + void onItemSelected(int position) { + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || + PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + return; + } + + //TODO Code 2 pane view + mConfigState.setAction(SETTING_UP_PROVIDER); + provider = adapter.getItem(position); + showProgressBar(); + onItemSelectedLogic(); + } + + @Override + public void onBackPressed() { + if (SETTING_UP_PROVIDER.equals(mConfigState.getAction()) || + PENDING_SHOW_FAILED_DIALOG.equals(mConfigState.getAction())) { + stopSettingUpProvider(); + } else { + askDashboardToQuitApp(); + super.onBackPressed(); + } + } + + private void stopSettingUpProvider() { + ProviderAPI.stop(); + loadingScreen.setVisibility(GONE); + + cancelSettingUpProvider(); + } + + @Override + public void cancelSettingUpProvider() { + hideProgressBar(); + mConfigState.setAction(PROVIDER_NOT_SET); + adapter.showAllProviders(); + preferences.edit().remove(Provider.KEY).remove(PROVIDER_ALLOW_ANONYMOUS).remove(PROVIDER_KEY).apply(); + } + + @Override + public void updateProviderDetails() { + mConfigState.setAction(SETTING_UP_PROVIDER); + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + + providerAPICommand.setAction(ProviderAPI.UPDATE_PROVIDER_DETAILS); + Bundle parameters = new Bundle(); + parameters.putString(Provider.MAIN_URL, provider.getMainUrl().toString()); + providerAPICommand.putExtra(ProviderAPI.PARAMETERS, parameters); + + startService(providerAPICommand); + } + + public void checkProviderSetUp() { + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + providerAPICommand.setAction(PROVIDER_SET_UP); + providerAPICommand.putExtra(ProviderAPI.RECEIVER_KEY, providerAPIResultReceiver); + startService(providerAPICommand); + } + + private void askDashboardToQuitApp() { + Intent askQuit = new Intent(); + askQuit.putExtra(APP_ACTION_QUIT, APP_ACTION_QUIT); + setResult(RESULT_CANCELED, askQuit); + } + + /** + * Asks ProviderApiService to download an anonymous (anon) VPN certificate. + */ + private void downloadVpnCertificate() { + Intent providerAPICommand = new Intent(this, ProviderAPI.class); + providerAPICommand.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + startService(providerAPICommand); + } + + /** + * Open the new provider dialog + */ + public void addAndSelectNewProvider() { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); + new NewProviderDialog().show(fragmentTransaction, NewProviderDialog.TAG); + } + + /** + * Open the new provider dialog with data + */ + public void addAndSelectNewProvider(String main_url) { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(NewProviderDialog.TAG); + + DialogFragment newFragment = new NewProviderDialog(); + Bundle data = new Bundle(); + data.putString(Provider.MAIN_URL, main_url); + newFragment.setArguments(data); + newFragment.show(fragmentTransaction, NewProviderDialog.TAG); + } + + /** + * Shows an error dialog, if configuring of a provider failed. + */ + public void showDownloadFailedDialog() { + try { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(DownloadFailedDialog.TAG); + DialogFragment newFragment; + try { + JSONObject errorJson = new JSONObject(reasonToFail); + newFragment = DownloadFailedDialog.newInstance(errorJson); + } catch (JSONException e) { + e.printStackTrace(); + newFragment = DownloadFailedDialog.newInstance(reasonToFail); + } + newFragment.show(fragmentTransaction, DownloadFailedDialog.TAG); + } catch (IllegalStateException e) { + e.printStackTrace(); + mConfigState.setAction(PENDING_SHOW_FAILED_DIALOG); + mConfigState.putExtra(REASON_TO_FAIL, reasonToFail); + } + + } + + /** + * 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. + * + * + */ + public void showProviderDetails() { + // show only if current activity is shown + if (isActivityShowing && mConfigState.getAction() != null && + !mConfigState.getAction().equalsIgnoreCase(SHOWING_PROVIDER_DETAILS)) { + mConfigState.setAction(SHOWING_PROVIDER_DETAILS); + Intent intent = new Intent(this, ProviderDetailActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent.putExtra(PROVIDER_KEY, provider); + startActivityForResult(intent, REQUEST_CODE_CONFIGURE_LEAP); + } + } + + @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, AboutFragment.class), 0); + return true; + case R.id.new_provider: + addAndSelectNewProvider(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void cancelAndShowAllProviders() { + mConfigState.setAction(PROVIDER_NOT_SET); + provider = null; + adapter.showAllProviders(); + } + + public class ProviderAPIBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "received Broadcast"); + + String action = intent.getAction(); + if (action == null || !action.equalsIgnoreCase(PROVIDER_API_EVENT)) { + return; + } + + if (mConfigState.getAction() != null && + mConfigState.getAction().equalsIgnoreCase(SETTING_UP_PROVIDER)) { + int resultCode = intent.getIntExtra(RESULT_CODE, -1); + Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); + + Bundle resultData = intent.getParcelableExtra(RESULT_KEY); + String handledProvider = resultData.getString(Provider.KEY); + + String providerName = ConfigHelper.getProviderName(handledProvider); + String providerDomain = ConfigHelper.getProviderDomain(handledProvider); + + if (providerName != null && providerName.equalsIgnoreCase(provider.getName()) && + providerDomain != null && + providerDomain.equalsIgnoreCase(provider.getDomain())) { + switch (resultCode) { + case PROVIDER_OK: + handleProviderSetUp(); + break; + case PROVIDER_NOK: + handleProviderSetupFailed(resultData); + break; + } + } else { + switch (resultCode) { + case CORRECTLY_DOWNLOADED_CERTIFICATE: + handleCorrectlyDownloadedCertificate(); + break; + case INCORRECTLY_DOWNLOADED_CERTIFICATE: + handleIncorrectlyDownloadedCertificate(); + break; + } + } + } + } + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java index 61e65f2d..f5991538 100644 --- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java @@ -17,7 +17,6 @@ import se.leap.bitmaskclient.userstatus.User; import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE; import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION; -import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; @@ -56,7 +55,7 @@ public class StartActivity extends Activity { case FIRST: storeAppVersion(); // TODO start ProfileCreation & replace below code - // (new Intent(getActivity(), ConfigurationWizard.class), Constants.REQUEST_CODE_SWITCH_PROVIDER); + // (new Intent(getActivity(), ProviderListActivity.class), Constants.REQUEST_CODE_SWITCH_PROVIDER); break; case UPGRADE: @@ -165,7 +164,7 @@ public class StartActivity extends Activity { if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); } - startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP); + startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index aae1e1ea..ebfb3ba7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -27,7 +27,7 @@ import android.widget.ListView; import android.widget.Toast; import se.leap.bitmaskclient.ConfigHelper; -import se.leap.bitmaskclient.ConfigurationWizard; +import se.leap.bitmaskclient.ProviderListActivity; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.VpnFragment; import se.leap.bitmaskclient.fragments.AboutFragment; @@ -304,7 +304,7 @@ public class NavigationDrawerFragment extends Fragment { // TODO STOP VPN // if (provider.hasEIP()) eip_fragment.stopEipIfPossible(); preferences.edit().clear().apply(); - startActivityForResult(new Intent(getActivity(), ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER); + startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); break; case 1: mTitle = getString(R.string.log_fragment_title); -- cgit v1.2.3 From c89fd2f73f8a84f9ef7742e39476a9645e6d3863 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 1 Feb 2018 15:30:39 +0100 Subject: #8832 add all ics-openvpn code changes --- app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 24 +---- .../main/java/de/blinkt/openvpn/VpnProfile.java | 117 ++++++++++++++------- .../java/de/blinkt/openvpn/core/ConfigParser.java | 5 +- .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 2 +- .../de/blinkt/openvpn/core/OpenVPNService.java | 49 +++++---- .../java/de/blinkt/openvpn/core/OpenVPNThread.java | 5 +- .../openvpn/core/OpenVpnManagementThread.java | 19 ++-- .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 1 - .../de/blinkt/openvpn/fragments/LogFragment.java | 1 - 9 files changed, 130 insertions(+), 93 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 0c3f20fb..4fff3071 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -5,47 +5,27 @@ package de.blinkt.openvpn; -import se.leap.bitmaskclient.R; - -import se.leap.bitmaskclient.R; - -import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.ActivityNotFoundException; -import android.content.ComponentName; -import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; -import android.content.ServiceConnection; import android.content.SharedPreferences; import android.net.VpnService; import android.os.Build; import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.preference.PreferenceManager; -import android.text.InputType; -import android.text.TextUtils; -import android.text.method.PasswordTransformationMethod; -import android.view.View; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.EditText; import java.io.IOException; import de.blinkt.openvpn.activities.LogWindow; import de.blinkt.openvpn.core.ConnectionStatus; -import de.blinkt.openvpn.core.IServiceStatus; -import de.blinkt.openvpn.core.OpenVPNStatusService; -import de.blinkt.openvpn.core.PasswordCache; import de.blinkt.openvpn.core.Preferences; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VPNLaunchHelper; import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.R; /** * This Activity actually handles two stages of a launcher shortcut's life cycle. @@ -134,7 +114,7 @@ public class LaunchVPN extends Activity { } @Override - protected void onActivityResult (int requestCode, int resultCode, Intent data) { + protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==START_VPN_PROFILE) { diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index aa25da48..1d6f41cd 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -5,6 +5,8 @@ package de.blinkt.openvpn; +import de.blinkt.openvpn.core.Preferences; +import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; import android.annotation.SuppressLint; @@ -36,6 +38,8 @@ import java.lang.reflect.Method; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.Signature; +import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -182,7 +186,6 @@ public class VpnProfile implements Serializable, Cloneable { public boolean mUseUdp = true; - public VpnProfile(String name) { mUuid = UUID.randomUUID(); mName = name; @@ -282,30 +285,42 @@ public class VpnProfile implements Serializable, Cloneable { } + + public static boolean doUseOpenVPN3(Context c) { + SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c); + boolean useOpenVPN3 = prefs.getBoolean("ovpn3", false); + if ("noovpn3".equals(BuildConfig.FLAVOR)) + useOpenVPN3 = false; + return useOpenVPN3; + } + public String getConfigFile(Context context, boolean configForOvpn3) { File cacheDir = context.getCacheDir(); String cfg = ""; - // Enable management interface - cfg += "# Enables connection to GUI\n"; - cfg += "management "; - - cfg += cacheDir.getAbsolutePath() + "/" + "mgmtsocket"; - cfg += " unix\n"; - cfg += "management-client\n"; - // Not needed, see updated man page in 2.3 - //cfg += "management-signal\n"; - cfg += "management-query-passwords\n"; - cfg += "management-hold\n\n"; - if (!configForOvpn3) { + // Enable management interface + cfg += "# Config for OpenVPN 2.x\n"; + cfg += "# Enables connection to GUI\n"; + cfg += "management "; + + cfg += cacheDir.getAbsolutePath() + "/" + "mgmtsocket"; + cfg += " unix\n"; + cfg += "management-client\n"; + // Not needed, see updated man page in 2.3 + //cfg += "management-signal\n"; + cfg += "management-query-passwords\n"; + cfg += "management-hold\n\n"; + cfg += String.format("setenv IV_GUI_VER %s \n", openVpnEscape(getVersionEnvString(context))); - String versionString = String.format(Locale.US, "%d %s %s %s %s %s", Build.VERSION.SDK_INT, Build.VERSION.RELEASE, - NativeUtils.getNativeAPI(), Build.BRAND, Build.BOARD, Build.MODEL); + String versionString = getPlatformVersionEnvString(); cfg += String.format("setenv IV_PLAT_VER %s\n", openVpnEscape(versionString)); + } else { + cfg += "# Config for OpeNVPN 3 C++\n"; } + cfg += "machine-readable-output\n"; cfg += "allow-recursive-routing\n"; @@ -418,8 +433,7 @@ public class VpnProfile implements Serializable, Cloneable { cfg += insertFileData("ca", mCaFilename); } - if (isUserPWAuth()) - { + if (isUserPWAuth()) { if (mAuthenticationType == AUTH_RETRY_NOINTERACT) cfg += "auth-retry nointeract"; } @@ -456,7 +470,7 @@ public class VpnProfile implements Serializable, Cloneable { if (!TextUtils.isEmpty(mIPv6Address)) { // Use our own ip as gateway since we ignore it anyway String fakegw = mIPv6Address.split("/", 2)[0]; - cfg += "ifconfig-ipv6 " + mIPv6Address + " " + fakegw +"\n"; + cfg += "ifconfig-ipv6 " + mIPv6Address + " " + fakegw + "\n"; } } @@ -490,16 +504,12 @@ public class VpnProfile implements Serializable, Cloneable { if (mOverrideDNS || !mUsePull) { if (!TextUtils.isEmpty(mDNS1)) { - if (mDNS1.contains(":")) - cfg += "dhcp-option DNS6 " + mDNS1 + "\n"; - else - cfg += "dhcp-option DNS " + mDNS1 + "\n"; - } if (!TextUtils.isEmpty(mDNS2)) { - if (mDNS2.contains(":")) - cfg += "dhcp-option DNS6 " + mDNS2 + "\n"; - else - cfg += "dhcp-option DNS " + mDNS2 + "\n"; - } if (!TextUtils.isEmpty(mSearchDomain)) + cfg += "dhcp-option DNS " + mDNS1 + "\n"; + } + if (!TextUtils.isEmpty(mDNS2)) { + cfg += "dhcp-option DNS " + mDNS2 + "\n"; + } + if (!TextUtils.isEmpty(mSearchDomain)) cfg += "dhcp-option DOMAIN " + mSearchDomain + "\n"; } @@ -511,9 +521,8 @@ public class VpnProfile implements Serializable, Cloneable { cfg += "mssfix\n"; } - if (mTunMtu >= 48 && mTunMtu != 1500) - { - cfg+= String.format(Locale.US, "tun-mtu %d\n", mTunMtu); + if (mTunMtu >= 48 && mTunMtu != 1500) { + cfg += String.format(Locale.US, "tun-mtu %d\n", mTunMtu); } if (mNobind) @@ -580,7 +589,7 @@ public class VpnProfile implements Serializable, Cloneable { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true); - if (usesystemproxy && !mIsOpenVPN22) { + if (usesystemproxy && !mIsOpenVPN22 && !configForOvpn3) { cfg += "# Use system proxy setting\n"; cfg += "management-query-proxy\n"; } @@ -609,6 +618,11 @@ public class VpnProfile implements Serializable, Cloneable { return cfg; } + public String getPlatformVersionEnvString() { + return String.format(Locale.US, "%d %s %s %s %s %s", Build.VERSION.SDK_INT, Build.VERSION.RELEASE, + NativeUtils.getNativeAPI(), Build.BRAND, Build.BOARD, Build.MODEL); + } + public String getVersionEnvString(Context c) { String version = "unknown"; try { @@ -907,12 +921,12 @@ public class VpnProfile implements Serializable, Cloneable { if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE) { if (mAlias == null) return R.string.no_keystore_cert_selected; - } else if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES){ + } else if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) { if (TextUtils.isEmpty(mCaFilename)) return R.string.no_ca_cert_selected; } - if (mCheckRemoteCN && mX509AuthType==X509_VERIFY_TLSREMOTE) + if (mCheckRemoteCN && mX509AuthType == X509_VERIFY_TLSREMOTE) return R.string.deprecated_tls_remote; if (!mUsePull || mAuthenticationType == TYPE_STATICKEYS) { @@ -948,6 +962,15 @@ public class VpnProfile implements Serializable, Cloneable { if (noRemoteEnabled) return R.string.remote_no_server_selected; + if (doUseOpenVPN3(context)) { + if (mAuthenticationType == TYPE_STATICKEYS) { + return R.string.openvpn3_nostatickeys; + } + if (mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) { + return R.string.openvpn3_pkcs12; + } + } + // Everything okay return R.string.no_error_found; @@ -1068,7 +1091,7 @@ public class VpnProfile implements Serializable, Cloneable { return mPrivateKey; } - public String getSignedData(String b64data) { + public String getSignedData(String b64data, boolean ecdsa) { PrivateKey privkey = getKeystoreKey(); byte[] data = Base64.decode(b64data, Base64.DEFAULT); @@ -1081,19 +1104,33 @@ public class VpnProfile implements Serializable, Cloneable { try { + @SuppressLint("GetInstance") + String keyalgorithm = privkey.getAlgorithm(); + + byte[] signed_bytes; + if (keyalgorithm.equals("EC")) { + Signature signer = Signature.getInstance("NONEwithECDSA"); + + signer.initSign(privkey); + signer.update(data); + signed_bytes = signer.sign(); + + } else { /* ECB is perfectly fine in this special case, since we are using it for the public/private part in the TLS exchange */ - @SuppressLint("GetInstance") - Cipher rsaSigner = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); + Cipher signer; + signer = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); + - rsaSigner.init(Cipher.ENCRYPT_MODE, privkey); + signer.init(Cipher.ENCRYPT_MODE, privkey); - byte[] signed_bytes = rsaSigner.doFinal(data); + signed_bytes = signer.doFinal(data); + } return Base64.encodeToString(signed_bytes, Base64.NO_WRAP); } catch (NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException - | BadPaddingException | NoSuchPaddingException e) { + | BadPaddingException | NoSuchPaddingException | SignatureException e) { VpnStatus.logError(R.string.error_rsa_sign, e.getClass().toString(), e.getLocalizedMessage()); return null; } 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 74afd61e..9889754d 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -261,6 +261,7 @@ public class ConfigParser { "group", "allow-recursive-routing", "ip-win32", + "ifconfig-nowarn", "management-hold", "management", "management-client", @@ -275,6 +276,7 @@ public class ConfigParser { "management-client-user", "management-client-group", "pause-exit", + "preresolve", "plugin", "machine-readable-output", "persist-key", @@ -300,7 +302,8 @@ public class ConfigParser { {"setenv", "IV_GUI_VER"}, {"setenv", "IV_OPENVPN_GUI_VERSION"}, {"engine", "dynamic"}, - {"setenv", "CLIENT_CERT"} + {"setenv", "CLIENT_CERT"}, + {"resolve-retry","60"} }; final String[] connectionOptions = { 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 e7019f42..38f51807 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -57,7 +57,7 @@ public class ICSOpenVPNApplication extends Application { name = getString(R.string.channel_name_status); mChannel = new NotificationChannel(OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID, - name, NotificationManager.IMPORTANCE_DEFAULT); + name, NotificationManager.IMPORTANCE_LOW); mChannel.setDescription(getString(R.string.channel_description_status)); mChannel.enableLights(true); 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 c15f659a..6c312c87 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -11,7 +11,6 @@ import android.app.Notification; import android.app.UiModeManager; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ShortcutManager; import android.content.res.Configuration; @@ -43,7 +42,6 @@ import java.util.Vector; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; import de.blinkt.openvpn.core.VpnStatus.StateListener; -import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.VpnNotificationManager; @@ -61,6 +59,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private static final String RESUME_VPN = "se.leap.bitmaskclient.RESUME_VPN"; public static final String NOTIFICATION_CHANNEL_BG_ID = "openvpn_bg"; public static final String NOTIFICATION_CHANNEL_NEWSTATUS_ID = "openvpn_newstat"; + public static final String VPNSERVICE_TUN = "vpnservice-tun"; private static boolean mNotificationAlwaysVisible = false; private final Vector mDnslist = new Vector<>(); @@ -76,7 +75,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private boolean mDisplayBytecount = false; private boolean mStarting = false; private long mConnecttime; - private boolean mOvpn3 = false; private OpenVPNManagement mManagement; private String mLastTunCfg; private String mRemoteGW; @@ -169,7 +167,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } // Similar to revoke but do not try to stop process - public void processDied() { + public void openvpnStopped() { endVpnService(); } @@ -291,6 +289,18 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac return START_REDELIVER_INTENT; } + /* TODO: check that for Bitmask */ + // Always show notification here to avoid problem with startForeground timeout + VpnStatus.logInfo(R.string.building_configration); + VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, ConnectionStatus.LEVEL_START); + notificationManager.buildOpenVpnNotification( + mProfile != null ? mProfile.mName : "", + VpnStatus.getLastCleanLogMessage(this), + VpnStatus.getLastCleanLogMessage(this), + ConnectionStatus.LEVEL_START, + 0, + NOTIFICATION_CHANNEL_NEWSTATUS_ID); + if (intent != null && intent.hasExtra(getPackageName() + ".profileUUID")) { String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID"); int profileVersion = intent.getIntExtra(getPackageName() + ".profileVersion", 0); @@ -319,6 +329,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mProfile.checkForRestart(this); } + if (mProfile == null) { + stopSelf(startId); + return START_NOT_STICKY; + } + + /* start the OpenVPN process itself in a background thread */ new Thread(new Runnable() { @Override @@ -343,6 +359,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } private void startOpenVPN() { + /** + * see change above (l. 292 ff) + */ VpnStatus.logInfo(R.string.building_configration); VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, ConnectionStatus.LEVEL_START); @@ -369,14 +388,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac mStarting = false; // Start a new session by creating a new thread. - SharedPreferences prefs = Preferences.getDefaultSharedPreferences(this); - - mOvpn3 = prefs.getBoolean("ovpn3", false); - if (!"ovpn3".equals(BuildConfig.FLAVOR)) - mOvpn3 = false; + boolean useOpenVPN3 = VpnProfile.doUseOpenVPN3(this); // Open the Management Interface - if (!mOvpn3) { + if (!useOpenVPN3) { // start a Thread that handles incoming messages of the managment socket OpenVpnManagementThread ovpnManagementThread = new OpenVpnManagementThread(mProfile, this); if (ovpnManagementThread.openManagementInterface(this)) { @@ -392,15 +407,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } Runnable processThread; - if (mOvpn3) - + if (useOpenVPN3) { - OpenVPNManagement mOpenVPN3 = instantiateOpenVPN3Core(); processThread = (Runnable) mOpenVPN3; mManagement = mOpenVPN3; - - } else { processThread = new OpenVPNThread(this, argv, nativeLibraryDirectory); mOpenVPNThread = processThread; @@ -757,8 +768,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac /** * Route that is always included, used by the v3 core */ - public void addRoute(CIDRIP route) { - mRoutes.addIP(route, true); + public void addRoute(CIDRIP route, boolean include) { + mRoutes.addIP(route, include); } public void addRoute(String dest, String mask, String gateway, String device) { @@ -810,7 +821,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private boolean isAndroidTunDevice(String device) { return device != null && - (device.startsWith("tun") || "(null)".equals(device) || "vpnservice-tun".equals(device)); + (device.startsWith("tun") || "(null)".equals(device) || VPNSERVICE_TUN.equals(device)); } public void setMtu(int mtu) { @@ -859,7 +870,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if (mLocalIP.len <= 31 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CIDRIP interfaceRoute = new CIDRIP(mLocalIP.mIp, mLocalIP.len); interfaceRoute.normalise(); - addRoute(interfaceRoute); + addRoute(interfaceRoute ,true); } 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 c96f88c4..b902f5d7 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -111,7 +111,8 @@ public class OpenVPNThread implements Runnable { } } - mService.processDied(); + if (!mNoProcessExitStatus) + mService.openvpnStopped(); Log.i(TAG, "Exiting"); } } @@ -177,7 +178,7 @@ public class OpenVPNThread implements Runnable { VpnStatus.logMessageOpenVPN(logStatus, logLevel, msg); if (logerror==1) - VpnStatus.logError("OpenSSL reproted a certificate with a weak hash, please the in app FAQ about weak hashes"); + VpnStatus.logError("OpenSSL reported a certificate with a weak hash, please the in app FAQ about weak hashes"); } else { VpnStatus.logInfo("P:" + logline); 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 492e8913..1124c5b7 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -260,7 +260,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { processLogMessage(argument); break; case "RSA_SIGN": - processSignCommand(argument); + processSignCommand(argument, false); + break; + case "ECDSA_SIGN": + processSignCommand(argument, true); break; default: VpnStatus.logWarning("MGMT: Got unrecognized command" + command); @@ -606,7 +609,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { if (mWaitingForRelease) releaseHold(); else if (samenetwork) - managmentCommand("network-change\n"); + managmentCommand("network-change samenetwork\n"); else managmentCommand("network-change\n"); } @@ -631,16 +634,20 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { releaseHold(); } - private void processSignCommand(String b64data) { + private void processSignCommand(String b64data, boolean ecdsa) { + + String signed_string = mProfile.getSignedData(b64data, ecdsa); + String signcmd = "rsa-sig\n"; + if (ecdsa) + signcmd = "ecdsa-sig\n"; - String signed_string = mProfile.getSignedData(b64data); if (signed_string == null) { - managmentCommand("rsa-sig\n"); + managmentCommand(signcmd); managmentCommand("\nEND\n"); stopOpenVPN(); return; } - managmentCommand("rsa-sig\n"); + managmentCommand(signcmd); managmentCommand(signed_string); managmentCommand("\nEND\n"); } 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 f3b40381..97a73964 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -6,7 +6,6 @@ package de.blinkt.openvpn.core; import android.annotation.TargetApi; -import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.os.Build; 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 a1fc7cdc..1a207a25 100644 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -23,7 +23,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; -import android.preference.Preference; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.text.SpannableString; -- cgit v1.2.3 From d4633f0549b3c3c23e27fba3ab14d1a1a62978af Mon Sep 17 00:00:00 2001 From: cyBerta Date: Tue, 6 Feb 2018 14:09:37 +0100 Subject: #8832 more upsteam changes --- app/src/main/java/de/blinkt/openvpn/VpnProfile.java | 20 ++++---------------- .../java/de/blinkt/openvpn/core/NativeUtils.java | 7 +++++++ .../blinkt/openvpn/core/OpenVpnManagementThread.java | 19 +++++++------------ 3 files changed, 18 insertions(+), 28 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index 1d6f41cd..1cef6670 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -5,7 +5,6 @@ package de.blinkt.openvpn; -import de.blinkt.openvpn.core.Preferences; import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; @@ -23,6 +22,7 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Base64; +import de.blinkt.openvpn.core.*; import org.spongycastle.util.io.pem.PemObject; import org.spongycastle.util.io.pem.PemWriter; @@ -35,11 +35,7 @@ import java.io.Serializable; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.SignatureException; +import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -54,14 +50,6 @@ import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; -import de.blinkt.openvpn.core.Connection; -import de.blinkt.openvpn.core.NativeUtils; -import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.PasswordCache; -import de.blinkt.openvpn.core.VPNLaunchHelper; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.X509Utils; - public class VpnProfile implements Serializable, Cloneable { // Note that this class cannot be moved to core where it belongs since // the profile loading depends on it being here @@ -289,7 +277,7 @@ public class VpnProfile implements Serializable, Cloneable { public static boolean doUseOpenVPN3(Context c) { SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c); boolean useOpenVPN3 = prefs.getBoolean("ovpn3", false); - if ("noovpn3".equals(BuildConfig.FLAVOR)) + if (!BuildConfig.openvpn3) useOpenVPN3 = false; return useOpenVPN3; } @@ -1091,7 +1079,7 @@ public class VpnProfile implements Serializable, Cloneable { return mPrivateKey; } - public String getSignedData(String b64data, boolean ecdsa) { + public String getSignedData(String b64data) { PrivateKey privkey = getKeystoreKey(); byte[] data = Base64.decode(b64data, Base64.DEFAULT); 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 ea003d41..70c7455a 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -18,6 +18,13 @@ public class NativeUtils { public static native String getNativeAPI(); + + public final static int[] openSSLlengths = { + 16, 64, 256, 1024, 8 * 1024, 16 * 1024 + }; + + public static native double[] getOpenSSLSpeed(String algorithm, int testnum); + static { System.loadLibrary("opvpnutil"); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) 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 1124c5b7..2b6df9af 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -148,6 +148,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { // Closing one of the two sockets also closes the other //mServerSocketLocal.close(); + managmentCommand("version 2\n"); while (true) { @@ -259,11 +260,8 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { case "LOG": processLogMessage(argument); break; - case "RSA_SIGN": - processSignCommand(argument, false); - break; - case "ECDSA_SIGN": - processSignCommand(argument, true); + case "PK_SIGN": + processSignCommand(argument); break; default: VpnStatus.logWarning("MGMT: Got unrecognized command" + command); @@ -634,20 +632,17 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { releaseHold(); } - private void processSignCommand(String b64data, boolean ecdsa) { + private void processSignCommand(String b64data) { - String signed_string = mProfile.getSignedData(b64data, ecdsa); - String signcmd = "rsa-sig\n"; - if (ecdsa) - signcmd = "ecdsa-sig\n"; + String signed_string = mProfile.getSignedData(b64data); if (signed_string == null) { - managmentCommand(signcmd); + managmentCommand("pk-sig\n"); managmentCommand("\nEND\n"); stopOpenVPN(); return; } - managmentCommand(signcmd); + managmentCommand("pk-sig\n"); managmentCommand(signed_string); managmentCommand("\nEND\n"); } -- cgit v1.2.3 From d2d61a16fd2a3ea0fd42073de98d1311b184444d Mon Sep 17 00:00:00 2001 From: cyBerta Date: Tue, 6 Feb 2018 14:31:07 +0100 Subject: fix build after reenabling copy classes from ics-openvpn build job --- app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 2 ++ app/src/main/java/de/blinkt/openvpn/VpnProfile.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 4fff3071..b2bf6b46 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -5,6 +5,8 @@ package de.blinkt.openvpn; +import se.leap.bitmaskclient.R; + import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index 1cef6670..4becdc32 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -5,9 +5,10 @@ package de.blinkt.openvpn; -import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.BuildConfig; + import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -- cgit v1.2.3