Giter VIP home page Giter VIP logo

mina-sshd's Introduction

Apache MINA SSHD

Apache MINA SSHD

Apache MINA SSHD is a 100% pure java library to support the SSH protocols on both the client and server side. It does not aim at being a replacement for the SSH client or SSH server from Unix operating systems, but rather provides support for Java based applications requiring SSH support.

The library can leverage several I/O back-ends:

  • The default transport is built-in and uses Java's AsynchronousSocketChannels.
  • Apache MINA, a scalable and high performance asynchronous I/O library, can be used instead, or
  • the Netty asynchronous event-driven network framework is also supported.

Releases

Releases of Apache MINA sshd are available at Maven Central. tar.gz and ZIP source and binary distributions are available at the Apache MINA sshd web site.

Snapshot releases from the main branch are published on each push or merge on the main branch, if the tests pass successfully. These snapshot releases are available at the Apache Snapshot maven repository.

Issue reporting

Bug reports and improvement or feature requests can be filed at the GitHub issue tracker or at the Apache issue tracker.

Sensitive issues such as security vulnerabilities must be reported through private channels, not via either issue tracker.

Core requirements

  • Java 8+ (as of version 1.3)

  • Slf4j

The code only requires the core abstract slf4j-api module. The actual implementation of the logging API can be selected from the many existing adaptors.

Basic artifacts structure

  • sshd-common - contains basic classes used throughout the project as well as code that does not require client or server network support.

  • sshd-core - contains the basic SSH client/server code implementing the connection, transport, channels, forwarding, etc..

    • sshd-mina, sshd-netty - replacements for the default NIO2 connector used to establish and manage network connections using MINA and/or Netty libraries respectively.
  • sshd-sftp - contains the server side SFTP subsystem and the SFTP client code.

  • sshd-scp - contains the server side SCP command handler and the SCP client code.

  • sshd-ldap - contains server-side password and public key authenticators that use an LDAP server.

  • sshd-git - contains replacements for JGit SSH session factory.

  • sshd-osgi - contains an artifact that combines sshd-common and sshd-core so it can be deployed in OSGi environments.

  • sshd-putty - contains code that can parse PUTTY key files.

  • sshd-openpgp - contains code that can parse OpenPGP key files (with some limitations - see relevant section)

  • sshd-cli - contains simple templates for command-line client/server - used to provide look-and-feel similar to the Linux ssh/sshd commands.

  • sshd-contrib - experimental code that is currently under review and may find its way into one of the other artifacts (or become an entirely new artifact - e.g., sshd-putty evolved this way).

Quick reference

Building the code

Including tests

mvn clean install

Without tests

mvn -Pquick clean install

SSH functionality breakdown

Technical Documentation

mina-sshd's People

Contributors

alankila avatar alex-sherwin avatar alex-vol-amz avatar alonbl avatar awfulstew avatar bergander avatar cleiner avatar cschneider avatar cscjtndk avatar davido avatar denton-l avatar dependabot[bot] avatar elecharny avatar fliegenklatsch avatar garydgregory avatar gnodet avatar hanneswell avatar hboutemy avatar janstey avatar jonnyzzz avatar jvz avatar mheemskerk avatar norrisjeremy avatar robertodeandrea avatar rovarga avatar stephenc avatar terranibble avatar the-yoda avatar thefourtheye avatar tomaswolf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mina-sshd's Issues

DefaultSftpClient can wait indefinitely in method send and init

Version

2.8.0

Bug description

Using the DefaultSftpClient for transferring some files, i came accross an issue where the sftp client stop responding and do not close for several days.
Using a threadDump, i can see that the DefaultSftpClient is waiting indefinitely on the method send.
Got a similar issue several days after but this time in method init.

The server side is a very slow SFTP, and the connection is not stable but nevertheless, it should not block a thread forever.

Actual behavior

infinite wait can occur in method send and init of DefaultSftpClient because of this code :

IoWriteFuture writeFuture = asyncIn.writeBuffer(buf); writeFuture.verify();

the 2 methods are using verify without specifying a maximum wait time.

Expected behavior

If the other side doesn't answer in a predefined time, exit and free the ressource.

Relevant log output

Unfortunately i don't have the threadDump anymore.

Other information

occurs in version 2.8.0 (but will also appear in 2.9.2)

How to add KeyExchangeFactories using sshd-core 2.8 version

Version

sshd-core 2.8 version

Bug description

We have security violation for the following algorithms.
diffie-hellman-group-exchange-sha1
diffie-hellman-group1-sha1
gss-gex-sha1-*
gss-group1-sha1-*
gss-group14-sha1-*
rsa1024-sha1

We want to programatically to add the specific alogorithm while starting the SSHServer. We tried many online samples like

sshd.setKeyExchangeFactories(Arrays.asList(BuiltinKeyExchange.***));

BuiltinKeyExchange there is no class of the same name

List kexFactories = I need all the above mentioned deprecated kexAlgo, can you please help with the code snippet.

Kindly take this on priority.

Actual behavior

Not able to set sshd.setKeyExchangeFactories(

Expected behavior

Share the sample code how to set the KEX algos/

Relevant log output

No response

Other information

No response

Cannot read ed25519 privatekey created using bouncy castle and eddsa-0.3.0.jar

Version

2.9.2

Bug description

We are trying to generate keypair using Ed25519 algorithm. We are using eddsa-0.3.0.jar.
We have added the security provider for the same.
Security.addProvider(new net.i2p.crypto.eddsa.EdDSASecurityProvider());

Code snippet for key generation
keypair = KeyUtils.generateKeyPair("ssh-ed25519", 256);

Private key data is in this format:
-----BEGIN PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,9014B6FD7912A84C144379D7E26FE20B

iub1Uwel6zjsazQ5JIZqmCel/1HpxLyI2jcvO8ET9TF5w8ESCVMmlgPc6PAXgjdn
7N1bsn1lS/FOI4wv9nY90g==
-----END PRIVATE KEY-----

We are facing issue during the parsing of the key.
rawData is a string which contains the private key data as shared above.

passwordProvider is initialized below:
FilePasswordProvider passwordProvider = new FilePasswordProvider() {
public String getPassword(SessionContext session, NamedResource file, int index) throws IOException {
return password;
}
};

Below is the code snippet for parsing of the key:

KeyPairResourceLoader bcLoader = SecurityUtils.getBouncycastleKeyPairResourceParser();
Collection kpList = bcLoader.loadKeyPairs(null, null, passwordProvider, rawData);
KeyPair p = GenericUtils.head(kpList);

But loadKeyPairs method is returning an empty list.

Actual behavior

loadKeyPairs is returning an empty list.

Expected behavior

loadKeyPairs should return the KeyPair list.
KeyPairResourceLoader is bouncy castle library class.

Relevant log output

No response

Other information

No response

direct-tcpip

Description

i start a sshd and type ssh(openssh) -L ... ,but i didn't receive "direct-tcpip" from client.

Motivation

I want to know how ssh(openssl) implement local port forward.

Alternatives considered

No response

Additional context

No response

Threads like sshd-SshClient[35a0cde2]-nio2-thread-1 lead to memory leak

Version

2.9.2 and hitstory version

Bug description

I have read #270 Issue, but it doesn't help me

In my project, I use SshClient and ClientChannel to create an ssh client connection. After connecting to the server, the connection thread will simply operate the pwd command, and then disconnect and terminate the thread through the close method. This process simulates the process of continuous users connecting to the server through the ssh client. I found that for each connection, mina-sshd will create 6 threads similar to "sshd-SshClient[35a0cde2]-nio2-thread-1". After calling the close method, these threads will not disappear and remain in the WAITING (parking) state.

Actual behavior

As the number of connections increases, thousands of "sshd-SshClient[35a0cde2]-nio2-thread-1" will eventually lead to memory leaks, making it impossible to create new connection threads and causing the process to crash. In my test, I allocated 1GB of memory to the process, and the exception "java.lang.OutOfMemoryError: unable to create new native thread" occurred after nearly 2000 connections

Expected behavior

Can such thread be terminated after closing the connection? Otherwise, if the client connects 2000 times, the memory will overflow and the program will crash. The reliability of such a program is too poor.

Relevant log output

Exception in thread "Thread-3979" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:717)
        at sun.nio.ch.AsynchronousChannelGroupImpl$2.run(AsynchronousChannelGroupImpl.java:123)
        at sun.nio.ch.AsynchronousChannelGroupImpl$2.run(AsynchronousChannelGroupImpl.java:118)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.nio.ch.AsynchronousChannelGroupImpl.startInternalThread(AsynchronousChannelGroupImpl.java:118)
        at sun.nio.ch.AsynchronousChannelGroupImpl.threadExit(AsynchronousChannelGroupImpl.java:164)
        at sun.nio.ch.EPollPort$EventHandlerTask.run(EPollPort.java:302)
        at java.lang.Thread.run(Thread.java:748)
Exception in thread "ConnThread1988" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:717)
        at sun.nio.ch.AsynchronousChannelGroupImpl$2.run(AsynchronousChannelGroupImpl.java:123)
        at sun.nio.ch.AsynchronousChannelGroupImpl$2.run(AsynchronousChannelGroupImpl.java:118)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.nio.ch.AsynchronousChannelGroupImpl.startInternalThread(AsynchronousChannelGroupImpl.java:118)
        at sun.nio.ch.AsynchronousChannelGroupImpl.startThreads(AsynchronousChannelGroupImpl.java:132)
        at sun.nio.ch.EPollPort.start(EPollPort.java:113)
        at sun.nio.ch.LinuxAsynchronousChannelProvider.openAsynchronousChannelGroup(LinuxAsynchronousChannelProvider.java:64)
        at java.nio.channels.AsynchronousChannelGroup.withThreadPool(AsynchronousChannelGroup.java:273)
        at org.apache.sshd.common.io.nio2.Nio2ServiceFactory.<init>(Nio2ServiceFactory.java:45)
        at org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory.create(Nio2ServiceFactoryFactory.java:50)
        at org.apache.sshd.common.io.DefaultIoServiceFactoryFactory.create(DefaultIoServiceFactoryFactory.java:53)
        at org.apache.sshd.common.helpers.AbstractFactoryManager.getIoServiceFactory(AbstractFactoryManager.java:113)
        at org.apache.sshd.client.SshClient.createConnector(SshClient.java:814)
        at org.apache.sshd.client.SshClient.start(SshClient.java:456)
        at com.wnt.connection.terminal.SshdConnTerminal.login(SshdConnTerminal.java:56)
        at com.wnt.connection.ConnTerminalFactory$ConnThread.run(ConnTerminalFactory.java:37)
