Using Apache Mina SSHD I've implemented an SSH and SFTP server in an Android app I'm working on, and I can log in through SSH fine, ls the root directory, cd to 'mnt/sdcard' and ls - all of this is working fine. I can also get su and do whatever else I want.
However when I connect through SFTP I am unable to list the contents of most directories (including '/', '/mnt/sdcard'). I can, however, list the contents of '/mnt/sdcard/Download' - as well as download and upload to and from that directory.
It seems that certain files are halting the directory listing in it's tracks - for example, in '/mnt/sdcard' it seems that 'TWRP' is the cause of the problem. Here's what I get in WinSCP:
General failure (server should provide error description).
Error code: 4 Error message from server: /mnt/sdcard/TWRP
Here's what I get from FileZilla (much less descriptive):
Command: cd "/mnt/sdcard" Response: New directory is: "/mnt/sdcard"
Command: ls Status: Listing directory /mnt/sdcard
Error: Reading directory .: failure Status: Directory listing successful
When trying to list the directories in '/' in WinSCP:
General failure (server should provide error description).
Error code: 4 Error message from server: /charger
I've implemented a custom FileSystemFactory in order to default incoming SFTP connections to '/mnt/sdcard/Download', but I would like to be able to SFTP to any directory (I don't mind using su if needed)
Here's the relevant code to set up the Android SSH/SFTP server and set the custom 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);
}
}
EDIT: Fixed SD card access with "su restorecon -FR /data/media/0". It turns out that the TWRP folder had bad permissions after my upgrade to Lollipop (even with "su ls -l" it wouldn't return the permissions, just said access denied). After fixing those permissions, I am able to list the sdcard directories with SFTP just fine.
However, I'm still unable to list the root directories ('/') with SFTP, but there are no problems doing it with "su ls -l" while SSH'd in (it does not work without su). I don't believe it to be the same issue - I think it's just that my SFTP access is not su.
Can anyone tell me how would I make SFTP run as su?