summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2020-12-29 00:54:08 +0100
committercyBerta <cyberta@riseup.net>2020-12-29 00:54:08 +0100
commit6b032b751324a30120cfaabe88940f95171df11f (patch)
treeb6b26b84358726a02e27558562e7e9ea70a7aaa0 /app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
parent16da1eeb5180cbb4a0d916785a08ccbcd3c1d74e (diff)
new year cleanup: restructure messy project
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java375
1 files changed, 0 insertions, 375 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
deleted file mode 100644
index e365c857..00000000
--- a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/**
- * Copyright (c) 2020 LEAP Encryption Access Project and contributers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package se.leap.bitmaskclient;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-
-import org.json.JSONObject;
-
-import java.util.Vector;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import de.blinkt.openvpn.LaunchVPN;
-import de.blinkt.openvpn.VpnProfile;
-import de.blinkt.openvpn.core.ConnectionStatus;
-import de.blinkt.openvpn.core.LogItem;
-import de.blinkt.openvpn.core.VpnStatus;
-import se.leap.bitmaskclient.appUpdate.DownloadServiceCommand;
-import se.leap.bitmaskclient.eip.EIP;
-import se.leap.bitmaskclient.eip.EipCommand;
-import se.leap.bitmaskclient.eip.EipStatus;
-import se.leap.bitmaskclient.eip.Gateway;
-import se.leap.bitmaskclient.eip.GatewaysManager;
-import se.leap.bitmaskclient.utils.PreferenceHelper;
-
-import static android.app.Activity.RESULT_CANCELED;
-import static android.content.Intent.CATEGORY_DEFAULT;
-import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET;
-import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NOTCONNECTED;
-import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT;
-import static se.leap.bitmaskclient.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_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_PREPARE_VPN;
-import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
-import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
-import static se.leap.bitmaskclient.Constants.EIP_EARLY_ROUTES;
-import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
-import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
-import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE;
-import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE;
-import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON;
-import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_GEOIP_JSON;
-import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.CHECK_VERSION_FILE;
-
-/**
- * Created by cyberta on 05.12.18.
- */
-class EipSetupObserver extends BroadcastReceiver implements VpnStatus.StateListener, VpnStatus.LogListener {
-
- private static final String TAG = EipSetupObserver.class.getName();
-
- //The real timout is 4*2s + 1*4s + 1*8s + 1*16s + 1*32s + 1*64s = 132 s;
- private static final String TIMEOUT = "4";
- private static final int UPDATE_CHECK_TIMEOUT = 1000*60*60*24*7;
- private Context context;
- private VpnProfile setupVpnProfile;
- private String observedProfileFromVpnStatus;
- AtomicBoolean changingGateway = new AtomicBoolean(false);
- AtomicInteger setupNClosestGateway = new AtomicInteger();
- AtomicInteger reconnectTry = new AtomicInteger();
- private Vector<EipSetupListener> listeners = new Vector<>();
- private SharedPreferences preferences;
- private static EipSetupObserver instance;
-
- private EipSetupObserver(Context context, SharedPreferences preferences) {
- this.context = context;
- this.preferences = preferences;
- IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT);
- updateIntentFilter.addAction(BROADCAST_EIP_EVENT);
- updateIntentFilter.addAction(BROADCAST_PROVIDER_API_EVENT);
- updateIntentFilter.addCategory(CATEGORY_DEFAULT);
- LocalBroadcastManager.getInstance(context.getApplicationContext()).registerReceiver(this, updateIntentFilter);
- instance = this;
- VpnStatus.addLogListener(this);
- }
-
- public static void init(Context context, SharedPreferences preferences) {
- if (instance == null) {
- instance = new EipSetupObserver(context, preferences);
- }
- }
-
- public static boolean reconnectingWithDifferentGateway() {
- return instance.setupNClosestGateway.get() > 0;
- }
-
- public static int connectionRetry() {
- return instance.reconnectTry.get();
- }
-
- public static int gatewayOrder() {
- return instance.setupNClosestGateway.get();
- }
-
- public static synchronized void addListener(EipSetupListener listener) {
- if (instance.listeners.contains(listener)) {
- return;
- }
- instance.listeners.add(listener);
- }
-
- public static synchronized void removeListener(EipSetupListener listener) {
- instance.listeners.remove(listener);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action == null) {
- return;
- }
-
- switch (action) {
- case BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT:
- handleGatewaySetupObserverEvent(intent);
- break;
- case BROADCAST_EIP_EVENT:
- handleEipEvent(intent);
- break;
- case BROADCAST_PROVIDER_API_EVENT:
- handleProviderApiEvent(intent);
- break;
- default:
- break;
- }
- }
-
- private void handleProviderApiEvent(Intent intent) {
- int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, RESULT_CANCELED);
- Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY);
- if (resultData == null) {
- resultData = Bundle.EMPTY;
- }
-
- Provider provider;
- switch (resultCode) {
- case CORRECTLY_DOWNLOADED_EIP_SERVICE:
- Log.d(TAG, "correctly updated service json");
- provider = resultData.getParcelable(PROVIDER_KEY);
- ProviderObservable.getInstance().updateProvider(provider);
- PreferenceHelper.storeProviderInPreferences(preferences, provider);
- if (EipStatus.getInstance().isDisconnected()) {
- EipCommand.startVPN(context.getApplicationContext(), true);
- }
- break;
- case CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE:
- provider = resultData.getParcelable(PROVIDER_KEY);
- ProviderObservable.getInstance().updateProvider(provider);
- PreferenceHelper.storeProviderInPreferences(preferences, provider);
- EipCommand.startVPN(context.getApplicationContext(), true);
- break;
- case CORRECTLY_DOWNLOADED_GEOIP_JSON:
- provider = resultData.getParcelable(PROVIDER_KEY);
- ProviderObservable.getInstance().updateProvider(provider);
- PreferenceHelper.storeProviderInPreferences(preferences, provider);
- maybeStartEipService(resultData);
- break;
- case INCORRECTLY_DOWNLOADED_GEOIP_JSON:
- maybeStartEipService(resultData);
- break;
- default:
- break;
- }
-
- for (EipSetupListener listener : listeners) {
- listener.handleProviderApiEvent(intent);
- }
- }
-
- private void maybeStartEipService(Bundle resultData) {
- if (resultData.getBoolean(EIP_ACTION_START)) {
- boolean earlyRoutes = resultData.getBoolean(EIP_EARLY_ROUTES);
- EipCommand.startVPN(context.getApplicationContext(), earlyRoutes);
- }
- }
-
-
- private void handleEipEvent(Intent intent) {
- int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, RESULT_CANCELED);
- Bundle result = intent.getBundleExtra(BROADCAST_RESULT_KEY);
- String eipRequest = result.getString(EIP_REQUEST);
- EIP.EIPErrors error = EIP.EIPErrors.UNKNOWN;
- try {
- JSONObject jsonObject = new JSONObject(result.getString(EIP.ERRORS));
- error = EIP.EIPErrors.valueOf(jsonObject.getString(EIP.ERRORID));
- } catch (Exception e) {
- //ignore
- }
- if (eipRequest == null) {
- return;
- }
- switch (eipRequest) {
- case EIP_ACTION_START:
- case EIP_ACTION_START_ALWAYS_ON_VPN:
- if (resultCode == RESULT_CANCELED) {
- //setup failed
- if (error == EIP.EIPErrors.NO_MORE_GATEWAYS) {
- finishGatewaySetup(false);
- EipCommand.startBlockingVPN(context.getApplicationContext());
- } else {
- //FIXME:
- finishGatewaySetup(false);
- EipCommand.stopVPN(context);
- EipStatus.refresh();
- }
- }
- break;
- case EIP_ACTION_PREPARE_VPN:
- if (resultCode == RESULT_CANCELED) {
- VpnStatus.logError("Error preparing VpnService.");
- finishGatewaySetup(false);
- EipStatus.refresh();
- }
- break;
- default:
- break;
- }
-
- for (EipSetupListener listener : listeners) {
- listener.handleEipEvent(intent);
- }
- }
-
- private void handleGatewaySetupObserverEvent(Intent event) {
- if (observedProfileFromVpnStatus != null || setupVpnProfile != null) {
- //finish last setup observation
- Log.d(TAG, "finish last gateway setup");
- finishGatewaySetup(true);
- }
-
- VpnProfile vpnProfile = (VpnProfile) event.getSerializableExtra(PROVIDER_PROFILE);
- if (vpnProfile == null) {
- Log.e(TAG, "Tried to setup non existing vpn profile.");
- return;
- }
- setupVpnProfile = vpnProfile;
- setupNClosestGateway.set(event.getIntExtra(Gateway.KEY_N_CLOSEST_GATEWAY, 0));
- Log.d(TAG, "bitmaskapp add state listener");
- VpnStatus.addStateListener(this);
-
- launchVPN(setupVpnProfile);
- }
-
- private void launchVPN(VpnProfile vpnProfile) {
- Intent intent = new Intent(context.getApplicationContext(), LaunchVPN.class);
- intent.setAction(Intent.ACTION_MAIN);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true);
- intent.putExtra(PROVIDER_PROFILE, vpnProfile);
- intent.putExtra(Gateway.KEY_N_CLOSEST_GATEWAY, setupNClosestGateway.get());
- context.startActivity(intent);
- }
-
- @Override
- public void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level) {
- // VpnStatus.updateStateString("NOPROCESS", "No process running.", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED);
-
- Log.d(TAG, "vpn status: " + state + " - " + logmessage + " - " + level);
- if (observedProfileFromVpnStatus == null ||
- setupVpnProfile == null) {
- return;
- }
- if (!observedProfileFromVpnStatus.equals(setupVpnProfile.getUUIDString())) {
- Log.d(TAG, "vpn profile to setup and observed profile currently is used differ: " + setupVpnProfile.getUUIDString() + " vs. " + observedProfileFromVpnStatus);
- return;
- }
-
- if (ConnectionStatus.LEVEL_STOPPING == level) {
- finishGatewaySetup(false);
- } else if ("CONNECTRETRY".equals(state) && LEVEL_CONNECTING_NO_SERVER_REPLY_YET.equals(level)) {
- Log.d(TAG, "trying gateway: " + setupVpnProfile.getName());
- if (TIMEOUT.equals(logmessage)) {
- Log.e(TAG, "Timeout reached! Try next gateway!");
- VpnStatus.logError("Timeout reached! Try next gateway!");
- selectNextGateway();
- return;
- }
- int current = reconnectTry.get();
- reconnectTry.set(current + 1);
- } else if ("NOPROCESS".equals(state) && LEVEL_NOTCONNECTED == level) {
- //??
- } else if ("CONNECTED".equals(state)) {
- //saveLastProfile(context.getApplicationContext(), setupVpnProfile.getUUIDString());
- Provider provider = ProviderObservable.getInstance().getCurrentProvider();
- if (setupNClosestGateway.get() > 0 || provider.shouldUpdateEipServiceJson()) {
- //setupNClostestGateway > 0: at least one failed gateway -> did the provider change it's gateways?
- ProviderAPICommand.execute(context, ProviderAPI.DOWNLOAD_SERVICE_JSON, provider);
- }
-
- if (shouldCheckAppUpdate()) {
- DownloadServiceCommand.execute(context, CHECK_VERSION_FILE);
- }
- finishGatewaySetup(false);
- } else if ("TCP_CONNECT".equals(state)) {
- changingGateway.set(false);
- }
- }
-
- private boolean shouldCheckAppUpdate() {
- return System.currentTimeMillis() - PreferenceHelper.getLastAppUpdateCheck(context) >= UPDATE_CHECK_TIMEOUT;
- }
-
- private void selectNextGateway() {
- changingGateway.set(true);
- reconnectTry.set(0);
- EipCommand.startVPN(context.getApplicationContext(), false, setupNClosestGateway.get() + 1);
- }
-
- private void finishGatewaySetup(boolean changingGateway) {
- VpnStatus.removeStateListener(this);
- setupVpnProfile = null;
- setupNClosestGateway.set(0);
- observedProfileFromVpnStatus = null;
- this.changingGateway.set(changingGateway);
- this.reconnectTry.set(0);
- }
-
- /**
- * gets called as soon as a new VPN is about to launch
- *
- * @param uuid
- */
- @Override
- public void setConnectedVPN(String uuid) {
- observedProfileFromVpnStatus = uuid;
- }
-
- @Override
- public void newLog(LogItem logItem) {
- if (logItem.getLogLevel() == VpnStatus.LogLevel.ERROR) {
- switch (logItem.getErrorType()) {
- case SHAPESHIFTER:
- VpnProfile profile = VpnStatus.getLastConnectedVpnProfile();
- if (profile == null) {
- EipCommand.startVPN(context.getApplicationContext(), false, 0);
- } else {
- GatewaysManager gatewaysManager = new GatewaysManager(context.getApplicationContext());
- int position = gatewaysManager.getPosition(profile);
- setupNClosestGateway.set(position >= 0 ? position : 0);
- selectNextGateway();
- }
- break;
- default:
- break;
-
- }
- }
- }
-}