Exception in thread "ConnThread1989" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:717)
        at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:950)
        at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1587)
        at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:334)
        at java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:573)
        at org.apache.sshd.common.helpers.AbstractFactoryManager.setupSessionTimeout(AbstractFactoryManager.java:480)
        at org.apache.sshd.client.SshClient.start(SshClient.java:454)
        at com.wnt.connection.terminal.SshdConnTerminal.login(SshdConnTerminal.java:56)
        at com.wnt.connection.ConnTerminalFactory$ConnThread.run(ConnTerminalFactory.java:37)

Other information

The following is my main source code:

ConnTerminalFactory.java Create 5000 ssh connections, 1 per second on average

import com.wnt.connection.model.ConnParams;
import com.wnt.connection.terminal.SshdConnTerminal;

public class ConnTerminalFactory {
    private final static int SSH_CONN = 2;
    private final static String SERVER_IP = "1.1.1.1";
    private final static int SERVER_PORT = 22;
    private final static String USERNAME = "root";
    private final static String PASSWD = "root";

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 5000; i++) {
            Thread.sleep(1000);
            ConnParams params = new ConnParams(SSH_CONN, SERVER_IP, SERVER_PORT, USERNAME, PASSWD);
            ConnThread connThread = new ConnThread(params);
            connThread.setName("ConnThread" + i);
            connThread.start();
        }
        System.out.println("Thread over--------------------------------");
        Thread.sleep(10000000);
    }

    private static class ConnThread extends Thread {
        private ConnParams params;

        public ConnThread(ConnParams params) {
            this.params = params;
        }

        @Override
        public void run() {
            try {
                SshdConnTerminal it = new SshdConnTerminal(params);
                it.login();
                it.execCmd("pwd");
                System.out.println(this.getName() + ",exec pwd result:" + it.readResponse());
                sleep(1000);
                it.logout();
                System.out.println(this.getName() + ",logout");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

SshdConnTerminal.java Terminal operations such as login, execute command, and logout

import com.wnt.connection.ConnTerminalUtil;
import com.wnt.connection.model.CmdResponse;
import com.wnt.connection.model.ConnParams;
import com.wnt.connection.model.TerminalStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sshd.client.ClientBuilder;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.channel.PtyChannelConfiguration;
import org.apache.sshd.common.kex.BuiltinDHFactories;
import org.apache.sshd.common.signature.BuiltinSignatures;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;

public class SshdConnTerminal implements IConnTerminal {
    private static final Logger LOGGER = LoggerFactory.getLogger(SshdConnTerminal.class);

    private final ConnParams params;
    private ClientSession session;
    private OutputStream out;
    private PrintStream pOut;
    InputStream in;
    ClientChannel channel;

    public SshdConnTerminal(ConnParams params) {
        this.params = params;
    }

    @Override
    public TerminalStream login() {
        TerminalStream ts = new TerminalStream();
        try {
            SshClient client = SshClient.setUpDefaultClient();
            // 解决server使用diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1算法,Client端默认算法不支持导致key exchange失败的问题
            client.setKeyExchangeFactories(NamedFactory.setUpTransformedFactories(
                    false,
                    BuiltinDHFactories.VALUES,
                    ClientBuilder.DH2KEX
            ));
            client.setSignatureFactories(new ArrayList<>(BuiltinSignatures.VALUES));
            client.start();
            session = client.connect(params.getUsername(), params.getAddress(), params.getPort()).verify(IConnTerminal.CONN_TIMEOUT).getSession();
            session.addPasswordIdentity(params.getPassword());
            session.auth().verify(IConnTerminal.CONN_TIMEOUT);
            // 设置终端类型为xterms,避免部分指令不识别终端类型
            PtyChannelConfiguration ptyConfig = new PtyChannelConfiguration();
            ptyConfig.setPtyType(params.getTerminalType());
            channel = session.createShellChannel(ptyConfig, null);
            channel = session.createShellChannel();
            channel.open().verify(IConnTerminal.CONN_TIMEOUT);
            out = channel.getInvertedIn();
            pOut = new PrintStream(out);
            in = channel.getInvertedOut();
            ts.fillContent(in, TerminalStream.CODE_SUCCESS, true, IConnTerminal.SUCCESS_LOGIN_MSG);
        } catch (Exception e) {
            LOGGER.error("error when ssh login.params:{}", params, e);
            ts.fillContent(null, processSshdException(e), false, "Login failed." + e.getMessage());
        }
        return ts;
    }

    private int processSshdException(Exception e) {
        if (!(e instanceof SshException)) {
            return TerminalStream.CODE_FAIL_OTHER;
        }
        String msg = e.getMessage();
        int disconnectCode = ((SshException) e).getDisconnectCode();
        if (StringUtils.containsIgnoreCase(msg, "信号灯超时时间已到") || StringUtils.containsIgnoreCase(msg, "Failed to get operation result within specified timeout")) {
            return TerminalStream.CODE_DST_UNREACHABLE;
        } else if (StringUtils.containsIgnoreCase(msg, "远程计算机拒绝网络连接") || StringUtils.containsIgnoreCase(msg, "The remote computer refused the network connection")) {
            return TerminalStream.CODE_CONN_REFUSED;
        } else if (disconnectCode == 14) {
            return TerminalStream.CODE_AUTH_FAIL;
        }
        return TerminalStream.CODE_FAIL_OTHER;
    }

    @Override
    public void rowWrite(byte[] buf) throws IOException {
        ConnTerminalUtil.rowWrite(buf, pOut);
    }

    @Override
    public String readResponse() throws IOException {
        return ConnTerminalUtil.readResponse(in);
    }

    @Override
    public void execCmd(String cmd) {
        ConnTerminalUtil.sendCommand(cmd, pOut);
    }

    @Override
    public CmdResponse execCmdWithResponse(String cmd) {
        return ConnTerminalUtil.sendCommandWithResponse(cmd, pOut, in);
    }

    @Override
    public void logout() {
        try {
            IOUtils.close(in);
            IOUtils.close(out);
            if (channel != null && channel.isOpen()) {
                channel.close(true);
            }
            if (session != null && session.isOpen()) {
                session.close(true);
            }
        } catch (Exception e) {
            LOGGER.error("error when ssh logout.params:{}", params, e);
        } finally {
            session = null;
            channel = null;
        }
    }
}

ConnTerminalUtil.java Tool class for reading and writing ssh input and output streams

import com.wnt.connection.model.CmdResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

public class ConnTerminalUtil {
    private static final Logger logger = LoggerFactory.getLogger(ConnTerminalUtil.class);

    public static final int READ_WAIT_COUNT = 5;
    public static final int READ_WAIT_DURATION_MS = 600;

    public static void sleep(int interval) {
        try {
            Thread.sleep(interval);
        } catch (Exception e) {
            logger.error("error when sleep.", e);
        }
    }

    public static String readResponse(InputStream in) throws IOException {
        int readable = 0;
        int last = 0;
        int waitCount = 0;
        while (waitCount < READ_WAIT_COUNT || readable == 0) {
            sleep(READ_WAIT_DURATION_MS);
            readable = in.available();
            if (readable == last) {
                waitCount++;
            } else {
                waitCount = 0;
                last = readable;
            }
            if (waitCount >= 20 || readable > 1024) {
                break;
            }
        }
        byte[] buf = new byte[readable];
        in.read(buf);

        return new String(buf, StandardCharsets.UTF_8);
    }

    public static CmdResponse sendCommandWithResponse(String command, PrintStream out, InputStream in) {
        CmdResponse response = new CmdResponse();
        try {
            sendCommand(command, out);
            response.setStdout(readResponse(in));
        } catch (Exception e) {
            response.setReturnCode(-1);
            response.setStdout("execCmd error, cmd:" + command);
            response.setStderr(e.getMessage());
        }
        return response;
    }

    public static void rowWrite(byte[] buf, OutputStream out) throws IOException {
        out.write(buf);
        out.flush();
    }

    public static void sendCommand(String command, PrintStream out) {
        out.println(command);
        out.flush();
    }
}

The variable sender of channelOpenConfirmation is possibly negative

Version

2.9.2

Bug description

The remote side then decides whether it can open the channel, and responds with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE.
byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
uint32 recipient channel
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
.... channel type specific data follows

the sender is uint32,but the variable sender of channelOpenConfirmation is int. if sender is more than 2147483647, the variable sender of channelOpenConfirmation will be negative and cause the IllegalArgumentException: Invalid UINT32.

Actual behavior

if the buffer related to sender is -128 1 0 1, the sender will be -2147418111 and it cause cause the IllegalArgumentException: Invalid UINT32.

Expected behavior

if sender is more than 2147483647,it Shouldn't cause the IllegalArgumentException: Invalid UINT32.

Relevant log output

IllegalArgumentException: Invalid UINT32 value: -2147418111 
java.lang.IllegalArgumentException: Invalid UINT32 value: -2147418111
	at org.apache.sshd.common.util.ValidateUtils.createFormattedException(ValidateUtils.java:213) ~[sshd-common-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.util.ValidateUtils.throwIllegalArgumentException(ValidateUtils.java:179) ~[sshd-common-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.util.ValidateUtils.checkTrue(ValidateUtils.java:162) ~[sshd-common-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.util.buffer.BufferUtils.validateUint32Value(BufferUtils.java:701) ~[sshd-common-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.util.buffer.Buffer.putUInt(Buffer.java:720) ~[sshd-common-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.createSendBuffer(ChannelAsyncOutputStream.java:393) ~[sshd-core-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.writePacket(ChannelAsyncOutputStream.java:338) ~[sshd-core-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.doWriteIfPossible(ChannelAsyncOutputStream.java:215) ~[sshd-core-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.writeBuffer(ChannelAsyncOutputStream.java:110) ~[sshd-core-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.forward.DefaultForwarder$StaticIoHandler.lambda$messageReceived$2(DefaultForwarder.java:1063) ~[sshd-core-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.util.threads.ThreadUtils.runAsInternal(ThreadUtils.java:68) ~[sshd-common-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.common.forward.DefaultForwarder$StaticIoHandler.messageReceived(DefaultForwarder.java:1063) ~[sshd-core-2.9.2-h0.gdd.pub.r1.jar:2.9.2-h0.gdd.pub.r1]
	at org.apache.sshd.mina.MinaService.messageReceived(MinaService.java:156) ~[sshd-mina-2.9.2.jar:2.9.2]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:1015) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:122) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:643) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1224) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1213) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64) ~[mina-core-2.1.6.jar:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_352]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_352]
	at java.lang.Thread.run(Thread.java:750) ~[?:1.8.0_352]

Other information

No response

What will cause the failure to open the channel

Hello, may I ask what will cause the failure to open the channel? Is this the exception caught in the log

org.apache.sshd.common.SshException: DefaultOpenFuture[ChannelExec[id=123, recipient=-1]-ClientSessionImpl[root@/10.155.109.229:22]]: Failed (SshChannelOpenException) to execute: open failed

waitFor practically non-functional

The only events I ever get out of it is OPENED and TIMEOUT (OPENED shows up even after I already wait for it once), but the ssh session seems to work fine.
My code:

ClientChannel shell = session.createShellChannel();

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
shell.setOut(outputStream);

shell.open();

shell.waitFor(EnumSet.of(ClientChannelEvent.OPENED), 0)); // Works fine

OutputStream os = shell.getInvertedIn();
os.write("ping -c 3 localhost\n".getBytes());
os.flush();

shell.waitFor(/* everything but OPENED */, 0); // never exits (until the whole ssh session timeouts and closes)

Same thing regardless if I use other threads, add a timeout, etc.

Client:Sent SSH_MSG_USERAUTH_REQUEST twice even PASSWORD_PROMPTS=1

Version

2.9.0

Bug description

Trying to find out if the reported in

https://issues.apache.org/jira/browse/SSHD-1159

has been fixed or not. Don't have ASF Jira account, so cannot update the information there.

For SSHD-1159, comment by Lyor Goldstein says

"Version 2.2.0 is quite old - please try 2.7.0"

I tried with version 2.9.0 and see the same behavior. SSH server is reporting two login attempts even though we run the following program only once. sshd daemon is configured with two auth methods, Publickey,keyboard-interactive

package sshclient;

import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.core.CoreModuleProperties;

public class ApacheSshDemo {

public static void main(String[] args) throws Exception {
    ApacheSshDemo demo = new ApacheSshDemo();
    System.err.print("starting apache sshd demo");
    demo.newSession("localhost", "_v_10.0.1.1_v_admin", "blahblahblah", 830, 30);
}

public void newSession(String host, String username,
String password, int port, long defaultTimeout) throws IOException {
SshClient client = SshClient.setUpDefaultClient();
PropertyResolverUtils.updateProperty(client, CoreModuleProperties.PASSWORD_PROMPTS.getName(), 1);
client.start();
client.setUserAuthFactories(Collections.singletonList(UserAuthKeyboardInteractiveFactory.INSTANCE));
try (ClientSession session = client.connect(username, host, port)
.verify(defaultTimeout, TimeUnit.SECONDS)
.getSession()) {
session.addPasswordIdentity(password);
session.auth()
.verify(defaultTimeout, TimeUnit.SECONDS);
System.err.println("ssh connection was successful");
} catch (Exception e) {
System.err.println("ssh exception is "+e);
} finally {
client.stop();
}
}
}

This is sshd dependency specified in pom.xml

org.apache.sshd sshd-core 2.9.0 Actual behavior

Utility on SSH server is indicating two login attempts.

vm12:/var/log# !fail
faillock --dir /var/log/faillock --user admin
admin:
When Type Source Valid
2022-12-08 13:54:25 RHOST 10.0.1.1 V
2022-12-08 13:54:29 RHOST 10.0.1.1 V

Expected behavior

vm12:/var/log# !fail
faillock --dir /var/log/faillock --user admin
admin:
When Type Source Valid
2022-12-08 13:54:25 RHOST 10.0.1.1 V

Relevant log output

No response

Other information

OpenSSH_8.2

Client startup sometimes take a long time

Version

2.9.2

Bug description

Sometimes the client starts quickly and sometimes slowly.

long startTime = System.currentTimeMillis();
client = SshClient.setUpDefaultClient();
client.start();
LOGGER.info(String.format("start client cost [%s] ms", System.currentTimeMillis() - startTime));

When it is slow, it takes about 90 seconds to start. What is the solution

Actual behavior

start client cost [9783] ms

Expected behavior

start client cost [200] ms

Relevant log output

No response

Other information

No response

Server side heartbeat not working

Version

master

Bug description

dependency:

<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>2.7.0</version>
</dependency>

Code:

SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(3333);
sshd.setShellFactory(InteractiveProcessShellFactory.INSTANCE);
sshd.setSessionHeartbeat(SessionHeartbeatController.HeartbeatType.IGNORE, Duration.ofSeconds(5));
sshd.setKeyPairProvider(new ClassLoadableResourceKeyPairProvider(getClass().getClassLoader(), "rsa.key"));
sshd.setPasswordAuthenticator((username, password, session) -> username.equals(password));
sshd.start();
log.info("SSHD server started");

ssh Client:

user/passwd = test

ssh [email protected] -p3333 

Actual behavior

read Server Setup Manual last section

I with my SSHD has ServerSide heartbeat,But setSessionHeartbeat API didn't working, ssh session didn't get any interval heartbeat

Expected behavior

SSHD automatic send heartbeat message for each ssh session

Relevant log output

No response

Other information

No response

SFTP fails and returns BufferException during file upload

Version

2.9.2

Bug description

On specific devices I got BufferException exception when I open new SFTP session in order to upload a local file to the remote device.

This is the code I use:

...
byte[] localfileBytes = new FileInputStream(localfilepath).readAllBytes();
try (SftpClient sftp = DefaultSftpClientFactory.INSTANCE.createSftpClient(session)) {
    try (SftpClient.CloseableHandle handle = sftp.open(remotefilepath,
                           EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
        sftp.write(handle, 0, localfileBytes, 0, localfileBytes.length);
    } catch (IOException e) {}
} catch (IOException e) {}
...

Actual behavior

The file is not uploaded to the remote device. I tried with both relative and absolute paths.

Expected behavior

The file must be uploaded to the remote device.

Relevant log output

org.apache.sshd.common.util.buffer.BufferException: Underflow: requested=4, available=0
        at deployment.test.ear//org.apache.sshd.common.util.buffer.Buffer.ensureAvailable(Buffer.java:635)
        at deployment.test.ear//org.apache.sshd.common.util.buffer.Buffer.getUInt(Buffer.java:281)
        at deployment.test.ear//org.apache.sshd.common.util.buffer.Buffer.getInt(Buffer.java:277)
        at deployment.test.ear//org.apache.sshd.common.util.buffer.ByteArrayBuffer.getString(ByteArrayBuffer.java:240)
        at deployment.test.ear//org.apache.sshd.common.util.buffer.Buffer.getString(Buffer.java:309)
        at deployment.test.ear//org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkHandleResponse(AbstractSftpClient.java:248)
        at deployment.test.ear//org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkHandle(AbstractSftpClient.java:232)
        at deployment.test.ear//org.apache.sshd.sftp.client.impl.AbstractSftpClient.open(AbstractSftpClient.java:573)
        at deployment.test.ear//com.test.UploadFile.upload(UploadFile.java:106)

Other information

The local device run OpenSSH 8.0p1.

connection pool improve performance

Description

How does sshd use the connection pool to reuse connections to improve performance

Motivation

How does sshd use the connection pool to reuse connections to improve performance

Alternatives considered

No response

Additional context

No response

Get sender from cmd SSH_MSG_CHANNEL_OPEN_CONFIRMATION wrong could result exception

Version

2.9.2

Bug description

While opening a channel, mina deals cmd of SSH_MSG_CHANNEL_OPEN_CONFIRMATION in org.apache.sshd.common.session.helpers.AbstractConnectionService#channelOpenConfirmation.

public void channelOpenConfirmation(Buffer buffer) throws IOException {
        Channel channel = getChannel(SshConstants.SSH_MSG_CHANNEL_OPEN_CONFIRMATION, buffer);
        if (channel == null) {
            return; // debug breakpoint
        }

        int sender = buffer.getInt();
        long rwsize = buffer.getUInt();
        long rmpsize = buffer.getUInt();
        if (log.isDebugEnabled()) {
            log.debug("channelOpenConfirmation({}) SSH_MSG_CHANNEL_OPEN_CONFIRMATION sender={}, window-size={}, packet-size={}",
                    channel, sender, rwsize, rmpsize);
        }
        /*
         * NOTE: the 'sender' of the SSH_MSG_CHANNEL_OPEN_CONFIRMATION is the recipient on the client side - see rfc4254
         * section 5.1:
         *
         * 'sender channel' is the channel number allocated by the other side
         *
         * in our case, the server
         */
        channel.handleOpenSuccess(sender, rwsize, rmpsize, buffer);
    }

mina defines sender as int( int sender = buffer.getInt(); ), while sender should be UINT32. Therefore , here could be a situation, when sender is bigger than 0x7fffffff, and turns to be a minus int, and then be set as channel's recipient.

When mina uses channel's recipient later, e.g. org.apache.sshd.common.channel.ChannelAsyncOutputStream#createSendBuffer

    protected Buffer createSendBuffer(Buffer buffer, Channel channel, int length) {
        SessionContext.validateSessionPayloadSize(length, "Invalid send buffer length: %d");

        Session s = channel.getSession();
        Buffer buf = s.createBuffer(cmd, length + 12);
        buf.putUInt(channel.getRecipient());
        if (cmd == SshConstants.SSH_MSG_CHANNEL_EXTENDED_DATA) {
            buf.putUInt(SshConstants.SSH_EXTENDED_DATA_STDERR);
        }
        buf.putUInt(length);
        buf.putRawBytes(buffer.array(), buffer.rpos(), length);
        buffer.rpos(buffer.rpos() + length);
        return buf;
    }

when put channel's recipient into buffer, putUInt(long i) checks input i, if i is a minus number, an IllegalArgumentException would be thrown, and the channel would be closed.

I searched git log, found out this problem is related to [SSHD-1244]. Lyor Goldstein changed lots of int variables into long to hold uint32 values, but unfortunately he missed some line. Line int sender = buffer.getInt(); in channelOpenConfirmation() is untouched while org.apache.sshd.common.session.helpers.AbstractConnectionService#channelOpen is correctly changed.

Not sure whether there were more left unmodified, since there were lots code change in [SSHD-1244]. We should review code to make sure.

Actual behavior

I use mina sshd as server. A client is connecting to server, send SSH_MSG_CHANNEL_OPEN_CONFIRMATION while sender is something like 0xFF010015, then exception is thrown , session is closed.

Expected behavior

It should connect like any other client.

Relevant log output

2022-12-19T15:32:57,781 | DEBUG | MinaProcessor-11               | ServerSessionImpl                |doHandleMessage() 551 | org.apache.sshd.common.session.helpers.AbstractSession |  |  |  | doHandleMessage(ServerSessionImpl[user@/120.126.12.100:29030]) process #8 SSH_MSG_CHANNEL_OPEN_CONFIRMATION 
2022-12-19T15:32:57,781 | DEBUG | MinaProcessor-11               | ServerConnectionService          |channelOpenConfirmation() 534 | org.apache.sshd.common.session.helpers.AbstractConnectionService |  |  |  | channelOpenConfirmation(TcpipClientChannel[id=0, recipient=-1]-ServerSessionImpl[user@/120.126.12.100:29030]) SSH_MSG_CHANNEL_OPEN_CONFIRMATION sender=-2147418110, window-size=131072, packet-size=32768 
2022-12-19T15:32:57,781 | DEBUG | MinaProcessor-11               | TcpipClientChannel               |setRecipient() 172 | org.apache.sshd.common.channel.AbstractChannel |  |  |  | setRecipient(TcpipClientChannel[id=0, recipient=-1]-ServerSessionImpl[user@/120.126.12.100:29030]) recipient=-2147418110 


java.lang.IllegalArgumentException: Invalid UINT32 value: -2147418097
	at org.apache.sshd.common.util.ValidateUtils.createFormattedException(ValidateUtils.java:213) ~[sshd-common-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.util.ValidateUtils.throwIllegalArgumentException(ValidateUtils.java:179) ~[sshd-common-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.util.ValidateUtils.checkTrue(ValidateUtils.java:162) ~[sshd-common-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.util.buffer.BufferUtils.validateUint32Value(BufferUtils.java:701) ~[sshd-common-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.util.buffer.Buffer.putUInt(Buffer.java:720) ~[sshd-common-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.createSendBuffer(ChannelAsyncOutputStream.java:393) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.writePacket(ChannelAsyncOutputStream.java:338) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.doWriteIfPossible(ChannelAsyncOutputStream.java:215) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.channel.ChannelAsyncOutputStream.writeBuffer(ChannelAsyncOutputStream.java:110) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.forward.DefaultForwarder$StaticIoHandler.lambda$messageReceived$2(DefaultForwarder.java:1063) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.util.threads.ThreadUtils.runAsInternal(ThreadUtils.java:68) ~[sshd-common-2.9.2.jar:2.9.2]
	at org.apache.sshd.common.forward.DefaultForwarder$StaticIoHandler.messageReceived(DefaultForwarder.java:1063) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.mina.MinaService.messageReceived(MinaService.java:156) ~[sshd-mina-2.9.2.jar:2.9.2]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:1015) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:49) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1128) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:122) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:650) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:643) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1224) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1213) ~[mina-core-2.1.6.jar:?]
	at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683) ~[mina-core-2.1.6.jar:?]

Other information

This bug is not existed in mina sshd 2.8.0.
In 2.8.0, everything is hold by int, and there are no value check when putting in buffer, so even if sender is minus, that doesn't matter.

Issue related to CVE-2022-45047

Version

2.7.0

Bug description

This is in regards to the security vulnerability,
https://nvd.nist.gov/vuln/detail/CVE-2022-45047

In our code implementation for apache sshd server of 2.7.0, we are using KeyPairProvider Interface, with below code snippet. So, I am reviewing whether we are really vulnerable to the above security issue.
To me it looks like, internally apache might still call SimpleGeneratorHostKeyProvider and hence vulnerability is there, and we need to upgrade to the latest version.

import org.apache.sshd.common.keyprovider.KeyPairProvider;
...
KeyPair hostKeyPair = readKeyPair(config.getHostIdentityKey());
if (hostKeyPair != null) {
KeyPairProvider serverKeys = getProvider(hostKeyPair);
sshdServer.setKeyPairProvider(serverKeys);
}

Thanks
Dev

Actual behavior

Question

Expected behavior

security issue

Relevant log output

No response

Other information

No response

Race condition causes ScpTest.testScpNativeOnMultipleFiles() to fail (flaky test)

The ultimate problem is a general one concerning ChannelExecs:

If

  • there is a communication protocol implemented between the client and the remote command via the stdin/stdout streams,
  • and if the protocol is such that the remote command can return an error code in this application protocol,
  • and the client uses the default inverted output stream to read that error code,
  • and the client then decides to close the channel (even gracefully),

then it is possible that the AbstractClientChannel's out stream is closed between lines 436 and 437, and then the flush()call on the ChannelPipedOutputStream may fail, causing the whole session to go down.

This can happen in the ScpTestat line 343, which tests an scp upload command that should fail. The scp server sends back an ERROR ack, which the client reads (on an I/O thread) and forwards in AbstractClientChannel. The client reads this though the ChannelPipedInputStream (on the main thread) and throws an exception, which then causes the channel to be closed at the end of DefaultScpClient.runUpload() (still on the main thread). Only then does the I/O thread call flush(), which then fails with an exception.

So in short we have

  1. I/O thread: receive data
  2. I/O thread: write data to ChannelPipedOutputStream
  3. Main thread: read data from ChannelPipedInputStream
  4. Main thread: close channel
  5. I/O thread: call ChannelPipedOutputStream.flush() and fail.

This is all the more infuriating since ChannelPipedOutputStream.flush() is essentially a no-op. Moreover: an exception when a channel has received data and tries to forward it should not take down the whole session but only this channel.

The code for restricting Windows host key file ACLs can result in empty permissions

Version

2.9.2

Bug description

For SSHD 2.9.2, new code was added to restrict the host key file's permissions to the current user. The relevant code for Windows compares existing ACLs to the new file's owner, and only keeps them if the check in

if (owner.equals(acl.principal()) || AclEntryType.DENY.equals(acl.type())) {
is true.

The expectation seems to be that the new file's UserPrincipal ("owner") always has a matching ALLOW ACL, so the owner would be the only one left with ALLOW permissions. However, we have encountered systems where this check is always false, resulting in a host key file that can not be written to, and only deleted with admin permissions.

We have written a small test program to compare the ACLs present on these systems; output will be attached below.

Actual behavior

The code results in a host key file that has no permissions when viewed in Windows Explorer's file properties, and can only be deleted with admin permissions.

Expected behavior

The code results in a host key file that is read/writable for the current user.

Relevant log output

Example of two FAILING Windows 10 systems' ACLs; user names are placeholders, and the boolean output is the result of owner.equals(acl.principal()):

---
Owner: DLR\user_a (User)
ACL:
  Principal:       VORDEFINIERT\Administratoren (Alias)
  Type:            ALLOW
  Permissions:     [EXECUTE, WRITE_ACL, READ_ATTRIBUTES, SYNCHRONIZE, WRITE_DATA, READ_ACL, WRITE_ATTRIBUTES, READ_NAMED_ATTRS, DELETE, WRITE_NAMED_ATTRS, DELETE_CHILD, APPEND_DATA, READ_DATA, WRITE_OWNER]
  Owner~Principal: false
ACL:
  Principal:       NT-AUTORITÄT\SYSTEM (Well-known group)
  Type:            ALLOW
  Permissions:     [EXECUTE, WRITE_ACL, READ_ATTRIBUTES, SYNCHRONIZE, WRITE_DATA, READ_ACL, WRITE_ATTRIBUTES, READ_NAMED_ATTRS, DELETE, WRITE_NAMED_ATTRS, DELETE_CHILD, APPEND_DATA, READ_DATA, WRITE_OWNER]
  Owner~Principal: false
ACL:
  Principal:       VORDEFINIERT\Benutzer (Alias)
  Type:            ALLOW
  Permissions:     [EXECUTE, READ_ATTRIBUTES, SYNCHRONIZE, READ_ACL, READ_NAMED_ATTRS, READ_DATA]
  Owner~Principal: false
ACL:
  Principal:       NT-AUTORITÄT\Authentifizierte Benutzer (Well-known group)
  Type:            ALLOW
  Permissions:     [WRITE_NAMED_ATTRS, EXECUTE, READ_ATTRIBUTES, SYNCHRONIZE, APPEND_DATA, WRITE_DATA, READ_ACL, WRITE_ATTRIBUTES, READ_NAMED_ATTRS, READ_DATA, DELETE]
  Owner~Principal: false
---

Example of a SUCCEEDING Windows 10 system:

---
Owner: DLR\user_b (User)
ACL:
  Principal:       NT-AUTORITÄT\SYSTEM (Well-known group)
  Type:            ALLOW
  Permissions:     [WRITE_NAMED_ATTRS, READ_DATA, SYNCHRONIZE, READ_ATTRIBUTES, WRITE_OWNER, DELETE_CHILD, APPEND_DATA, WRITE_ACL, WRITE_ATTRIBUTES, DELETE, WRITE_DATA, READ_NAMED_ATTRS, EXECUTE, READ_ACL]
  Owner~Principal: false
ACL:
  Principal:       VORDEFINIERT\Administratoren (Alias)
  Type:            ALLOW
  Permissions:     [WRITE_NAMED_ATTRS, READ_DATA, SYNCHRONIZE, READ_ATTRIBUTES, WRITE_OWNER, DELETE_CHILD, APPEND_DATA, WRITE_ACL, WRITE_ATTRIBUTES, DELETE, WRITE_DATA, READ_NAMED_ATTRS, EXECUTE, READ_ACL]
  Owner~Principal: false
ACL:
  Principal:       DLR\user_b (User)
  Type:            ALLOW
  Permissions:     [WRITE_NAMED_ATTRS, READ_DATA, SYNCHRONIZE, READ_ATTRIBUTES, WRITE_OWNER, DELETE_CHILD, APPEND_DATA, WRITE_ACL, WRITE_ATTRIBUTES, DELETE, WRITE_DATA, READ_NAMED_ATTRS, EXECUTE, READ_ACL]
  Owner~Principal: true

---

Example of a SUCCEEDING Windows Server system, running as administrator; here, the ownership was assigned to a group, which is also what passes the check, so the whole group would retain access; is this the indended result?

---

Owner: VORDEFINIERT\Administratoren (Alias)
ACL:
  Principal:       NT-AUTORITÄT\SYSTEM (Well-known group)
  Type:            ALLOW
  Permissions:     [DELETE_CHILD, WRITE_DATA, READ_ATTRIBUTES, EXECUTE, READ_ACL, READ_DATA, DELETE, WRITE_OWNER, WRITE_ATTRIBUTES, READ_NAMED_ATTRS, APPEND_DATA, SYNCHRONIZE, WRITE_NAMED_ATTRS, WRITE_ACL]
  Owner~Principal: false
ACL:
  Principal:       VORDEFINIERT\Administratoren (Alias)
  Type:            ALLOW
  Permissions:     [DELETE_CHILD, WRITE_DATA, READ_ATTRIBUTES, EXECUTE, READ_ACL, READ_DATA, DELETE, WRITE_OWNER, WRITE_ATTRIBUTES, READ_NAMED_ATTRS, APPEND_DATA, SYNCHRONIZE, WRITE_NAMED_ATTRS, WRITE_ACL]
  Owner~Principal: true
ACL:
  Principal:       WIN-redacted\Administrator (User)
  Type:            ALLOW
  Permissions:     [DELETE_CHILD, WRITE_DATA, READ_ATTRIBUTES, EXECUTE, READ_ACL, READ_DATA, DELETE, WRITE_OWNER, WRITE_ATTRIBUTES, READ_NAMED_ATTRS, APPEND_DATA, SYNCHRONIZE, WRITE_NAMED_ATTRS, WRITE_ACL]
  Owner~Principal: false

---

Other information

No response

Allow for the use of HTTP or SOCKS proxies

Description

I am using MINA SSHD as part of Spring Integration 6.0.1 since it replaced the JSch SSH implementation there.
However, I was using an HTTP proxy to connect with JSch and this seems to be no longer possible with MINA because it supports only SSH jump hosts as a proxy.

So my request would be to implement a more flexible approach to proxies and also allow for the use of HTTP and SOCKS proxies.,

Motivation

This feature is needed to make it possible to use MINA SSHD and the frameworks that depend on it in environments where the server being accessed can only be reached via an HTTP/SOCKS proxy.

Especially In scenarios where MINA SSHD is used for transferring data via SFTP this seems not to be a far-fetched scenario.

Alternatives considered

An alternative would be to install a jump host with internet access. However, in larger organizations this might not always be possible, or take a long time to make it through all the corporate red tape.

Additional context

No response

I/System.out: Unexpected status line: est.javastack.org��PHTTP/1.1 200 OK

my code is daynamic port forwardin but not work for use android

package com.topvpn.myvpn;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.client.session.forward.DynamicPortForwardingTracker;
import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.common.forward.PortForwardingEventListener;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.channel.ChannelSessionFactory;
import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
import org.apache.sshd.server.forward.DirectTcpipFactory;
import org.apache.sshd.server.forward.ForwardedTcpipFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class activity_ssh extends AppCompatActivity {

ClientChannel channel;
TextView shellOutput;
String host, username, password;
Integer port;
String command;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_ssh);

    // set output field
    shellOutput = findViewById(R.id.textView);

    // Get user credentials from indent
    Intent intent = getIntent();
    host = intent.getStringExtra("host");
    port = Integer.parseInt(intent.getStringExtra("port"));
    username = intent.getStringExtra("username");
    password = intent.getStringExtra("password");

    // Command which will be executed
    command = "pwd\n";

    // Setting user.com property manually
    // since isn't set by default in android
    String key = "user.home";
    Context Syscontext;
    Syscontext = getApplicationContext();
    String val = Syscontext.getApplicationInfo().dataDir;
    System.setProperty(key, val);

    // Creating a client instance
    SshClient client = SshClient.setUpDefaultClient();

    client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE);

    client.start();

    // Starting new thread because network processes
    // can interfere with UI if started in main thread
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // Connection establishment and authentication
                try (ClientSession session = client.connect(username, host, port).verify(10000).getSession()) {

                    session.addPasswordIdentity(password);
                    session.auth().verify(50000);

                    System.out.println("Connection establihed");

                    // Create a channel to communicate
                    channel = session.createChannel(Channel.CHANNEL_SHELL);
                    System.out.println("Starting shell");

                    ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
                    channel.setOut(responseStream);

                    // Open channel
                    channel.open().verify(5, TimeUnit.SECONDS);
                    try (OutputStream pipedIn = channel.getInvertedIn()) {
                        pipedIn.write(command.getBytes());
                        pipedIn.flush();
                    }
                    session.addPortForwardingEventListener(new PortForwardingEventListener() {

                        @Override
                        public void establishedDynamicTunnel(Session session, SshdSocketAddress local,
                                                             SshdSocketAddress boundAddress, Throwable reason) throws IOException {
                            // TODO Auto-generated method stub
                            PortForwardingEventListener.super.establishedDynamicTunnel(session, local, boundAddress, reason);

                            System.out.println("Dynamic Forword Tunnel is Ready");
                        }
                    });

                    SshdSocketAddress sshdSocketAddress = session
                            .startDynamicPortForwarding(new SshdSocketAddress("localhost", 1212));

                    System.out.println("Host: " + sshdSocketAddress.getHostName());
                    System.out.println("Port: " + sshdSocketAddress.getPort());

                    Proxy proxy = new Proxy(Proxy.Type.SOCKS,
                            new InetSocketAddress(sshdSocketAddress.getHostName(), sshdSocketAddress.getPort()));
                    testRemoteURL(proxy);

                    // Close channel
                    channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),
                            TimeUnit.SECONDS.toMillis(5));

                    // Output after converting to string type
                    String responseString = new String(responseStream.toByteArray());
                    System.out.println(responseString);
                    shellOutput.setText(responseString);


                } catch (IOException e) {
                    System.out.println(e.getMessage());
                    e.printStackTrace();
                } finally {
                    client.stop();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();
}
private static void testRemoteURL(final Proxy proxy) throws IOException {
    URL url = new URL("http://test.javastack.org/");
    HttpURLConnection connection = (HttpURLConnection) (proxy != null ? url.openConnection(proxy) : url.openConnection());
    //LOGGER.info("Get URL: {}", connection.getURL());
    try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
        String result = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            result = in.lines().collect(Collectors.joining("\n"));
        }
        System.out.println(result);
       // LOGGER.info("Response from server: {}", result);

    }
}

}

