Home | History | Annotate | Download | only in certinstaller
      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