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 88aa3129b2336e0bfb9156cc4b71bd2bfc1196b4
Author: Lyor Goldstein <lgoldst...@apache.org>
AuthorDate: Fri Feb 26 10:53:05 2021 +0200

    [SSHD-1133] Added capability to specify a custom charset for returning 
environment variables related data from the ScpShell
---
 CHANGES.md                                                  |  3 ++-
 docs/scp.md                                                 |  2 ++
 .../main/java/org/apache/sshd/scp/ScpModuleProperties.java  |  7 +++++++
 .../src/main/java/org/apache/sshd/scp/server/ScpShell.java  | 13 +++++++++----
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 6de775d..df0eb3e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -45,4 +45,5 @@
 * [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
+* [SSHD-1133](https://issues.apache.org/jira/browse/SSHD-1133) Added 
capability to specify a custom charset for parsing incoming commands to the 
`ScpShell`
+* [SSHD-1133](https://issues.apache.org/jira/browse/SSHD-1133) Added 
capability to specify a custom charset for returning environment variables 
related data from the `ScpShell`
\ No newline at end of file
diff --git a/docs/scp.md b/docs/scp.md
index 06364c1..96274b8 100644
--- a/docs/scp.md
+++ b/docs/scp.md
@@ -204,6 +204,8 @@ ScpModuleProperties.SHELL_NAME_DECODING_CHARSET.set(sshd, 
Charset.forName("US-AS
 
 **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.
 
+A similar behavior is controlled via `SHELL_ENVVARS_ENCODING_CHARSET` which 
controls responses from the `ScpShell` regarding environment variables - the 
main difference being that the default is US-ASCII rather than UTF-8.
+
 ## 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 4bdae9a..9f19e02 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
@@ -60,6 +60,13 @@ public final class ScpModuleProperties {
             = Property.charset("scp-shell-name-encoding-charset", 
StandardCharsets.UTF_8);
 
     /**
+     * Used to indicate the {@link Charset} (or its name) for handling 
environment values in {@code ScpShell} -
+     * extracted from the channel session when shell initialized.
+     */
+    public static final Property<Charset> SHELL_ENVVARS_ENCODING_CHARSET
+            = Property.charset("scp-shell-envvars-encoding-charset", 
StandardCharsets.US_ASCII);
+
+    /**
      * 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.
      */
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 af31fbc..df4d433 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
@@ -90,6 +90,7 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
 
     protected final Map<String, Object> variables = new HashMap<>();
     protected final Charset nameEncodingCharset;
+    protected final Charset envVarsEnodingCharset;
 
     protected final ScpFileOpener opener;
     protected final ScpTransferEventListener listener;
@@ -107,6 +108,7 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
         this.channelSession = Objects.requireNonNull(channelSession, "No 
channel session provided");
 
         nameEncodingCharset = 
ScpModuleProperties.SHELL_NAME_ENCODING_CHARSET.getRequired(channelSession);
+        envVarsEnodingCharset = 
ScpModuleProperties.SHELL_ENVVARS_ENCODING_CHARSET.getRequired(channelSession);
 
         if (sendSize < ScpHelper.MIN_SEND_BUFFER_SIZE) {
             throw new IllegalArgumentException(
@@ -155,7 +157,7 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
     }
 
     protected void signalError(String cmd, String errorMsg) {
-        signalError(cmd, errorMsg, StandardCharsets.US_ASCII);
+        signalError(cmd, errorMsg, envVarsEnodingCharset);
     }
 
     protected void signalError(String cmd, String errorMsg, Charset cs) {
@@ -217,6 +219,7 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
             log.warn("run({}) {}", channel, message);
             try {
                 OutputStream stderr = getErrorStream();
+                // Don't encode it with any user defined charset
                 stderr.write(message.getBytes(StandardCharsets.US_ASCII));
             } catch (IOException ioe) {
                 log.warn("run({}) Failed ({}) to write error message={}: {}",
@@ -311,7 +314,9 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
     protected void handleUnsupportedCommand(String command, String[] argv) 
throws Exception {
         log.warn("handleUnsupportedCommand({}) unsupported: {}", 
getServerChannelSession(), command);
         variables.put(STATUS, 127);
-        getErrorStream().write(("command not found: " + argv[0] + 
"\n").getBytes(StandardCharsets.US_ASCII));
+        OutputStream errorStream = getErrorStream();
+        // Don't encode it with any user defined charset
+        errorStream.write(("command not found: " + argv[0] + 
"\n").getBytes(StandardCharsets.US_ASCII));
     }
 
     protected List<String[]> parse(String command) {
@@ -366,7 +371,7 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
         if (argv.length == 1) {
             envValues.entrySet()
                     .stream()
-                    .forEach(e -> println(argv[0], e.getKey() + "=" + 
e.getValue(), stdout, StandardCharsets.US_ASCII));
+                    .forEach(e -> println(argv[0], e.getKey() + "=" + 
e.getValue(), stdout, envVarsEnodingCharset));
             variables.put(STATUS, 0);
             return;
         }
@@ -387,7 +392,7 @@ public class ScpShell extends AbstractFileSystemCommand 
implements ServerChannel
             log.debug("printenv({}) {}={}", getServerChannelSession(), 
varName, varValue);
         }
 
-        println(argv[0], varValue, stdout, StandardCharsets.US_ASCII);
+        println(argv[0], varValue, stdout, envVarsEnodingCharset);
         variables.put(STATUS, 0);
     }
 

Reply via email to