Add Enterprise Wifi connection support in sl4a.
b/19590352
Also add sl4a support to enable/disable lockscreen with password,
which is essential because keystore is locked without a lockscreen password.
Also fix:
b/19590414
b/19585194
Change-Id: I2498817240eda7b022c484bb7b01477474b2150a
diff --git a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java b/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java
index 9a73cdb..7510fc1 100644
--- a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java
@@ -18,6 +18,7 @@
import android.app.AlarmManager;
import android.app.Service;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.media.AudioManager;
import android.net.ConnectivityManager;
@@ -26,6 +27,7 @@
import android.provider.Settings.SettingNotFoundException;
import android.view.WindowManager;
+import com.android.internal.widget.LockPatternUtils;
import com.googlecode.android_scripting.BaseApplication;
import com.googlecode.android_scripting.FutureActivityTaskExecutor;
import com.googlecode.android_scripting.Log;
@@ -48,6 +50,7 @@
private final AudioManager mAudio;
private final PowerManager mPower;
private final AlarmManager mAlarm;
+ private final LockPatternUtils mLockPatternUtils;
/**
* Creates a new SettingsFacade.
@@ -60,6 +63,7 @@
mAudio = (AudioManager) mService.getSystemService(Context.AUDIO_SERVICE);
mPower = (PowerManager) mService.getSystemService(Context.POWER_SERVICE);
mAlarm = (AlarmManager) mService.getSystemService(Context.ALARM_SERVICE);
+ mLockPatternUtils = new LockPatternUtils(mService);
}
@Rpc(description = "Sets the screen timeout to this number of seconds.",
@@ -227,6 +231,24 @@
return SystemClock.elapsedRealtime();
}
+ @Rpc(description = "Set a string password to the device.")
+ public void setDevicePassword(@RpcParameter(name = "password") String password) {
+ mLockPatternUtils.setLockPatternEnabled(true);
+ mLockPatternUtils.setCredentialRequiredToDecrypt(true);
+ mLockPatternUtils.saveLockPassword(password,
+ DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+ false);
+ }
+
+ @Rpc(description = "Disable screen lock password on the device.")
+ public void disableDevicePassword() {
+ mLockPatternUtils.clearEncryptionPassword();
+ mLockPatternUtils.setLockPatternEnabled(false);
+ mLockPatternUtils.setCredentialRequiredToDecrypt(false);
+ mLockPatternUtils.clearLock(false);
+ mLockPatternUtils.setLockScreenDisabled(true);
+ }
+
@Rpc(description = "Set the system time in epoch.")
public void setTime(Long currentTime) {
mAlarm.setTime(currentTime);
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
index 5e56745..8800f9a 100755
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
@@ -13,6 +13,7 @@
import android.net.wifi.ScanResult;
import android.net.wifi.WifiActivityEnergyInfo;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
@@ -22,6 +23,7 @@
import android.os.Bundle;
import android.provider.Settings.Global;
import android.provider.Settings.SettingNotFoundException;
+import android.util.Base64;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.EventFacade;
@@ -32,8 +34,23 @@
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -186,9 +203,9 @@
Bundle msg = new Bundle();
String ssid = wInfo.getSSID();
if (ssid.charAt(0) == '"' && ssid.charAt(ssid.length() - 1) == '"') {
- msg.putString("ssid", ssid.substring(1, ssid.length() - 1));
+ msg.putString("SSID", ssid.substring(1, ssid.length() - 1));
} else {
- msg.putString("ssid", ssid);
+ msg.putString("SSID", ssid);
}
String bssid = wInfo.getBSSID();
msg.putString("bssid", bssid);
@@ -257,20 +274,82 @@
}
}
- private WifiConfiguration wifiConfigurationFromScanResult(ScanResult result) {
- if (result == null)
+ private WifiConfiguration genEnterpriseConfig(String configStr) throws JSONException,
+ GeneralSecurityException {
+ if (configStr == null) {
return null;
+ }
+ JSONObject j = new JSONObject(configStr);
WifiConfiguration config = new WifiConfiguration();
- config.SSID = "\"" + result.SSID + "\"";
- applyingkeyMgmt(config, result);
- config.BSSID = result.BSSID;
- config.scanResultCache = new HashMap<String, ScanResult>();
- if (config.scanResultCache == null)
- return null;
- config.scanResultCache.put(result.BSSID, result);
+ config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
+ config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
+ if (j.has("SSID")) {
+ config.SSID = j.getString("SSID");
+ }
+ WifiEnterpriseConfig eConfig = new WifiEnterpriseConfig();
+ if (j.has(WifiEnterpriseConfig.EAP_KEY)) {
+ int eap = j.getInt(WifiEnterpriseConfig.EAP_KEY);
+ eConfig.setEapMethod(eap);
+ }
+ if (j.has(WifiEnterpriseConfig.PHASE2_KEY)) {
+ int p2Method = j.getInt(WifiEnterpriseConfig.PHASE2_KEY);
+ eConfig.setPhase2Method(p2Method);
+ }
+ if (j.has(WifiEnterpriseConfig.CA_CERT_KEY)) {
+ String certStr = j.getString(WifiEnterpriseConfig.CA_CERT_KEY);
+ Log.v("CA Cert String is " + certStr);
+ eConfig.setCaCertificate(strToX509Cert(certStr));
+ }
+ if (j.has(WifiEnterpriseConfig.CLIENT_CERT_KEY)
+ && j.has(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY)) {
+ String certStr = j.getString(WifiEnterpriseConfig.CLIENT_CERT_KEY);
+ String keyStr = j.getString(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY);
+ Log.v("Client Cert String is " + certStr);
+ Log.v("Client Key String is " + keyStr);
+ X509Certificate cert = strToX509Cert(certStr);
+ PrivateKey privKey = strToPrivateKey(keyStr);
+ Log.v("Cert is " + cert);
+ Log.v("Private Key is " + privKey);
+ eConfig.setClientKeyEntry(privKey, cert);
+ }
+ if (j.has(WifiEnterpriseConfig.IDENTITY_KEY)) {
+ String identity = j.getString(WifiEnterpriseConfig.IDENTITY_KEY);
+ Log.v("Setting identity to " + identity);
+ eConfig.setIdentity(identity);
+ }
+ if (j.has(WifiEnterpriseConfig.PASSWORD_KEY)) {
+ String pwd = j.getString(WifiEnterpriseConfig.PASSWORD_KEY);
+ Log.v("Setting password to " + pwd);
+ eConfig.setPassword(pwd);
+ }
+ if (j.has(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY)) {
+ String altSub = j.getString(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
+ Log.v("Setting Alt Subject to " + altSub);
+ eConfig.setAltSubjectMatch(altSub);
+ }
+ config.enterpriseConfig = eConfig;
return config;
}
+ private WifiConfiguration genWifiConfig(String SSID, String pwd) {
+ WifiConfiguration wifiConfig = new WifiConfiguration();
+ wifiConfig.SSID = "\"" + SSID + "\"";
+ if (pwd == null) {
+ wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ } else {
+ wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfig.preSharedKey = "\"" + pwd + "\"";
+ }
+ return wifiConfig;
+ }
+
+ private boolean matchScanResult(ScanResult result, String id) {
+ if (result.BSSID.equals(id) || result.SSID.equals(id)) {
+ return true;
+ }
+ return false;
+ }
+
private WifiConfiguration parseWifiApConfig(String configStr) throws JSONException {
if (configStr == null) {
return null;
@@ -307,14 +386,54 @@
info.pin = j.getString("pin");
}
return info;
-
}
- private boolean matchScanResult(ScanResult result, String id) {
- if (result.BSSID.equals(id) || result.SSID.equals(id)) {
- return true;
- }
- return false;
+ private byte[] base64StrToBytes(String input) {
+ return Base64.decode(input, Base64.DEFAULT);
+ }
+
+ private X509Certificate strToX509Cert(String certStr) throws CertificateException {
+ byte[] certBytes = base64StrToBytes(certStr);
+ InputStream certStream = new ByteArrayInputStream(certBytes);
+ CertificateFactory cf = CertificateFactory.getInstance("X509");
+ return (X509Certificate) cf.generateCertificate(certStream);
+ }
+
+ private PrivateKey strToPrivateKey(String key) throws NoSuchAlgorithmException,
+ InvalidKeySpecException {
+ byte[] keyBytes = base64StrToBytes(key);
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
+ KeyFactory fact = KeyFactory.getInstance("RSA");
+ PrivateKey priv = fact.generatePrivate(keySpec);
+ return priv;
+ }
+
+ private PublicKey strToPublicKey(String key) throws NoSuchAlgorithmException,
+ InvalidKeySpecException {
+ byte[] keyBytes = base64StrToBytes(key);
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+ KeyFactory fact = KeyFactory.getInstance("RSA");
+ PublicKey pub = fact.generatePublic(keySpec);
+ return pub;
+ }
+
+ private WifiConfiguration wifiConfigurationFromScanResult(ScanResult result) {
+ if (result == null)
+ return null;
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "\"" + result.SSID + "\"";
+ applyingkeyMgmt(config, result);
+ config.BSSID = result.BSSID;
+ config.scanResultCache = new HashMap<String, ScanResult>();
+ if (config.scanResultCache == null)
+ return null;
+ config.scanResultCache.put(result.BSSID, result);
+ return config;
+ }
+
+ @Rpc(description = "Test for base64 string transfer.")
+ public void wifiTest(String base64Str) throws JSONException, UnsupportedEncodingException {
+ Log.d(new String(Base64.decode(base64Str, Base64.DEFAULT), "UTF-8"));
}
@Rpc(description = "Add a network.")
@@ -340,18 +459,6 @@
return mWifi.getWifiState() == WifiManager.WIFI_STATE_ENABLED;
}
- private WifiConfiguration genWifiConfig(String SSID, String pwd) {
- WifiConfiguration wifiConfig = new WifiConfiguration();
- wifiConfig.SSID = "\"" + SSID + "\"";
- if (pwd.length() == 0) {
- wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
- } else {
- wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- wifiConfig.preSharedKey = "\"" + pwd + "\"";
- }
- return wifiConfig;
- }
-
/**
* Connects to a WPA protected wifi network
*
@@ -369,7 +476,12 @@
WifiConfiguration wifiConfig = genWifiConfig(SSID, Password);
mWifi.addNetwork(wifiConfig);
Boolean status = false;
- for (WifiConfiguration conf : mWifi.getConfiguredNetworks()) {
+ List<WifiConfiguration> configuredNetworks = mWifi.getConfiguredNetworks();
+ if (configuredNetworks == null) {
+ Log.d("No configured network available.");
+ return false;
+ }
+ for (WifiConfiguration conf : configuredNetworks) {
if (conf.SSID != null && conf.SSID.equals("\"" + SSID + "\"")) {
mWifi.disconnect();
mWifi.enableNetwork(conf.networkId, true);
@@ -393,6 +505,15 @@
return mWifi.enableNetwork(netId, disableOthers);
}
+ @Rpc(description = "Connect to a wifi network that uses Enterprise authentication methods.")
+ public void wifiEnterpriseConnect(@RpcParameter(name = "configStr") String configStr)
+ throws JSONException, GeneralSecurityException {
+ // Create Certificate
+ WifiActionListener listener = new WifiActionListener(mEventFacade, "EnterpriseConnect");
+ WifiConfiguration config = this.genEnterpriseConfig(configStr);
+ mWifi.connect(config, listener);
+ }
+
/**
* Forget a wifi network with priority
*
@@ -539,9 +660,11 @@
@Rpc(description = "Stop listening for wifi state change related broadcasts.")
public void wifiStopTrackingStateChange() {
- mService.unregisterReceiver(mTetherStateReceiver);
- mService.unregisterReceiver(mStateChangeReceiver);
- mTrackingWifiStateChange = false;
+ if (mTrackingWifiStateChange == true) {
+ mService.unregisterReceiver(mTetherStateReceiver);
+ mService.unregisterReceiver(mStateChangeReceiver);
+ mTrackingWifiStateChange = false;
+ }
}
@Rpc(description = "Toggle Wifi on and off.", returns = "True if Wifi is enabled.")
@@ -577,7 +700,7 @@
public void shutdown() {
wifiLockRelease();
if (mTrackingWifiStateChange == true) {
- mService.unregisterReceiver(mStateChangeReceiver);
+ wifiStopTrackingStateChange();
}
}
}
diff --git a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
index 1e81638..7051e9e 100644
--- a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
+++ b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
@@ -85,7 +85,7 @@
sFacadeClassList.add(CommonIntentsFacade.class);
sFacadeClassList.add(ContactsFacade.class);
sFacadeClassList.add(EventFacade.class);
- sFacadeClassList.add(ImsManagerFacade.class);
+ sFacadeClassList.add(ImsManagerFacade.class);
sFacadeClassList.add(LocationFacade.class);
sFacadeClassList.add(PhoneFacade.class);
sFacadeClassList.add(PreferencesFacade.class);