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 c52e1c4d980e8ee98452945641a9bb2bc70a51cd Author: Lyor Goldstein <lgoldst...@apache.org> AuthorDate: Mon Aug 17 11:20:57 2020 +0300 [SSHD-1005] Added ScpTransferEventListener if verbose level in SshServerCliSupport setup --- .../sshd/cli/server/SshServerCliSupport.java | 14 +++- .../org/apache/sshd/cli/server/SshServerMain.java | 17 +++-- .../helper/ScpCommandTransferEventListener.java | 77 ++++++++++++++++++++++ .../org/apache/sshd/cli/server/SshFsMounter.java | 7 +- 4 files changed, 104 insertions(+), 11 deletions(-) diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java index c173cb7..d731231 100644 --- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java @@ -38,6 +38,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.sshd.cli.CliSupport; +import org.apache.sshd.cli.server.helper.ScpCommandTransferEventListener; import org.apache.sshd.cli.server.helper.ServerPortForwardingEventListener; import org.apache.sshd.cli.server.helper.SftpServerSubSystemEventListener; import org.apache.sshd.common.PropertyResolver; @@ -254,12 +255,16 @@ public abstract class SshServerCliSupport extends CliSupport { * to load and instantiate it using a public no-args constructor</LI> * </UL> * + * @param level The verbosity {@link Level} + * @param stdout The STDOUT stream for logging * @param stderr The STDERR stream for errors * @param options The available options - assuming defaults if {@code null} * @return The resolved {@link ShellFactory} * @throws Exception If failed to resolve */ - public static ShellFactory resolveShellFactory(PrintStream stderr, PropertyResolver options) throws Exception { + public static ShellFactory resolveShellFactory( + Level level, PrintStream stdout, PrintStream stderr, PropertyResolver options) + throws Exception { String factory = (options == null) ? null : options.getString(SHELL_FACTORY_OPTION); if (GenericUtils.isEmpty(factory)) { return DEFAULT_SHELL_FACTORY; @@ -270,7 +275,12 @@ public abstract class SshServerCliSupport extends CliSupport { } if (ScpCommandFactory.SCP_FACTORY_NAME.equalsIgnoreCase(factory)) { - return new ScpCommandFactory(); + ScpCommandFactory shell = new ScpCommandFactory(); + if (isEnabledVerbosityLogging(level)) { + shell.addEventListener(new ScpCommandTransferEventListener(stdout, stderr)); + } + + return shell; } ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(ShellFactory.class); diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java index 1646e08..0e437b5 100644 --- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java @@ -29,6 +29,7 @@ import java.util.TreeMap; import java.util.logging.Level; import java.util.stream.Collectors; +import org.apache.sshd.cli.server.helper.ScpCommandTransferEventListener; import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.PropertyResolver; import org.apache.sshd.common.PropertyResolverUtils; @@ -191,7 +192,7 @@ public class SshServerMain extends SshServerCliSupport { setupServerBanner(sshd, resolver); sshd.setPort(port); - ShellFactory shellFactory = resolveShellFactory(System.err, resolver); + ShellFactory shellFactory = resolveShellFactory(level, System.out, System.err, resolver); if (shellFactory != null) { System.out.append("Using shell=").println(shellFactory.getClass().getName()); sshd.setShellFactory(shellFactory); @@ -201,7 +202,7 @@ public class SshServerMain extends SshServerCliSupport { sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE); setupUserAuthFactories(sshd, resolver); setupServerForwarding(sshd, level, System.out, System.err, resolver); - setupCommandFactory(sshd, shellFactory); + setupCommandFactory(sshd, level, System.out, System.err, shellFactory); List<SubsystemFactory> subsystems = resolveServerSubsystems(sshd, level, System.out, System.err, resolver); if (GenericUtils.isNotEmpty(subsystems)) { @@ -215,14 +216,18 @@ public class SshServerMain extends SshServerCliSupport { System.err.println("Exiting after a very (very very) long time"); } - private static CommandFactory setupCommandFactory(SshServer sshd, ShellFactory shellFactory) { + private static CommandFactory setupCommandFactory( + SshServer sshd, Level level, Appendable stdout, Appendable stderr, ShellFactory shellFactory) { ScpCommandFactory scpFactory; if (shellFactory instanceof ScpCommandFactory) { scpFactory = (ScpCommandFactory) shellFactory; } else { - scpFactory = new ScpCommandFactory.Builder() - .withDelegate(ProcessShellCommandFactory.INSTANCE) - .build(); + ScpCommandFactory.Builder builder = new ScpCommandFactory.Builder() + .withDelegate(ProcessShellCommandFactory.INSTANCE); + if (isEnabledVerbosityLogging(level)) { + builder = builder.addEventListener(new ScpCommandTransferEventListener(stdout, stderr)); + } + scpFactory = builder.build(); } sshd.setCommandFactory(scpFactory); return scpFactory; diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/helper/ScpCommandTransferEventListener.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/helper/ScpCommandTransferEventListener.java new file mode 100644 index 0000000..85b9261 --- /dev/null +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/helper/ScpCommandTransferEventListener.java @@ -0,0 +1,77 @@ +/* + * 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.cli.server.helper; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermission; +import java.util.Set; + +import org.apache.sshd.common.session.Session; +import org.apache.sshd.scp.common.ScpTransferEventListener; +import org.apache.sshd.scp.server.ScpCommandFactory; + +/** + * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> + */ +public class ScpCommandTransferEventListener + extends ServerEventListenerHelper + implements ScpTransferEventListener { + public ScpCommandTransferEventListener(Appendable stdout, Appendable stderr) { + super(ScpCommandFactory.SCP_FACTORY_NAME, stdout, stderr); + } + + @Override + public void startFileEvent( + Session session, FileOperation op, Path file, long length, Set<PosixFilePermission> perms) + throws IOException { + outputDebugMessage("startFileEvent(%s)[%s] len=%d, perms=%s: %s", session, op, length, perms, file); + } + + @Override + public void endFileEvent( + Session session, FileOperation op, Path file, long length, Set<PosixFilePermission> perms, Throwable thrown) + throws IOException { + if (thrown != null) { + outputErrorMessage("endFileEvent(%s)[%s] failed (%s) len=%d, perms=%s [%s]: %s", + session, op, thrown.getClass().getSimpleName(), length, perms, file, thrown.getMessage()); + } else { + outputDebugMessage("endFileEvent(%s)[%s] len=%d, perms=%s: %s", session, op, length, perms, file); + } + } + + @Override + public void startFolderEvent(Session session, FileOperation op, Path file, Set<PosixFilePermission> perms) + throws IOException { + outputDebugMessage("startFolderEvent(%s)[%s] perms=%s: %s", session, op, perms, file); + } + + @Override + public void endFolderEvent( + Session session, FileOperation op, Path file, Set<PosixFilePermission> perms, Throwable thrown) + throws IOException { + if (thrown != null) { + outputErrorMessage("endFolderEvent(%s)[%s] failed (%s) perms=%s [%s]: %s", + session, op, thrown.getClass().getSimpleName(), perms, file, thrown.getMessage()); + } else { + outputDebugMessage("endFolderEvent(%s)[%s] lperms=%s: %s", session, op, perms, file); + } + } +} diff --git a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java index 4683d33..74626a2 100644 --- a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java +++ b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java @@ -32,6 +32,7 @@ import java.util.Objects; import java.util.TreeMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import java.util.logging.Level; import org.apache.sshd.cli.CliSupport; import org.apache.sshd.common.PropertyResolver; @@ -299,11 +300,11 @@ public final class SshFsMounter extends SshServerCliSupport { } PropertyResolver resolver = PropertyResolverUtils.toPropertyResolver(options); + Level level = resolveLoggingVerbosity(resolver, args); SshServer sshd = error ? null : setupIoServiceFactory( CoreTestSupportUtils.setupTestServer(SshFsMounter.class), resolver, - resolveLoggingVerbosity(resolver, args), - System.out, System.err, args); + level, System.out, System.err, args); if (sshd == null) { error = true; } @@ -325,7 +326,7 @@ public final class SshFsMounter extends SshServerCliSupport { // Should come AFTER key pair provider setup so auto-welcome can be generated if needed setupServerBanner(sshd, resolver); - ShellFactory shellFactory = resolveShellFactory(System.err, resolver); + ShellFactory shellFactory = resolveShellFactory(level, System.out, System.err, resolver); if (shellFactory != null) { System.out.append("Using shell=").println(shellFactory.getClass().getName()); sshd.setShellFactory(shellFactory);