aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/fil/libre/repwifiapp/network/NetworkManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/fil/libre/repwifiapp/network/NetworkManager.java')
-rw-r--r--app/src/fil/libre/repwifiapp/network/NetworkManager.java379
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);
+ }
+
+}