1
0
mirror of http://galexander.org/git/simplesshd.git synced 2024-11-27 09:48:08 +00:00

replace awkward authorized keys editor with a single "Reset Keys" option

to delete the authorized_keys file and revert to single-use passwords
This commit is contained in:
Greg Alexander 2016-10-16 19:07:52 -04:00
parent 4d888fdd81
commit 0523529968
6 changed files with 27 additions and 313 deletions

View File

@ -3,9 +3,9 @@
<item android:id="@+id/settings"
android:icon="@android:drawable/ic_menu_manage"
android:title="Settings" />
<item android:id="@+id/authkeys"
<item android:id="@+id/resetkeys"
android:icon="@android:drawable/ic_secure"
android:title="Authorized Keys" />
android:title="Reset Keys" />
<item android:id="@+id/doc"
android:icon="@android:drawable/ic_menu_help"
android:title="Documentation" />

View File

@ -1,133 +0,0 @@
package org.galexander.sshd;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.text.InputType;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class AuthKeys extends Activity {
private EditText authtext;
private String authtext_orig;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.authkeys);
authtext = (EditText)findViewById(R.id.authtext);
authtext_orig = null;
}
public void onResume() {
super.onResume();
AuthKeysLoad.go(this);
}
public void onPause() {
save_authtext();
super.onPause();
}
public void fetch_clicked(View v) {
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setTitle("Fetch authorized_keys");
final EditText url = new EditText(this);
url.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_URI);
ab.setView(url);
ab.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int which) {
start_fetch(url.getText().toString());
} });
ab.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int which) {
d.cancel();
} });
ab.show();
}
public void cancel_clicked(View v) {
authtext_orig = null;
finish();
}
public void save_clicked(View v) {
save_authtext();
finish();
}
private void save_authtext() {
String s = get_authtext();
if ((s != null) && ((authtext_orig != null) ||
!s.equals(authtext_orig))) {
Intent i = new Intent(this, AuthKeysSave.class);
i.putExtra("s", s);
startService(i);
}
/* so that we won't save it again */
authtext_orig = null;
}
private String get_authtext() {
if (authtext != null) {
return authtext.getText().toString();
}
return null;
}
/* called from AuthKeysLoad, which puts it on the UI thread */
public void set_authtext(String s) {
if (authtext != null) {
authtext.setText(s);
authtext_orig = s;
}
}
/* called from AuthKeysFetch, from its own thread */
public void append_authtext(String s) {
if (authtext != null) {
String t = get_authtext();
if (t == null) {
t = "";
}
if (!t.endsWith("\n")) {
t += "\n";
}
t += s;
authtext.setText(t);
}
}
private void start_fetch(String url) {
Intent i = new Intent(this, AuthKeysFetch.class);
final Context ctx = this;
i.putExtra("url", url);
i.putExtra("m", new Messenger(new Handler() {
public void handleMessage(Message msg) {
Object o = msg.obj;
if (o == null) {
return;
}
String s = (String)o;
int n = msg.arg1;
if (n == 0) {
/* s is data read from the url */
append_authtext(s);
} else {
/* s must be an error message */
Toast.makeText(ctx, s,
Toast.LENGTH_LONG).show();
}
} } ));
startService(i);
}
}

View File

@ -1,60 +0,0 @@
package org.galexander.sshd;
import android.app.IntentService;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import java.io.InputStream;
import java.net.URL;
import java.net.HttpURLConnection;
public class AuthKeysFetch extends IntentService {
public AuthKeysFetch() {
super("SimpleSSHDAuthKeysFetch");
}
protected void onHandleIntent(Intent i) {
Messenger m = (Messenger)i.getParcelableExtra("m");
Message msg = Message.obtain();
String url = i.getStringExtra("url");
String result = "";
byte[] b = new byte[1024];
try {
if (url == null) {
throw new Exception("no url");
}
URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection)
u.openConnection();
try {
InputStream in = conn.getInputStream();
try {
while (result.length() < 65536) {
int r = in.read(b);
if (r <= 0) {
break;
}
result += new String(b, 0, r);
}
} finally {
in.close();
}
} finally {
conn.disconnect();
}
if (result.equals("")) {
throw new Exception("empty file");
}
msg.arg1 = 0;
msg.obj = result;
} catch (Exception e) {
msg.arg1 = 1;
msg.obj = "HTTP fetch: " + e.getMessage();
}
try {
m.send(msg);
} catch (Exception e) { }
}
}

