Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / wpadebug / src / w1 / fi / wpadebug / WpaCredActivity.java
1 /*
2  * wpadebug - wpa_supplicant and Wi-Fi debugging app for Android
3  * Copyright (c) 2013, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 package w1.fi.wpadebug;
10
11 import java.util.ArrayList;
12 import java.util.ListIterator;
13 import java.io.BufferedReader;
14 import java.io.InputStreamReader;
15 import java.io.InputStream;
16 import java.io.IOException;
17
18 import android.app.ListActivity;
19 import android.app.ActionBar;
20 import android.content.Intent;
21 import android.os.Bundle;
22 import android.view.View;
23 import android.view.Menu;
24 import android.view.MenuItem;
25 import android.widget.ListView;
26 import android.widget.ArrayAdapter;
27 import android.widget.Toast;
28 import android.widget.AdapterView.AdapterContextMenuInfo;
29
30 class Credential
31 {
32     int id;
33     String realm;
34     String username;
35     String domain;
36     String imsi;
37
38     public Credential(String entry)
39     {
40         String fields[] = entry.split("\t");
41         id = Integer.parseInt(fields[0]);
42         if (fields.length > 1)
43             realm = fields[1];
44         else
45             realm = "";
46         if (fields.length > 2)
47             username = fields[2];
48         else
49             username = "";
50         if (fields.length > 3 && fields[3].length() > 0)
51             domain = fields[3];
52         else
53             domain = null;
54         if (fields.length > 4 && fields[4].length() > 0)
55             imsi = fields[4];
56         else
57             imsi = null;
58     }
59
60     public Credential(int _id, String _username, String _realm, String _domain,
61                       String _imsi)
62     {
63         id = _id;
64         username = _username;
65         realm = _realm;
66         domain = _domain;
67         imsi = _imsi;
68     }
69
70
71     @Override
72     public String toString()
73     {
74         String res = id + " - " + username + "@" + realm;
75         if (domain != null)
76             res += " (domain=" + domain + ")";
77         if (imsi != null)
78             res += " (imsi=" + imsi + ")";
79         return res;
80     }
81 }
82
83 public class WpaCredActivity extends ListActivity
84 {
85     private static final String TAG = "wpadebug";
86     static final int CRED_EDIT_REQ = 0;
87     private ArrayList<Credential> mList;
88     private ArrayAdapter<Credential> mListAdapter;
89
90     @Override
91     public void onCreate(Bundle savedInstanceState)
92     {
93         super.onCreate(savedInstanceState);
94
95         mList = new ArrayList<Credential>();
96
97         String res = run("LIST_CREDS");
98         if (res == null) {
99             Toast.makeText(this, "Could not get credential list",
100                            Toast.LENGTH_LONG).show();
101             finish();
102             return;
103         }
104
105         String creds[] = res.split("\n");
106         for (String cred: creds) {
107             if (Character.isDigit(cred.charAt(0)))
108                 mList.add(new Credential(cred));
109         }
110
111         mListAdapter = new ArrayAdapter<Credential>(this, android.R.layout.simple_list_item_1, mList);
112
113         setListAdapter(mListAdapter);
114         registerForContextMenu(getListView());
115
116         ActionBar abar = getActionBar();
117     }
118
119     @Override
120     public boolean onCreateOptionsMenu(Menu menu)
121     {
122         menu.add(0, 0, 0, "Add credential");
123         return true;
124     }
125
126     protected void onActivityResult(int requestCode, int resultCode,
127                                     Intent data)
128     {
129         if (requestCode == CRED_EDIT_REQ) {
130             if (resultCode != RESULT_OK)
131                 return;
132
133             String username = data.getStringExtra("username");
134
135             String realm = data.getStringExtra("realm");
136
137             String domain = data.getStringExtra("domain");
138             if (domain != null && domain.length() == 0)
139                 domain = null;
140
141             String imsi = data.getStringExtra("imsi");
142             if (imsi != null && imsi.length() == 0)
143                 imsi = null;
144
145             String password = data.getStringExtra("password");
146             if (password != null && password.length() == 0)
147                 password = null;
148
149             String res = run("ADD_CRED");
150             if (res == null || res.contains("FAIL")) {
151                 Toast.makeText(this, "Failed to add credential",
152                                Toast.LENGTH_LONG).show();
153                 return;
154             }
155
156             int id = -1;
157             String lines[] = res.split("\n");
158             for (String line: lines) {
159                 if (Character.isDigit(line.charAt(0))) {
160                     id = Integer.parseInt(line);
161                     break;
162                 }
163             }
164
165             if (id < 0) {
166                 Toast.makeText(this, "Failed to add credential (invalid id)",
167                                Toast.LENGTH_LONG).show();
168                 return;
169             }
170
171             if (!set_cred_quoted(id, "username", username) ||
172                 !set_cred_quoted(id, "realm", realm) ||
173                 (password != null &&
174                  !set_cred_quoted(id, "password", password)) ||
175                 (domain != null && !set_cred_quoted(id, "domain", domain)) ||
176                 (imsi != null && !set_cred_quoted(id, "imsi", imsi))) {
177                 run("REMOVE_CRED " + id);
178                 Toast.makeText(this, "Failed to set credential field",
179                                Toast.LENGTH_LONG).show();
180                 return;
181             }
182
183             mListAdapter.add(new Credential(id, username, realm, domain, imsi));
184         }
185     }
186
187     @Override
188     public boolean onOptionsItemSelected(MenuItem item)
189     {
190         if (item.getTitle().equals("Add credential")) {
191             startActivityForResult(new Intent(this, WpaCredEditActivity.class),
192                                    CRED_EDIT_REQ);
193             return true;
194         }
195         return false;
196     }
197
198     public void onCreateContextMenu(android.view.ContextMenu menu, View v,
199                                     android.view.ContextMenu.ContextMenuInfo menuInfo)
200     {
201         menu.add(0, v.getId(), 0, "Delete");
202     }
203
204     @Override
205     public boolean onContextItemSelected(MenuItem item)
206     {
207         if (item.getTitle().equals("Delete")) {
208             AdapterContextMenuInfo info =
209                 (AdapterContextMenuInfo) item.getMenuInfo();
210             Credential cred = (Credential) getListAdapter().getItem(info.position);
211             String res = run("REMOVE_CRED " + cred.id);
212             if (res == null || !res.contains("OK")) {
213                 Toast.makeText(this, "Failed to delete credential",
214                                Toast.LENGTH_LONG).show();
215             } else
216                 mListAdapter.remove(cred);
217             return true;
218         }
219         return super.onContextItemSelected(item);
220     }
221
222     @Override
223     protected void onListItemClick(ListView l, View v, int position, long id)
224     {
225         Credential item = (Credential) getListAdapter().getItem(position);
226         Toast.makeText(this, "Credential selected: " + item,
227                        Toast.LENGTH_SHORT).show();
228     }
229
230     private String run(String cmd)
231     {
232         try {
233             Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/mksh-su", "-c", "wpa_cli " + cmd});
234             BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
235             StringBuffer output = new StringBuffer();
236             int read;
237             char[] buffer = new char[1024];
238             while ((read = reader.read(buffer)) > 0)
239                 output.append(buffer, 0, read);
240             reader.close();
241             proc.waitFor();
242             return output.toString();
243         } catch (IOException e) {
244             Toast.makeText(this, "Could not run command",
245                            Toast.LENGTH_LONG).show();
246             return null;
247         } catch (InterruptedException e) {
248             throw new RuntimeException(e);
249         }
250     }
251
252     private boolean set_cred(int id, String field, String value)
253     {
254         String res = run("SET_CRED " + id + " " + field + " " + value);
255         return res != null && res.contains("OK");
256     }
257
258     private boolean set_cred_quoted(int id, String field, String value)
259     {
260         String value2 = "'\"" + value + "\"'";
261         return set_cred(id, field, value2);
262     }
263 }