From a74d09929575e44f86d09283ae4633b0dcfcb566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 6 Jan 2015 10:11:50 +0100 Subject: Extracted GatewaysManager + coded its tests --- .../se/leap/bitmaskclient/eip/GatewaysManager.java | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java (limited to 'app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java new file mode 100644 index 00000000..b1aa5a2f --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2013, 2014, 2015 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.eip; + +import android.content.*; +import android.util.Log; + +import com.google.gson.*; +import com.google.gson.reflect.*; + +import org.json.*; + +import java.lang.reflect.*; +import java.util.*; + +import de.blinkt.openvpn.*; +import de.blinkt.openvpn.core.*; +import se.leap.bitmaskclient.*; + +/** + * @author parmegv + */ +public class GatewaysManager { + + private Context context; + private SharedPreferences preferences; + private List gateways = new ArrayList<>(); + private ProfileManager profile_manager; + private Type list_type = new TypeToken>() {}.getType(); + + public GatewaysManager() {} + + public GatewaysManager(Context context, SharedPreferences preferences) { + this.context = context; + this.preferences = preferences; + profile_manager = ProfileManager.getInstance(context); + } + public Gateway select() { + GatewaySelector gateway_selector = new GatewaySelector(gateways); + return gateway_selector.select(); + } + + public boolean isEmpty() { + return gateways.isEmpty(); + } + + public int size() { + return gateways.size(); + } + + public void addFromString(String gateways) { + List gateways_list = new ArrayList(); + try { + gateways_list = new Gson().fromJson(gateways, list_type); + } catch(JsonSyntaxException e) { + gateways_list.add(new Gson().fromJson(gateways, Gateway.class)); + } + + if(gateways_list != null) { + for (Gateway gateway : gateways_list) + removeDuplicatedGateway(gateway); + this.gateways.addAll(gateways_list); + } else + Log.d("GatewaysManager", "No gateways added"); + } + + @Override + public String toString() { + return new Gson().toJson(gateways, list_type); + } + + public void fromEipServiceJson(JSONObject eip_definition) { + try { + JSONArray gatewaysDefined = eip_definition.getJSONArray("gateways"); + for (int i = 0; i < gatewaysDefined.length(); i++) { + JSONObject gw = gatewaysDefined.getJSONObject(i); + if (isOpenVpnGateway(gw)) { + JSONObject secrets = secretsConfiguration(); + Gateway aux = new Gateway(eip_definition, secrets, gw); + if(!containsProfileWithSecrets(aux.getProfile())) { + addGateway(aux); + } + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private boolean isOpenVpnGateway(JSONObject gateway) { + try { + String transport = gateway.getJSONObject("capabilities").getJSONArray("transport").toString(); + return transport.contains("openvpn"); + } catch (JSONException e) { + return false; + } + } + + private JSONObject secretsConfiguration() { + JSONObject result = new JSONObject(); + try { + result.put(Provider.CA_CERT, preferences.getString(Provider.CA_CERT, "")); + result.put(Constants.PRIVATE_KEY, preferences.getString(Constants.PRIVATE_KEY, "")); + result.put(Constants.CERTIFICATE, preferences.getString(Constants.CERTIFICATE, "")); + } catch (JSONException e) { + e.printStackTrace(); + } + return result; + } + + private boolean containsProfileWithSecrets(VpnProfile profile) { + boolean result = false; + + Collection profiles = profile_manager.getProfiles(); + for(VpnProfile aux : profiles) { + result = result || sameConnections(profile.mConnections, aux.mConnections) + && profile.mClientCertFilename.equalsIgnoreCase(aux.mClientCertFilename) + && profile.mClientKeyFilename.equalsIgnoreCase(aux.mClientKeyFilename); + } + return result; + } + + private void addGateway(Gateway gateway) { + removeDuplicatedGateway(gateway); + + gateways.add(gateway); + + VpnProfile profile = gateway.getProfile(); + profile_manager.addProfile(profile); + //profile_manager.saveProfile(context, profile); + //profile_manager.saveProfileList(context); + } + + private void removeDuplicatedGateway(Gateway gateway) { + Iterator it = gateways.iterator(); + List gateways_to_remove = new ArrayList<>(); + while(it.hasNext()) { + Gateway aux = it.next(); + if(sameConnections(aux.getProfile().mConnections, gateway.getProfile().mConnections)) { + gateways_to_remove.add(aux); + } + } + gateways.removeAll(gateways_to_remove); + removeDuplicatedProfiles(gateway.getProfile()); + } + + private void removeDuplicatedProfiles(VpnProfile original) { + Collection profiles = profile_manager.getProfiles(); + List remove_list = new ArrayList<>(); + for(VpnProfile aux : profiles) { + if (sameConnections(original.mConnections, aux.mConnections)) + remove_list.add(aux); + } + for (VpnProfile profile : remove_list) + profile_manager.removeProfile(context, profile); + } + + private boolean sameConnections(Connection[] c1, Connection[] c2) { + int same_connections = 0; + for(Connection c1_aux : c1) { + for(Connection c2_aux : c2) + if(c2_aux.mServerName.equals(c1_aux.mServerName)) { + same_connections++; + break; + } + } + return c1.length == c2.length && c1.length == same_connections; + } +} -- cgit v1.2.3