From 77d06cfe7724de81a5bbb947509ed8ccf3b2915e Mon Sep 17 00:00:00 2001 From: Samoilenko Yuri Date: Tue, 7 Jan 2014 17:40:21 +0400 Subject: [PATCH] sftp implementations splits from sftpplugin --- kdeconnect-android.iml | 9 + .../Plugins/SftpPlugin/SftpImpl.java | 183 +++++++++++++++ .../Plugins/SftpPlugin/SftpPlugin.java | 218 ++---------------- 3 files changed, 205 insertions(+), 205 deletions(-) create mode 100644 src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpImpl.java diff --git a/kdeconnect-android.iml b/kdeconnect-android.iml index 2acb8db6..0d760a05 100644 --- a/kdeconnect-android.iml +++ b/kdeconnect-android.iml @@ -73,12 +73,21 @@ +<<<<<<< HEAD +======= + + + + + + +>>>>>>> sftp implementations splits from sftpplugin diff --git a/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpImpl.java b/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpImpl.java new file mode 100644 index 00000000..74142a37 --- /dev/null +++ b/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpImpl.java @@ -0,0 +1,183 @@ +package org.kde.kdeconnect.Plugins.SftpPlugin; + +import android.util.Log; + +import org.apache.sshd.SshServer; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.server.Command; +import org.apache.sshd.server.PasswordAuthenticator; +import org.apache.sshd.server.command.ScpCommandFactory; +import org.apache.sshd.server.filesystem.NativeFileSystemFactory; +import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; +import org.apache.sshd.server.session.ServerSession; +import org.apache.sshd.server.sftp.SftpSubsystem; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Arrays; +import java.util.Enumeration; + +class SimplePasswordAuthenticator implements PasswordAuthenticator { + + public void setUser(String user) {this.user = user;} + public String getUser() {return this.user;} + + public void setPassword(String password) {this.password = password;} + public String getPassword() {return this.password;} + + @Override + public boolean authenticate(String user, String password, ServerSession session) { + return user.equals(this.user) && password.equals(this.password); + } + + private String user; + private String password; +} + +class SimpleSftpServer { + private static final int STARTPORT = 1739; + private static final int ENDPORT = 1764; + + private static final String USER = "kdeconnect"; + + public static int port = -1; + private static boolean started = false; + + public final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator(); + private final SshServer sshd = SshServer.setUpDefaultServer(); + + + public void init() { + passwordAuth.setUser(USER); + sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser")); + + sshd.setFileSystemFactory(new NativeFileSystemFactory()); + //sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i", "-l" })); + sshd.setCommandFactory(new ScpCommandFactory()); + sshd.setSubsystemFactories(Arrays.>asList(new SftpSubsystem.Factory())); + + sshd.setPasswordAuthenticator(passwordAuth); + } + + public boolean start() { + if (!started) { + String password = Long.toHexString(Double.doubleToLongBits(Math.random())); + passwordAuth.setPassword(password); + + port = STARTPORT; + while(!started) { + try { + sshd.setPort(port); + sshd.start(); + started = true; + } catch(Exception e) { + port++; + if (port >= ENDPORT) { + port = -1; + Log.e("SftpServer", "No more ports available"); + return false; + } + } + } + } + + return true; + } + + public void stop() { + try { + started = false; + sshd.stop(); + } catch (InterruptedException e) { + + } + } + + public String getLocalIpAddress() { + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress()) { + return inetAddress.getHostAddress().toString(); + } + } + } + } catch (SocketException ex) { + } + return null; + } + +} + +// ======================================= +// Comented to be example of customization od SSHD +// ======================================= + +// static class SecureFileSystemFactory implements FileSystemFactory { +// // +// public SecureFileSystemFactory() { +// } +// // +// @Override +// public FileSystemView createFileSystemView(final Session username) { +// final String userName = username.getUsername(); +// final String home = "/mnt/sdcard/"; +// return new SecureFileSystemView(home, userName, false); +// } +// } + +// static class SecureFileSystemView extends NativeFileSystemView { +// // the first and the last character will always be '/' +// // It is always with respect to the root directory. +// private String currDir = "/"; +// private String rootDir = "/"; +// private String userName; +// private boolean isReadOnly = true; +// private boolean caseInsensitive = false; +// // +// public SecureFileSystemView(final String rootDir, final String userName, final boolean isReadOnly) { +// super(userName); +// this.rootDir = NativeSshFile.normalizeSeparateChar(rootDir); +// this.userName = userName; +// this.isReadOnly = isReadOnly; +// } +// // +// @Override +// public SshFile getFile(final String file) { +// return getFile(currDir, file); +// } +// +// @Override +// public SshFile getFile(final SshFile baseDir, final String file) { +// return getFile(baseDir.getAbsolutePath(), file); +// } +// +// // +// protected SshFile getFile(final String dir, final String file) { +// // get actual file object +// String physicalName = NativeSshFile.getPhysicalName("/", dir, file, caseInsensitive); +// File fileObj = new File(rootDir, physicalName); // chroot +// +// // strip the root directory and return +// String userFileName = physicalName.substring("/".length() - 1); +// return new SecureSshFile(userFileName, fileObj, userName, isReadOnly); +// } +// } +// +// static class SecureSshFile extends NativeSshFile { +// final boolean isReadOnly; +// // +// public SecureSshFile(final String fileName, final File file, final String userName, final boolean isReadOnly) { +// super(fileName, file, userName); +// this.isReadOnly = isReadOnly; +// } +// // +// public boolean isWritable() { +// if (isReadOnly) +// return false; +// return super.isWritable(); +// } +// } \ No newline at end of file diff --git a/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java b/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java index 0e34cd4d..630bfa8d 100644 --- a/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java +++ b/src/main/java/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java @@ -2,69 +2,25 @@ package org.kde.kdeconnect.Plugins.SftpPlugin; import android.app.Activity; import android.app.AlertDialog; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Environment; import android.widget.Button; -import org.apache.sshd.SshServer; -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.server.Command; -import org.apache.sshd.server.PasswordAuthenticator; -import org.apache.sshd.server.command.ScpCommandFactory; -import org.apache.sshd.server.filesystem.NativeFileSystemFactory; -import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; -import org.apache.sshd.server.session.ServerSession; -import org.apache.sshd.server.sftp.SftpSubsystem; import org.kde.kdeconnect.NetworkPackage; import org.kde.kdeconnect.Plugins.Plugin; import org.kde.kdeconnect_tp.R; -import java.io.IOException; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Arrays; -import java.util.Enumeration; - public class SftpPlugin extends Plugin { - private static final int PORT = 8022; - private static final String USER = "kdeconnect"; - private static final String PASSWORD = "kdeconnectpassword"; - - private final SshServer sshd = SshServer.setUpDefaultServer(); - private boolean started = false; - - public class SimplePasswordAuthenticator implements PasswordAuthenticator { - - public void setUser(String user) {this.user = user;} - - public void setPassword(String password) {this.password = password;} - - @Override - public boolean authenticate(String user, String password, ServerSession session) { - return user.equals(this.user) && password.equals(this.password); - } - - private String user; - private String password; - } - - - private final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator(); - //private final SimplePublicKeyAuthenticator publicKeyAuth = new SimplePublicKeyAuthenticator(); + private static final SimpleSftpServer server = new SimpleSftpServer(); /*static { PluginFactory.registerPlugin(BatteryPlugin.class); }*/ @Override - public String getPluginName() { - return "plugin_sftp"; - } + public String getPluginName() {return "plugin_sftp";} @Override public String getDisplayName() { @@ -82,85 +38,17 @@ public class SftpPlugin extends Plugin { } @Override - public boolean isEnabledByDefault() { - return true; - } - - private BroadcastReceiver receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent batteryIntent) { -// -// Intent batteryChargeIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); -// int level = batteryChargeIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); -// int scale = batteryChargeIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1); -// int currentCharge = level*100 / scale; -// boolean isCharging = (0 != batteryChargeIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0)); -// boolean lowBattery = Intent.ACTION_BATTERY_LOW.equals(batteryIntent.getAction()); -// int thresholdEvent = lowBattery? THRESHOLD_EVENT_BATTERY_LOW : THRESHOLD_EVENT_NONE; -// -// if (lastInfo != null -// && isCharging != lastInfo.getBoolean("isCharging") -// && currentCharge != lastInfo.getInt("currentCharge") -// && thresholdEvent != lastInfo.getInt("thresholdEvent") -// ) { -// -// //Do not send again if nothing has changed -// return; -// -// } else { -// -// NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_BATTERY); -// np.set("currentCharge", currentCharge); -// np.set("isCharging", isCharging); -// np.set("thresholdEvent", thresholdEvent); -// device.sendPackage(np); -// lastInfo = np; -// -// } - - } - }; + public boolean isEnabledByDefault() {return true;} @Override public boolean onCreate() { - passwordAuth.setUser(USER); - passwordAuth.setPassword(PASSWORD); - sshd.setPort(PORT); - sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser")); - - sshd.setFileSystemFactory(new NativeFileSystemFactory()); - //sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i", "-l" })); - sshd.setCommandFactory(new ScpCommandFactory()); - sshd.setSubsystemFactories(Arrays.>asList(new SftpSubsystem.Factory())); - - sshd.setPasswordAuthenticator(passwordAuth); + server.init(); return true; } @Override public void onDestroy() { - try { - started = false; - sshd.stop(); - } catch (InterruptedException e) { - - } - } - - public String getLocalIpAddress() { - try { - for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { - NetworkInterface intf = en.nextElement(); - for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress()) { - return inetAddress.getHostAddress().toString(); - } - } - } - } catch (SocketException ex) { - } - return null; + server.stop(); } @Override @@ -168,104 +56,24 @@ public class SftpPlugin extends Plugin { if (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_SFTP)) return false; // if (np.getBoolean("startBrowsing")) { - try { - if (!started) { - sshd.start(); - started = true; - } - + if (server.start()) { NetworkPackage np2 = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SFTP); - np2.set("ip", getLocalIpAddress()); - np2.set("port", PORT); - np2.set("user", USER); - np2.set("password", PASSWORD); - np2.set("home", Environment.getExternalStorageDirectory().getAbsolutePath()); + np2.set("ip", server.getLocalIpAddress()); + np2.set("port", server.port); + np2.set("user", server.passwordAuth.getUser()); + np2.set("password", server.passwordAuth.getPassword()); + np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath()); device.sendPackage(np2); return true; - } catch (IOException e) { - e.printStackTrace(); } } return false; } @Override - public AlertDialog getErrorDialog(Context baseContext) { - return null; - } + public AlertDialog getErrorDialog(Context baseContext) {return null;} @Override - public Button getInterfaceButton(Activity activity) { - return null; - } + public Button getInterfaceButton(Activity activity) {return null;} - // ======================================= - // Comented to be example of customization od SSHD - // ======================================= - -// static class SecureFileSystemFactory implements FileSystemFactory { -// // -// public SecureFileSystemFactory() { -// } -// // -// @Override -// public FileSystemView createFileSystemView(final Session username) { -// final String userName = username.getUsername(); -// final String home = "/mnt/sdcard/"; -// return new SecureFileSystemView(home, userName, false); -// } -// } - -// static class SecureFileSystemView extends NativeFileSystemView { -// // the first and the last character will always be '/' -// // It is always with respect to the root directory. -// private String currDir = "/"; -// private String rootDir = "/"; -// private String userName; -// private boolean isReadOnly = true; -// private boolean caseInsensitive = false; -// // -// public SecureFileSystemView(final String rootDir, final String userName, final boolean isReadOnly) { -// super(userName); -// this.rootDir = NativeSshFile.normalizeSeparateChar(rootDir); -// this.userName = userName; -// this.isReadOnly = isReadOnly; -// } -// // -// @Override -// public SshFile getFile(final String file) { -// return getFile(currDir, file); -// } -// -// @Override -// public SshFile getFile(final SshFile baseDir, final String file) { -// return getFile(baseDir.getAbsolutePath(), file); -// } -// -// // -// protected SshFile getFile(final String dir, final String file) { -// // get actual file object -// String physicalName = NativeSshFile.getPhysicalName("/", dir, file, caseInsensitive); -// File fileObj = new File(rootDir, physicalName); // chroot -// -// // strip the root directory and return -// String userFileName = physicalName.substring("/".length() - 1); -// return new SecureSshFile(userFileName, fileObj, userName, isReadOnly); -// } -// } -// -// static class SecureSshFile extends NativeSshFile { -// final boolean isReadOnly; -// // -// public SecureSshFile(final String fileName, final File file, final String userName, final boolean isReadOnly) { -// super(fileName, file, userName); -// this.isReadOnly = isReadOnly; -// } -// // -// public boolean isWritable() { -// if (isReadOnly) -// return false; -// return super.isWritable(); -// } -// } }