Merged the hostap_2.6 updates, and the Leap of Faith work, from the hostap_update...
[mech_eap.git] / libeap / wpadebug / src / w1 / fi / wpadebug / WpaCredActivity.java
diff --git a/libeap/wpadebug/src/w1/fi/wpadebug/WpaCredActivity.java b/libeap/wpadebug/src/w1/fi/wpadebug/WpaCredActivity.java
new file mode 100644 (file)
index 0000000..3902f09
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * wpadebug - wpa_supplicant and Wi-Fi debugging app for Android
+ * Copyright (c) 2013, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+package w1.fi.wpadebug;
+
+import java.util.ArrayList;
+import java.util.ListIterator;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.IOException;
+
+import android.app.ListActivity;
+import android.app.ActionBar;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ListView;
+import android.widget.ArrayAdapter;
+import android.widget.Toast;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+class Credential
+{
+    int id;
+    String realm;
+    String username;
+    String domain;
+    String imsi;
+
+    public Credential(String entry)
+    {
+       String fields[] = entry.split("\t");
+       id = Integer.parseInt(fields[0]);
+       if (fields.length > 1)
+           realm = fields[1];
+       else
+           realm = "";
+       if (fields.length > 2)
+           username = fields[2];
+       else
+           username = "";
+       if (fields.length > 3 && fields[3].length() > 0)
+           domain = fields[3];
+       else
+           domain = null;
+       if (fields.length > 4 && fields[4].length() > 0)
+           imsi = fields[4];
+       else
+           imsi = null;
+    }
+
+    public Credential(int _id, String _username, String _realm, String _domain,
+                     String _imsi)
+    {
+       id = _id;
+       username = _username;
+       realm = _realm;
+       domain = _domain;
+       imsi = _imsi;
+    }
+
+
+    @Override
+    public String toString()
+    {
+       String res = id + " - " + username + "@" + realm;
+       if (domain != null)
+           res += " (domain=" + domain + ")";
+       if (imsi != null)
+           res += " (imsi=" + imsi + ")";
+       return res;
+    }
+}
+
+public class WpaCredActivity extends ListActivity
+{
+    private static final String TAG = "wpadebug";
+    static final int CRED_EDIT_REQ = 0;
+    private ArrayList<Credential> mList;
+    private ArrayAdapter<Credential> mListAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+       mList = new ArrayList<Credential>();
+
+       String res = run("LIST_CREDS");
+       if (res == null) {
+           Toast.makeText(this, "Could not get credential list",
+                          Toast.LENGTH_LONG).show();
+           finish();
+           return;
+       }
+
+       String creds[] = res.split("\n");
+       for (String cred: creds) {
+           if (Character.isDigit(cred.charAt(0)))
+               mList.add(new Credential(cred));
+       }
+
+       mListAdapter = new ArrayAdapter<Credential>(this, android.R.layout.simple_list_item_1, mList);
+
+       setListAdapter(mListAdapter);
+       registerForContextMenu(getListView());
+
+       ActionBar abar = getActionBar();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+       menu.add(0, 0, 0, "Add credential");
+       return true;
+    }
+
+    protected void onActivityResult(int requestCode, int resultCode,
+                                   Intent data)
+    {
+       if (requestCode == CRED_EDIT_REQ) {
+           if (resultCode != RESULT_OK)
+               return;
+
+           String username = data.getStringExtra("username");
+
+           String realm = data.getStringExtra("realm");
+
+           String domain = data.getStringExtra("domain");
+           if (domain != null && domain.length() == 0)
+               domain = null;
+
+           String imsi = data.getStringExtra("imsi");
+           if (imsi != null && imsi.length() == 0)
+               imsi = null;
+
+           String password = data.getStringExtra("password");
+           if (password != null && password.length() == 0)
+               password = null;
+
+           String res = run("ADD_CRED");
+           if (res == null || res.contains("FAIL")) {
+               Toast.makeText(this, "Failed to add credential",
+                              Toast.LENGTH_LONG).show();
+               return;
+           }
+
+           int id = -1;
+           String lines[] = res.split("\n");
+           for (String line: lines) {
+               if (Character.isDigit(line.charAt(0))) {
+                   id = Integer.parseInt(line);
+                   break;
+               }
+           }
+
+           if (id < 0) {
+               Toast.makeText(this, "Failed to add credential (invalid id)",
+                              Toast.LENGTH_LONG).show();
+               return;
+           }
+
+           if (!set_cred_quoted(id, "username", username) ||
+               !set_cred_quoted(id, "realm", realm) ||
+               (password != null &&
+                !set_cred_quoted(id, "password", password)) ||
+               (domain != null && !set_cred_quoted(id, "domain", domain)) ||
+               (imsi != null && !set_cred_quoted(id, "imsi", imsi))) {
+               run("REMOVE_CRED " + id);
+               Toast.makeText(this, "Failed to set credential field",
+                              Toast.LENGTH_LONG).show();
+               return;
+           }
+
+           mListAdapter.add(new Credential(id, username, realm, domain, imsi));
+       }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item)
+    {
+       if (item.getTitle().equals("Add credential")) {
+           startActivityForResult(new Intent(this, WpaCredEditActivity.class),
+                                  CRED_EDIT_REQ);
+           return true;
+       }
+       return false;
+    }
+
+    public void onCreateContextMenu(android.view.ContextMenu menu, View v,
+                                   android.view.ContextMenu.ContextMenuInfo menuInfo)
+    {
+       menu.add(0, v.getId(), 0, "Delete");
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item)
+    {
+       if (item.getTitle().equals("Delete")) {
+           AdapterContextMenuInfo info =
+               (AdapterContextMenuInfo) item.getMenuInfo();
+           Credential cred = (Credential) getListAdapter().getItem(info.position);
+           String res = run("REMOVE_CRED " + cred.id);
+           if (res == null || !res.contains("OK")) {
+               Toast.makeText(this, "Failed to delete credential",
+                              Toast.LENGTH_LONG).show();
+           } else
+               mListAdapter.remove(cred);
+           return true;
+       }
+       return super.onContextItemSelected(item);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id)
+    {
+       Credential item = (Credential) getListAdapter().getItem(position);
+       Toast.makeText(this, "Credential selected: " + item,
+                      Toast.LENGTH_SHORT).show();
+    }
+
+    private String run(String cmd)
+    {
+       try {
+           Process proc = Runtime.getRuntime().exec(new String[]{"/system/bin/mksh-su", "-c", "wpa_cli " + cmd});
+           BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+           StringBuffer output = new StringBuffer();
+           int read;
+           char[] buffer = new char[1024];
+           while ((read = reader.read(buffer)) > 0)
+               output.append(buffer, 0, read);
+           reader.close();
+           proc.waitFor();
+           return output.toString();
+       } catch (IOException e) {
+           Toast.makeText(this, "Could not run command",
+                          Toast.LENGTH_LONG).show();
+           return null;
+       } catch (InterruptedException e) {
+           throw new RuntimeException(e);
+       }
+    }
+
+    private boolean set_cred(int id, String field, String value)
+    {
+       String res = run("SET_CRED " + id + " " + field + " " + value);
+       return res != null && res.contains("OK");
+    }
+
+    private boolean set_cred_quoted(int id, String field, String value)
+    {
+       String value2 = "'\"" + value + "\"'";
+       return set_cred(id, field, value2);
+    }
+}