aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2013-05-05 16:38:51 (GMT)
committerJouni Malinen <j@w1.fi>2013-05-05 18:05:20 (GMT)
commit728b04314c4935a6715abd794f36e531ab9800cb (patch)
treea9b0475daf6fbbf3c71b80a1652fb05c6b3fb677
parentd7232a8da636073189a41b42c6ff389b562a86f3 (diff)
downloadhostap-728b04314c4935a6715abd794f36e531ab9800cb.zip
hostap-728b04314c4935a6715abd794f36e531ab9800cb.tar.gz
hostap-728b04314c4935a6715abd794f36e531ab9800cb.tar.bz2
wpadebug: Add credential manager
Signed-hostap: Jouni Malinen <j@w1.fi>
-rw-r--r--wpadebug/AndroidManifest.xml8
-rw-r--r--wpadebug/res/layout/cred_edit.xml117
-rw-r--r--wpadebug/res/layout/main.xml12
-rw-r--r--wpadebug/src/w1/fi/wpadebug/MainActivity.java6
-rw-r--r--wpadebug/src/w1/fi/wpadebug/WpaCredActivity.java263
-rw-r--r--wpadebug/src/w1/fi/wpadebug/WpaCredEditActivity.java55
6 files changed, 461 insertions, 0 deletions
diff --git a/wpadebug/AndroidManifest.xml b/wpadebug/AndroidManifest.xml
index 227f182..56f80aa 100644
--- a/wpadebug/AndroidManifest.xml
+++ b/wpadebug/AndroidManifest.xml
@@ -36,5 +36,13 @@
android:label="WPA command list"
android:parentActivityName="w1.fi.wpadebug.MainActivity">
</activity>
+ <activity android:name="w1.fi.wpadebug.WpaCredActivity"
+ android:label="Credentials"
+ android:parentActivityName="w1.fi.wpadebug.MainActivity">
+ </activity>
+ <activity android:name="w1.fi.wpadebug.WpaCredEditActivity"
+ android:label="Credential"
+ android:parentActivityName="w1.fi.wpadebug.WpaCredActivity">
+ </activity>
</application>
</manifest>
diff --git a/wpadebug/res/layout/cred_edit.xml b/wpadebug/res/layout/cred_edit.xml
new file mode 100644
index 0000000..292b30a
--- /dev/null
+++ b/wpadebug/res/layout/cred_edit.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ >
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Username"
+ />
+ <EditText android:id="@+id/cred_edit_username"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:lines="1"
+ />
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Realm"
+ />
+ <EditText android:id="@+id/cred_edit_realm"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:lines="1"
+ />
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Password"
+ />
+ <EditText android:id="@+id/cred_edit_password"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:lines="1"
+ android:inputType="textPassword"
+ />
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Domain"
+ />
+ <EditText android:id="@+id/cred_edit_domain"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:lines="1"
+ />
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="IMSI"
+ />
+ <EditText android:id="@+id/cred_edit_imsi"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:lines="1"
+ android:hint="Used only with SIM/USIM testing"
+ />
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Save"
+ android:onClick="credSave"
+ />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel"
+ android:onClick="credCancel"
+ />
+ </LinearLayout>
+</LinearLayout>
diff --git a/wpadebug/res/layout/main.xml b/wpadebug/res/layout/main.xml
index 76841b1..6fdd565 100644
--- a/wpadebug/res/layout/main.xml
+++ b/wpadebug/res/layout/main.xml
@@ -58,6 +58,18 @@
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:text="Credentials"
+ android:onClick="runWpaCredentials"
+ />
+ </LinearLayout>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:text="log:info"
android:onClick="wpaLogLevelInfo"
/>
diff --git a/wpadebug/src/w1/fi/wpadebug/MainActivity.java b/wpadebug/src/w1/fi/wpadebug/MainActivity.java
index 0c601d3..c5d123e 100644
--- a/wpadebug/src/w1/fi/wpadebug/MainActivity.java
+++ b/wpadebug/src/w1/fi/wpadebug/MainActivity.java
@@ -53,6 +53,12 @@ public class MainActivity extends Activity
startActivity(intent);
}
+ public void runWpaCredentials(View view)
+ {
+ Intent intent = new Intent(this, WpaCredActivity.class);
+ startActivity(intent);
+ }
+
public void runWpaCliCmd(View view)
{
Intent intent = new Intent(this, DisplayMessageActivity.class);
diff --git a/wpadebug/src/w1/fi/wpadebug/WpaCredActivity.java b/wpadebug/src/w1/fi/wpadebug/WpaCredActivity.java
new file mode 100644
index 0000000..3902f09
--- /dev/null
+++ b/wpadebug/src/w1/fi/wpadebug/WpaCredActivity.java
@@ -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);
+ }
+}
diff --git a/wpadebug/src/w1/fi/wpadebug/WpaCredEditActivity.java b/wpadebug/src/w1/fi/wpadebug/WpaCredEditActivity.java
new file mode 100644
index 0000000..3f846c7
--- /dev/null
+++ b/wpadebug/src/w1/fi/wpadebug/WpaCredEditActivity.java
@@ -0,0 +1,55 @@
+/*
+ * 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 android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+
+public class WpaCredEditActivity extends Activity
+{
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.cred_edit);
+ }
+
+ public void credSave(View view)
+ {
+ Intent data = new Intent();
+ EditText edit;
+
+ edit = (EditText) findViewById(R.id.cred_edit_username);
+ data.putExtra("username", edit.getText().toString());
+
+ edit = (EditText) findViewById(R.id.cred_edit_realm);
+ data.putExtra("realm", edit.getText().toString());
+
+ edit = (EditText) findViewById(R.id.cred_edit_password);
+ data.putExtra("password", edit.getText().toString());
+
+ edit = (EditText) findViewById(R.id.cred_edit_domain);
+ data.putExtra("domain", edit.getText().toString());
+
+ edit = (EditText) findViewById(R.id.cred_edit_imsi);
+ data.putExtra("imsi", edit.getText().toString());
+
+ setResult(Activity.RESULT_OK, data);
+ finish();
+ }
+
+ public void credCancel(View view)
+ {
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ }
+}