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 <lgoldst...@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-ren...@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)) {

Reply via email to