please help me???

How do I force the use of "RSA key" to connect to the remote side?

Version

2.7.0

Bug description

I notice sometimes sshd use "rsa key" connect remote, log like this

"Server at /192.168.218.182:830 presented unverified RSA key: SHA256:3lpuMiEyQ192HpfOAwjv+jhmliKfrG7w2Yl8x4bpfog"

and sometimes use "ec key"

Server at /192.168.218.182:830 presented unverified EC key: SHA256:nxJ168FpD/BD25sqDMQGv1ji6E11Fops01b0QUEOLxg

and the ec key never change.

I modified /root/.ssh/config file, but not work

HostKeyAlgorithms ssh-rsa

Actual behavior

use "ec key" connect remote

Expected behavior

force use "rsa key" connect remote

Relevant log output

No response

Other information

No response

DefaultSftpClient : add a property to allow to change the predefined maxLength of packet in method received

Description

in DefaultSftpClient, the method received test the maximum size of the packet just received with this :

if (length > (8 * SshConstants.SSH_REQUIRED_PAYLOAD_PACKET_LENGTH_SUPPORT)) { throw new StreamCorruptedException("Illogical sftp packet length: " + length); }

Unfortunately, this default 8 times is a bit low and cannot be modified.

When retrieving a directory listing from a server, i got the exception "illogical sftp packet length", and after investigating, the server contains about 6500 directories to retrieve info about.

