sshsshdminaaccess-rights

Apache Mina: Get the user's username upon receiving a command


Using Apache Mina, I'm trying to allow certain users to run certain custom SSH commands. But I can't figure out how to get the username or any sort of information about the user in a CommandFactory.

Right now, my server configuration looks like this:

SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPasswordAuthenticator(new SshPasswordAuthenticator());
sshd.setPort(localServerPort);
sshd.setCommandFactory(new ScpCommandFactory());
sshd.setShellFactory(new SshShellFactory());
sshd.setSessionFactory(new SshSessionFactory());
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File("my.pem").getAbsolutePath()));
sshd.setFileSystemFactory(new VirtualFileSystemFactory(path.getAbsolutePath()));
List<NamedFactory<Command>> namedFactoryList = new ArrayList<>();
namedFactoryList.add(new SftpSubsystem.Factory());
sshd.setSubsystemFactories(namedFactoryList);

And this is what my SshShellFactory class looks like:

import org.apache.sshd.common.Factory;
import org.apache.sshd.server.session.SessionFactory;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.CommandFactory;


public class SshShellFactory implements CommandFactory, Factory<Command> {

    @Override
    public Command createCommand(String command) {
        return new SshSessionCommandWriter();
    }

    @Override
    public Command create() {
        return createCommand("none");
    }
}

Where ServerVariables stores variables related to my software, SshSessionCommandWriter does I/O operations on the streams and SshCommandManager interprets commands read in SshSessionCommandWriter and returns a value to the client.

If I could find a way to somehow get the username of the user running the command, It would be perfect for my use case. I currently have this information in SshSessionFactory and SshPasswordAuthenticator, but not in SshShellFactory.


Solution

  • So the SshSessionCommandWriter object that I created must implement the Command interface. This command interface has the method public void start(Environment env) in its contracts. It turns out the username is stored inside the environment variables:

    public class SshSessionCommandWriter implements Command, Runnable {
    
        @Override
        public void start(Environment env) throws IOException {
            String username = env.getEnv().get(Environment.ENV_USER);
        }
    }