mirror of
git://f0xx.org/android_cast
synced 2026-07-29 08:37:37 +03:00
bastion RSSH + other changes
This commit is contained in:
@@ -139,5 +139,9 @@ dependencies {
|
||||
|
||||
implementation 'com.github.mwiede:jsch:0.2.21'
|
||||
|
||||
implementation 'org.apache.sshd:sshd-core:2.14.0'
|
||||
implementation 'org.apache.sshd:sshd-scp:2.14.0'
|
||||
implementation 'org.slf4j:slf4j-android:1.7.36'
|
||||
|
||||
implementation project(':tunnel')
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<li><b>Google Play In-App Review</b> — Google Play SDK terms</li>
|
||||
<li><b>Eclipse Paho MQTT client</b> — Eclipse Public License 1.0 and Eclipse Distribution License 1.0 (dual-licensed)</li>
|
||||
<li><b>JSch (mwiede fork)</b> — BSD 3-Clause License (reverse SSH remote access)</li>
|
||||
<li><b>Apache MINA SSHD</b> — Apache License 2.0 (embedded local SSH on device for RSSH alpha)</li>
|
||||
</ul>
|
||||
|
||||
<h2>JUnit 4</h2>
|
||||
|
||||
@@ -42,6 +42,10 @@ public final class ReverseSshTunnelBridge {
|
||||
Log.w(TAG, "incomplete RSSH credentials");
|
||||
return false;
|
||||
}
|
||||
if (!RsshLocalSshServer.start(user, pass, localPort)) {
|
||||
Log.w(TAG, "local SSH on :" + localPort + " failed");
|
||||
return false;
|
||||
}
|
||||
CountDownLatch connectedLatch = new CountDownLatch(1);
|
||||
AtomicBoolean ok = new AtomicBoolean(false);
|
||||
worker = new Thread(() -> {
|
||||
@@ -54,7 +58,7 @@ public final class ReverseSshTunnelBridge {
|
||||
s.setConfig(cfg);
|
||||
s.setServerAliveInterval(30_000);
|
||||
s.connect(CONNECT_TIMEOUT_MS);
|
||||
s.setPortForwardingR(remotePort, localHost, localPort);
|
||||
s.setPortForwardingR("127.0.0.1", remotePort, localHost, localPort);
|
||||
session = s;
|
||||
connected.set(true);
|
||||
ok.set(true);
|
||||
@@ -98,6 +102,7 @@ public final class ReverseSshTunnelBridge {
|
||||
Session s = session;
|
||||
session = null;
|
||||
connected.set(false);
|
||||
RsshLocalSshServer.stop();
|
||||
if (s != null) {
|
||||
try {
|
||||
s.disconnect();
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.foxx.androidcast.remoteaccess;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.sshd.server.SshServer;
|
||||
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
|
||||
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
|
||||
import org.apache.sshd.server.shell.ProcessShellFactory;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Embedded SSH on {@code 127.0.0.1:8022} for RSSH reverse forward target.
|
||||
* Operator reaches this via bastion forwarded port (same username/password).
|
||||
*/
|
||||
public final class RsshLocalSshServer {
|
||||
private static final String TAG = "RsshLocalSsh";
|
||||
|
||||
private static volatile SshServer server;
|
||||
private static volatile String activeUser = "";
|
||||
private static final AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
private RsshLocalSshServer() {}
|
||||
|
||||
public static boolean start(String username, String password, int port) {
|
||||
stop();
|
||||
if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (port <= 0 || port > 65535) {
|
||||
port = 8022;
|
||||
}
|
||||
final String user = username;
|
||||
final String pass = password;
|
||||
final int listenPort = port;
|
||||
try {
|
||||
Path hostKey = Files.createTempFile("rssh_host", ".key");
|
||||
hostKey.toFile().deleteOnExit();
|
||||
SshServer sshd = SshServer.setUpDefaultServer();
|
||||
sshd.setHost("127.0.0.1");
|
||||
sshd.setPort(listenPort);
|
||||
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(hostKey));
|
||||
sshd.setPasswordAuthenticator((PasswordAuthenticator) (u, p, session) ->
|
||||
user.equals(u) && pass.equals(p));
|
||||
sshd.setShellFactory(new ProcessShellFactory("/system/bin/sh", "-"));
|
||||
sshd.start();
|
||||
server = sshd;
|
||||
activeUser = user;
|
||||
running.set(true);
|
||||
Log.i(TAG, "local SSH listening 127.0.0.1:" + listenPort + " user=" + user);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "local SSH start failed: " + e.getMessage());
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
running.set(false);
|
||||
activeUser = "";
|
||||
SshServer local = server;
|
||||
server = null;
|
||||
if (local != null) {
|
||||
try {
|
||||
local.stop(true);
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "local SSH stop: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isRunning() {
|
||||
SshServer local = server;
|
||||
return running.get() && local != null && local.isStarted();
|
||||
}
|
||||
|
||||
public static String activeUsername() {
|
||||
return activeUser != null ? activeUser : "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user