Changing this value to a bigger one solved the issue for my cases, but i'm wondering if we can parametrised this value and not hard coding it in the futur.

Motivation

From https://www.rfc-editor.org/rfc/rfc4253#section-6.1

All implementations MUST be able to process packets with anuncompressed payload length of 32768 bytes or less and a total packet size of 35000 bytes or less (including 'packet_length', 'padding_length', 'payload', 'random padding', and 'mac'). The maximum of 35000 bytes is an arbitrarily chosen value that is largerthan the uncompressed length noted above. Implementations SHOULDsupport longer packets, where they might be needed. For example, if an implementation wants to send a very large number of certificates, the larger packets MAY be sent if the identification string indicatesthat the other party is able to process them. However, implementations SHOULD check that the packet length is reasonable in order for the implementation to avoid denial of service and/or buffer overflow attacks.

Alternatives considered

No response

Additional context

No response

Threads like sshd-SshClient[3c0574ec]-nio2-thread-17 Not Released even after .sshSession.close();

We

We are creating a session like
ClientSession session = (ClientSession)((ConnectFuture)client.connect(loginUserName, hostName, 22).verify(2L, TimeUnit.SECONDS)).getSession();
...
session.addPublicKeyIdentity(keys.iterator().next());
..
session.auth().verify(120000L, TimeUnit.MILLISECONDS);

