diff options
Diffstat (limited to 'app/src/fil/libre/repwifiapp/network/NetworkManager.java')
-rw-r--r-- | app/src/fil/libre/repwifiapp/network/NetworkManager.java | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/app/src/fil/libre/repwifiapp/network/NetworkManager.java b/app/src/fil/libre/repwifiapp/network/NetworkManager.java new file mode 100644 index 0000000..4d5635d --- /dev/null +++ b/app/src/fil/libre/repwifiapp/network/NetworkManager.java @@ -0,0 +1,379 @@ +// +// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net> +// +// This file is part of RepWifiApp. +// +// RepWifiApp is free software: you can redistribute it and/or modify +// it under the terms of the GNU General public static License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// RepWifiApp 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 static License for more details. +// +// You should have received a copy of the GNU General public static License +// along with RepWifiApp. If not, see <http://www.gnu.org/licenses/>. +// +// ******************************************************************** + +package fil.libre.repwifiapp.network; + +import fil.libre.repwifiapp.Utils; +import fil.libre.repwifiapp.helpers.Logger; +import org.json.JSONArray; +import org.json.JSONObject; +import java.io.File; +import java.util.ArrayList; + +public abstract class NetworkManager { + + private static final String VERSION_NOTE = "RepWifiStorageVersion: 2.0"; + private static final String F_SEP = "\t"; + private static final int NET_MAX_AGE = 1095; // Expressed in days + + private static String knownNetworksFile = null; + + public static void init(String storageFilePath){ + knownNetworksFile = storageFilePath; + } + + private static AccessPointInfo getSavedInfo(AccessPointInfo i) { + + if (i == null) { + return null; + } + + String bssid = i.getBssid(); + String ssid = i.getSsid(); + + if (bssid == null || ssid == null || bssid.trim().equals("") || ssid.trim().equals("")) { + return null; + } + + AccessPointInfo ret = null; + AccessPointInfo[] list = getKnownNetworks(); + + if (list == null) { + return null; + } + + for (AccessPointInfo toTest : list) { + + // try to match both bssid and ssid. + // if bssid doesn't match, but ssid does, + // then the network is a candidate. + // if no bssid equality is found, + // then return the best match (only ssid), if any + if (toTest.getSsid().equals(ssid)) { + + i.setPassword(toTest.getPassword()); + i.setDhcpConfiguration(toTest.getDhcpConfiguration()); + i.setVpnProfileName(toTest.getVpnProfileName()); + + if (toTest.getBssid().equals(bssid)) { + // complete match, return. + return i; + + } else { + // probable match + ret = i; + } + + } + + } + + return ret; + + } + + private static boolean saveOrRemove(AccessPointInfo info, boolean save) { + + AccessPointInfo[] existingNets = getKnownNetworks(); + + ArrayList<AccessPointInfo> newlist = new ArrayList<AccessPointInfo>(); + + if (existingNets == null || existingNets.length == 0) { + // no existing storage yet, create it + + if (save) { + // set timestamp + info.setLastTimeUsed(System.currentTimeMillis()); + newlist.add(info); + AccessPointInfo[] newContents = new AccessPointInfo[newlist.size()]; + newContents = newlist.toArray(newContents); + + return saveList(newContents); + + } else { + // nothing to do, return + return true; + } + + } + + if (save) { + // add the updated info to the storage + info.setLastTimeUsed(System.currentTimeMillis()); + newlist.add(info); + } + + for (AccessPointInfo old : existingNets) { + + if (old == null) { + // error while loading from file. skip. + continue; + } + + // keep network only if it's not older than the max age for a + // network + else if (old.isOlderThan(NET_MAX_AGE)) { + // skip it + continue; + } + + else if (old.getBssid().equals(info.getBssid()) && old.getSsid().equals(info.getSsid())) { + // found previously saved entry for the same network we are + // managing + // skip it + continue; + } + + else { + // old network info that can be kept in the storage + newlist.add(old); + } + + } + + AccessPointInfo[] newContents = new AccessPointInfo[newlist.size()]; + newContents = newlist.toArray(newContents); + + return saveList(newContents); + + } + + private static AccessPointInfo getFromStringOld(String savedString) { + + if (savedString == null || savedString.trim().equals("")) { + return null; + } + + String[] fields = savedString.split(F_SEP); + + if (fields.length < 4) { + return null; + } + + String bssid = fields[0]; + String ssid = fields[1]; + String pass = fields[2]; + String lastUsed = fields[3]; + String auth = null; + String ipWmask = null; + String gw = null; + boolean useDhcp = true; + String vpnProfile = null; + + if (fields.length > 4) { + auth = fields[4]; + } + + if (fields.length > 6) { + ipWmask = fields[5]; + gw = fields[6]; + useDhcp = false; + } + + if (fields.length > 7) { + vpnProfile = fields[7]; + } + + long lastusedmillis = 0; + try { + lastusedmillis = Long.parseLong(lastUsed); + } catch (NumberFormatException e) { + // invalid format + Logger.logError("Invalid time format in network manager \"" + lastUsed + + "\". Network BSSID: " + bssid, e); + } + + if (bssid.trim().equals("") || ssid.trim().equals("") || pass.trim().equals("")) { + return null; + } + + AccessPointInfo i = new AccessPointInfo(ssid, bssid, auth, null, null); + i.setPassword(pass); + i.setLastTimeUsed(lastusedmillis); + i.setVpnProfileName(vpnProfile); + + if (!useDhcp) { + DhcpSettings s = DhcpSettings.parseSavedSettings(ipWmask, gw); + i.setDhcpConfiguration(s); + } + + return i; + + } + + private static boolean saveList(AccessPointInfo[] list) { + + try { + + JSONArray jarr = new JSONArray(); + for (AccessPointInfo i : list) { + + JSONObject jo = i.toJson(); + if (jo == null) { + return false; + } + + jarr.put(jo); + + } + + StringBuilder sb = new StringBuilder(); + sb.append(VERSION_NOTE); + sb.append("\n"); + + sb.append(jarr.toString(2)); + + return Utils.writeFile(knownNetworksFile, sb.toString(), true); + + } catch (Exception e) { + Logger.logError("Exception while saving AccessPointInfo array to JSON-formatted file.", + e); + return false; + } + + } + + public static boolean updateStorageVersion() { + + try{ + String[] lines = Utils.readFileLines(knownNetworksFile); + + if (lines == null){ + return false; + } + + if (lines.length == 0) { + return true; + } + + if (lines[0].trim().equals(VERSION_NOTE)) { + return true; + + } else { + + AccessPointInfo[] infos = getKnownNetworksOld(); + if (infos == null || infos.length == 0) { + return true; + } + return saveList(infos); + + } + }catch (Exception e){ + Logger.logError("Exception while trying to update network storage version",e); + return false; + } + + } + + public static AccessPointInfo[] getKnownNetworks() { + + try { + + String fconts = Utils.readFile(knownNetworksFile); + if (fconts == null) { + return null; + } + + if (!fconts.startsWith(VERSION_NOTE)) { + // wrong version, try to convert it + if (updateStorageVersion()) { + return getKnownNetworks(); + } else { + return null; + } + } + + JSONArray jarr = new JSONArray(fconts.replace(VERSION_NOTE, "")); + ArrayList<AccessPointInfo> list = new ArrayList<AccessPointInfo>(); + + int count = 0; + for (int i = 0; i < jarr.length(); i++) { + AccessPointInfo info = AccessPointInfo.fromJsonObject(jarr.getJSONObject(i)); + if (info == null) { + continue; + } + count += 1; + list.add(info); + } + + AccessPointInfo[] arr = new AccessPointInfo[count]; + return list.toArray(arr); + + } catch (Exception e) { + Logger.logError("Exception while parsing JSON content from storage file.", e); + return null; + } + + } + + public static AccessPointInfo[] getKnownNetworksOld() { + + ArrayList<AccessPointInfo> list = new ArrayList<AccessPointInfo>(); + + File f = new File(knownNetworksFile); + if (!f.exists()) { + return null; + } + + String[] lines = Utils.readFileLines(knownNetworksFile); + if (lines == null || lines.length == 0) { + return null; + } + + for (String l : lines) { + + AccessPointInfo info = getFromStringOld(l); + if (info != null) { + list.add(info); + } + + } + + AccessPointInfo[] ret = new AccessPointInfo[list.size()]; + ret = list.toArray(ret); + + return ret; + + } + + public static boolean isKnown(AccessPointInfo info) { + + AccessPointInfo i = getSavedInfo(info); + if (i == null) { + return false; + } else { + return true; + } + + } + + public static boolean save(AccessPointInfo info) { + return saveOrRemove(info, true); + } + + public static boolean remove(AccessPointInfo info) { + return saveOrRemove(info, false); + } + + public static AccessPointInfo getSavedNetwork(AccessPointInfo i) { + return getSavedInfo(i); + } + +} |