1package com.android.certinstaller;
2
3import android.app.Activity;
4import android.app.AlertDialog;
5import android.content.ActivityNotFoundException;
6import android.content.Context;
7import android.content.DialogInterface;
8import android.content.Intent;
9import android.content.res.Resources;
10import android.net.wifi.WifiConfiguration;
11import android.net.wifi.WifiEnterpriseConfig;
12import android.net.wifi.WifiManager;
13import android.os.Bundle;
14import android.security.Credentials;
15import android.security.KeyStore;
16import android.util.Log;
17import android.view.View;
18import android.widget.Button;
19import android.widget.TextView;
20import android.widget.Toast;
21import android.os.AsyncTask;
22
23import java.security.PrivateKey;
24import java.security.interfaces.RSAPrivateKey;
25import java.util.Collection;
26import java.util.Iterator;
27import java.util.LinkedList;
28import java.util.List;
29
30public 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