Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a97fe138 authored by Christopher Tate's avatar Christopher Tate Committed by Android (Google) Code Review
Browse files

Merge "Exclude ephemeral networks from wifi backup" into lmp-mr1-dev

parents 2b46774f cab915a3
Loading
Loading
Loading
Loading
+105 −29
Original line number Original line Diff line number Diff line
@@ -25,6 +25,8 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Context;
import android.database.Cursor;
import android.database.Cursor;
import android.net.Uri;
import android.net.Uri;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager;
import android.os.FileUtils;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Handler;
@@ -33,9 +35,12 @@ import android.os.Process;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;


import libcore.io.IoUtils;

import java.io.BufferedOutputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayReader;
import java.io.CharArrayReader;
import java.io.DataInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.DataOutputStream;
@@ -48,11 +53,15 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.io.Writer;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.zip.CRC32;
import java.util.zip.CRC32;


/**
/**
@@ -138,6 +147,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        String ssid = "";  // equals() and hashCode() need these to be non-null
        String ssid = "";  // equals() and hashCode() need these to be non-null
        String key_mgmt = "";
        String key_mgmt = "";
        boolean certUsed = false;
        boolean certUsed = false;
        boolean hasWepKey = false;
        final ArrayList<String> rawLines = new ArrayList<String>();
        final ArrayList<String> rawLines = new ArrayList<String>();


        public static Network readFromStream(BufferedReader in) {
        public static Network readFromStream(BufferedReader in) {
@@ -164,9 +174,9 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            rawLines.add(line);
            rawLines.add(line);


            // remember the ssid and key_mgmt lines for duplicate culling
            // remember the ssid and key_mgmt lines for duplicate culling
            if (line.startsWith("ssid")) {
            if (line.startsWith("ssid=")) {
                ssid = line;
                ssid = line;
            } else if (line.startsWith("key_mgmt")) {
            } else if (line.startsWith("key_mgmt=")) {
                key_mgmt = line;
                key_mgmt = line;
            } else if (line.startsWith("client_cert=")) {
            } else if (line.startsWith("client_cert=")) {
                certUsed = true;
                certUsed = true;
@@ -174,6 +184,8 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                certUsed = true;
                certUsed = true;
            } else if (line.startsWith("ca_path=")) {
            } else if (line.startsWith("ca_path=")) {
                certUsed = true;
                certUsed = true;
            } else if (line.startsWith("wep_")) {
                hasWepKey = true;
            }
            }
        }
        }


@@ -193,6 +205,56 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            Log.v(TAG, "}");
            Log.v(TAG, "}");
        }
        }


        // Calculate the equivalent of WifiConfiguration's configKey()
        public String configKey() {
            if (ssid == null) {
                // No SSID => malformed network definition
                return null;
            }

            final String bareSsid = ssid.substring(ssid.indexOf('=') + 1);

            final BitSet types = new BitSet();
            if (key_mgmt == null) {
                // no key_mgmt specified; this is defined as equivalent to "WPA-PSK WPA-EAP"
                types.set(KeyMgmt.WPA_PSK);
                types.set(KeyMgmt.WPA_EAP);
            } else {
                // Need to parse the key_mgmt line
                final String bareKeyMgmt = key_mgmt.substring(key_mgmt.indexOf('=') + 1);
                String[] typeStrings = bareKeyMgmt.split("\\s+");

                // Parse out all the key management regimes permitted for this network.  The literal
                // strings here are the standard values permitted in wpa_supplicant.conf.
                for (int i = 0; i < typeStrings.length; i++) {
                    final String ktype = typeStrings[i];
                    if (ktype.equals("WPA-PSK")) {
                        Log.v(TAG, "  + setting WPA_PSK bit");
                        types.set(KeyMgmt.WPA_PSK);
                    } else if (ktype.equals("WPA-EAP")) {
                        Log.v(TAG, "  + setting WPA_EAP bit");
                        types.set(KeyMgmt.WPA_EAP);
                    } else if (ktype.equals("IEEE8021X")) {
                        Log.v(TAG, "  + setting IEEE8021X bit");
                        types.set(KeyMgmt.IEEE8021X);
                    }
                }
            }

            // Now build the canonical config key paralleling the WifiConfiguration semantics
            final String key;
            if (types.get(KeyMgmt.WPA_PSK)) {
                key = bareSsid + KeyMgmt.strings[KeyMgmt.WPA_PSK];
            } else if (types.get(KeyMgmt.WPA_EAP) || types.get(KeyMgmt.IEEE8021X)) {
                key = bareSsid + KeyMgmt.strings[KeyMgmt.WPA_EAP];
            } else if (hasWepKey) {
                key = bareSsid + "WEP";  // hardcoded this way in WifiConfiguration
            } else {
                key = bareSsid + KeyMgmt.strings[KeyMgmt.NONE];
            }
            return key;
        }

        // Same approach as Pair.equals() and Pair.hashCode()
        // Same approach as Pair.equals() and Pair.hashCode()
        @Override
        @Override
        public boolean equals(Object o) {
        public boolean equals(Object o) {
@@ -216,6 +278,17 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        }
        }
    }
    }


    boolean networkInWhitelist(Network net, List<WifiConfiguration> whitelist) {
        final String netConfigKey = net.configKey();
        final int N = whitelist.size();
        for (int i = 0; i < N; i++) {
            if (Objects.equals(netConfigKey, whitelist.get(i).configKey(true))) {
                return true;
            }
        }
        return false;
    }

    // Ingest multiple wifi config file fragments, looking for network={} blocks
    // Ingest multiple wifi config file fragments, looking for network={} blocks
    // and eliminating duplicates
    // and eliminating duplicates
    class WifiNetworkSettings {
    class WifiNetworkSettings {
@@ -223,7 +296,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        final HashSet<Network> mKnownNetworks = new HashSet<Network>();
        final HashSet<Network> mKnownNetworks = new HashSet<Network>();
        final ArrayList<Network> mNetworks = new ArrayList<Network>(8);
        final ArrayList<Network> mNetworks = new ArrayList<Network>(8);


        public void readNetworks(BufferedReader in) {
        public void readNetworks(BufferedReader in, List<WifiConfiguration> whitelist) {
            try {
            try {
                String line;
                String line;
                while (in.ready()) {
                while (in.ready()) {
@@ -232,6 +305,15 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                        // Parse out 'network=' decls so we can ignore duplicates
                        // Parse out 'network=' decls so we can ignore duplicates
                        if (line.startsWith("network")) {
                        if (line.startsWith("network")) {
                            Network net = Network.readFromStream(in);
                            Network net = Network.readFromStream(in);
                            if (whitelist != null) {
                                if (!networkInWhitelist(net, whitelist)) {
                                    if (DEBUG_BACKUP) {
                                        Log.v(TAG, "Network not in whitelist, skipping: "
                                                + net.ssid + " / " + net.key_mgmt);
                                    }
                                    continue;
                                }
                            }
                            if (! mKnownNetworks.contains(net)) {
                            if (! mKnownNetworks.contains(net)) {
                                if (DEBUG_BACKUP) {
                                if (DEBUG_BACKUP) {
                                    Log.v(TAG, "Adding " + net.ssid + " / " + net.key_mgmt);
                                    Log.v(TAG, "Adding " + net.ssid + " / " + net.key_mgmt);
@@ -844,24 +926,23 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        BufferedReader br = null;
        BufferedReader br = null;
        try {
        try {
            File file = new File(filename);
            File file = new File(filename);
            if (file.exists()) {
            if (!file.exists()) {
                br = new BufferedReader(new FileReader(file));
                StringBuffer relevantLines = new StringBuffer();
                boolean started = false;
                String line;
                while ((line = br.readLine()) != null) {
                    if (!started && line.startsWith("network")) {
                        started = true;
                    }
                    if (started) {
                        relevantLines.append(line).append("\n");
                    }
                }
                if (relevantLines.length() > 0) {
                    return relevantLines.toString().getBytes();
                } else {
                return EMPTY_DATA;
                return EMPTY_DATA;
            }
            }

            WifiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
            List<WifiConfiguration> configs = wifi.getConfiguredNetworks();

            WifiNetworkSettings fromFile = new WifiNetworkSettings();
            br = new BufferedReader(new FileReader(file));
            fromFile.readNetworks(br, configs);

            // Write the parsed networks into a packed byte array
            if (fromFile.mKnownNetworks.size() > 0) {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                OutputStreamWriter out = new OutputStreamWriter(bos);
                fromFile.write(out);
                return bos.toByteArray();
            } else {
            } else {
                return EMPTY_DATA;
                return EMPTY_DATA;
            }
            }
@@ -869,12 +950,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            Log.w(TAG, "Couldn't backup " + filename);
            Log.w(TAG, "Couldn't backup " + filename);
            return EMPTY_DATA;
            return EMPTY_DATA;
        } finally {
        } finally {
            if (br != null) {
            IoUtils.closeQuietly(br);
                try {
                    br.close();
                } catch (IOException e) {
                }
            }
        }
        }
    }
    }


@@ -886,7 +962,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            if (supplicantFile.exists()) {
            if (supplicantFile.exists()) {
                // Retain the existing APs; we'll append the restored ones to them
                // Retain the existing APs; we'll append the restored ones to them
                BufferedReader in = new BufferedReader(new FileReader(FILE_WIFI_SUPPLICANT));
                BufferedReader in = new BufferedReader(new FileReader(FILE_WIFI_SUPPLICANT));
                supplicantImage.readNetworks(in);
                supplicantImage.readNetworks(in, null);
                in.close();
                in.close();


                supplicantFile.delete();
                supplicantFile.delete();
@@ -897,7 +973,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                char[] restoredAsBytes = new char[size];
                char[] restoredAsBytes = new char[size];
                for (int i = 0; i < size; i++) restoredAsBytes[i] = (char) bytes[i];
                for (int i = 0; i < size; i++) restoredAsBytes[i] = (char) bytes[i];
                BufferedReader in = new BufferedReader(new CharArrayReader(restoredAsBytes));
                BufferedReader in = new BufferedReader(new CharArrayReader(restoredAsBytes));
                supplicantImage.readNetworks(in);
                supplicantImage.readNetworks(in, null);


                if (DEBUG_BACKUP) {
                if (DEBUG_BACKUP) {
                    Log.v(TAG, "Final AP list:");
                    Log.v(TAG, "Final AP list:");