After doing a PUT File operation ( Method like below ) and doing the session close like sshSession.close();

We see Threads like sshd-SshClient[3c0574ec]-nio2-thread-17 not getting released.

Put File method
public static void putFile(ClientSession session, String srcPath, String destPathForPut) throws SSHConnectionException {
try(SftpClient sftpClient = DefaultSftpClientFactory.INSTANCE.createSftpClient(session);
OutputStream o = sftpClient.write(destPathForPut, new SftpClient.OpenMode[] { SftpClient.OpenMode.Create, SftpClient.OpenMode.Write, SftpClient.OpenMode.Truncate }); BufferedOutputStream os = new BufferedOutputStream(o)) {
File sourceFile = new File(srcPath);
Files.copy(sourceFile.toPath(), os);
} catch (IOException e) {
s_log.log(Level.SEVERE, "Failed to store content via sftp at " + destPathForPut + " on host due to " + e
.getMessage(), e);
throw new SSHConnectionException("Failed to store content via sftp at " + destPathForPut + " on host due to " + e

      .getMessage(), e);
} 

}

Adding custom filter to filter chain on sftp

Im trying to find ways to add custom filter to filter chain. But ServerSession/IoSession doesn't provide a simpler way to inject custom filter.
Im using SshServer.setUpDefaultServer from org.apache.sshd.server which doesn't expose the IoAcceptor to be able to add filter to the chain.