View File

@ -1,58 +0,0 @@
package org.galexander.sshd;
import android.app.Activity;
import android.os.AsyncTask;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
public class AuthKeysLoad extends AsyncTask<Void,Void,Void> {
private AuthKeys act = null;
private String result = null;
private String error = null;
public static void go(AuthKeys act_) {
(new AuthKeysLoad(act_)).execute();
}
AuthKeysLoad(AuthKeys act_) {
super();
act = act_;
}
protected Void doInBackground(Void... v) {
try {
File f = new File(Prefs.get_path(), "authorized_keys");
FileInputStream fis = new FileInputStream(f);
byte b[] = new byte[1024];
result = "";
try {
while (true) {
int r = fis.read(b);
if (r <= 0) {
break;
}
result += new String(b, 0, r);
}
} finally {
fis.close();
}
} catch (Exception e) {
error = e.getMessage();
}
return null;
}
protected void onPostExecute(Void v) {
if (result != null) {
act.set_authtext(result);
} else if (error != null) {
Toast.makeText(act,
"failed to load authorized_keys: " + error,
Toast.LENGTH_LONG).show();
}
}
}

View File

@ -1,36 +0,0 @@
package org.galexander.sshd;
import android.app.IntentService;
import android.content.Intent;
import java.io.File;
import java.io.FileOutputStream;
public class AuthKeysSave extends IntentService {
public AuthKeysSave() {
super("SimpleSSHDAuthKeysSave");
}
protected void onHandleIntent(Intent i) {
String s = i.getStringExtra("s");
if (s == null) {
return;
}
try {
File p = new File(Prefs.get_path());
if (!p.exists()) {
p.mkdirs();
}
File f = new File(p, "authorized_keys");
FileOutputStream fos = new FileOutputStream(f);
int ofs = 0;
try {
fos.write(s.getBytes());
} finally {
fos.close();
}
} catch (Exception e) {
SimpleSSHD.toast(
"authorized_keys save failed: "+e.getMessage());
}
}
}

View File

@ -11,7 +11,6 @@ import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Button;
import android.widget.Toast;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
@ -32,7 +31,6 @@ public class SimpleSSHD extends Activity
private TextView ip_view;
public static SimpleSSHD curr = null;
private UpdaterThread updater = null;
private static String pending_toast = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -47,11 +45,6 @@ public class SimpleSSHD extends Activity
super.onResume();
synchronized (lock) {
curr = this;
if (pending_toast != null) {
Toast.makeText(this, pending_toast,
Toast.LENGTH_LONG).show();
pending_toast = null;
}
}
update_startstop_prime();
updater = new UpdaterThread();
@ -81,8 +74,8 @@ public class SimpleSSHD extends Activity
case R.id.settings:
startActivity(new Intent(this, Settings.class));
return true;
case R.id.authkeys:
startActivity(new Intent(this, AuthKeys.class));
case R.id.resetkeys:
reset_keys();
return true;
case R.id.doc: {
Intent i = new Intent(Intent.ACTION_VIEW);
@ -227,6 +220,29 @@ public class SimpleSSHD extends Activity
return ret;
}
private void do_reset_keys() {
new File(Prefs.get_path(), "authorized_keys").delete();
}
private void reset_keys() {
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setCancelable(true);
b.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di,
int which) { do_reset_keys(); }
});
b.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di,
int which) { }
});
b.setIcon(android.R.drawable.ic_dialog_alert);
b.setTitle("Reset Keys");
b.setMessage("Delete the authorized_keys file? (then you will only be able to login with single-use passwords)");
b.show();
}
public String my_version() {
try {
return getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
@ -234,19 +250,4 @@ public class SimpleSSHD extends Activity
return "UNKNOWN";
}
}
/* called from AuthKeysSave (in its own worker thread) if it fails */
public static void toast(final String s) {
synchronized (lock) {
if (curr != null) {
curr.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(curr, s,
Toast.LENGTH_LONG).show();
} });
} else {
pending_toast = s;
}
}
}
}