From 268a7f205fa09edc145aace8bed30f75270a801f Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Tue, 6 Feb 2018 17:02:00 +0100 Subject: 8827 - handle switch provider correctly * ProviderAPI no longer stores values in SharedPreferences * use EipCommand to start / stop EIP * update NavigationDrawer after changing provider * use Broadcasts for ProviderAPI * parse more properties from definition into Provider * ProviderApi no longer uses static variables * no more static Context in ProviderApiCommand --- .../java/se/leap/bitmaskclient/EipFragment.java | 216 +++++++++++++-------- 1 file changed, 136 insertions(+), 80 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/EipFragment.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index 414b1f2a..9726ebf2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -18,10 +18,12 @@ package se.leap.bitmaskclient; import android.app.Activity; import android.app.AlertDialog; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.graphics.ColorMatrix; @@ -50,26 +52,33 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal; import de.blinkt.openvpn.core.OpenVPNService; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VpnStatus; -import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.eip.VoidVpnService; +import se.leap.bitmaskclient.userstatus.User; +import static android.app.Activity.RESULT_OK; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK; +import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT; +import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_START; import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP; import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN; import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE; import static se.leap.bitmaskclient.Constants.EIP_NOTIFICATION; -import static se.leap.bitmaskclient.Constants.EIP_RECEIVER; import static se.leap.bitmaskclient.Constants.EIP_REQUEST; import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT; import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED; import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; +import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN; +import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_CERTIFICATE; public class EipFragment extends Fragment implements Observer { @@ -79,6 +88,7 @@ public class EipFragment extends Fragment implements Observer { public static final String START_EIP_ON_BOOT = "start on boot"; private SharedPreferences preferences; + private Provider provider; @InjectView(R.id.background) AppCompatImageView background; @@ -102,6 +112,9 @@ public class EipFragment extends Fragment implements Observer { private EipStatus eipStatus; private boolean wantsToConnect; + private ProviderAPIResultReceiver providerAPIResultReceiver; + private EIPBroadcastReceiver eipBroadcastReceiver; + private IOpenVPNServiceInternal mService; private ServiceConnection openVpnConnection = new ServiceConnection() { @@ -123,7 +136,18 @@ public class EipFragment extends Fragment implements Observer { public void onAttach(Context context) { super.onAttach(context); - downloadEIPServiceConfig(); + Bundle arguments = getArguments(); + if (arguments != null) { + provider = getArguments().getParcelable(PROVIDER_KEY); + if (provider == null) { + getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); + } else { + Log.d(TAG, provider.getName() + " configured as provider"); + } + } else { + Log.e(TAG, "no provider given - starting ProviderListActivity"); + getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); + } } @Override @@ -132,6 +156,8 @@ public class EipFragment extends Fragment implements Observer { eipStatus = EipStatus.getInstance(); eipStatus.addObserver(this); eipReceiver = new EIPReceiver(new Handler()); + eipBroadcastReceiver = new EIPBroadcastReceiver(); + providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), new EipFragmentReceiver()); preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); } @@ -152,6 +178,7 @@ public class EipFragment extends Fragment implements Observer { super.onResume(); //FIXME: avoid race conditions while checking certificate an logging in at about the same time //eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY); + setUpBroadcastReceiver(); handleNewState(); bindOpenVpnService(); } @@ -160,6 +187,8 @@ public class EipFragment extends Fragment implements Observer { public void onPause() { super.onPause(); getActivity().unbindService(openVpnConnection); + getActivity().unregisterReceiver(eipBroadcastReceiver); + Log.d(TAG, "broadcast unregistered"); } @Override @@ -199,8 +228,8 @@ public class EipFragment extends Fragment implements Observer { startEipFromScratch(); else if (canLogInToStartEIP()) { wantsToConnect = true; - Bundle bundle = new Bundle(); - MainActivity.sessionDialog(bundle); + Intent intent = new Intent(getContext(), LoginActivity.class); + getActivity().startActivityForResult(intent, REQUEST_CODE_LOG_IN); } else { Log.d(TAG, "WHAT IS GOING ON HERE?!"); // TODO: implement a fallback: check if vpncertificate was not downloaded properly or give @@ -250,7 +279,7 @@ public class EipFragment extends Fragment implements Observer { public void startEipFromScratch() { wantsToConnect = false; saveStatus(true); - eipCommand(EIP_ACTION_START); + EipCommand.startVPN(getContext(), eipReceiver); } private void stop() { @@ -282,13 +311,7 @@ public class EipFragment extends Fragment implements Observer { protected void stopEipIfPossible() { //FIXME: no need to start a service here! - eipCommand(EIP_ACTION_STOP); - } - - private void downloadEIPServiceConfig() { - ProviderAPIResultReceiver provider_api_receiver = new ProviderAPIResultReceiver(new Handler(), Dashboard.dashboardReceiver); - if(eipReceiver != null) - ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_EIP_SERVICE, provider_api_receiver); + EipCommand.stopVPN(getContext(), eipReceiver); } protected void askToStopEIP() { @@ -310,25 +333,6 @@ public class EipFragment extends Fragment implements Observer { .show(); } - protected void updateEipService() { - eipCommand(EIP_ACTION_UPDATE); - } - - /** - * Send a command to EIP - * - * @param action A valid String constant from EIP class representing an Intent - * filter for the EIP class - */ - private void eipCommand(String action) { - Activity activity = getActivity(); - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent vpn_intent = new Intent(activity.getApplicationContext(), EIP.class); - vpn_intent.setAction(action); - vpn_intent.putExtra(EIP_RECEIVER, eipReceiver); - activity.startService(vpn_intent); - } - @Override public void update(Observable observable, Object data) { if (observable instanceof EipStatus) { @@ -401,58 +405,81 @@ public class EipFragment extends Fragment implements Observer { protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); - String request = resultData.getString(EIP_REQUEST); + handleEIPEvent(resultCode, resultData); + } + } + + private class EIPBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "received Broadcast"); - if (request == null) { + String action = intent.getAction(); + if (action == null || !action.equalsIgnoreCase(BROADCAST_EIP_EVENT)) { return; } - switch (request) { - case EIP_ACTION_START: - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - break; - } - break; - case EIP_ACTION_STOP: - switch (resultCode) { - case Activity.RESULT_OK: - stop(); - break; - case Activity.RESULT_CANCELED: - break; - } - break; - case EIP_NOTIFICATION: - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - break; - } - break; - case EIP_ACTION_CHECK_CERT_VALIDITY: - switch (resultCode) { - case Activity.RESULT_OK: - break; - case Activity.RESULT_CANCELED: - Dashboard.downloadVpnCertificate(); - break; - } - break; - case EIP_ACTION_UPDATE: - switch (resultCode) { - case Activity.RESULT_OK: - if (wantsToConnect) - startEipFromScratch(); - break; - case Activity.RESULT_CANCELED: - handleNewState(); - break; - } - } + int resultCode = intent.getIntExtra(BROADCAST_RESULT_KEY, -1); + Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY); + Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); + + handleEIPEvent(resultCode, resultData); + + } + } + + private void handleEIPEvent(int resultCode, Bundle resultData) { + String request = resultData.getString(EIP_REQUEST); + + if (request == null) { + return; + } + + switch (request) { + case EIP_ACTION_START: + switch (resultCode) { + case RESULT_OK: + break; + case Activity.RESULT_CANCELED: + break; + } + break; + case EIP_ACTION_STOP: + switch (resultCode) { + case RESULT_OK: + stop(); + break; + case Activity.RESULT_CANCELED: + break; + } + break; + case EIP_NOTIFICATION: + switch (resultCode) { + case RESULT_OK: + break; + case Activity.RESULT_CANCELED: + break; + } + break; + case EIP_ACTION_CHECK_CERT_VALIDITY: + switch (resultCode) { + case RESULT_OK: + break; + case Activity.RESULT_CANCELED: + downloadVpnCertificate(); + break; + } + break; + case EIP_ACTION_UPDATE: + switch (resultCode) { + case RESULT_OK: + if (wantsToConnect) + startEipFromScratch(); + break; + case Activity.RESULT_CANCELED: + handleNewState(); + break; + } } } @@ -474,4 +501,33 @@ public class EipFragment extends Fragment implements Observer { background.setImageAlpha(255); } + private class EipFragmentReceiver implements ProviderAPIResultReceiver.Receiver{ + + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) { + provider = resultData.getParcelable(PROVIDER_KEY); + EipCommand.updateEipService(getContext(), eipReceiver); + } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE) { + //dashboard.setResult(RESULT_CANCELED); + // TODO CATCH ME IF YOU CAN + } + } + } + + private void downloadVpnCertificate() { + boolean is_authenticated = User.loggedIn(); + boolean allowed_anon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false); + if (allowed_anon || is_authenticated) { + ProviderAPICommand.execute(getContext(), DOWNLOAD_CERTIFICATE, provider, providerAPIResultReceiver); + } + } + + private void setUpBroadcastReceiver() { + IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_EIP_EVENT); + updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); + getActivity().registerReceiver(eipBroadcastReceiver, updateIntentFilter); + Log.d(TAG, "broadcast registered"); + } + } -- cgit v1.2.3 From 9e6fe0e215e32343b38cdf20080de209a31287dd Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Fri, 9 Feb 2018 12:46:06 +0100 Subject: 8827 - merge request discussions * add NullPointer checks to EipFragment * add Provider to DownloadFailedDialog * remove unused code * store certificates for pinning in SharedPreferences --- .../java/se/leap/bitmaskclient/EipFragment.java | 186 +++++++++++++-------- 1 file changed, 114 insertions(+), 72 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/EipFragment.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index 2f7977dd..ceae6706 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -33,6 +33,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.ResultReceiver; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v7.widget.AppCompatImageView; import android.util.Log; @@ -140,16 +141,19 @@ public class EipFragment extends Fragment implements Observer { public void onAttach(Context context) { super.onAttach(context); Bundle arguments = getArguments(); - if (arguments != null) { - provider = getArguments().getParcelable(PROVIDER_KEY); - if (provider == null) { - getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); + Activity activity = getActivity(); + if (activity != null) { + if (arguments != null) { + provider = arguments.getParcelable(PROVIDER_KEY); + if (provider == null) { + activity.startActivityForResult(new Intent(activity, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); + } else { + Log.d(TAG, provider.getName() + " configured as provider"); + } } else { - Log.d(TAG, provider.getName() + " configured as provider"); + Log.e(TAG, "no provider given - starting ProviderListActivity"); + activity.startActivityForResult(new Intent(activity, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); } - } else { - Log.e(TAG, "no provider given - starting ProviderListActivity"); - getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); } } @@ -160,11 +164,16 @@ public class EipFragment extends Fragment implements Observer { eipReceiver = new EIPReceiver(new Handler()); eipBroadcastReceiver = new EIPBroadcastReceiver(); providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), new EipFragmentReceiver()); - preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); + Activity activity = getActivity(); + if (activity != null) { + preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); + } else { + Log.e(TAG, "activity is null in onCreate - no preferences set!"); + } } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { eipStatus.addObserver(this); View view = inflater.inflate(R.layout.eip_service_fragment, container, false); ButterKnife.inject(this, view); @@ -189,8 +198,12 @@ public class EipFragment extends Fragment implements Observer { @Override public void onPause() { super.onPause(); - getActivity().unbindService(openVpnConnection); - getActivity().unregisterReceiver(eipBroadcastReceiver); + + Activity activity = getActivity(); + if (activity != null) { + getActivity().unbindService(openVpnConnection); + getActivity().unregisterReceiver(eipBroadcastReceiver); + } Log.d(TAG, "broadcast unregistered"); } @@ -201,7 +214,7 @@ public class EipFragment extends Fragment implements Observer { } @Override - public void onSaveInstanceState(Bundle outState) { + public void onSaveInstanceState(@NonNull Bundle outState) { outState.putBoolean(IS_CONNECTED, eipStatus.isConnected()); super.onSaveInstanceState(outState); } @@ -238,7 +251,10 @@ public class EipFragment extends Fragment implements Observer { else if (canLogInToStartEIP()) { wantsToConnect = true; Intent intent = new Intent(getContext(), LoginActivity.class); - getActivity().startActivityForResult(intent, REQUEST_CODE_LOG_IN); + Activity activity = getActivity(); + if (activity != null) { + activity.startActivityForResult(intent, REQUEST_CODE_LOG_IN); + } } else { Log.d(TAG, "WHAT IS GOING ON HERE?!"); // TODO: implement a fallback: check if vpncertificate was not downloaded properly or give @@ -268,21 +284,25 @@ public class EipFragment extends Fragment implements Observer { 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(); + if (activity != null) { + 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(); + } else { + Log.e(TAG, "activity is null when asking to cancel"); + } } public void startEipFromScratch() { @@ -302,9 +322,14 @@ public class EipFragment extends Fragment implements Observer { 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); + if (activity != null) { + Intent stopVoidVpnIntent = new Intent(activity, VoidVpnService.class); + stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); + activity.startService(stopVoidVpnIntent); + } else { + Log.e(TAG, "activity is null when trying to stop blocking vpn"); + // TODO what to do if not stopping void vpn? + } } private void disconnect() { @@ -325,21 +350,25 @@ public class EipFragment extends Fragment implements Observer { 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(); + if (activity != null) { + 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(); + } else { + Log.e(TAG, "activity is null when asking to stop EIP"); + } } @Override @@ -362,25 +391,29 @@ public class EipFragment extends Fragment implements Observer { 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.getProviderName(preferences)); - colorBackground(); + if (activity != null) { + 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.getProviderName(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(); + } } else { - mainButton.setText(activity.getString(R.string.vpn_button_turn_on)); - key.setImageResource(R.drawable.vpn_disconnected); - routedText.setVisibility(GONE); - vpnRoute.setVisibility(GONE); - greyscaleBackground(); + Log.e(TAG, "activity is null while trying to handle new state"); } } @@ -399,9 +432,13 @@ public class EipFragment extends Fragment implements Observer { 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); + if (activity != null) { + Intent intent = new Intent(activity, OpenVPNService.class); + intent.setAction(OpenVPNService.START_SERVICE); + activity.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE); + } else { + Log.e(TAG, "activity is null when binding OpenVpn"); + } } protected class EIPReceiver extends ResultReceiver { @@ -533,10 +570,15 @@ public class EipFragment extends Fragment implements Observer { } private void setUpBroadcastReceiver() { - IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_EIP_EVENT); - updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); - getActivity().registerReceiver(eipBroadcastReceiver, updateIntentFilter); - Log.d(TAG, "broadcast registered"); + Activity activity = getActivity(); + if (activity != null) { + IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_EIP_EVENT); + updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); + activity.registerReceiver(eipBroadcastReceiver, updateIntentFilter); + Log.d(TAG, "broadcast registered"); + } else { + Log.e(TAG, "activity null when setting up boradcat receiver"); + } } } -- cgit v1.2.3 From 7f84522ce01e8bcf1b3063ff7fa19a9a7dca61ea Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Fri, 9 Feb 2018 18:29:51 +0100 Subject: 8827 - resolve discussions * use LocalBroadcastManager for broadcasts * add NullPointer checks to EipFragment * store VpnCertificate & private key in Provider not preferences * EipFragment uses provider instead of reading from preferences * use switch in ProviderApiManager --- .../java/se/leap/bitmaskclient/EipFragment.java | 130 +++++++++++---------- 1 file changed, 70 insertions(+), 60 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/EipFragment.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index ceae6706..b4c7a7de 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -29,12 +29,11 @@ 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.annotation.NonNull; import android.support.v4.app.Fragment; +import android.support.v4.content.LocalBroadcastManager; import android.support.v7.widget.AppCompatImageView; import android.util.Log; import android.view.LayoutInflater; @@ -56,13 +55,14 @@ import de.blinkt.openvpn.core.VpnStatus; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.eip.VoidVpnService; -import se.leap.bitmaskclient.userstatus.User; import static android.app.Activity.RESULT_OK; +import static android.content.Intent.CATEGORY_DEFAULT; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK; import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT; +import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT; import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_START; @@ -72,14 +72,15 @@ import static se.leap.bitmaskclient.Constants.EIP_ACTION_UPDATE; import static se.leap.bitmaskclient.Constants.EIP_NOTIFICATION; import static se.leap.bitmaskclient.Constants.EIP_REQUEST; import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT; -import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOWED_REGISTERED; -import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; -import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE; import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE; +import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE; public class EipFragment extends Fragment implements Observer { @@ -111,12 +112,10 @@ public class EipFragment extends Fragment implements Observer { @InjectView(R.id.vpn_route) TextView vpnRoute; - private EIPReceiver eipReceiver; private EipStatus eipStatus; private boolean wantsToConnect; - private ProviderAPIResultReceiver providerAPIResultReceiver; - private EIPBroadcastReceiver eipBroadcastReceiver; + private EIPFragmentBroadcastReceiver eipFragmentBroadcastReceiver; private IOpenVPNServiceInternal mService; private ServiceConnection openVpnConnection = new ServiceConnection() { @@ -161,9 +160,7 @@ public class EipFragment extends Fragment implements Observer { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); eipStatus = EipStatus.getInstance(); - eipReceiver = new EIPReceiver(new Handler()); - eipBroadcastReceiver = new EIPBroadcastReceiver(); - providerAPIResultReceiver = new ProviderAPIResultReceiver(new Handler(), new EipFragmentReceiver()); + eipFragmentBroadcastReceiver = new EIPFragmentBroadcastReceiver(); Activity activity = getActivity(); if (activity != null) { preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); @@ -202,7 +199,7 @@ public class EipFragment extends Fragment implements Observer { Activity activity = getActivity(); if (activity != null) { getActivity().unbindService(openVpnConnection); - getActivity().unregisterReceiver(eipBroadcastReceiver); + LocalBroadcastManager.getInstance(activity).unregisterReceiver(eipFragmentBroadcastReceiver); } Log.d(TAG, "broadcast unregistered"); } @@ -246,30 +243,36 @@ public class EipFragment extends Fragment implements Observer { } private void handleSwitchOn() { - if (canStartEIP()) + Context context = getContext(); + if (context == null) { + Log.e(TAG, "context is null when switch turning on"); + return; + } + + if (canStartEIP()) { startEipFromScratch(); - else if (canLogInToStartEIP()) { + } else if (canLogInToStartEIP()) { wantsToConnect = true; Intent intent = new Intent(getContext(), LoginActivity.class); + intent.putExtra(PROVIDER_KEY, provider); Activity activity = getActivity(); if (activity != null) { activity.startActivityForResult(intent, REQUEST_CODE_LOG_IN); } } else { - Log.d(TAG, "WHAT IS GOING ON HERE?!"); - // TODO: implement a fallback: check if vpncertificate was not downloaded properly or give - // a user feedback. A button that does nothing on click is not a good option + // provider has no VpnCertificate but user is logged in + downloadVpnCertificate(); } } private boolean canStartEIP() { - boolean certificateExists = !preferences.getString(PROVIDER_VPN_CERTIFICATE, "").isEmpty(); - boolean isAllowedAnon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false); + boolean certificateExists = !provider.hasVpnCertificate(); + boolean isAllowedAnon = provider.allowsAnonymous(); return (isAllowedAnon || certificateExists) && !eipStatus.isConnected() && !eipStatus.isConnecting(); } private boolean canLogInToStartEIP() { - boolean isAllowedRegistered = preferences.getBoolean(PROVIDER_ALLOWED_REGISTERED, false); + boolean isAllowedRegistered = provider.allowsRegistered(); boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); return isAllowedRegistered && !isLoggedIn && !eipStatus.isConnecting() && !eipStatus.isConnected(); } @@ -308,7 +311,12 @@ public class EipFragment extends Fragment implements Observer { public void startEipFromScratch() { wantsToConnect = false; saveStatus(true); - EipCommand.startVPN(getContext(), eipReceiver); + Context context = getContext(); + if (context != null) { + EipCommand.startVPN(context); + } else { + Log.e(TAG, "context is null when trying to start VPN"); + } } private void stop() { @@ -344,8 +352,12 @@ public class EipFragment extends Fragment implements Observer { } protected void stopEipIfPossible() { - //FIXME: no need to start a service here! - EipCommand.stopVPN(getContext(), eipReceiver); + Context context = getContext(); + if (context != null) { + EipCommand.stopVPN(getContext()); + } else { + Log.e(TAG, "context is null when trying to stop EIP"); + } } protected void askToStopEIP() { @@ -441,36 +453,26 @@ public class EipFragment extends Fragment implements Observer { } } - protected class EIPReceiver extends ResultReceiver { - - EIPReceiver(Handler handler) { - super(handler); - } - - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - super.onReceiveResult(resultCode, resultData); - - handleEIPEvent(resultCode, resultData); - } - } - - private class EIPBroadcastReceiver extends BroadcastReceiver { + private class EIPFragmentBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "received Broadcast"); String action = intent.getAction(); - if (action == null || !action.equalsIgnoreCase(BROADCAST_EIP_EVENT)) { + if (action == null) { return; } int resultCode = intent.getIntExtra(BROADCAST_RESULT_KEY, -1); Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY); - Log.d(TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); - - handleEIPEvent(resultCode, resultData); - + switch (action) { + case BROADCAST_EIP_EVENT: + handleEIPEvent(resultCode, resultData); + break; + case BROADCAST_PROVIDER_API_EVENT: + handleProviderApiEvent(resultCode, resultData); + break; + } } } @@ -547,37 +549,45 @@ public class EipFragment extends Fragment implements Observer { background.setImageAlpha(255); } - private class EipFragmentReceiver implements ProviderAPIResultReceiver.Receiver{ + public void handleProviderApiEvent(int resultCode, Bundle resultData) { + Context context = getContext(); + if (context == null) { + return; + } - @Override - public void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE) { + // TODO call DOWNLOAD_EIP_SERVICES ore remove respective cases + switch (resultCode) { + case CORRECTLY_DOWNLOADED_EIP_SERVICE: provider = resultData.getParcelable(PROVIDER_KEY); - EipCommand.updateEipService(getContext(), eipReceiver); - } else if (resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE) { + EipCommand.updateEipService(context); + break; + case INCORRECTLY_DOWNLOADED_EIP_SERVICE: //dashboard.setResult(RESULT_CANCELED); - // TODO CATCH ME IF YOU CAN - } + // TODO CATCH ME IF YOU CAN - WHAT DO WE WANT TO DO? + break; + case CORRECTLY_DOWNLOADED_CERTIFICATE: + startEipFromScratch(); + break; + case INCORRECTLY_DOWNLOADED_CERTIFICATE: + // TODO CATCH ME IF YOU CAN - LOGIN? + break; } } private void downloadVpnCertificate() { - boolean is_authenticated = User.loggedIn(); - boolean allowed_anon = preferences.getBoolean(PROVIDER_ALLOW_ANONYMOUS, false); - if (allowed_anon || is_authenticated) { - ProviderAPICommand.execute(getContext(), DOWNLOAD_CERTIFICATE, provider, providerAPIResultReceiver); - } + ProviderAPICommand.execute(getContext(), DOWNLOAD_CERTIFICATE, provider); } private void setUpBroadcastReceiver() { Activity activity = getActivity(); if (activity != null) { IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_EIP_EVENT); - updateIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); - activity.registerReceiver(eipBroadcastReceiver, updateIntentFilter); + updateIntentFilter.addAction(BROADCAST_PROVIDER_API_EVENT); + updateIntentFilter.addCategory(CATEGORY_DEFAULT); + LocalBroadcastManager.getInstance(activity).registerReceiver(eipFragmentBroadcastReceiver, updateIntentFilter); Log.d(TAG, "broadcast registered"); } else { - Log.e(TAG, "activity null when setting up boradcat receiver"); + Log.e(TAG, "activity null when setting up broadcast receiver"); } } -- cgit v1.2.3 From ca82cdf77ee4d30b820a1f936315c6c5be78359d Mon Sep 17 00:00:00 2001 From: Fup Duck Date: Sun, 11 Feb 2018 13:25:24 +0100 Subject: 8827 - discussion * validate urls before changing anything in Provider.define() * save private key and vpn cert after login/signup --- app/src/main/java/se/leap/bitmaskclient/EipFragment.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/EipFragment.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index b4c7a7de..41d9ff04 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -63,6 +63,7 @@ import static android.view.View.VISIBLE; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK; import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT; import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT; +import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE; import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.Constants.EIP_ACTION_START; @@ -266,7 +267,7 @@ public class EipFragment extends Fragment implements Observer { } private boolean canStartEIP() { - boolean certificateExists = !provider.hasVpnCertificate(); + boolean certificateExists = provider.hasVpnCertificate(); boolean isAllowedAnon = provider.allowsAnonymous(); return (isAllowedAnon || certificateExists) && !eipStatus.isConnected() && !eipStatus.isConnecting(); } @@ -463,7 +464,7 @@ public class EipFragment extends Fragment implements Observer { return; } - int resultCode = intent.getIntExtra(BROADCAST_RESULT_KEY, -1); + int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, -1); Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY); switch (action) { case BROADCAST_EIP_EVENT: -- cgit v1.2.3