Any recommendations or resources would be greatly appreciated.

Referring to docs here

SshChannelNotFoundException: Received SSH_MSG_CHANNEL_WINDOW_ADJUST on unassigned channel 0 (last assigned=null)

Version

2.8.0

Bug description

We received a report from a Gerrit user at review.opendev.org who could not pull their repositories via SSH. Upon investigating, we could see a consistent error logged for them

SshChannelNotFoundException: Received SSH_MSG_CHANNEL_WINDOW_ADJUST on unassigned channel 0 (last assigned=null)

and then the connection appears to disconnect. This user was using openssh 9.1_p1-r3

This issue seems to have some history with Gerrit. It seems in [1] there was a report of high-latency connections causing a similar-but-different error after an upgrade to 1.7.0 or maybe 2.0.0

SshChannelNotFoundException: Received SSH_MSG_CHANNEL_WINDOW_ADJUST on unknown channel 0

If I'm understanding what happened here, there was no particular root cause found as to why this error was occurring. However, what happened was that a ChannelIdTrackingUnknownChannelReferenceHandler implementation was added to sshd-contrib and incorporated into gerrit with [2].

If I'm understanding what this does, it basically watches when channels are initalized and saves that channel number to a session variable LAST_CHANNEL_ID_KEY. It then seems to basically ignore the ChannelIdTrackingUnknownChannelReference error if that channel has ever been opened before (i.e. the channel raising the exception is < LAST_CHANNEL_ID_KEY, and assuming channels are opened sequentially).

I think the summary at that point might be "we don't really know why we're seeing adjustment messages for unassigned channels, but we're ok to ignore that if we know the channel was opened at some point"?

Gerrit enabled this by default, but left an undocumented escape-hatch of an enableChannelIdTracking flag to turn it off; i.e. go back to the default state of raising an error for any messages for unassigned channels [3].

I think what we can see from this current error is that the client has sent this window adjustment message when mina seems to think no channel has ever been opened -- since the last assigned is null (on unassigned channel 0 (last assigned=null)).

This seems quite weird, and possibly racy? I confess only a passing knowledge of the SSH protocol, but how would the remote end have thought that the channel was setup enough to send a window adjustment when the mina side appears to have never have made the call to the channelInitialized() function here?

I should note this was again debugged to a high-latency, possibly unreliable connection. The user tried both ipv4 and ipv6 and could replicate the issue. When the switched to tethering via their phone, the problem did not occur. But it does seem to me that tcp/ip should keep what is coming across the wire in-order ...

Once identified by this user, upon inspecting the logs we noticed there were more connections exhibiting this behaviour. It seems to be heavily skewed to a few users that seem to have a lot of problems, but then we have this same message occurring once or twice for many more users.

I guess the question is -- is this a symptom of a connection that is so out of order with packet loss etc. that it can not be recovered; and this is just the first error that it happens to hit; or is this possibly some sort of race, where if this race didn't happen, the connection could be completed, even if slowly?

[1] https://issues.apache.org/jira/browse/SSHD-942
[2] https://gerrit-review.googlesource.com/c/gerrit/+/238384/9/java/com/google/gerrit/sshd/ChannelIdTrackingUnknownChannelReferenceHandler.java
[3] https://gerrit-review.googlesource.com/c/gerrit/+/238384/9/java/com/google/gerrit/sshd/SshDaemon.java

Actual behavior

Connection closed unexpectedly

Expected behavior

Connection to work

Relevant log output

No response

Other information

No response

ChannelShell. getInvertedOut() cannot be closed

Version

2.9.2

Bug description

//close
if (channelShell != null) {
    channelShell.close(true);
    channelShell.getInvertedOut().close();
}
try {
    ChannelShell channelShell = clientSession.createShellChannel();
    OpenFuture open = channelShell.open();
    if (open.await(3000, TimeUnit.SECONDS)) {
        if (open.isOpened()) {
            byte[] buffer = new byte[1024];
            int i;
            //TODO ChannelShell关闭,不会让这里停止,甚至channelShell.getInvertedOut().close()都不行
            while ((i = channelShell.getInvertedOut().read(buffer)) != -1) {
                sendToFrontend(session, Arrays.copyOfRange(buffer, 0, i));
            }
        } else {
            throw new BusinessException("通道打开失败");
        }
    } else {
        throw new BusinessException("连接超时");
    }
} catch (IOException e) {
    throw new BusinessException("通道创建失败:" + e.getMessage());
}

Closing ChannelShell will not stop channelShell. getInvertedOut(), even channelShell. getInvertedOut().close()

Actual behavior

Closing ChannelShell will not stop channelShell. getInvertedOut(), even channelShell. getInvertedOut().close()

Expected behavior

Close ChannelShell to close channelShell. getInvertedOut()

try {
    ChannelShell channelShell = clientSession.createShellChannel();
    OpenFuture open = channelShell.open();
    if (open.await(3000, TimeUnit.SECONDS)) {
        if (open.isOpened()) {
            byte[] buffer = new byte[1024];
            int i;
            //TODO Closing ChannelShell will not stop channelShell. getInvertedOut(), even channelShell. getInvertedOut().close()
            while ((i = channelShell.getInvertedOut().read(buffer)) != -1) {
                sendToFrontend(session, Arrays.copyOfRange(buffer, 0, i));
            }
        } else {
            throw new BusinessException("通道打开失败");
        }
    } else {
        throw new BusinessException("连接超时");
    }
} catch (IOException e) {
    throw new BusinessException("通道创建失败:" + e.getMessage());
}

Relevant log output

No response

Other information

No response

Race condition in BufferedIoOutputStream

SFTP tests are flaky. Turns out that they are running into

23:13:59.123 | ERROR | MinaProcessor-25 | o.a.s.c.c.BufferedIoOutputStream | org.apache.sshd.common.channel.BufferedIoOutputStream             219 | finishWrite(sftp-out@0)[ChannelAsyncOutputStream[ChannelSession[id=0, recipient=0]-ServerSessionImpl[testTransferIntegrityWithBufferLargerThanPacket[REKEY_BLOCK_SIZE 65,536]@/127.0.0.1:59555]] cmd=SSH_MSG_CHANNEL_DATA] - pending byte counts underflow (-64525) after 18070131 bytes
23:13:59.123 | ERROR | m-42976-thread-1 | o.a.s.s.s.SftpSubsystem          | org.apache.sshd.common.util.logging.LoggingUtils                  693 | run(ServerSessionImpl[testTransferIntegrityWithBufferLargerThanPacket[REKEY_BLOCK_SIZE 65,536]@/127.0.0.1:59555]) SshChannelBufferedOutputException caught in SFTP subsystem after 863 buffers: Pending byte counts underflow
23:23:59.498 | INFO  | )-timer-thread-1 | o.a.s.s.s.ServerSessionImpl      | org.apache.sshd.common.session.helpers.SessionHelper             1183 | Disconnecting(ServerSessionImpl[testTransferIntegrityWithBufferLargerThanPacket[REKEY_BLOCK_SIZE 65,536]@/127.0.0.1:59555]): SSH2_DISCONNECT_PROTOCOL_ERROR - Detected IdleTimeout after 600375/600000 ms.

Finished org.apache.sshd.sftp.client.SftpTransferTest:testTransferIntegrityWithBufferLargerThanPacket[REKEY_BLOCK_SIZE 65,536] in 610192 ms

Let's ignore the fact that test hangs for 10 minutes until that timeout expires; that a different minor problem. The real problem is the "pending byte counts underflow", which indicates that the BufferedIoOutputStream somehow managed to write more data than was passed to it.

This is a race condition between BufferedIoOutputStream.startWriting() and BufferedIoOutputStream.finishWrite(). The following sequence of events is possible when a write that was in progress just finished and the user of the stream just initiates a new write:

  1. Thread 1: startWriting gets the head of the write queue -- this is still the future/buffer that was just written
  2. Thread 2: finishWrite removes that write from the write queue
  3. Thread 2: finishWrite clears the "current" write
  4. Thread 1: startWriting sets the "current" write and happily writes the future/buffer again.

Combined with the fact that the underlying ChannelAsyncOutputStream may in some cases copy the buffer and actually write that copy, but doesn't consume the original buffer in that case, this leads to the same data being written again, and when that second write finishes, this byte count gets subtracted again from the number of total bytes to be written. So the count is added once but subtracted twice, and eventually this "pending byte counts underflow" is hit.

This race condition in BufferedIoOutputStream needs to be fixed. Optionally ChannelAsyncOutputStream should consume the original buffer if it makes a copy; though I'm undecided on that: if it did, it might have hidden this bug (because then the second write of that buffer would have been a zero-byte write).

