1 package com.android.certinstaller; 2 3 import android.app.Activity; 4 import android.app.AlertDialog; 5 import android.content.ActivityNotFoundException; 6 import android.content.Context; 7 import android.content.DialogInterface; 8 import android.content.Intent; 9 import android.content.res.Resources; 10 import android.net.wifi.WifiConfiguration; 11 import android.net.wifi.WifiEnterpriseConfig; 12 import android.net.wifi.WifiManager; 13 import android.os.Bundle; 14 import android.security.Credentials; 15 import android.security.KeyStore; 16 import android.util.Log; 17 import android.view.View; 18 import android.widget.Button; 19 import android.widget.TextView; 20 import android.widget.Toast; 21 import android.os.AsyncTask; 22 23 import java.security.PrivateKey; 24 import java.security.interfaces.RSAPrivateKey; 25 import java.util.Collection; 26 import java.util.Iterator; 27 import java.util.LinkedList; 28 import java.util.List; 29 30 public class WiFiInstaller extends Activity { 31 32 private static final String TAG = "WifiInstaller"; 33 private static final String NETWORK_NAME = "network_name"; 34 private static final String INSTALL_STATE = "install_state"; 35 public static final int INSTALL_SUCCESS = 2; 36 public static final int INSTALL_FAIL = 1; 37 public static final int INSTALL_FAIL_NO_WIFI = 0; 38 WifiConfiguration mWifiConfiguration; 39 WifiManager mWifiManager; 40 boolean doNotInstall; 41 42 @Override 43 protected void onCreate(Bundle savedStates) { 44 super.onCreate(savedStates); 45 46 Bundle bundle = getIntent().getExtras(); 47 String uriString = bundle.getString(CertInstallerMain.WIFI_CONFIG_FILE); 48 String mimeType = bundle.getString(CertInstallerMain.WIFI_CONFIG); 49 byte[] data = bundle.getByteArray(CertInstallerMain.WIFI_CONFIG_DATA); 50 51 Log.d(TAG, "WiFi data for " + CertInstallerMain.WIFI_CONFIG + ": " + 52 mimeType + " is " + (data != null ? data.length : "-")); 53 54 mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 55 mWifiConfiguration = mWifiManager.buildWifiConfig(uriString, mimeType, data); 56 57 if (mWifiConfiguration != null) { 58 WifiEnterpriseConfig enterpriseConfig = mWifiConfiguration.enterpriseConfig; 59 doNotInstall = (enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TTLS 60 || enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS) 61 && enterpriseConfig.getCaCertificate() == null; 62 if (!doNotInstall && (enterpriseConfig.getClientCertificate() != null 63 || enterpriseConfig.getCaCertificate() != null)) { 64 if (!KeyStore.getInstance().isUnlocked()) { 65 try { 66 startActivity(new Intent(Credentials.UNLOCK_ACTION)); 67 } catch (ActivityNotFoundException e) { 68 Log.w(TAG, e); 69 } 70 } 71 } 72 } else { 73 Log.w(TAG, "failed to build wifi configuration"); 74 doNotInstall = true; 75 } 76 } 77 78 @Override 79 protected void onResume() { 80 super.onResume(); 81 createMainDialog(); 82 } 83 84 public static List<String> splitDomain(String domain) { 85 if (domain.endsWith(".")) { 86 domain = domain.substring(0, domain.length() - 1); 87 } 88 89 String[] labels = domain.toLowerCase().split("\\."); 90 LinkedList<String> labelList = new LinkedList<>(); 91 for (String label : labels) { 92 labelList.addFirst(label); 93 } 94 95 return labelList; 96 } 97 98 public static boolean sameBaseDomain(List<String> arg1, String domain) { 99 if (domain == null) { 100 return false; 101 } 102 103 List<String> arg2 = splitDomain(domain); 104 if (arg2.isEmpty()) { 105 return false; 106 } 107 Iterator<String> l1 = arg1.iterator(); 108 Iterator<String> l2 = arg2.iterator(); 109 110 while(l1.hasNext() && l2.hasNext()) { 111 if (!l1.next().equals(l2.next())) { 112 return false; 113 } 114 } 115 return true; 116 } 117 118 private void createMainDialog() { 119 Resources res = getResources(); 120 AlertDialog.Builder builder = new AlertDialog.Builder(this); 121 View layout = getLayoutInflater().inflate(R.layout.wifi_main_dialog, null); 122 builder.setView(layout); 123 124 TextView text = (TextView) layout.findViewById(R.id.wifi_info); 125 if (!doNotInstall) { 126 text.setText(String.format(getResources().getString(R.string.wifi_installer_detail), 127 mWifiConfiguration.providerFriendlyName)); 128 129 builder.setTitle(mWifiConfiguration.providerFriendlyName); 130 builder.setIcon(res.getDrawable(R.drawable.signal_wifi_4_bar_lock_black_24dp)); 131 132 builder.setPositiveButton(R.string.wifi_install_label, 133 new DialogInterface.OnClickListener() { 134 @Override 135 public void onClick(DialogInterface dialog, int which) { 136 final boolean wifiEnabled = mWifiManager.isWifiEnabled(); 137 if (wifiEnabled) { 138 Toast.makeText(WiFiInstaller.this, getString(R.string.wifi_installing_label), 139 Toast.LENGTH_LONG).show(); 140 } 141 AsyncTask.execute(new Runnable() { 142 @Override 143 public void run() { 144 boolean success = false; 145 if (wifiEnabled) { 146 List<String> newDomain = splitDomain(mWifiConfiguration.FQDN); 147 for (WifiConfiguration config : 148 mWifiManager.getConfiguredNetworks()) { 149 if (sameBaseDomain(newDomain, config.FQDN)) { 150 mWifiManager.removeNetwork(config.networkId); 151 break; 152 } 153 } 154 try { 155 success = mWifiManager.addNetwork(mWifiConfiguration) != -1 156 && mWifiManager.saveConfiguration(); 157 } 158 catch (RuntimeException rte) { 159 Log.w(TAG, "Caught exception while installing wifi config: " + 160 rte, rte); 161 success = false; 162 } 163 } 164 if (success) { 165 Intent intent = new Intent(getApplicationContext(), 166 CredentialsInstallDialog.class); 167 intent.putExtra(NETWORK_NAME, 168 mWifiConfiguration.providerFriendlyName); 169 intent.putExtra(INSTALL_STATE, INSTALL_SUCCESS); 170 startActivity(intent); 171 } else { 172 Intent intent = new Intent(getApplicationContext(), 173 CredentialsInstallDialog.class); 174 if (!wifiEnabled) { 175 intent.putExtra(INSTALL_STATE, INSTALL_FAIL_NO_WIFI); 176 } else { 177 intent.putExtra(INSTALL_STATE, INSTALL_FAIL); 178 } 179 startActivity(intent); 180 } 181 finish(); 182 } 183 }); 184 dialog.dismiss(); 185 } 186 }); 187 188 builder.setNegativeButton(R.string.wifi_cancel_label, new 189 DialogInterface.OnClickListener() { 190 @Override 191 public void onClick(DialogInterface dialog, int which) { 192 dialog.dismiss(); 193 finish(); 194 } 195 }); 196 } else { 197 text.setText(getResources().getString(R.string.wifi_installer_download_error)); 198 builder.setPositiveButton(R.string.done_label, new DialogInterface.OnClickListener() { 199 @Override 200 public void onClick(DialogInterface dialog, int which) { 201 dialog.dismiss(); 202 finish(); 203 } 204 }); 205 } 206 builder.create().show(); 207 } 208 } 209