You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2021/03/05 09:26:12 UTC

[mina-sshd] 02/07: [SSHD-1133] Added capability to specify a custom charset for parsing incoming commands to the ScpShell

This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 0dc159ab3bbac86ccd99a370c87518b9ea98866b
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Fri Feb 26 10:44:31 2021 +0200

    [SSHD-1133] Added capability to specify a custom charset for parsing incoming commands to the ScpShell
---
 CHANGES.md                                                  |  3 +++
 docs/scp.md                                                 | 13 +++++++++++++
 .../main/java/org/apache/sshd/scp/ScpModuleProperties.java  | 13 ++++++++++---
 .../src/main/java/org/apache/sshd/scp/server/ScpShell.java  |  5 +++--
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 6e44df8..6de775d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -16,6 +16,8 @@
 
 * [SSHD-1133](https://issues.apache.org/jira/browse/SSHD-1133) Re-factored locations and names of `ServerSession` and server-side `ChannelSession` related classes
 
+## Potential compatibility issues
+
 ## Minor code helpers
 
 * [SSHD-525](https://issues.apache.org/jira/browse/SSHD-525) Added support for SFTP **client-side** ["posix-rename@openssh.com"
@@ -43,3 +45,4 @@
 * [SSHD-1114](https://issues.apache.org/jira/browse/SSHD-1114) Added capability for interactive key based authentication participation via UserInteraction
 * [SSHD-1125](https://issues.apache.org/jira/browse/SSHD-1125) Added mechanism to throttle pending write requests in BufferedIoOutputStream
 * [SSHD-1127](https://issues.apache.org/jira/browse/SSHD-1127) Added capability to register a custom receiver for SFTP STDERR channel raw or stream data
+* [SSHD-1133](https://issues.apache.org/jira/browse/SSHD-1133) Added capability to specify a custom charset for parsing incoming commands to the `ScpShell`
\ No newline at end of file
diff --git a/docs/scp.md b/docs/scp.md
index d7274b1..06364c1 100644
--- a/docs/scp.md
+++ b/docs/scp.md
@@ -191,6 +191,19 @@ sshd.setShellFactory(factory);
 
 **Note:** a similar result can be achieved if activating SSHD from the command line by specifying `-o ShellFactory=scp`
 
+### Text encoding/decoding
+
+The SCP "shell" is text-based and therefore subject to character encoding/decoding of the data being exchanged. By default, the exchange is supposed to use the UTF-8 encoding which is the default/standard one for SSH. However, there are clients/servers "in the wild" that do not conform to this convention. For this purpose, it is possible to define a different  character encoding via the `SHELL_NAME_EN/DECODING_CHARSET` properties - e.g.:
+
+```java
+SshServer sshd = ...setup server...
+// Can also use the character name string rather than the object instance itself
+ScpModuleProperties.SHELL_NAME_ENCODING_CHARSET.set(sshd, Charset.forName("US-ASCII"));
+ScpModuleProperties.SHELL_NAME_DECODING_CHARSET.set(sshd, Charset.forName("US-ASCII"));
+```
+
+**Caveat emptor:** that the code does not enforce "symmetry" of the chosen character sets - in other words, user can either by design or error cause different encoding to be used for the incoming commands vs. the outgoing responses. It is important to bear in mind that if the text to be encoded/decoded contains characters that cannot be  safely handled by the chosen encoder/decoder than the result might not be correctly parsed/understood by the peer.
+
 ## Remote-to-remote transfer
 
 The code provides an `ScpTransferHelper` class that enables copying files between 2 remote accounts without going through
diff --git a/sshd-scp/src/main/java/org/apache/sshd/scp/ScpModuleProperties.java b/sshd-scp/src/main/java/org/apache/sshd/scp/ScpModuleProperties.java
index 4821f34..4bdae9a 100644
--- a/sshd-scp/src/main/java/org/apache/sshd/scp/ScpModuleProperties.java
+++ b/sshd-scp/src/main/java/org/apache/sshd/scp/ScpModuleProperties.java
@@ -53,12 +53,19 @@ public final class ScpModuleProperties {
             = Property.bool("scp-auto-sync-on-write", true);
 
     /**
-     * Used to indicate the {@link Charset} (or its name) for encoding referenced files/folders names - extracted from
-     * the client channel session when 1st initialized.
+     * Used to indicate the {@link Charset} (or its name) for encoding returned textual responses from the
+     * {@code ScpShell} - extracted from the channel session when shell initialized.
      */
-    public static final Property<Charset> NAME_ENCODING_CHARSET
+    public static final Property<Charset> SHELL_NAME_ENCODING_CHARSET
             = Property.charset("scp-shell-name-encoding-charset", StandardCharsets.UTF_8);
 
+    /**
+     * Used to indicate the {@link Charset} (or its name) for decoding incoming commands to be processed by the
+     * {@code ScpShell} - extracted from the channel session when shell initialized.
+     */
+    public static final Property<Charset> SHELL_NAME_DECODING_CHARSET
+            = Property.charset("scp-shell-name-decoding-charset", StandardCharsets.UTF_8);
+
     private ScpModuleProperties() {
         throw new UnsupportedOperationException("No instance");
     }
diff --git a/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java b/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java
index ca413be..af31fbc 100644
--- a/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java
+++ b/sshd-scp/src/main/java/org/apache/sshd/scp/server/ScpShell.java
@@ -106,7 +106,7 @@ public class ScpShell extends AbstractFileSystemCommand implements ServerChannel
         super(null, executorService);
         this.channelSession = Objects.requireNonNull(channelSession, "No channel session provided");
 
-        nameEncodingCharset = ScpModuleProperties.NAME_ENCODING_CHARSET.getRequired(channelSession);
+        nameEncodingCharset = ScpModuleProperties.SHELL_NAME_ENCODING_CHARSET.getRequired(channelSession);
 
         if (sendSize < ScpHelper.MIN_SEND_BUFFER_SIZE) {
             throw new IllegalArgumentException(
@@ -185,9 +185,10 @@ public class ScpShell extends AbstractFileSystemCommand implements ServerChannel
 
             prepareEnvironment(getEnvironment());
 
+            Charset decodingCharset = ScpModuleProperties.SHELL_NAME_DECODING_CHARSET.getRequired(channel);
             // Use a special stream reader so that the stream can be used with the scp command
             try (InputStream inputStream = getInputStream();
-                 Reader r = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
+                 Reader r = new InputStreamReader(inputStream, decodingCharset)) {
                 for (int executedCommands = 0;; executedCommands++) {
                     command = readLine(r);
                     if (GenericUtils.isEmpty(command)) {