use app-private path for home/ssh directory by default, and make a menu

option to Copy App-private Path
sigsegv_dump
Greg Alexander 6 years ago
parent 8fd055940e
commit 906d6a30ef

27
NOTES

@ -621,9 +621,30 @@ READ_EXTERNAL_STORAGE, so long as I explicitly request
WRITE_EXTERNAL_STORAGE. WRITE_EXTERNAL_STORAGE.
XXX - make sure to create the app-private files/ on first startup May 19, 2018.
XXX - add options menu "copy app-private path", or something
XXX - change default from /sdcard/ssh to app-private/files for new installs, or something Michael Mess wrote to let me know that he can't use authorized_keys file
because the /sdcard/ssh/authorized_keys file is group-readwritable. I
know regular OpenSSH on a PC does complain if the authorized_keys file is
world-writable, so this made sense to me. He says it is a security flaw,
but really, it is not, because any app that can run code and write to
/sdcard/ssh already has all of the permissions that SimpleSSHD has
(except network, but whatever) -- it isn't escalation, just a horizontal
spreading.
He suggested moving the SSH config into app-private, which is something
I've been toying with anyways.
So after some internal debate, I decided to do two changes:
* add "Copy app-private path" to the options menu, which brings up a
dialog showing the app-private path, with an option "Copy" to put it
in the clipboard.
* make the default for new installs for "home" and "path" be the
app-private dir
I look forward to seeing if anyone complains about it.
XXX - upgrade project.properties to android-26 XXX - upgrade project.properties to android-26
XXX - call checkSelfPermission/requestPermission to get WRITE_EXTERNAL_STORAGE XXX - call checkSelfPermission/requestPermission to get WRITE_EXTERNAL_STORAGE

@ -29,8 +29,8 @@ Port 2222
</pre> </pre>
<li> Launch SimpleSSHD, and in Settings enable "Start on Boot", then <li> Launch SimpleSSHD, and in Settings enable "Start on Boot", then
manually start it for the first time. manually start it for the first time.
<li> Create <tt>/sdcard/ssh/authorized_keys</tt> <li> Create <tt>authorized_keys</tt> in the home directory
<li> Optionally make <tt>/sdcard/ssh/.profile</tt> <li> Optionally make <tt>.profile</tt>
</ul> </ul>
<p>If SimpleSSHD does not find an <tt>authorized_keys</tt> file when a <p>If SimpleSSHD does not find an <tt>authorized_keys</tt> file when a
@ -45,6 +45,15 @@ file.</p>
is supported. If you screw up your <tt>authorized_keys</tt> file, use is supported. If you screw up your <tt>authorized_keys</tt> file, use
the options menu (upper right) -> Reset Keys.</p> the options menu (upper right) -> Reset Keys.</p>
<p>The default home directory is now the app-private directory, which
will generally be something like
<tt>/data/data/org.galexander.sshd/files</tt>, but may vary depending on
your device. Use options menu -> Copy App-private Path to view the path
or copy it onto the clipboard. A nice feature of the app-private
directory is it generally supports the full range of Unix of file
permissions, including execute! A disadvantage is that these files all
disappear if you uninstall SimpleSSHD.</p>
<p>Once you get setup, you may want BusyBox. Check out <p>Once you get setup, you may want BusyBox. Check out
<a href="https://play.google.com/store/apps/details?id=org.galexander.busybox">SimpleBusyBox</a>.</p> <a href="https://play.google.com/store/apps/details?id=org.galexander.busybox">SimpleBusyBox</a>.</p>
@ -77,8 +86,10 @@ and then click "QUIT" when you are done.</dd>
greater than 1024 (because SimpleSSHD does not have root).</dd> greater than 1024 (because SimpleSSHD does not have root).</dd>
<dt>SSH Path</dt> <dt>SSH Path</dt>
<dd>Path for general dropbear files, which defaults to <dd>Path for general dropbear files, which now defaults to
<tt>/sdcard/ssh</tt>. Most importantly, this is where the app-private directory (usually something like
<tt>/data/data/org.galexander.sshd/files</tt>).
Most importantly, this is where
<tt>authorized_keys</tt> is found. It is also where host keys wind up <tt>authorized_keys</tt> is found. It is also where host keys wind up
(they are created on demand), and where temporary files go. This path (they are created on demand), and where temporary files go. This path
should probably be under <tt>/sdcard</tt>.</dd> should probably be under <tt>/sdcard</tt>.</dd>
@ -106,8 +117,9 @@ SuperSU.</dd>
<dt>Home Directory</dt> <dt>Home Directory</dt>
<dd>The login shell's home directory, which also defaults <dd>The login shell's home directory, which also defaults
to <tt>/sdcard/ssh</tt>. This is where your ssh session starts out, and is to the app-private directory.
where <tt>.profile</tt> will be found if it is present.</dd> This is where your ssh session starts out, and is where <tt>.profile</tt>
will be found if it is present.</dd>
<dt>Extra Commandline</dt> <dt>Extra Commandline</dt>
<dd>You can specify additional commandline options for dropbear server. <dd>You can specify additional commandline options for dropbear server.
@ -158,6 +170,8 @@ harmless.
<h2>Change Log</h2> <h2>Change Log</h2>
<ul> <ul>
<li> <b>2018/05/19 Version 19:</b> Use the app-private directory by
default on new installs for the SSH/home dir.
<li> <b>2018/05/16 Version 18:</b> Use correct idiom for <tt>su</tt> as a <li> <b>2018/05/16 Version 18:</b> Use correct idiom for <tt>su</tt> as a
login shell (so busybox <tt>su</tt> can work). Add environment variables login shell (so busybox <tt>su</tt> can work). Add environment variables
to settings. to settings.