(The problem is not specific to the MINA transport back-end; it also occurs with NIO2 from time to time. CI builds are green because the race condition appears to be hit infrequently, and on a re-run the test usually succeeds.)

[BUG]The command "source ~/.bashrc" is invalid.

Version

2.9.0

Bug description

When I execute the command "source ~.bashrc", it doesn't take effect. As shown below, there is an environment variable "ABC" in my bashrc, but I can't output it.k

The code is as follows:

        ClientSession session = client.connect(user, host, port).verify().getSession();
        boolean result = session.auth().verify().isSuccess();
        if (result) {
            System.out.println("Success");
        } else {
            System.out.println("Failed");
        }
        System.out.println(result);

        String command = "cat ~/.bashrc && source ~/.bashrc && echo $ABC && echo END";
        String cmd = String.format(command);
        System.out.println(cmd);
        String executeResult = session.executeRemoteCommand(cmd);
        System.out.println(executeResult);
        client.stop();

Actual behavior

The outputs is as follows:

.... some other contents.....
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
export ABC=abc

END

Expected behavior

I think the output should be

.... some other contents.....
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
export ABC=abc
abc
END

Relevant log output

No response

Other information

No response

SshClient.connect() does not respect username parameter when a default is specified in ssh/config

Version

2.9.2

Bug description

In ssh/config:

Host A
    ...
Host B
    ...
Host *
    User xxx

In Java code:

SshClient client = SshClient.setUpDefaultClient ();
HostConfigEntry entry = client.getHostConfigEntryResolver ().resolveEffectiveHost ("hhh", 22, null, "xxx", null, null);
// "entry" is ignored. Just noting that resolveEffectiveHost() gets called, in case it matters.
ClientSession session = client.connect ("yyy", "hhh", 22).verify (timeout).getSession ();  // Username "yyy", not "xxx".
session.setUserInteraction (I);
session.addPasswordIdentity ("ppp");
session.auth ().verify (120000);

Actual behavior

Based on debug log, username "xxx" is passed to host, not username "yyy". After removing the default entry in ssh/config, the correct username is passed.

Expected behavior

When the programmer explicitly specifies a username+host pair in the connect() call, it should take precedence over all other sources of username for the given host. In particular, it should definitely override a default value in config, much the same way specific host entries in config override the default. Perhaps some special value could indicate to use the default, for example passing null for username.

Relevant log output

No response

Other information

No response

Memory Leak in SftpFileSystemProvider

Version

master

Bug description

The newInputStream and newOutputStream methods of SftpFileSystemProvider call the SftpFileSystem#getClient() method without call the close() method:
image

Actual behavior

I have a thread that uploads a file to the server every 10 seconds, as time goes by, the heap memory will get bigger and bigger, and eventually the heap memory will occur out of memory:
image

When I exported the heap memory, I found that there are a lot of objects of org.apache.sshd.sftp.client.fs.SftpFileSystem$Wrapper
image

Expected behavior

When the program is running normally, the heap memory will not overflow

Relevant log output

No response

Other information

No response

Performance problems in tests (NIO2 and MINA, Linux only)

Looking through the GitHub build logs, there seems to be a problem with two tests on Linux, with the NIO2 or MINA transport back-ends. They show very poor performance:

org.apache.sshd.sftp.client.SftpTransferTest

Build                   NIO2       MINA      Netty

ubuntu, java 8         ~300s       ~300s     ~70s
ubuntu, java 11        ~300s       ~300s     ~50s
ubuntu, java 17        ~300s       ~300s     ~50s

windows, java 8         ~62s        ~67s     ~66s
windows, java 11        ~49s        ~49s     ~43s
windows, java 17        ~43s        ~44s     ~45s

org.apache.sshd.scp.client.ScpTest

Build                   NIO2       MINA      Netty

ubuntu, java 8          ~19s        ~19s     ~11s
ubuntu, java 11         ~19s        ~19s     ~11s
ubuntu, java 17         ~19s        ~19s     ~11s

windows, java 8         ~12s        ~12s     ~12s
windows, java 11        ~12s        ~12s     ~12s
windows, java 17        ~12s        ~12s     ~12s

These are the only tests for which I see such discrepancies. It looks like the code is doing something that doesn't play well with NIO2 or MINA on Linux.

It's not a new problem either; I could find this pattern also in the build logs of 2022-10-25 (commit 7ad3ead) and also in even older builds. Though e.g. in a build from 2022-09-20 the differences are smaller (but still there; 120s instead of 300s, and 15s instead of 19s).

The windows times and the Linux/Netty times appear to be about normal and are what I also see for NIO2 or MINA when building locally on OS X: 12s for ScpTest and about a minute for the SftpTransferTest.

What is going on here?

Heartbeat does not respond to timeout while waiting for a response from the server

If heartbeat is waiting for a response from the server and the response did not come within the allotted time, then we must kill the session because the server is not responding, in which case the lack of response to waiting for a response in org.apache.sshd.client.session.ClientConnectionService#sendHeartBeat looks like wrong behavior.

Should we do something like
if (!replyReceived.await(toWait, TimeUnit.MILLISECONDS)) { throw new TimeoutException("No response from server"); }
when waiting response on heartbeat request

timeout

Am I understanding heartbeat logic correctly?

sftpclient successfully creates a directory, but an exception is thrown. What is the problem

Version

sshd-sftp 2.9.2

Bug description

The sftp failed to recursively create a remote directory, but the directory was successfully created!

private void createRemoteDirectories(SftpClient sftp, String remoteDir) throws IOException {
        try {
            SftpClient.Attributes attrs = sftp.stat(remoteDir);
            ValidateUtils.checkTrue(attrs.isDirectory(), "Remote path already exists but is not a directory: %s",
                    remoteDir);
        } catch (SftpException e) {
            if (e.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) {
                String[] items = remoteDir.substring(1).split(File.separator);
                String tempPath = File.separator;
                for (String item : items) {
                    tempPath += item + File.separator;
                    try {
                        SftpClient.Attributes attrs = sftp.stat(tempPath);
                        ValidateUtils.checkTrue(attrs.isDirectory(), "Remote path already exists but is not a directory: %s",
                                tempPath);
                    } catch (SftpException ex) {
                        if (ex.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) {
                            logger.info("mkdir {}", tempPath);
                            sftp.mkdir(tempPath);
                        } else {
                            throw ex;
                        }
                    }
                }
            }
        }
    }

Actual behavior

The directory was created successfully but an exception was thrown!

Expected behavior

The directory was successfully created with no exceptions!

Relevant log output

2023-03-14 10:48:45.958 [main] INFO  com.leo.sftp.client.DefaultSftpClientImpl - mkdir /bbb/
Exception in thread "main" SFTP error (SSH_FX_FAILURE): General failure
	at org.apache.sshd.sftp.client.impl.AbstractSftpClient.throwStatusException(AbstractSftpClient.java:217)
	at org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkResponseStatus(AbstractSftpClient.java:212)
	at org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkResponseStatus(AbstractSftpClient.java:186)
	at org.apache.sshd.sftp.client.impl.AbstractSftpClient.checkCommandStatus(AbstractSftpClient.java:164)
	at org.apache.sshd.sftp.client.impl.AbstractSftpClient.mkdir(AbstractSftpClient.java:802)
	at com.leo.sftp.client.DefaultSftpClientImpl.createRemoteDirectories(DefaultSftpClientImpl.java:335)
	at com.leo.sftp.client.DefaultSftpClientImpl.putFile(DefaultSftpClientImpl.java:243)
	at com.leo.sftp.client.DefaultSftpClientImpl.put(DefaultSftpClientImpl.java:219)
	at com.leo.sftp.client.DefaultSftpClientImpl.put(DefaultSftpClientImpl.java:186)
	at com.leo.sftp.client.DefaultSftpClientImpl.put(DefaultSftpClientImpl.java:179)
	at com.leo.sftp.client.SftpClientMain.main(SftpClientMain.java:83)

Other information

No response

Connect to server failed when get session:error: 在一个非套接字上尝试了一个操作

Version

2.9.2

Bug description

Recently, we switched from jsch to mina ssh. In some of our customers' environments, we encountered the following error when connecting to the customer's machine through SSH. When we roll back to the version using jsch, we can connect the environment properly.

Operating system: windows server 2016
target environment ip: IPv6

Actual behavior

connection build failed.

Expected behavior

Connect the device properly.

Relevant log output

![image](https://user-images.githubusercontent.com/122873415/212870558-88eb5c4a-671d-47c2-945d-7f4e3ceb74aa.png)
Caused by: java.io.IOException: 在一个非套接字上尝试了一个操作。
	at sun.nio.ch.WindowsAsynchronousSocketChannelImpl.connect0(Native Method) ~[?:1.8.0_332]
	at sun.nio.ch.WindowsAsynchronousSocketChannelImpl.access$200(WindowsAsynchronousSocketChannelImpl.java:43) ~[?:1.8.0_332]
	at sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ConnectTask.run(WindowsAsynchronousSocketChannelImpl.java:235) ~[?:1.8.0_332]
	at sun.nio.ch.WindowsAsynchronousSocketChannelImpl.implConnect(WindowsAsynchronousSocketChannelImpl.java:382) ~[?:1.8.0_332]
	at sun.nio.ch.AsynchronousSocketChannelImpl.connect(AsynchronousSocketChannelImpl.java:210) ~[?:1.8.0_332]
	at org.apache.sshd.common.io.nio2.Nio2Connector.connect(Nio2Connector.java:72) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.client.SshClient.doConnect(SshClient.java:632) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.client.SshClient.doConnect(SshClient.java:615) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.client.SshClient.connect(SshClient.java:546) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.client.SshClient.connect(SshClient.java:538) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.client.session.ClientSessionCreator.connect(ClientSessionCreator.java:74) ~[sshd-core-2.9.2.jar:2.9.2]
	at org.apache.sshd.client.session.ClientSessionCreator.connect(ClientSessionCreator.java:57) ~[sshd-core-2.9.2.jar:2.9.2]

Other information

our code :
image

SftpSubsystem eats exceptions

Version

2.9.3

Bug description

While trying to implement a virtual file system for SFTPD, I ran into a condition in which the connection would close but there was nothing in the logs. After 5 hours of trying to configure the logger all I could see is DEBUG messages, but no log of the exception or error. I eventually traced it down that although there is a master catch in SftpSubsystem.run, it was never being reached. It appears that AbstractSftpSubsystemHelper contains a lot of code with this sort of pattern...

      } catch (IOException | RuntimeException e) {
            sendStatus(prepareReply(buffer), id, e, SftpConstants.SSH_FXP_OPEN, path);
            return;
        }

