3

I'm running OpenJDK 14 on macOS 10.15.7. I'm doing some proof-of-concept code establishing an SSH server with Apache Mina SSHD and then connecting to it. Here's what I have:

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;

import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.server.ServerBuilder;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.AsyncAuthException;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.password.PasswordChangeRequiredException;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.shell.InteractiveProcessShellFactory;
import org.apache.sshd.server.shell.ProcessShellFactory;

public class FunctionalTest
{
    private static class TestAuthenticator
        extends AbstractLoggingBean
        implements PasswordAuthenticator
    {
        @Override
        public boolean authenticate(String username, String password, ServerSession session)
            throws PasswordChangeRequiredException, AsyncAuthException
        {
            if ("test".equals(username) && "foobar".equals(password))
            {
                this.log.info("authenticate({}[{}]: accepted", username, session);
                return true;
            }

            this.log.warn("authenticate({}[{}]: rejected", username, session);
            return false;
        }
    }

    public static void main(String... args) throws IOException
    {
        SshServer sshd = SshServer.setUpDefaultServer();
        sshd.setHost("0.0.0.0");
        sshd.setPort(1022);
        sshd.setShellFactory(InteractiveProcessShellFactory.INSTANCE);
        sshd.setPasswordAuthenticator(new TestAuthenticator());
        sshd.setCipherFactories(Arrays.asList(BuiltinCiphers.aes256ctr, BuiltinCiphers.aes192ctr));
        sshd.setKeyExchangeFactories(ServerBuilder.setUpDefaultKeyExchanges(false));
        sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Paths.get("key.ser")));
        sshd.start();

        try
        {
            Thread.sleep(3_600_000);
        }
        catch(InterruptedException e)
        {
            System.out.println("Caught interrupt ... stopping server.");
            sshd.stop(true);
        }
    }
}

When I start this, I can ssh -p 1022 test@localhost with the password foobar and it works. After successful authentication, I first see this:

sh: no job control in this shell

Then at the prompt, characters I type (including newlines) are echoed twice instead of once, resulting in everything being dduupplliiccaatteedd:

williamsn:mina-test williamsn$ llss  --aall

total 24
... (list of files)
williamsn:mina-test williamsn$ eecchhoo  hheelllloo
hello

williamsn:mina-test williamsn$

Additionally, if I run an interactive command like top, it doesn't recognize my inputs, and control characters don't work. ttoopp starts (though its output is ugly and additive instead of replacing the screen), but if I type q to exit (q is not echoed twice in this case), top does not exit in response to the q. It just keeps going. ctrl+c also does not work—top just keeps going. The only way to exit top is to kill my ssh process or shut down the MINA server.

I feel like I must be doing something terribly wrong here. Thoughts?

Nick Williams
  • 2,864
  • 5
  • 29
  • 43

1 Answers1

0

The "no job control" message indicates that the spawned shell Is not in a full interactive mode, and the double letters show that you have a mismatch between local and remote character echo. I can only assume that the default shell on mac-os (/usr/bin/sh ) is not a bash implementation like it is on Linux. Try changing the shell factory to new ProcessShellFactory("/usr/bin/bash","-i")

Sorry I don't have a mac to try this out.

Paul

Paul
  • 1
  • Thanks, Paul! I actually tried Bash first, before trying `sh`, with the exact same behavior, but just different wording: I used `sshd.setShellFactory(new ProcessShellFactory("bash", "/usr/local/bin/bash", "-i"));` (note that the `ProcessShellFactory` documentation is out of date and that new, first argument is required now), and output like in the following comment: – Nick Williams Dec 13 '20 at 19:21
  • Password authentication [\n] Password: [\n] bash: cannot set terminal process group (67423): Inappropriate ioctl for device [\n] bash: no job control in this shell [\n] bash-5.0$ – Nick Williams Dec 13 '20 at 19:21
  • having exactly same issue. any update? @Nick. tried also on centos, same. – Lance Mao Jul 25 '21 at 07:04
  • Unfortunately, no luck. And nobody ever replies on the mailing list, so I gave up. – Nick Williams Aug 10 '21 at 14:03