diff --git a/0001-Avoid-optional-dependency-on-native-tomcat-APR-libra.patch b/0001-Avoid-optional-dependency-on-native-tomcat-APR-libra.patch
index 6006344..f1a3b44 100644
--- a/0001-Avoid-optional-dependency-on-native-tomcat-APR-libra.patch
+++ b/0001-Avoid-optional-dependency-on-native-tomcat-APR-libra.patch
@@ -14,9 +14,9 @@ diff --git a/pom.xml b/pom.xml
index 867ca88..7c29678 100644
--- a/pom.xml
+++ b/pom.xml
-@@ -397,11 +397,6 @@
+@@ -428,11 +428,6 @@
mina-core
- 2.0.19
+ 2.0.23
-
- tomcat
@@ -30,19 +30,19 @@ diff --git a/sshd-core/pom.xml b/sshd-core/pom.xml
index 6171c5c..73a43a7 100644
--- a/sshd-core/pom.xml
+++ b/sshd-core/pom.xml
-@@ -44,12 +44,6 @@
- ${project.version}
+@@ -43,12 +43,6 @@
--
+
- tomcat
- tomcat-apr
- true
-
-
-
+- org.bouncycastlebcpg-jdk15on
+ true
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
index ab19539..5757e68 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
@@ -54,24 +54,24 @@ index ab19539..5757e68 100644
-import org.apache.sshd.agent.unix.AprLibrary;
-import org.apache.sshd.agent.unix.UnixAgentFactory;
import org.apache.sshd.common.FactoryManager;
- import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.PropertyResolver;
-@@ -53,9 +51,7 @@ public class ProxyAgentFactory implements SshAgentFactory {
+ import org.apache.sshd.common.channel.ChannelFactory;
+@@ -51,9 +49,7 @@ public class ProxyAgentFactory implements SshAgentFactory {
@Override
- public List> getChannelForwardingFactories(FactoryManager manager) {
+ public List getChannelForwardingFactories(FactoryManager manager) {
- return isPreferredUnixAgent(manager)
-- ? UnixAgentFactory.DEFAULT_FORWARDING_CHANNELS
-- : LocalAgentFactory.DEFAULT_FORWARDING_CHANNELS;
+- ? UnixAgentFactory.DEFAULT_FORWARDING_CHANNELS
+- : LocalAgentFactory.DEFAULT_FORWARDING_CHANNELS;
+ return LocalAgentFactory.DEFAULT_FORWARDING_CHANNELS;
}
@Override
-@@ -106,16 +102,6 @@ public class ProxyAgentFactory implements SshAgentFactory {
+@@ -104,16 +100,6 @@ public class ProxyAgentFactory implements SshAgentFactory {
}
public static boolean isPreferredUnixAgent(PropertyResolver resolver) {
-- if (PropertyResolverUtils.getBooleanProperty(resolver, PREFER_UNIX_AGENT, OsUtils.isUNIX())) {
+- if (CoreModuleProperties.PREFER_UNIX_AGENT.getRequired(resolver)) {
- try {
- if (AprLibrary.getInstance() != null) {
- return true;
@@ -103,5 +103,3 @@ index 5395ceb..f456263 100644
--
2.20.1
-
-
diff --git a/CVE-2021-30129-1.patch b/CVE-2021-30129-1.patch
deleted file mode 100644
index a6148be..0000000
--- a/CVE-2021-30129-1.patch
+++ /dev/null
@@ -1,1116 +0,0 @@
-From 68c780f2e746eedb714ff6e17c6815fbffddeff6 Mon Sep 17 00:00:00 2001
-From: Guillaume Nodet
-Date: Fri, 17 Jul 2020 11:33:21 +0200
-Subject: [PATCH 1/1] [SSHD-1035] Move property definitions tocommon locations
-
----
- .../java/org/apache/sshd/common/Property.java | 408 +++++++++++
- .../sshd/core/CoreModuleProperties.java | 681 ++++++++++++++++++
- 2 files changed, 1089 insertions(+)
- create mode 100644 sshd-common/src/main/java/org/apache/sshd/common/Property.java
- create mode 100644 sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
-
-diff --git a/sshd-common/src/main/java/org/apache/sshd/common/Property.java b/sshd-common/src/main/java/org/apache/sshd/common/Property.java
-new file mode 100644
-index 0000000..f5ad335
---- /dev/null
-+++ b/sshd-common/src/main/java/org/apache/sshd/common/Property.java
-@@ -0,0 +1,408 @@
-+/*
-+ * Licensed to the Apache Software Foundation (ASF) under one
-+ * or more contributor license agreements. See the NOTICE file
-+ * distributed with this work for additional information
-+ * regarding copyright ownership. The ASF licenses this file
-+ * to you under the Apache License, Version 2.0 (the
-+ * "License"); you may not use this file except in compliance
-+ * with the License. You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing,
-+ * software distributed under the License is distributed on an
-+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-+ * KIND, either express or implied. See the License for the
-+ * specific language governing permissions and limitations
-+ * under the License.
-+ */
-+package org.apache.sshd.common;
-+
-+import java.nio.charset.Charset;
-+import java.time.Duration;
-+import java.util.Arrays;
-+import java.util.Objects;
-+import java.util.Optional;
-+import java.util.function.Consumer;
-+
-+/**
-+ * Property definition.
-+ *
-+ * @author Apache MINA SSHD Project
-+ */
-+public interface Property {
-+
-+ static Property string(String name) {
-+ return new StringProperty(name);
-+ }
-+
-+ static Property string(String name, String def) {
-+ return new StringProperty(name, def);
-+ }
-+
-+ static Property bool(String name) {
-+ return new BooleanProperty(name);
-+ }
-+
-+ static Property bool(String name, boolean def) {
-+ return new BooleanProperty(name, def);
-+ }
-+
-+ static Property integer(String name) {
-+ return new IntProperty(name);
-+ }
-+
-+ static Property integer(String name, int def) {
-+ return new IntProperty(name, def);
-+ }
-+
-+ // CHECKSTYLE:OFF
-+ static Property long_(String name) {
-+ return new LongProperty(name);
-+ }
-+
-+ static Property long_(String name, long def) {
-+ return new LongProperty(name, def);
-+ }
-+
-+ static > Property enum_(String name, Class type) {
-+ return new EnumProperty<>(name, type);
-+ }
-+
-+ static > Property enum_(String name, Class type, T def) {
-+ return new EnumProperty<>(name, type, def);
-+ }
-+ // CHECKSTYLE:ON
-+
-+ static Property duration(String name) {
-+ return new DurationProperty(name);
-+ }
-+
-+ static Property duration(String name, Duration def) {
-+ return new DurationProperty(name, def);
-+ }
-+
-+ static Property durationSec(String name) {
-+ return new DurationInSecondsProperty(name);
-+ }
-+
-+ static Property durationSec(String name, Duration def) {
-+ return new DurationInSecondsProperty(name, def);
-+ }
-+
-+ static Property charset(String name) {
-+ return new CharsetProperty(name);
-+ }
-+
-+ static Property charset(String name, Charset def) {
-+ return new CharsetProperty(name, def);
-+ }
-+
-+ static Property
-+ *
-+ *
-+ *
A {@link java.net.URI} or a string starting with "file:/", in which case it will be converted to a
-+ * {@link java.nio.file.Path} and handled accordingly.
-+ *
-+ *
-+ *
-+ *
A string containing a special value indicator - e.g., {@link #AUTO_WELCOME_BANNER_VALUE}, in which case the
-+ * relevant banner content will be generated.
-+ *
-+ *
-+ *
-+ *
Any other object whose {@code toString()} value yields a non empty string will be used as the banner
-+ * contents.
-+ *
-+ *
-+ *
-+ * @see RFC-4252 section 5.4
-+ */
-+ public static final Property WELCOME_BANNER
-+ = Property.object("welcome-banner");
-+
-+ /**
-+ * Special value that can be set for the {@link #WELCOME_BANNER} property indicating that the server should generate
-+ * a banner consisting of the random art of the server's keys (if any are provided). If no server keys are
-+ * available, then no banner will be sent
-+ */
-+ public static final String AUTO_WELCOME_BANNER_VALUE = "#auto-welcome-banner";
-+
-+ /**
-+ * Key used to denote the language code for the welcome banner (if such a banner is configured).
-+ */
-+ public static final Property WELCOME_BANNER_LANGUAGE
-+ = Property.string("welcome-banner-language", "en");
-+
-+ /**
-+ * The {@link WelcomeBannerPhase} value - either as an enum or a string
-+ */
-+ public static final Property WELCOME_BANNER_PHASE
-+ = Property.enum_("welcome-banner-phase", WelcomeBannerPhase.class, WelcomeBannerPhase.IMMEDIATE);
-+
-+ /**
-+ * The charset to use if the configured welcome banner points to a file - if not specified (either as a string or a
-+ * {@link java.nio.charset.Charset} then the local default is used.
-+ */
-+ public static final Property WELCOME_BANNER_CHARSET
-+ = Property.charset("welcome-banner-charset", Charset.defaultCharset());
-+
-+ /**
-+ * This key is used when configuring multi-step authentications. The value needs to be a blank separated list of
-+ * comma separated list of authentication method names. For example, an argument of
-+ * publickey,password publickey,keyboard-interactive would require the user to complete public key
-+ * authentication, followed by either password or keyboard interactive authentication. Only methods that are next in
-+ * one or more lists are offered at each stage, so for this example, it would not be possible to attempt password or
-+ * keyboard-interactive authentication before public key.
-+ */
-+ public static final Property AUTH_METHODS
-+ = Property.string("auth-methods");
-+
-+ /**
-+ * Key used to retrieve the value of the maximum concurrent open session count per username. If not set, then
-+ * unlimited
-+ */
-+ public static final Property MAX_CONCURRENT_SESSIONS
-+ = Property.integer("max-concurrent-sessions");
-+
-+ /**
-+ * Key used to retrieve any extra lines to be sent during initial protocol handshake before the
-+ * identification. The configured string value should use {@value #SERVER_EXTRA_IDENT_LINES_SEPARATOR} character to
-+ * denote line breaks
-+ */
-+ public static final Property SERVER_EXTRA_IDENTIFICATION_LINES
-+ = Property.string("server-extra-identification-lines");
-+
-+ /**
-+ * Separator used in the {@link #SERVER_EXTRA_IDENTIFICATION_LINES} configuration string to indicate new line break
-+ */
-+ public static final char SERVER_EXTRA_IDENT_LINES_SEPARATOR = '|';
-+
-+ /**
-+ * Key used to retrieve the value of the server identification string. If set, then it is appended to the
-+ * (standard) "SSH-2.0-" prefix. Otherwise a default is sent that consists of "SSH-2.0-" plus
-+ * the current SSHD artifact name and version in uppercase - e.g., "SSH-2.0-APACHE-SSHD-1.0.0"
-+ */
-+ public static final Property SERVER_IDENTIFICATION
-+ = Property.string("server-identification");
-+
-+ /**
-+ * Key used to configure the timeout used when receiving a close request on a channel to wait until the command
-+ * cleanly exits after setting an EOF on the input stream.
-+ */
-+ public static final Property COMMAND_EXIT_TIMEOUT
-+ = Property.duration("command-exit-timeout", Duration.ofMillis(5L));
-+
-+ /**
-+ * A URL pointing to the moduli file. If not specified, the default internal file will be used.
-+ */
-+ public static final Property MODULI_URL
-+ = Property.string("moduli-url");
-+
-+ /**
-+ * See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
-+ */
-+ public static final Property KB_SERVER_INTERACTIVE_NAME
-+ = Property.string("kb-server-interactive-name", "Password authentication");
-+
-+ /**
-+ * See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
-+ */
-+ public static final Property KB_SERVER_INTERACTIVE_INSTRUCTION
-+ = Property.string("kb-server-interactive-instruction", "");
-+
-+ /**
-+ * See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
-+ */
-+ public static final Property KB_SERVER_INTERACTIVE_LANG
-+ = Property.string("kb-server-interactive-language", "en-US");
-+
-+ /**
-+ * See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
-+ */
-+ public static final Property KB_SERVER_INTERACTIVE_PROMPT
-+ = Property.string("kb-server-interactive-prompt", "Password: ");
-+
-+ /**
-+ * See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
-+ */
-+ public static final Property KB_SERVER_INTERACTIVE_ECHO_PROMPT
-+ = Property.bool("kb-server-interactive-echo-prompt", false);
-+
-+ /**
-+ * Maximum amount of extended (a.k.a. STDERR) data allowed to be accumulated until a {@link ChannelDataReceiver} for
-+ * the data is registered
-+ */
-+ public static final Property MAX_EXTDATA_BUFSIZE
-+ = Property.integer("channel-session-max-extdata-bufsize", 0);
-+
-+ /**
-+ * See {@link org.apache.sshd.server.kex.DHGEXServer}.
-+ */
-+ public static final Property PROP_DHGEX_SERVER_MIN_KEY
-+ = Property.integer("dhgex-server-min");
-+
-+ /**
-+ * See {@link org.apache.sshd.server.kex.DHGEXServer}.
-+ */
-+ public static final Property PROP_DHGEX_SERVER_MAX_KEY
-+ = Property.integer("dhgex-server-max");
-+ /**
-+ * Value used by the {@link org.apache.sshd.server.shell.InvertedShellWrapper} to control the "busy-wait"
-+ * sleep time (millis) on the pumping loop if nothing was pumped - must be positive.
-+ */
-+ public static final Property PUMP_SLEEP_TIME
-+ = Property.duration("inverted-shell-wrapper-pump-sleep", Duration.ofMillis(1));
-+
-+ /**
-+ * Value used by the {@link org.apache.sshd.server.shell.InvertedShellWrapper} to control copy buffer size.
-+ */
-+ public static final Property BUFFER_SIZE
-+ = Property.integer("inverted-shell-wrapper-buffer-size", IoUtils.DEFAULT_COPY_SIZE);
-+
-+ /**
-+ * Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control the channel open
-+ * timeout.
-+ */
-+ public static final Property X11_OPEN_TIMEOUT
-+ = Property.duration("x11-fwd-open-timeout", Duration.ofSeconds(30L));
-+
-+ /**
-+ * Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control from which X11
-+ * display number to start looking for a free value.
-+ */
-+ public static final Property X11_DISPLAY_OFFSET
-+ = Property.integer("x11-fwd-display-offset", 10);
-+
-+ /**
-+ * Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control up to which (but not
-+ * including) X11 display number to look or a free value.
-+ */
-+ public static final Property X11_MAX_DISPLAYS
-+ = Property.integer("x11-fwd-max-display", 1000);
-+
-+ /**
-+ * Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control the base port number
-+ * for the X11 display number socket binding.
-+ */
-+ public static final Property X11_BASE_PORT
-+ = Property.integer("x11-fwd-base-port", 6000);
-+
-+ /**
-+ * Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control the host used to bind
-+ * to for the X11 display when looking for a free port.
-+ */
-+ public static final Property X11_BIND_HOST
-+ = Property.string("x11-fwd-bind-host", SshdSocketAddress.LOCALHOST_IPV4);
-+
-+ private CoreModuleProperties() {
-+ // private
-+ }
-+
-+}
---
-2.27.0
-
diff --git a/CVE-2021-30129-2.patch b/CVE-2021-30129-2.patch
deleted file mode 100644
index 8138582..0000000
--- a/CVE-2021-30129-2.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 5b5bd1dcfa0c2fc250e079e1ebcd643b51f735eb Mon Sep 17 00:00:00 2001
-From: Lyor Goldstein
-Date: Fri, 26 Feb 2021 06:54:43 +0200
-Subject: [PATCH] [SSHD-1125] Added option to require immediate close of
- channel in command ExitCallback invocation
-
----
- .../org/apache/sshd/server/ExitCallback.java | 27 +++++++++++++++++--
- .../sshd/server/channel/ChannelSession.java | 10 +++----
- .../sshd/util/test/BogusExitCallback.java | 12 ++++++---
- .../server/subsystem/sftp/SftpSubsystem.java | 6 +++--
- 4 files changed, 43 insertions(+), 12 deletions(-)
-
-diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java b/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
-index dfa55be..eb1bca1 100644
---- a/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
-+++ b/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
-@@ -30,7 +30,17 @@ public interface ExitCallback {
- * @param exitValue the exit value
- */
- default void onExit(int exitValue) {
-- onExit(exitValue, "");
-+ onExit(exitValue, false);
-+ }
-+
-+ /**
-+ * Informs the SSH server that the shell has exited
-+ *
-+ * @param exitValue the exit value
-+ * @param closeImmediately whether to also terminate the channel immediately or do a graceful close.
-+ */
-+ default void onExit(int exitValue, boolean closeImmediately) {
-+ onExit(exitValue, "", closeImmediately);
- }
-
- /**
-@@ -39,5 +49,18 @@ public interface ExitCallback {
- * @param exitValue the exit value
- * @param exitMessage exit value description
- */
-- void onExit(int exitValue, String exitMessage);
-+ default void onExit(int exitValue, String exitMessage) {
-+ onExit(exitValue, exitMessage, false);
-+ }
-+
-+ /**
-+ *
-+ * Informs the SSH client/server that the shell has exited
-+ *
-+ * @param exitValue the exit value
-+ * @param exitMessage exit value description
-+ * @param closeImmediately whether to also terminate the channel immediately or do a graceful close.
-+ */
-+ void onExit(int exitValue, String exitMessage, boolean closeImmediately);
-+
- }
-diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
-index e54e0e4..484b4f0 100644
---- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
-+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
-@@ -684,9 +684,9 @@ public class ChannelSession extends AbstractServerChannel {
- tempBuffer = null;
- doWriteData(buffer.array(), buffer.rpos(), buffer.available());
- }
-- command.setExitCallback((exitValue, exitMessage) -> {
-+ command.setExitCallback((exitValue, exitMessage, closeImmediately) -> {
- try {
-- closeShell(exitValue);
-+ closeShell(exitValue, closeImmediately);
- if (log.isDebugEnabled()) {
- log.debug("onExit({}) code={} message='{}' shell closed", ChannelSession.this, exitValue, exitMessage);
- }
-@@ -798,9 +798,9 @@ public class ChannelSession extends AbstractServerChannel {
- return env;
- }
-
-- protected void closeShell(int exitValue) throws IOException {
-+ protected void closeShell(int exitValue, boolean closeImmediately) throws IOException {
- if (log.isDebugEnabled()) {
-- log.debug("closeShell({}) exit code={}", this, exitValue);
-+ log.debug("closeShell({}) exit code={}, immediate={}", this, exitValue, closeImmediately);
- }
-
- if (!isClosing()) {
-@@ -810,7 +810,7 @@ public class ChannelSession extends AbstractServerChannel {
- sendEof();
- sendExitStatus(exitValue);
- commandExitFuture.setClosed();
-- close(false);
-+ close(closeImmediately);
- } else {
- commandExitFuture.setClosed();
- }
-diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java
-index a4f1ff6..9de602a 100644
---- a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java
-+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java
-@@ -25,21 +25,23 @@ public class BogusExitCallback implements ExitCallback {
- private boolean exited;
- private int exitValue;
- private String exitMessage;
-+ private boolean closeImmediately;
-
- public BogusExitCallback() {
- super();
- }
-
- @Override
-- public void onExit(int exitValue) {
-- onExit(exitValue, String.valueOf(exitValue));
-+ public void onExit(int exitValue, boolean closeImmediately) {
-+ onExit(exitValue, String.valueOf(exitValue), closeImmediately);
- }
-
- @Override
-- public void onExit(int exitValue, String exitMessage) {
-+ public void onExit(int exitValue, String exitMessage, boolean closeImmediately) {
- this.exited = true;
- this.exitValue = exitValue;
- this.exitMessage = exitMessage;
-+ this.closeImmediately = closeImmediately;
- }
-
- public boolean isExited() {
-@@ -53,4 +55,8 @@ public class BogusExitCallback implements ExitCallback {
- public String getExitMessage() {
- return exitMessage;
- }
-+
-+ public boolean isCloseImmediately() {
-+ return closeImmediately;
-+ }
- }
-diff --git a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
-index 66a0ced..c18b55e 100644
---- a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
-+++ b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
-@@ -299,6 +299,7 @@ public class SftpSubsystem
-
- @Override
- public void run() {
-+ int exitCode = 0;
- try {
- while (true) {
- Buffer buffer = requests.take();
-@@ -318,10 +319,11 @@ public class SftpSubsystem
- if (log.isDebugEnabled()) {
- log.debug("run(" + session + ") caught exception details", t);
- }
-+ exitCode = -1;
- }
- } finally {
- closeAllHandles();
-- callback.onExit(0);
-+ callback.onExit(exitCode, exitCode != 0);
- }
- }
-
---
-2.27.0
-
diff --git a/CVE-2021-30129-3.patch b/CVE-2021-30129-3.patch
deleted file mode 100644
index 722ea2b..0000000
--- a/CVE-2021-30129-3.patch
+++ /dev/null
@@ -1,408 +0,0 @@
-From f9b2f236e6a663011b50bd7e9a41ec90e6b94831 Mon Sep 17 00:00:00 2001
-From: Lyor Goldstein
-Date: Thu, 25 Feb 2021 21:05:49 +0200
-Subject: [PATCH] [SSHD-1125] Added mechanism to throttle pending write
- requests in BufferedIoOutputStream
-
----
- .../channel/BufferedIoOutputStream.java | 187 ++++++++++++++++--
- .../SshChannelBufferedOutputException.java | 41 ++++
- .../sshd/core/CoreModuleProperties.java | 19 ++
- .../sshd/util/test/AsyncEchoShellFactory.java | 13 +-
- .../server/subsystem/sftp/SftpSubsystem.java | 3 +-
- 5 files changed, 243 insertions(+), 20 deletions(-)
- create mode 100644 sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java
-
-diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java
-index 1cb75aa..c95a449 100644
---- a/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java
-+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java
-@@ -20,29 +20,55 @@ package org.apache.sshd.common.channel;
-
- import java.io.EOFException;
- import java.io.IOException;
-+import java.time.Duration;
-+import java.util.Objects;
- import java.util.Queue;
- import java.util.concurrent.ConcurrentLinkedQueue;
-+import java.util.concurrent.atomic.AtomicInteger;
-+import java.util.concurrent.atomic.AtomicLong;
- import java.util.concurrent.atomic.AtomicReference;
-
- import org.apache.sshd.common.Closeable;
-+import org.apache.sshd.common.PropertyResolver;
-+import org.apache.sshd.common.channel.exception.SshChannelBufferedOutputException;
- import org.apache.sshd.common.future.SshFutureListener;
- import org.apache.sshd.common.io.IoOutputStream;
- import org.apache.sshd.common.io.IoWriteFuture;
-+import org.apache.sshd.common.util.GenericUtils;
-+import org.apache.sshd.common.util.ValidateUtils;
- import org.apache.sshd.common.util.buffer.Buffer;
- import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
-+import org.apache.sshd.core.CoreModuleProperties;
-
- /**
- * An {@link IoOutputStream} capable of queuing write requests
- */
- public class BufferedIoOutputStream extends AbstractInnerCloseable implements IoOutputStream {
-+ protected final Object id;
-+ protected final int channelId;
-+ protected final int maxPendingBytesCount;
-+ protected final Duration maxWaitForPendingWrites;
- protected final IoOutputStream out;
-+ protected final AtomicInteger pendingBytesCount = new AtomicInteger();
-+ protected final AtomicLong writtenBytesCount = new AtomicLong();
- protected final Queue writes = new ConcurrentLinkedQueue<>();
- protected final AtomicReference currentWrite = new AtomicReference<>();
-- protected final Object id;
-+ protected final AtomicReference pendingException = new AtomicReference<>();
-
-- public BufferedIoOutputStream(Object id, IoOutputStream out) {
-- this.out = out;
-- this.id = id;
-+ public BufferedIoOutputStream(Object id, int channelId, IoOutputStream out, PropertyResolver resolver) {
-+ this(id, channelId, out, CoreModuleProperties.BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_SIZE.getRequired(resolver),
-+ CoreModuleProperties.BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_WAIT.getRequired(resolver));
-+ }
-+
-+ public BufferedIoOutputStream(
-+ Object id, int channelId, IoOutputStream out, int maxPendingBytesCount,
-+ Duration maxWaitForPendingWrites) {
-+ this.id = Objects.requireNonNull(id, "No stream identifier provided");
-+ this.channelId = channelId;
-+ this.out = Objects.requireNonNull(out, "No delegate output stream provided");
-+ this.maxPendingBytesCount = maxPendingBytesCount;
-+ ValidateUtils.checkTrue(maxPendingBytesCount > 0, "Invalid max. pending bytes count: %d", maxPendingBytesCount);
-+ this.maxWaitForPendingWrites = Objects.requireNonNull(maxWaitForPendingWrites, "No max. pending time value provided");
- }
-
- public Object getId() {
-@@ -52,26 +78,114 @@ public class BufferedIoOutputStream extends AbstractInnerCloseable implements Io
- @Override
- public IoWriteFuture writePacket(Buffer buffer) throws IOException {
- if (isClosing()) {
-- throw new EOFException("Closed");
-+ throw new EOFException("Closed/ing - state=" + state);
- }
-
-+ waitForAvailableWriteSpace(buffer.available());
-+
- IoWriteFutureImpl future = new IoWriteFutureImpl(getId(), buffer);
- writes.add(future);
- startWriting();
- return future;
- }
-
-+ protected void waitForAvailableWriteSpace(int requiredSize) throws IOException {
-+ /*
-+ * NOTE: this code allows a single pending write to give this mechanism "the slip" and
-+ * exit the loop "unscathed" even though there is a pending exception. However, the goal
-+ * here is to avoid an OOM by having an unlimited accumulation of pending write requests
-+ * due to fact that the peer is not consuming the sent data. Please note that the pending
-+ * exception is "sticky" - i.e., the next write attempt will fail. This also means that if
-+ * the write request that "got away" was the last one by chance and it was consumed by the
-+ * peer there will be no exception thrown - which is also fine since as mentioned the goal
-+ * is not to enforce a strict limit on the pending bytes size but rather on the accumulation
-+ * of the pending write requests.
-+ *
-+ * We could have counted pending requests rather than bytes. However, we also want to avoid
-+ * having a large amount of data pending consumption by the peer as well. This code strikes
-+ * such a balance by allowing a single pending request to exceed the limit, but at the same
-+ * time prevents too many bytes from pending by having a bunch of pending requests that while
-+ * below the imposed number limit may cumulatively represent a lot of pending bytes.
-+ */
-+
-+ long expireTime = System.currentTimeMillis() + maxWaitForPendingWrites.toMillis();
-+ synchronized (pendingBytesCount) {
-+ for (int count = pendingBytesCount.get();
-+ /*
-+ * The (count > 0) condition is put in place to allow a single pending
-+ * write to exceed the maxPendingBytesCount as long as there are no
-+ * other pending ones.
-+ */
-+ (count > 0)
-+ // Not already over the limit or about to be over it
-+ && ((count + requiredSize) > maxPendingBytesCount)
-+ // No pending exception signaled
-+ && (pendingException.get() == null);
-+ count = pendingBytesCount.get()) {
-+ long remTime = expireTime - System.currentTimeMillis();
-+ if (remTime <= 0L) {
-+ pendingException.compareAndSet(null,
-+ new SshChannelBufferedOutputException(
-+ channelId,
-+ "Max. pending write timeout expired after " + writtenBytesCount + " bytes"));
-+ throw pendingException.get();
-+ }
-+
-+ try {
-+ pendingBytesCount.wait(remTime);
-+ } catch (InterruptedException e) {
-+ pendingException.compareAndSet(null,
-+ new SshChannelBufferedOutputException(
-+ channelId,
-+ "Waiting for pending writes interrupted after " + writtenBytesCount + " bytes"));
-+ throw pendingException.get();
-+ }
-+ }
-+
-+ IOException e = pendingException.get();
-+ if (e != null) {
-+ throw e;
-+ }
-+
-+ pendingBytesCount.addAndGet(requiredSize);
-+ }
-+ }
-+
- protected void startWriting() throws IOException {
- IoWriteFutureImpl future = writes.peek();
-+ // No more pending requests
- if (future == null) {
- return;
- }
-
-+ // Don't try to write any further if pending exception signaled
-+ Throwable pendingError = pendingException.get();
-+ if (pendingError != null) {
-+ log.error("startWriting({})[{}] propagate to {} write requests pending error={}[{}]",
-+ getId(), out, writes.size(), getClass().getSimpleName(), pendingError.getMessage());
-+
-+ IoWriteFutureImpl currentFuture = currentWrite.getAndSet(null);
-+ for (IoWriteFutureImpl pendingWrite : writes) {
-+ // Checking reference by design
-+ if (GenericUtils.isSameReference(pendingWrite, currentFuture)) {
-+ continue; // will be taken care of when its listener is eventually called
-+ }
-+
-+ future.setValue(pendingError);
-+ }
-+
-+ writes.clear();
-+ return;
-+ }
-+
-+ // Cannot honor this request yet since other pending one incomplete
- if (!currentWrite.compareAndSet(null, future)) {
- return;
- }
-
-- out.writePacket(future.getBuffer()).addListener(new SshFutureListener() {
-+ Buffer buffer = future.getBuffer();
-+ int bufferSize = buffer.available();
-+ out.writePacket(buffer).addListener(new SshFutureListener() {
- @Override
- public void operationComplete(IoWriteFuture f) {
- if (f.isWritten()) {
-@@ -79,32 +193,71 @@ public class BufferedIoOutputStream extends AbstractInnerCloseable implements Io
- } else {
- future.setValue(f.getException());
- }
-- finishWrite();
-+ finishWrite(future, bufferSize);
-+ }
-+ });
-+ }
-+
-+ protected void finishWrite(IoWriteFutureImpl future, int bufferSize) {
-+ /*
-+ * Update the pending bytes count only if successfully written,
-+ * otherwise signal an error
-+ */
-+ if (future.isWritten()) {
-+ long writtenSize = writtenBytesCount.addAndGet(bufferSize);
-+ int stillPending;
-+ synchronized (pendingBytesCount) {
-+ stillPending = pendingBytesCount.addAndGet(0 - bufferSize);
-+ pendingBytesCount.notifyAll();
- }
-
-- @SuppressWarnings("synthetic-access")
-- private void finishWrite() {
-+ /*
-+ * NOTE: since the pending exception is updated outside the synchronized block
-+ * a pending write could be successfully enqueued, however this is acceptable
-+ * - see comment in waitForAvailableWriteSpace
-+ */
-+ if (stillPending < 0) {
-+ log.error("finishWrite({})[{}] - pending byte counts underflow ({}) after {} bytes", getId(), out, stillPending,
-+ writtenSize);
-+ pendingException.compareAndSet(null,
-+ new SshChannelBufferedOutputException(channelId, "Pending byte counts underflow"));
-+ }
-+ } else {
-+ Throwable t = future.getException();
-+ if (t instanceof SshChannelBufferedOutputException) {
-+ pendingException.compareAndSet(null, (SshChannelBufferedOutputException) t);
-+ } else {
-+ pendingException.compareAndSet(null, new SshChannelBufferedOutputException(channelId, t));
-+ }
-+
-+ // In case someone waiting so that they can detect the exception
-+ synchronized (pendingBytesCount) {
-+ pendingBytesCount.notifyAll();
-+ }
-+ }
-+
- writes.remove(future);
- currentWrite.compareAndSet(future, null);
- try {
- startWriting();
- } catch (IOException e) {
-- log.error("finishWrite({}) failed ({}) re-start writing", out, e.getClass().getSimpleName());
-+ if (e instanceof SshChannelBufferedOutputException) {
-+ pendingException.compareAndSet(null, (SshChannelBufferedOutputException) e);
-+ } else {
-+ pendingException.compareAndSet(null, new SshChannelBufferedOutputException(channelId, e));
-+ }
-+ log.error("finishWrite({})[{}] failed ({}) re-start writing: {}",
-+ getId(), out, e.getClass().getSimpleName(), e.getMessage(), e);
- }
- }
-- });
-- }
-
- @Override
- protected Closeable getInnerCloseable() {
-- return builder()
-- .when(getId(), writes)
-- .close(out)
-- .build();
-+ return builder().when(getId(), writes).close(out).build();
- }
-
- @Override
- public String toString() {
-- return getClass().getSimpleName() + "[" + out + "]";
-+ return getClass().getSimpleName() + "(" + getId() + ")[" + out + "]";
- }
- }
-diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java
-new file mode 100644
-index 0000000..97e6105
---- /dev/null
-+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java
-@@ -0,0 +1,41 @@
-+/*
-+ * Licensed to the Apache Software Foundation (ASF) under one
-+ * or more contributor license agreements. See the NOTICE file
-+ * distributed with this work for additional information
-+ * regarding copyright ownership. The ASF licenses this file
-+ * to you under the Apache License, Version 2.0 (the
-+ * "License"); you may not use this file except in compliance
-+ * with the License. You may obtain a copy of the License at
-+ *
-+ * http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ * Unless required by applicable law or agreed to in writing,
-+ * software distributed under the License is distributed on an
-+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-+ * KIND, either express or implied. See the License for the
-+ * specific language governing permissions and limitations
-+ * under the License.
-+ */
-+
-+package org.apache.sshd.common.channel.exception;
-+
-+/**
-+ * Used by the {@code BufferedIoOutputStream} to signal a non-recoverable error
-+ *
-+ * @author Apache MINA SSHD Project
-+ */
-+public class SshChannelBufferedOutputException extends SshChannelException {
-+ private static final long serialVersionUID = -8663890657820958046L;
-+
-+ public SshChannelBufferedOutputException(int channelId, String message) {
-+ this(channelId, message, null);
-+ }
-+
-+ public SshChannelBufferedOutputException(int channelId, Throwable cause) {
-+ this(channelId, cause.getMessage(), cause);
-+ }
-+
-+ public SshChannelBufferedOutputException(int channelId, String message, Throwable cause) {
-+ super(channelId, message, cause);
-+ }
-+}
-diff --git a/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java b/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
-index 9e9b2d2..0d122e5 100644
---- a/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
-+++ b/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
-@@ -24,6 +24,7 @@ import java.time.Duration;
-
- import org.apache.sshd.client.config.keys.ClientIdentityLoader;
- import org.apache.sshd.common.Property;
-+import org.apache.sshd.common.SshConstants;
- import org.apache.sshd.common.channel.Channel;
- import org.apache.sshd.common.session.Session;
- import org.apache.sshd.common.util.OsUtils;
-@@ -240,6 +241,24 @@ public final class CoreModuleProperties {
- public static final Property WINDOW_TIMEOUT
- = Property.duration("window-timeout", Duration.ZERO);
-
-+ /**
-+ * Key used when creating a {@code BufferedIoOutputStream} in order to specify max. allowed unwritten pending bytes.
-+ * If this value is exceeded then the code waits up to {@link #BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_WAIT} for the
-+ * pending data to be written and thus make room for the new request.
-+ */
-+ public static final Property BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_SIZE
-+ = Property.integer("buffered-io-output-max-pending-write-size",
-+ SshConstants.SSH_REQUIRED_PAYLOAD_PACKET_LENGTH_SUPPORT * 8);
-+
-+ /**
-+ * Key used when creating a {@code BufferedIoOutputStream} in order to specify max. wait time (msec.) for pending
-+ * writes to be completed before enqueuing a new request
-+ *
-+ * @see #BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_SIZE
-+ */
-+ public static final Property BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_WAIT
-+ = Property.duration("buffered-io-output-max-pending-write-wait", Duration.ofSeconds(30L));
-+
- /**
- * Key used to retrieve the value of the maximum packet size in the configuration properties map.
- */
-diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
-index de9dbf4..465ff83 100644
---- a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
-+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
-@@ -99,12 +99,21 @@ public class AsyncEchoShellFactory implements ShellFactory {
-
- @Override
- public void setIoOutputStream(IoOutputStream out) {
-- this.out = new BufferedIoOutputStream("STDOUT", out);
-+ this.out = wrapOutputStream("SHELL-STDOUT", out);
- }
-
- @Override
- public void setIoErrorStream(IoOutputStream err) {
-- this.err = new BufferedIoOutputStream("STDERR", err);
-+ this.err = wrapOutputStream("SHELL-STDERR", err);
-+ }
-+
-+ protected BufferedIoOutputStream wrapOutputStream(String prefix, IoOutputStream stream) {
-+ if (stream instanceof BufferedIoOutputStream) {
-+ return (BufferedIoOutputStream) stream;
-+ }
-+
-+ int channelId = session.getId();
-+ return new BufferedIoOutputStream(prefix + "@" + channelId, channelId, stream, session);
- }
-
- @Override
-diff --git a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
-index 66a0ced..15201ec 100644
---- a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
-+++ b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
-@@ -256,7 +256,8 @@ public class SftpSubsystem
-
- @Override
- public void setIoOutputStream(IoOutputStream out) {
-- this.out = new BufferedIoOutputStream("sftp out buffer", out);
-+ int channelId = channelSession.getId();
-+ this.out = new BufferedIoOutputStream("sftp-out@" + channelId, channelId, out, channelSession);
- }
-
- @Override
---
-2.27.0
-
diff --git a/apache-sshd-2.2.0-src.tar.gz b/apache-sshd-2.2.0-src.tar.gz
deleted file mode 100644
index d4fe2cf..0000000
Binary files a/apache-sshd-2.2.0-src.tar.gz and /dev/null differ
diff --git a/apache-sshd-2.9.2-src.tar.gz b/apache-sshd-2.9.2-src.tar.gz
new file mode 100644
index 0000000..ef94ea5
Binary files /dev/null and b/apache-sshd-2.9.2-src.tar.gz differ
diff --git a/apache-sshd-javadoc.patch b/apache-sshd-javadoc.patch
new file mode 100644
index 0000000..b676699
--- /dev/null
+++ b/apache-sshd-javadoc.patch
@@ -0,0 +1,241 @@
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java 2022-11-16 09:50:02.519293210 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java 2022-11-16 10:29:30.819501234 +0100
+@@ -36,7 +36,7 @@
+ public interface PasswordIdentityProvider {
+
+ /**
+- * An "empty" implementation of {@link PasswordIdentityProvider} that returns an empty group of passwords
++ * An "empty" implementation of {@link PasswordIdentityProvider} that returns an empty group of passwords
+ */
+ PasswordIdentityProvider EMPTY_PASSWORDS_PROVIDER = new PasswordIdentityProvider() {
+ @Override
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java 2022-11-16 09:50:02.523293237 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java 2022-11-16 10:21:06.704044979 +0100
+@@ -754,7 +754,7 @@
+ * @param expected The expected fingerprint if {@code null} or empty then returns a failure with the default
+ * fingerprint.
+ * @param key the {@link PublicKey} - if {@code null} then returns null.
+- * @return SimpleImmutableEntry - key is success indicator, value is actual fingerprint,
++ * @return SimpleImmutableEntry<Boolean, String> - key is success indicator, value is actual fingerprint,
+ * {@code null} if no key.
+ * @see #getDefaultFingerPrintFactory()
+ * @see #checkFingerPrint(String, Factory, PublicKey)
+@@ -768,7 +768,7 @@
+ * fingerprint.
+ * @param f The {@link Factory} to be used to generate the default {@link Digest} for the key
+ * @param key the {@link PublicKey} - if {@code null} then returns null.
+- * @return SimpleImmutableEntry - key is success indicator, value is actual fingerprint,
++ * @return SimpleImmutableEntry<Boolean, String> - key is success indicator, value is actual fingerprint,
+ * {@code null} if no key.
+ */
+ public static SimpleImmutableEntry checkFingerPrint(
+@@ -781,7 +781,7 @@
+ * fingerprint.
+ * @param d The {@link Digest} to be used to generate the default fingerprint for the key
+ * @param key the {@link PublicKey} - if {@code null} then returns null.
+- * @return SimpleImmutableEntry - key is success indicator, value is actual fingerprint,
++ * @return SimpleImmutableEntry<Boolean, String> - key is success indicator, value is actual fingerprint,
+ * {@code null} if no key.
+ */
+ public static SimpleImmutableEntry checkFingerPrint(String expected, Digest d, PublicKey key) {
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java 2022-11-16 09:50:02.523293237 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java 2022-11-16 10:27:11.094543153 +0100
+@@ -63,9 +63,7 @@
+ import org.apache.sshd.common.util.security.SecurityUtils;
+
+ /**
+- * Basic support for OpenSSH
+- * key file(s)
++ * Basic support for OpenSSH key file(s)
+ *
+ * @author Apache MINA SSHD Project
+ */
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java 2022-11-16 09:50:02.531293291 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java 2022-11-16 10:07:03.290271908 +0100
+@@ -64,13 +64,13 @@
+ SkED25519BufferPublicKeyParser.INSTANCE));
+
+ /**
+- * @param keyType The key type - e.g., "ssh-rsa", "ssh-dss"
++ * @param keyType The key type - e.g., "ssh-rsa", "ssh-dss"
+ * @return {@code true} if this key type is supported by the parser
+ */
+ boolean isKeyTypeSupported(String keyType);
+
+ /**
+- * @param keyType The key type - e.g., "ssh-rsa", "ssh-dss"
++ * @param keyType The key type - e.g., "ssh-rsa", "ssh-dss"
+ * @param buffer The {@link Buffer} containing the encoded raw public key
+ * @return The decoded {@link PublicKey}
+ * @throws GeneralSecurityException If failed to generate the key
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/GenericUtils.java 2022-11-16 09:50:02.527293266 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/GenericUtils.java 2022-11-16 10:17:14.006452121 +0100
+@@ -112,10 +112,11 @@
+ * @param with String to replace with
+ * @param max maximum number of values to replace, or -1 if no maximum
+ * @return the text with any replacements processed
+- * @author Arnout J. Kuiper ajkuiper@wxs.nl
+- * @author Magesh Umasankar
+- * @author Bruce Atherton
+- * @author Antoine Levy-Lambert
++ *
++ * author Arnout J. Kuiper ajkuiper@wxs.nl
++ * author Magesh Umasankar
++ * author Bruce Atherton
++ * author Antoine Levy-Lambert
+ */
+ @SuppressWarnings("PMD.AssignmentInOperand")
+ public static String replace(String text, String repl, String with, int max) {
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/io/der/DERWriter.java 2022-11-16 09:50:02.531293291 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/io/der/DERWriter.java 2022-11-16 10:09:10.435142161 +0100
+@@ -76,7 +76,7 @@
+ }
+
+ /**
+- * The integer is always considered to be positive, so if the first byte is < 0, we pad with a zero to make it
++ * The integer is always considered to be positive, so if the first byte is < 0, we pad with a zero to make it
+ * positive
+ *
+ * @param bytes {@link BigInteger} bytes
+@@ -87,7 +87,7 @@
+ }
+
+ /**
+- * The integer is always considered to be positive, so if the first byte is < 0, we pad with a zero to make it
++ * The integer is always considered to be positive, so if the first byte is < 0, we pad with a zero to make it
+ * positive
+ *
+ * @param bytes {@link BigInteger} bytes
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/OsUtils.java 2022-11-16 09:50:02.527293266 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/OsUtils.java 2022-11-16 10:28:23.527039819 +0100
+@@ -165,7 +165,7 @@
+ }
+
+ /**
+- * Remove {@code Windows} domain and/or group prefix as well as "(User);" suffix
++ * Remove {@code Windows} domain and/or group prefix as well as "(User);" suffix
+ *
+ * @param user The original username - ignored if {@code null}/empty
+ * @return The canonical user - unchanged if {@code Unix} O/S
+--- apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java 2022-11-16 09:50:02.535293319 +0100
++++ apache-sshd-2.9.2/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java 2022-11-16 10:31:13.564205742 +0100
+@@ -119,7 +119,7 @@
+ /**
+ * The min. key size value used for testing whether Diffie-Hellman Group Exchange is supported or not. According to
+ * RFC 4419 section 3: "Servers and clients SHOULD support
+- * groups with a modulus length of k bits, where 1024 <= k <= 8192".
++ * groups with a modulus length of k bits, where 1024 <= k <= 8192".
+ *
+ * Note: this has been amended by RFC 8270
+ */
+--- apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/client/session/ClientProxyConnector.java 2022-11-16 09:50:02.571293565 +0100
++++ apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/client/session/ClientProxyConnector.java 2022-11-16 10:28:51.175229400 +0100
+@@ -23,8 +23,8 @@
+
+ /**
+ * Provides a way to implement proxied connections where some metadata about the client is sent before the actual
+- * SSH protocol is executed - e.g., the PROXY
+- * protocol. The implementor should use the {@code IoSession#write(Buffer)} method to send any packets with the
++ * SSH protocol is executed - e.g., the PROXY protocol.
++ * The implementor should use the {@code IoSession#write(Buffer)} method to send any packets with the
+ * meta-data.
+ *
+ * @author Apache MINA SSHD Project
+--- apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java 2022-11-16 09:50:02.575293593 +0100
++++ apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java 2022-11-16 10:04:31.529233186 +0100
+@@ -67,7 +67,7 @@
+
+ /**
+ * The default {@link BuiltinCiphers} setup in order of preference as specified by
+- * ssh_config(5)
++ * ssh_config(5)
+ */
+ public static final List DEFAULT_CIPHERS_PREFERENCE = Collections.unmodifiableList(
+ Arrays.asList(
+@@ -83,7 +83,7 @@
+
+ /**
+ * The default {@link BuiltinDHFactories} setup in order of preference as specified by
+- * ssh_config(5)
++ * ssh_config(5)
+ */
+ public static final List DEFAULT_KEX_PREFERENCE = Collections.unmodifiableList(
+ Arrays.asList(
+@@ -104,7 +104,7 @@
+
+ /**
+ * The default {@link BuiltinMacs} setup in order of preference as specified by
+- * ssh_config(5)
++ * ssh_config(5)
+ */
+ public static final List DEFAULT_MAC_PREFERENCE = Collections.unmodifiableList(
+ Arrays.asList(
+--- apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/channel/LocalWindow.java 2022-11-16 09:50:02.575293593 +0100
++++ apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/channel/LocalWindow.java 2022-11-16 10:22:11.968492069 +0100
+@@ -51,8 +51,6 @@
+ /**
+ * Initializes the {@link LocalWindow} with the packet and window sizes from the {@code resolver}.
+ *
+- * @param size the initial window size
+- * @param packetSize the peer's advertised maximum packet size
+ * @param resolver {@PropertyResolver} to access properties
+ */
+ public void init(PropertyResolver resolver) {
+--- apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/KeyExchangeMessageHandler.java 2022-11-16 09:50:02.579293619 +0100
++++ apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/KeyExchangeMessageHandler.java 2022-11-16 10:49:31.567743605 +0100
+@@ -46,7 +46,7 @@
+ /**
+ * Manages SSH message sending during a key exchange. RFC 4253 specifies that during a key exchange, no high-level
+ * messages are to be sent, but a receiver must be able to deal with messages "in flight" until the peer's
+- * {@link SshConstants#SSH_MSG_KEX_INIT} message is received.
++ * {@link SshConstants#SSH_MSG_KEXINIT} message is received.
+ *
+ * Apache MINA sshd queues up high-level messages that threads try to send while a key exchange is ongoing, and sends
+ * them once the key exchange is done. Sending queued messages may make the peer re-trigger a new key exchange, in which
+@@ -154,7 +154,7 @@
+ }
+
+ /**
+- * Initializes the state for a new key exchange. {@link #allPacketsFlushed()} will be {@code false}, and a new
++ * Initializes the state for a new key exchange. kexFlushed will be {@code false}, and a new
+ * future to be fulfilled when all queued packets will be flushed once the key exchange is done is set. The
+ * currently set future from an earlier key exchange is returned. The returned future may or may not be fulfilled;
+ * if it isn't, there are still left-over pending packets to write from the previous key exchange, which will be
+@@ -406,7 +406,7 @@
+ * exchange, flushing is stopped and is to be resumed by another call to this method when the new key exchange is
+ * done.
+ *
+- * @param flushDone the future obtained from {@link #getFlushedFuture()}; will be fulfilled once all pending packets
++ * @param flushDone the future obtained from {@link #terminateKeyExchange()}; will be fulfilled once all pending packets
+ * have been written
+ */
+ protected void flushQueue(DefaultKeyExchangeFuture flushDone) {
+--- apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java 2022-11-16 09:50:02.579293619 +0100
++++ apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java 2022-11-16 10:02:05.032231651 +0100
+@@ -224,11 +224,11 @@
+ * {@link Buffer} to the given {@link ReplyHandler}, which may execute in a different thread.
+ *
+ *
+- *
want-reply == true && replyHandler != null
++ *
want-reply == true && replyHandler != null
+ *
The returned future is fulfilled with {@code null} when the request was sent, or with an exception if the
+ * request could not be sent. The {@code replyHandler} is invoked once the reply is received, with the SSH reply
+ * code and the data received.
+- *
want-reply == true && replyHandler == null
++ *
want-reply == true && replyHandler == null
+ *
The returned future is fulfilled with an exception if the request could not be sent, or a failure reply was
+ * received. If a success reply was received, the future is fulfilled with the received data buffer.
+ *
want-reply == false
+--- apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/server/session/ServerProxyAcceptor.java 2022-11-16 09:50:02.583293646 +0100
++++ apache-sshd-2.9.2/sshd-core/src/main/java/org/apache/sshd/server/session/ServerProxyAcceptor.java 2022-11-16 10:33:44.345239622 +0100
+@@ -23,8 +23,7 @@
+
+ /**
+ * Provides a way to implement proxied connections where some metadata about the client is sent before the actual
+- * SSH protocol is executed - e.g., the PROXY
+- * protocol.
++ * SSH protocol is executed - e.g., the PROXY protocol.
+ *
+ * @author Apache MINA SSHD Project
+ */
diff --git a/apache-sshd.spec b/apache-sshd.spec
index 235d0a6..1dc32a2 100644
--- a/apache-sshd.spec
+++ b/apache-sshd.spec
@@ -1,15 +1,13 @@
Epoch: 1
Name: apache-sshd
-Version: 2.2.0
-Release: 2
+Version: 2.9.2
+Release: 1
Summary: Apache SSHD
License: ASL 2.0 and ISC
URL: http://mina.apache.org/sshd-project
Source0: https://archive.apache.org/dist/mina/sshd/%{version}/apache-sshd-%{version}-src.tar.gz
Patch0: 0001-Avoid-optional-dependency-on-native-tomcat-APR-libra.patch
-Patch1: CVE-2021-30129-1.patch
-Patch2: CVE-2021-30129-2.patch
-Patch3: CVE-2021-30129-3.patch
+Patch1: apache-sshd-javadoc.patch
BuildRequires: maven-local mvn(junit:junit) mvn(net.i2p.crypto:eddsa) mvn(org.apache.ant:ant)
BuildRequires: mvn(org.apache:apache:pom:) mvn(org.apache.felix:maven-bundle-plugin)
@@ -22,6 +20,7 @@ BuildRequires: mvn(org.apache.maven.surefire:surefire-junit47)
BuildRequires: mvn(org.bouncycastle:bcpg-jdk15on) mvn(org.bouncycastle:bcpkix-jdk15on)
BuildRequires: mvn(org.codehaus.mojo:build-helper-maven-plugin)
BuildRequires: mvn(org.codehaus.plexus:plexus-archiver) mvn(org.slf4j:slf4j-api)
+BuildRequires: mvn(org.slf4j:jcl-over-slf4j)
BuildArch: noarch
%description
Apache SSHD is a 100% pure java library to support the SSH protocols on both
@@ -36,10 +35,9 @@ This package provides %{name}.
%setup -q
%patch0 -p1
%patch1 -p1
-%patch2 -p1
-%patch3 -p1
rm -rf sshd-core/src/main/java/org/apache/sshd/agent/unix
%pom_remove_dep :spring-framework-bom
+%pom_remove_dep :testcontainers-bom sshd-sftp sshd-core
%pom_disable_module assembly
%pom_disable_module sshd-mina
%pom_disable_module sshd-netty
@@ -50,11 +48,13 @@ rm -rf sshd-core/src/main/java/org/apache/sshd/agent/unix
%pom_disable_module sshd-cli
%pom_disable_module sshd-openpgp
%pom_remove_plugin :apache-rat-plugin
-%pom_remove_plugin :groovy-maven-plugin
+%pom_remove_plugin :gmavenplus-plugin
%pom_remove_plugin :maven-checkstyle-plugin
%pom_remove_plugin :maven-enforcer-plugin
%pom_remove_plugin :maven-pmd-plugin
%pom_remove_plugin :animal-sniffer-maven-plugin
+%pom_remove_plugin :impsort-maven-plugin
+%pom_remove_plugin :formatter-maven-plugin . sshd-core
%pom_xpath_inject "pom:configuration/pom:instructions" "<_nouses>true" .
%build
@@ -71,6 +71,9 @@ rm -rf sshd-core/src/main/java/org/apache/sshd/agent/unix
%license LICENSE.txt NOTICE.txt assembly/src/main/legal/licenses/jbcrypt.txt
%changelog
+* Mon Nov 21 2022 liangqifeng - 1:2.9.2-1
+- Fix CVE-2022-45047
+
* Tue Aug 10 2021 yaoxin - 2.2.0-2
- Fix CVE-2021-30129