@ -3,6 +3,8 @@
<item android:id="@+id/settings" <item android:id="@+id/settings"
android:icon="@android:drawable/ic_menu_manage" android:icon="@android:drawable/ic_menu_manage"
android:title="Settings" /> android:title="Settings" />
<item android:id="@+id/copypriv"
android:title="Copy App-private Path" />
<item android:id="@+id/resetkeys" <item android:id="@+id/resetkeys"
android:icon="@android:drawable/ic_secure" android:icon="@android:drawable/ic_secure"
android:title="Reset Keys" /> android:title="Reset Keys" />

@ -24,7 +24,7 @@
android:key="path" android:key="path"
android:title="SSH Path" android:title="SSH Path"
android:summary="Location of misc dropbear files (put authorized_keys here)." android:summary="Location of misc dropbear files (put authorized_keys here)."
android:defaultValue="/sdcard/ssh" /> android:defaultValue="/xxx" />
<EditTextPreference <EditTextPreference
android:key="shell" android:key="shell"
android:title="Login Shell" android:title="Login Shell"
@ -38,7 +38,7 @@
android:key="home" android:key="home"
android:title="Home Directory" android:title="Home Directory"
android:summary="Default directory after login (put .profile here)." android:summary="Default directory after login (put .profile here)."
android:defaultValue="/sdcard/ssh" /> android:defaultValue="/xxx" />
<EditTextPreference <EditTextPreference
android:key="extra" android:key="extra"
android:title="Extra Commandline" android:title="Extra Commandline"

@ -10,6 +10,7 @@ public class Prefs {
public static void init(Context c) { public static void init(Context c) {
if (pref == null) { if (pref == null) {
pref = PreferenceManager.getDefaultSharedPreferences(c); pref = PreferenceManager.getDefaultSharedPreferences(c);
set_defaults();
} }
} }
@ -35,13 +36,13 @@ public class Prefs {
return ret; return ret;
} }
public static String get_path() { public static String get_path() {
return pref.getString("path", "/sdcard/ssh"); return pref.getString("path", SimpleSSHD.app_private);
} }
public static String get_shell() { public static String get_shell() {
return pref.getString("shell", "/system/bin/sh"); return pref.getString("shell", "/system/bin/sh");
} }
public static String get_home() { public static String get_home() {
return pref.getString("home", "/sdcard/ssh"); return pref.getString("home", SimpleSSHD.app_private);
} }
public static String get_extra() { public static String get_extra() {
return pref.getString("extra", ""); return pref.getString("extra", "");
@ -50,7 +51,21 @@ public class Prefs {
return pref.getString("env", ""); return pref.getString("env", "");
} }
public static SharedPreferences.Editor edit() { /* NB - other defaults can be filled in by either Prefs or Settings as
return pref.edit(); * needed */
private static void set_defaults() {
boolean need_path = (pref.getString("path", null) == null);
boolean need_home = (pref.getString("home", null) == null);
if (!need_path && !need_home) {
return;
}
SharedPreferences.Editor edit = pref.edit();
if (need_path) {
edit.putString("path", SimpleSSHD.app_private);
}
if (need_home) {
edit.putString("home", SimpleSSHD.app_private);
}
edit.commit();
} }
}; };

@ -7,13 +7,15 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.Intent; import android.content.Intent;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.widget.CheckBox; import android.text.ClipboardManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Button;
import android.view.View; import android.view.View;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.net.Uri; import android.net.Uri;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
@ -30,10 +32,12 @@ public class SimpleSSHD extends Activity
private Button startstop_view; private Button startstop_view;
private TextView ip_view; private TextView ip_view;
public static SimpleSSHD curr = null; public static SimpleSSHD curr = null;
public static String app_private = null;
private UpdaterThread updater = null; private UpdaterThread updater = null;
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
app_private = getFilesDir().toString();
Prefs.init(this); Prefs.init(this);
setContentView(R.layout.main); setContentView(R.layout.main);
log_view = (EditText)findViewById(R.id.log); log_view = (EditText)findViewById(R.id.log);
@ -74,6 +78,9 @@ public class SimpleSSHD extends Activity
case R.id.settings: case R.id.settings:
startActivity(new Intent(this, Settings.class)); startActivity(new Intent(this, Settings.class));
return true; return true;
case R.id.copypriv:
copy_app_private();
return true;
case R.id.resetkeys: case R.id.resetkeys:
reset_keys(); reset_keys();
return true; return true;
@ -237,6 +244,32 @@ public class SimpleSSHD extends Activity
return ret; return ret;
} }
private void copy_app_private() {
new AlertDialog.Builder(this)
.setCancelable(true)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di,
int which) { }
})
.setNegativeButton("Copy",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di,
int which) {
ClipboardManager cl = (ClipboardManager)
getSystemService(
Context.CLIPBOARD_SERVICE);
if (cl != null) {
cl.setText(app_private);
}
}
})
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle("App-private path")
.setMessage(app_private)
.show();
}
private void do_reset_keys() { private void do_reset_keys() {
new File(Prefs.get_path(), "authorized_keys").delete(); new File(Prefs.get_path(), "authorized_keys").delete();
} }

Loading…
Cancel
Save