Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +105 −29 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; /** /** Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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; } } } } Loading @@ -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) { Loading @@ -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 { Loading @@ -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()) { Loading @@ -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); Loading Loading @@ -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; } } Loading @@ -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) { } } } } } } Loading @@ -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(); Loading @@ -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:"); Loading Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +105 −29 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; /** /** Loading Loading @@ -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) { Loading @@ -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; Loading @@ -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; } } } } Loading @@ -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) { Loading @@ -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 { Loading @@ -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()) { Loading @@ -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); Loading Loading @@ -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; } } Loading @@ -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) { } } } } } } Loading @@ -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(); Loading @@ -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:"); Loading