Repository: mina-sshd Updated Branches: refs/heads/master f2d3e6ff4 -> 95f75c4dd
[SSHD-488] Expose SshKeyScan#main via a batch script Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/95f75c4d Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/95f75c4d Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/95f75c4d Branch: refs/heads/master Commit: 95f75c4dd447bfa820beb0865f4895a5ed9906be Parents: f2d3e6f Author: Lyor Goldstein <[email protected]> Authored: Mon Oct 3 11:22:18 2016 +0300 Committer: Lyor Goldstein <[email protected]> Committed: Mon Oct 3 11:22:18 2016 +0300 ---------------------------------------------------------------------- README.md | 6 +- assembly/src/main/descriptors/unix-bin.xml | 21 ++ .../src/main/distribution/bin/ssh-keyscan.bat | 105 ++++++++ .../src/main/distribution/bin/ssh-keyscan.sh | 266 +++++++++++++++++++ .../java/org/apache/sshd/client/SshKeyScan.java | 51 ++++ 5 files changed, 445 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/95f75c4d/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 29b6938..d08827b 100644 --- a/README.md +++ b/README.md @@ -967,7 +967,7 @@ In this context, the SSHD code allows the user to configure both the frequency a * `no-more-sessions@*` - As described in [OpenSSH protocol section 2.2](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL). In this context, the code consults the `ServerFactoryManagder.MAX_CONCURRENT_SESSIONS` server-side configuration property in order to -decide whether to accept a successfully authentication session. +decide whether to accept a successfully authenticated session. # Extension modules @@ -976,9 +976,7 @@ There are several extension modules available ## Command line clients -The _apache-sshd.zip_ distribution provides `Windows/Linux` scripts that use the MINA SSHD code base to implement the common _ssh, scp, sftp_ commands. The clients accept most useful switches from the original commands they mimic, where the `-o Option=Value` arguments can be used to configure the client/server in addition to the system properties mechanism. For more details, consult the _main_ methods code in the respective `SshClient`, `SftpCommand` and `DefaultScpClient` classes. - -The code includes `SshKeyScan#main` that is an equivalent for [ssh-keyscan(1)](https://www.freebsd.org/cgi/man.cgi?query=ssh-keyscan&sektion=1), though it is not wrapped inside a script. +The _apache-sshd.zip_ distribution provides `Windows/Linux` scripts that use the MINA SSHD code base to implement the common _ssh, scp, sftp_ commands. The clients accept most useful switches from the original commands they mimic, where the `-o Option=Value` arguments can be used to configure the client/server in addition to the system properties mechanism. For more details, consult the _main_ methods code in the respective `SshClient`, `SftpCommand` and `DefaultScpClient` classes. The code also includes `SshKeyScan#main` that is a simple implementation for [ssh-keyscan(1)](https://www.freebsd.org/cgi/man.cgi?query=ssh-keyscan&sektion=1). The distribution also includes also an _sshd_ script that can be used to launch a server instance - see `SshServer#main` for activation command line arguments and options. http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/95f75c4d/assembly/src/main/descriptors/unix-bin.xml ---------------------------------------------------------------------- diff --git a/assembly/src/main/descriptors/unix-bin.xml b/assembly/src/main/descriptors/unix-bin.xml index 4d027b1..a9d9b13 100644 --- a/assembly/src/main/descriptors/unix-bin.xml +++ b/assembly/src/main/descriptors/unix-bin.xml @@ -28,6 +28,9 @@ <excludes> <exclude>bin/sshd.sh</exclude> <exclude>bin/ssh.sh</exclude> + <exclude>bin/scp.sh</exclude> + <exclude>bin/sftp.sh</exclude> + <exclude>bin/ssh-keyscan.sh</exclude> </excludes> </fileSet> </fileSets> @@ -45,6 +48,24 @@ <fileMode>0755</fileMode> <lineEnding>unix</lineEnding> </file> + <file> + <source>src/main/distribution/bin/scp.sh</source> + <outputDirectory>/bin/</outputDirectory> + <fileMode>0755</fileMode> + <lineEnding>unix</lineEnding> + </file> + <file> + <source>src/main/distribution/bin/sftp.sh</source> + <outputDirectory>/bin/</outputDirectory> + <fileMode>0755</fileMode> + <lineEnding>unix</lineEnding> + </file> + <file> + <source>src/main/distribution/bin/ssh-keyscan.sh</source> + <outputDirectory>/bin/</outputDirectory> + <fileMode>0755</fileMode> + <lineEnding>unix</lineEnding> + </file> </files> <dependencySets> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/95f75c4d/assembly/src/main/distribution/bin/ssh-keyscan.bat ---------------------------------------------------------------------- diff --git a/assembly/src/main/distribution/bin/ssh-keyscan.bat b/assembly/src/main/distribution/bin/ssh-keyscan.bat new file mode 100644 index 0000000..bbbd1e0 --- /dev/null +++ b/assembly/src/main/distribution/bin/ssh-keyscan.bat @@ -0,0 +1,105 @@ +@echo off +rem +rem +rem Licensed to the Apache Software Foundation (ASF) under one or more +rem contributor license agreements. See the NOTICE file distributed with +rem this work for additional information regarding copyright ownership. +rem The ASF licenses this file to You under the Apache License, Version 2.0 +rem (the "License"); you may not use this file except in compliance with +rem the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, software +rem distributed under the License is distributed on an "AS IS" BASIS, +rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem See the License for the specific language governing permissions and +rem limitations under the License. +rem +rem + +if not "%ECHO%" == "" echo %ECHO% + +setlocal +set DIRNAME=%~dp0% +set PROGNAME=%~nx0% +set ARGS=%* + +title scp + +goto BEGIN + +:warn + echo %PROGNAME%: %* +goto :EOF + +:BEGIN + +rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +if not "%SSHD_HOME%" == "" ( + call :warn Ignoring predefined value for SSHD_HOME +) +set SSHD_HOME=%DIRNAME%.. +if not exist "%SSHD_HOME%" ( + call :warn SSHD_HOME is not valid: %SSHD_HOME% + goto END +) + +set DEFAULT_JAVA_OPTS=-server -Xmx512M -Dcom.sun.management.jmxremote +set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 + +rem Support for loading native libraries +set PATH=%PATH%;%SSHD_HOME%\lib + +rem Setup the Java Virtual Machine +if not "%JAVA%" == "" goto :Check_JAVA_END + set JAVA=java + if "%JAVA_HOME%" == "" call :warn JAVA_HOME not set; results may vary + if not "%JAVA_HOME%" == "" set JAVA=%JAVA_HOME%\bin\java + if not exist "%JAVA_HOME%" ( + call :warn JAVA_HOME is not valid: "%JAVA_HOME%" + goto END + ) +:Check_JAVA_END + +if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS% + +if "%SSHD_DEBUG%" == "" goto :SSHD_DEBUG_END + rem Use the defaults if JAVA_DEBUG_OPTS was not set + if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS% + + set "JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%" + call :warn Enabling Java debug options: %JAVA_DEBUG_OPTS% +:SSHD_DEBUG_END + +rem Setup the classpath +set CLASSPATH=%LOCAL_CLASSPATH% +pushd "%SSHD_HOME%\lib" +for %%G in (*.*) do call:APPEND_TO_CLASSPATH %%G +popd +goto CLASSPATH_END + +: APPEND_TO_CLASSPATH +set filename=%~1 +set suffix=%filename:~-4% +if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%SSHD_HOME%\lib\%filename% +goto :EOF + +:CLASSPATH_END + +SET ARGS=%1 %2 %3 %4 %5 %6 %7 %8 +rem Execute the Java Virtual Machine +cd %SSHD_HOME% +"%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%" -Dsshd.home="%SSHD_HOME%" org.apache.sshd.client.SshKeyScan %ARGS% + +rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +:END + +endlocal + +if not "%PAUSE%" == "" pause + +:END_NO_PAUSE + http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/95f75c4d/assembly/src/main/distribution/bin/ssh-keyscan.sh ---------------------------------------------------------------------- diff --git a/assembly/src/main/distribution/bin/ssh-keyscan.sh b/assembly/src/main/distribution/bin/ssh-keyscan.sh new file mode 100644 index 0000000..e6245e0 --- /dev/null +++ b/assembly/src/main/distribution/bin/ssh-keyscan.sh @@ -0,0 +1,266 @@ +#!/bin/sh +# +# 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. +# + +DIRNAME=`dirname $0` +PROGNAME=`basename $0` + +# +# Check/Set up some easily accessible MIN/MAX params for JVM mem usage +# + +if [ "x$JAVA_MIN_MEM" = "x" ]; then + JAVA_MIN_MEM=128M + export JAVA_MIN_MEM +fi + +if [ "x$JAVA_MAX_MEM" = "x" ]; then + JAVA_MAX_MEM=512M + export JAVA_MAX_MEM +fi + +warn() { + echo "${PROGNAME}: $*" +} + +die() { + warn "$*" + exit 1 +} + +maybeSource() { + file="$1" + if [ -f "$file" ] ; then + . $file + fi +} + +detectOS() { + # OS specific support (must be 'true' or 'false'). + cygwin=false; + darwin=false; + aix=false; + os400=false; + case "`uname`" in + CYGWIN*) + cygwin=true + ;; + Darwin*) + darwin=true + ;; + AIX*) + aix=true + ;; + OS400*) + os400=true + ;; + esac + # For AIX, set an environment variable + if $aix; then + export LDR_CNTRL=MAXDATA=0xB0000000@DSA + export IBM_JAVA_HEAPDUMP_TEXT=true + echo $LDR_CNTRL + fi +} + +unlimitFD() { + # Use the maximum available, or set MAX_FD != -1 to use that + if [ "x$MAX_FD" = "x" ]; then + MAX_FD="maximum" + fi + + # Increase the maximum file descriptors if we can + if [ "$os400" = "false" ] && [ "$cygwin" = "false" ]; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ "$MAX_FD_LIMIT" != 'unlimited' ]; then + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + # use the system max + MAX_FD="$MAX_FD_LIMIT" + fi + + ulimit -n $MAX_FD > /dev/null + # echo "ulimit -n" `ulimit -n` + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT" + fi + fi + fi +} + +locateHome() { + if [ "x$SSHD_HOME" != "x" ]; then + warn "Ignoring predefined value for SSHD_HOME" + fi + + # In POSIX shells, CDPATH may cause cd to write to stdout + (unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + SSHD_HOME=`cd $DIRNAME/..; pwd` + if [ ! -d "$SSHD_HOME" ]; then + die "SSHD_HOME is not valid: $SSHD_HOME" + fi +} + +setupNativePath() { + # Support for loading native libraries + LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$SSHD_BASE/lib:$SSHD_HOME/lib" + + # For Cygwin, set PATH from LD_LIBRARY_PATH + if $cygwin; then + LD_LIBRARY_PATH=`cygpath --path --windows "$LD_LIBRARY_PATH"` + PATH="$PATH;$LD_LIBRARY_PATH" + export PATH + fi + export LD_LIBRARY_PATH +} + +locateJava() { + # Setup the Java Virtual Machine + if $cygwin ; then + [ -n "$JAVA" ] && JAVA=`cygpath --unix "$JAVA"` + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + fi + + if [ "x$JAVA" = "x" ]; then + if [ "x$JAVA_HOME" = "x" ] && [ "$darwin" = "true" ]; then + JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home + fi + if [ "x$JAVA_HOME" != "x" ]; then + if [ ! -d "$JAVA_HOME" ]; then + die "JAVA_HOME is not valid: $JAVA_HOME" + fi + JAVA="$JAVA_HOME/bin/java" + else + warn "JAVA_HOME not set; results may vary" + JAVA="java" + fi + fi +} + +detectJVM() { + #echo "`$JAVA -version`" + # This service should call `java -version`, + # read stdout, and look for hints + if $JAVA -version 2>&1 | grep "^IBM" ; then + JVM_VENDOR="IBM" + # on OS/400, java -version does not contain IBM explicitly + elif $os400; then + JVM_VENDOR="IBM" + else + JVM_VENDOR="SUN" + fi + # echo "JVM vendor is $JVM_VENDOR" +} + +setupDebugOptions() { + if [ "x$JAVA_OPTS" = "x" ]; then + JAVA_OPTS="$DEFAULT_JAVA_OPTS" + fi + export JAVA_OPTS + + # Set Debug options if enabled + if [ "x$SSHD_DEBUG" != "x" ]; then + # Use the defaults if JAVA_DEBUG_OPTS was not set + if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then + JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS" + fi + + JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS" + warn "Enabling Java debug options: $JAVA_DEBUG_OPTS" + fi +} + +setupDefaults() { + DEFAULT_JAVA_OPTS="-Xms$JAVA_MIN_MEM -Xmx$JAVA_MAX_MEM " + + #Set the JVM_VENDOR specific JVM flags + if [ "$JVM_VENDOR" = "SUN" ]; then + DEFAULT_JAVA_OPTS="-server $DEFAULT_JAVA_OPTS -Dcom.sun.management.jmxremote" + elif [ "$JVM_VENDOR" = "IBM" ]; then + if $os400; then + DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS" + elif $aix; then + DEFAULT_JAVA_OPTS="-Xverify:none -Xlp $DEFAULT_JAVA_OPTS" + else + DEFAULT_JAVA_OPTS="-Xverify:none $DEFAULT_JAVA_OPTS" + fi + fi + + # Add the jars in the lib dir + for file in $SSHD_HOME/lib/*.jar + do + if [ -z "$CLASSPATH" ]; then + CLASSPATH="$file" + else + CLASSPATH="$CLASSPATH:$file" + fi + done + DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005" + + ## + ## TODO: Move to conf/profiler/yourkit.{sh|cmd} + ## + # Uncomment to enable YourKit profiling + #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent" +} + +init() { + # Determine if there is special OS handling we must perform + detectOS + + # Unlimit the number of file descriptors if possible + unlimitFD + + # Locate the Sshd home directory + locateHome + + # Setup the native library path + setupNativePath + + # Locate the Java VM to execute + locateJava + + # Determine the JVM vendor + detectJVM + + # Setup default options + setupDefaults + + # Install debug options + setupDebugOptions + +} + +run() { + if $cygwin; then + SSHD_HOME=`cygpath --path --windows "$SSHD_HOME"` + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + fi + cd $SSHD_BASE + exec $JAVA $JAVA_OPTS -Dsshd.home="$SSHD_HOME" $OPTS -classpath "$CLASSPATH" org.apache.sshd.client.SshKeyScan "$@" +} + +main() { + init + run "$@" +} + +main "$@" http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/95f75c4d/sshd-core/src/main/java/org/apache/sshd/client/SshKeyScan.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshKeyScan.java b/sshd-core/src/main/java/org/apache/sshd/client/SshKeyScan.java index 8ce551c..5e0707c 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/SshKeyScan.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/SshKeyScan.java @@ -54,6 +54,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; +import org.apache.sshd.client.auth.keyboard.UserInteraction; import org.apache.sshd.client.future.ConnectFuture; import org.apache.sshd.client.keyverifier.ServerKeyVerifier; import org.apache.sshd.client.session.ClientSession; @@ -201,6 +202,42 @@ public class SshKeyScan implements Channel, Callable<Void>, ServerKeyVerifier, S client.setServerKeyVerifier(this); try (BufferedReader rdr = new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8))) { + client.setUserInteraction(new UserInteraction() { + @Override + public boolean isInteractionAllowed(ClientSession session) { + return true; + } + + @Override + public String[] interactive(ClientSession session, String name, String instruction, String lang, String[] prompt, boolean[] echo) { + return null; + } + + @Override + public String getUpdatedPassword(ClientSession session, String prompt, String lang) { + return null; + } + + @Override + public void serverVersionInfo(ClientSession session, List<String> lines) { + if (isEnabled(Level.FINE) && GenericUtils.isNotEmpty(lines)) { + for (String l : lines) { + log(Level.FINE, "Server Info: " + l); + } + } + } + + @Override + public void welcome(ClientSession session, String banner, String lang) { + if (isEnabled(Level.FINE) && GenericUtils.isNotEmpty(banner)) { + String[] lines = GenericUtils.split(banner, '\n'); + for (String l : lines) { + log(Level.FINE, "Welcome[" + lang + "]: " + l); + } + } + } + }); + client.start(); for (String line = rdr.readLine(); line != null; line = rdr.readLine()) { String[] hosts = GenericUtils.split(GenericUtils.trimToEmpty(line), ','); @@ -359,6 +396,20 @@ public class SshKeyScan implements Channel, Callable<Void>, ServerKeyVerifier, S public void sessionNegotiationStart( Session session, Map<KexProposalOption, String> clientProposal, Map<KexProposalOption, String> serverProposal) { logSessionEvent(session, "sessionNegotiationStart"); + logNegotiationProposal("c2s", clientProposal); + logNegotiationProposal("s2c", serverProposal); + } + + protected void logNegotiationProposal(String type, Map<KexProposalOption, String> proposal) { + if (!isEnabled(Level.FINEST)) { + return; + } + + for (Map.Entry<KexProposalOption, String> pe : proposal.entrySet()) { + KexProposalOption option = pe.getKey(); + String value = pe.getValue(); + log(Level.FINEST, option.getDescription() + "[" + type + "]: " + value); + } } @Override