It seems like poor practice to not log something when an exception occurs.

To reproduce this I implemented a custom FileSystemFactory which returned MyFileSystem in which getSeparator() throw an exception. To hit multiple points I had to proxy Path, FileSystem, and FileSystemProvider to the normal versions. The exception must happen in the Path, FileSystem, or FileSystemProvider. Throws in FileSystemFactory are caught properly as SftpSubsystem catches during prepare, but not in doProcess.

Actual behavior

Nothing was logged.

Expected behavior

A log message with the source of the exception. If this is addressed, perhaps this should be logged at the DEBUG level as this was not normally logged in the past. After all there are a lot of tolerable exceptions (missing file, permissions, etc) that are not errors for normal operation.

Relevant log output

No response

Other information

Logging was configured with log4j with DEBUG to console. But the lack of output is programmatic rather than the logger, so it should be universal.

ssh links init fail, throw Exception.Do anyone know what cause it or how to fix it

3131
java.lang.IllegalStateException: Channel id=0 not registered because session is being closed: ChannelShell[id=0, recipient=-1]-ClientSessionImpl[root@null]
at org.apache.sshd.common.channel.AbstractChannel.handleChannelRegistrationResult(AbstractChannel.java:440) ~[sshd-core-2.9.2.jar:2.9.2]
at org.apache.sshd.common.session.helpers.AbstractConnectionService.registerChannel(AbstractConnectionService.java:423) ~[sshd-core-2.9.2.jar:2.9.2]
at org.apache.sshd.client.session.AbstractClientSession.createShellChannel(AbstractClientSession.java:500) ~[sshd-core-2.9.2.jar:2.9.2]
at org.apache.sshd.client.session.ClientSession.createShellChannel(ClientSession.java:159) ~[sshd-core-2.9.2.jar:2.9.2]

channel already closed

I am trying to store ClientChannel(Shell) in Hashmap to reuse later.But after Storing to Hashmap Channel State is changed to CLOSED.Please Explain me What Causing this. errorthis error.
SSH_MSG_CHANNEL_DATA) len=11 - channel already closed

bracketed-paste mode

Description

When I set up a bash connection and execute a command, the command echoes are wrapped in characters.
an example: cat /proc/version
ESC:[?2004l Linux version xxx. ESC[?2004h

I have consulted related documents. This is the default bracketed-paste mode enabled after bash5.1. Can sshd disable this mode on the client?

Motivation

Generally, the client only cares about the necessary output information.

Alternatives considered

No response

Additional context

No response

How to disable the warning "Server at xxxx preseneted unverfied EC key"

Version

2.7.0

Bug description

every time when the program connects to the remote host using apache-mina-sshd will print the WARN log like "Server at xxx presented unverfied EC key", I wonder how to disable it?

Actual behavior

every time when the program connects to the remote host using apache-mina-sshd will print the WARN log like "Server at xxx presented unverfied EC key"

Expected behavior

No WARN log like "Server at xxx preseneted unverfied EC key" be printed.

Relevant log output

No response

Other information

No response

exceptions in SftpFileSystemProvider on Files.delete( Path p)

Version

sshd-sftp 2.9.2

Bug description

While using a Path on SftpFileSystemProvider:

Exceptions thrown in on Files.delete( Path p), when deleting symbolic links.

  • When deleting a symbolic links to non-existing file.
  • When deleting a symbolic link to existing directory
  • When deleting a symbolic link to existing file

Actual behavior

probably the links are followed, and the link is handled like the linkdestination. this causes exceptions.

Expected behavior

No exception but deletion of the symbolic link.

Relevant log output

No response

Other information

Server OpenSSH_8.9p1 Ubuntu-3ubuntu0.1

requestNewKeysExchange may cause KeyExchangeMessageHandler into dead lock,cpu 100%

Version

2.9.1

Bug description

i observed in cases, the write packet thread is always running and in the interval i saw "equestNewKeysExchange(ClientSessionImpl[root@/47.104.92.124:22]) Initiating key re-exchange
method:o.a.s.c.s.ClientSessionImpl(AbstractSession.java:2404) " in log

Actual behavior

after i saw log "equestNewKeysExchange(ClientSessionImpl[root@/47.104.92.124:22]) Initiating key re-exchange
method:o.a.s.c.s.ClientSessionImpl(AbstractSession.java:2404)",the write packet thread is soar to 100%,not stopped

Expected behavior

i expect when the connection is closed the cpu is down,and the thread is stopped

Relevant log output

equestNewKeysExchange(ClientSessionImpl[root@/47.104.92.124:22]) Initiating key re-exchange
method:o.a.s.c.s.ClientSessionImpl(AbstractSession.java:2404)

Other information

No response

Compilation error due to ExecutorService API change in JDK 19

Version

3b16da4

Bug description

Starting in JDK 19, ExecutorService implements AutoCloseable: openjdk/jdk@00e6c63#diff-139913957207a1eeaa338c35b269f2c566b358590ae62dd2a8063e98bb5b0456

This change causes a compilation error in mina-sshd.

Actual behavior

cd ~/sshd-common
mvn clean package -Djava.sdk.version=19
...
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sshd-common: Compilation failure: Compilation failure:
[ERROR] /usr/local/google/home/cushon/src/mina-sshd/sshd-common/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java:[43,8] org.apache.sshd.common.util.threads.NoCloseExecutor is not abstract and does not override abstract method close() in java.nio.channels.Channel
[ERROR] /usr/local/google/home/cushon/src/mina-sshd/sshd-common/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java:[29,8] types java.util.concurrent.ExecutorService and org.apache.sshd.common.Closeable are incompatible;
[ERROR]   interface org.apache.sshd.common.util.threads.CloseableExecutorService inherits unrelated defaults for close() from types java.util.concurrent.ExecutorService and org.apache.sshd.common.Closeable
[ERROR] /usr/local/google/home/cushon/src/mina-sshd/sshd-common/src/main/java/org/apache/sshd/common/util/threads/SshThreadPoolExecutor.java:[35,8] types org.apache.sshd.common.Closeable and java.util.concurrent.ExecutorService are incompatible;
[ERROR]   class org.apache.sshd.common.util.threads.SshThreadPoolExecutor inherits unrelated defaults for close() from types org.apache.sshd.common.Closeable and java.util.concurrent.ExecutorService
[ERROR] -> [Help 1]

Expected behavior

I expected the project to compile

Relevant log output

Apache Maven 3.8.6
Maven home: /usr/share/maven
Java version: 19.0.1, vendor: Oracle Corporation
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", arch: "amd64", family: "unix"

Other information

No response

SSHD Client failing on private key file with key password

Version

2.9.2

Bug description

When attempting to run the SSH client with that private key file that is protected with a password the Mina SSH client doesn't make the connection.

The client was run using the command

java -jar MinaSshClient-2.9.2.jar -i K:\id_rsa [email protected]

Actual behavior

The client seems to fail to load the key resource with the following warning

WARNING: org.apache.sshd.cli.client.SshCl: Failed (FailedLoginException) to load key resource=K:\id_rsa: No password provider for encrypted key in K:\id_rsa

the connection subsequently fails with a "No more authentication methods available"

Expected behavior

The client should prompt for a password for the key file or have another command line parameter to specify it.

Relevant log output

No response

Other information

I did a bit of debugging on this and for whatever reason the prompt for the password for the private key file isn't being triggered by the code in the SshClientCliSupport, setupSessionIdentities method.

Whether or not it's the correct solution what I did in my own code is I used the setPasswordFinder method on the FileKeyPairProvider with the same code segment as for the client setFilePasswordProvider and it seemed to work.

Can mina sshd be used in Android?

Version

2.9.2

Bug description

I try to used mina sshd in Android but I have some problems:

  1. in LazyDefaultUserHomeFolderHolder, the path is read from System.getProperty("user.home"). But in Android, System.getProperty("user.home") is null. Will this be a problem?
  2. in ExceptionUtils, sshd uses class javax.management.MBeanException and javax.management.ReflectionException. But they don't exist on Android.

Can mina sshd be used in Android? Or is there any android version of sshd can be used in Android?

Actual behavior

  1. I change System.getProperty("user.home") to Environment.getExternalStorageDirectory().getAbsolutePath(). Otherwise, sshd can not connect to server.

Expected behavior

sshd can run in android

Relevant log output

No response

Other information

No response

How to: Unable to access session statistics

I have implemented the sessionClosed of org.apache.sshd.common.session.SessionListener to access session stats; but couldn't access to methods specified for variables here on session/IoSession.

As a workaround currently I have overridden read and written methods of AbstractSftpEventListenerAdapter to pull dataLen.
Is there any other/right way I could access these stats?

How to: create sshclient with a private key

Version

3.0.0 alpha

Bug description

Please,

can you provide an example on how to connect a mina ssh client to a server through a private key authentication?

Actual behavior

Can't create a client witth private key.

Expected behavior

Also in the cli client, missing the option to load the private key.

Relevant log output

No response

Other information

No response

Support for more than one jump host

Description

I have a special server running to which the connection is only possible via 2 jump hosts and my configuration for SSH looks like this:

Host jump1
  Hostname                    jump1.corp
  Port                        22
  User                        nightman
  LogLevel                    QUIET

Host jump2
  HostName                    jump2.dmz.corp
  Port                        22
  User                        nightman
  ProxyJump                   jump1
  LogLevel                    QUIET

Host host*.dmz.corp
  ProxyJump                   nightman@jump2:22

This is working well with the native SSH clients.

It would be nice when your great libary would support such a configuration as well!

:-)

Motivation

Enhancements would make the library better usable for jump hosts.

Alternatives considered

There is no workaround I found so far.

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.