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 } else { 63 Log.w(TAG, "failed to build wifi configuration"); 64 doNotInstall = true; 65 } 66 } 67 68 @Override 69 protected void onResume() { 70 super.onResume(); 71 createMainDialog(); 72 } 73 74 public static List<String> splitDomain(String domain) { 75 if (domain.endsWith(".")) { 76 domain = domain.substring(0, domain.length() - 1); 77 } 78 79 String[] labels = domain.toLowerCase().split("\\."); 80 LinkedList<String> labelList = new LinkedList<>(); 81 for (String label : labels) { 82 labelList.addFirst(label); 83 } 84 85 return labelList; 86 } 87 88 public static boolean sameBaseDomain(List<String> arg1, String domain) { 89 if (domain == null) { 90 return false; 91 } 92 93 List<String> arg2 = splitDomain(domain); 94 if (arg2.isEmpty()) { 95 return false; 96 } 97 Iterator<String> l1 = arg1.iterator(); 98 Iterator<String> l2 = arg2.iterator(); 99 100 while(l1.hasNext() && l2.hasNext()) { 101 if (!l1.next().equals(l2.next())) { 102 return false; 103 } 104 } 105 return true; 106 } 107 108 private void createMainDialog() { 109 Resources res = getResources(); 110 AlertDialog.Builder builder = new AlertDialog.Builder(this); 111 View layout = getLayoutInflater().inflate(R.layout.wifi_main_dialog, null); 112 builder.setView(layout); 113 114 TextView text = (TextView) layout.findViewById(R.id.wifi_info); 115 if (!doNotInstall) { 116 text.setText(String.format(getResources().getString(R.string.wifi_installer_detail), 117 mWifiConfiguration.providerFriendlyName)); 118 119 builder.setTitle(mWifiConfiguration.providerFriendlyName); 120 builder.setIcon(res.getDrawable(R.drawable.signal_wifi_4_bar_lock_black_24dp)); 121 122 builder.setPositiveButton(R.string.wifi_install_label, 123 new DialogInterface.OnClickListener() { 124 @Override 125 public void onClick(DialogInterface dialog, int which) { 126 final boolean wifiEnabled = mWifiManager.isWifiEnabled(); 127 if (wifiEnabled) { 128 Toast.makeText(WiFiInstaller.this, getString(R.string.wifi_installing_label), 129 Toast.LENGTH_LONG).show(); 130 } 131 AsyncTask.execute(new Runnable() { 132 @Override 133 public void run() { 134 boolean success = false; 135 if (wifiEnabled) { 136 List<String> newDomain = splitDomain(mWifiConfiguration.FQDN); 137 for (WifiConfiguration config : 138 mWifiManager.getConfiguredNetworks()) { 139 if (sameBaseDomain(newDomain, config.FQDN)) { 140 mWifiManager.removeNetwork(config.networkId); 141 break; 142 } 143 } 144 try { 145 success = mWifiManager.addNetwork(mWifiConfiguration) != -1 146 && mWifiManager.saveConfiguration(); 147 } 148 catch (RuntimeException rte) { 149 Log.w(TAG, "Caught exception while installing wifi config: " + 150 rte, rte); 151 success = false; 152 } 153 } 154 if (success) { 155 Intent intent = new Intent(getApplicationContext(), 156 CredentialsInstallDialog.class); 157 intent.putExtra(NETWORK_NAME, 158 mWifiConfiguration.providerFriendlyName); 159 intent.putExtra(INSTALL_STATE, INSTALL_SUCCESS); 160 startActivity(intent); 161 } else { 162 Intent intent = new Intent(getApplicationContext(), 163 CredentialsInstallDialog.class); 164 if (!wifiEnabled) { 165 intent.putExtra(INSTALL_STATE, INSTALL_FAIL_NO_WIFI); 166 } else { 167 intent.putExtra(INSTALL_STATE, INSTALL_FAIL); 168 } 169 startActivity(intent); 170 } 171 finish(); 172 } 173 }); 174 dialog.dismiss(); 175 } 176 }); 177 178 builder.setNegativeButton(R.string.wifi_cancel_label, new 179 DialogInterface.OnClickListener() { 180 @Override 181 public void onClick(DialogInterface dialog, int which) { 182 dialog.dismiss(); 183 finish(); 184 } 185 }); 186 } else { 187 text.setText(getResources().getString(R.string.wifi_installer_download_error)); 188 builder.setPositiveButton(R.string.done_label, new DialogInterface.OnClickListener() { 189 @Override 190 public void onClick(DialogInterface dialog, int which) { 191 dialog.dismiss(); 192 finish(); 193 } 194 }); 195 } 196 builder.create().show(); 197 } 198 } 199