4

使用Apache Mina SSHD我已经在我正在开发的 Android 应用程序中实现了一个 SSH 和 SFTP 服务器,我可以通过 SSH 登录,ls 根目录,cd 到“mnt/sdcard”和 ls - 所有这些工作正常。我也可以得到 su 并做任何我想做的事情。

但是,当我通过 SFTP 连接时,我无法列出大多数目录的内容(包括“/”、“/mnt/sdcard”)。但是,我可以列出“/mnt/sdcard/Download”的内容 - 以及从该目录下载和上传。

似乎某些文件正在停止其轨道中的目录列表 - 例如,在“/mnt/sdcard”中,“TWRP”似乎是问题的原因。这是我在 WinSCP 中得到的:

一般故障(服务器应提供错误描述)。

错误代码:4 来自服务器的错误消息:/mnt/sdcard/TWRP

这是我从 FileZilla 得到的(描述性要少得多):

命令:cd "/mnt/sdcard" 响应:新目录是:"/mnt/sdcard"

命令:ls 状态:列表目录/mnt/sdcard

错误:读取目录。:失败状态:目录列表成功

当试图在 WinSCP 中列出 '/' 中的目录时:

一般故障(服务器应提供错误描述)。

错误代码:4 来自服务器的错误消息:/charger

我已经实现了一个自定义 FileSystemFactory,以便默认传入 SFTP 连接到“/mnt/sdcard/Download”,但我希望能够 SFTP 到任何目录(如果需要,我不介意使用 su)

以下是设置 Android SSH/SFTP 服务器和设置自定义 FileSystemFactory 的相关代码:

//Initialize the server:
final Logger log = LoggerFactory.getLogger(server_service.class);
final SshServer sshd = SshServer.setUpDefaultServer();
final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator();
final SimplePublicKeyAuthenticator publicKeyAuth = new SimplePublicKeyAuthenticator();

passwordAuth.setUser(username_string);
passwordAuth.setPassword(password_string);
sshd.setPort(port);
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(server_info.getAppContext().getFilesDir().getPath() + "/key.ser"));
sshd.setShellFactory(new PseudoTerminalFactory("/system/bin/sh", "-i"));
sshd.setPasswordAuthenticator(passwordAuth);
sshd.setPublickeyAuthenticator(publicKeyAuth);
sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
sshd.setFileSystemFactory(getModifiedNativeFileSystemFactory());

try {
    sshd.start();
    Log.i("SUCCESS: Server listening on port",Integer.toString(port));
    server_info.sshd = sshd;
    server_info.log = log;
} catch (Exception ex) {
    Log.e("FAILURE: Server start failed", ex.toString());
    ex.printStackTrace();
}


}

//Custom FileSystemFactory to change initial root directory on SFTP connection
NativeFileSystemFactory getModifiedNativeFileSystemFactory() {
    return new NativeFileSystemFactory() {

    @Override
    public FileSystemView createFileSystemView(Session session) {
        String userName = getUsername(session);
        NativeFileSystemView nfsv = new ModifiedNativeFileSystemView(
                userName, isCaseInsensitive());
        Log.d("Creating a modified NativeFileSystemView for user", nfsv.getUserName());
        return nfsv;
    }

};
}
//Hook for testing without valid session
String getUsername(Session session) {
    return session.getUsername();
}
//Class to return the altered FileSystemView with changed initial directory
class ModifiedNativeFileSystemView extends NativeFileSystemView {
    String modifiedRootDir;

public ModifiedNativeFileSystemView(String userName,boolean caseInsensitive) {
    super(userName, caseInsensitive);
    modifiedRootDir = System.getProperty("user.dir") + File.separator + TARGET_DIR_NAME;
    Log.d("Modified NativeFileSystemView created with root directory", modifiedRootDir);
}

@Override
public SshFile getFile(String file) {
    return getFile(modifiedRootDir, file);
}
}

编辑:使用“su restorecon -FR /data/media/0”修复 SD 卡访问。 事实证明,在我升级到 Lollipop 后,TWRP 文件夹的权限不好(即使使用“su ls -l”它也不会返回权限,只是说访问被拒绝)。修复这些权限后,我就可以使用 SFTP 列出 sdcard 目录了。
但是,我仍然无法使用 SFTP 列出根目录('/'),但是在 SSH 中使用“su ls -l”执行此操作没有问题(没有 su 将无法工作)。我不认为这是同一个问题 - 我认为这只是我的 SFTP 访问权限不是 su。
谁能告诉我如何让 SFTP 以 su 身份运行?

4

0 回答 0