pax_global_header00006660000000000000000000000064146543637210014525gustar00rootroot0000000000000052 comment=600ffb3aae7052c3a8b56bc2fa03546c2fca1354 mwiede-jsch-c8efa3f/000077500000000000000000000000001465436372100145055ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.devcontainer/000077500000000000000000000000001465436372100172445ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.devcontainer/Dockerfile000066400000000000000000000050001465436372100212310ustar00rootroot00000000000000# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.137.0/containers/java/.devcontainer/base.Dockerfile ARG VARIANT="17" FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT} # [Optional] Install Maven or Gradle ARG INSTALL_MAVEN="false" ARG MAVEN_VERSION=3.6.3 ARG INSTALL_GRADLE="false" ARG GRADLE_VERSION=5.4.1 RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "source /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \ && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "source /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi # [Optional] Install a version of Node.js using nvm for front end dev ARG INSTALL_NODE="true" ARG NODE_VERSION="lts/*" RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi # Note: You can use any Debian/Ubuntu based image you want. # FROM mcr.microsoft.com/vscode/devcontainers/base:buster # [Option] Install zsh ARG INSTALL_ZSH="true" # [Option] Upgrade OS packages to their latest versions ARG UPGRADE_PACKAGES="false" # [Option] Enable non-root Docker access in container ARG ENABLE_NONROOT_DOCKER="true" # Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies. ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=$USER_UID ARG SOURCE_SOCKET=/var/run/docker-host.sock ARG TARGET_SOCKET=/var/run/docker.sock COPY library-scripts/*.sh /tmp/library-scripts/ RUN apt-get update \ && /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" \ # Use Docker script from script library to set things up && /bin/bash /tmp/library-scripts/docker-debian.sh "${ENABLE_NONROOT_DOCKER}" "${SOURCE_SOCKET}" "${TARGET_SOCKET}" "${USERNAME}" \ # Clean up && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/ # Setting the ENTRYPOINT to docker-init.sh will configure non-root access to # the Docker socket if "overrideCommand": false is set in devcontainer.json. # The script will also execute CMD if you need to alter startup behaviors. ENTRYPOINT [ "/usr/local/share/docker-init.sh" ] CMD [ "sleep", "infinity" ] # [Optional] Uncomment this section to install additional OS packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # && apt-get -y install --no-install-recommends mwiede-jsch-c8efa3f/.devcontainer/devcontainer.json000066400000000000000000000025611465436372100226240ustar00rootroot00000000000000{ "name": "Java PLUS Docker from Docker", "build": { "dockerfile": "Dockerfile", "args": { // Update the VARIANT arg to pick a Java version: 11, 14 "VARIANT": "17", // Options "INSTALL_MAVEN": "true", "INSTALL_GRADLE": "false", "INSTALL_NODE": "false", "NODE_VERSION": "lts/*" } }, "runArgs": [ "--init" ], "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind" ], // Use this environment variable if you need to bind mount your local source code into a new container. "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" }, // Set *default* container specific settings.json values on container create. "settings": { "java.home": "/docker-java-home", "maven.executable.path": "/usr/local/sdkman/candidates/maven/current/bin/mvn" }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-azuretools.vscode-docker", "vscjava.vscode-java-pack" ] // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "docker --version", // Uncomment the next two lines to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. , "overrideCommand": false, "remoteUser": "vscode" }mwiede-jsch-c8efa3f/.devcontainer/library-scripts/000077500000000000000000000000001465436372100223755ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.devcontainer/library-scripts/common-debian.sh000066400000000000000000000251031465436372100254420ustar00rootroot00000000000000#!/usr/bin/env bash #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. #------------------------------------------------------------------------------------------------------------- # # Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/common.md # # Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My *! flag] INSTALL_ZSH=${1:-"true"} USERNAME=${2:-"automatic"} USER_UID=${3:-"automatic"} USER_GID=${4:-"automatic"} UPGRADE_PACKAGES=${5:-"true"} INSTALL_OH_MYS=${6:-"true"} set -e if [ "$(id -u)" -ne 0 ]; then echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' exit 1 fi # If in automatic mode, determine if a user already exists, if not use vscode if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then USERNAME="" POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") for CURRENT_USER in ${POSSIBLE_USERS[@]}; do if id -u ${CURRENT_USER} > /dev/null 2>&1; then USERNAME=${CURRENT_USER} break fi done if [ "${USERNAME}" = "" ]; then USERNAME=vscode fi elif [ "${USERNAME}" = "none" ]; then USERNAME=root USER_UID=0 USER_GID=0 fi # Load markers to see which steps have already run MARKER_FILE="/usr/local/etc/vscode-dev-containers/common" if [ -f "${MARKER_FILE}" ]; then echo "Marker file found:" cat "${MARKER_FILE}" source "${MARKER_FILE}" fi # Ensure apt is in non-interactive to avoid prompts export DEBIAN_FRONTEND=noninteractive # Function to call apt-get if needed apt-get-update-if-needed() { if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then echo "Running apt-get update..." apt-get update else echo "Skipping apt-get update." fi } # Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then apt-get-update-if-needed PACKAGE_LIST="apt-utils \ git \ openssh-client \ gnupg2 \ iproute2 \ procps \ lsof \ htop \ net-tools \ psmisc \ curl \ wget \ rsync \ ca-certificates \ unzip \ zip \ nano \ vim-tiny \ less \ jq \ lsb-release \ apt-transport-https \ dialog \ libc6 \ libgcc1 \ libgssapi-krb5-2 \ libicu[0-9][0-9] \ liblttng-ust0 \ libstdc++6 \ zlib1g \ locales \ sudo \ ncdu \ man-db" # Install libssl1.1 if available if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then PACKAGE_LIST="${PACKAGE_LIST} libssl1.1" fi # Install appropriate version of libssl1.0.x if available LIBSSL=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '') if [ "$(echo "$LIBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then # Debian 9 PACKAGE_LIST="${PACKAGE_LIST} libssl1.0.2" elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then # Ubuntu 18.04, 16.04, earlier PACKAGE_LIST="${PACKAGE_LIST} libssl1.0.0" fi fi echo "Packages to verify are installed: ${PACKAGE_LIST}" apt-get -y install --no-install-recommends ${PACKAGE_LIST} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 ) PACKAGES_ALREADY_INSTALLED="true" fi # Get to latest versions of all packages if [ "${UPGRADE_PACKAGES}" = "true" ]; then apt-get-update-if-needed apt-get -y upgrade --no-install-recommends apt-get autoremove -y fi # Ensure at least the en_US.UTF-8 UTF-8 locale is available. # Common need for both applications and things like the agnoster ZSH theme. if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen locale-gen LOCALE_ALREADY_SET="true" fi # Create or update a non-root user to match UID/GID. if id -u ${USERNAME} > /dev/null 2>&1; then # User exists, update if needed if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -G $USERNAME)" ]; then groupmod --gid $USER_GID $USERNAME usermod --gid $USER_GID $USERNAME fi if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then usermod --uid $USER_UID $USERNAME fi else # Create user if [ "${USER_GID}" = "automatic" ]; then groupadd $USERNAME else groupadd --gid $USER_GID $USERNAME fi if [ "${USER_UID}" = "automatic" ]; then useradd -s /bin/bash --gid $USERNAME -m $USERNAME else useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME fi fi # Add add sudo support for non-root user if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME chmod 0440 /etc/sudoers.d/$USERNAME EXISTING_NON_ROOT_USER="${USERNAME}" fi # ** Shell customization section ** if [ "${USERNAME}" = "root" ]; then USER_RC_PATH="/root" else USER_RC_PATH="/home/${USERNAME}" fi # .bashrc/.zshrc snippet RC_SNIPPET="$(cat << EOF export USER=\$(whoami) export PATH=\$PATH:\$HOME/.local/bin EOF )" # code shim, it fallbacks to code-insiders if code is not available cat << 'EOF' > /usr/local/bin/code #!/bin/sh get_in_path_except_current() { which -a "$1" | grep -v "$0" | head -1 } code="$(get_in_path_except_current code)" if [ -n "$code" ]; then exec "$code" "$@" elif [ "$(command -v code-insiders)" ]; then exec code-insiders "$@" else echo "code or code-insiders is not installed" >&2 exit 127 fi EOF chmod +x /usr/local/bin/code # Codespaces themes - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme CODESPACES_BASH="$(cat \ <&1 echo -e "$(cat "${TEMPLATE}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${USER_RC_FILE} if [ "${OH_MY}" = "bash" ]; then sed -i -e 's/OSH_THEME=.*/OSH_THEME="codespaces"/g' ${USER_RC_FILE} mkdir -p ${OH_MY_INSTALL_DIR}/custom/themes/codespaces echo "${CODESPACES_BASH}" > ${OH_MY_INSTALL_DIR}/custom/themes/codespaces/codespaces.theme.sh else sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="codespaces"/g' ${USER_RC_FILE} mkdir -p ${OH_MY_INSTALL_DIR}/custom/themes echo "${CODESPACES_ZSH}" > ${OH_MY_INSTALL_DIR}/custom/themes/codespaces.zsh-theme fi # Shrink git while still enabling updates cd ${OH_MY_INSTALL_DIR} git repack -a -d -f --depth=1 --window=1 if [ "${USERNAME}" != "root" ]; then cp -rf ${USER_RC_FILE} ${OH_MY_INSTALL_DIR} /root chown -R ${USERNAME}:${USERNAME} ${USER_RC_PATH} fi } if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then echo "${RC_SNIPPET}" >> /etc/bash.bashrc RC_SNIPPET_ALREADY_ADDED="true" fi install-oh-my bash bashrc.osh-template https://github.com/ohmybash/oh-my-bash # Optionally install and configure zsh and Oh My Zsh! if [ "${INSTALL_ZSH}" = "true" ]; then if ! type zsh > /dev/null 2>&1; then apt-get-update-if-needed apt-get install -y zsh fi if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then echo "${RC_SNIPPET}" >> /etc/zsh/zshrc ZSH_ALREADY_INSTALLED="true" fi install-oh-my zsh zshrc.zsh-template https://github.com/ohmyzsh/ohmyzsh fi # Write marker file mkdir -p "$(dirname "${MARKER_FILE}")" echo -e "\ PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\ LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\ EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\ RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\ ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}" echo "Done!" mwiede-jsch-c8efa3f/.devcontainer/library-scripts/docker-debian.sh000066400000000000000000000153151465436372100254250ustar00rootroot00000000000000#!/usr/bin/env bash #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. #------------------------------------------------------------------------------------------------------------- # # Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/docker.md # # Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] ENABLE_NONROOT_DOCKER=${1:-"true"} SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"} TARGET_SOCKET=${3:-"/var/run/docker.sock"} USERNAME=${4:-"automatic"} set -e if [ "$(id -u)" -ne 0 ]; then echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' exit 1 fi # Determine the appropriate non-root user if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then USERNAME="" POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") for CURRENT_USER in ${POSSIBLE_USERS[@]}; do if id -u ${CURRENT_USER} > /dev/null 2>&1; then USERNAME=${CURRENT_USER} break fi done if [ "${USERNAME}" = "" ]; then USERNAME=root fi elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then USERNAME=root fi # Function to run apt-get if needed apt-get-update-if-needed() { if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then echo "Running apt-get update..." apt-get update else echo "Skipping apt-get update." fi } # Ensure apt is in non-interactive to avoid prompts export DEBIAN_FRONTEND=noninteractive # Install apt-transport-https, curl, lsb-release, gpg if missing if ! dpkg -s apt-transport-https curl ca-certificates lsb-release > /dev/null 2>&1 || ! type gpg > /dev/null 2>&1; then apt-get-update-if-needed apt-get -y install --no-install-recommends apt-transport-https curl ca-certificates lsb-release gnupg2 fi # Install Docker CLI if not already installed if type docker > /dev/null 2>&1; then echo "Docker CLI already installed." else curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT) echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list apt-get update apt-get -y install --no-install-recommends docker-ce-cli fi # Install Docker Compose if not already installed if type docker-compose > /dev/null 2>&1; then echo "Docker Compose already installed." else LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")') curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose fi # If init file already exists, exit if [ -f "/usr/local/share/docker-init.sh" ]; then exit 0 fi # By default, make the source and target sockets the same if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then touch "${SOURCE_SOCKET}" ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}" fi # Add a stub if not adding non-root user access, user is root if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh chmod +x /usr/local/share/docker-init.sh exit 0 fi # If enabling non-root access and specified user is found, setup socat and add script chown -h "${USERNAME}":root "${TARGET_SOCKET}" if ! dpkg -s socat > /dev/null 2>&1; then apt-get-update-if-needed apt-get -y install socat fi tee /usr/local/share/docker-init.sh > /dev/null \ << EOF #!/usr/bin/env bash #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. #------------------------------------------------------------------------------------------------------------- set -e SOCAT_PATH_BASE=/tmp/vscr-dind-socat SOCAT_LOG=\${SOCAT_PATH_BASE}.log SOCAT_PID=\${SOCAT_PATH_BASE}.pid # Wrapper function to only use sudo if not already root sudoIf() { if [ "\$(id -u)" -ne 0 ]; then sudo "\$@" else "\$@" fi } # Log messages log() { echo -e "[\$(date)] \$@" | sudoIf tee -a \${SOCAT_LOG} > /dev/null } echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}" # If enabled, try to add a docker group with the right GID. If the group is root, # fall back on using socat to forward the docker socket to another unix socket so # that we can set permissions on it without affecting the host. if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET}) if [ "\${SOCKET_GID}" != "0" ]; then log "Adding user to group with GID \${SOCKET_GID}." if [ "\$(cat /etc/group | grep :\${SOCKET_GID}:)" = "" ]; then sudoIf groupadd --gid \${SOCKET_GID} docker-host fi # Add user to group if not already in it if [ "\$(id ${USERNAME} | grep -E 'groups=.+\${SOCKET_GID}\(')" = "" ]; then sudoIf usermod -aG \${SOCKET_GID} ${USERNAME} fi else # Enable proxy if not already running if [ ! -f "\${SOCAT_PID}" ] || ! ps -p \$(cat \${SOCAT_PID}) > /dev/null; then log "Enabling socket proxy." log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode" sudoIf rm -rf ${TARGET_SOCKET} (sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null) else log "Socket proxy already running." fi fi log "Success" fi # Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. set +e exec "\$@" EOF chmod +x /usr/local/share/docker-init.sh chown ${USERNAME}:root /usr/local/share/docker-init.sh echo "Done!" mwiede-jsch-c8efa3f/.github/000077500000000000000000000000001465436372100160455ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.github/dependabot.yml000066400000000000000000000013551465436372100207010ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "maven" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" open-pull-requests-limit: 25 - package-ecosystem: "github-actions" # Workflow files stored in the # default location of `.github/workflows` directory: "/" schedule: interval: "weekly" open-pull-requests-limit: 25 mwiede-jsch-c8efa3f/.github/workflows/000077500000000000000000000000001465436372100201025ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.github/workflows/automerge.yml000066400000000000000000000013471465436372100226220ustar00rootroot00000000000000name: Dependabot auto-merge patch versions on: pull_request permissions: contents: write pull-requests: write jobs: dependabot: runs-on: ubuntu-latest if: ${{ github.actor == 'dependabot[bot]' }} steps: - name: Dependabot metadata id: metadata uses: dependabot/fetch-metadata@dbb049abf0d677abbd7f7eee0375145b417fdd34 # v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}} run: gh pr merge --auto --merge "$PR_URL" env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} mwiede-jsch-c8efa3f/.github/workflows/codeql-analysis.yml000066400000000000000000000056571465436372100237320ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: workflow_dispatch jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ 'java' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup JDK uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: '21' check-latest: true cache: 'maven' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # If the Autobuild fails above, remove it and uncomment the following three lines. # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. # - run: | # echo "Run, Build Application using script" # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15 mwiede-jsch-c8efa3f/.github/workflows/coverity.yml000066400000000000000000000013431465436372100224720ustar00rootroot00000000000000name: Coverity Scan # We only want to run this on demand at the moment on: workflow_dispatch jobs: coverity: runs-on: ubuntu-latest steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up build JDK uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: '21' check-latest: true cache: 'maven' - uses: vapier/coverity-scan-action@2068473c7bdf8c2fb984a6a40ae76ee7facd7a85 # v1.8.0 with: email: ${{ secrets.COVERITY_SCAN_EMAIL }} token: ${{ secrets.COVERITY_SCAN_TOKEN }} build_language: 'java' command: 'mvn -DskipTests=true compile' mwiede-jsch-c8efa3f/.github/workflows/javadoc.yml000066400000000000000000000014711465436372100222370ustar00rootroot00000000000000name: Build Javadocs and Deploy to Github Pages on: workflow_dispatch: push: tags: - '*' permissions: contents: write jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up build JDK uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: '21' check-latest: true - name: Build Javadoc run: ./mvnw -B -V -e javadoc:javadoc - name: Deploy 🚀 uses: JamesIves/github-pages-deploy-action@94f3c658273cf92fb48ef99e5fbc02bd2dc642b2 # v4.6.3 with: folder: target/site/apidocs target-folder: ${{github.ref_name}} mwiede-jsch-c8efa3f/.github/workflows/maven.yml000066400000000000000000000062471465436372100217440ustar00rootroot00000000000000# This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven name: Java CI with Maven on: workflow_dispatch: push: branches: [ master ] paths-ignore: - '**.md' pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Cache local Maven repository uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: | ~/.m2/repository ~/.m2/wrapper key: ${{ runner.os }}-build-maven-${{ hashFiles('**/pom.xml', '**/maven-wrapper.properties') }} restore-keys: | ${{ runner.os }}-build-maven- - name: Set up JDK uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: '21' check-latest: true - name: Build with Maven run: ./mvnw -B -V -e verify -DskipTests=true -DskipITs=true - name: Archive target directory run: tar -cf target.tar target - name: Upload target directory archive uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: build_target path: target.tar test: needs: build runs-on: ubuntu-latest strategy: matrix: java: ['8', '11', '17', '21', '22'] steps: - name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Cache local Maven repository uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: | ~/.m2/repository ~/.m2/wrapper key: ${{ runner.os }}-test-${{ matrix.java }}-maven-${{ hashFiles('**/pom.xml', '**/maven-wrapper.properties') }} restore-keys: | ${{ runner.os }}-test-${{ matrix.java }}-maven- - name: Set up JDK uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: ${{ matrix.java }} check-latest: true - name: Download target directory archive uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: build_target - name: Extract target directory archive run: tar -xf target.tar - name: Test with Maven run: ./mvnw -B -V -e -Pcoverage verify -Denforcer.skip=true -Dmaven.resources.skip=true -Dflatten.skip=true -Dmaven.main.skip=true -Dbnd.skip=true -Dassembly.skipAssembly=true -Dmaven.javadoc.skip=true -Dcyclonedx.skip=true -Dformatter.skip=true -Dforbiddenapis.skip=true -DskipTests=false -DskipITs=false - name: Upload test results uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: java-${{ matrix.java }}-testresults path: | **/target/surefire-reports/ **/target/failsafe-reports/ **/target/site/jacoco/ **/target/site/jacoco-it/ if: always() mwiede-jsch-c8efa3f/.github/workflows/release.yml000066400000000000000000000026401465436372100222470ustar00rootroot00000000000000 # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: create # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" release: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 # Runs a set of commands using the runners shell - name: Release uses: mwiede/github-actions-maven-release@master with: release-branch-name: "release" gpg-enabled: "true" gpg-key-id: ${{ secrets.GPG_ID }} gpg-key: ${{ secrets.GPG_KEY }} maven-repo-server-id: ${{ secrets.MVN_REPO_ID }} maven-repo-server-username: ${{ secrets.MVN_REPO_PRIVATE_REPO_USER }} maven-repo-server-password: ${{ secrets.MVN_REPO_PRIVATE_REPO_PASSWORD }} #maven-args: "-Dmaven.javadoc.skip=true -DskipTests -DskipITs -Ddockerfile.skip -DdockerCompose.skip" maven-args: "-Dgpg.passphrase=" git-release-bot-name: "release-bot" git-release-bot-email: "mwiede@gmx.de" access-token: ${{ secrets.ACCESS_TOKEN }} mwiede-jsch-c8efa3f/.gitignore000066400000000000000000000144501465436372100165010ustar00rootroot00000000000000# IDE files # *.geany nb-configuration.xml .flattened-pom.xml target.tar # Created by https://www.toptal.com/developers/gitignore/api/intellij+all,netbeans,eclipse,visualstudiocode,vim,emacs,macos,windows,linux,java,maven # Edit at https://www.toptal.com/developers/gitignore?templates=intellij+all,netbeans,eclipse,visualstudiocode,vim,emacs,macos,windows,linux,java,maven ### Eclipse ### .metadata bin/ tmp/ *.tmp *.bak *.swp *~.nib local.properties .settings/ .loadpath .recommenders # External tool builders .externalToolBuilders/ # Locally stored "Eclipse launch configurations" *.launch # PyDev specific (Python IDE for Eclipse) *.pydevproject # CDT-specific (C/C++ Development Tooling) .cproject # CDT- autotools .autotools # Java annotation processor (APT) .factorypath # PDT-specific (PHP Development Tools) .buildpath # sbteclipse plugin .target # Tern plugin .tern-project # TeXlipse plugin .texlipse # STS (Spring Tool Suite) .springBeans # Code Recommenders .recommenders/ # Annotation Processing .apt_generated/ .apt_generated_test/ # Scala IDE specific (Scala & Java development for Eclipse) .cache-main .scala_dependencies .worksheet # Uncomment this line if you wish to ignore the project description file. # Typically, this file would be tracked if it contains build/dependency configurations: #.project ### Eclipse Patch ### # Spring Boot Tooling .sts4-cache/ ### Emacs ### # -*- mode: gitignore; -*- *~ \#*\# /.emacs.desktop /.emacs.desktop.lock *.elc auto-save-list tramp .\#* # Org-mode .org-id-locations *_archive # flymake-mode *_flymake.* # eshell files /eshell/history /eshell/lastdir # elpa packages /elpa/ # reftex files *.rel # AUCTeX auto folder /auto/ # cask packages .cask/ dist/ # Flycheck flycheck_*.el # server auth directory /server/ # projectiles files .projectile # directory configuration .dir-locals.el # network security /network-security.data ### Intellij+all ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf # AWS User-specific .idea/**/aws.xml # Generated files .idea/**/contentModel.xml # Sensitive or high-churn files .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/dbnavigator.xml # Gradle .idea/**/gradle.xml .idea/**/libraries # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. # .idea/artifacts # .idea/compiler.xml # .idea/jarRepositories.xml # .idea/modules.xml # .idea/*.iml # .idea/modules # *.iml # *.ipr # CMake cmake-build-*/ # Mongo Explorer plugin .idea/**/mongoSettings.xml # File-based project format *.iws # IntelliJ out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties # Editor-based Rest Client .idea/httpRequests # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser ### Intellij+all Patch ### # Ignores the whole .idea folder and all .iml files # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 .idea/ # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 *.iml modules.xml .idea/misc.xml *.ipr # Sonarlint plugin .idea/sonarlint ### Java ### # Compiled class file *.class # Log file *.log # BlueJ files *.ctxt # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.nar *.ear *.zip *.tar.gz *.rar # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* ### Linux ### # temporary files which can be created if a process still has a handle open of a deleted file .fuse_hidden* # KDE directory preferences .directory # Linux trash folder which might appear on any partition or disk .Trash-* # .nfs files are created when an open file is removed but is still being accessed .nfs* ### macOS ### # General .DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk ### Maven ### target/ pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup pom.xml.next release.properties dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties # https://github.com/takari/maven-wrapper#usage-without-binary-jar .mvn/wrapper/maven-wrapper.jar ### Maven Patch ### # Eclipse m2e generated files # Eclipse Core .project # JDT-specific (Eclipse Java Development Tools) .classpath ### NetBeans ### **/nbproject/private/ **/nbproject/Makefile-*.mk **/nbproject/Package-*.bash build/ nbbuild/ nbdist/ .nb-gradle/ ### Vim ### # Swap [._]*.s[a-v][a-z] !*.svg # comment out if you don't need vector files [._]*.sw[a-p] [._]s[a-rt-v][a-z] [._]ss[a-gi-z] [._]sw[a-p] # Session Session.vim Sessionx.vim # Temporary .netrwhist # Auto-generated tag files tags # Persistent undo [._]*.un~ ### VisualStudioCode ### .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json *.code-workspace # Local History for Visual Studio Code .history/ ### VisualStudioCode Patch ### # Ignore all local history of files .history .ionide ### Windows ### # Windows thumbnail cache files Thumbs.db Thumbs.db:encryptable ehthumbs.db ehthumbs_vista.db # Dump file *.stackdump # Folder config file [Dd]esktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msix *.msm *.msp # Windows shortcuts *.lnk # End of https://www.toptal.com/developers/gitignore/api/intellij+all,netbeans,eclipse,visualstudiocode,vim,emacs,macos,windows,linux,java,maven mwiede-jsch-c8efa3f/.mvn/000077500000000000000000000000001465436372100153635ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.mvn/wrapper/000077500000000000000000000000001465436372100170435ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.mvn/wrapper/maven-wrapper.properties000066400000000000000000000016671465436372100237570ustar00rootroot00000000000000# 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. wrapperVersion=3.3.2 distributionType=only-script distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip mwiede-jsch-c8efa3f/.sdkmanrc000066400000000000000000000001741465436372100163120ustar00rootroot00000000000000# Enable auto-env through the sdkman_auto_env config # Add key=value pairs of SDKs to use below java=21.0.4-tem maven=3.9.8 mwiede-jsch-c8efa3f/.vscode/000077500000000000000000000000001465436372100160465ustar00rootroot00000000000000mwiede-jsch-c8efa3f/.vscode/settings.json000066400000000000000000000002651465436372100206040ustar00rootroot00000000000000{ "java.configuration.updateBuildConfiguration": "automatic", "terminal.integrated.defaultProfile.linux": "bash", "java.checkstyle.configuration": "/google_checks.xml" }mwiede-jsch-c8efa3f/ChangeLog000066400000000000000000001403661465436372100162710ustar00rootroot00000000000000ChangeLog of JSch ==================================================================== Last modified: Thu Nov 22 01:06:27 UTC 2018 Changes since version 0.1.54: - bugfix: fixed vulnerabilities in examples; ScpTo.java, ScpFrom.java and ScpNoneCipher.java, https://gist.github.com/ymnk/2318108/revisions#diff-a5ec82fe8ccb2efa64aa42a5592bb137 https://gist.github.com/ymnk/2318108/revisions#diff-c1b069ab3a670f4fd3270d0f57550007 https://gist.github.com/ymnk/2318108/revisions#diff-a20032aa3cc9119fa627ec948b9ada46 thanks to Dylan Katz(http://dylankatz.com). - bugfix: OpenSSHConfig#getUser() should not overwrite the given user-name. - bugfix: fixed 'Invalid encoding for signature' errors in ssh-dss. - bugfix: fixed bugs in the key-exchange for ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. - bugfix: failed to generate the key pair from private keys, ecdsa 384 and 521. - bugfix: failed to load the ecdsa 521 key identity from ssh-add command. - change: updating copyright messages; 2016 -> 2018 - feature: supporting key files on EBCDIC environment. Changes since version 0.1.53: - bugfix: fixed CVS-2016-5725 Refer to following links, http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-5725 https://github.com/tintinweb/pub/tree/master/pocs/cve-2016-5725 Thanks a lot for tintinweb's contributions. - bugfix: sftp-put may send the garbage data in some rare case. - bugfix: fixed a deadlock bug in KnownHosts#getHostKey(). - bugfix: SftpProgressMonitor#init() was not invoked in sftp-put by using the output-stream. - change: KnownHosts#setKnownHosts() should accept the non-existing file. - change: excluding the user interaction time from the timeout value. - change: addressing SFTP slow file transfer speed with Titan FTP. - change: updating copyright messages; 2015 -> 2016 Changes since version 0.1.52: - bugfix: the rekey initiated by the remote may crash the session. - change: Logjam: use ecdh-sha2-nistp* if available, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 - change: Logjam: diffie-hellman-group-exchange-sha256 and diffie-hellman-group-exchange-sha1 will use 2048-bit key on Java8's SunJCE, thanks to JDK-6521495 and JDK-7044060. - change: key words for OpenSSH's config file should be case-insensitive. - change: there should be the host name in "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED" message. Changes since version 0.1.51: - bugfix: resource leak: duplicate keys in LocalIdentityRepository. - feature: added the support for SSH ECC defined in RFC5656, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521 This functionality requires Java7 or later. - feature: added the support for server host keys in ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521 - feature: generating key-pairs in ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521 - change: aes192-ctr, aes256-ctr and diffie-hellman-group-exchange-sha256 have been enabled by the default. - change: key exchange methods, ecdh-sha2-nistp256, ecdh-sha2-nistp384 and ecdh-sha2-nistp521 have been enabled by the default. - change: the support for host keys in ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 and ecdsa-sha2-nistp521 have been enabled by the default. - change: 'examples/KeyGen.java' demonstrates how to generate ecdsa-sha2-* key-pairs. - change: updating copyright messages; 2014 -> 2015 - TODO: The ECC support is not functional on Java6 with BouncyCastle. Changes since version 0.1.50: - bugfix: reproducibility of "verify: false". FIXED. Hundreds of thousands of connections had caused that exception. - bugfix: resource leaks at the failure of making local port forwarding. FIXED. - bugfix: NPE in connecting to the non-standard TCP port. FIXED. This problem had appeared if a host-key does not exist in "known_host" file. - bugfix: TCP connection may not be dropped if error messages from the remote are too long. FIXED. - bugfix: SftpATTRS#getAtimeString() returns the wrong string. FIXED. - bugfix: bytes to be added by SSH_MSG_CHANNEL_WINDOW_ADJUST must be in unsigned integer. FIXED. - bugfix: Util#checkTilde() should not convert a tilde in "C:\PROGRA~1\". FIXED. - bugfix: A long long command for ChannelExec will cause an ArrayIndexOutOfBoundsException. FIXED. - bugfix: ChannelSftp should not send bulk request greedily even if the remote window has the enough space. FIXED. - bugfix: Util.createSocket() should throw an exception with 'cause'. FIXED. - bugfix: failed to parse .ssh/config in the EBCDIC environment. FIXED. - bugfix: com.jcraft.jsch.jcraft.HMACSHA1(used only for MacOSX) is not reusable. FIXED. - bugfix: NPE caused by the delayed response for channel opening requests. FIXED. - bugfix: hung-up in uploading huge data to ProFTPd without the config 'SFTPClientMatch "JSCH.*" channelWindowSize 1GB' FIXED. - bugfix: Cipher#init() may cause an infinite loop with 100% cpu use due to https://bugs.openjdk.java.net/browse/JDK-8028627 FIXED. - bugfix: in some case, JSche#setKnowHosts(InputStream stream) may fail to close the given stream. FIXED - change: com.jcraft.jsch.jcraft.HMAC* will not be used. It seems Java6 on Mac OS X has fixed some memory leak bug in JCE, so there is no reason to use c.j.j.j.HMAC* introduced at 0.1.30. - change: updating copyright messages; 2013 -> 2014 - change: allowed to create the symbolic/hard link to the relative path by ChannelSftp#symlink(String oldpath, String newpath) ChannelSftp#hardlink(String oldpath, String newpath) - change: the availability of ciphers listed in "CheckCiphers" config will not be checked if they are not used. - change: Util#fromBase64() will throw JSchException in stead of RuntimeException, if the given string is not in base64 format. - feature: added the support for private keys in PKCS#8 format. - feature: introduced the interface com.jcraft.jsch.PBKDF to abstract the implementation of Password-Based Key Derivation Function, and added its implementation com.jcraft.jsch.jce.PBKDF by using JCE. Changes since version 0.1.49: - bugfix: "verify: false" error on Java7u6(and later). FIXED. http://stackoverflow.com/questions/12279836/ssh-using-jschexception-verify-false-sometimes-fails https://issues.apache.org/jira/browse/IVY-1374 - bugfix: Session#setPortForwardingL(String bind_address, int lport, String host, int rport) will not work for the long host name. FIXED. - change: changed JSch#getIdentityRepository() to be public. - feature: added the following method to choose a canceled remote port-forwarding with the specified bind address, Session#delPortForwardingR(String bind_address, int rport) - feature: added support for following OpenSSH's sftp extensions, posix-rename@openssh.com, statvfs@openssh.com, hardlink@openssh.com, and some methods and a class to use those functionalities, ChannelSftp#hardlink(String oldpath, String newpath), ChannelSftp#statVFS(String path) SftpStatVFS - feature: added support for OpenSSH's configuration file, JSch#setConfigRepository(ConfigRepository configRepository) JSch#getConfigRepository() OpenSSHConfig class Session#getSession(String host) and added an example to demonstrate how to use it, examples/OpenSSHConfig.java OpenSSHConfig class will recognize the following keywords, Host User Hostname Port PreferredAuthentications IdentityFile NumberOfPasswordPrompts ConnectTimeout HostKeyAlias UserKnownHostsFile KexAlgorithms HostKeyAlgorithms Ciphers Macs Compression CompressionLevel ForwardAgent RequestTTY ServerAliveInterval LocalForward RemoteForward ClearAllForwardings - feature: added support for "diffie-hellman-group-exchange-sha256" - feature: allowed to use tilde(~) in the file name, JSch#setIdentity(String prvkey, String pubkey) JSch#setKnownHosts(String prvkey, String pubkey) - feature: added support for known_hosts file, which may include markers(@revoke) and comments. HostKey(String host, int type, byte[] key, String comment) HostKey(String marker, String host, int type, byte[] key, String comment) HostKey#getComment() HostKey#getMarker() - feature: added following methods to KeyPar class, writePrivateKey(java.io.OutputStream out, byte[] passphrase) writePrivateKey(String name, byte[] passphrase) - feature: allowed to set the connection timeout for the local port-forwarding, and added following methods, Session#setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) ChannelDirectTCPIP#connect(int connectTimeout) - feature: added the following method to Session class getStreamForwarder(String host, int port) and updated example/StreamForwarding.java to use that method. - feature: added following methods to Session class, setPortForwardingL(String conf) setPortForwardingR(String conf) - feature: allowed to have the session local HostkeyRepository, Session#setHostKeyRepository(HostKeyRepository hostkeyRepository) Session#getHostKeyRepository() - feature: added support for OpenSSH's local extension, "no-more-sessions@openssh.com" and the method, Session#noMoreSessionChannels() Changes since version 0.1.48: - bugfix: Some sftp servers will sometimes fail to handle bulk requests, and whenever detecting such failures, we should re-send requests again and again. FIXED - bugfix: KeyPair#getFingerPrint() should return a fingerprint instead of keysize + " " + fingerprint. FIXED - bugfix: KeyPair#getKeySize() should return its key size. FIXED - bugfix: SftpATTRS#isDir() should return false for unix domain socket files. FIXED - change: improved the heuristics for the password prompt in the keyboard-interactive authentication. It may not be started with "password:". - change: ChannelSftp#put(InputStream src, String dst) will not check if dst is directory or not, and if an exception is thrown, the check will be done. - change: if the compression is enabled without jzlib.jar, an exception will be thrown. - feature: JSch#addIdentity() and KeyPair#load() methods will accept Putty's private key files. Note that Putty encrypts its private key with "aes256-cbc". So, to handle such key files, "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" must be installed. - feature: hmac-sha2-256 defined in RFC6668 is supported. - feature: added following methods to KeyPair class, byte[] getSignature(byte[] data) Signature getVerifier() byte[] forSSHAgent() void setPublicKeyComment(String comment) - feature: added following methods to SftpATTR class, boolean isChr() boolean isBlk() boolean isFifo() boolean isSock() Changes since version 0.1.47: - change: the file transfer speed with ChannelSftp#get(String src) has been improved; sending multiple requests at any one time. - change: by the default, at most, 16 requests will be sent at any one time in ChannelSftp. - feature: added Session#{setIdentityRepository(),getIdentityRepository()} Changes since version 0.1.46: - bugfix: failed to initialize channels for the stream forwarding. FIXED - change: Session#getHostKey() will return the given hostkey even if session is not established. - change: Logger will record additional messages about algorithm negotiations. - feature: added ChannelSftp#ls(String path, LsEntrySelector selector) method. - feature: added IdentityRepository#{getName(),getStatus()} methods. Changes since version 0.1.45: - bugfix: in the agent forwarding mode, "ssh-add -l" on the remote will freeze. FIXED - bugfix: requests should not be sent to the closed channel. FIXED - bugfix: ChannelShell#setAgentForwarding(true) will cause resource leaks. FIXED - change: for the efficiency, channel opening will be delayed in local port forwarding. - change: added examples/Sudo.java to demonstrate sudo on exec channel. - change: authentication trials will be failed at 6 failures by the default. - change: updating copyright messages; 2011 -> 2012 - feature: added JSch#setIdentityRepository(IdentityRepository irepo) to integrate with jsch-agent-proxy. Changes since version 0.1.44: - bugfix: fields referred by multiple threads simultaneously should be volatile. FIXED - bugfix: use local window size offered by the remote in sftp put. FIXED - bugfix: SftpProgressMonitor#init was not invoked in sftp-put for input-stream. FIXED - bugfix: sftp protocol version 3, 4 and 5 should allow only UTF-8 encoding. FIXED - bugfix: Channel Subsystem had failed to set X forwarding flag. FIXED - bugfix: Channel X11 had leaked some resources. FIXED - bugfix: packet compression may break sessions in some case(transferring deflated data). FIXED - bugfix: failed to set dev-null for logger FIXED - bugfix: even in sftp protocol version 3 session, some sftpd sends data packets defined in sftp protocol 6 ;-( working around it. FIXED - bugfix: ChannelSftp file globbing logic had missed the string "foo\\\*bar" as a pattern. FIXED - bugfix: sequential accesses to ChannelSftp by multiple threads may break its I/O channel. https://bugs.eclipse.org/bugs/show_bug.cgi?id=359184 FIXED - bugfix: KeyPair.load can not handle private keys cyphered with AES. FIXED - change: to improve sftp-put performance, send multiple packet at one time. - change: wait/notify will be used instead of sleep loop in establishing channel connections. - change: increasing local window size for sftp get. - change: updating copyright messages; 2010 -> 2011 - change: src/com -> src/main/java/com - feature: key-exchange method "diffie-hellman-group14-sha1" (RFC4253#section-8.2) - feature: KeyPair#getPlulicKeyCommment() is added. Changes since version 0.1.43: - bugfix: hmac-md5-96 and hmac-sha1-96 are broken. FIXED. - bugfix: working around OOME in parsing broken data from the remote. FIXED. - bugfix: failed to send very long command for exec channels. FIXED. - bugfix: in some case, failed to get the response for remote port-forwarding request. FIXED. - feature: support for private keys ciphered with aes192-cbc and aes128-cbc. Changes since version 0.1.42: - bugfix: the remote window size must be in unsigned int. FIXED. - bugfix: support for EBCDIC environment. FIXED. - bugfix: data may be written to the closed channel. FIXED. - bugfix: NPE in closing channels. FIXED. - bugfix: the private key file may include garbage data before its header. FIXED. - bugfix: the session down may not be detected during the re-keying process. FIXED. - change: try keyboard-interactive auth with the given password if UserInfo is not given. - change: working around the wrong auth method list sent by some SSHD in the partial auth success. - change: working around the CPNI-957037 Plain-text Recovery Attack. - change: in searching for [host]:non-default port in known_hosts, host:22 should be also checked. - change: updating copyright messages; 2009 -> 2010 Changes since version 0.1.41: - bugfix: making exec request during re-keying process will cause the dead lock for the session. FIXED. Many thanks for PanLi at Prominic dot NET and www.prominic.net, US based hosting company. Without their testing JSch with hundreds of hosts and their bug reports, this problem was not fixed. - change: updating copyright messages; 2008 -> 2009 Changes since version 0.1.40: - bugfix: canceling the remote port-forwarding with the incorrect bind-address. FIXED. - bugfix: sftp had missed to close the file in some case. FIXED. - bugfix: ls(sftp) will throw an exception for the empty directory in connecting to some sftpd server. FIXED. - change: dropping the session gently in accepting incorrect packets. - change: by the default, aes128-ctr will be chosen if it is available on the local and the remote. - feature: adding the support for the private key ciphered in AES256. - feature: new ciphers: aes128-ctr,aes192-ctr,aes256-ctr, 3des-ctr,arcfour,arcfour128 ,arcfour256 Changes since version 0.1.39: - bugfix: ProxySOCKS4 had not been functional. FIXED. - bugfix: NPE at closing the session when it is not opened. FIXED. - change: JSch#getConfing has become public. Changes since version 0.1.38: - bugfix: session will be dropped at rekeying. FIXED. - bugfix: NPE should not be thrown at unexpected session drop. FIXED. - change: Channel#getSession() may throw JSchExecption. Changes since version 0.1.37: - bugfix: NPE should not be thrown at unexpected session drop. FIXED. - bugfix: AIOOBE at Session#connect(). FIXED. - bugfix: Even if 'true' is given for Channel#setOutputStream(OutputStream out, boolean dontclose) as the second paramter, 'out' will be closed. FIXED. - change: 'examples/Sftp.java' has been modified to demonstrate ChannelSftp#reaplpath(String path) - change: setEnv(Hashtable env) for exec and shell channels have been marked as @deprecated - feature: setEnv(String name, String value) has been added to exec and shell channels. - feature: setEnv(byte[] name, byte[] value) has been added to exec and shell channels. - feature: ChannelSftp#realpath(String path) has been added. - feature: ChannelExec#setCommand(byte[] command) has been added. - feature: com.jcraft.jsch.ChannelSftp.LsEntry has implemented java.lang.Comparable - feature: Session#getServerAliveInterval(), Session#getServerAliveCountMaX() have been added. Changes since version 0.1.36: - bugfix: some sftpd will send invalid data in sftp protocol point of view, and we need to work around such data. FIXED. - bugfix: the stream forwarding had been broken since 0.1.30. FIXED. - bugfix: failed to detect 'SSH_MSG_CHANNEL_OPEN_FAILURE'. FIXED. - bugfix: ChannelSftp will generate the unfavorable absolute pathname in some case. FIXED. - bugfix: failed to ignore the invalid public-key file. FIXED. - change: ignoring empty data sent by 'SSH_MSG_CHANNEL_DATA' and 'SSH_MSG_CHANNEL_EXTENDED_DATA'. - change: updating copyright messages; 2007 -> 2008 - change: build.xml will enable 'javac.debug' option by the default. - change: added logging messages to IndentityFile and Session class. - change: followings are deprecated methods, InputStream ChannelSftp#get(String src, int mode) InputStream ChannelSftp#get(String src, SftpProgressMonitor, int mode) - feature: following method is added, InputStream ChannelSftp#get(String src, SftpProgressMonitor monitor, long skip) Changes since version 0.1.35: - bugfix: ChannelSftp can not handle the local filenames correctly on Windows. FIXED. - bugfix: '/' must be handled as the file separator on JVM for Windows. FIXED. - change: the system property "javax.security.auth.useSubjectCredsOnly" will be set to "false" for "gssapi-with-mic" if that property is not given explicitly. - change: added changes about ChannelSftp#{pwd(), home()} to ChangeLog; 'Changes since version 0.1.34:' section. Changes since version 0.1.34: - bugfix: the OutputStream from the channel may make the JVM lockup in some case. FIXED. There was a possibility that Channel#connect() may be failed to initialize its internal without throwing the JSchException. On such case, the write operation for OutputStream from that channel will cause the system(JVM) to lock up. - bugfix: ChannelSftp had problems filename globbing. FIXED. - bugfix: the message included in SSH_FXP_STATUS must be UTF-8. FIXED. - change: ChannelSftp supports the filename globbing for the filename in multi-byte characters. - change: ChannelSftp will internally handle filenames in UTF-8 encoding. - change: ChannelSftp#pwd() may throw an SftpException. - change: ChannelSftp#home() may throw an SftpException. - feature: following methods have been added in ChannelSftp String getServerVersion() String getClientVersion() void setFilenameEncoding(String encoding) String getExtension(String key) Changes since version 0.1.33: - bugfix: there had a possibility that the session may be broken if ciphers for upward/downward streams are different. FIXED. - bugfix: the authentication method "keyboard-interactive" had not been tried without UserInfo. FIXED. - bugfix: ChannelShell#setTerminalMode(byte[] terminal_mode) had not been functional. FIXED. - bugfix: the remote port-forwarding to the daemon had been broken since 0.1.30. FIXED. - change: the cipher "aes128-cbc" will be used if AES is available. - change: the interface 'com.jcraft.jsch.ForwardedTCPIPDaemon' has been changed. - change: the data transfer rate will be improved on some environment. - feature: ChannelExec can control the size of pty; ChannelExec#setPtySize(int col, int row, int wp, int hp) is added. - feature: the property "CheckCiphers" has been added. Refer to 'examples/AES.java'. - feature: Session#setConfig(String key, String value), JSch#setConfig(String key, String value) have been added. Changes since version 0.1.32: - bugfix: freeze in 'diffie-hellman-group-exchange-sha1'. FIXED. By the default, 'diffie-hellman-group1-sha1' will be used and if you have not chosen 'diffie-hellman-group-exchange-sha1' explicitly, you don't have to worry about it. - bugfix: there should be timeout mechanism in opening a socket for remote port forwarding. FIXED. At the failure or timeout, 'SSH_MSG_CHANNEL_OPEN_FAILURE' will be sent to sshd. - bugfix: there should be timeout mechanism in opening a socket for X11 forwarding. FIXED. At the failure or timeout, 'SSH_MSG_CHANNEL_OPEN_FAILURE' will be sent to sshd. Changes since version 0.1.31: - bugfix: remote port forwarding will be hanged at its closing. FIXED. - bugfix: X forwarding channels will be hanged and some resources will be leaked whenever they are closed. FIXED. - bugfix: failed to detect "Connection refused". FIXED. - bugfix: at the failure for keyboard-interactive auth method, a session will be terminated. FIXED. - bugfix: due to the cancel for keyboard-interactive auth method, a session will be terminated. FIXED. - change: com.jcraft.jsch.jcraft.Compression#uncompress will respect the argument "start". - change: "gssapi-with-mic" will choose the default credential. - feature: Session#setPortForwardingL will return the assigned local TCP port number; TCP port will be assigned dynamically if lport==0. - feature: support for SSH_MSG_UNIMPLEMENTED. - feature: support for PASSWD_CHANGEREQ. Changes since version 0.1.30: - bugfix: a problem in padding for ciphered private key. PKCS#5 padding should be used. FIXED. - bugfix: crash in parsing invalid public key file. FIXED. - bugfix: a public key may not have a comment. FIXED. - bugfix: output stream from ChannelSftp#put will hang if it is closed twice. FIXED. - feature: agent forwarding. To enable this functionality, Channel{Exec,Shell,Sftp}#setAgentForwarding(boolean enable) are added. - feature: ChannelShell#setTerminalMode(byte[] terminal_mode) is added. - feature: Session#setDaemonThread(boolean true) to run internal threads as daemon threads. - feature: an option "PreferredAuthentications" is added. The default value is "gssapi-with-mic,publickey,keyboard-interactive,password". - change: if alias-name is given, non-standard TCP port number will not be saved in 'known_hosts' file. Changes since version 0.1.29: - bugfix: ChannelSftp#cd() will not throw an exception even if a file is given. FIXED. - bugfix: ChannelSftp#put() has a bug which will appear in using on the slow network. FIXED. - bugfix: ChannelSftp#ls() has a bug which will appear in using on the slow network. FIXED. - bugfix: a bug had sneaked in the remote port forwarding. FIXED. - bugfix: some APIs from JCE have the memory leak on Mac OS X, so we have re-written the code(com.jcraft.jsch.jcraft.HMAC* classes) without them. On Mac OS X, such new classes will be used automatically. FIXED. - bugfix: the session will be crashed by the long banner message. FIXED. - change: '/dev/random' will not be referred on Gnu/Linux. - change: if non-standard TCP port number is used, that number will be saved in known_hosts file as recent OpenSSH's ssh client does. - change: Channel#getOutputStream will not use Piped{Output,Input}Stream. - change: com.jcraft.jsch.HostKeyRepository interface has been slightly modified. - feature: Session#setPortForwardingR(String bind_address, ...) has been added. - feature: the packet compression method 'zlib@openssh.com' has been supported. - feature: the hashed known_hosts file has been supported. Refer to 'examples/KnownHosts.java'. - feature: the authentication method 'gssapi-with-mic' has been experimentally supported. - feature: com.jcraft.jsch.Logger interface and JSch#setLogger(Logger logger) have been added. Refer to 'examples/Logger.java' for the usage. Changes since version 0.1.28: - bugfix: ChannelSftp#put will stack in some situations FIXED. - bugfix: ChannelSftp invoked 'glob_remote' redundantly. FIXED. - bugfix: ChannelSftp failed to make globbing for some file names. FIXED. - bugfix: ChannelSftp did not carefully read its input-stream. FIXED. - bugfix: ChannelSftp#lstat did not try globbing for given path. FIXED. - bugfix: at closing channel, eof_lcoal and eof_remote did not become true. FIXED. - bugfix: IdentityFile did not carefully read file input-streams. FIXED. - bugfix: KeyPair did not carefully read file input-streams. FIXED. - bugfix: ProxySOCKS4 did not carefully read file input-streams. FIXED. - bugfix: ProxySOCKS5 did not carefully read file input-streams. FIXED. - bugfix: ForwardedTCPIPDaemom may fail in some situation. FIXED. - bugfix: X forwarding failed to handle the magic-cookie in some case FIXED. Thanks to Walter Pfannenmller. - bugfix: setKnownHosts in KnownHosts.java doesn't read the last line if linefeed is missing FIXED. Thanks to Henrik Langos. - bugfix: With StrictHostKeyChecking set to yes connect() shouldn't ask. FIXED. Thanks to Henrik Langos. - change: Identity#setPassphrase(String passphrase) is replaced with Identity#setPassphrase(byte[] passphrase). - change: IdentityFile will clear its internal secrets at finalizing. - change: KeyPair will clear its internal secrets at finalizing. - change: KeyPair will clear its internal secrets at finalizing. - change: MAC#doFinal() is replaced with MAC#doFile(byte[] buf, int offset) - change: at TCP socket reading timeout, keep-alive message will be sent to the remote sshd. To disable this functionality, invoke explicitly Session.setServerAliveCountMax(0) - change: PortWatcher stops to use InetAddress.getByAddress(). - change: in the user authentication, username, password and passphrase will be encoded in UTF-8. - change: JSch#addIdentity will check duplicate keys. - change: SftpException#message has been deleted. - change: SftpException#getMessage() will return the detailed message. - feature: IdentityFile#setPassphrase(byte[] passphrase) is added. - feature: IdentityFile#clear() is added to clear its internal secrets. - feature: KeyPair#decrypt(byte[] passphrase) is added. - feature: JSch#addIdentity(String path, byte[] passphrase) is added. - feature: JSch#getIdentityNames() is added. - feature: JSch#removeIdentity(String name) is added. - feature: JSch#removeAllIdentity() is added. - feature: ChannelSftp#readlink(String path) is added. - feature: ChannelSftp#getHome() is added. - feature: Channel#connect(int connectTimeout) is added. - feature: ChannelShell#setPtyType(String ttype) is added. - feature: Session#setPassword(byte[] password) is added. - feature: Session#setHostKeyAlias(String alias) is added. - feature: KeepAlive is implemented and Session#setServerAliveInterval(int interval) and Session#setServerAliveCountMax(int count) are added. - feature: Session#sendKeepAliveMsg() is added. - feature: JSchException#getCause() may return a reason. - feature: SftpException#getCause() may return a reason. - feature: ChannelExec#setErrStream(OutputStream out, boolean dontclose) is added. Changes since version 0.1.27: - bugfix: ChannelSftp#localAbsolutePath did not work correctly. FIXED. - bugfix: ChannelSftp#chmod did not work for directory. FIXED. - bugfix: ProxyHTTP had a bug in processing HTTP headers. FIXED. - bugfix: messages before server's version string should be ignored. FIXED. - feature: Environment Variable Passing. Changes since version 0.1.26: - bugfix: there was a session crash bug. That occurrence is rare, but depends on the thread scheduling. FIXED. - bugfix: problems in generating remote/local absolute paths on sftp. FIXED. - bugfix: problems in handling cancel operations for sftp. FIXED. - bugfix: ChannelX11s were not terminated for a wrong cookie. FIXED. - bugfix: NoSuchAlgorithmException should be thrown if JCE is not accessible. FIXED. - bugfix: ProxyHTTP should check the return code from proxy. FIXED. - bugfix: server's version string should be checked carefully. FIXED. - feature: some more improvements on sftp uploading. - feature: 'getUserName' method is added to Session class. Changes since version 0.1.25: - bugfix: infinite loop/hang on connection at unexpected error during key-exchanging operation. FIXED - bugfix: delays on sftp uploading. FIXED - bugfix: failed to purge a host-key from its repository in some case. FIXED. - feature: SOCKS4 proxy Changes since version 0.1.24: - bugfix: remote port forwarding is not established. FIXED. - bugfix: failed to parse known_hosts file if it has a long public key blob. FIXED. - bugfix: sftp put/get operations keep failing. FIXED. - bugfix: ChannelShell.setXForwarding always set xforwarding to be true. FIXED. - change: ChannelShell.setPty is added. - change: Proxy interface is free from session object. - change: added examples/ScpToNoneCipher.java to demonstrate NONE Cipher switching. - feature: added NONE Cipher switching support. - feature: timeout check will be enabled for proxy connections. Changes since version 0.1.23: - bugfix: there was resource leak problems in closing local port forwardings. FIXED. - bugfix: there was a session crash problems in using aes-cbc cipher. FIXED. - change: ChannelSession.setPtySize was redefined. - feature: added SocketFactory for remote port forwarding. Session.setPortForwardingR(int rport, String host, int lport, SocketFactory sf) - feature: added ServerSocketFactory for local port forwarding. Session.setPortForwardingL(String boundaddress, int lport, String host, int rport, ServerSocketFactory ssf) Changes since version 0.1.22: - bugfix: there was a freeze problem at fails on key-exchanging. FIXED. - bugfix: race-condition forcefully disconnects session in closing channels. FIXED. Changes since version 0.1.21: - bugfix: there is a bug in read() method implementation for the input-stream returned from ChannelSftp.get(). FIXED. - bugfix: at fail on requesting for the remote port forwarding, an exception should be thrown. FIXED. - bugfix: SSH_MSG_CHANNEL_OPEN request for the X11 forwarding should not be accepted if clients don not expect it. FIXED. - bugfix: there is a problem in transferring large data(mote than 1GB) to sshd from recent OpenSSH(3.6.1 or later). FIXED. For security concerns, those sshd will re-key periodically and jsch had failed to handle it. - bugfix: 'exec', 'shell' and 'sftp' channels will fail if the acceptable packet size by remote sshd is not so large. FIXED. - bugfix: there are problems in 'InputStream ChannelSftp.get(String)' and 'OutputStream put(String)'. FIXED. - feature: added boolean flag 'dontclose' to * setInputStream(), * setOutputStream() and * setExtOutputStream() methods of Channel class. - feature: added 'com.jcraft.jsch.ChannelSubsystem' - feature: allowed to control the compression level in the packet compression. Refer to 'examples/Compression.java'. - change: modified 'com/jcraft/jsch/jce/KeyPairGenRSA.java' to be complied on JDK 1.2. - change: 'examples/ScpTo.java' and 'examples/ScpFrom.java' will use 'long' type for the file size instead of 'int'. - change: 'Identity.getSignature' method will not expect 'session'. - change: while waiting for socket connection establishment, Thread.join will be used instead of Thread.sleep. Changes since version 0.1.20: - known issue: there are problems in 'InputStream ChannelSftp.get(String)' and 'OutputStream put(String)'. They will be re-implemented in the next release. - bugfix: EOF packets should not be sent twice. This bug had crashed the session on every channel close. FIXED. - bugfix: at the fail on opening connection to remote sshd, a misleading exception "invalid server's version string" had been thrown. FIXED. - bugfix: fixed a bug in hadling the size of remote channel window. - bugfix: channels should not be closed even if EOF is received. FIXED. - bugfix: fixed bugs in file name globbing on sftp. - change: to transfer packets efficiently, the size of internal buffer for each channel has been increased. - change: ChannelSftp.ls will return a vector of com.jcraft.jsch.ChannelSftp.LsEntry. Sorry for inconveniences. - feature: added ForwardedTCPIPDaemon. Refer to 'examples/Daemon.java', which demonstrates to provide network services like inetd. - feature: ChannelExec.setPty() method to request for assigning pseudo tty. - feature: added ciphers "aes128-cbc", "aes192-cbc" and "aes256-cbc". Refer to 'examples/AES.java'. - feature: local port-forwarding settings can be dynamically deleted by the bound address. - feature: added 'Channel.isClosed()'. Channel.getExitStatus() should be invoked after Channel.isClosed()==true. Changes since version 0.1.19: - ClassCastException while calling ChannelExec.finalize() method. FIXED. Thanks to wswiatek at ais dot pl. Changes since version 0.1.18: - fixed problems related to thread-safety. Thanks to Eric Meek at cs dot utk dot edu. - At the lost of the network connectivity to the remote SSHD, clients connected to the local port were never made aware of the disconnection. FIXED. - fixed confusions in handling EOFs from local input stream and the input stream for remote process. - 'com.jcraft.jsch.jce.AES128CBC' is added, but it is not be functional in this release. It will work in the next release. - Some sshd(Foxit-WAC-Serve) waits for SSH_MSG_NEWKEYS request before sending it. FIXED. - fixed a problem in connecting to Cisco Devices. Thanks to Jason Jeffords at comcast dot net. - changed the method 'add' of 'HostKeyRepository' interface. - 'UIKeyborarInteracetive' will ignore empty prompt by sshd. - added 'sendIgnore()' method to 'Session' class. - added '-p' for scp command in 'examples/ScpTo.java' to preserve modification times, access times, and modes from the original file. Changes since version 0.1.17: - added 'com.jcraft.jsch.HostKeyRepository' interface. It will allow you to handle host keys in your own repository (for example, RDB) instead of using 'known_hosts' file. - added methods to get the finger-print of host keys. refer to 'examples/KnownHosts.java'. - improved 'known_hosts' file handling. - comment lines will be kept. - SSH1 host keys will be kept. - each hostname can have multiple host keys. - fixed a crash bug in processing private keys which have too long key-bits. Changes since version 0.1.16: - 'com.jcraft.jsch.jce.DHG1' and 'com.jcraft.jsch.jce.DHGEX' are moved to 'com.jcraft.jsch' package. - added APIs to handle hostkeys included in 'known_hosts', JSch.getHostKeys(), JSch.removeHostKey() - allowing to set timeout value in opening sockets, Session.connect(int timeout) Changes since version 0.1.15: - adding support of setting mtime for remote files on sftp channel. - setKnownHosts method of JSch class will accept InputStream. - implementation of Basic password authentication for HTTP proxy. - fixed a bug in checking which ssh protocol version remote sshd supports - SSH_MSG_CHANNEL_OPEN_FAILURE will be handled correctly. - methods in SftpATTRS class has been public. - working around SIGBLOB bug hidden in older sshd. Changes since version 0.1.14: - fixed a crash bug in accepting keep-alive messages. - the parent directory of 'known_hosts' file will be created if it does not exist. - the Subsystem channel support was removed. Changes since version 0.1.13: - added 'setClientVersion' method to Session class. - fixed hung-up problem on SftpChannel in connecting to the sshd, which does not support sftp. - fixed OutOfMemory exception problem in decrypting a private key with bad passphrase. - fixed hung-up problem in communicating with the sshd, whose window size is small. - RuntimeExceptions will be thrown from jsch APIs. - SSH_MSG_CHANNEL_SUCCESS and SSH_MSG_CHANNEL_FAILURE requests have been supported. Changes since version 0.1.12: - added the partial authentication support. - allowing to change the passphrase of a private key file instead of creating a new private key. - added 'examples/ChangePassphrase.java' - the interface 'UIKeyboardInteractive' has been modified. Changes since version 0.1.11: - RSA keypair generation. - added the method 'getFingerPrint' to KeyPair class, which will return the finger print of the public key. - fixed a bug in generating non-ciphered private key. Changes since version 0.1.10: - fixed a bug in the password authentication, sneaked in 0.1.9. By this bug, the password authentication had failed every time. Changes since version 0.1.9: - username and password can be in UTF-8 encoding. - DSA keypair generation. - added 'examples/KeyGen.java', which demonstrates the DSA keypair generation. Changes since version 0.1.8: - fixed crash problems on the local port forwarding. - fixed crash problems on the remote port forwarding. - added setErrStream() and getErrStream() to ChannelExec. - added keyboard-interactive authentication support. - modified TripleDESCBC to support IBM's JDK 1.4.1. - added 'examples/UserAuthKI.java', which demonstrates keyboard-interactive authentication. Changes since version 0.1.7: - added APIs for sftp resume downloads and uploads. The author greatly appreciates elpernotador(webmaster at unlix dot com dot ar), who motivated him to hack this functionality. - 'examples/Sftp.java' demonstrates sftp resume functionality. Please refer to "put-resume", "put-append", "get-resume" and "get-append" command. - added the support of 'window-change' request. - fixed a freeze bug in 'Inputstream get(String src)' method of 'ChannelSftp' class. Changes since version 0.1.6: - added 'int getExitStatus()' method to 'Channel' class. - fixed crash bugs in closing channels for port forwarding. - fixed glitches in managing forwarded ports. Changes since version 0.1.5: - fixed crash bugs in port forwarding. - modified to use "ssh-rsa" for key-exchanging by the default. - the port forwarding setting can be canceled dynamically. - fixed a freeze bug in getting an empty file on sftp channel. Changes since version 0.1.4: - fixed a bug in managing local window size. The local window should be consumed by CHANNEL_EXTENDED_DATA packet. - checking the availability of the ssh session in opening channels. In some case, ssh session had been freezed. - java.io.File.separator will be refereed in generating local pathname on sftp channel. - absolute local pathname will be handled correctly on sftp channel. Changes since version 0.1.3: - fixed a serious bug, which had leaked resources related to ChannelExec. - added the older SFTP protocol(version 0, 1, 2) support. - fixed a problem in the authentication step for FSecure's sshd. - fixed a bug, which had broken Diffie-Hellman key exchange in some case. - implemented the file name globbing for local files on sftp session. - fixed a bug in the file name globbing. - added an interface 'SftpProgressMonitor'. - modified 'examples/Sftp.java' to demonstrate displaying progress-bar in transferring files. Changes since version 0.1.2: - modified 'build.xml' to allow Ant users to compile jsch with debug support (i.e. line-number tables) by overriding the property javac.debug on the command line. - added a property 'StrictHostKeyChecking'. - added 'UserAuthNone' class to request a list of authentication methods on remote sshd. - channels will be managed in each sessions. - added 'ChannelSubsystem', which allows users to use their own implementations for subsystems. - added 'isEOF()' method to 'Channel' class. - supported key pair files in DOS file format. Changes since version 0.1.1: - added the file name globbing support on sftp session. - fixed a bug in the public key authentication. When there was not a public key in ~/.ssh/, that problem occurred. - improved the 'setTimeout' method. - fixed a typo in 'LICENSE.txt' Changes since version 0.1.0: - added 'rekey' method to 'Session' class for key re-exchanging. - added 'rekey' and 'compression' command to 'examples/Sftp.java'. - added new 'get' and 'put' methods to 'ChannelSftp'. Those methods will operate I/O streams. - methods in 'ChannelSftp' will throw 'SftpException' - 'ChannelSftp.Ssh_exp_name' is added for the output of 'ls'. Thanks to Graeme Vetterlein. - added 'setTimeout' and 'getTimeout' methods to 'Session' class. - guess will be done in the algorithm negotiation step. - FSecure's DSA private key has been supported partially. - hostkeys will be saved into 'known_hosts' file. - fixed a bug in 'Util.toBase64' method. - 'Identity' will reject unrecognized keys. - 'build.xml' will check if jzlib is available or not. Thanks to Stefan Bodewig. - added javadoc target in 'build.xml'. Thanks to Robert Anderson. Changes since version 0.0.13: - fixed a bug in connecting to Fsecure's sshd on Windows. - the license is changed to BSD style. Changes since version 0.0.12: - fixed a bug in verifying DAS signatures. - added 'SftpATTR' class, which allow you to get attributes of remote files on sftp channel, and 'stat', 'lstat' method are added to 'ChannelSftp' class. - added 'getInputStream' and 'getOutputStream' methods Channel class, which return passive I/O streams. - 'setIdentity' method is deleted from 'Session' class and 'addIdentity' method is added to 'JSch' class - 'setUserName' method is deleted from 'Session' class and 'getSession' method of 'JSch' class is changed. - 'isConnected' method is added to 'Session' class. - 'UserInfo' interface is changed. Changes since version 0.0.11: - taking care of remote window size. - adding 'disconnect' method to 'Channel' and 'Session' classes. - signal sending support. - 'mkdir' command for sftp. - 'fromBase64' method has been moved to Util class and 'toBase64' method has also been added to that class. - 'KnownHosts' class for checking host-key in 'known_host' file. - 'examples/KnownHosts.java' has been added. - 'setUserName' and 'setPassword' methods have been added to Session class. - 'UserInfo' interface has been changed. - The implementation of compression has moved to 'com.jcraft.jsch.jcraft' package. - fixed a bug in handling 'SSH_MSG_CHANNEL_REQUET' request. - fixed a bug in sending multiple requests on a single session. Changes since version 0.0.10: - Diffie-Hellman key exchange 'diffie-hellman-group1-sha1' is supported. Refer to 'src/com/jcraft/jsch/jce/DHG1.java'. Thanks to Mitsugu Kitano, whose feedback was very helpful. - By the default, 'diffie-hellman-group1-sha1' will be used in the key exchange step. - The file attribute on 'SSH File Transfer Protocol' is supported. Now, we can say JSch supports 'SSH File Transfer Protocol'. - 'examples/Sftp.java' is updated. 'chgrp','chown','chmod' commands are supported. Changes since version 0.0.9: - SSH File Transfer Protocol is supported partially. - 'examples/Sftp.java' is added. This example is a tiny sftp command and supports 'cd','put','get','rm',etc. - 'close' method is added to Channel interface. - build.xml for examples is added. Thanks to Ronald Broberg. Changes since version 0.0.8: - the tunneling through a SOCKS5 proxy is supported. - 'examples/ScpFrom.java' is added. - 'com.jcraft.jsch.UserInfo' interface is modified. Changes since version 0.0.7: - Packet comression is supported. - 'examples/Compression.java' is added. - JZlib is included. Changes since version 0.0.6: - RSA host key is supported. - RSA public key authentication is supported. Changes since version 0.0.5: - DSA public key authentication is supported. - examples/UserAuthPubKey.java is added. - examples/ScpTo.java is added. Changes since version 0.0.4: - 3des-cbc is supported. - hmac-sha1 is supported. - hmac-md5-96 is supported. - hmac-sha1-96 is supported. Changes since version 0.0.3: - port forwarding, similar to the -L option of SSH. - examples/PortForwardingL.java is added. - examples/StreamForwarding.java is added. - examples/Exec.java is renamed as examples/Shell.java - stream forwarding is added. - ChannelSftp class is added for implementing filexfer. - interfaces for jsch users are changed. Changes since version 0.0.2: - remote exec is supported. - examples/Exec.java is added. - build.xml and some scripts for Ant are added. (lbruand) - Const class is added. (lbruand) Changes since version 0.0.1: - the tunneling via HTTP proxy is supported. - port forwarding like option -R of ssh command. the given port on the remote host will be forwarded to the given host and port on the local side. mwiede-jsch-c8efa3f/ChangeLog.md000066400000000000000000000443411465436372100166640ustar00rootroot00000000000000* [0.2.19](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.19) * Enforce DHGEX prime modulus bit length meets configured constraints. * #604 Fix possible rekeying timeouts. * [0.2.18](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.18) * Handle negated patterns according to ssh_config(5) by @bmiddaugh in https://github.com/mwiede/jsch/pull/565 * [0.2.17](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.17) * Add PBKDF2-HMAC-SHA512/256 & PBKDF2-HMAC-SHA512/224, which are both supported as of Java 21. * [0.2.16](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.16) * Add support for sntrup761x25519-sha512@openssh.com KEX algorithm. * Switch to bnd-maven-plugin in order to support Multi-Release OSGi bundle JAR's via supplemental manifest files. * Introduce JSchProxyException to replace generic JschException in Proxy implementations by @mvegter in https://github.com/mwiede/jsch/pull/467 * [0.2.15](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.15) * address [CVE-2023-48795](https://nvd.nist.gov/vuln/detail/CVE-2023-48795) by adding support for new strict key exchange extension * Add support for `ext-info-in-auth@openssh.com` extension * [0.2.14](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.14) * [#450](https://github.com/mwiede/jsch/issues/450) use Socket.connect() with a timeout that has been supported since Java 1.4 instead of using old method of creating a separate thread and joining to that thread with timeout. * [0.2.13](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.13) * #411 Add flush operation from Fix added is/jsch#39, with new config option to allow disabling in case it causes regressions. * #403 add a warning when Channel.getInputStream() or Channel.getExtInputStream() is called after Channel.connect(). * [0.2.12](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.12) * Further refine previous fixes for windows line endings in PEM keys from [#369](https://github.com/mwiede/jsch/issues/369) & [#362](https://github.com/mwiede/jsch/issues/362). * replace call to BigInteger.intValueExact to remain comptaible with Android [#397](https://github.com/mwiede/jsch/pull/397) * Introduce JSchSessionDisconnectException to allow the reasonCode to be retrieved without String parsing [#416](https://github.com/mwiede/jsch/pull/416) * Introduce specific JSchException for HostKey related failures [#410](https://github.com/mwiede/jsch/pull/410) * [0.2.11](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.11) * [#369](https://github.com/mwiede/jsch/issues/369) fix multi-line PEM key parsing to work with windows line endings due to regression from previous fix for [#362](https://github.com/mwiede/jsch/issues/362). * [0.2.10](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.10) * Fix new Java 21 compiler warning: `possible 'this' escape before subclass is fully initialized`. * Tweak OSGi bundle manifest to allow Log4j 3. * [#362](https://github.com/mwiede/jsch/issues/362) fix PEM key parsing to work with windows line endings. * [#361](https://github.com/mwiede/jsch/issues/361) guard against `UIKeyboardInteractive` implementations that include NULL elements in the `String[]` returned from `promptKeyboardInteractive()`. * Add a default implmentation of the deprecated `decrypt()` method to the `Identity` interface that throws an `UnsupportedOperationException`. * [0.2.9](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.9) * [#293](https://github.com/mwiede/jsch/issues/293) allow UserAuthNone to be extended. * Make JGSS module optional. * Tweak OSGi bundle manifest: * Avoid self-import. * Mark JGSS as optional. * Loosen import versions of dependencies. * Correctly adhere to the Multi-release JAR spec by ensuring all public classes under versioned directories preside over classes present in the top-level directory. * Eliminate stray `System.err.println()` calls. * Change PageantConnector to use JNA's built-in support for `User32.SendMessage()`. * [0.2.8](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.8) * [#287](https://github.com/mwiede/jsch/issues/287) add algorithm type information to algorithm negotiation logs. * [#289](https://github.com/mwiede/jsch/issues/289) wrap NoClassDefFoundError's for invalid private keys. * [0.2.7](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.7) * Fix exception logging in Log4j2Logger. * [#265](https://github.com/mwiede/jsch/issues/265) change buffer_margin computation to be dynamic based upon the MAC to allow connections that advertise small maximum packet sizes. * [#266](https://github.com/mwiede/jsch/issues/266) fix PuTTY key parsing to work with unix line endings. * Add support for ECDSA & EdDSA type PuTTY keys. * [#71](https://github.com/mwiede/jsch/issues/71) add support for PuTTY version 3 format keys. * Encrypted PuTTY version 3 format keys requires [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on). * Eliminate KeyPairDeferred and instead change handling of OpenSSH V1 type keys to be more like other KeyPair types. * Be more vigilant about clearing private key data. * Improve PKCS8 key handling and add support for PKCS5 2.1 encryption. * Add support for ECDSA type PKCS8 keys. * Add support for SCrypt type KDF for PKCS8 keys. * PKCS8 keys using SCrypt requires [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on). * Add support for EdDSA type PKCS8 keys. * EdDSA type PKCS8 keys requires [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on). * Attempt to authenticate using other signature algorithms supported by the same public key. * Allow this behavior to be disabled via `try_additional_pubkey_algorithms` config option. * Some servers incorrectly respond with `SSH_MSG_USERAUTH_PK_OK` to an initial auth query that they don't actually support for RSA keys. * Add a new config option `enable_pubkey_auth_query` to allow skipping auth queries and proceed directly to attempting full `SSH_MSG_USERAUTH_REQUEST`'s. * Add a new config option `enable_auth_none` to control whether an initial auth request for the method `none` is sent to detect all supported auth methods available on the server. * [0.2.6](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.6) * Include host alias instead of the real host in messages and exceptions by @ShadelessFox in https://github.com/mwiede/jsch/pull/257 * Fix missing keySize set when loading V1 RSA keys by @Alex-Vol-Amz in https://github.com/mwiede/jsch/pull/258 * Enhancement to present KeyPair.getKeyTypeString() method by @Alex-Vol-Amz in https://github.com/mwiede/jsch/pull/259 * [0.2.5](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.5) * Explictly free resources in `Compression` implementations in https://github.com/mwiede/jsch/pull/241 * Fix integration test failures on Apple Silicon by skipping OpenSSH 7.4 tests by @norrisjeremy in https://github.com/mwiede/jsch/pull/227 * generate osgi bundle manifest data for jar #248 by @mwiede in https://github.com/mwiede/jsch/pull/249 * [0.2.4](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.4) * When connections fail due to an algorithm negotiation failure, throw a `JSchAlgoNegoFailException` that extends `JSchException`. * The new `JSchAlgoNegoFailException` details which specific algorithm negotiation failed, along with what both JSch and the server proposed. * [0.2.3](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.3) * #188 fix private key length checks for ssh-ed25519 & ssh-ed448. by @norrisjeremy in https://github.com/mwiede/jsch/pull/189 * [0.2.2](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.2) * misc improvements by @norrisjeremy in https://github.com/mwiede/jsch/pull/152 * Fixing Issue #131 by @kimmerin in https://github.com/mwiede/jsch/pull/134 * [0.2.1](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.1) * Allow to set a Logger per JSch-instance rather than a VM-wide one [#128](https://github.com/mwiede/jsch/pull/128) * Preliminary changes prior to Javadoc work [#126](https://github.com/mwiede/jsch/pull/126) * Remove check to allow setting any filename encoding with any server version [#137](https://github.com/mwiede/jsch/issues/137) [#142](https://github.com/mwiede/jsch/pull/142) * [0.2.0](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.0) * Disable RSA/SHA1 signature algorithm by default [#75](https://github.com/mwiede/jsch/issues/75) * Add basic Logger implementations that can be optionally utilized with `JSch.setLogger()`: * JulLogger, using `java.util.logging.Logger` * JplLogger, using [Java 9's JEP 264](https://openjdk.java.net/jeps/264) * Log4j2Logger, using [Apache Log4j 2](https://logging.apache.org/log4j/2.x/) * Slf4jLogger, using [SLF4J](https://www.slf4j.org/) * Fix client version to be compliant with [RFC 4253 section 4.2](https://datatracker.ietf.org/doc/html/rfc4253#section-4.2) by not including minus sign characters [#115](https://github.com/mwiede/jsch/issues/115) * Add `java.util.zip` based compression implementation [#114](https://github.com/mwiede/jsch/issues/114) * This is based upon the [CompressionJUZ implementation](http://www.jcraft.com/jsch/examples/CompressionJUZ.java) posted to the [JSch-users mailing list](https://sourceforge.net/p/jsch/mailman/jsch-users/thread/201202031343.WAA19979%40jcraft.com/#msg28781313) in 2012 by the original JSch author * The existing JZlib implementation remains the default to maintain strict [RFC 4253 section 6.2](https://datatracker.ietf.org/doc/html/rfc4253#section-6.2) compliance * To use the new implementation globally, execute `JSch.setConfig("zlib@openssh.com", "com.jcraft.jsch.juz.Compression")` + `JSch.setConfig("zlib", "com.jcraft.jsch.juz.Compression")` * To use the new implementation per session, execute `session.setConfig("zlib@openssh.com", "com.jcraft.jsch.juz.Compression")` + `session.setConfig("zlib", "com.jcraft.jsch.juz.Compression")` * [0.1.72](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.72) * Switch chacha20-poly1305@openssh.com algorithm to a pure [Bouncy Castle](https://www.bouncycastle.org/java.html) based implementation * implement openssh config behavior to handle append, prepend and removal of algorithms [#104](https://github.com/mwiede/jsch/pull/104) * [0.1.71](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.71) * Address [#98](https://github.com/mwiede/jsch/issues/98) by restoring JSch.VERSION * [0.1.70](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.70) * Address [#89](https://github.com/mwiede/jsch/issues/89) by fixing rare ECDSA signature validation issue * Address [#93](https://github.com/mwiede/jsch/issues/93) by always setting the "want reply" flag for "env" type channel requests to false * [0.1.69](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.69) * Address [#83](https://github.com/mwiede/jsch/issues/83) by sending CR LF at the end of the identification string * Fix earlier change for [#76](https://github.com/mwiede/jsch/issues/76) that failed to correctly make the "Host" keyword case-insensitive * Fix PageantConnector struct class visibility [#86](https://github.com/mwiede/jsch/pull/86) * [0.1.68](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.68) * Added support for the rijndael-cbc@lysator.liu.se algorithm * Added support for the hmac-ripemd160, hmac-ripemd160@openssh.com and hmac-ripemd160-etm@openssh.com algorithms using [Bouncy Castle](https://www.bouncycastle.org/java.html) * Added support for various algorithms from [RFC 4253](https://datatracker.ietf.org/doc/html/rfc4253) and [RFC 4344](https://datatracker.ietf.org/doc/html/rfc4344) using [Bouncy Castle](https://www.bouncycastle.org/java.html) * cast128-cbc * cast128-ctr * twofish-cbc * twofish128-cbc * twofish128-ctr * twofish192-cbc * twofish192-ctr * twofish256-cbc * twofish256-ctr * Added support for the seed-cbc@ssh.com algorithm using [Bouncy Castle](https://www.bouncycastle.org/java.html) * Address [#76](https://github.com/mwiede/jsch/issues/76) by making the "Host" keyword case-insensitive * [0.1.67](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.67) * Added support for the blowfish-ctr algorithm from [RFC 4344](https://datatracker.ietf.org/doc/html/rfc4344) * Fix bug where ext-info-c was incorrectly advertised during rekeying * According to [RFC 8308 section 2.1](https://datatracker.ietf.org/doc/html/rfc8308#section-2.1), ext-info-c should only advertised during the first key exchange * Address [#77](https://github.com/mwiede/jsch/issues/77) by attempting to add compatibility with older [Bouncy Castle](https://www.bouncycastle.org/java.html) releases * [0.1.66](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.66) * Added support for [RFC 8308](https://datatracker.ietf.org/doc/html/rfc8308) extension negotiation and server-sig-algs extension * This support is enabled by default, but can be controlled via the enable_server_sig_algs config option (or `jsch.enable_server_sig_algs` system property) * When enabled and a server-sig-algs message is received from the server, the algorithms included by the server and also present in the PubkeyAcceptedKeyTypes config option will be attempted first when using publickey authentication * Additionally if the server is detected as OpenSSH version 7.4, the rsa-sha2-256 & rsa-sha2-512 algorithms will be added to the received server-sig-algs as a workaround for [OpenSSH bug 2680](https://bugzilla.mindrot.org/show_bug.cgi?id=2680) * Added support for various algorithms supported by Tectia (ssh.com): * diffie-hellman-group14-sha224@ssh.com * diffie-hellman-group14-sha256@ssh.com * diffie-hellman-group15-sha256@ssh.com * diffie-hellman-group15-sha384@ssh.com * diffie-hellman-group16-sha384@ssh.com * diffie-hellman-group16-sha512@ssh.com * diffie-hellman-group18-sha512@ssh.com * diffie-hellman-group-exchange-sha224@ssh.com * diffie-hellman-group-exchange-sha384@ssh.com * diffie-hellman-group-exchange-sha512@ssh.com * hmac-sha224@ssh.com * hmac-sha256@ssh.com * hmac-sha256-2@ssh.com * hmac-sha384@ssh.com * hmac-sha512@ssh.com * ssh-rsa-sha224@ssh.com * ssh-rsa-sha256@ssh.com * ssh-rsa-sha384@ssh.com * ssh-rsa-sha512@ssh.com * Added support for SHA224 to FingerprintHash * Fixing [#52](https://github.com/mwiede/jsch/issues/52) * Deprecate `void setFilenameEncoding(String encoding)` in favor of `void setFilenameEncoding(Charset encoding)` in `ChannelSftp` * Added support for rsa-sha2-256 & rsa-rsa2-512 algorithms to `ChannelAgentForwarding` * Address [#65](https://github.com/mwiede/jsch/issues/65) by adding ssh-agent support derived from [jsch-agent-proxy](https://github.com/ymnk/jsch-agent-proxy) * See `examples/JSchWithAgentProxy.java` for simple example * ssh-agent support requires either [Java 16's JEP 380](https://openjdk.java.net/jeps/380) or the addition of [junixsocket](https://github.com/kohlschutter/junixsocket) to classpath * Pageant support is untested & requires the addition of [JNA](https://github.com/java-native-access/jna) to classpath * Added support for the following algorithms with older Java releases by using [Bouncy Castle](https://www.bouncycastle.org/java.html): * ssh-ed25519 * ssh-ed448 * curve25519-sha256 * curve25519-sha256@libssh.org * curve448-sha512 * chacha20-poly1305@openssh.com * [0.1.65](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.65) * Added system properties to allow manipulation of various crypto algorithms used by default * Integrated JZlib, allowing use of zlib@openssh.com & zlib compressions without the need to provide the JZlib jar-file * Modularized the jar-file for use with Java 9 or newer * Added runtime controls for the min/max/preferred sizes used for diffie-hellman-group-exchange-sha256 & diffie-hellman-group-exchange-sha1 * Renamed PubkeyAcceptedKeyTypes config to PubkeyAcceptedAlgorithms to match recent changes in OpenSSH (PubkeyAcceptedKeyTypes is still accepted for backward compatibility) * Reduced number of algorithms that are runtime checked by default via CheckCiphers, CheckMacs, CheckKexes & CheckSignatures to improve runtime performance * Added config options dhgex_min, dhgex_max & dhgex_preferred to allow runtime manipulation of key size negotiation in diffie-hellman-group-exchange type Kex algorithms * Default values are: * dhgex_min = 2048 * dhgex_max = 8192 * dhgex_preferred = 3072 * [0.1.64](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.64) Fixing [#55](https://github.com/mwiede/jsch/pull/55) * [0.1.63](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.63) Fixing [#42](https://github.com/mwiede/jsch/issues/42) * [0.1.62](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.62) bugfixes and code cleanup * [0.1.61](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.61) * Add support for chacha20-poly1305@openssh.com, ssh-ed25519, ssh-ed448, curve448-sha512, diffie-hellman-group15-sha512 & diffie-hellman-group17-sha512. This makes use of the new EdDSA feature added in [Java 15's JEP 339](https://openjdk.java.net/jeps/339). [#17](https://github.com/mwiede/jsch/pull/17) * added integration test for public key authentication [#19](https://github.com/mwiede/jsch/pull/19) * [0.1.60](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.60) * support for openssh-v1-private-key format [opensshFormat.md](opensshFormat.md). * Fix bug with AEAD ciphers when compression is used. [#15](https://github.com/mwiede/jsch/pull/15) * [0.1.59](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.59) fixing issue from https://sourceforge.net/p/jsch/mailman/message/36872566/ * [0.1.58](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.58) support for more algorithms contributed by [@norrisjeremy](https://github.com/norrisjeremy) see [#4](https://github.com/mwiede/jsch/pull/4) * [0.1.57](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.57) support for rsa-sha2-256 and rsa-sha2-512. [#1](https://github.com/mwiede/jsch/pull/1) * [0.1.56](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.56) support for direct-streamlocal@openssh.com (see [SocketForwardingL.java](examples/SocketForwardingL.java)) mwiede-jsch-c8efa3f/LICENSE.JZlib.txt000066400000000000000000000031471465436372100173460ustar00rootroot00000000000000JZlib 0.0.* were released under the GNU LGPL license. Later, we have switched over to a BSD-style license. ------------------------------------------------------------------------------ Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mwiede-jsch-c8efa3f/LICENSE.jBCrypt.txt000066400000000000000000000015051465436372100177050ustar00rootroot00000000000000jBCrypt is subject to the following license: /* * Copyright (c) 2006 Damien Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ mwiede-jsch-c8efa3f/LICENSE.txt000066400000000000000000000031631465436372100163330ustar00rootroot00000000000000JSch 0.0.* was released under the GNU LGPL license. Later, we have switched over to a BSD-style license. ------------------------------------------------------------------------------ Copyright (c) 2002-2015 Atsuhiko Yamanaka, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mwiede-jsch-c8efa3f/README000066400000000000000000000212651465436372100153730ustar00rootroot00000000000000 JSch Java Secure Channel by ymnk@jcraft.com, JCraft,Inc. http://www.jcraft.com/jsch/ Last modified: Thu Mar 18 13:58:16 UTC 2015 Description =========== JSch is a pure Java implementation of SSH2. JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs. JSch is licensed under BSD style license. Documentation ============= * README files all over the source tree have info related to the stuff in the directories. * ChangeLog: what changed from the previous version? Directories & Files in the Source Tree ====================================== * src/com/ has source trees of JSch * example/ has some samples, which demonstrate the usages. * tools/ has scripts for Ant. Why JSch? ========== Our intension in developing this stuff is to enable users of our pure java X servers, WiredX(http://wiredx.net/) and WeirdX, to enjoy secure X sessions. Our efforts have mostly targeted the SSH2 protocol in relation to X Window System and X11 forwarding. Of course, we are also interested in adding other functionality - port forward, file transfer, terminal emulation, etc. Features ======== * JSch is in pure Java, but it depends on JavaTM Cryptography Extension (JCE). JSch is know to work with: o J2SE 1.4.0 or later (no additional libraries required). o J2SE 1.3 and Sun's JCE reference implementation that can be obtained at http://java.sun.com/products/jce/ o J2SE 1.2.2 and later and Bouncycastle's JCE implementation that can be obtained at http://www.bouncycastle.org/ * SSH2 protocol support. * Key exchange: diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha256, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521 * Cipher: blowfish-cbc,3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc 3des-ctr,aes128-ctr,aes192-ctr,aes256-ctc, arcfour,arcfour128,arcfour256 * MAC: hmac-md5,hmac-md5-96,hmac-sha1,hmac-sha1-96 * Host key type: ssh-dss,ssh-rsa, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521 * Userauth: password * Userauth: publickey(DSA,RSA,ECDSA) * Userauth: keyboard-interactive * Userauth: gssapi-with-mic * X11 forwarding. * xauth spoofing. * connection through HTTP proxy. * connection through SOCKS5, SOCKS4 proxy. * port forwarding. * stream forwarding. * signal sending. The unofficial patch for sshd of openssh will be find in the thread http://marc.theaimsgroup.com/?l=openssh-unix-dev&m=104295745607575&w=2 * envrironment variable passing. * remote exec. * generating DSA and RSA key pairs. * supporting private keys in OpenSSL(traditional SSLeay) and PKCS#8 format. * SSH File Transfer Protocol(version 0, 1, 2, 3) * partial authentication * packet compression: zlib, zlib@openssh.com JZlib(http://www.jcraft.com/jzlib/) has been used. * hashed known_hosts file. * NONE Cipher switching. http://www.psc.edu/networking/projects/hpn-ssh/none.php * JSch is licensed under BSD style license(refer to LICENSE.txt). How To Try ========== This archive does not include java byte code, so please compile the source code by your self. $ cd jsch-?.?.?/src $ javac com/jcraft/jsch/*java com/jcraft/jsch/jce/*java com/jcraft/jzlib/*.java '/examples/' directory has included some samples to demonstrate what JSch can do. Please refer to '/examples/README' file. AES cipher ========== JSch supports aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr, aes256-ctr but you require AES support in your J2SE to choose some of them. If you are using Sun's J2SE, J2SE 1.4.2 or later is required. And then, J2SE 1.4.2(or later) does not support aes256 by the default, because of 'import control restrictions of some countries'. We have confirmed that by applying "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 1.4.2" on http://java.sun.com/j2se/1.4.2/download.html#docs we can enjoy 'aes256-cbc,aes256-ctr'. Stream Forwarding ================= JSch has a unique functionality, Stream Forwarding. Stream Forwarding allows you to plug Java I/O streams directly into a remote TCP port without assigning and opening a local TCP port. In port forwarding, as with the -L option of ssh command, you have to assign and open a local TCP port and that port is also accessible by crackers on localhost. In some case, that local TCP port may be plugged to a secret port via SSH session. A sample program, /example/StreamForwarding.java , demonstrates this functionality. Generating Authentication Keys ============================== JSch allows you to generate DSA and RSA key pairs, which are in OpenSSH format. Please refer to 'examples/KeyGen.java'. Packet Compression ================== According to the draft from IETF sesch working group, the packet compression can be applied to each data stream directions; from sshd server to ssh client and from ssh client to sshd server. So, jsch allows you to choose which data stream direction will be compressed or not. For example, in X11 forwarding session, the packet compression for data stream from sshd to ssh client will save the network traffic, but usually the traffic from ssh client to sshd is light, so by omitting the compression for this direction, you may be able to save some CPU time. Please refer to a sample program 'examples/Compression.java'. Property ======== By setting properties, you can control the behavior of jsch. Here is an example of enabling the packet compression, Session session=jsch.getSession(user, host, 22); java.util.Properties config=new java.util.Properties(); config.put("compression.s2c", "zlib,none"); config.put("compression.c2s", "zlib,none"); session.setConfig(config); session.connect(); Current release has supported following properties, * compression.s2c: zlib, none default: none Specifies whether to use compression for the data stream from sshd to jsch. If "zlib,none" is given and the remote sshd does not allow the packet compression, compression will not be done. * compression.c2s: zlib, none default: none Specifies whether to use compression for the data stream from jsch to sshd. * StrictHostKeyChecking: ask | yes | no default: ask If this property is set to ``yes'', jsch will never automatically add host keys to the $HOME/.ssh/known_hosts file, and refuses to connect to hosts whose host key has changed. This property forces the user to manually add all new hosts. If this property is set to ``no'', jsch will automatically add new host keys to the user known hosts files. If this property is set to ``ask'', new host keys will be added to the user known host files only after the user has confirmed that is what they really want to do, and jsch will refuse to connect to hosts whose host key has changed. TODO ==== * re-implementation with java.nio. * replacing cipher, hash by JCE with pure Java code. * SSH File Transfer Protocol version 4. * error handling. Copyrights & Disclaimers ======================== JSch is copyrighted by ymnk, JCraft,Inc. and is licensed through BSD style license. Read the LICENSE.txt file for the complete license. Credits and Acknowledgments ============================ JSch has been developed by ymnk@jcraft.com and it can not be hacked without several help. * First of all, we want to thank JCE team at Sun Microsystems. For long time, we had planed to implement SSH2 in pure Java, but we had hesitated to do because tons of work must be done for implementing ciphers, hashes, etc., from the scratch. Thanks to newly added functionalities to J2SE 1.4.0, we could start this project. * We appreciate the OpenSSH project. The options '-ddd' of sshd, '---vvv' of ssh and the compile options '-DPACKET_DEBUG', '-DDEBUG_KEXDH' and '-DDEBUG_KEX' were very useful in debugging JSch. * We appreciate IETF sesch working group and SSH Communications Security Corp. Without the standardization of the protocol, we could not get the chance to implement JSch. * We appreciate Seigo Haruyama(http://www.unixuser.org/~haruyama/), who are interpreting drafts of SSH2 protocol in Japanese. His works were very useful for us to understand the technical terms in our native language. * We also appreciate SourceForge.net's awesome service to the Open Source Community. If you have any comments, suggestions and questions, write us at jsch@jcraft.com ``SSH is a registered trademark and Secure Shell is a trademark of SSH Communications Security Corp (www.ssh.com)''. mwiede-jsch-c8efa3f/Readme.md000066400000000000000000000203041465436372100162230ustar00rootroot00000000000000# Fork of JSch-0.1.55 See original [README](README) [![GitHub release](https://img.shields.io/github/v/tag/mwiede/jsch.svg)](https://github.com/mwiede/jsch/releases/latest) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.mwiede/jsch/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.mwiede/jsch) ![Java CI with Maven](https://github.com/mwiede/jsch/workflows/Java%20CI%20with%20Maven/badge.svg) ## Why should you use this library? As I explained in a [blog post](http://www.matez.de/index.php/2020/06/22/the-future-of-jsch-without-ssh-rsa/) the main points are: * OpenSSH has disabled ssh-rsa in [release 8.8](https://www.openssh.com/txt/release-8.8) per default and you need a library which supports rsa-sha2-256 and rsa-sha2-512. * Drop in replacement: just change dependency coordinates and you are good to go. * No active maintenance of [JSch at SourceForge](https://sourceforge.net/projects/jsch/). * Stay in sync with OpenJDK features so there is no need for additional dependencies. ## How to you use this library as a replacement for `com.jcraft:jsch` Make sure, that you only have one jsch dependency on your classpath. For example you can check the output of `mvn dependency:tree`. ### by replacing a direct maven dependency replace ```xml com.jcraft jsch 0.1.55 ``` with ```xml com.github.mwiede jsch 0.2.18 ``` ### by replacing jsch as a transitive maven dependency When you have an artifact `foo:bar`, which contains `com.jcraft:jsch` as a transitive dependency, you need to add `com.github.mwiede:jsch` as another dependency and exclude the jcraft one: ```xml com.github.mwiede jsch 0.2.18 foo bar com.jcraft jsch ``` *Addition*: You can further exclude any of `com.jcraft:jsch.agentproxy.jsch`, `com.jcraft:jsch.agentproxy.core` or `com.jcraft:jsch.agentproxy.pageant`, because these modules where integrated in this fork (see release notes of [0.1.66](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.66)). ## FAQ ### Which is the minimum Java version required? * Java 8. For more limitations, see next answer. ### Are ssh-ed25519, ssh-ed448, curve25519-sha256, curve448-sha512 & chacha20-poly1305@openssh.com supported? * This library is a [Multi-Release-jar](https://openjdk.org/jeps/238), which means that you can only use certain features when a more recent Java version is used. * In order to use ssh-ed25519 & ssh-ed448, you must use at least Java 15 or add [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on) to the classpath. * In order to use curve25519-sha256 & curve448-sha512, you must use at least Java 11 or add [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on) to the classpath. * In order to use chacha20-poly1305@openssh.com, you must add [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on) to the classpath. * As of the [0.1.66](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.66) release, these algorithms can now be used with older Java releases if [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on) is added to the classpath. * As of the [0.1.72](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.72) release, chacha20-poly1305@openssh.com can only be used if [Bouncy Castle](https://www.bouncycastle.org/java.html) (bcprov-jdk18on) is added to the classpath. ### Why do ssh-rsa type keys not work with this JSch fork and my server? * As of the [0.2.0](https://github.com/mwiede/jsch/releases/tag/jsch-0.2.0) release, the RSA/SHA1 signature algorithm is disabled by default. * SHA1 is no longer considered secure by the general cryptographic community and this JSch fork strives to maintain secure choices for default algorithms that it will utilize. * This also follows the lead of the OpenSSH project in which they disabled RSA/SHA1 signatures by default as of [OpenSSH release 8.8](https://www.openssh.com/txt/release-8.8). * ssh-rsa type keys continue to function by default with the RSA/SHA256 (rsa-sha2-256) & RSA/SHA512 (rsa-sha2-512) signature algorithms defined by [RFC 8332](https://datatracker.ietf.org/doc/html/rfc8332). * If your server only supports RSA/SHA1 signatures and you require their use in your application, then you will need to manually reenable them by one of the following means (also see wiki page [Jsch-Configuration](https://github.com/mwiede/jsch/wiki/Jsch-Configuration)): * Globally by adding "ssh-rsa" to the `jsch.server_host_key` + `jsch.client_pubkey` properties. * Globally by executing something similar to `JSch.setConfig("server_host_key", JSch.getConfig("server_host_key") + ",ssh-rsa")` + `JSch.setConfig("PubkeyAcceptedAlgorithms", JSch.getConfig("PubkeyAcceptedAlgorithms") + ",ssh-rsa")`. * On a per-session basis by executing something similar to `session.setConfig("server_host_key", session.getConfig("server_host_key") + ",ssh-rsa")` + `session.setConfig("PubkeyAcceptedAlgorithms", session.getConfig("PubkeyAcceptedAlgorithms") + ",ssh-rsa")`. * Adding "ssh-rsa" to your OpenSSH type config file with the "HostKeyAlgorithms" + "PubkeyAcceptedAlgorithms" keywords & then utilizing the `OpenSSHConfig` class. ### Is this fork 100% compatible with original JSch, because the connection to my server does not work any more! * For compatibility with OpenSSH and improved security, the order of crypto algorithms was changed. If you still want to use older or deprecated algorithms, you need to change the configuration. Examples see [#37](https://github.com/mwiede/jsch/issues/37), [#40](https://github.com/mwiede/jsch/issues/40) * To make it easier to adjust the crypto algorithms, starting with [0.1.65](https://github.com/mwiede/jsch/releases/tag/jsch-0.1.65) the following system properties can be set at your application's startup: * `jsch.kex` * analogous to `JSch.setConfig("kex", "...")` * `jsch.server_host_key` * analogous to `JSch.setConfig("server_host_key", "...")` * `jsch.prefer_known_host_key_types` * analogous to `JSch.setConfig("prefer_known_host_key_types", "...")` * `jsch.enable_server_sig_algs` * analogous to `JSch.setConfig("enable_server_sig_algs", "...")` * `jsch.cipher` * analogous to `JSch.setConfig("cipher.s2c", "...")` + `JSch.setConfig("cipher.c2s", "...")` * `jsch.mac` * analogous to `JSch.setConfig("mac.s2c", "...")` + `JSch.setConfig("mac.c2s", "...")` * `jsch.compression` * analogous to `JSch.setConfig("compression.s2c", "...")` + `JSch.setConfig("compression.c2s", "...")` * `jsch.lang` * analogous to `JSch.setConfig("lang.s2c", "...")` + `JSch.setConfig("lang.c2s", "...")` * `jsch.dhgex_min` * analogous to `JSch.setConfig("dhgex_min", "...")` * `jsch.dhgex_max` * analogous to `JSch.setConfig("dhgex_max", "...")` * `jsch.dhgex_preferred` * analogous to `JSch.setConfig("dhgex_preferred", "...")` * `jsch.compression_level` * analogous to `JSch.setConfig("compression_level", "...")` * `jsch.preferred_authentications` * analogous to `JSch.setConfig("PreferredAuthentications", "...")` * `jsch.client_pubkey` * analogous to `JSch.setConfig("PubkeyAcceptedAlgorithms", "...")` * `jsch.check_ciphers` * analogous to `JSch.setConfig("CheckCiphers", "...")` * `jsch.check_macs` * analogous to `JSch.setConfig("CheckMacs", "...")` * `jsch.check_kexes` * analogous to `JSch.setConfig("CheckKexes", "...")` * `jsch.check_signatures` * analogous to `JSch.setConfig("CheckSignatures", "...")` * `jsch.fingerprint_hash` * analogous to `JSch.setConfig("FingerprintHash", "...")` * `jsch.max_auth_tries` * analogous to `JSch.setConfig("MaxAuthTries", "...")` ## Changes since fork: See [ChangeLog.md](ChangeLog.md) mwiede-jsch-c8efa3f/eclipse-java-google-style.xml000066400000000000000000001062431465436372100222100ustar00rootroot00000000000000 mwiede-jsch-c8efa3f/examples/000077500000000000000000000000001465436372100163235ustar00rootroot00000000000000mwiede-jsch-c8efa3f/examples/AES.java000066400000000000000000000106341465436372100176020ustar00rootroot00000000000000/** This program will demonstrate how to use "aes128-cbc". */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class AES { public static void main(String[] arg) { try { JSch jsch = new JSch(); // jsch.setKnownHosts("/home/foo/.ssh/known_hosts"); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // session.setPassword("your password"); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.setConfig("cipher.s2c", "aes128-cbc,3des-cbc,blowfish-cbc"); session.setConfig("cipher.c2s", "aes128-cbc,3des-cbc,blowfish-cbc"); session.setConfig("CheckCiphers", "aes128-cbc"); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/ChangePassphrase.java000066400000000000000000000042221465436372100224050ustar00rootroot00000000000000/** * This program will demonstrate to change the passphrase for a private key file instead of creating * a new private key. A passphrase will be prompted if the given private-key has been encrypted. * After successfully loading the content of the private-key, the new passphrase will be prompted * and the given private-key will be re-encrypted with that new passphrase. */ import com.jcraft.jsch.JSch; import com.jcraft.jsch.KeyPair; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JTextField; public class ChangePassphrase { public static void main(String[] arg) { if (arg.length != 1) { System.err.println("usage: java ChangePassphrase private_key"); System.exit(-1); } JSch jsch = new JSch(); String pkey = arg[0]; try { KeyPair kpair = KeyPair.load(jsch, pkey); System.out .println(pkey + " has " + (kpair.isEncrypted() ? "been " : "not been ") + "encrypted"); String passphrase = ""; while (kpair.isEncrypted()) { JTextField passphraseField = new JPasswordField(20); Object[] ob = {passphraseField}; int result = JOptionPane.showConfirmDialog(null, ob, "Enter passphrase for " + pkey, JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) { System.exit(-1); } passphrase = passphraseField.getText(); if (!kpair.decrypt(passphrase)) { System.out.println("failed to decrypt " + pkey); } else { System.out.println(pkey + " is decrypted."); } } passphrase = ""; JTextField passphraseField = new JPasswordField(20); Object[] ob = {passphraseField}; int result = JOptionPane.showConfirmDialog(null, ob, "Enter new passphrase for " + pkey + " (empty for no passphrase)", JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) { System.exit(-1); } passphrase = passphraseField.getText(); kpair.writePrivateKey(pkey, passphrase.getBytes()); kpair.dispose(); } catch (Exception e) { System.out.println(e); } System.exit(0); } } mwiede-jsch-c8efa3f/examples/Compression.java000066400000000000000000000107551465436372100214770ustar00rootroot00000000000000/** * This program will demonstrate the packet compression. You will be asked username, hostname and * passwd. If everything works fine, you will get the shell prompt. In this program, all data from * sshd server to jsch will be compressed. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Compression { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.setConfig("compression.s2c", "zlib@openssh.com,zlib,none"); session.setConfig("compression.c2s", "zlib@openssh.com,zlib,none"); session.setConfig("compression_level", "9"); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/Daemon.java000066400000000000000000000127751465436372100204050ustar00rootroot00000000000000/** * This program will demonstrate how to provide a network service like inetd by using remote * port-forwarding functionality. */ import com.jcraft.jsch.ChannelForwardedTCPIP; import com.jcraft.jsch.ForwardedTCPIPDaemon; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Daemon { public static void main(String[] arg) { int rport; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String foo = JOptionPane.showInputDialog("Enter remote port number", "8888"); rport = Integer.parseInt(foo); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); // session.setPortForwardingR(rport, Parrot.class.getName()); session.setPortForwardingR(rport, "Daemon$Parrot"); System.out.println(host + ":" + rport + " <--> " + "Parrot"); } catch (Exception e) { System.out.println(e); } } public static class Parrot implements ForwardedTCPIPDaemon { ChannelForwardedTCPIP channel; Object[] arg; InputStream in; OutputStream out; @Override public void setChannel(ChannelForwardedTCPIP c, InputStream in, OutputStream out) { this.channel = c; this.in = in; this.out = out; } @Override public void setArg(Object[] arg) { this.arg = arg; } @Override public void run() { try { byte[] buf = new byte[1024]; System.out.println("remote port: " + channel.getRemotePort()); System.out.println("remote host: " + channel.getSession().getHost()); while (true) { int i = in.read(buf, 0, buf.length); if (i <= 0) break; out.write(buf, 0, i); out.flush(); if (buf[0] == '.') break; } } catch (JSchException e) { System.out.println("session is down."); } catch (IOException e) { } } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/Exec.java000066400000000000000000000133411465436372100200540ustar00rootroot00000000000000/** * This program will demonstrate remote exec. You will be asked username, hostname, displayname, * passwd and command. If everything works fine, given command will be invoked on the remote side * and outputs will be printed out. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.InputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Exec { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // String xhost = "127.0.0.1"; // int xport = 0; // String display = JOptionPane.showInputDialog("Enter display name", xhost + ":" + xport); // xhost = display.substring(0, display.indexOf(':')); // xport = Integer.parseInt(display.substring(display.indexOf(':') + 1)); // session.setX11Host(xhost); // session.setX11Port(xport + 6000); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); String command = JOptionPane.showInputDialog("Enter command", "set|grep SSH"); Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // X Forwarding // channel.setXForwarding(true); // channel.setInputStream(System.in); channel.setInputStream(null); // channel.setOutputStream(System.out); // OutputStream fos = new FileOutputStream("/tmp/stderr"); // ((ChannelExec) channel).setErrStream(fos); ((ChannelExec) channel).setErrStream(System.err); InputStream in = channel.getInputStream(); channel.connect(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; System.out.print(new String(tmp, 0, i)); } if (channel.isClosed()) { if (in.available() > 0) continue; System.out.println("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } channel.disconnect(); session.disconnect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/JSchWithAgentProxy.java000066400000000000000000000047011465436372100226740ustar00rootroot00000000000000import com.jcraft.jsch.AgentIdentityRepository; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelShell; import com.jcraft.jsch.IdentityRepository; import com.jcraft.jsch.JSch; import com.jcraft.jsch.SSHAgentConnector; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import javax.swing.JOptionPane; public class JSchWithAgentProxy { public static void main(String[] arg) { try { JSch jsch = new JSch(); // IdentityRepository irepo = new AgentIdentityRepository(new PageantConnector()); IdentityRepository irepo = new AgentIdentityRepository(new SSHAgentConnector()); jsch.setIdentityRepository(irepo); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); session.setConfig("PreferredAuthentications", "publickey"); // username and passphrase will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); ((ChannelShell) channel).setAgentForwarding(true); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { String passwd = null; @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { return true; } @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { return true; } @Override public void showMessage(String message) {} @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { String[] response = new String[prompt.length]; response[0] = passwd; return response; } } } mwiede-jsch-c8efa3f/examples/JumpHosts.java000066400000000000000000000124461465436372100211310ustar00rootroot00000000000000/** * This program will demonstrate SSH through jump hosts. Suppose that you don't have direct accesses * to host2 and host3. java JumpHosts usr1@host1 usr2@host2 usr3@host3. You will be asked passwords * for those destinations. If everything works fine, you will get file lists of your home-directory * at host3. */ import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class JumpHosts { public static void main(String[] arg) { try { JSch jsch = new JSch(); if (arg.length <= 1) { System.out.println("This program expects more arguments."); System.exit(-1); } Session session = null; Session[] sessions = new Session[arg.length]; String host = arg[0]; String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); sessions[0] = session = jsch.getSession(user, host, 22); session.setUserInfo(new MyUserInfo()); session.connect(); System.out.println("The session has been established to " + user + "@" + host); for (int i = 1; i < arg.length; i++) { host = arg[i]; user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); int assinged_port = session.setPortForwardingL(0, host, 22); System.out .println("portforwarding: " + "localhost:" + assinged_port + " -> " + host + ":" + 22); sessions[i] = session = jsch.getSession(user, "127.0.0.1", assinged_port); session.setUserInfo(new MyUserInfo()); session.setHostKeyAlias(host); session.connect(); System.out.println("The session has been established to " + user + "@" + host); } ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(); sftp.ls(".", new ChannelSftp.LsEntrySelector() { @Override public int select(ChannelSftp.LsEntry le) { System.out.println(le); return ChannelSftp.LsEntrySelector.CONTINUE; } }); sftp.disconnect(); for (int i = sessions.length - 1; i >= 0; i--) { sessions[i].disconnect(); } } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/KeyGen.java000066400000000000000000000051071465436372100203530ustar00rootroot00000000000000/** * This progam will demonstrate the keypair generation. You will be asked a passphrase for * output_keyfile. If everything works fine, you will get the keypair, output_keyfile and * output_keyfile+".pub". The private key and public key are in the OpenSSH format. */ import com.jcraft.jsch.JSch; import com.jcraft.jsch.KeyPair; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JTextField; public class KeyGen { public static void main(String[] arg) { int key_size = 1024; if (arg.length < 3) { System.err.println("usage: java KeyGen rsa output_keyfile comment\n" + " java KeyGen dsa output_keyfile comment\n" + " java KeyGen ecdsa-sha2-256 output_keyfile comment\n" + " java KeyGen ecdsa-sha2-384 output_keyfile comment\n" + " java KeyGen ecdsa-sha2-521 output_keyfile comment"); System.exit(-1); } String _type = arg[0]; int type = 0; if (_type.equals("rsa")) { type = KeyPair.RSA; } else if (_type.equals("dsa")) { type = KeyPair.DSA; } else if (_type.equals("ecdsa-sha2-nistp256")) { type = KeyPair.ECDSA; key_size = 256; } else if (_type.equals("ecdsa-sha2-nistp384")) { type = KeyPair.ECDSA; key_size = 384; } else if (_type.equals("ecdsa-sha2-nistp521")) { type = KeyPair.ECDSA; key_size = 521; } else { System.err.println("usage: java KeyGen rsa output_keyfile comment\n" + " java KeyGen dsa output_keyfile comment\n" + " java KeyGen ecdsa-sha2-256 output_keyfile comment\n" + " java KeyGen ecdsa-sha2-384 output_keyfile comment\n" + " java KeyGen ecdsa-sha2-521 output_keyfile comment"); System.exit(-1); } String filename = arg[1]; String comment = arg[2]; JSch jsch = new JSch(); String passphrase = ""; JTextField passphraseField = new JPasswordField(20); Object[] ob = {passphraseField}; int result = JOptionPane.showConfirmDialog(null, ob, "Enter passphrase (empty for no passphrase)", JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passphrase = passphraseField.getText(); } try { KeyPair kpair = KeyPair.genKeyPair(jsch, type, key_size); kpair.writePrivateKey(filename, passphrase.getBytes()); kpair.writePublicKey(filename + ".pub", comment); System.out.println("Finger print: " + kpair.getFingerPrint()); kpair.dispose(); } catch (Exception e) { System.out.println(e); } System.exit(0); } } mwiede-jsch-c8efa3f/examples/KnownHosts.java000066400000000000000000000127401465436372100213070ustar00rootroot00000000000000/** * This program will demonstrate the 'known_hosts' file handling. You will be asked username, * hostname, a path for 'known_hosts' and passwd. If everything works fine, you will get the shell * prompt. In current implementation, jsch only reads 'known_hosts' for checking and does not modify * it. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.HostKey; import com.jcraft.jsch.HostKeyRepository; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class KnownHosts { public static void main(String[] arg) { try { JSch jsch = new JSch(); JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Choose your known_hosts(ex. ~/.ssh/known_hosts)"); chooser.setFileHidingEnabled(false); int returnVal = chooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { System.out.println("You chose " + chooser.getSelectedFile().getAbsolutePath() + "."); jsch.setKnownHosts(chooser.getSelectedFile().getAbsolutePath()); } HostKeyRepository hkr = jsch.getHostKeyRepository(); HostKey[] hks = hkr.getHostKey(); if (hks != null) { System.out.println("Host keys in " + hkr.getKnownHostsRepositoryID()); for (HostKey hk : hks) { System.out.println(hk.getHost() + " " + hk.getType() + " " + hk.getFingerPrint(jsch)); } System.out.println(""); } String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); // In adding to known_hosts file, host names will be hashed. // session.setConfig("HashKnownHosts", "yes"); session.connect(); { HostKey hk = session.getHostKey(); System.out.println( "HostKey: " + hk.getHost() + " " + hk.getType() + " " + hk.getFingerPrint(jsch)); } Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { public String getPassword() { return passwd; } public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); public String getPassphrase() { return null; } public boolean promptPassphrase(String message) { return true; } public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/Logger.java000066400000000000000000000113371465436372100204120ustar00rootroot00000000000000/** This program will demonstrate how to enable logging mechanism and get logging messages. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Logger { public static void main(String[] arg) { try { JSch.setLogger(new MyLogger()); JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyLogger implements com.jcraft.jsch.Logger { static java.util.Map name = new java.util.HashMap<>(); static { name.put(DEBUG, "DEBUG: "); name.put(INFO, "INFO: "); name.put(WARN, "WARN: "); name.put(ERROR, "ERROR: "); name.put(FATAL, "FATAL: "); } @Override public boolean isEnabled(int level) { return true; } @Override public void log(int level, String message) { System.err.print(name.get(level)); System.err.println(message); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/OpenSSHConfig.java000066400000000000000000000101171465436372100215730ustar00rootroot00000000000000/** * This program demonsrates how to use OpenSSHConfig class. You will be asked username, hostname and * passwd. If everything works fine, you will get the shell prompt. Output may be ugly because of * lacks of terminal-emulation, but you can issue commands. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ConfigRepository; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import javax.swing.JOptionPane; public class OpenSSHConfig { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); String config = "Port 22\n" + "\n" + "Host foo\n" + " User " + user + "\n" + " Hostname " + host + "\n" + "Host *\n" + " ConnectTime 30000\n" + " PreferredAuthentications keyboard-interactive,password,publickey\n" + " #ForwardAgent yes\n" + " #StrictHostKeyChecking no\n" + " #IdentityFile ~/.ssh/id_rsa\n" + " #UserKnownHostsFile ~/.ssh/known_hosts"; System.out.println("Generated configurations:"); System.out.println(config); ConfigRepository configRepository = com.jcraft.jsch.OpenSSHConfig.parse(config); // com.jcraft.jsch.OpenSSHConfig.parseFile("~/.ssh/config"); jsch.setConfigRepository(configRepository); // "foo" is from "Host foo" in the above config. Session session = jsch.getSession("foo"); String passwd = JOptionPane.showInputDialog("Enter password"); session.setPassword(passwd); UserInfo ui = new MyUserInfo() { @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } @Override public boolean promptYesNo(String message) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, message, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } // If password is not given before the invocation of Session#connect(), // implement also following methods, // * UserInfo#getPassword(), // * UserInfo#promptPassword(String message) and // * UIKeyboardInteractive#promptKeyboardInteractive() }; session.setUserInfo(ui); session.connect(); // making a connection with timeout as defined above. Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); // a hack for MS-DOS prompt on Windows. // channel.setInputStream(new FilterInputStream(System.in) { // @Override // public int read(byte[] b, int off, int len) throws IOException { // return in.read(b, off, len > 1024 ? 1024 : len); // } // }); channel.setOutputStream(System.out); // Choose the pty-type "vt102". // ((ChannelShell) channel).setPtyType("vt102"); // Set environment variable "LANG" as "ja_JP.eucJP". // ((ChannelShell) channel).setEnv("LANG", "ja_JP.eucJP"); // channel.connect(); channel.connect(3 * 1000); } catch (Exception e) { System.out.println(e); } } public abstract static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return null; } @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return false; } @Override public boolean promptPassword(String message) { return false; } @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { return null; } } } mwiede-jsch-c8efa3f/examples/PortForwardingL.java000066400000000000000000000115161465436372100222550ustar00rootroot00000000000000/** * This program will demonstrate the port forwarding like option -L of ssh command. The given port * on the local host will be forwarded to the given remote host and port on the remote side. You * will be asked username, hostname, port:host:hostport and passwd. If everything works fine, you * will get the shell prompt. Try the port on localhost. */ import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class PortForwardingL { public static void main(String[] arg) { int lport; String rhost; int rport; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String foo = JOptionPane.showInputDialog("Enter -L port:host:hostport", "port:host:hostport"); lport = Integer.parseInt(foo.substring(0, foo.indexOf(':'))); foo = foo.substring(foo.indexOf(':') + 1); rhost = foo.substring(0, foo.indexOf(':')); rport = Integer.parseInt(foo.substring(foo.indexOf(':') + 1)); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); // Channel channel = session.openChannel("shell"); // channel.connect(); int assinged_port = session.setPortForwardingL(lport, rhost, rport); System.out.println("localhost:" + assinged_port + " -> " + rhost + ":" + rport); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/PortForwardingR.java000066400000000000000000000114541465436372100222640ustar00rootroot00000000000000/** * This program will demonstrate the port forwarding like option -R of ssh command; the given port * on the remote host will be forwarded to the given host and port on the local side. You will be * asked username, hostname, port:host:hostport and passwd. If everything works fine, you will get * the shell prompt. Try the port on remote host. */ import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class PortForwardingR { public static void main(String[] arg) { int rport; String lhost; int lport; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String foo = JOptionPane.showInputDialog("Enter -R port:host:hostport", "port:host:hostport"); rport = Integer.parseInt(foo.substring(0, foo.indexOf(':'))); foo = foo.substring(foo.indexOf(':') + 1); lhost = foo.substring(0, foo.indexOf(':')); lport = Integer.parseInt(foo.substring(foo.indexOf(':') + 1)); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); // Channel channel = session.openChannel("shell"); // channel.connect(); session.setPortForwardingR(rport, lhost, lport); System.out.println(host + ":" + rport + " -> " + lhost + ":" + lport); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/README000066400000000000000000000165771465436372100172230ustar00rootroot00000000000000 README of example directory ==================================================================== Last modified: Wed Oct 16 13:53:12 UTC 2002 This directory contains some examples, which demonstrate how to use JSch - Shell.java This program enables you to connect to sshd server and get the shell prompt. $ CLASSPATH=.:../build javac Shell.java $ CLASSPATH=.:../build java Shell You will be asked username, hostname and passwd. If everything works fine, you will get the shell prompt. Output will be ugly because of lacks of terminal-emulation, but you can issue commands. - X11Forwarding.java This program will demonstrate X11 forwarding. $ CLASSPATH=.:../build javac X11Forwarding.java $ CLASSPATH=.:../build java X11Forwarding You will be asked username, hostname, displayname and passwd. If your X server does not run at 127.0.0.1, please enter correct displayname. If everything works fine, you will get the shell prompt. Try X applications; for example, xlogo. - Exec.java This program will demonstrate remote exec. $ CLASSPATH=.:../build javac Exec.java $ CLASSPATH=.:../build java Exec You will be asked username, hostname, displayname, passwd and command. If everything works fine, given command will be invoked on the remote side and outputs will be printed out. - ViaHTTP.java This program will demonstrate the ssh session via HTTP proxy. $ CLASSPATH=.:../build javac ViaHTTP.java $ CLASSPATH=.:../build java ViaHTTP You will be asked username, hostname, proxy-server and passwd. If everything works fine, you will get the shell prompt. - ViaSOCKS.java This program will demonstrate the ssh session via SOCKS proxy. $ CLASSPATH=.:../build javac ViaSOCKS.java $ CLASSPATH=.:../build java ViaSOCKS You will be asked username, hostname, proxy-server and passwd. If everything works fine, you will get the shell prompt. - PortForwardingR.java This program will demonstrate the port forwarding like option -R of ssh command; the given port on the remote host will be forwarded to the given host and port on the local side. $ CLASSPATH=.:../build javac PortForwardingR.java $ CLASSPATH=.:../build java PortForwardingR You will be asked username, hostname, port:host:hostport and passwd. If everything works fine, you will get the shell prompt. Try the port on remote host. - PortForwardingL.java This program will demonstrate the port forwarding like option -L of ssh command; the given port on the local host will be forwarded to the given remote host and port on the remote side. $ CLASSPATH=.:../build javac PortForwardingL.java $ CLASSPATH=.:../build java PortForwardingL You will be asked username, hostname, port:host:hostport and passwd. If everything works fine, you will get the shell prompt. Try the port on localhost. - StreamForwarding.java This program will demonstrate the stream forwarding. The given Java I/O streams will be forwared to the given remote host and port on the remote side. It is simmilar to the -L option of ssh command, but you don't have to assign and open a local tcp port. $ CLASSPATH=.:../build javac StreamForwarding.java $ CLASSPATH=.:../build java StreamForwarding You will be asked username, hostname, host:hostport and passwd. If everything works fine, System.in and System.out streams will be forwared to remote port and you can send messages from command line. - UserAuthPubKey.java This program will demonstrate the user authentification by public key. $ CLASSPATH=.:../build javac UserAuthPubKey.java $ CLASSPATH=.:../build java UserAuthPubKey You will be asked username, hostname, privatekey(id_dsa) and passphrase. If everything works fine, you will get the shell prompt - Compression.java This program will demonstrate the packet compression. $ CLASSPATH=.:../build javac Compression.java $ CLASSPATH=.:../build java Compression You will be asked username, hostname and passwd. If everything works fine, you will get the shell prompt. In this program, all data from sshd server to jsch will be compressed. - ScpTo.java This program will demonstrate the file transfer from local to remote. $ CLASSPATH=.:../build javac ScpTo.java $ CLASSPATH=.:../build java ScpTo file1 user@remotehost:file2 You will be asked passwd. If everything works fine, a local file 'file1' will copied to 'file2' on 'remotehost'. - ScpFrom.java This program will demonstrate the file transfer from remote to local $ CLASSPATH=.:../build javac ScpFrom.java $ CLASSPATH=.:../build java ScpFrom user@remotehost:file1 file2 You will be asked passwd. If everything works fine, a file 'file1' on 'remotehost' will copied to local 'file1'. - Sftp.java This program will demonstrate the sftp protocol support. $ CLASSPATH=.:../build javac Sftp.java $ CLASSPATH=.:../build java Sftp You will be asked username, host and passwd. If everything works fine, you will get a prompt 'sftp>'. 'help' command will show available command. In current implementation, the destination path for 'get' and 'put' commands must be a file, not a directory. - KnownHosts.java This program will demonstrate the 'known_hosts' file handling. $ CLASSPATH=.:../build javac KnownHosts.java $ CLASSPATH=.:../build java KnownHosts You will be asked username, hostname, a path for 'known_hosts' and passwd. If everything works fine, you will get the shell prompt. In current implementation, jsch only reads 'known_hosts' for checking and does not modify it. - UserAuthKI.java This program will demonstrate the keyboard-interactive authentication. $ CLASSPATH=.:../build javac UserAuthKI.java $ CLASSPATH=.:../build java UserAuthKI If the remote sshd supports keyboard-interactive authentication, you will be prompted. - KeyGen.java This progam will demonstrate the DSA keypair generation. $ CLASSPATH=.:../build javac KeyGen.java $ CLASSPATH=.:../build java KeyGen rsa output_keyfile comment or $ CLASSPATH=.:../build java KeyGen dsa output_keyfile comment You will be asked a passphrase for output_keyfile. If everything works fine, you will get the DSA or RSA keypair, output_keyfile and output_keyfile+".pub". The private key and public key are in the OpenSSH format. - ChangePassphrase.java This program will demonstrate to change the passphrase for a private key file instead of creating a new private key. $ CLASSPATH=.:../build javac ChangePassphrase.java $ CLASSPATH=.:../build java ChangePassphrase private-key A passphrase will be prompted if the given private-key has been encrypted. After successfully loading the content of the private-key, the new passphrase will be prompted and the given private-key will be re-encrypted with that new passphrase. - AES.java This program will demonstrate how to use "aes128-cbc". - Daemon.java This program will demonstrate how to provide a network service like inetd by using remote port-forwarding functionality. - Logger.java This program will demonstrate how to enable logging mechanism and get logging messages. - Subsystem.java This program will demonstrate how to use the Subsystem channel. - Sudo.java This program will demonstrate how to exec 'sudo' on the remote. - ScpToNoneCipher.java This program will demonstrate how to enable none cipher. - JumpHosts.java This program will demonstrate SSH through jump hosts. - OpenSSHConfig.java This program will demonstrate how OpenSSH's config is supported. mwiede-jsch-c8efa3f/examples/ScpFrom.java000066400000000000000000000160651465436372100205470ustar00rootroot00000000000000/** * This program will demonstrate the file transfer from remote to local. If everything works fine, a * file 'file1' on 'remotehost' will copied to local 'file1'. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class ScpFrom { public static void main(String[] arg) { if (arg.length != 2) { System.err.println("usage: java ScpFrom user@remotehost:file1 file2"); System.exit(-1); } try { String user = arg[0].substring(0, arg[0].indexOf('@')); arg[0] = arg[0].substring(arg[0].indexOf('@') + 1); String host = arg[0].substring(0, arg[0].indexOf(':')); String rfile = arg[0].substring(arg[0].indexOf(':') + 1); String lfile = arg[1]; String prefix = null; if (new File(lfile).isDirectory()) { prefix = lfile + File.separator; } JSch jsch = new JSch(); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); // exec 'scp -f rfile' remotely rfile = rfile.replace("'", "'\"'\"'"); rfile = "'" + rfile + "'"; String command = "scp -f " + rfile; Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); byte[] buf = new byte[1024]; // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); while (true) { int c = checkAck(in); if (c != 'C') { break; } // read '0644 ' in.read(buf, 0, 5); long filesize = 0L; while (true) { if (in.read(buf, 0, 1) < 0) { // error break; } if (buf[0] == ' ') break; filesize = filesize * 10L + (long) (buf[0] - '0'); } String file = null; for (int i = 0;; i++) { in.read(buf, i, 1); if (buf[i] == (byte) 0x0a) { file = new String(buf, 0, i); break; } } // System.out.println("filesize=" + filesize + ", file=" + file); // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); // read a content of lfile try (OutputStream fos = new FileOutputStream(prefix == null ? lfile : prefix + file)) { int foo; while (true) { if (buf.length < filesize) foo = buf.length; else foo = (int) filesize; foo = in.read(buf, 0, foo); if (foo < 0) { // error break; } fos.write(buf, 0, foo); filesize -= foo; if (filesize == 0L) break; } } if (checkAck(in) != 0) { System.exit(0); } // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); } session.disconnect(); System.exit(0); } catch (Exception e) { System.out.println(e); } } static int checkAck(InputStream in) throws IOException { int b = in.read(); // b may be 0 for success, // 1 for error, // 2 for fatal error, // -1 if (b == 0) return b; if (b == -1) return b; if (b == 1 || b == 2) { StringBuilder sb = new StringBuilder(); int c; do { c = in.read(); sb.append((char) c); } while (c != '\n'); if (b == 1) { // error System.out.print(sb); } if (b == 2) { // fatal error System.out.print(sb); } } return b; } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/ScpTo.java000066400000000000000000000152721465436372100202250ustar00rootroot00000000000000/** * This program will demonstrate the file transfer from local to remote. You will be asked passwd. * If everything works fine, a local file 'file1' will copied to 'file2' on 'remotehost'. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class ScpTo { public static void main(String[] arg) { if (arg.length != 2) { System.err.println("usage: java ScpTo file1 user@remotehost:file2"); System.exit(-1); } try { String lfile = arg[0]; String user = arg[1].substring(0, arg[1].indexOf('@')); arg[1] = arg[1].substring(arg[1].indexOf('@') + 1); String host = arg[1].substring(0, arg[1].indexOf(':')); String rfile = arg[1].substring(arg[1].indexOf(':') + 1); JSch jsch = new JSch(); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); // exec 'scp -t rfile' remotely rfile = rfile.replace("'", "'\"'\"'"); rfile = "'" + rfile + "'"; String command = "scp -p -t " + rfile; Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); if (checkAck(in) != 0) { System.exit(0); } File _lfile = new File(lfile); command = "T " + (_lfile.lastModified() / 1000) + " 0"; // The access time should be sent here, // but it is not accessible with JavaAPI ;-< command += " " + (_lfile.lastModified() / 1000) + " 0\n"; out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.exit(0); } // send "C0644 filesize filename", where filename should not include '/' long filesize = _lfile.length(); command = "C0644 " + filesize + " "; if (lfile.lastIndexOf('/') > 0) { command += lfile.substring(lfile.lastIndexOf('/') + 1); } else { command += lfile; } command += "\n"; out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.exit(0); } byte[] buf = new byte[1024]; // send a content of lfile try (InputStream fis = new FileInputStream(lfile)) { while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) break; out.write(buf, 0, len); // out.flush(); } } // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); if (checkAck(in) != 0) { System.exit(0); } session.disconnect(); System.exit(0); } catch (Exception e) { System.out.println(e); } } static int checkAck(InputStream in) throws IOException { int b = in.read(); // b may be 0 for success, // 1 for error, // 2 for fatal error, // -1 if (b == 0) return b; if (b == -1) return b; if (b == 1 || b == 2) { StringBuilder sb = new StringBuilder(); int c; do { c = in.read(); sb.append((char) c); } while (c != '\n'); if (b == 1) { // error System.out.print(sb); } if (b == 2) { // fatal error System.out.print(sb); } } return b; } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/ScpToNoneCipher.java000066400000000000000000000155601465436372100222000ustar00rootroot00000000000000/** * This program will demonstrate how to enable none cipher. You will be asked passwd. If everything * works fine, a local file 'file1' will copied to 'file2' on 'remotehost'. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class ScpToNoneCipher { public static void main(String[] arg) { if (arg.length != 2) { System.err.println("usage: java ScpTo file1 user@remotehost:file2"); System.exit(-1); } try { String lfile = arg[0]; String user = arg[1].substring(0, arg[1].indexOf('@')); arg[1] = arg[1].substring(arg[1].indexOf('@') + 1); String host = arg[1].substring(0, arg[1].indexOf(':')); String rfile = arg[1].substring(arg[1].indexOf(':') + 1); JSch jsch = new JSch(); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); session.setConfig("cipher.s2c", "none,aes128-cbc,3des-cbc,blowfish-cbc"); session.setConfig("cipher.c2s", "none,aes128-cbc,3des-cbc,blowfish-cbc"); session.rekey(); // exec 'scp -t rfile' remotely rfile = rfile.replace("'", "'\"'\"'"); rfile = "'" + rfile + "'"; String command = "scp -p -t " + rfile; Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); if (checkAck(in) != 0) { System.exit(0); } File _lfile = new File(lfile); command = "T " + (_lfile.lastModified() / 1000) + " 0"; // The access time should be sent here, // but it is not accessible with JavaAPI ;-< command += " " + (_lfile.lastModified() / 1000) + " 0\n"; out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.exit(0); } // send "C0644 filesize filename", where filename should not include '/' long filesize = _lfile.length(); command = "C0644 " + filesize + " "; if (lfile.lastIndexOf('/') > 0) { command += lfile.substring(lfile.lastIndexOf('/') + 1); } else { command += lfile; } command += "\n"; out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.exit(0); } byte[] buf = new byte[1024]; // send a content of lfile try (InputStream fis = new FileInputStream(lfile)) { while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) break; out.write(buf, 0, len); // out.flush(); } } // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); if (checkAck(in) != 0) { System.exit(0); } session.disconnect(); System.exit(0); } catch (Exception e) { System.out.println(e); } } static int checkAck(InputStream in) throws IOException { int b = in.read(); // b may be 0 for success, // 1 for error, // 2 for fatal error, // -1 if (b == 0) return b; if (b == -1) return b; if (b == 1 || b == 2) { StringBuilder sb = new StringBuilder(); int c; do { c = in.read(); sb.append((char) c); } while (c != '\n'); if (b == 1) { // error System.out.print(sb); } if (b == 2) { // fatal error System.out.print(sb); } } return b; } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/Sftp.java000066400000000000000000000426641465436372100201160ustar00rootroot00000000000000/** * This program will demonstrate the sftp protocol support. If everything works fine, you will get a * prompt 'sftp>'. 'help' command will show available command. In current implementation, the * destination path for 'get' and 'put' commands must be a file, not a directory. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpATTRS; import com.jcraft.jsch.SftpException; import com.jcraft.jsch.SftpProgressMonitor; import com.jcraft.jsch.SftpStatVFS; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.ProgressMonitor; public class Sftp { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); int port = 22; Session session = jsch.getSession(user, host, port); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("sftp"); channel.connect(); ChannelSftp c = (ChannelSftp) channel; java.io.InputStream in = System.in; java.io.PrintStream out = System.out; java.util.List cmds = new java.util.ArrayList<>(); byte[] buf = new byte[1024]; int i; String str; int level = 0; while (true) { out.print("sftp> "); cmds.clear(); i = in.read(buf, 0, 1024); if (i <= 0) break; i--; if (i > 0 && buf[i - 1] == 0x0d) i--; // str = new String(buf, 0, i); // System.out.println("|" + str + "|"); int s = 0; for (int ii = 0; ii < i; ii++) { if (buf[ii] == ' ') { if (ii - s > 0) { cmds.add(new String(buf, s, ii - s)); } while (ii < i) { if (buf[ii] != ' ') break; ii++; } s = ii; } } if (s < i) { cmds.add(new String(buf, s, i - s)); } if (cmds.isEmpty()) continue; String cmd = cmds.get(0); if (cmd.equals("quit")) { c.quit(); break; } if (cmd.equals("exit")) { c.exit(); break; } if (cmd.equals("rekey")) { session.rekey(); continue; } if (cmd.equals("compression")) { if (cmds.size() < 2) { out.println("compression level: " + level); continue; } try { level = Integer.parseInt(cmds.get(1)); if (level == 0) { session.setConfig("compression.s2c", "none"); session.setConfig("compression.c2s", "none"); } else { session.setConfig("compression.s2c", "zlib@openssh.com,zlib,none"); session.setConfig("compression.c2s", "zlib@openssh.com,zlib,none"); } } catch (Exception e) { } session.rekey(); continue; } if (cmd.equals("cd") || cmd.equals("lcd")) { if (cmds.size() < 2) continue; String path = cmds.get(1); try { if (cmd.equals("cd")) c.cd(path); else c.lcd(path); } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("rm") || cmd.equals("rmdir") || cmd.equals("mkdir")) { if (cmds.size() < 2) continue; String path = cmds.get(1); try { if (cmd.equals("rm")) c.rm(path); else if (cmd.equals("rmdir")) c.rmdir(path); else c.mkdir(path); } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("chgrp") || cmd.equals("chown") || cmd.equals("chmod")) { if (cmds.size() != 3) continue; String path = cmds.get(2); int foo = 0; if (cmd.equals("chmod")) { byte[] bar = cmds.get(1).getBytes(); for (int k : bar) { if (k < '0' || k > '7') { foo = -1; break; } foo <<= 3; foo |= (k - '0'); } if (foo == -1) continue; } else { try { foo = Integer.parseInt(cmds.get(1)); } catch (Exception e) { continue; } } try { if (cmd.equals("chgrp")) { c.chgrp(foo, path); } else if (cmd.equals("chown")) { c.chown(foo, path); } else if (cmd.equals("chmod")) { c.chmod(foo, path); } } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("pwd") || cmd.equals("lpwd")) { str = (cmd.equals("pwd") ? "Remote" : "Local"); str += " working directory: "; if (cmd.equals("pwd")) str += c.pwd(); else str += c.lpwd(); out.println(str); continue; } if (cmd.equals("ls") || cmd.equals("dir")) { String path = "."; if (cmds.size() == 2) path = cmds.get(1); try { java.util.Vector vv = c.ls(path); if (vv != null) { for (ChannelSftp.LsEntry le : vv) { // out.println(le); out.println(le.getLongname()); } } } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("lls") || cmd.equals("ldir")) { String path = "."; if (cmds.size() == 2) path = cmds.get(1); try { java.io.File file = new java.io.File(path); if (!file.exists()) { out.println(path + ": No such file or directory"); continue; } if (file.isDirectory()) { String[] list = file.list(); for (String l : list) { out.println(l); } continue; } out.println(path); } catch (Exception e) { System.out.println(e); } continue; } if (cmd.equals("get") || cmd.equals("get-resume") || cmd.equals("get-append") || cmd.equals("put") || cmd.equals("put-resume") || cmd.equals("put-append")) { if (cmds.size() != 2 && cmds.size() != 3) continue; String p1 = cmds.get(1); // String p2 = p1; String p2 = "."; if (cmds.size() == 3) p2 = cmds.get(2); try { SftpProgressMonitor monitor = new MyProgressMonitor(); if (cmd.startsWith("get")) { int mode = ChannelSftp.OVERWRITE; if (cmd.equals("get-resume")) { mode = ChannelSftp.RESUME; } else if (cmd.equals("get-append")) { mode = ChannelSftp.APPEND; } c.get(p1, p2, monitor, mode); } else { int mode = ChannelSftp.OVERWRITE; if (cmd.equals("put-resume")) { mode = ChannelSftp.RESUME; } else if (cmd.equals("put-append")) { mode = ChannelSftp.APPEND; } c.put(p1, p2, monitor, mode); } } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("ln") || cmd.equals("symlink") || cmd.equals("rename") || cmd.equals("hardlink")) { if (cmds.size() != 3) continue; String p1 = cmds.get(1); String p2 = cmds.get(2); try { if (cmd.equals("hardlink")) { c.hardlink(p1, p2); } else if (cmd.equals("rename")) c.rename(p1, p2); else c.symlink(p1, p2); } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("df")) { if (cmds.size() > 2) continue; String p1 = cmds.size() == 1 ? "." : cmds.get(1); SftpStatVFS stat = c.statVFS(p1); long size = stat.getSize(); long used = stat.getUsed(); long avail = stat.getAvailForNonRoot(); long root_avail = stat.getAvail(); long capacity = stat.getCapacity(); System.out.println("Size: " + size); System.out.println("Used: " + used); System.out.println("Avail: " + avail); System.out.println("(root): " + root_avail); System.out.println("%Capacity: " + capacity); continue; } if (cmd.equals("stat") || cmd.equals("lstat")) { if (cmds.size() != 2) continue; String p1 = cmds.get(1); SftpATTRS attrs = null; try { if (cmd.equals("stat")) attrs = c.stat(p1); else attrs = c.lstat(p1); } catch (SftpException e) { System.out.println(e); } if (attrs != null) { out.println(attrs); } else { } continue; } if (cmd.equals("readlink")) { if (cmds.size() != 2) continue; String p1 = cmds.get(1); String filename = null; try { filename = c.readlink(p1); out.println(filename); } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("realpath")) { if (cmds.size() != 2) continue; String p1 = cmds.get(1); String filename = null; try { filename = c.realpath(p1); out.println(filename); } catch (SftpException e) { System.out.println(e); } continue; } if (cmd.equals("version")) { out.println("SFTP protocol version " + c.version()); continue; } if (cmd.equals("help") || cmd.equals("?")) { out.println(help); continue; } out.println("unimplemented command: " + cmd); } session.disconnect(); } catch (Exception e) { System.out.println(e); } System.exit(0); } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } public static class MyProgressMonitor implements SftpProgressMonitor { ProgressMonitor monitor; long count = 0; long max = 0; @Override public void init(int op, String src, String dest, long max) { this.max = max; monitor = new ProgressMonitor(null, ((op == SftpProgressMonitor.PUT) ? "put" : "get") + ": " + src, "", 0, (int) max); count = 0; percent = -1; monitor.setProgress((int) this.count); monitor.setMillisToDecideToPopup(1000); } private long percent = -1; @Override public boolean count(long count) { this.count += count; if (percent >= this.count * 100 / max) { return true; } percent = this.count * 100 / max; monitor.setNote("Completed " + this.count + "(" + percent + "%) out of " + max + "."); monitor.setProgress((int) this.count); return !(monitor.isCanceled()); } @Override public void end() { monitor.close(); } } private static String help = " Available commands:\n" + " * means unimplemented command.\n" + "cd path Change remote directory to 'path'\n" + "lcd path Change local directory to 'path'\n" + "chgrp grp path Change group of file 'path' to 'grp'\n" + "chmod mode path Change permissions of file 'path' to 'mode'\n" + "chown own path Change owner of file 'path' to 'own'\n" + "df [path] Display statistics for current directory or\n" + " filesystem containing 'path'\n" + "help Display this help text\n" + "get remote-path [local-path] Download file\n" + "get-resume remote-path [local-path] Resume to download file.\n" + "get-append remote-path [local-path] Append remote file to local file\n" + "hardlink oldpath newpath Hardlink remote file\n" + "*lls [ls-options [path]] Display local directory listing\n" + "ln oldpath newpath Symlink remote file\n" + "*lmkdir path Create local directory\n" + "lpwd Print local working directory\n" + "ls [path] Display remote directory listing\n" + "*lumask umask Set local umask to 'umask'\n" + "mkdir path Create remote directory\n" + "put local-path [remote-path] Upload file\n" + "put-resume local-path [remote-path] Resume to upload file\n" + "put-append local-path [remote-path] Append local file to remote file.\n" + "pwd Display remote working directory\n" + "stat path Display info about path\n" + "exit Quit sftp\n" + "quit Quit sftp\n" + "rename oldpath newpath Rename remote file\n" + "rmdir path Remove remote directory\n" + "rm path Delete remote file\n" + "symlink oldpath newpath Symlink remote file\n" + "readlink path Check the target of a symbolic link\n" + "realpath path Canonicalize the path\n" + "rekey Key re-exchanging\n" + "compression level Packet compression will be enabled\n" + "version Show SFTP version\n" + "? Synonym for help"; } mwiede-jsch-c8efa3f/examples/Shell.java000066400000000000000000000072241465436372100202420ustar00rootroot00000000000000/** * This program enables you to connect to sshd server and get the shell prompt. You will be asked * username, hostname and passwd. If everything works fine, you will get the shell prompt. Output * may be ugly because of lacks of terminal-emulation, but you can issue commands. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import javax.swing.JOptionPane; public class Shell { public static void main(String[] arg) { try { JSch jsch = new JSch(); // jsch.setKnownHosts("/home/foo/.ssh/known_hosts"); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String passwd = JOptionPane.showInputDialog("Enter password"); session.setPassword(passwd); UserInfo ui = new MyUserInfo() { @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } @Override public boolean promptYesNo(String message) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, message, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } // If password is not given before the invocation of Session#connect(), // implement also following methods, // * UserInfo#getPassword(), // * UserInfo#promptPassword(String message) and // * UIKeyboardInteractive#promptKeyboardInteractive() }; session.setUserInfo(ui); // It must not be recommended, but if you want to skip host-key check, // invoke following, // session.setConfig("StrictHostKeyChecking", "no"); // session.connect(); session.connect(30000); // making a connection with timeout. Channel channel = session.openChannel("shell"); // Enable agent-forwarding. // ((ChannelShell) channel).setAgentForwarding(true); channel.setInputStream(System.in); // a hack for MS-DOS prompt on Windows. // channel.setInputStream(new FilterInputStream(System.in) { // @Override // public int read(byte[] b, int off, int len) throws IOException { // return in.read(b, off, len > 1024 ? 1024 : len); // } // }); channel.setOutputStream(System.out); // Choose the pty-type "vt102". // ((ChannelShell) channel).setPtyType("vt102"); // Set environment variable "LANG" as "ja_JP.eucJP". // ((ChannelShell) channel).setEnv("LANG", "ja_JP.eucJP"); // channel.connect(); channel.connect(3 * 1000); } catch (Exception e) { System.out.println(e); } } public abstract static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return null; } @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return false; } @Override public boolean promptPassword(String message) { return false; } @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { return null; } } } mwiede-jsch-c8efa3f/examples/SocketForwardingL.java000066400000000000000000000066211465436372100225620ustar00rootroot00000000000000/** * This program enables you to connect to sshd server and forward the docker socket. You will be * asked username, hostname and passwd. If everything works fine, you will get the response code to * the _ping endpoint of the dockerd. */ import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.net.HttpURLConnection; import java.net.URL; import javax.swing.JOptionPane; public class SocketForwardingL { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String passwd = JOptionPane.showInputDialog("Enter password"); session.setPassword(passwd); UserInfo ui = new MyUserInfo() { @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } @Override public boolean promptYesNo(String message) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, message, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } // If password is not given before the invocation of Session#connect(), // implement also following methods, // * UserInfo#getPassword(), // * UserInfo#promptPassword(String message) and // * UIKeyboardInteractive#promptKeyboardInteractive() }; session.setUserInfo(ui); // It must not be recommended, but if you want to skip host-key check, // invoke following, // session.setConfig("StrictHostKeyChecking", "no"); // session.connect(); session.connect(30000); // making a connection with timeout. final int boundPort = session.setSocketForwardingL(null, 0, "/var/run/docker.sock", null, 1000); URL myURL = new URL("http://localhost:" + boundPort + "/_ping"); HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection(); System.out.println( "Docker Ping http response code (" + myURL + "): " + myURLConnection.getResponseCode()); session.disconnect(); HttpURLConnection myURLConnection2 = (HttpURLConnection) myURL.openConnection(); System.out.println("Docker Ping http response code: " + myURLConnection2.getResponseCode()); } catch (Exception e) { System.out.println(e); } } public abstract static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return null; } @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return false; } @Override public boolean promptPassword(String message) { return false; } @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { return null; } } } mwiede-jsch-c8efa3f/examples/StreamForwarding.java000066400000000000000000000116711465436372100224520ustar00rootroot00000000000000/** * This program will demonstrate the stream forwarding. The given Java I/O streams will be forwared * to the given remote host and port on the remote side. It is similar to the -L option of ssh * command, but you don't have to assign and open a local tcp port. You will be asked username, * hostname, host:hostport and passwd. If everything works fine, System.in and System.out streams * will be forwared to remote port and you can send messages from command line. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class StreamForwarding { public static void main(String[] arg) { int port; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); String foo = JOptionPane.showInputDialog("Enter host and port", "host:port"); host = foo.substring(0, foo.indexOf(':')); port = Integer.parseInt(foo.substring(foo.indexOf(':') + 1)); System.out.println("System.{in,out} will be forwarded to " + host + ":" + port + "."); Channel channel = session.getStreamForwarder(host, port); // InputStream in = channel.getInputStream(); // OutpuStream out = channel.getOutputStream(); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(1000); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/Subsystem.java000066400000000000000000000120571465436372100211710ustar00rootroot00000000000000/** This program will demonstrate how to use the Subsystem channel. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSubsystem; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Subsystem { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); String subsystem = JOptionPane.showInputDialog("Enter subsystem name", ""); Channel channel = session.openChannel("subsystem"); ((ChannelSubsystem) channel).setSubsystem(subsystem); ((ChannelSubsystem) channel).setPty(true); channel.setInputStream(System.in); ((ChannelSubsystem) channel).setErrStream(System.err); channel.setOutputStream(System.out); channel.connect(); // channel.setInputStream(System.in); // ((ChannelSubsystem) channel).setErrStream(System.err); // InputStream in = channel.getInputStream(); // channel.connect(); // // byte[] tmp = new byte[1024]; // while (true) { // while (in.available() > 0) { // int i = in.read(tmp, 0, 1024); // if (i < 0) // break; // System.out.print(new String(tmp, 0, i)); // } // if (channel.isClosed()) { // System.out.println("exit-status: " + channel.getExitStatus()); // break; // } // try { // Thread.sleep(1000); // } catch (Exception ee) { // } // } // channel.disconnect(); // session.disconnect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/Sudo.java000066400000000000000000000131671465436372100201100ustar00rootroot00000000000000/** This program will demonstrate how to exec 'sudo' on the remote. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class Sudo { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); String command = JOptionPane.showInputDialog("Enter command, execed with sudo", "printenv SUDO_USER"); String sudo_pass = null; { JTextField passwordField = new JPasswordField(8); Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, "Enter password for sudo", JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) { System.exit(-1); } sudo_pass = passwordField.getText(); } Channel channel = session.openChannel("exec"); // man sudo // -S The -S (stdin) option causes sudo to read the password from the // standard input instead of the terminal device. // -p The -p (prompt) option allows you to override the default // password prompt and use a custom one. ((ChannelExec) channel).setCommand("sudo -S -p '' " + command); InputStream in = channel.getInputStream(); OutputStream out = channel.getOutputStream(); ((ChannelExec) channel).setErrStream(System.err); channel.connect(); out.write((sudo_pass + "\n").getBytes()); out.flush(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; System.out.print(new String(tmp, 0, i)); } if (channel.isClosed()) { System.out.println("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } channel.disconnect(); session.disconnect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/UserAuthKI.java000066400000000000000000000110571465436372100211560ustar00rootroot00000000000000/** * This program will demonstrate the keyboard-interactive authentication. If the remote sshd * supports keyboard-interactive authentication, you will be prompted. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class UserAuthKI { public static void main(String[] arg) { try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // username and passphrase will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return false; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { // System.out.println("promptKeyboardInteractive"); // System.out.println("destination: " + destination); // System.out.println("name: " + name); // System.out.println("instruction: " + instruction); // System.out.println("prompt.length: " + prompt.length); // System.out.println("prompt: " + prompt[0]); panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/UserAuthPubKey.java000066400000000000000000000114401465436372100220460ustar00rootroot00000000000000/** * This program will demonstrate the user authentification by public key. You will be asked * username, hostname, privatekey(id_dsa) and passphrase. If everything works fine, you will get the * shell prompt. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class UserAuthPubKey { public static void main(String[] arg) { try { JSch jsch = new JSch(); JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Choose your privatekey(ex. ~/.ssh/id_dsa)"); chooser.setFileHidingEnabled(false); int returnVal = chooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { System.out.println("You chose " + chooser.getSelectedFile().getAbsolutePath() + "."); jsch.addIdentity(chooser.getSelectedFile().getAbsolutePath() // , "passphrase" ); } String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); // username and passphrase will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return null; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passphrase; JTextField passphraseField = new JPasswordField(20); @Override public String getPassphrase() { return passphrase; } @Override public boolean promptPassphrase(String message) { Object[] ob = {passphraseField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passphrase = passphraseField.getText(); return true; } else { return false; } } @Override public boolean promptPassword(String message) { return true; } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/ViaHTTP.java000066400000000000000000000111361465436372100204070ustar00rootroot00000000000000/** * This program will demonstrate the ssh session via HTTP proxy. You will be asked username, * hostname, proxy-server and passwd. If everything works fine, you will get the shell prompt. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.ProxyHTTP; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class ViaHTTP { public static void main(String[] arg) { String proxy_host; int proxy_port; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String proxy = JOptionPane.showInputDialog("Enter proxy server", "hostname:port"); proxy_host = proxy.substring(0, proxy.indexOf(':')); proxy_port = Integer.parseInt(proxy.substring(proxy.indexOf(':') + 1)); session.setProxy(new ProxyHTTP(proxy_host, proxy_port)); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/ViaSOCKS5.java000066400000000000000000000111451465436372100205770ustar00rootroot00000000000000/** * This program will demonstrate the ssh session via SOCKS proxy. You will be asked username, * hostname, proxy-server and passwd. If everything works fine, you will get the shell prompt. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.ProxySOCKS5; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class ViaSOCKS5 { public static void main(String[] arg) { String proxy_host; int proxy_port; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String proxy = JOptionPane.showInputDialog("Enter proxy server", "hostname:port"); proxy_host = proxy.substring(0, proxy.indexOf(':')); proxy_port = Integer.parseInt(proxy.substring(proxy.indexOf(':') + 1)); session.setProxy(new ProxySOCKS5(proxy_host, proxy_port)); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/examples/X11Forwarding.java000066400000000000000000000113651465436372100215700ustar00rootroot00000000000000/** * This program will demonstrate X11 forwarding. You will be asked username, hostname, displayname * and passwd. If your X server does not run at 127.0.0.1, please enter correct displayname. If * everything works fine, you will get the shell prompt. Try X applications; for example, xlogo. */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class X11Forwarding { public static void main(String[] arg) { String xhost = "127.0.0.1"; int xport = 0; try { JSch jsch = new JSch(); String host = null; if (arg.length > 0) { host = arg[0]; } else { host = JOptionPane.showInputDialog("Enter username@hostname", System.getProperty("user.name") + "@localhost"); } String user = host.substring(0, host.indexOf('@')); host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); String display = JOptionPane.showInputDialog("Please enter display name", xhost + ":" + xport); xhost = display.substring(0, display.indexOf(':')); xport = Integer.parseInt(display.substring(display.indexOf(':') + 1)); session.setX11Host(xhost); session.setX11Port(xport + 6000); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); Channel channel = session.openChannel("shell"); channel.setXForwarding(true); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(); } catch (Exception e) { System.out.println(e); } } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { @Override public String getPassword() { return passwd; } @Override public boolean promptYesNo(String str) { Object[] options = {"yes", "no"}; int foo = JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); return foo == 0; } String passwd; JTextField passwordField = new JPasswordField(20); @Override public String getPassphrase() { return null; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptPassword(String message) { Object[] ob = {passwordField}; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } @Override public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } } mwiede-jsch-c8efa3f/mvnw000077500000000000000000000246511465436372100154320ustar00rootroot00000000000000#!/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. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # Apache Maven Wrapper startup batch script, version 3.3.2 # # Optional ENV vars # ----------------- # JAVA_HOME - location of a JDK home dir, required when download maven via java source # MVNW_REPOURL - repo url base for downloading maven distribution # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- set -euf [ "${MVNW_VERBOSE-}" != debug ] || set -x # OS specific support. native_path() { printf %s\\n "$1"; } case "$(uname)" in CYGWIN* | MINGW*) [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" native_path() { cygpath --path --windows "$1"; } ;; esac # set JAVACMD and JAVACCMD set_java_home() { # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched if [ -n "${JAVA_HOME-}" ]; then if [ -x "$JAVA_HOME/jre/sh/java" ]; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" JAVACCMD="$JAVA_HOME/jre/sh/javac" else JAVACMD="$JAVA_HOME/bin/java" JAVACCMD="$JAVA_HOME/bin/javac" if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 return 1 fi fi else JAVACMD="$( 'set' +e 'unset' -f command 2>/dev/null 'command' -v java )" || : JAVACCMD="$( 'set' +e 'unset' -f command 2>/dev/null 'command' -v javac )" || : if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 return 1 fi fi } # hash string like Java String::hashCode hash_string() { str="${1:-}" h=0 while [ -n "$str" ]; do char="${str%"${str#?}"}" h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) str="${str#?}" done printf %x\\n $h } verbose() { :; } [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } die() { printf %s\\n "$1" >&2 exit 1 } trim() { # MWRAPPER-139: # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. # Needed for removing poorly interpreted newline sequences when running in more # exotic environments such as mingw bash on Windows. printf "%s" "${1}" | tr -d '[:space:]' } # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties while IFS="=" read -r key value; do case "${key-}" in distributionUrl) distributionUrl=$(trim "${value-}") ;; distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; esac done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" case "${distributionUrl##*/}" in maven-mvnd-*bin.*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; :Linux*x86_64*) distributionPlatform=linux-amd64 ;; *) echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 distributionPlatform=linux-amd64 ;; esac distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" ;; maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; esac # apply MVNW_REPOURL and calculate MAVEN_HOME # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" distributionUrlName="${distributionUrl##*/}" distributionUrlNameMain="${distributionUrlName%.*}" distributionUrlNameMain="${distributionUrlNameMain%-bin}" MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" exec_maven() { unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" } if [ -d "$MAVEN_HOME" ]; then verbose "found existing MAVEN_HOME at $MAVEN_HOME" exec_maven "$@" fi case "${distributionUrl-}" in *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; esac # prepare tmp dir if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } trap clean HUP INT TERM EXIT else die "cannot create temp dir" fi mkdir -p -- "${MAVEN_HOME%/*}" # Download and Install Apache Maven verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." verbose "Downloading from: $distributionUrl" verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" # select .zip or .tar.gz if ! command -v unzip >/dev/null; then distributionUrl="${distributionUrl%.zip}.tar.gz" distributionUrlName="${distributionUrl##*/}" fi # verbose opt __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v # normalize http auth case "${MVNW_PASSWORD:+has-password}" in '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; esac if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then verbose "Found wget ... using wget" wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then verbose "Found curl ... using curl" curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" elif set_java_home; then verbose "Falling back to use Java to download" javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" cat >"$javaSource" <<-END public class Downloader extends java.net.Authenticator { protected java.net.PasswordAuthentication getPasswordAuthentication() { return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); } public static void main( String[] args ) throws Exception { setDefault( new Downloader() ); java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); } } END # For Cygwin/MinGW, switch paths to Windows format before running javac and java verbose " - Compiling Downloader.java ..." "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" verbose " - Running Downloader.java ..." "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" fi # If specified, validate the SHA-256 sum of the Maven distribution zip file if [ -n "${distributionSha256Sum-}" ]; then distributionSha256Result=false if [ "$MVN_CMD" = mvnd.sh ]; then echo "Checksum validation is not supported for maven-mvnd." >&2 echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 exit 1 elif command -v sha256sum >/dev/null; then if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then distributionSha256Result=true fi elif command -v shasum >/dev/null; then if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then distributionSha256Result=true fi else echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 exit 1 fi if [ $distributionSha256Result = false ]; then echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 exit 1 fi fi # unzip and move if command -v unzip >/dev/null; then unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" else tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" clean || : exec_maven "$@" mwiede-jsch-c8efa3f/mvnw.cmd000066400000000000000000000156251465436372100161720ustar00rootroot00000000000000<# : batch portion @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @REM distributed with this work for additional information @REM regarding copyright ownership. The ASF licenses this file @REM to you under the Apache License, Version 2.0 (the @REM "License"); you may not use this file except in compliance @REM with 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, @REM software distributed under the License is distributed on an @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @REM KIND, either express or implied. See the License for the @REM specific language governing permissions and limitations @REM under the License. @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- @REM Apache Maven Wrapper startup batch script, version 3.3.2 @REM @REM Optional ENV vars @REM MVNW_REPOURL - repo url base for downloading maven distribution @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output @REM ---------------------------------------------------------------------------- @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) @SET __MVNW_CMD__= @SET __MVNW_ERROR__= @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% @SET PSModulePath= @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) ) @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% @SET __MVNW_PSMODULEP_SAVE= @SET __MVNW_ARG0_NAME__= @SET MVNW_USERNAME= @SET MVNW_PASSWORD= @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) @echo Cannot start maven from wrapper >&2 && exit /b 1 @GOTO :EOF : end batch / begin powershell #> $ErrorActionPreference = "Stop" if ($env:MVNW_VERBOSE -eq "true") { $VerbosePreference = "Continue" } # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl if (!$distributionUrl) { Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" } switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { "maven-mvnd-*" { $USE_MVND = $true $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" $MVN_CMD = "mvnd.cmd" break } default { $USE_MVND = $false $MVN_CMD = $script -replace '^mvnw','mvn' break } } # apply MVNW_REPOURL and calculate MAVEN_HOME # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ if ($env:MVNW_REPOURL) { $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" } $distributionUrlName = $distributionUrl -replace '^.*/','' $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" if ($env:MAVEN_USER_HOME) { $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" } $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" exit $? } if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" } # prepare tmp dir $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null trap { if ($TMP_DOWNLOAD_DIR.Exists) { try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } } } New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null # Download and Install Apache Maven Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." Write-Verbose "Downloading from: $distributionUrl" Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" $webclient = New-Object System.Net.WebClient if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null # If specified, validate the SHA-256 sum of the Maven distribution zip file $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum if ($distributionSha256Sum) { if ($USE_MVND) { Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." } Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." } } # unzip and move Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null try { Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null } catch { if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { Write-Error "fail to move MAVEN_HOME" } } finally { try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } } Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" mwiede-jsch-c8efa3f/opensshFormat.md000066400000000000000000000004761465436372100176660ustar00rootroot00000000000000# Links regarding OPENSSH key format * nice read: * See discussion: * implementation of bcrypt_pbkdf: mwiede-jsch-c8efa3f/pom.xml000066400000000000000000001151161465436372100160270ustar00rootroot00000000000000 4.0.0 com.github.mwiede jsch jar 0.2.19 JSch https://github.com/mwiede/jsch JSch is a pure Java implementation of SSH2 scm:git:https://github.com/mwiede/jsch.git scm:git:https://github.com/mwiede/jsch.git https://github.com/mwiede/jsch jsch-0.2.19 ossrh https://oss.sonatype.org/content/repositories/snapshots ossrh https://oss.sonatype.org/service/local/staging/deploy/maven2/ GitHub https://github.com/mwiede/jsch/issues GitHub https://github.com/mwiede/jsch/actions ymnk Atsuhiko Yamanaka ymnk at jcraft D0t com https://github.com/ymnk JCraft,Inc. http://www.jcraft.com/ architect developer +9 mwiede Matthias Wiedemann mwiede@gmx.de Community https://github.com/mwiede norrisjeremy Jeremy Norris Community https://github.com/norrisjeremy Revised BSD https://github.com/mwiede/jsch/blob/master/LICENSE.txt Revised BSD https://github.com/mwiede/jsch/blob/master/LICENSE.JZlib.txt ISC https://github.com/mwiede/jsch/blob/master/LICENSE.jBCrypt.txt 2024-08-06T09:05:46Z UTF-8 UTF-8 true 2.10.0 5.14.0 2.23.1 2.29.2 3.3.1 org.bouncycastle bcprov-jdk18on 1.78.1 true com.kohlschutter.junixsocket junixsocket-common ${junixsocket.version} true com.kohlschutter compiler-annotations 1.7.3 provided true net.java.dev.jna jna-jpms ${jna.version} true net.java.dev.jna jna-platform-jpms ${jna.version} true org.apache.logging.log4j log4j-api ${log4j.version} true org.osgi org.osgi.core org.slf4j slf4j-api 2.0.13 true org.junit.jupiter junit-jupiter 5.10.3 test org.testcontainers junit-jupiter 1.20.1 test net.java.dev.jna jna org.slf4j slf4j-api commons-codec commons-codec 1.17.1 test commons-io commons-io 2.16.1 test com.kohlschutter.junixsocket junixsocket-native-common ${junixsocket.version} test org.apache.logging.log4j log4j-core-test ${log4j.version} test org.junit-pioneer junit-pioneer org.apache.maven maven-core org.assertj assertj-core commons-io commons-io org.apache.commons commons-lang3 org.hamcrest hamcrest com.google.code.java-allocation-instrumenter java-allocation-instrumenter junit junit org.junit.platform junit-platform-commons org.springframework spring-test com.github.valfirst slf4j-test 3.0.1 test com.google.errorprone error_prone_annotations ${errorprone.version} org.apache.maven.plugins maven-enforcer-plugin 3.5.0 enforce-java enforce 17 org.codehaus.mojo flatten-maven-plugin 1.6.0 ossrh all flatten process-resources flatten flatten.clean clean clean org.codehaus.mojo build-helper-maven-plugin 3.6.0 regex-property versionWithoutMinus ${project.version} - _ false org.codehaus.mojo templating-maven-plugin 3.0.0 filter-sources org.apache.maven.plugins maven-compiler-plugin 3.13.0 8 true true true -Xlint:all,-processing,-classfile,-options default-compile-9 compile ${project.basedir}/src/main/java9 true 9 default-compile-10 compile ${project.basedir}/src/main/java10 true 10 default-compile-11 compile ${project.basedir}/src/main/java11 true 11 default-compile-15 compile ${project.basedir}/src/main/java15 true 15 default-compile-16 compile ${project.basedir}/src/main/java16 true 16 biz.aQute.bnd bnd-maven-plugin 7.0.0 org.apache.maven.plugins maven-surefire-plugin ${surefire.version} false org.apache.maven.plugins maven-failsafe-plugin ${surefire.version} false integration-test verify org.apache.maven.plugins maven-clean-plugin 3.4.0 org.apache.maven.plugins maven-resources-plugin 3.3.1 copy-licenses process-resources copy-resources ${project.build.outputDirectory}/META-INF ${project.basedir} false LICENSE* org.apache.maven.plugins maven-jar-plugin 3.4.2 true true ${project.build.outputDirectory}/META-INF/MANIFEST.MF org.apache.maven.plugins maven-assembly-plugin 3.7.1 attach-sources package single ${project.basedir}/src/assembly/sources.xml org.apache.maven.plugins maven-javadoc-plugin 3.8.0 true none com.jcraft.jsch com.jcraft.jsch.* ${project.build.sourceDirectory}:${project.build.directory}/generated-sources/java-templates:${project.basedir}/src/main/java9:${project.basedir}/src/main/java10:${project.basedir}/src/main/java11:${project.basedir}/src/main/java15:${project.basedir}/src/main/java16 attach-javadocs jar org.cyclonedx cyclonedx-maven-plugin 2.8.1 false false makeBom org.apache.maven.plugins maven-release-plugin 3.1.1 false release org.apache.maven.plugins maven-gpg-plugin 3.2.4 org.apache.maven.plugins maven-deploy-plugin 3.1.2 org.apache.maven.plugins maven-install-plugin 3.1.2 org.apache.maven.plugins maven-site-plugin 3.12.1 org.apache.maven.plugins maven-dependency-plugin 3.7.1 org.apache.maven.plugins maven-checkstyle-plugin 3.4.0 true true warning google_checks.xml ${project.build.sourceDirectory} ${project.build.testSourceDirectory} ${project.basedir}/examples ${project.basedir}/src/main/java9 ${project.basedir}/src/main/java10 ${project.basedir}/src/main/java11 ${project.basedir}/src/main/java15 ${project.basedir}/src/main/java16 ${project.basedir}/src/main/java-templates net.revelc.code.formatter formatter-maven-plugin 2.24.1 ${project.basedir}/eclipse-java-google-style.xml UTF-8 ${project.build.sourceDirectory} ${project.build.testSourceDirectory} ${project.basedir}/examples ${project.basedir}/src/main/java9 ${project.basedir}/src/main/java10 ${project.basedir}/src/main/java11 ${project.basedir}/src/main/java15 ${project.basedir}/src/main/java16 ${project.basedir}/src/main/java-templates org.jacoco jacoco-maven-plugin 0.8.12 com/jcraft/jsch/JavaVersion.class com/jcraft/jsch/JplLogger.class com/jcraft/jsch/UnixDomainSocketFactory.class com/jcraft/jsch/jce/KeyPairGenEdDSA.class com/jcraft/jsch/jce/SignatureEd25519.class com/jcraft/jsch/jce/SignatureEd448.class com/jcraft/jsch/jce/XDH.class META-INF/versions/9/com/jcraft/jsch/JavaVersion.class META-INF/versions/10/com/jcraft/jsch/JavaVersion.class de.thetaphi forbiddenapis 3.7 jdk-unsafe jdk-deprecated jdk-non-portable jdk-reflection com.jcraft.jsch.annotations.SuppressForbiddenApi release org.apache.maven.plugins maven-gpg-plugin sign-artifacts verify sign coverage org.jacoco jacoco-maven-plugin default-prepare-agent prepare-agent default-prepare-agent-integration prepare-agent-integration default-report report default-report-integration report-integration errorprone org.apache.maven.plugins maven-compiler-plugin true -XDcompilePolicy=simple -Xplugin:ErrorProne -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED com.google.errorprone error_prone_core ${errorprone.version} format net.revelc.code.formatter formatter-maven-plugin format format formatvalidation [17,) net.revelc.code.formatter formatter-maven-plugin verify validate checkstyle org.apache.maven.plugins maven-checkstyle-plugin validate validate check forbiddenapis [16,) de.thetaphi forbiddenapis 16 check check jdk-system-out testCheck testCheck commons-io-unsafe-2.14.0 bnd [17,) biz.aQute.bnd bnd-maven-plugin bnd-process process-classes bnd-process mwiede-jsch-c8efa3f/src/000077500000000000000000000000001465436372100152745ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/assembly/000077500000000000000000000000001465436372100171135ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/assembly/sources.xml000066400000000000000000000051271465436372100213250ustar00rootroot00000000000000 sources false jar ${project.build.outputDirectory}/META-INF META-INF LICENSE* ${project.build.sourceDirectory} **/*.java ${project.build.directory}/generated-sources/java-templates **/*.java ${project.basedir}/src/main/java9 META-INF/versions/9 **/*.java ${project.basedir}/src/main/java10 META-INF/versions/10 **/*.java ${project.basedir}/src/main/java11 META-INF/versions/11 **/*.java ${project.basedir}/src/main/java15 META-INF/versions/15 **/*.java ${project.basedir}/src/main/java16 META-INF/versions/16 **/*.java ${project.basedir}/.flattened-pom.xml META-INF/maven/${project.groupId}/${project.artifactId} pom.xml ${project.build.directory}/maven-archiver/pom.properties META-INF/maven/${project.groupId}/${project.artifactId} mwiede-jsch-c8efa3f/src/main/000077500000000000000000000000001465436372100162205ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java-templates/000077500000000000000000000000001465436372100211355ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java-templates/com/000077500000000000000000000000001465436372100217135ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java-templates/com/jcraft/000077500000000000000000000000001465436372100231645ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java-templates/com/jcraft/jsch/000077500000000000000000000000001465436372100241135ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java-templates/com/jcraft/jsch/Version.java000066400000000000000000000002551465436372100264050ustar00rootroot00000000000000package com.jcraft.jsch; final class Version { private static final String VERSION = "${versionWithoutMinus}"; static String getVersion() { return VERSION; } } mwiede-jsch-c8efa3f/src/main/java/000077500000000000000000000000001465436372100171415ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/000077500000000000000000000000001465436372100177175ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/000077500000000000000000000000001465436372100211705ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/000077500000000000000000000000001465436372100221175ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/AgentConnector.java000066400000000000000000000031651465436372100257000ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface AgentConnector { String getName(); boolean isAvailable(); void query(Buffer buffer) throws AgentProxyException; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/AgentIdentity.java000066400000000000000000000047031465436372100255360ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class AgentIdentity implements Identity { private AgentProxy agent; private byte[] blob; private String comment; private String algname; AgentIdentity(AgentProxy agent, byte[] blob, String comment) { this.agent = agent; this.blob = blob; this.comment = comment; algname = Util.byte2str((new Buffer(blob)).getString()); } @Override public boolean setPassphrase(byte[] passphrase) throws JSchException { return true; } @Override public byte[] getPublicKeyBlob() { return blob; } @Override public byte[] getSignature(byte[] data) { return agent.sign(blob, data, null); } @Override public byte[] getSignature(byte[] data, String alg) { return agent.sign(blob, data, alg); } @Override public String getAlgName() { return algname; } @Override public String getName() { return comment; } @Override public boolean isEncrypted() { return false; } @Override public void clear() {} } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java000066400000000000000000000044671465436372100276450ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Vector; public class AgentIdentityRepository implements IdentityRepository { private AgentProxy agent; public AgentIdentityRepository(AgentConnector connector) { this.agent = new AgentProxy(connector); } @Override public Vector getIdentities() { return agent.getIdentities(); } @Override public boolean add(byte[] identity) { return agent.addIdentity(identity); } @Override public boolean remove(byte[] blob) { return agent.removeIdentity(blob); } @Override public void removeAll() { agent.removeAllIdentities(); } @Override public String getName() { return agent.getConnector().getName(); } @Override public int getStatus() { if (agent.getConnector().isAvailable()) { return RUNNING; } else { return NOTRUNNING; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/AgentProxy.java000066400000000000000000000171621465436372100250710ustar00rootroot00000000000000/* * Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Vector; class AgentProxy { private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1; private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2; private static final byte SSH_AGENTC_RSA_CHALLENGE = 3; private static final byte SSH_AGENT_RSA_RESPONSE = 4; private static final byte SSH_AGENT_FAILURE = 5; private static final byte SSH_AGENT_SUCCESS = 6; private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7; private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8; private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9; private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11; private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12; private static final byte SSH2_AGENTC_SIGN_REQUEST = 13; private static final byte SSH2_AGENT_SIGN_RESPONSE = 14; private static final byte SSH2_AGENTC_ADD_IDENTITY = 17; private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18; private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19; private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20; private static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21; private static final byte SSH_AGENTC_LOCK = 22; private static final byte SSH_AGENTC_UNLOCK = 23; private static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24; private static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25; private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26; private static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1; private static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2; private static final byte SSH2_AGENT_FAILURE = 30; private static final byte SSH_COM_AGENT2_FAILURE = 102; // private static final byte SSH_AGENT_OLD_SIGNATURE = 0x1; private static final int SSH_AGENT_RSA_SHA2_256 = 0x2; private static final int SSH_AGENT_RSA_SHA2_512 = 0x4; private static final int MAX_AGENT_IDENTITIES = 2048; private final byte[] buf = new byte[1024]; private final Buffer buffer = new Buffer(buf); private AgentConnector connector; AgentProxy(AgentConnector connector) { this.connector = connector; } synchronized Vector getIdentities() { Vector identities = new Vector<>(); int required_size = 1 + 4; buffer.reset(); buffer.checkFreeSize(required_size); buffer.putInt(required_size - 4); buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES); try { connector.query(buffer); } catch (AgentProxyException e) { buffer.rewind(); buffer.putByte(SSH_AGENT_FAILURE); return identities; } int rcode = buffer.getByte(); // System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER); if (rcode != SSH2_AGENT_IDENTITIES_ANSWER) { return identities; } int count = buffer.getInt(); // System.out.println(count); if (count <= 0 || count > MAX_AGENT_IDENTITIES) { return identities; } for (int i = 0; i < count; i++) { byte[] blob = buffer.getString(); String comment = Util.byte2str(buffer.getString()); identities.add(new AgentIdentity(this, blob, comment)); } return identities; } synchronized byte[] sign(byte[] blob, byte[] data, String alg) { int flags = 0x0; if (alg != null) { if (alg.equals("rsa-sha2-256")) { flags = SSH_AGENT_RSA_SHA2_256; } else if (alg.equals("rsa-sha2-512")) { flags = SSH_AGENT_RSA_SHA2_512; } } int required_size = 1 + 4 * 4 + blob.length + data.length; buffer.reset(); buffer.checkFreeSize(required_size); buffer.putInt(required_size - 4); buffer.putByte(SSH2_AGENTC_SIGN_REQUEST); buffer.putString(blob); buffer.putString(data); buffer.putInt(flags); try { connector.query(buffer); } catch (AgentProxyException e) { buffer.rewind(); buffer.putByte(SSH_AGENT_FAILURE); } int rcode = buffer.getByte(); // System.out.println(rcode == SSH2_AGENT_SIGN_RESPONSE); if (rcode != SSH2_AGENT_SIGN_RESPONSE) { return null; } return buffer.getString(); } synchronized boolean removeIdentity(byte[] blob) { int required_size = 1 + 4 * 2 + blob.length; buffer.reset(); buffer.checkFreeSize(required_size); buffer.putInt(required_size - 4); buffer.putByte(SSH2_AGENTC_REMOVE_IDENTITY); buffer.putString(blob); try { connector.query(buffer); } catch (AgentProxyException e) { buffer.rewind(); buffer.putByte(SSH_AGENT_FAILURE); } int rcode = buffer.getByte(); // System.out.println(rcode == SSH_AGENT_SUCCESS); return rcode == SSH_AGENT_SUCCESS; } synchronized void removeAllIdentities() { int required_size = 1 + 4; buffer.reset(); buffer.checkFreeSize(required_size); buffer.putInt(required_size - 4); buffer.putByte(SSH2_AGENTC_REMOVE_ALL_IDENTITIES); try { connector.query(buffer); } catch (AgentProxyException e) { buffer.rewind(); buffer.putByte(SSH_AGENT_FAILURE); } // int rcode = buffer.getByte(); // System.out.println(rcode == SSH_AGENT_SUCCESS); } synchronized boolean addIdentity(byte[] identity) { int required_size = 1 + 4 + identity.length; buffer.reset(); buffer.checkFreeSize(required_size); buffer.putInt(required_size - 4); buffer.putByte(SSH2_AGENTC_ADD_IDENTITY); buffer.putByte(identity); try { connector.query(buffer); } catch (AgentProxyException e) { buffer.rewind(); buffer.putByte(SSH_AGENT_FAILURE); } int rcode = buffer.getByte(); // System.out.println(rcode == SSH_AGENT_SUCCESS); return rcode == SSH_AGENT_SUCCESS; } synchronized boolean isRunning() { int required_size = 1 + 4; buffer.reset(); buffer.checkFreeSize(required_size); buffer.putInt(required_size - 4); buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES); try { connector.query(buffer); } catch (AgentProxyException e) { return false; } int rcode = buffer.getByte(); // System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER); return rcode == SSH2_AGENT_IDENTITIES_ANSWER; } synchronized AgentConnector getConnector() { return connector; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/AgentProxyException.java000066400000000000000000000033651465436372100267500ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class AgentProxyException extends Exception { private static final long serialVersionUID = -1L; public AgentProxyException(String message) { super(message); } public AgentProxyException(String message, Throwable e) { super(message, e); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Argon2.java000066400000000000000000000035601465436372100241160ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface Argon2 extends KDF { public static final int ARGON2D = 0; public static final int ARGON2I = 1; public static final int ARGON2ID = 2; public static final int V10 = 0x10; public static final int V13 = 0x13; void init(byte[] salt, int iteration, int type, byte[] additional, byte[] secret, int memory, int parallelism, int version) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/BCrypt.java000066400000000000000000000031211465436372100241620ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface BCrypt extends KDF { void init(byte[] salt, int iteration) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Buffer.java000066400000000000000000000174241465436372100242030ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class Buffer { final byte[] tmp = new byte[4]; byte[] buffer; int index; int s; public Buffer(int size) { buffer = new byte[size]; index = 0; s = 0; } public Buffer(byte[] buffer) { this.buffer = buffer; index = 0; s = 0; } public Buffer() { this(1024 * 10 * 2); } public void putByte(byte foo) { buffer[index++] = foo; } public void putByte(byte[] foo) { putByte(foo, 0, foo.length); } public void putByte(byte[] foo, int begin, int length) { System.arraycopy(foo, begin, buffer, index, length); index += length; } public void putString(byte[] foo) { putString(foo, 0, foo.length); } public void putString(byte[] foo, int begin, int length) { putInt(length); putByte(foo, begin, length); } public void putInt(int val) { tmp[0] = (byte) (val >>> 24); tmp[1] = (byte) (val >>> 16); tmp[2] = (byte) (val >>> 8); tmp[3] = (byte) (val); System.arraycopy(tmp, 0, buffer, index, 4); index += 4; } public void putLong(long val) { tmp[0] = (byte) (val >>> 56); tmp[1] = (byte) (val >>> 48); tmp[2] = (byte) (val >>> 40); tmp[3] = (byte) (val >>> 32); System.arraycopy(tmp, 0, buffer, index, 4); tmp[0] = (byte) (val >>> 24); tmp[1] = (byte) (val >>> 16); tmp[2] = (byte) (val >>> 8); tmp[3] = (byte) (val); System.arraycopy(tmp, 0, buffer, index + 4, 4); index += 8; } void skip(int n) { index += n; } void putPad(int n) { while (n > 0) { buffer[index++] = (byte) 0; n--; } } public void putMPInt(byte[] foo) { int i = foo.length; if ((foo[0] & 0x80) != 0) { i++; putInt(i); putByte((byte) 0); } else { putInt(i); } putByte(foo); } public int getLength() { return index - s; } public int getOffSet() { return s; } public void setOffSet(int s) { this.s = s; } public long getLong() { long foo = getInt() & 0xffffffffL; foo = ((foo << 32)) | (getInt() & 0xffffffffL); return foo; } public int getInt() { int foo = getShort(); foo = ((foo << 16) & 0xffff0000) | (getShort() & 0xffff); return foo; } public long getUInt() { long foo = 0L; long bar = 0L; foo = getByte(); foo = ((foo << 8) & 0xff00) | (getByte() & 0xff); bar = getByte(); bar = ((bar << 8) & 0xff00) | (getByte() & 0xff); foo = ((foo << 16) & 0xffff0000) | (bar & 0xffff); return foo; } int getShort() { int foo = getByte(); foo = ((foo << 8) & 0xff00) | (getByte() & 0xff); return foo; } public int getByte() { return (buffer[s++] & 0xff); } public void getByte(byte[] foo) { getByte(foo, 0, foo.length); } void getByte(byte[] foo, int start, int len) { System.arraycopy(buffer, s, foo, start, len); s += len; } public int getByte(int len) { int foo = s; s += len; return foo; } public byte[] getMPInt() { int i = getInt(); // uint32 if (i < 0 || // bigger than 0x7fffffff i > 8 * 1024) { // TODO: an exception should be thrown. i = 8 * 1024; // the session will be broken, but working around OOME. } byte[] foo = new byte[i]; getByte(foo, 0, i); return foo; } public byte[] getMPIntBits() { int bits = getInt(); int bytes = (bits + 7) / 8; byte[] foo = new byte[bytes]; getByte(foo, 0, bytes); if ((foo[0] & 0x80) != 0) { byte[] bar = new byte[foo.length + 1]; bar[0] = 0; // ?? System.arraycopy(foo, 0, bar, 1, foo.length); foo = bar; } return foo; } public byte[] getString() { int i = getInt(); // uint32 if (i < 0 || // bigger than 0x7fffffff i > 256 * 1024) { // TODO: an exception should be thrown. i = 256 * 1024; // the session will be broken, but working around OOME. } byte[] foo = new byte[i]; getByte(foo, 0, i); return foo; } byte[] getString(int[] start, int[] len) { int i = getInt(); start[0] = getByte(i); len[0] = i; return buffer; } public void reset() { index = 0; s = 0; } public void shift() { if (s == 0) return; System.arraycopy(buffer, s, buffer, 0, index - s); index = index - s; s = 0; } void rewind() { s = 0; } byte getCommand() { return buffer[5]; } // Hardcode this since we can't use dynamic Session value private static final int buffer_margin = 32 + // maximum padding length 64 + // maximum mac length 32; // margin for deflater; deflater may inflate data void checkFreeSize(int n) { int size = index + n + buffer_margin; if (buffer.length < size) { int i = buffer.length * 2; if (i < size) i = size; byte[] tmp = new byte[i]; System.arraycopy(buffer, 0, tmp, 0, index); buffer = tmp; } } byte[][] getBytes(int n, String msg) throws JSchException { byte[][] tmp = new byte[n][]; for (int i = 0; i < n; i++) { int j = getInt(); if (getLength() < j) { throw new JSchException(msg); } tmp[i] = new byte[j]; getByte(tmp[i]); } return tmp; } /* * static Buffer fromBytes(byte[]... args){ int length = args.length*4; for(int i = 0; i < * args.length; i++){ length += args[i].length; } Buffer buf = new Buffer(length); for(int i = 0; * i < args.length; i++){ buf.putString(args[i]); } return buf; } */ static Buffer fromBytes(byte[][] args) { int length = args.length * 4; for (int i = 0; i < args.length; i++) { length += args[i].length; } Buffer buf = new Buffer(length); for (int i = 0; i < args.length; i++) { buf.putString(args[i]); } return buf; } /* * static String[] chars={ "0","1","2","3","4","5","6","7","8","9", "a","b","c","d","e","f" }; * static void dump_buffer(){ int foo; for(int i=0; i>>4)&0xf]); * System.err.print(chars[foo&0xf]); if(i%16==15){ System.err.println(""); continue; } if(i>0 && * i%2==1){ System.err.print(" "); } } System.err.println(""); } static void dump(byte[] b){ * dump(b, 0, b.length); } static void dump(byte[] b, int s, int l){ for(int i=s; i pool = new Vector<>(); static Channel getChannel(String type, Session session) { Channel ret = null; if (type.equals("session")) { ret = new ChannelSession(); } if (type.equals("shell")) { ret = new ChannelShell(); } if (type.equals("exec")) { ret = new ChannelExec(); } if (type.equals("x11")) { ret = new ChannelX11(); } if (type.equals("auth-agent@openssh.com")) { ret = new ChannelAgentForwarding(); } if (type.equals("direct-tcpip")) { ret = new ChannelDirectTCPIP(); } if (type.equals("forwarded-tcpip")) { ret = new ChannelForwardedTCPIP(); } if (type.equals("sftp")) { ChannelSftp sftp = new ChannelSftp(); boolean useWriteFlushWorkaround = session.getConfig("use_sftp_write_flush_workaround").equals("yes"); sftp.setUseWriteFlushWorkaround(useWriteFlushWorkaround); ret = sftp; } if (type.equals("subsystem")) { ret = new ChannelSubsystem(); } if (type.equals("direct-streamlocal@openssh.com")) { ret = new ChannelDirectStreamLocal(); } if (ret == null) { return null; } ret.setSession(session); return ret; } static Channel getChannel(int id, Session session) { synchronized (pool) { for (int i = 0; i < pool.size(); i++) { Channel c = pool.elementAt(i); if (c.id == id && c.session == session) return c; } } return null; } static void del(Channel c) { synchronized (pool) { pool.removeElement(c); } } int id; volatile int recipient = -1; protected byte[] type = Util.str2byte("foo"); volatile int lwsize_max = 0x100000; volatile int lwsize = lwsize_max; // local initial window size volatile int lmpsize = 0x4000; // local maximum packet size volatile long rwsize = 0; // remote initial window size volatile int rmpsize = 0; // remote maximum packet size IO io = null; Thread thread = null; volatile boolean eof_local = false; volatile boolean eof_remote = false; volatile boolean close = false; volatile boolean connected = false; volatile boolean open_confirmation = false; volatile int exitstatus = -1; volatile int reply = 0; volatile int connectTimeout = 0; protected Session session; int notifyme = 0; Channel() { synchronized (pool) { id = index++; pool.addElement(this); } } synchronized void setRecipient(int foo) { this.recipient = foo; if (notifyme > 0) notifyAll(); } int getRecipient() { return recipient; } void init() throws JSchException {} public void connect() throws JSchException { connect(0); } public void connect(int connectTimeout) throws JSchException { this.connectTimeout = connectTimeout; try { sendChannelOpen(); start(); } catch (Exception e) { connected = false; disconnect(); if (e instanceof JSchException) throw (JSchException) e; throw new JSchException(e.toString(), e); } } public void setXForwarding(boolean foo) {} public void start() throws JSchException {} public boolean isEOF() { return eof_remote; } void getData(Buffer buf) { setRecipient(buf.getInt()); setRemoteWindowSize(buf.getUInt()); setRemotePacketSize(buf.getInt()); } public void setInputStream(InputStream in) { io.setInputStream(in, false); } public void setInputStream(InputStream in, boolean dontclose) { io.setInputStream(in, dontclose); } public void setOutputStream(OutputStream out) { io.setOutputStream(out, false); } public void setOutputStream(OutputStream out, boolean dontclose) { io.setOutputStream(out, dontclose); } public void setExtOutputStream(OutputStream out) { io.setExtOutputStream(out, false); } public void setExtOutputStream(OutputStream out, boolean dontclose) { io.setExtOutputStream(out, dontclose); } public InputStream getInputStream() throws IOException { Session _session = this.session; if (_session != null && isConnected() && _session.getLogger().isEnabled(Logger.WARN)) { _session.getLogger().log(Logger.WARN, "getInputStream() should be called before connect()"); } int max_input_buffer_size = 32 * 1024; try { max_input_buffer_size = Integer.parseInt(getSession().getConfig("max_input_buffer_size")); } catch (Exception e) { } PipedInputStream in = new MyPipedInputStream(32 * 1024, // this value should be customizable. max_input_buffer_size); boolean resizable = 32 * 1024 < max_input_buffer_size; io.setOutputStream(new PassiveOutputStream(in, resizable), false); return in; } public InputStream getExtInputStream() throws IOException { Session _session = this.session; if (_session != null && isConnected() && _session.getLogger().isEnabled(Logger.WARN)) { _session.getLogger().log(Logger.WARN, "getExtInputStream() should be called before connect()"); } int max_input_buffer_size = 32 * 1024; try { max_input_buffer_size = Integer.parseInt(getSession().getConfig("max_input_buffer_size")); } catch (Exception e) { } PipedInputStream in = new MyPipedInputStream(32 * 1024, // this value should be customizable. max_input_buffer_size); boolean resizable = 32 * 1024 < max_input_buffer_size; io.setExtOutputStream(new PassiveOutputStream(in, resizable), false); return in; } public OutputStream getOutputStream() throws IOException { final Channel channel = this; OutputStream out = new OutputStream() { private int dataLen = 0; private Buffer buffer = null; private Packet packet = null; private boolean closed = false; private synchronized void init() throws IOException { buffer = new Buffer(rmpsize); packet = new Packet(buffer); byte[] _buf = buffer.buffer; try { if (_buf.length - (14 + 0) - getSession().getBufferMargin() <= 0) { buffer = null; packet = null; throw new IOException("failed to initialize the channel."); } } catch (JSchException e) { throw new IOException("failed to initialize the channel.", e); } } byte[] b = new byte[1]; @Override public void write(int w) throws IOException { b[0] = (byte) w; write(b, 0, 1); } @Override public void write(byte[] buf, int s, int l) throws IOException { if (packet == null) { init(); } if (closed) { throw new IOException("Already closed"); } byte[] _buf = buffer.buffer; int _bufl = _buf.length; try { while (l > 0) { int _l = l; int buffer_margin = getSession().getBufferMargin(); if (l > _bufl - (14 + dataLen) - buffer_margin) { _l = _bufl - (14 + dataLen) - buffer_margin; } if (_l <= 0) { flush(); continue; } System.arraycopy(buf, s, _buf, 14 + dataLen, _l); dataLen += _l; s += _l; l -= _l; } } catch (JSchException e) { throw new IOException(e.toString(), e); } } @Override public void flush() throws IOException { if (closed) { throw new IOException("Already closed"); } if (dataLen == 0) return; packet.reset(); buffer.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); buffer.putInt(recipient); buffer.putInt(dataLen); buffer.skip(dataLen); try { int foo = dataLen; dataLen = 0; synchronized (channel) { if (!channel.close) getSession().write(packet, channel, foo); } } catch (Exception e) { close(); throw new IOException(e.toString(), e); } } @Override public void close() throws IOException { if (packet == null) { try { init(); } catch (IOException e) { // close should be finished silently. return; } } if (closed) { return; } if (dataLen > 0) { flush(); } channel.eof(); closed = true; } }; return out; } static class MyPipedInputStream extends PipedInputStream { private int BUFFER_SIZE = 1024; private int max_buffer_size = BUFFER_SIZE; MyPipedInputStream() throws IOException { super(); } MyPipedInputStream(int size) throws IOException { super(); buffer = new byte[size]; BUFFER_SIZE = size; max_buffer_size = size; } MyPipedInputStream(int size, int max_buffer_size) throws IOException { this(size); this.max_buffer_size = max_buffer_size; } MyPipedInputStream(PipedOutputStream out) throws IOException { super(out); } MyPipedInputStream(PipedOutputStream out, int size) throws IOException { super(out); buffer = new byte[size]; BUFFER_SIZE = size; } /* * TODO: We should have our own Piped[I/O]Stream implementation. Before accepting data, JDK's * PipedInputStream will check the existence of reader thread, and if it is not alive, the * stream will be closed. That behavior may cause the problem if multiple threads make access to * it. */ public synchronized void updateReadSide() throws IOException { if (available() != 0) { // not empty return; } in = 0; out = 0; buffer[in++] = 0; read(); } private int freeSpace() { int size = 0; if (out < in) { size = buffer.length - in; } else if (in < out) { if (in == -1) size = buffer.length; else size = out - in; } return size; } synchronized void checkSpace(int len) throws IOException { int size = freeSpace(); if (size < len) { int datasize = buffer.length - size; int foo = buffer.length; while ((foo - datasize) < len) { foo *= 2; } if (foo > max_buffer_size) { foo = max_buffer_size; } if ((foo - datasize) < len) return; byte[] tmp = new byte[foo]; if (out < in) { System.arraycopy(buffer, 0, tmp, 0, buffer.length); } else if (in < out) { if (in == -1) { } else { System.arraycopy(buffer, 0, tmp, 0, in); System.arraycopy(buffer, out, tmp, tmp.length - (buffer.length - out), (buffer.length - out)); out = tmp.length - (buffer.length - out); } } else if (in == out) { System.arraycopy(buffer, 0, tmp, 0, buffer.length); in = buffer.length; } buffer = tmp; } else if (buffer.length == size && size > BUFFER_SIZE) { int i = size / 2; if (i < BUFFER_SIZE) i = BUFFER_SIZE; byte[] tmp = new byte[i]; buffer = tmp; } } } void setLocalWindowSizeMax(int foo) { this.lwsize_max = foo; } void setLocalWindowSize(int foo) { this.lwsize = foo; } void setLocalPacketSize(int foo) { this.lmpsize = foo; } synchronized void setRemoteWindowSize(long foo) { this.rwsize = foo; } synchronized void addRemoteWindowSize(long foo) { this.rwsize += foo; if (notifyme > 0) notifyAll(); } void setRemotePacketSize(int foo) { this.rmpsize = foo; } abstract void run(); void write(byte[] foo) throws IOException { write(foo, 0, foo.length); } void write(byte[] foo, int s, int l) throws IOException { try { io.put(foo, s, l); } catch (NullPointerException e) { } } void write_ext(byte[] foo, int s, int l) throws IOException { try { io.put_ext(foo, s, l); } catch (NullPointerException e) { } } void eof_remote() { eof_remote = true; try { io.out_close(); } catch (NullPointerException e) { } } void eof() { if (eof_local) return; eof_local = true; int i = getRecipient(); if (i == -1) return; try { Buffer buf = new Buffer(100); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_EOF); buf.putInt(i); synchronized (this) { if (!close) getSession().write(packet); } } catch (Exception e) { // System.err.println("Channel.eof"); // e.printStackTrace(); } /* * if(!isConnected()){ disconnect(); } */ } /* * http://www1.ietf.org/internet-drafts/draft-ietf-secsh-connect-24.txt * * 5.3 Closing a Channel When a party will no longer send more data to a channel, it SHOULD send * SSH_MSG_CHANNEL_EOF. * * byte SSH_MSG_CHANNEL_EOF uint32 recipient_channel * * No explicit response is sent to this message. However, the application may send EOF to whatever * is at the other end of the channel. Note that the channel remains open after this message, and * more data may still be sent in the other direction. This message does not consume window space * and can be sent even if no window space is available. * * When either party wishes to terminate the channel, it sends SSH_MSG_CHANNEL_CLOSE. Upon * receiving this message, a party MUST send back a SSH_MSG_CHANNEL_CLOSE unless it has already * sent this message for the channel. The channel is considered closed for a party when it has * both sent and received SSH_MSG_CHANNEL_CLOSE, and the party may then reuse the channel number. * A party MAY send SSH_MSG_CHANNEL_CLOSE without having sent or received SSH_MSG_CHANNEL_EOF. * * byte SSH_MSG_CHANNEL_CLOSE uint32 recipient_channel * * This message does not consume window space and can be sent even if no window space is * available. * * It is recommended that any data sent before this message is delivered to the actual * destination, if possible. */ void close() { if (close) return; close = true; eof_local = eof_remote = true; int i = getRecipient(); if (i == -1) return; try { Buffer buf = new Buffer(100); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_CLOSE); buf.putInt(i); synchronized (this) { getSession().write(packet); } } catch (Exception e) { // e.printStackTrace(); } } public boolean isClosed() { return close; } static void disconnect(Session session) { Channel[] channels = null; int count = 0; synchronized (pool) { channels = new Channel[pool.size()]; for (int i = 0; i < pool.size(); i++) { try { Channel c = pool.elementAt(i); if (c.session == session) { channels[count++] = c; } } catch (Exception e) { } } } for (int i = 0; i < count; i++) { channels[i].disconnect(); } } public void disconnect() { // System.err.println(this+":disconnect "+io+" "+connected); // Thread.dumpStack(); try { synchronized (this) { if (!connected) { return; } connected = false; } close(); eof_remote = eof_local = true; thread = null; try { if (io != null) { io.close(); } } catch (Exception e) { // e.printStackTrace(); } // io=null; } finally { Channel.del(this); } } public boolean isConnected() { Session _session = this.session; if (_session != null) { return _session.isConnected() && connected; } return false; } public void sendSignal(String signal) throws Exception { RequestSignal request = new RequestSignal(); request.setSignal(signal); request.request(getSession(), this); } // public String toString(){ // return "Channel: type="+new // String(type)+",id="+id+",recipient="+recipient+",window_size="+window_size+",packet_size="+packet_size; // } /* * class OutputThread extends Thread{ Channel c; OutputThread(Channel c){ this.c=c;} public void * run(){c.output_thread();} } */ static class PassiveInputStream extends MyPipedInputStream { PipedOutputStream os; PassiveInputStream(PipedOutputStream out, int size) throws IOException { super(out, size); this.os = out; } PassiveInputStream(PipedOutputStream out) throws IOException { super(out); this.os = out; } @Override public void close() throws IOException { if (this.os != null) { this.os.close(); } this.os = null; } } static class PassiveOutputStream extends PipedOutputStream { private MyPipedInputStream _sink = null; PassiveOutputStream(PipedInputStream in, boolean resizable_buffer) throws IOException { super(in); if (resizable_buffer && (in instanceof MyPipedInputStream)) { this._sink = (MyPipedInputStream) in; } } @Override public void write(int b) throws IOException { if (_sink != null) { _sink.checkSpace(1); } super.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { if (_sink != null) { _sink.checkSpace(len); } super.write(b, off, len); } } void setExitStatus(int status) { exitstatus = status; } public int getExitStatus() { return exitstatus; } void setSession(Session session) { this.session = session; } public Session getSession() throws JSchException { Session _session = session; if (_session == null) { throw new JSchException("session is not available"); } return _session; } public int getId() { return id; } protected void sendOpenConfirmation() throws Exception { Buffer buf = new Buffer(200); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_CHANNEL_OPEN_CONFIRMATION); buf.putInt(getRecipient()); buf.putInt(id); buf.putInt(lwsize); buf.putInt(lmpsize); getSession().write(packet); } protected void sendOpenFailure(int reasoncode) { try { Buffer buf = new Buffer(200); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_CHANNEL_OPEN_FAILURE); buf.putInt(getRecipient()); buf.putInt(reasoncode); buf.putString(Util.str2byte("open failed")); buf.putString(Util.empty); getSession().write(packet); } catch (Exception e) { } } protected Packet genChannelOpenPacket() { Buffer buf = new Buffer(200); Packet packet = new Packet(buf); // byte SSH_MSG_CHANNEL_OPEN(90) // string channel type // // uint32 sender channel // 0 // uint32 initial window size // 0x100000(65536) // uint32 maxmum packet size // 0x4000(16384) packet.reset(); buf.putByte((byte) 90); buf.putString(this.type); buf.putInt(this.id); buf.putInt(this.lwsize); buf.putInt(this.lmpsize); return packet; } protected void sendChannelOpen() throws Exception { Session _session = getSession(); if (!_session.isConnected()) { throw new JSchException("session is down"); } Packet packet = genChannelOpenPacket(); _session.write(packet); int retry = 2000; long start = System.currentTimeMillis(); long timeout = connectTimeout; if (timeout != 0L) retry = 1; synchronized (this) { while (this.getRecipient() == -1 && _session.isConnected() && retry > 0) { if (timeout > 0L) { if ((System.currentTimeMillis() - start) > timeout) { retry = 0; continue; } } try { long t = timeout == 0L ? 10L : timeout; this.notifyme = 1; wait(t); } catch (InterruptedException e) { } finally { this.notifyme = 0; } retry--; } } if (!_session.isConnected()) { throw new JSchException("session is down"); } if (this.getRecipient() == -1) { // timeout throw new JSchException("channel is not opened."); } if (this.open_confirmation == false) { // SSH_MSG_CHANNEL_OPEN_FAILURE throw new JSchException("channel is not opened."); } connected = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java000066400000000000000000000213041465436372100273340ustar00rootroot00000000000000/* * Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.util.Vector; class ChannelAgentForwarding extends Channel { private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000; private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1; private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2; private static final byte SSH_AGENTC_RSA_CHALLENGE = 3; private static final byte SSH_AGENT_RSA_RESPONSE = 4; private static final byte SSH_AGENT_FAILURE = 5; private static final byte SSH_AGENT_SUCCESS = 6; private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7; private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8; private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9; private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11; private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12; private static final byte SSH2_AGENTC_SIGN_REQUEST = 13; private static final byte SSH2_AGENT_SIGN_RESPONSE = 14; private static final byte SSH2_AGENTC_ADD_IDENTITY = 17; private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18; private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19; private static final byte SSH2_AGENT_FAILURE = 30; // static private final int SSH_AGENT_OLD_SIGNATURE=0x1; private static final int SSH_AGENT_RSA_SHA2_256 = 0x2; private static final int SSH_AGENT_RSA_SHA2_512 = 0x4; private Buffer rbuf = null; private Buffer wbuf = null; private Packet packet = null; private Buffer mbuf = null; ChannelAgentForwarding() { super(); lwsize_max = LOCAL_WINDOW_SIZE_MAX; lwsize = LOCAL_WINDOW_SIZE_MAX; lmpsize = LOCAL_MAXIMUM_PACKET_SIZE; type = Util.str2byte("auth-agent@openssh.com"); rbuf = new Buffer(); rbuf.reset(); // wbuf=new Buffer(rmpsize); // packet=new Packet(wbuf); mbuf = new Buffer(); connected = true; } @Override void run() { try { sendOpenConfirmation(); } catch (Exception e) { close = true; disconnect(); } } @Override void write(byte[] foo, int s, int l) throws IOException { if (packet == null) { wbuf = new Buffer(rmpsize); packet = new Packet(wbuf); } rbuf.shift(); if (rbuf.buffer.length < rbuf.index + l) { byte[] newbuf = new byte[rbuf.s + l]; System.arraycopy(rbuf.buffer, 0, newbuf, 0, rbuf.buffer.length); rbuf.buffer = newbuf; } rbuf.putByte(foo, s, l); int mlen = rbuf.getInt(); if (mlen > rbuf.getLength()) { rbuf.s -= 4; return; } int typ = rbuf.getByte(); Session _session = null; try { _session = getSession(); } catch (JSchException e) { throw new IOException(e.toString(), e); } IdentityRepository irepo = _session.getIdentityRepository(); UserInfo userinfo = _session.getUserInfo(); mbuf.reset(); if (typ == SSH2_AGENTC_REQUEST_IDENTITIES) { mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER); Vector identities = irepo.getIdentities(); synchronized (identities) { int count = 0; for (int i = 0; i < identities.size(); i++) { Identity identity = identities.elementAt(i); if (identity.getPublicKeyBlob() != null) count++; } mbuf.putInt(count); for (int i = 0; i < identities.size(); i++) { Identity identity = identities.elementAt(i); byte[] pubkeyblob = identity.getPublicKeyBlob(); if (pubkeyblob == null) continue; mbuf.putString(pubkeyblob); mbuf.putString(Util.empty); } } } else if (typ == SSH_AGENTC_REQUEST_RSA_IDENTITIES) { mbuf.putByte(SSH_AGENT_RSA_IDENTITIES_ANSWER); mbuf.putInt(0); } else if (typ == SSH2_AGENTC_SIGN_REQUEST) { byte[] blob = rbuf.getString(); byte[] data = rbuf.getString(); int flags = rbuf.getInt(); // if((flags & SSH_AGENT_OLD_SIGNATURE)!=0){ // old OpenSSH 2.0, 2.1 // datafellows = SSH_BUG_SIGBLOB; // } Vector identities = irepo.getIdentities(); Identity identity = null; synchronized (identities) { for (int i = 0; i < identities.size(); i++) { Identity _identity = identities.elementAt(i); if (_identity.getPublicKeyBlob() == null) continue; if (!Util.array_equals(blob, _identity.getPublicKeyBlob())) { continue; } if (_identity.isEncrypted()) { if (userinfo == null) continue; while (_identity.isEncrypted()) { if (!userinfo.promptPassphrase("Passphrase for " + _identity.getName())) { break; } String _passphrase = userinfo.getPassphrase(); if (_passphrase == null) { break; } byte[] passphrase = Util.str2byte(_passphrase); try { if (_identity.setPassphrase(passphrase)) { break; } } catch (JSchException e) { break; } } } if (!_identity.isEncrypted()) { identity = _identity; break; } } } byte[] signature = null; if (identity != null) { Buffer kbuf = new Buffer(blob); String keytype = Util.byte2str(kbuf.getString()); if (keytype.equals("ssh-rsa")) { if ((flags & SSH_AGENT_RSA_SHA2_256) != 0) { signature = identity.getSignature(data, "rsa-sha2-256"); } else if ((flags & SSH_AGENT_RSA_SHA2_512) != 0) { signature = identity.getSignature(data, "rsa-sha2-512"); } else { signature = identity.getSignature(data, "ssh-rsa"); } } else { signature = identity.getSignature(data); } } if (signature == null) { mbuf.putByte(SSH2_AGENT_FAILURE); } else { mbuf.putByte(SSH2_AGENT_SIGN_RESPONSE); mbuf.putString(signature); } } else if (typ == SSH2_AGENTC_REMOVE_IDENTITY) { byte[] blob = rbuf.getString(); irepo.remove(blob); mbuf.putByte(SSH_AGENT_SUCCESS); } else if (typ == SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES) { mbuf.putByte(SSH_AGENT_SUCCESS); } else if (typ == SSH2_AGENTC_REMOVE_ALL_IDENTITIES) { irepo.removeAll(); mbuf.putByte(SSH_AGENT_SUCCESS); } else if (typ == SSH2_AGENTC_ADD_IDENTITY) { int fooo = rbuf.getLength(); byte[] tmp = new byte[fooo]; rbuf.getByte(tmp); boolean result = irepo.add(tmp); mbuf.putByte(result ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); } else { rbuf.skip(rbuf.getLength() - 1); mbuf.putByte(SSH_AGENT_FAILURE); } byte[] response = new byte[mbuf.getLength()]; mbuf.getByte(response); send(response); } private void send(byte[] message) { packet.reset(); wbuf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); wbuf.putInt(recipient); wbuf.putInt(4 + message.length); wbuf.putString(message); try { getSession().write(packet, this, 4 + message.length); } catch (Exception e) { } } @Override void eof_remote() { super.eof_remote(); eof(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelDirectStreamLocal.java000066400000000000000000000036451465436372100276240ustar00rootroot00000000000000package com.jcraft.jsch; import static com.jcraft.jsch.Session.SSH_MSG_CHANNEL_OPEN; /** * Extension of {@link ChannelDirectTCPIP} to support socket forwarding. * *

* https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL */ public class ChannelDirectStreamLocal extends ChannelDirectTCPIP { private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000; private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; private static final byte[] _type = Util.str2byte("direct-streamlocal@openssh.com"); private String socketPath; ChannelDirectStreamLocal() { super(); type = _type; lwsize_max = LOCAL_WINDOW_SIZE_MAX; lwsize = LOCAL_WINDOW_SIZE_MAX; lmpsize = LOCAL_MAXIMUM_PACKET_SIZE; } @Override protected Packet genChannelOpenPacket() { if (socketPath == null) { session.getLogger().log(Logger.FATAL, "socketPath must be set"); throw new RuntimeException("socketPath must be set"); } /* * Similar to direct-tcpip, direct-streamlocal is sent by the client to request that the server * make a connection to a Unix domain socket. * * byte SSH_MSG_CHANNEL_OPEN string "direct-streamlocal@openssh.com" uint32 sender channel * uint32 initial window size uint32 maximum packet size string socket path string reserved * uint32 reserved */ Buffer buf = new Buffer(50 + socketPath.length() + session.getBufferMargin()); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_CHANNEL_OPEN); buf.putString(this.type); buf.putInt(id); buf.putInt(lwsize); buf.putInt(lmpsize); buf.putString(Util.str2byte(socketPath)); buf.putString(Util.str2byte(originator_IP_address)); buf.putInt(originator_port); return packet; } public String getSocketPath() { return socketPath; } public void setSocketPath(String socketPath) { this.socketPath = socketPath; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java000066400000000000000000000117731465436372100262760ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.InputStream; import java.io.OutputStream; public class ChannelDirectTCPIP extends Channel { private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000; private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; private static final byte[] _type = Util.str2byte("direct-tcpip"); String host; int port; String originator_IP_address = "127.0.0.1"; int originator_port = 0; ChannelDirectTCPIP() { super(); type = _type; lwsize_max = LOCAL_WINDOW_SIZE_MAX; lwsize = LOCAL_WINDOW_SIZE_MAX; lmpsize = LOCAL_MAXIMUM_PACKET_SIZE; } @Override void init() { io = new IO(); } @Override public void connect(int connectTimeout) throws JSchException { this.connectTimeout = connectTimeout; try { Session _session = getSession(); if (!_session.isConnected()) { throw new JSchException("session is down"); } if (io.in != null) { thread = new Thread(this::run); thread.setName("DirectTCPIP thread " + _session.getHost()); if (_session.daemon_thread) { thread.setDaemon(_session.daemon_thread); } thread.start(); } else { sendChannelOpen(); } } catch (Exception e) { io.close(); io = null; Channel.del(this); if (e instanceof JSchException) { throw (JSchException) e; } } } @Override void run() { try { sendChannelOpen(); Buffer buf = new Buffer(rmpsize); Packet packet = new Packet(buf); Session _session = getSession(); int i = 0; while (isConnected() && thread != null && io != null && io.in != null) { i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin()); if (i <= 0) { eof(); break; } packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(i); buf.skip(i); synchronized (this) { if (close) break; _session.write(packet, this, i); } } } catch (Exception e) { // Whenever an exception is thrown by sendChannelOpen(), // 'connected' is false. if (!connected) { connected = true; } disconnect(); return; } eof(); disconnect(); } @Override public void setInputStream(InputStream in) { io.setInputStream(in); } @Override public void setOutputStream(OutputStream out) { io.setOutputStream(out); } public void setHost(String host) { this.host = host; } public void setPort(int port) { this.port = port; } public void setOrgIPAddress(String foo) { this.originator_IP_address = foo; } public void setOrgPort(int foo) { this.originator_port = foo; } @Override protected Packet genChannelOpenPacket() { Buffer buf = new Buffer(50 + // 6 + 4*8 + 12 host.length() + originator_IP_address.length() + session.getBufferMargin()); Packet packet = new Packet(buf); // byte SSH_MSG_CHANNEL_OPEN(90) // string channel type // // uint32 sender channel // 0 // uint32 initial window size // 0x100000(65536) // uint32 maxmum packet size // 0x4000(16384) packet.reset(); buf.putByte((byte) 90); buf.putString(this.type); buf.putInt(id); buf.putInt(lwsize); buf.putInt(lmpsize); buf.putString(Util.str2byte(host)); buf.putInt(port); buf.putString(Util.str2byte(originator_IP_address)); buf.putInt(originator_port); return packet; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelExec.java000066400000000000000000000055221465436372100251430ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class ChannelExec extends ChannelSession { byte[] command = new byte[0]; @Override public void start() throws JSchException { Session _session = getSession(); try { sendRequests(); Request request = new RequestExec(command); request.request(_session, this); } catch (Exception e) { if (e instanceof JSchException) throw (JSchException) e; throw new JSchException("ChannelExec", e); } if (io.in != null) { thread = new Thread(this::run); thread.setName("Exec thread " + _session.getHost()); if (_session.daemon_thread) { thread.setDaemon(_session.daemon_thread); } thread.start(); } } public void setCommand(String command) { this.command = Util.str2byte(command); } public void setCommand(byte[] command) { this.command = command; } @Override void init() throws JSchException { io.setInputStream(getSession().in); io.setOutputStream(getSession().out); } public void setErrStream(OutputStream out) { setExtOutputStream(out); } public void setErrStream(OutputStream out, boolean dontclose) { setExtOutputStream(out, dontclose); } public InputStream getErrStream() throws IOException { return getExtInputStream(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java000066400000000000000000000250121465436372100267700ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.PipedOutputStream; import java.net.Socket; import java.util.Vector; public class ChannelForwardedTCPIP extends Channel { private static Vector pool = new Vector<>(); private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000; // static private final int LOCAL_WINDOW_SIZE_MAX=0x100000; private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; private static final int TIMEOUT = 10 * 1000; private Socket socket = null; private ForwardedTCPIPDaemon daemon = null; private Config config = null; ChannelForwardedTCPIP() { super(); lwsize_max = LOCAL_WINDOW_SIZE_MAX; lwsize = LOCAL_WINDOW_SIZE_MAX; lmpsize = LOCAL_MAXIMUM_PACKET_SIZE; io = new IO(); connected = true; } @Override public void run() { try { if (config instanceof ConfigDaemon) { ConfigDaemon _config = (ConfigDaemon) config; Class c = Class.forName(_config.target).asSubclass(ForwardedTCPIPDaemon.class); daemon = c.getDeclaredConstructor().newInstance(); PipedOutputStream out = new PipedOutputStream(); io.setInputStream(new PassiveInputStream(out, 32 * 1024), false); daemon.setChannel(this, getInputStream(), out); daemon.setArg(_config.arg); new Thread(daemon).start(); } else { ConfigLHost _config = (ConfigLHost) config; socket = (_config.factory == null) ? Util.createSocket(_config.target, _config.lport, TIMEOUT) : _config.factory.createSocket(_config.target, _config.lport); socket.setTcpNoDelay(true); io.setInputStream(socket.getInputStream()); io.setOutputStream(socket.getOutputStream()); } sendOpenConfirmation(); } catch (Exception e) { sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED); close = true; disconnect(); return; } thread = Thread.currentThread(); Buffer buf = new Buffer(rmpsize); Packet packet = new Packet(buf); int i = 0; try { Session _session = getSession(); while (thread != null && io != null && io.in != null) { i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin()); if (i <= 0) { eof(); break; } packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(i); buf.skip(i); synchronized (this) { if (close) break; _session.write(packet, this, i); } } } catch (Exception e) { // System.err.println(e); } // thread=null; // eof(); disconnect(); } @Override void getData(Buffer buf) { setRecipient(buf.getInt()); setRemoteWindowSize(buf.getUInt()); setRemotePacketSize(buf.getInt()); byte[] addr = buf.getString(); int port = buf.getInt(); byte[] orgaddr = buf.getString(); int orgport = buf.getInt(); /* * System.err.println("addr: "+Util.byte2str(addr)); System.err.println("port: "+port); * System.err.println("orgaddr: "+Util.byte2str(orgaddr)); * System.err.println("orgport: "+orgport); */ Session _session = null; try { _session = getSession(); } catch (JSchException e) { // session has been already down. } this.config = getPort(_session, Util.byte2str(addr), port); if (this.config == null) this.config = getPort(_session, null, port); if (this.config == null) { if (_session.getLogger().isEnabled(Logger.ERROR)) { _session.getLogger().log(Logger.ERROR, "ChannelForwardedTCPIP: " + Util.byte2str(addr) + ":" + port + " is not registered."); } } } private static Config getPort(Session session, String address_to_bind, int rport) { synchronized (pool) { for (int i = 0; i < pool.size(); i++) { Config bar = pool.elementAt(i); if (bar.session != session) continue; if (bar.rport != rport) { if (bar.rport != 0 || bar.allocated_rport != rport) continue; } if (address_to_bind != null && !bar.address_to_bind.equals(address_to_bind)) continue; return bar; } return null; } } static String[] getPortForwarding(Session session) { Vector foo = new Vector<>(); synchronized (pool) { for (int i = 0; i < pool.size(); i++) { Config config = pool.elementAt(i); if (config.session == session) { if (config instanceof ConfigDaemon) foo.addElement(config.allocated_rport + ":" + config.target + ":"); else foo.addElement( config.allocated_rport + ":" + config.target + ":" + ((ConfigLHost) config).lport); } } } String[] bar = new String[foo.size()]; for (int i = 0; i < foo.size(); i++) { bar[i] = foo.elementAt(i); } return bar; } static String normalize(String address) { if (address == null) { return "localhost"; } else if (address.length() == 0 || address.equals("*")) { return ""; } else { return address; } } static void addPort(Session session, String _address_to_bind, int port, int allocated_port, String target, int lport, SocketFactory factory) throws JSchException { String address_to_bind = normalize(_address_to_bind); synchronized (pool) { if (getPort(session, address_to_bind, port) != null) { throw new JSchException("PortForwardingR: remote port " + port + " is already registered."); } ConfigLHost config = new ConfigLHost(); config.session = session; config.rport = port; config.allocated_rport = allocated_port; config.target = target; config.lport = lport; config.address_to_bind = address_to_bind; config.factory = factory; pool.addElement(config); } } static void addPort(Session session, String _address_to_bind, int port, int allocated_port, String daemon, Object[] arg) throws JSchException { String address_to_bind = normalize(_address_to_bind); synchronized (pool) { if (getPort(session, address_to_bind, port) != null) { throw new JSchException("PortForwardingR: remote port " + port + " is already registered."); } ConfigDaemon config = new ConfigDaemon(); config.session = session; config.rport = port; config.allocated_rport = port; config.target = daemon; config.arg = arg; config.address_to_bind = address_to_bind; pool.addElement(config); } } static void delPort(ChannelForwardedTCPIP c) { Session _session = null; try { _session = c.getSession(); } catch (JSchException e) { // session has been already down. } if (_session != null && c.config != null) delPort(_session, c.config.rport); } static void delPort(Session session, int rport) { delPort(session, null, rport); } static void delPort(Session session, String address_to_bind, int rport) { synchronized (pool) { Config foo = getPort(session, normalize(address_to_bind), rport); if (foo == null) foo = getPort(session, null, rport); if (foo == null) return; pool.removeElement(foo); if (address_to_bind == null) { address_to_bind = foo.address_to_bind; } if (address_to_bind == null) { address_to_bind = "0.0.0.0"; } } Buffer buf = new Buffer(200); // ?? Packet packet = new Packet(buf); try { // byte SSH_MSG_GLOBAL_REQUEST 80 // string "cancel-tcpip-forward" // boolean want_reply // string address_to_bind (e.g. "127.0.0.1") // uint32 port number to bind packet.reset(); buf.putByte((byte) 80 /* SSH_MSG_GLOBAL_REQUEST */); buf.putString(Util.str2byte("cancel-tcpip-forward")); buf.putByte((byte) 0); buf.putString(Util.str2byte(address_to_bind)); buf.putInt(rport); session.write(packet); } catch (Exception e) { // throw new JSchException(e.toString(), e); } } static void delPort(Session session) { int[] rport = null; int count = 0; synchronized (pool) { rport = new int[pool.size()]; for (int i = 0; i < pool.size(); i++) { Config config = pool.elementAt(i); if (config.session == session) { rport[count++] = config.rport; // ((Integer)bar[1]).intValue(); } } } for (int i = 0; i < count; i++) { delPort(session, rport[i]); } } public int getRemotePort() { return (config != null ? config.rport : 0); } private void setSocketFactory(SocketFactory factory) { if (config != null && (config instanceof ConfigLHost)) ((ConfigLHost) config).factory = factory; } abstract static class Config { Session session; int rport; int allocated_rport; String address_to_bind; String target; } static class ConfigDaemon extends Config { Object[] arg; } static class ConfigLHost extends Config { int lport; SocketFactory factory; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelSession.java000066400000000000000000000171521465436372100257040ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Enumeration; import java.util.Hashtable; class ChannelSession extends Channel { private static byte[] _session = Util.str2byte("session"); protected boolean agent_forwarding = false; protected boolean xforwading = false; protected Hashtable env = null; protected boolean pty = false; protected String ttype = "vt100"; protected int tcol = 80; protected int trow = 24; protected int twp = 640; protected int thp = 480; protected byte[] terminal_mode = null; ChannelSession() { super(); type = _session; io = new IO(); } /** * Enable the agent forwarding. * * @param enable */ public void setAgentForwarding(boolean enable) { agent_forwarding = enable; } /** * Enable the X11 forwarding. Refer to RFC4254 6.3.1. Requesting X11 Forwarding. * * @param enable */ @Override public void setXForwarding(boolean enable) { xforwading = enable; } /** * @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead. * @see #setEnv(String, String) * @see #setEnv(byte[], byte[]) */ @Deprecated public void setEnv(Hashtable env) { synchronized (this) { this.env = env; } } /** * Set the environment variable. If name and value are needed to be * passed to the remote in your favorite encoding, use {@link #setEnv(byte[], byte[])}. Refer to * RFC4254 6.4 Environment Variable Passing. * * @param name A name for environment variable. * @param value A value for environment variable. */ public void setEnv(String name, String value) { setEnv(Util.str2byte(name), Util.str2byte(value)); } /** * Set the environment variable. Refer to RFC4254 6.4 Environment Variable Passing. * * @param name A name of environment variable. * @param value A value of environment variable. * @see #setEnv(String, String) */ public void setEnv(byte[] name, byte[] value) { synchronized (this) { getEnv().put(name, value); } } private Hashtable getEnv() { if (env == null) env = new Hashtable<>(); return env; } /** * Allocate a Pseudo-Terminal. Refer to RFC4254 6.2. Requesting a Pseudo-Terminal. * * @param enable */ public void setPty(boolean enable) { pty = enable; } /** * Set the terminal mode. * * @param terminal_mode */ public void setTerminalMode(byte[] terminal_mode) { this.terminal_mode = terminal_mode; } /** * Change the window dimension interactively. Refer to RFC4254 6.7. Window Dimension Change * Message. * * @param col terminal width, columns * @param row terminal height, rows * @param wp terminal width, pixels * @param hp terminal height, pixels */ public void setPtySize(int col, int row, int wp, int hp) { setPtyType(this.ttype, col, row, wp, hp); if (!pty || !isConnected()) { return; } try { RequestWindowChange request = new RequestWindowChange(); request.setSize(col, row, wp, hp); request.request(getSession(), this); } catch (Exception e) { // System.err.println("ChannelSessio.setPtySize: "+e); } } /** * Set the terminal type. This method is not effective after Channel#connect(). * * @param ttype terminal type(for example, "vt100") * @see #setPtyType(String, int, int, int, int) */ public void setPtyType(String ttype) { setPtyType(ttype, 80, 24, 640, 480); } /** * Set the terminal type. This method is not effective after Channel#connect(). * * @param ttype terminal type(for example, "vt100") * @param col terminal width, columns * @param row terminal height, rows * @param wp terminal width, pixels * @param hp terminal height, pixels */ public void setPtyType(String ttype, int col, int row, int wp, int hp) { this.ttype = ttype; this.tcol = col; this.trow = row; this.twp = wp; this.thp = hp; } protected void sendRequests() throws Exception { Session _session = getSession(); Request request; if (agent_forwarding) { request = new RequestAgentForwarding(); request.request(_session, this); } if (xforwading) { request = new RequestX11(); request.request(_session, this); } if (pty) { request = new RequestPtyReq(); ((RequestPtyReq) request).setTType(ttype); ((RequestPtyReq) request).setTSize(tcol, trow, twp, thp); if (terminal_mode != null) { ((RequestPtyReq) request).setTerminalMode(terminal_mode); } request.request(_session, this); } if (env != null) { for (Enumeration _env = env.keys(); _env.hasMoreElements();) { byte[] name = _env.nextElement(); byte[] value = env.get(name); request = new RequestEnv(); ((RequestEnv) request).setEnv(toByteArray(name), toByteArray(value)); request.request(_session, this); } } } private byte[] toByteArray(Object o) { if (o instanceof String) { return Util.str2byte((String) o); } return (byte[]) o; } @Override void run() { // System.err.println(this+":run >"); Buffer buf = new Buffer(rmpsize); Packet packet = new Packet(buf); int i = -1; try { Session _session = getSession(); while (isConnected() && thread != null && io != null && io.in != null) { i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin()); if (i == 0) continue; if (i == -1) { eof(); break; } if (close) break; // System.out.println("write: "+i); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(i); buf.skip(i); _session.write(packet, this, i); } } catch (Exception e) { // System.err.println("# ChannelExec.run"); // e.printStackTrace(); } Thread _thread = thread; if (_thread != null) { synchronized (_thread) { _thread.notifyAll(); } } thread = null; // System.err.println(this+":run <"); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelSftp.java000066400000000000000000002544611465436372100252030ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Hashtable; import java.util.Vector; public class ChannelSftp extends ChannelSession { private static final int LOCAL_MAXIMUM_PACKET_SIZE = 32 * 1024; private static final int LOCAL_WINDOW_SIZE_MAX = (64 * LOCAL_MAXIMUM_PACKET_SIZE); private static final byte SSH_FXP_INIT = 1; private static final byte SSH_FXP_VERSION = 2; private static final byte SSH_FXP_OPEN = 3; private static final byte SSH_FXP_CLOSE = 4; private static final byte SSH_FXP_READ = 5; private static final byte SSH_FXP_WRITE = 6; private static final byte SSH_FXP_LSTAT = 7; private static final byte SSH_FXP_FSTAT = 8; private static final byte SSH_FXP_SETSTAT = 9; private static final byte SSH_FXP_FSETSTAT = 10; private static final byte SSH_FXP_OPENDIR = 11; private static final byte SSH_FXP_READDIR = 12; private static final byte SSH_FXP_REMOVE = 13; private static final byte SSH_FXP_MKDIR = 14; private static final byte SSH_FXP_RMDIR = 15; private static final byte SSH_FXP_REALPATH = 16; private static final byte SSH_FXP_STAT = 17; private static final byte SSH_FXP_RENAME = 18; private static final byte SSH_FXP_READLINK = 19; private static final byte SSH_FXP_SYMLINK = 20; private static final byte SSH_FXP_STATUS = 101; private static final byte SSH_FXP_HANDLE = 102; private static final byte SSH_FXP_DATA = 103; private static final byte SSH_FXP_NAME = 104; private static final byte SSH_FXP_ATTRS = 105; private static final byte SSH_FXP_EXTENDED = (byte) 200; private static final byte SSH_FXP_EXTENDED_REPLY = (byte) 201; // pflags private static final int SSH_FXF_READ = 0x00000001; private static final int SSH_FXF_WRITE = 0x00000002; private static final int SSH_FXF_APPEND = 0x00000004; private static final int SSH_FXF_CREAT = 0x00000008; private static final int SSH_FXF_TRUNC = 0x00000010; private static final int SSH_FXF_EXCL = 0x00000020; private static final int SSH_FILEXFER_ATTR_SIZE = 0x00000001; private static final int SSH_FILEXFER_ATTR_UIDGID = 0x00000002; private static final int SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004; private static final int SSH_FILEXFER_ATTR_ACMODTIME = 0x00000008; private static final int SSH_FILEXFER_ATTR_EXTENDED = 0x80000000; public static final int SSH_FX_OK = 0; public static final int SSH_FX_EOF = 1; public static final int SSH_FX_NO_SUCH_FILE = 2; public static final int SSH_FX_PERMISSION_DENIED = 3; public static final int SSH_FX_FAILURE = 4; public static final int SSH_FX_BAD_MESSAGE = 5; public static final int SSH_FX_NO_CONNECTION = 6; public static final int SSH_FX_CONNECTION_LOST = 7; public static final int SSH_FX_OP_UNSUPPORTED = 8; /* * SSH_FX_OK Indicates successful completion of the operation. SSH_FX_EOF indicates end-of-file * condition; for SSH_FX_READ it means that no more data is available in the file, and for * SSH_FX_READDIR it indicates that no more files are contained in the directory. * SSH_FX_NO_SUCH_FILE is returned when a reference is made to a file which should exist but * doesn't. SSH_FX_PERMISSION_DENIED is returned when the authenticated user does not have * sufficient permissions to perform the operation. SSH_FX_FAILURE is a generic catch-all error * message; it should be returned if an error occurs for which there is no more specific error * code defined. SSH_FX_BAD_MESSAGE may be returned if a badly formatted packet or protocol * incompatibility is detected. SSH_FX_NO_CONNECTION is a pseudo-error which indicates that the * client has no connection to the server (it can only be generated locally by the client, and * MUST NOT be returned by servers). SSH_FX_CONNECTION_LOST is a pseudo-error which indicates that * the connection to the server has been lost (it can only be generated locally by the client, and * MUST NOT be returned by servers). SSH_FX_OP_UNSUPPORTED indicates that an attempt was made to * perform an operation which is not supported for the server (it may be generated locally by the * client if e.g. the version number exchange indicates that a required feature is not supported * by the server, or it may be returned by the server if the server does not implement an * operation). */ private static final int MAX_MSG_LENGTH = 256 * 1024; public static final int OVERWRITE = 0; public static final int RESUME = 1; public static final int APPEND = 2; private boolean interactive = false; private int seq = 1; private int[] ackid = new int[1]; private Buffer buf; private Packet packet; // The followings will be used in file uploading. private Buffer obuf; private Packet opacket; private int client_version = 3; private int server_version = 3; private String version = String.valueOf(client_version); private Hashtable extensions = null; private InputStream io_in = null; private boolean extension_posix_rename = false; private boolean extension_statvfs = false; // private boolean extension_fstatvfs = false; private boolean extension_hardlink = false; /* * 10. Changes from previous protocol versions The SSH File Transfer Protocol has changed over * time, before it's standardization. The following is a description of the incompatible changes * between different versions. 10.1 Changes between versions 3 and 2 o The SSH_FXP_READLINK and * SSH_FXP_SYMLINK messages were added. o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages * were added. o The SSH_FXP_STATUS message was changed to include fields `error message' and * `language tag'. 10.2 Changes between versions 2 and 1 o The SSH_FXP_RENAME message was added. * 10.3 Changes between versions 1 and 0 o Implementation changes, no actual protocol changes. */ private static final String file_separator = File.separator; private static final char file_separatorc = File.separatorChar; private static boolean fs_is_bs = (byte) File.separatorChar == '\\'; private String cwd; private String home; private String lcwd; private Charset fEncoding = StandardCharsets.UTF_8; private boolean fEncoding_is_utf8 = true; private boolean useWriteFlushWorkaround = true; private RequestQueue rq = new RequestQueue(16); /** * Specify how many requests may be sent at any one time. Increasing this value may slightly * improve file transfer speed but will increase memory usage. The default is 16 requests. * * @param bulk_requests how many requests may be outstanding at any one time. */ public void setBulkRequests(int bulk_requests) throws JSchException { if (bulk_requests > 0) rq = new RequestQueue(bulk_requests); else throw new JSchException("setBulkRequests: " + bulk_requests + " must be greater than 0."); } /** * This method will return the value how many requests may be sent at any one time. * * @return how many requests may be sent at any one time. */ public int getBulkRequests() { return rq.size(); } public void setUseWriteFlushWorkaround(boolean useWriteFlushWorkaround) { this.useWriteFlushWorkaround = useWriteFlushWorkaround; } public boolean getUseWriteFlushWorkaround() { return useWriteFlushWorkaround; } public ChannelSftp() { super(); lwsize_max = LOCAL_WINDOW_SIZE_MAX; lwsize = LOCAL_WINDOW_SIZE_MAX; lmpsize = LOCAL_MAXIMUM_PACKET_SIZE; } @Override void init() {} @Override public void start() throws JSchException { try { PipedOutputStream pos = new PipedOutputStream(); io.setOutputStream(pos); PipedInputStream pis = new MyPipedInputStream(pos, rq.size() * rmpsize); io.setInputStream(pis); io_in = io.in; if (io_in == null) { throw new JSchException("channel is down"); } Request request = new RequestSftp(); request.request(getSession(), this); /* * System.err.println("lmpsize: "+lmpsize); System.err.println("lwsize: "+lwsize); * System.err.println("rmpsize: "+rmpsize); System.err.println("rwsize: "+rwsize); */ buf = new Buffer(lmpsize); packet = new Packet(buf); obuf = new Buffer(rmpsize); opacket = new Packet(obuf); int i = 0; int length; int type; byte[] str; // send SSH_FXP_INIT sendINIT(); // receive SSH_FXP_VERSION Header header = new Header(); header = header(buf, header); length = header.length; if (length > MAX_MSG_LENGTH) { throw new SftpException(SSH_FX_FAILURE, "Received message is too long: " + length); } type = header.type; // 2 -> SSH_FXP_VERSION server_version = header.rid; // System.err.println("SFTP protocol server-version="+server_version); extensions = new Hashtable<>(); if (length > 0) { // extension data fill(buf, length); byte[] extension_name = null; byte[] extension_data = null; while (length > 0) { extension_name = buf.getString(); length -= (4 + extension_name.length); extension_data = buf.getString(); length -= (4 + extension_data.length); extensions.put(Util.byte2str(extension_name), Util.byte2str(extension_data)); } } if (extensions.get("posix-rename@openssh.com") != null && extensions.get("posix-rename@openssh.com").equals("1")) { extension_posix_rename = true; } if (extensions.get("statvfs@openssh.com") != null && extensions.get("statvfs@openssh.com").equals("2")) { extension_statvfs = true; } /* * if(extensions.get("fstatvfs@openssh.com")!=null && * extensions.get("fstatvfs@openssh.com").equals("2")){ extension_fstatvfs = true; } */ if (extensions.get("hardlink@openssh.com") != null && extensions.get("hardlink@openssh.com").equals("1")) { extension_hardlink = true; } lcwd = new File(".").getCanonicalPath(); } catch (Exception e) { // System.err.println(e); if (e instanceof JSchException) throw (JSchException) e; throw new JSchException(e.toString(), e); } } public void quit() { disconnect(); } public void exit() { disconnect(); } public void lcd(String path) throws SftpException { path = localAbsolutePath(path); if ((new File(path)).isDirectory()) { try { path = (new File(path)).getCanonicalPath(); } catch (Exception e) { } lcwd = path; return; } throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such directory"); } public void cd(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); path = isUnique(path); byte[] str = _realpath(path); SftpATTRS attr = _stat(str); if ((attr.getFlags() & SftpATTRS.SSH_FILEXFER_ATTR_PERMISSIONS) == 0) { throw new SftpException(SSH_FX_FAILURE, "Can't change directory: " + path); } if (!attr.isDir()) { throw new SftpException(SSH_FX_FAILURE, "Can't change directory: " + path); } setCwd(Util.byte2str(str, fEncoding)); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void put(String src, String dst) throws SftpException { put(src, dst, null, OVERWRITE); } public void put(String src, String dst, int mode) throws SftpException { put(src, dst, null, mode); } public void put(String src, String dst, SftpProgressMonitor monitor) throws SftpException { put(src, dst, monitor, OVERWRITE); } /** * Sends data from src file to dst file. The mode should be * OVERWRITE, RESUME or APPEND. * * @param src source file * @param dst destination file * @param monitor progress monitor * @param mode how data should be added to dst */ public void put(String src, String dst, SftpProgressMonitor monitor, int mode) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); src = localAbsolutePath(src); dst = remoteAbsolutePath(dst); Vector v = glob_remote(dst); int vsize = v.size(); if (vsize != 1) { if (vsize == 0) { if (isPattern(dst)) throw new SftpException(SSH_FX_FAILURE, dst); else dst = Util.unquote(dst); } throw new SftpException(SSH_FX_FAILURE, v.toString()); } else { dst = v.elementAt(0); } boolean isRemoteDir = isRemoteDir(dst); v = glob_local(src); vsize = v.size(); StringBuilder dstsb = null; if (isRemoteDir) { if (!dst.endsWith("/")) { dst += "/"; } dstsb = new StringBuilder(dst); } else if (vsize > 1) { throw new SftpException(SSH_FX_FAILURE, "Copying multiple files, but the destination is missing or a file."); } for (int j = 0; j < vsize; j++) { String _src = v.elementAt(j); String _dst = null; if (isRemoteDir) { int i = _src.lastIndexOf(file_separatorc); if (fs_is_bs) { int ii = _src.lastIndexOf('/'); if (ii != -1 && ii > i) i = ii; } if (i == -1) dstsb.append(_src); else dstsb.append(_src.substring(i + 1)); _dst = dstsb.toString(); dstsb.delete(dst.length(), _dst.length()); } else { _dst = dst; } // System.err.println("_dst "+_dst); long size_of_dst = 0; if (mode == RESUME) { try { SftpATTRS attr = _stat(_dst); size_of_dst = attr.getSize(); } catch (Exception eee) { // System.err.println(eee); } long size_of_src = new File(_src).length(); if (size_of_src < size_of_dst) { throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + _dst); } if (size_of_src == size_of_dst) { return; } } if (monitor != null) { monitor.init(SftpProgressMonitor.PUT, _src, _dst, (new File(_src)).length()); if (mode == RESUME) { monitor.count(size_of_dst); } } try (InputStream fis = new FileInputStream(_src)) { _put(fis, _dst, monitor, mode); } } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void put(InputStream src, String dst) throws SftpException { put(src, dst, null, OVERWRITE); } public void put(InputStream src, String dst, int mode) throws SftpException { put(src, dst, null, mode); } public void put(InputStream src, String dst, SftpProgressMonitor monitor) throws SftpException { put(src, dst, monitor, OVERWRITE); } /** * Sends data from the input stream src to dst file. The * mode should be OVERWRITE, RESUME or APPEND. * * @param src input stream * @param dst destination file * @param monitor progress monitor * @param mode how data should be added to dst */ public void put(InputStream src, String dst, SftpProgressMonitor monitor, int mode) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); dst = remoteAbsolutePath(dst); Vector v = glob_remote(dst); int vsize = v.size(); if (vsize != 1) { if (vsize == 0) { if (isPattern(dst)) throw new SftpException(SSH_FX_FAILURE, dst); else dst = Util.unquote(dst); } throw new SftpException(SSH_FX_FAILURE, v.toString()); } else { dst = v.elementAt(0); } if (monitor != null) { monitor.init(SftpProgressMonitor.PUT, "-", dst, SftpProgressMonitor.UNKNOWN_SIZE); } _put(src, dst, monitor, mode); } catch (Exception e) { if (e instanceof SftpException) { if (((SftpException) e).id == SSH_FX_FAILURE && isRemoteDir(dst)) { throw new SftpException(SSH_FX_FAILURE, dst + " is a directory"); } throw (SftpException) e; } throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void _put(InputStream src, String dst, SftpProgressMonitor monitor, int mode) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); byte[] dstb = Util.str2byte(dst, fEncoding); long skip = 0; if (mode == RESUME || mode == APPEND) { try { SftpATTRS attr = _stat(dstb); skip = attr.getSize(); } catch (Exception eee) { // System.err.println(eee); } } if (mode == RESUME && skip > 0) { long skipped = src.skip(skip); if (skipped < skip) { throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + dst); } } if (mode == OVERWRITE) { sendOPENW(dstb); } else { sendOPENA(dstb); } Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, "invalid type=" + type); } if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } byte[] handle = buf.getString(); // handle byte[] data = null; boolean dontcopy = true; int buffer_margin = session.getBufferMargin(); if (!dontcopy) { // This case will not work anymore. data = new byte[obuf.buffer.length - (5 + 13 + 21 + handle.length + buffer_margin)]; } long offset = 0; if (mode == RESUME || mode == APPEND) { offset += skip; } int startid = seq; int ackcount = 0; int _s = 0; int _datalen = 0; if (!dontcopy) { // This case will not work anymore. _datalen = data.length; } else { data = obuf.buffer; _s = 5 + 13 + 21 + handle.length; _datalen = obuf.buffer.length - _s - buffer_margin; } int bulk_requests = rq.size(); while (true) { int nread = 0; int count = 0; int s = _s; int datalen = _datalen; do { nread = src.read(data, s, datalen); if (nread > 0) { s += nread; datalen -= nread; count += nread; } } while (datalen > 0 && nread > 0); if (count <= 0) break; int foo = count; while (foo > 0) { if ((seq - 1) == startid || ((seq - startid) - ackcount) >= bulk_requests) { while (((seq - startid) - ackcount) >= bulk_requests) { if (checkStatus(ackid, header)) { int _ackid = ackid[0]; if (startid > _ackid || _ackid > seq - 1) { if (_ackid == seq) { if (getSession().getLogger().isEnabled(Logger.ERROR)) { getSession().getLogger().log(Logger.ERROR, "ack error: startid=" + startid + " seq=" + seq + " _ackid=" + _ackid); } } else { throw new SftpException(SSH_FX_FAILURE, "ack error: startid=" + startid + " seq=" + seq + " _ackid=" + _ackid); } } ackcount++; } else { break; } } } if (dontcopy) { foo -= sendWRITE(handle, offset, data, 0, foo); if (data != obuf.buffer) { data = obuf.buffer; _datalen = obuf.buffer.length - _s - buffer_margin; } } else { foo -= sendWRITE(handle, offset, data, _s, foo); } } offset += count; if (monitor != null && !monitor.count(count)) { break; } } int _ackcount = seq - startid; while (_ackcount > ackcount) { if (!checkStatus(null, header)) { break; } ackcount++; } if (monitor != null) monitor.end(); _sendCLOSE(handle, header); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public OutputStream put(String dst) throws SftpException { return put(dst, (SftpProgressMonitor) null, OVERWRITE); } public OutputStream put(String dst, final int mode) throws SftpException { return put(dst, (SftpProgressMonitor) null, mode); } public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode) throws SftpException { return put(dst, monitor, mode, 0); } /** * Sends data from the output stream to dst file. The mode should be * OVERWRITE, RESUME or APPEND. * * @param dst destination file * @param monitor progress monitor * @param mode how data should be added to dst * @param offset data will be added at offset * @return output stream, which accepts data to be transferred. */ public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); dst = remoteAbsolutePath(dst); dst = isUnique(dst); if (isRemoteDir(dst)) { throw new SftpException(SSH_FX_FAILURE, dst + " is a directory"); } byte[] dstb = Util.str2byte(dst, fEncoding); long skip = 0; if (mode == RESUME || mode == APPEND) { try { SftpATTRS attr = _stat(dstb); skip = attr.getSize(); } catch (Exception eee) { // System.err.println(eee); } } if (monitor != null) { monitor.init(SftpProgressMonitor.PUT, "-", dst, SftpProgressMonitor.UNKNOWN_SIZE); } if (mode == OVERWRITE) { sendOPENW(dstb); } else { sendOPENA(dstb); } Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } final byte[] handle = buf.getString(); // handle if (mode == RESUME || mode == APPEND) { offset += skip; } final long[] _offset = new long[1]; _offset[0] = offset; OutputStream out = new OutputStream() { private boolean init = true; private boolean isClosed = false; private int[] ackid = new int[1]; private int startid = 0; private int _ackid = 0; private int ackcount = 0; private int writecount = 0; private Header header = new Header(); @Override public void write(byte[] d) throws IOException { write(d, 0, d.length); } @Override public void write(byte[] d, int s, int len) throws IOException { if (init) { startid = seq; _ackid = seq; init = false; } if (isClosed) { throw new IOException("stream already closed"); } try { int _len = len; while (_len > 0) { if (useWriteFlushWorkaround && rwsize < 21 + handle.length + _len + 4) { flush(); } int sent = sendWRITE(handle, _offset[0], d, s, _len); writecount++; _offset[0] += sent; s += sent; _len -= sent; if ((seq - 1) == startid || io_in.available() >= 1024) { while (io_in.available() > 0) { if (checkStatus(ackid, header)) { _ackid = ackid[0]; if (startid > _ackid || _ackid > seq - 1) { throw new SftpException(SSH_FX_FAILURE, ""); } ackcount++; } else { break; } } } } if (monitor != null && !monitor.count(len)) { close(); throw new IOException("canceled"); } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e.toString(), e); } } byte[] _data = new byte[1]; @Override public void write(int foo) throws IOException { _data[0] = (byte) foo; write(_data, 0, 1); } @Override public void flush() throws IOException { if (isClosed) { throw new IOException("stream already closed"); } if (!init) { try { while (writecount > ackcount) { if (!checkStatus(null, header)) { break; } ackcount++; } } catch (SftpException e) { throw new IOException(e.toString(), e); } } } @Override public void close() throws IOException { if (isClosed) { return; } flush(); if (monitor != null) monitor.end(); try { _sendCLOSE(handle, header); } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e.toString(), e); } isClosed = true; } }; return out; } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void get(String src, String dst) throws SftpException { get(src, dst, null, OVERWRITE); } public void get(String src, String dst, SftpProgressMonitor monitor) throws SftpException { get(src, dst, monitor, OVERWRITE); } public void get(String src, String dst, SftpProgressMonitor monitor, int mode) throws SftpException { // System.out.println("get: "+src+" "+dst); boolean _dstExist = false; String _dst = null; try { ((MyPipedInputStream) io_in).updateReadSide(); src = remoteAbsolutePath(src); dst = localAbsolutePath(dst); Vector v = glob_remote(src); int vsize = v.size(); if (vsize == 0) { throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file"); } File dstFile = new File(dst); boolean isDstDir = dstFile.isDirectory(); StringBuilder dstsb = null; if (isDstDir) { if (!dst.endsWith(file_separator)) { dst += file_separator; } dstsb = new StringBuilder(dst); } else if (vsize > 1) { throw new SftpException(SSH_FX_FAILURE, "Copying multiple files, but destination is missing or a file."); } for (int j = 0; j < vsize; j++) { String _src = v.elementAt(j); SftpATTRS attr = _stat(_src); if (attr.isDir()) { throw new SftpException(SSH_FX_FAILURE, "not supported to get directory " + _src); } _dst = null; if (isDstDir) { int i = _src.lastIndexOf('/'); if (i == -1) dstsb.append(_src); else dstsb.append(_src.substring(i + 1)); _dst = dstsb.toString(); if (_dst.indexOf("..") != -1) { String dstc = (new File(dst)).getCanonicalPath(); String _dstc = (new File(_dst)).getCanonicalPath(); if (!(_dstc.length() > dstc.length() && _dstc.substring(0, dstc.length() + 1).equals(dstc + file_separator))) { throw new SftpException(SSH_FX_FAILURE, "writing to an unexpected file " + _src); } } dstsb.delete(dst.length(), _dst.length()); } else { _dst = dst; } File _dstFile = new File(_dst); if (mode == RESUME) { long size_of_src = attr.getSize(); long size_of_dst = _dstFile.length(); if (size_of_dst > size_of_src) { throw new SftpException(SSH_FX_FAILURE, "failed to resume for " + _dst); } if (size_of_dst == size_of_src) { return; } } if (monitor != null) { monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize()); if (mode == RESUME) { monitor.count(_dstFile.length()); } } _dstExist = _dstFile.exists(); try (OutputStream fos = mode == OVERWRITE ? new FileOutputStream(_dst) : new FileOutputStream(_dst, true) /* append */) { // System.err.println("_get: "+_src+", "+_dst); _get(_src, fos, monitor, mode, new File(_dst).length()); } } } catch (Exception e) { if (!_dstExist && _dst != null) { File _dstFile = new File(_dst); if (_dstFile.exists() && _dstFile.length() == 0) { _dstFile.delete(); } } if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void get(String src, OutputStream dst) throws SftpException { get(src, dst, null, OVERWRITE, 0); } public void get(String src, OutputStream dst, SftpProgressMonitor monitor) throws SftpException { get(src, dst, monitor, OVERWRITE, 0); } public void get(String src, OutputStream dst, SftpProgressMonitor monitor, int mode, long skip) throws SftpException { // System.err.println("get: "+src+", "+dst); try { ((MyPipedInputStream) io_in).updateReadSide(); src = remoteAbsolutePath(src); src = isUnique(src); if (monitor != null) { SftpATTRS attr = _stat(src); monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize()); if (mode == RESUME) { monitor.count(skip); } } _get(src, dst, monitor, mode, skip); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private void _get(String src, OutputStream dst, SftpProgressMonitor monitor, int mode, long skip) throws SftpException { // System.err.println("_get: "+src+", "+dst); byte[] srcb = Util.str2byte(src, fEncoding); try { sendOPENR(srcb); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } byte[] handle = buf.getString(); // filename long offset = 0; if (mode == RESUME) { offset += skip; } int request_max = 1; rq.init(); long request_offset = offset; int request_len = buf.buffer.length - 13; if (server_version == 0) { request_len = 1024; } loop: while (true) { while (rq.count() < request_max) { sendREAD(handle, request_offset, request_len, rq); request_offset += request_len; } header = header(buf, header); length = header.length; type = header.type; RequestQueue.Request rr = null; try { rr = rq.get(header.rid); } catch (RequestQueue.OutOfOrderException e) { request_offset = e.offset; skip(header.length); rq.cancel(header, buf); continue; } if (type == SSH_FXP_STATUS) { fill(buf, length); int i = buf.getInt(); if (i == SSH_FX_EOF) { break loop; } throwStatusError(buf, i); } if (type != SSH_FXP_DATA) { break loop; } buf.rewind(); fill(buf.buffer, 0, 4); length -= 4; int length_of_data = buf.getInt(); // length of data /* * Since sftp protocol version 6, "end-of-file" has been defined, byte SSH_FXP_DATA uint32 * request-id string data bool end-of-file [optional] but some sftpd server will send such a * field in the sftp protocol 3 ;-( */ int optional_data = length - length_of_data; int foo = length_of_data; while (foo > 0) { int bar = foo; if (bar > buf.buffer.length) { bar = buf.buffer.length; } int data_len = io_in.read(buf.buffer, 0, bar); if (data_len < 0) { break loop; } dst.write(buf.buffer, 0, data_len); offset += data_len; foo -= data_len; if (monitor != null) { if (!monitor.count(data_len)) { skip(foo); if (optional_data > 0) { skip(optional_data); } break loop; } } } // System.err.println("length: "+length); // length should be 0 if (optional_data > 0) { skip(optional_data); } if (length_of_data < rr.length) { // rq.cancel(header, buf); sendREAD(handle, rr.offset + length_of_data, (int) (rr.length - length_of_data), rq); request_offset = rr.offset + rr.length; } if (request_max < rq.size()) { request_max++; } } dst.flush(); if (monitor != null) monitor.end(); rq.cancel(header, buf); _sendCLOSE(handle, header); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private class RequestQueue { class OutOfOrderException extends Exception { private static final long serialVersionUID = -1L; long offset; OutOfOrderException(long offset) { this.offset = offset; } } class Request { int id; long offset; long length; } Request[] rrq = null; int head, count; RequestQueue(int size) { rrq = new Request[size]; for (int i = 0; i < rrq.length; i++) { rrq[i] = new Request(); } init(); } void init() { head = count = 0; } void add(int id, long offset, int length) { if (count == 0) head = 0; int tail = head + count; if (tail >= rrq.length) tail -= rrq.length; rrq[tail].id = id; rrq[tail].offset = offset; rrq[tail].length = length; count++; } Request get(int id) throws OutOfOrderException, SftpException { count -= 1; int i = head; head++; if (head == rrq.length) head = 0; if (rrq[i].id != id) { long offset = getOffset(); boolean find = false; for (int j = 0; j < rrq.length; j++) { if (rrq[j].id == id) { find = true; rrq[j].id = 0; break; } } if (find) throw new OutOfOrderException(offset); throw new SftpException(SSH_FX_FAILURE, "RequestQueue: unknown request id " + id); } rrq[i].id = 0; return rrq[i]; } int count() { return count; } int size() { return rrq.length; } void cancel(Header header, Buffer buf) throws IOException { int _count = count; for (int i = 0; i < _count; i++) { header = header(buf, header); int length = header.length; for (int j = 0; j < rrq.length; j++) { if (rrq[j].id == header.rid) { rrq[j].id = 0; break; } } skip(length); } init(); } long getOffset() { long result = Long.MAX_VALUE; for (int i = 0; i < rrq.length; i++) { if (rrq[i].id == 0) continue; if (result > rrq[i].offset) result = rrq[i].offset; } return result; } } public InputStream get(String src) throws SftpException { return get(src, null, 0L); } public InputStream get(String src, SftpProgressMonitor monitor) throws SftpException { return get(src, monitor, 0L); } /** * @deprecated This method will be deleted in the future. */ @Deprecated public InputStream get(String src, int mode) throws SftpException { return get(src, null, 0L); } /** * @deprecated This method will be deleted in the future. */ @Deprecated public InputStream get(String src, final SftpProgressMonitor monitor, final int mode) throws SftpException { return get(src, monitor, 0L); } public InputStream get(String src, final SftpProgressMonitor monitor, final long skip) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); src = remoteAbsolutePath(src); src = isUnique(src); byte[] srcb = Util.str2byte(src, fEncoding); SftpATTRS attr = _stat(srcb); if (monitor != null) { monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize()); } sendOPENR(srcb); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } final byte[] handle = buf.getString(); // handle rq.init(); InputStream in = new InputStream() { long offset = skip; boolean closed = false; int rest_length = 0; byte[] _data = new byte[1]; byte[] rest_byte = new byte[1024]; Header header = new Header(); int request_max = 1; long request_offset = offset; @Override public int read() throws IOException { if (closed) return -1; int i = read(_data, 0, 1); if (i == -1) { return -1; } else { return _data[0] & 0xff; } } @Override public int read(byte[] d) throws IOException { if (closed) return -1; return read(d, 0, d.length); } @Override public int read(byte[] d, int s, int len) throws IOException { if (closed) return -1; if (d == null) { throw new NullPointerException(); } if (s < 0 || len < 0 || s + len > d.length) { throw new IndexOutOfBoundsException(); } if (len == 0) { return 0; } if (rest_length > 0) { int foo = rest_length; if (foo > len) foo = len; System.arraycopy(rest_byte, 0, d, s, foo); if (foo != rest_length) { System.arraycopy(rest_byte, foo, rest_byte, 0, rest_length - foo); } if (monitor != null) { if (!monitor.count(foo)) { close(); return -1; } } rest_length -= foo; return foo; } if (buf.buffer.length - 13 < len) { len = buf.buffer.length - 13; } if (server_version == 0 && len > 1024) { len = 1024; } if (rq.count() == 0 || true // working around slow transfer speed for // some sftp servers including Titan FTP. ) { int request_len = buf.buffer.length - 13; if (server_version == 0) { request_len = 1024; } while (rq.count() < request_max) { try { sendREAD(handle, request_offset, request_len, rq); } catch (Exception e) { throw new IOException("error"); } request_offset += request_len; } } header = header(buf, header); rest_length = header.length; int type = header.type; int id = header.rid; RequestQueue.Request rr = null; try { rr = rq.get(header.rid); } catch (RequestQueue.OutOfOrderException e) { request_offset = e.offset; skip(header.length); rq.cancel(header, buf); return 0; } catch (SftpException e) { throw new IOException("error: " + e.toString(), e); } if (type != SSH_FXP_STATUS && type != SSH_FXP_DATA) { throw new IOException("error"); } if (type == SSH_FXP_STATUS) { fill(buf, rest_length); int i = buf.getInt(); rest_length = 0; if (i == SSH_FX_EOF) { close(); return -1; } // throwStatusError(buf, i); throw new IOException("error"); } buf.rewind(); fill(buf.buffer, 0, 4); int length_of_data = buf.getInt(); rest_length -= 4; /* * Since sftp protocol version 6, "end-of-file" has been defined, byte SSH_FXP_DATA uint32 * request-id string data bool end-of-file [optional] but some sftpd server will send such * a field in the sftp protocol 3 ;-( */ int optional_data = rest_length - length_of_data; offset += length_of_data; int foo = length_of_data; if (foo > 0) { int bar = foo; if (bar > len) { bar = len; } int i = io_in.read(d, s, bar); if (i < 0) { return -1; } foo -= i; rest_length = foo; if (foo > 0) { if (rest_byte.length < foo) { rest_byte = new byte[foo]; } int _s = 0; int _len = foo; int j; while (_len > 0) { j = io_in.read(rest_byte, _s, _len); if (j <= 0) break; _s += j; _len -= j; } } if (optional_data > 0) { io_in.skip(optional_data); } if (length_of_data < rr.length) { // rq.cancel(header, buf); try { sendREAD(handle, rr.offset + length_of_data, (int) (rr.length - length_of_data), rq); } catch (Exception e) { throw new IOException("error"); } request_offset = rr.offset + rr.length; } if (request_max < rq.size()) { request_max++; } if (monitor != null) { if (!monitor.count(i)) { close(); return -1; } } return i; } return 0; // ?? } @Override public void close() throws IOException { if (closed) return; closed = true; if (monitor != null) monitor.end(); rq.cancel(header, buf); try { _sendCLOSE(handle, header); } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e.toString(), e); } } }; return in; } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public Vector ls(String path) throws SftpException { final Vector v = new Vector<>(); LsEntrySelector selector = new LsEntrySelector() { @Override public int select(LsEntry entry) { v.addElement(entry); return CONTINUE; } }; ls(path, selector); return v; } /** * List files specified by the remote path. Each files and directories will be passed * to LsEntrySelector#select(LsEntry) method, and if that method returns * LsEntrySelector#BREAK, the operation will be canceled immediately. * * @see ChannelSftp.LsEntrySelector * @since 0.1.47 */ public void ls(String path, LsEntrySelector selector) throws SftpException { // System.out.println("ls: "+path); try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); byte[] pattern = null; Vector v = new Vector<>(); int foo = path.lastIndexOf('/'); String dir = path.substring(0, ((foo == 0) ? 1 : foo)); String _pattern = path.substring(foo + 1); dir = Util.unquote(dir); // If pattern has included '*' or '?', we need to convert // to UTF-8 string before globbing. byte[][] _pattern_utf8 = new byte[1][]; boolean pattern_has_wildcard = isPattern(_pattern, _pattern_utf8); if (pattern_has_wildcard) { pattern = _pattern_utf8[0]; } else { String upath = Util.unquote(path); // SftpATTRS attr=_lstat(upath); SftpATTRS attr = _stat(upath); if (attr.isDir()) { pattern = null; dir = upath; } else { /* * // If we can generage longname by ourself, // we don't have to use openDIR. String * filename=Util.unquote(_pattern); String longname=... v.addElement(new LsEntry(filename, * longname, attr)); return v; */ if (fEncoding_is_utf8) { pattern = _pattern_utf8[0]; pattern = Util.unquote(pattern); } else { _pattern = Util.unquote(_pattern); pattern = Util.str2byte(_pattern, fEncoding); } } } sendOPENDIR(Util.str2byte(dir, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } int cancel = LsEntrySelector.CONTINUE; byte[] handle = buf.getString(); // handle while (cancel == LsEntrySelector.CONTINUE) { sendREADDIR(handle); header = header(buf, header); length = header.length; type = header.type; if (type != SSH_FXP_STATUS && type != SSH_FXP_NAME) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { fill(buf, length); int i = buf.getInt(); if (i == SSH_FX_EOF) break; throwStatusError(buf, i); } buf.rewind(); fill(buf.buffer, 0, 4); length -= 4; int count = buf.getInt(); byte[] str; int flags; buf.reset(); while (count > 0) { if (length > 0) { buf.shift(); int j = (buf.buffer.length > (buf.index + length)) ? length : (buf.buffer.length - buf.index); int i = fill(buf.buffer, buf.index, j); buf.index += i; length -= i; } byte[] filename = buf.getString(); byte[] longname = null; if (server_version <= 3) { longname = buf.getString(); } SftpATTRS attrs = SftpATTRS.getATTR(buf); if (cancel == LsEntrySelector.BREAK) { count--; continue; } boolean find = false; String f = null; if (pattern == null) { find = true; } else if (!pattern_has_wildcard) { find = Util.array_equals(pattern, filename); } else { byte[] _filename = filename; if (!fEncoding_is_utf8) { f = Util.byte2str(_filename, fEncoding); _filename = Util.str2byte(f, StandardCharsets.UTF_8); } find = Util.glob(pattern, _filename); } if (find) { if (f == null) { f = Util.byte2str(filename, fEncoding); } String l = null; if (longname == null) { // TODO: we need to generate long name from attrs // for the sftp protocol 4(and later). l = attrs.toString() + " " + f; } else { l = Util.byte2str(longname, fEncoding); } cancel = selector.select(new LsEntry(f, l, attrs)); } count--; } } _sendCLOSE(handle, header); /* * if(v.size()==1 && pattern_has_wildcard){ LsEntry le=(LsEntry)v.elementAt(0); * if(le.getAttrs().isDir()){ String f=le.getFilename(); if(isPattern(f)){ f=Util.quote(f); } * if(!dir.endsWith("/")){ dir+="/"; } v=null; return ls(dir+f); } } */ } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public String readlink(String path) throws SftpException { try { if (server_version < 3) { throw new SftpException(SSH_FX_OP_UNSUPPORTED, "The remote sshd is too old to support symlink operation."); } ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); path = isUnique(path); sendREADLINK(Util.str2byte(path, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_NAME) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_NAME) { int count = buf.getInt(); // count byte[] filename = null; for (int i = 0; i < count; i++) { filename = buf.getString(); if (server_version <= 3) { byte[] longname = buf.getString(); } SftpATTRS.getATTR(buf); } return Util.byte2str(filename, fEncoding); } int i = buf.getInt(); throwStatusError(buf, i); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } return null; } public void symlink(String oldpath, String newpath) throws SftpException { if (server_version < 3) { throw new SftpException(SSH_FX_OP_UNSUPPORTED, "The remote sshd is too old to support symlink operation."); } try { ((MyPipedInputStream) io_in).updateReadSide(); String _oldpath = remoteAbsolutePath(oldpath); newpath = remoteAbsolutePath(newpath); _oldpath = isUnique(_oldpath); if (oldpath.charAt(0) != '/') { // relative path String cwd = getCwd(); oldpath = _oldpath.substring(cwd.length() + (cwd.endsWith("/") ? 0 : 1)); } else { oldpath = _oldpath; } if (isPattern(newpath)) { throw new SftpException(SSH_FX_FAILURE, newpath); } newpath = Util.unquote(newpath); sendSYMLINK(Util.str2byte(oldpath, fEncoding), Util.str2byte(newpath, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i == SSH_FX_OK) return; throwStatusError(buf, i); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void hardlink(String oldpath, String newpath) throws SftpException { if (!extension_hardlink) { throw new SftpException(SSH_FX_OP_UNSUPPORTED, "hardlink@openssh.com is not supported"); } try { ((MyPipedInputStream) io_in).updateReadSide(); String _oldpath = remoteAbsolutePath(oldpath); newpath = remoteAbsolutePath(newpath); _oldpath = isUnique(_oldpath); if (oldpath.charAt(0) != '/') { // relative path String cwd = getCwd(); oldpath = _oldpath.substring(cwd.length() + (cwd.endsWith("/") ? 0 : 1)); } else { oldpath = _oldpath; } if (isPattern(newpath)) { throw new SftpException(SSH_FX_FAILURE, newpath); } newpath = Util.unquote(newpath); sendHARDLINK(Util.str2byte(oldpath, fEncoding), Util.str2byte(newpath, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i == SSH_FX_OK) return; throwStatusError(buf, i); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void rename(String oldpath, String newpath) throws SftpException { if (server_version < 2) { throw new SftpException(SSH_FX_OP_UNSUPPORTED, "The remote sshd is too old to support rename operation."); } try { ((MyPipedInputStream) io_in).updateReadSide(); oldpath = remoteAbsolutePath(oldpath); newpath = remoteAbsolutePath(newpath); oldpath = isUnique(oldpath); Vector v = glob_remote(newpath); int vsize = v.size(); if (vsize >= 2) { throw new SftpException(SSH_FX_FAILURE, v.toString()); } if (vsize == 1) { newpath = v.elementAt(0); } else { // vsize==0 if (isPattern(newpath)) throw new SftpException(SSH_FX_FAILURE, newpath); newpath = Util.unquote(newpath); } sendRENAME(Util.str2byte(oldpath, fEncoding), Util.str2byte(newpath, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i == SSH_FX_OK) return; throwStatusError(buf, i); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void rm(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); Header header = new Header(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); sendREMOVE(Util.str2byte(path, fEncoding)); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i != SSH_FX_OK) { throwStatusError(buf, i); } } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private boolean isRemoteDir(String path) { try { sendSTAT(Util.str2byte(path, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_ATTRS) { return false; } SftpATTRS attr = SftpATTRS.getATTR(buf); return attr.isDir(); } catch (Exception e) { } return false; } public void chgrp(int gid, String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); SftpATTRS attr = _stat(path); attr.setFLAGS(0); attr.setUIDGID(attr.uid, gid); _setStat(path, attr); } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void chown(int uid, String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); SftpATTRS attr = _stat(path); attr.setFLAGS(0); attr.setUIDGID(uid, attr.gid); _setStat(path, attr); } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void chmod(int permissions, String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); SftpATTRS attr = _stat(path); attr.setFLAGS(0); attr.setPERMISSIONS(permissions); _setStat(path, attr); } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void setMtime(String path, int mtime) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); SftpATTRS attr = _stat(path); attr.setFLAGS(0); attr.setACMODTIME(attr.getATime(), mtime); _setStat(path, attr); } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void rmdir(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); Header header = new Header(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); sendRMDIR(Util.str2byte(path, fEncoding)); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i != SSH_FX_OK) { throwStatusError(buf, i); } } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void mkdir(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); sendMKDIR(Util.str2byte(path, fEncoding), null); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i == SSH_FX_OK) return; throwStatusError(buf, i); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public SftpATTRS stat(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); path = isUnique(path); return _stat(path); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } // return null; } private SftpATTRS _stat(byte[] path) throws SftpException { try { sendSTAT(path); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_ATTRS) { if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } throw new SftpException(SSH_FX_FAILURE, ""); } SftpATTRS attr = SftpATTRS.getATTR(buf); return attr; } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } // return null; } private SftpATTRS _stat(String path) throws SftpException { return _stat(Util.str2byte(path, fEncoding)); } public SftpStatVFS statVFS(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); path = isUnique(path); return _statVFS(path); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } // return null; } private SftpStatVFS _statVFS(byte[] path) throws SftpException { if (!extension_statvfs) { throw new SftpException(SSH_FX_OP_UNSUPPORTED, "statvfs@openssh.com is not supported"); } try { sendSTATVFS(path); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != (SSH_FXP_EXTENDED_REPLY & 0xff)) { if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } throw new SftpException(SSH_FX_FAILURE, ""); } else { SftpStatVFS stat = SftpStatVFS.getStatVFS(buf); return stat; } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } // return null; } private SftpStatVFS _statVFS(String path) throws SftpException { return _statVFS(Util.str2byte(path, fEncoding)); } public SftpATTRS lstat(String path) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); path = isUnique(path); return _lstat(path); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private SftpATTRS _lstat(String path) throws SftpException { try { sendLSTAT(Util.str2byte(path, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_ATTRS) { if (type == SSH_FXP_STATUS) { int i = buf.getInt(); throwStatusError(buf, i); } throw new SftpException(SSH_FX_FAILURE, ""); } SftpATTRS attr = SftpATTRS.getATTR(buf); return attr; } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private byte[] _realpath(String path) throws SftpException, IOException, Exception { sendREALPATH(Util.str2byte(path, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_NAME) { throw new SftpException(SSH_FX_FAILURE, ""); } int i; if (type == SSH_FXP_STATUS) { i = buf.getInt(); throwStatusError(buf, i); } i = buf.getInt(); // count byte[] str = null; while (i-- > 0) { str = buf.getString(); // absolute path; if (server_version <= 3) { byte[] lname = buf.getString(); // long filename } SftpATTRS attr = SftpATTRS.getATTR(buf); // dummy attribute } return str; } public void setStat(String path, SftpATTRS attr) throws SftpException { try { ((MyPipedInputStream) io_in).updateReadSide(); path = remoteAbsolutePath(path); Vector v = glob_remote(path); int vsize = v.size(); for (int j = 0; j < vsize; j++) { path = v.elementAt(j); _setStat(path, attr); } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private void _setStat(String path, SftpATTRS attr) throws SftpException { try { sendSETSTAT(Util.str2byte(path, fEncoding), attr); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i != SSH_FX_OK) { throwStatusError(buf, i); } } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public String pwd() throws SftpException { return getCwd(); } public String lpwd() { return lcwd; } public String version() { return version; } public String getHome() throws SftpException { if (home == null) { try { ((MyPipedInputStream) io_in).updateReadSide(); byte[] _home = _realpath(""); home = Util.byte2str(_home, fEncoding); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } return home; } private String getCwd() throws SftpException { if (cwd == null) cwd = getHome(); return cwd; } private void setCwd(String cwd) { this.cwd = cwd; } private void read(byte[] buf, int s, int l) throws IOException, SftpException { int i = 0; while (l > 0) { i = io_in.read(buf, s, l); if (i <= 0) { throw new SftpException(SSH_FX_FAILURE, ""); } s += i; l -= i; } } private boolean checkStatus(int[] ackid, Header header) throws IOException, SftpException { header = header(buf, header); int length = header.length; int type = header.type; if (ackid != null) ackid[0] = header.rid; fill(buf, length); if (type != SSH_FXP_STATUS) { throw new SftpException(SSH_FX_FAILURE, ""); } int i = buf.getInt(); if (i != SSH_FX_OK) { throwStatusError(buf, i); } return true; } private boolean _sendCLOSE(byte[] handle, Header header) throws Exception { sendCLOSE(handle); return checkStatus(null, header); } private void sendINIT() throws Exception { packet.reset(); putHEAD(SSH_FXP_INIT, 5); buf.putInt(3); // version 3 getSession().write(packet, this, 5 + 4); } private void sendREALPATH(byte[] path) throws Exception { sendPacketPath(SSH_FXP_REALPATH, path); } private void sendSTAT(byte[] path) throws Exception { sendPacketPath(SSH_FXP_STAT, path); } private void sendSTATVFS(byte[] path) throws Exception { sendPacketPath((byte) 0, path, "statvfs@openssh.com"); } /* * private void sendFSTATVFS(byte[] handle) throws Exception{ sendPacketPath((byte)0, handle, * "fstatvfs@openssh.com"); } */ private void sendLSTAT(byte[] path) throws Exception { sendPacketPath(SSH_FXP_LSTAT, path); } private void sendFSTAT(byte[] handle) throws Exception { sendPacketPath(SSH_FXP_FSTAT, handle); } private void sendSETSTAT(byte[] path, SftpATTRS attr) throws Exception { packet.reset(); putHEAD(SSH_FXP_SETSTAT, 9 + path.length + attr.length()); buf.putInt(seq++); buf.putString(path); // path attr.dump(buf); getSession().write(packet, this, 9 + path.length + attr.length() + 4); } private void sendREMOVE(byte[] path) throws Exception { sendPacketPath(SSH_FXP_REMOVE, path); } private void sendMKDIR(byte[] path, SftpATTRS attr) throws Exception { packet.reset(); putHEAD(SSH_FXP_MKDIR, 9 + path.length + (attr != null ? attr.length() : 4)); buf.putInt(seq++); buf.putString(path); // path if (attr != null) attr.dump(buf); else buf.putInt(0); getSession().write(packet, this, 9 + path.length + (attr != null ? attr.length() : 4) + 4); } private void sendRMDIR(byte[] path) throws Exception { sendPacketPath(SSH_FXP_RMDIR, path); } private void sendSYMLINK(byte[] p1, byte[] p2) throws Exception { sendPacketPath(SSH_FXP_SYMLINK, p1, p2); } private void sendHARDLINK(byte[] p1, byte[] p2) throws Exception { sendPacketPath((byte) 0, p1, p2, "hardlink@openssh.com"); } private void sendREADLINK(byte[] path) throws Exception { sendPacketPath(SSH_FXP_READLINK, path); } private void sendOPENDIR(byte[] path) throws Exception { sendPacketPath(SSH_FXP_OPENDIR, path); } private void sendREADDIR(byte[] path) throws Exception { sendPacketPath(SSH_FXP_READDIR, path); } private void sendRENAME(byte[] p1, byte[] p2) throws Exception { sendPacketPath(SSH_FXP_RENAME, p1, p2, extension_posix_rename ? "posix-rename@openssh.com" : null); } private void sendCLOSE(byte[] path) throws Exception { sendPacketPath(SSH_FXP_CLOSE, path); } private void sendOPENR(byte[] path) throws Exception { sendOPEN(path, SSH_FXF_READ); } private void sendOPENW(byte[] path) throws Exception { sendOPEN(path, SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC); } private void sendOPENA(byte[] path) throws Exception { sendOPEN(path, SSH_FXF_WRITE | /* SSH_FXF_APPEND | */ SSH_FXF_CREAT); } private void sendOPEN(byte[] path, int mode) throws Exception { packet.reset(); putHEAD(SSH_FXP_OPEN, 17 + path.length); buf.putInt(seq++); buf.putString(path); buf.putInt(mode); buf.putInt(0); // attrs getSession().write(packet, this, 17 + path.length + 4); } private void sendPacketPath(byte fxp, byte[] path) throws Exception { sendPacketPath(fxp, path, (String) null); } private void sendPacketPath(byte fxp, byte[] path, String extension) throws Exception { packet.reset(); int len = 9 + path.length; if (extension == null) { putHEAD(fxp, len); buf.putInt(seq++); } else { len += (4 + extension.length()); putHEAD(SSH_FXP_EXTENDED, len); buf.putInt(seq++); buf.putString(Util.str2byte(extension)); } buf.putString(path); // path getSession().write(packet, this, len + 4); } private void sendPacketPath(byte fxp, byte[] p1, byte[] p2) throws Exception { sendPacketPath(fxp, p1, p2, null); } private void sendPacketPath(byte fxp, byte[] p1, byte[] p2, String extension) throws Exception { packet.reset(); int len = 13 + p1.length + p2.length; if (extension == null) { putHEAD(fxp, len); buf.putInt(seq++); } else { len += (4 + extension.length()); putHEAD(SSH_FXP_EXTENDED, len); buf.putInt(seq++); buf.putString(Util.str2byte(extension)); } buf.putString(p1); buf.putString(p2); getSession().write(packet, this, len + 4); } private int sendWRITE(byte[] handle, long offset, byte[] data, int start, int length) throws Exception { int _length = length; opacket.reset(); Session _session = getSession(); int buffer_margin = _session.getBufferMargin(); if (obuf.buffer.length < obuf.index + 13 + 21 + handle.length + length + buffer_margin) { _length = obuf.buffer.length - (obuf.index + 13 + 21 + handle.length + buffer_margin); // System.err.println("_length="+_length+" length="+length); } putHEAD(obuf, SSH_FXP_WRITE, 21 + handle.length + _length); // 14 obuf.putInt(seq++); // 4 obuf.putString(handle); // 4+handle.length obuf.putLong(offset); // 8 if (obuf.buffer != data) { obuf.putString(data, start, _length); // 4+_length } else { obuf.putInt(_length); obuf.skip(_length); } _session.write(opacket, this, 21 + handle.length + _length + 4); return _length; } private void sendREAD(byte[] handle, long offset, int length) throws Exception { sendREAD(handle, offset, length, null); } private void sendREAD(byte[] handle, long offset, int length, RequestQueue rrq) throws Exception { packet.reset(); putHEAD(SSH_FXP_READ, 21 + handle.length); buf.putInt(seq++); buf.putString(handle); buf.putLong(offset); buf.putInt(length); getSession().write(packet, this, 21 + handle.length + 4); if (rrq != null) { rrq.add(seq - 1, offset, length); } } private void putHEAD(Buffer buf, byte type, int length) throws Exception { buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(length + 4); buf.putInt(length); buf.putByte(type); } private void putHEAD(byte type, int length) throws Exception { putHEAD(buf, type, length); } private Vector glob_remote(String _path) throws Exception { Vector v = new Vector<>(); int i = 0; int foo = _path.lastIndexOf('/'); if (foo < 0) { // it is not absolute path. v.addElement(Util.unquote(_path)); return v; } String dir = _path.substring(0, ((foo == 0) ? 1 : foo)); String _pattern = _path.substring(foo + 1); dir = Util.unquote(dir); byte[] pattern = null; byte[][] _pattern_utf8 = new byte[1][]; boolean pattern_has_wildcard = isPattern(_pattern, _pattern_utf8); if (!pattern_has_wildcard) { if (!dir.equals("/")) dir += "/"; v.addElement(dir + Util.unquote(_pattern)); return v; } pattern = _pattern_utf8[0]; sendOPENDIR(Util.str2byte(dir, fEncoding)); Header header = new Header(); header = header(buf, header); int length = header.length; int type = header.type; fill(buf, length); if (type != SSH_FXP_STATUS && type != SSH_FXP_HANDLE) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { i = buf.getInt(); throwStatusError(buf, i); } byte[] handle = buf.getString(); // filename String pdir = null; // parent directory while (true) { sendREADDIR(handle); header = header(buf, header); length = header.length; type = header.type; if (type != SSH_FXP_STATUS && type != SSH_FXP_NAME) { throw new SftpException(SSH_FX_FAILURE, ""); } if (type == SSH_FXP_STATUS) { fill(buf, length); break; } buf.rewind(); fill(buf.buffer, 0, 4); length -= 4; int count = buf.getInt(); byte[] str; int flags; buf.reset(); while (count > 0) { if (length > 0) { buf.shift(); int j = (buf.buffer.length > (buf.index + length)) ? length : (buf.buffer.length - buf.index); i = io_in.read(buf.buffer, buf.index, j); if (i <= 0) break; buf.index += i; length -= i; } byte[] filename = buf.getString(); // System.err.println("filename: "+new String(filename)); if (server_version <= 3) { str = buf.getString(); // longname } SftpATTRS attrs = SftpATTRS.getATTR(buf); byte[] _filename = filename; String f = null; boolean found = false; if (!fEncoding_is_utf8) { f = Util.byte2str(filename, fEncoding); _filename = Util.str2byte(f, StandardCharsets.UTF_8); } found = Util.glob(pattern, _filename); if (found) { if (f == null) { f = Util.byte2str(filename, fEncoding); } if (pdir == null) { pdir = dir; if (!pdir.endsWith("/")) { pdir += "/"; } } v.addElement(pdir + f); } count--; } } if (_sendCLOSE(handle, header)) return v; return null; } private boolean isPattern(byte[] path) { int length = path.length; int i = 0; while (i < length) { if (path[i] == '*' || path[i] == '?') return true; if (path[i] == '\\' && (i + 1) < length) i++; i++; } return false; } private Vector glob_local(String _path) throws Exception { // System.err.println("glob_local: "+_path); Vector v = new Vector<>(); byte[] path = Util.str2byte(_path, StandardCharsets.UTF_8); int i = path.length - 1; while (i >= 0) { if (path[i] != '*' && path[i] != '?') { i--; continue; } if (!fs_is_bs && i > 0 && path[i - 1] == '\\') { i--; if (i > 0 && path[i - 1] == '\\') { i--; i--; continue; } } break; } if (i < 0) { v.addElement(fs_is_bs ? _path : Util.unquote(_path)); return v; } while (i >= 0) { if (path[i] == file_separatorc || (fs_is_bs && path[i] == '/')) { // On Windows, '/' is also // the separator. break; } i--; } if (i < 0) { v.addElement(fs_is_bs ? _path : Util.unquote(_path)); return v; } byte[] dir; if (i == 0) { dir = new byte[] {(byte) file_separatorc}; } else { dir = new byte[i]; System.arraycopy(path, 0, dir, 0, i); } byte[] pattern = new byte[path.length - i - 1]; System.arraycopy(path, i + 1, pattern, 0, pattern.length); // System.err.println("dir: "+new String(dir)+" pattern: "+new String(pattern)); try { String[] children = (new File(Util.byte2str(dir, StandardCharsets.UTF_8))).list(); String pdir = Util.byte2str(dir) + file_separator; for (int j = 0; j < children.length; j++) { // System.err.println("children: "+children[j]); if (Util.glob(pattern, Util.str2byte(children[j], StandardCharsets.UTF_8))) { v.addElement(pdir + children[j]); } } } catch (Exception e) { } return v; } private void throwStatusError(Buffer buf, int i) throws SftpException { if (server_version >= 3 && // WindRiver's sftp will send invalid buf.getLength() >= 4) { // SSH_FXP_STATUS packet. byte[] str = buf.getString(); // byte[] tag=buf.getString(); throw new SftpException(i, Util.byte2str(str, StandardCharsets.UTF_8)); } else { throw new SftpException(i, "Failure"); } } private static boolean isLocalAbsolutePath(String path) { return (new File(path)).isAbsolute(); } @Override public void disconnect() { super.disconnect(); } private boolean isPattern(String path, byte[][] utf8) { byte[] _path = Util.str2byte(path, StandardCharsets.UTF_8); if (utf8 != null) utf8[0] = _path; return isPattern(_path); } private boolean isPattern(String path) { return isPattern(path, null); } private void fill(Buffer buf, int len) throws IOException { buf.reset(); fill(buf.buffer, 0, len); buf.skip(len); } private int fill(byte[] buf, int s, int len) throws IOException { int i = 0; int foo = s; while (len > 0) { i = io_in.read(buf, s, len); if (i <= 0) { throw new IOException("inputstream is closed"); // return (s-foo)==0 ? i : s-foo; } s += i; len -= i; } return s - foo; } private void skip(long foo) throws IOException { while (foo > 0) { long bar = io_in.skip(foo); if (bar <= 0) break; foo -= bar; } } static class Header { int length; int type; int rid; } private Header header(Buffer buf, Header header) throws IOException { buf.rewind(); int i = fill(buf.buffer, 0, 9); header.length = buf.getInt() - 5; header.type = buf.getByte() & 0xff; header.rid = buf.getInt(); return header; } private String remoteAbsolutePath(String path) throws SftpException { if (path.charAt(0) == '/') return path; String cwd = getCwd(); // if(cwd.equals(getHome())) return path; if (cwd.endsWith("/")) return cwd + path; return cwd + "/" + path; } private String localAbsolutePath(String path) { if (isLocalAbsolutePath(path)) return path; if (lcwd.endsWith(file_separator)) return lcwd + path; return lcwd + file_separator + path; } /** * This method will check if the given string can be expanded to the unique string. If it can be * expanded to mutiple files, SftpException will be thrown. * * @return the returned string is unquoted. */ private String isUnique(String path) throws SftpException, Exception { Vector v = glob_remote(path); if (v.size() != 1) { throw new SftpException(SSH_FX_FAILURE, path + " is not unique: " + v.toString()); } return v.elementAt(0); } public int getServerVersion() throws SftpException { if (!isConnected()) { throw new SftpException(SSH_FX_FAILURE, "The channel is not connected."); } return server_version; } @Deprecated public void setFilenameEncoding(String encoding) throws SftpException { try { setFilenameEncoding(Charset.forName(encoding)); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void setFilenameEncoding(Charset encoding) { fEncoding = encoding; fEncoding_is_utf8 = fEncoding.equals(StandardCharsets.UTF_8); } public String getExtension(String key) { if (extensions == null) return null; return extensions.get(key); } public String realpath(String path) throws SftpException { try { byte[] _path = _realpath(remoteAbsolutePath(path)); return Util.byte2str(_path, fEncoding); } catch (Exception e) { if (e instanceof SftpException) throw (SftpException) e; throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public static class LsEntry implements Comparable { private String filename; private String longname; private SftpATTRS attrs; LsEntry(String filename, String longname, SftpATTRS attrs) { setFilename(filename); setLongname(longname); setAttrs(attrs); } public String getFilename() { return filename; }; void setFilename(String filename) { this.filename = filename; }; public String getLongname() { return longname; }; void setLongname(String longname) { this.longname = longname; }; public SftpATTRS getAttrs() { return attrs; }; void setAttrs(SftpATTRS attrs) { this.attrs = attrs; }; @Override public String toString() { return longname; } @Override public int compareTo(LsEntry o) { return filename.compareTo(o.getFilename()); } } /** * This interface will be passed as an argument for ls method. * * @see ChannelSftp.LsEntry * @see #ls(String, ChannelSftp.LsEntrySelector) * @since 0.1.47 */ public interface LsEntrySelector { public final int CONTINUE = 0; public final int BREAK = 1; /** * The select method will be invoked in ls method for each file entry. * If this method returns BREAK, ls will be canceled. * * @param entry one of entry from ls * @return if BREAK is returned, the 'ls' operation will be canceled. */ public int select(LsEntry entry); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelShell.java000066400000000000000000000045011465436372100253220ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class ChannelShell extends ChannelSession { ChannelShell() { super(); pty = true; } @Override public void start() throws JSchException { Session _session = getSession(); try { sendRequests(); Request request = new RequestShell(); request.request(_session, this); } catch (Exception e) { if (e instanceof JSchException) throw (JSchException) e; throw new JSchException("ChannelShell", e); } if (io.in != null) { thread = new Thread(this::run); thread.setName("Shell for " + _session.host); if (_session.daemon_thread) { thread.setDaemon(_session.daemon_thread); } thread.start(); } } @Override void init() throws JSchException { io.setInputStream(getSession().in); io.setOutputStream(getSession().out); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelSubsystem.java000066400000000000000000000057421465436372100262610ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class ChannelSubsystem extends ChannelSession { boolean want_reply = true; String subsystem = ""; public void setWantReply(boolean foo) { want_reply = foo; } public void setSubsystem(String foo) { subsystem = foo; } @Override public void start() throws JSchException { Session _session = getSession(); try { Request request; if (xforwading) { request = new RequestX11(); request.request(_session, this); } if (pty) { request = new RequestPtyReq(); request.request(_session, this); } request = new RequestSubsystem(); ((RequestSubsystem) request).request(_session, this, subsystem, want_reply); } catch (Exception e) { if (e instanceof JSchException) { throw (JSchException) e; } throw new JSchException("ChannelSubsystem", e); } if (io.in != null) { thread = new Thread(this::run); thread.setName("Subsystem for " + _session.host); if (_session.daemon_thread) { thread.setDaemon(_session.daemon_thread); } thread.start(); } } @Override void init() throws JSchException { io.setInputStream(getSession().in); io.setOutputStream(getSession().out); } public void setErrStream(OutputStream out) { setExtOutputStream(out); } public InputStream getErrStream() throws IOException { return getExtInputStream(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ChannelX11.java000066400000000000000000000174201465436372100246300ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.net.Socket; import java.util.Hashtable; class ChannelX11 extends Channel { private static final int LOCAL_WINDOW_SIZE_MAX = 0x20000; private static final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; private static final int TIMEOUT = 10 * 1000; private static String host = "127.0.0.1"; private static int port = 6000; private boolean init = true; static byte[] cookie = null; private static byte[] cookie_hex = null; private static Hashtable faked_cookie_pool = new Hashtable<>(); private static Hashtable faked_cookie_hex_pool = new Hashtable<>(); private static byte[] table = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66}; private Socket socket = null; static int revtable(byte foo) { for (int i = 0; i < table.length; i++) { if (table[i] == foo) return i; } return 0; } static void setCookie(String foo) { cookie_hex = Util.str2byte(foo); cookie = new byte[16]; for (int i = 0; i < 16; i++) { cookie[i] = (byte) (((revtable(cookie_hex[i * 2]) << 4) & 0xf0) | ((revtable(cookie_hex[i * 2 + 1])) & 0xf)); } } static void setHost(String foo) { host = foo; } static void setPort(int foo) { port = foo; } static byte[] getFakedCookie(Session session) { synchronized (faked_cookie_hex_pool) { byte[] foo = faked_cookie_hex_pool.get(session); if (foo == null) { Random random = Session.random; foo = new byte[16]; synchronized (random) { random.fill(foo, 0, 16); } /* * System.err.print("faked_cookie: "); for(int i=0; i>> 4) & 0xf]; bar[2 * i + 1] = table[(foo[i]) & 0xf]; } faked_cookie_hex_pool.put(session, bar); foo = bar; } return foo; } } static void removeFakedCookie(Session session) { synchronized (faked_cookie_hex_pool) { faked_cookie_hex_pool.remove(session); faked_cookie_pool.remove(session); } } ChannelX11() { super(); lwsize_max = LOCAL_WINDOW_SIZE_MAX; lwsize = LOCAL_WINDOW_SIZE_MAX; lmpsize = LOCAL_MAXIMUM_PACKET_SIZE; type = Util.str2byte("x11"); connected = true; /* * try{ socket=Util.createSocket(host, port, TIMEOUT); socket.setTcpNoDelay(true); io=new IO(); * io.setInputStream(socket.getInputStream()); io.setOutputStream(socket.getOutputStream()); } * catch(Exception e){ //System.err.println(e); } */ } @Override void run() { try { socket = Util.createSocket(host, port, TIMEOUT); socket.setTcpNoDelay(true); io = new IO(); io.setInputStream(socket.getInputStream()); io.setOutputStream(socket.getOutputStream()); sendOpenConfirmation(); } catch (Exception e) { sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED); close = true; disconnect(); return; } thread = Thread.currentThread(); Buffer buf = new Buffer(rmpsize); Packet packet = new Packet(buf); int i = 0; try { Session _session = getSession(); while (thread != null && io != null && io.in != null) { i = io.in.read(buf.buffer, 14, buf.buffer.length - 14 - _session.getBufferMargin()); if (i <= 0) { eof(); break; } if (close) break; packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(i); buf.skip(i); _session.write(packet, this, i); } } catch (Exception e) { // System.err.println(e); } disconnect(); } private byte[] cache = new byte[0]; private byte[] addCache(byte[] foo, int s, int l) { byte[] bar = new byte[cache.length + l]; System.arraycopy(foo, s, bar, cache.length, l); if (cache.length > 0) System.arraycopy(cache, 0, bar, 0, cache.length); cache = bar; return cache; } @Override void write(byte[] foo, int s, int l) throws IOException { // if(eof_local)return; if (init) { Session _session = null; try { _session = getSession(); } catch (JSchException e) { throw new IOException(e.toString(), e); } foo = addCache(foo, s, l); s = 0; l = foo.length; if (l < 9) return; int plen = (foo[s + 6] & 0xff) * 256 + (foo[s + 7] & 0xff); int dlen = (foo[s + 8] & 0xff) * 256 + (foo[s + 9] & 0xff); if ((foo[s] & 0xff) == 0x42) { } else if ((foo[s] & 0xff) == 0x6c) { plen = ((plen >>> 8) & 0xff) | ((plen << 8) & 0xff00); dlen = ((dlen >>> 8) & 0xff) | ((dlen << 8) & 0xff00); } else { // ?? } if (l < 12 + plen + ((-plen) & 3) + dlen) return; byte[] bar = new byte[dlen]; System.arraycopy(foo, s + 12 + plen + ((-plen) & 3), bar, 0, dlen); byte[] faked_cookie = null; synchronized (faked_cookie_pool) { faked_cookie = faked_cookie_pool.get(_session); } /* * System.err.print("faked_cookie: "); for(int i=0; i c = Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class); sha = c.getDeclaredConstructor().newInstance(); sha.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } buf = new Buffer(); packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_KEX_ECDH_INIT); try { Class c = Class.forName(session.getConfig("ecdh-sha2-nistp")).asSubclass(ECDH.class); ecdh = c.getDeclaredConstructor().newInstance(); ecdh.init(key_size); Q_C = ecdh.getQ(); buf.putString(Q_C); } catch (Exception e) { throw new JSchException(e.toString(), e); } if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-( return; } session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent"); session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY"); } state = SSH_MSG_KEX_ECDH_REPLY; } @Override public boolean next(Buffer _buf) throws Exception { int i, j; switch (state) { case SSH_MSG_KEX_ECDH_REPLY: // The server responds with: // byte SSH_MSG_KEX_ECDH_REPLY // string K_S, server's public host key // string Q_S, server's ephemeral public key octet string // string the signature on the exchange hash j = _buf.getInt(); j = _buf.getByte(); j = _buf.getByte(); if (j != SSH_MSG_KEX_ECDH_REPLY) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_ECDH_REPLY " + j); } return false; } K_S = _buf.getString(); byte[] Q_S = _buf.getString(); byte[][] r_s = KeyPairECDSA.fromPoint(Q_S); // RFC 5656, // 4. ECDH Key Exchange // All elliptic curve public keys MUST be validated after they are // received. An example of a validation algorithm can be found in // Section 3.2.2 of [SEC1]. If a key fails validation, // the key exchange MUST fail. if (!ecdh.validate(r_s[0], r_s[1])) { return false; } K = encodeAsMPInt(normalize(ecdh.getSecret(r_s[0], r_s[1]))); byte[] sig_of_H = _buf.getString(); // The hash H is computed as the HASH hash of the concatenation of the // following: // string V_C, client's identification string (CR and LF excluded) // string V_S, server's identification string (CR and LF excluded) // string I_C, payload of the client's SSH_MSG_KEXINIT // string I_S, payload of the server's SSH_MSG_KEXINIT // string K_S, server's public host key // string Q_C, client's ephemeral public key octet string // string Q_S, server's ephemeral public key octet string // mpint K, shared secret // This value is called the exchange hash, and it is used to authenti- // cate the key exchange. buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putString(Q_C); buf.putString(Q_S); byte[] foo = new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.length); sha.update(K, 0, K.length); H = sha.digest(); i = 0; j = 0; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); String alg = Util.byte2str(K_S, i, j); i += j; boolean result = verify(alg, K_S, i, sig_of_H); state = STATE_END; return result; } return false; } @Override public int getState() { return state; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG1.java000066400000000000000000000067271465436372100234610ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG1 extends DHGN { static final byte[] g = {2}; static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE6, (byte) 0x53, (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; @Override byte[] G() { return g; } @Override byte[] P() { return p; } @Override String sha_name() { return "sha-1"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG14.java000066400000000000000000000031111465436372100235250ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG14 extends DHG14N { @Override String sha_name() { return "sha-1"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG14224.java000066400000000000000000000031161465436372100237620ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG14224 extends DHG14N { @Override String sha_name() { return "sha-224"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG14256.java000066400000000000000000000031161465436372100237670ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG14256 extends DHG14N { @Override String sha_name() { return "sha-256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG14N.java000066400000000000000000000122231465436372100236470ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class DHG14N extends DHGN { static final byte[] g = {2}; static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F, (byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD, (byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03, (byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2, (byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAC, (byte) 0xAA, (byte) 0x68, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; @Override byte[] G() { return g; } @Override byte[] P() { return p; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG15.java000066400000000000000000000031131465436372100235300ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG15 extends DHG15N { @Override String sha_name() { return "sha-512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG15256.java000066400000000000000000000031161465436372100237700ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG15256 extends DHG15N { @Override String sha_name() { return "sha-256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG15384.java000066400000000000000000000031161465436372100237720ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG15384 extends DHG15N { @Override String sha_name() { return "sha-384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG15N.java000066400000000000000000000156051465436372100236570ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class DHG15N extends DHGN { static final byte[] g = {2}; static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F, (byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD, (byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03, (byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2, (byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD, (byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33, (byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA, (byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB, (byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D, (byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85, (byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE, (byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C, (byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE, (byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B, (byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08, (byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8, (byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17, (byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57, (byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88, (byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2, (byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43, (byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E, (byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x3A, (byte) 0xD2, (byte) 0xCA, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; @Override byte[] G() { return g; } @Override byte[] P() { return p; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG16.java000066400000000000000000000031131465436372100235310ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG16 extends DHG16N { @Override String sha_name() { return "sha-512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG16384.java000066400000000000000000000031161465436372100237730ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG16384 extends DHG16N { @Override String sha_name() { return "sha-384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG16N.java000066400000000000000000000211611465436372100236520ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class DHG16N extends DHGN { static final byte[] g = {2}; static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F, (byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD, (byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03, (byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2, (byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD, (byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33, (byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA, (byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB, (byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D, (byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85, (byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE, (byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C, (byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE, (byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B, (byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08, (byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8, (byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17, (byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57, (byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88, (byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2, (byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43, (byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E, (byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x21, (byte) 0x08, (byte) 0x01, (byte) 0x1A, (byte) 0x72, (byte) 0x3C, (byte) 0x12, (byte) 0xA7, (byte) 0x87, (byte) 0xE6, (byte) 0xD7, (byte) 0x88, (byte) 0x71, (byte) 0x9A, (byte) 0x10, (byte) 0xBD, (byte) 0xBA, (byte) 0x5B, (byte) 0x26, (byte) 0x99, (byte) 0xC3, (byte) 0x27, (byte) 0x18, (byte) 0x6A, (byte) 0xF4, (byte) 0xE2, (byte) 0x3C, (byte) 0x1A, (byte) 0x94, (byte) 0x68, (byte) 0x34, (byte) 0xB6, (byte) 0x15, (byte) 0x0B, (byte) 0xDA, (byte) 0x25, (byte) 0x83, (byte) 0xE9, (byte) 0xCA, (byte) 0x2A, (byte) 0xD4, (byte) 0x4C, (byte) 0xE8, (byte) 0xDB, (byte) 0xBB, (byte) 0xC2, (byte) 0xDB, (byte) 0x04, (byte) 0xDE, (byte) 0x8E, (byte) 0xF9, (byte) 0x2E, (byte) 0x8E, (byte) 0xFC, (byte) 0x14, (byte) 0x1F, (byte) 0xBE, (byte) 0xCA, (byte) 0xA6, (byte) 0x28, (byte) 0x7C, (byte) 0x59, (byte) 0x47, (byte) 0x4E, (byte) 0x6B, (byte) 0xC0, (byte) 0x5D, (byte) 0x99, (byte) 0xB2, (byte) 0x96, (byte) 0x4F, (byte) 0xA0, (byte) 0x90, (byte) 0xC3, (byte) 0xA2, (byte) 0x23, (byte) 0x3B, (byte) 0xA1, (byte) 0x86, (byte) 0x51, (byte) 0x5B, (byte) 0xE7, (byte) 0xED, (byte) 0x1F, (byte) 0x61, (byte) 0x29, (byte) 0x70, (byte) 0xCE, (byte) 0xE2, (byte) 0xD7, (byte) 0xAF, (byte) 0xB8, (byte) 0x1B, (byte) 0xDD, (byte) 0x76, (byte) 0x21, (byte) 0x70, (byte) 0x48, (byte) 0x1C, (byte) 0xD0, (byte) 0x06, (byte) 0x91, (byte) 0x27, (byte) 0xD5, (byte) 0xB0, (byte) 0x5A, (byte) 0xA9, (byte) 0x93, (byte) 0xB4, (byte) 0xEA, (byte) 0x98, (byte) 0x8D, (byte) 0x8F, (byte) 0xDD, (byte) 0xC1, (byte) 0x86, (byte) 0xFF, (byte) 0xB7, (byte) 0xDC, (byte) 0x90, (byte) 0xA6, (byte) 0xC0, (byte) 0x8F, (byte) 0x4D, (byte) 0xF4, (byte) 0x35, (byte) 0xC9, (byte) 0x34, (byte) 0x06, (byte) 0x31, (byte) 0x99, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; @Override byte[] G() { return g; } @Override byte[] P() { return p; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG17.java000066400000000000000000000310671465436372100235430ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG17 extends DHGN { static final byte[] g = {2}; static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F, (byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD, (byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03, (byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2, (byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD, (byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33, (byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA, (byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB, (byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D, (byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85, (byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE, (byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C, (byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE, (byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B, (byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08, (byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8, (byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17, (byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57, (byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88, (byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2, (byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43, (byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E, (byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x21, (byte) 0x08, (byte) 0x01, (byte) 0x1A, (byte) 0x72, (byte) 0x3C, (byte) 0x12, (byte) 0xA7, (byte) 0x87, (byte) 0xE6, (byte) 0xD7, (byte) 0x88, (byte) 0x71, (byte) 0x9A, (byte) 0x10, (byte) 0xBD, (byte) 0xBA, (byte) 0x5B, (byte) 0x26, (byte) 0x99, (byte) 0xC3, (byte) 0x27, (byte) 0x18, (byte) 0x6A, (byte) 0xF4, (byte) 0xE2, (byte) 0x3C, (byte) 0x1A, (byte) 0x94, (byte) 0x68, (byte) 0x34, (byte) 0xB6, (byte) 0x15, (byte) 0x0B, (byte) 0xDA, (byte) 0x25, (byte) 0x83, (byte) 0xE9, (byte) 0xCA, (byte) 0x2A, (byte) 0xD4, (byte) 0x4C, (byte) 0xE8, (byte) 0xDB, (byte) 0xBB, (byte) 0xC2, (byte) 0xDB, (byte) 0x04, (byte) 0xDE, (byte) 0x8E, (byte) 0xF9, (byte) 0x2E, (byte) 0x8E, (byte) 0xFC, (byte) 0x14, (byte) 0x1F, (byte) 0xBE, (byte) 0xCA, (byte) 0xA6, (byte) 0x28, (byte) 0x7C, (byte) 0x59, (byte) 0x47, (byte) 0x4E, (byte) 0x6B, (byte) 0xC0, (byte) 0x5D, (byte) 0x99, (byte) 0xB2, (byte) 0x96, (byte) 0x4F, (byte) 0xA0, (byte) 0x90, (byte) 0xC3, (byte) 0xA2, (byte) 0x23, (byte) 0x3B, (byte) 0xA1, (byte) 0x86, (byte) 0x51, (byte) 0x5B, (byte) 0xE7, (byte) 0xED, (byte) 0x1F, (byte) 0x61, (byte) 0x29, (byte) 0x70, (byte) 0xCE, (byte) 0xE2, (byte) 0xD7, (byte) 0xAF, (byte) 0xB8, (byte) 0x1B, (byte) 0xDD, (byte) 0x76, (byte) 0x21, (byte) 0x70, (byte) 0x48, (byte) 0x1C, (byte) 0xD0, (byte) 0x06, (byte) 0x91, (byte) 0x27, (byte) 0xD5, (byte) 0xB0, (byte) 0x5A, (byte) 0xA9, (byte) 0x93, (byte) 0xB4, (byte) 0xEA, (byte) 0x98, (byte) 0x8D, (byte) 0x8F, (byte) 0xDD, (byte) 0xC1, (byte) 0x86, (byte) 0xFF, (byte) 0xB7, (byte) 0xDC, (byte) 0x90, (byte) 0xA6, (byte) 0xC0, (byte) 0x8F, (byte) 0x4D, (byte) 0xF4, (byte) 0x35, (byte) 0xC9, (byte) 0x34, (byte) 0x02, (byte) 0x84, (byte) 0x92, (byte) 0x36, (byte) 0xC3, (byte) 0xFA, (byte) 0xB4, (byte) 0xD2, (byte) 0x7C, (byte) 0x70, (byte) 0x26, (byte) 0xC1, (byte) 0xD4, (byte) 0xDC, (byte) 0xB2, (byte) 0x60, (byte) 0x26, (byte) 0x46, (byte) 0xDE, (byte) 0xC9, (byte) 0x75, (byte) 0x1E, (byte) 0x76, (byte) 0x3D, (byte) 0xBA, (byte) 0x37, (byte) 0xBD, (byte) 0xF8, (byte) 0xFF, (byte) 0x94, (byte) 0x06, (byte) 0xAD, (byte) 0x9E, (byte) 0x53, (byte) 0x0E, (byte) 0xE5, (byte) 0xDB, (byte) 0x38, (byte) 0x2F, (byte) 0x41, (byte) 0x30, (byte) 0x01, (byte) 0xAE, (byte) 0xB0, (byte) 0x6A, (byte) 0x53, (byte) 0xED, (byte) 0x90, (byte) 0x27, (byte) 0xD8, (byte) 0x31, (byte) 0x17, (byte) 0x97, (byte) 0x27, (byte) 0xB0, (byte) 0x86, (byte) 0x5A, (byte) 0x89, (byte) 0x18, (byte) 0xDA, (byte) 0x3E, (byte) 0xDB, (byte) 0xEB, (byte) 0xCF, (byte) 0x9B, (byte) 0x14, (byte) 0xED, (byte) 0x44, (byte) 0xCE, (byte) 0x6C, (byte) 0xBA, (byte) 0xCE, (byte) 0xD4, (byte) 0xBB, (byte) 0x1B, (byte) 0xDB, (byte) 0x7F, (byte) 0x14, (byte) 0x47, (byte) 0xE6, (byte) 0xCC, (byte) 0x25, (byte) 0x4B, (byte) 0x33, (byte) 0x20, (byte) 0x51, (byte) 0x51, (byte) 0x2B, (byte) 0xD7, (byte) 0xAF, (byte) 0x42, (byte) 0x6F, (byte) 0xB8, (byte) 0xF4, (byte) 0x01, (byte) 0x37, (byte) 0x8C, (byte) 0xD2, (byte) 0xBF, (byte) 0x59, (byte) 0x83, (byte) 0xCA, (byte) 0x01, (byte) 0xC6, (byte) 0x4B, (byte) 0x92, (byte) 0xEC, (byte) 0xF0, (byte) 0x32, (byte) 0xEA, (byte) 0x15, (byte) 0xD1, (byte) 0x72, (byte) 0x1D, (byte) 0x03, (byte) 0xF4, (byte) 0x82, (byte) 0xD7, (byte) 0xCE, (byte) 0x6E, (byte) 0x74, (byte) 0xFE, (byte) 0xF6, (byte) 0xD5, (byte) 0x5E, (byte) 0x70, (byte) 0x2F, (byte) 0x46, (byte) 0x98, (byte) 0x0C, (byte) 0x82, (byte) 0xB5, (byte) 0xA8, (byte) 0x40, (byte) 0x31, (byte) 0x90, (byte) 0x0B, (byte) 0x1C, (byte) 0x9E, (byte) 0x59, (byte) 0xE7, (byte) 0xC9, (byte) 0x7F, (byte) 0xBE, (byte) 0xC7, (byte) 0xE8, (byte) 0xF3, (byte) 0x23, (byte) 0xA9, (byte) 0x7A, (byte) 0x7E, (byte) 0x36, (byte) 0xCC, (byte) 0x88, (byte) 0xBE, (byte) 0x0F, (byte) 0x1D, (byte) 0x45, (byte) 0xB7, (byte) 0xFF, (byte) 0x58, (byte) 0x5A, (byte) 0xC5, (byte) 0x4B, (byte) 0xD4, (byte) 0x07, (byte) 0xB2, (byte) 0x2B, (byte) 0x41, (byte) 0x54, (byte) 0xAA, (byte) 0xCC, (byte) 0x8F, (byte) 0x6D, (byte) 0x7E, (byte) 0xBF, (byte) 0x48, (byte) 0xE1, (byte) 0xD8, (byte) 0x14, (byte) 0xCC, (byte) 0x5E, (byte) 0xD2, (byte) 0x0F, (byte) 0x80, (byte) 0x37, (byte) 0xE0, (byte) 0xA7, (byte) 0x97, (byte) 0x15, (byte) 0xEE, (byte) 0xF2, (byte) 0x9B, (byte) 0xE3, (byte) 0x28, (byte) 0x06, (byte) 0xA1, (byte) 0xD5, (byte) 0x8B, (byte) 0xB7, (byte) 0xC5, (byte) 0xDA, (byte) 0x76, (byte) 0xF5, (byte) 0x50, (byte) 0xAA, (byte) 0x3D, (byte) 0x8A, (byte) 0x1F, (byte) 0xBF, (byte) 0xF0, (byte) 0xEB, (byte) 0x19, (byte) 0xCC, (byte) 0xB1, (byte) 0xA3, (byte) 0x13, (byte) 0xD5, (byte) 0x5C, (byte) 0xDA, (byte) 0x56, (byte) 0xC9, (byte) 0xEC, (byte) 0x2E, (byte) 0xF2, (byte) 0x96, (byte) 0x32, (byte) 0x38, (byte) 0x7F, (byte) 0xE8, (byte) 0xD7, (byte) 0x6E, (byte) 0x3C, (byte) 0x04, (byte) 0x68, (byte) 0x04, (byte) 0x3E, (byte) 0x8F, (byte) 0x66, (byte) 0x3F, (byte) 0x48, (byte) 0x60, (byte) 0xEE, (byte) 0x12, (byte) 0xBF, (byte) 0x2D, (byte) 0x5B, (byte) 0x0B, (byte) 0x74, (byte) 0x74, (byte) 0xD6, (byte) 0xE6, (byte) 0x94, (byte) 0xF9, (byte) 0x1E, (byte) 0x6D, (byte) 0xCC, (byte) 0x40, (byte) 0x24, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,}; @Override byte[] G() { return g; } @Override byte[] P() { return p; } @Override String sha_name() { return "sha-512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHG18.java000066400000000000000000000371321465436372100235430ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHG18 extends DHGN { static final byte[] g = {2}; static final byte[] p = {(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B, (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E, (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4, (byte) 0x5B, (byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF, (byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3, (byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF, (byte) 0x5F, (byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD, (byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52, (byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96, (byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC, (byte) 0x98, (byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21, (byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE, (byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86, (byte) 0x03, (byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2, (byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52, (byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17, (byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95, (byte) 0x6A, (byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05, (byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAA, (byte) 0xC4, (byte) 0x2D, (byte) 0xAD, (byte) 0x33, (byte) 0x17, (byte) 0x0D, (byte) 0x04, (byte) 0x50, (byte) 0x7A, (byte) 0x33, (byte) 0xA8, (byte) 0x55, (byte) 0x21, (byte) 0xAB, (byte) 0xDF, (byte) 0x1C, (byte) 0xBA, (byte) 0x64, (byte) 0xEC, (byte) 0xFB, (byte) 0x85, (byte) 0x04, (byte) 0x58, (byte) 0xDB, (byte) 0xEF, (byte) 0x0A, (byte) 0x8A, (byte) 0xEA, (byte) 0x71, (byte) 0x57, (byte) 0x5D, (byte) 0x06, (byte) 0x0C, (byte) 0x7D, (byte) 0xB3, (byte) 0x97, (byte) 0x0F, (byte) 0x85, (byte) 0xA6, (byte) 0xE1, (byte) 0xE4, (byte) 0xC7, (byte) 0xAB, (byte) 0xF5, (byte) 0xAE, (byte) 0x8C, (byte) 0xDB, (byte) 0x09, (byte) 0x33, (byte) 0xD7, (byte) 0x1E, (byte) 0x8C, (byte) 0x94, (byte) 0xE0, (byte) 0x4A, (byte) 0x25, (byte) 0x61, (byte) 0x9D, (byte) 0xCE, (byte) 0xE3, (byte) 0xD2, (byte) 0x26, (byte) 0x1A, (byte) 0xD2, (byte) 0xEE, (byte) 0x6B, (byte) 0xF1, (byte) 0x2F, (byte) 0xFA, (byte) 0x06, (byte) 0xD9, (byte) 0x8A, (byte) 0x08, (byte) 0x64, (byte) 0xD8, (byte) 0x76, (byte) 0x02, (byte) 0x73, (byte) 0x3E, (byte) 0xC8, (byte) 0x6A, (byte) 0x64, (byte) 0x52, (byte) 0x1F, (byte) 0x2B, (byte) 0x18, (byte) 0x17, (byte) 0x7B, (byte) 0x20, (byte) 0x0C, (byte) 0xBB, (byte) 0xE1, (byte) 0x17, (byte) 0x57, (byte) 0x7A, (byte) 0x61, (byte) 0x5D, (byte) 0x6C, (byte) 0x77, (byte) 0x09, (byte) 0x88, (byte) 0xC0, (byte) 0xBA, (byte) 0xD9, (byte) 0x46, (byte) 0xE2, (byte) 0x08, (byte) 0xE2, (byte) 0x4F, (byte) 0xA0, (byte) 0x74, (byte) 0xE5, (byte) 0xAB, (byte) 0x31, (byte) 0x43, (byte) 0xDB, (byte) 0x5B, (byte) 0xFC, (byte) 0xE0, (byte) 0xFD, (byte) 0x10, (byte) 0x8E, (byte) 0x4B, (byte) 0x82, (byte) 0xD1, (byte) 0x20, (byte) 0xA9, (byte) 0x21, (byte) 0x08, (byte) 0x01, (byte) 0x1A, (byte) 0x72, (byte) 0x3C, (byte) 0x12, (byte) 0xA7, (byte) 0x87, (byte) 0xE6, (byte) 0xD7, (byte) 0x88, (byte) 0x71, (byte) 0x9A, (byte) 0x10, (byte) 0xBD, (byte) 0xBA, (byte) 0x5B, (byte) 0x26, (byte) 0x99, (byte) 0xC3, (byte) 0x27, (byte) 0x18, (byte) 0x6A, (byte) 0xF4, (byte) 0xE2, (byte) 0x3C, (byte) 0x1A, (byte) 0x94, (byte) 0x68, (byte) 0x34, (byte) 0xB6, (byte) 0x15, (byte) 0x0B, (byte) 0xDA, (byte) 0x25, (byte) 0x83, (byte) 0xE9, (byte) 0xCA, (byte) 0x2A, (byte) 0xD4, (byte) 0x4C, (byte) 0xE8, (byte) 0xDB, (byte) 0xBB, (byte) 0xC2, (byte) 0xDB, (byte) 0x04, (byte) 0xDE, (byte) 0x8E, (byte) 0xF9, (byte) 0x2E, (byte) 0x8E, (byte) 0xFC, (byte) 0x14, (byte) 0x1F, (byte) 0xBE, (byte) 0xCA, (byte) 0xA6, (byte) 0x28, (byte) 0x7C, (byte) 0x59, (byte) 0x47, (byte) 0x4E, (byte) 0x6B, (byte) 0xC0, (byte) 0x5D, (byte) 0x99, (byte) 0xB2, (byte) 0x96, (byte) 0x4F, (byte) 0xA0, (byte) 0x90, (byte) 0xC3, (byte) 0xA2, (byte) 0x23, (byte) 0x3B, (byte) 0xA1, (byte) 0x86, (byte) 0x51, (byte) 0x5B, (byte) 0xE7, (byte) 0xED, (byte) 0x1F, (byte) 0x61, (byte) 0x29, (byte) 0x70, (byte) 0xCE, (byte) 0xE2, (byte) 0xD7, (byte) 0xAF, (byte) 0xB8, (byte) 0x1B, (byte) 0xDD, (byte) 0x76, (byte) 0x21, (byte) 0x70, (byte) 0x48, (byte) 0x1C, (byte) 0xD0, (byte) 0x06, (byte) 0x91, (byte) 0x27, (byte) 0xD5, (byte) 0xB0, (byte) 0x5A, (byte) 0xA9, (byte) 0x93, (byte) 0xB4, (byte) 0xEA, (byte) 0x98, (byte) 0x8D, (byte) 0x8F, (byte) 0xDD, (byte) 0xC1, (byte) 0x86, (byte) 0xFF, (byte) 0xB7, (byte) 0xDC, (byte) 0x90, (byte) 0xA6, (byte) 0xC0, (byte) 0x8F, (byte) 0x4D, (byte) 0xF4, (byte) 0x35, (byte) 0xC9, (byte) 0x34, (byte) 0x02, (byte) 0x84, (byte) 0x92, (byte) 0x36, (byte) 0xC3, (byte) 0xFA, (byte) 0xB4, (byte) 0xD2, (byte) 0x7C, (byte) 0x70, (byte) 0x26, (byte) 0xC1, (byte) 0xD4, (byte) 0xDC, (byte) 0xB2, (byte) 0x60, (byte) 0x26, (byte) 0x46, (byte) 0xDE, (byte) 0xC9, (byte) 0x75, (byte) 0x1E, (byte) 0x76, (byte) 0x3D, (byte) 0xBA, (byte) 0x37, (byte) 0xBD, (byte) 0xF8, (byte) 0xFF, (byte) 0x94, (byte) 0x06, (byte) 0xAD, (byte) 0x9E, (byte) 0x53, (byte) 0x0E, (byte) 0xE5, (byte) 0xDB, (byte) 0x38, (byte) 0x2F, (byte) 0x41, (byte) 0x30, (byte) 0x01, (byte) 0xAE, (byte) 0xB0, (byte) 0x6A, (byte) 0x53, (byte) 0xED, (byte) 0x90, (byte) 0x27, (byte) 0xD8, (byte) 0x31, (byte) 0x17, (byte) 0x97, (byte) 0x27, (byte) 0xB0, (byte) 0x86, (byte) 0x5A, (byte) 0x89, (byte) 0x18, (byte) 0xDA, (byte) 0x3E, (byte) 0xDB, (byte) 0xEB, (byte) 0xCF, (byte) 0x9B, (byte) 0x14, (byte) 0xED, (byte) 0x44, (byte) 0xCE, (byte) 0x6C, (byte) 0xBA, (byte) 0xCE, (byte) 0xD4, (byte) 0xBB, (byte) 0x1B, (byte) 0xDB, (byte) 0x7F, (byte) 0x14, (byte) 0x47, (byte) 0xE6, (byte) 0xCC, (byte) 0x25, (byte) 0x4B, (byte) 0x33, (byte) 0x20, (byte) 0x51, (byte) 0x51, (byte) 0x2B, (byte) 0xD7, (byte) 0xAF, (byte) 0x42, (byte) 0x6F, (byte) 0xB8, (byte) 0xF4, (byte) 0x01, (byte) 0x37, (byte) 0x8C, (byte) 0xD2, (byte) 0xBF, (byte) 0x59, (byte) 0x83, (byte) 0xCA, (byte) 0x01, (byte) 0xC6, (byte) 0x4B, (byte) 0x92, (byte) 0xEC, (byte) 0xF0, (byte) 0x32, (byte) 0xEA, (byte) 0x15, (byte) 0xD1, (byte) 0x72, (byte) 0x1D, (byte) 0x03, (byte) 0xF4, (byte) 0x82, (byte) 0xD7, (byte) 0xCE, (byte) 0x6E, (byte) 0x74, (byte) 0xFE, (byte) 0xF6, (byte) 0xD5, (byte) 0x5E, (byte) 0x70, (byte) 0x2F, (byte) 0x46, (byte) 0x98, (byte) 0x0C, (byte) 0x82, (byte) 0xB5, (byte) 0xA8, (byte) 0x40, (byte) 0x31, (byte) 0x90, (byte) 0x0B, (byte) 0x1C, (byte) 0x9E, (byte) 0x59, (byte) 0xE7, (byte) 0xC9, (byte) 0x7F, (byte) 0xBE, (byte) 0xC7, (byte) 0xE8, (byte) 0xF3, (byte) 0x23, (byte) 0xA9, (byte) 0x7A, (byte) 0x7E, (byte) 0x36, (byte) 0xCC, (byte) 0x88, (byte) 0xBE, (byte) 0x0F, (byte) 0x1D, (byte) 0x45, (byte) 0xB7, (byte) 0xFF, (byte) 0x58, (byte) 0x5A, (byte) 0xC5, (byte) 0x4B, (byte) 0xD4, (byte) 0x07, (byte) 0xB2, (byte) 0x2B, (byte) 0x41, (byte) 0x54, (byte) 0xAA, (byte) 0xCC, (byte) 0x8F, (byte) 0x6D, (byte) 0x7E, (byte) 0xBF, (byte) 0x48, (byte) 0xE1, (byte) 0xD8, (byte) 0x14, (byte) 0xCC, (byte) 0x5E, (byte) 0xD2, (byte) 0x0F, (byte) 0x80, (byte) 0x37, (byte) 0xE0, (byte) 0xA7, (byte) 0x97, (byte) 0x15, (byte) 0xEE, (byte) 0xF2, (byte) 0x9B, (byte) 0xE3, (byte) 0x28, (byte) 0x06, (byte) 0xA1, (byte) 0xD5, (byte) 0x8B, (byte) 0xB7, (byte) 0xC5, (byte) 0xDA, (byte) 0x76, (byte) 0xF5, (byte) 0x50, (byte) 0xAA, (byte) 0x3D, (byte) 0x8A, (byte) 0x1F, (byte) 0xBF, (byte) 0xF0, (byte) 0xEB, (byte) 0x19, (byte) 0xCC, (byte) 0xB1, (byte) 0xA3, (byte) 0x13, (byte) 0xD5, (byte) 0x5C, (byte) 0xDA, (byte) 0x56, (byte) 0xC9, (byte) 0xEC, (byte) 0x2E, (byte) 0xF2, (byte) 0x96, (byte) 0x32, (byte) 0x38, (byte) 0x7F, (byte) 0xE8, (byte) 0xD7, (byte) 0x6E, (byte) 0x3C, (byte) 0x04, (byte) 0x68, (byte) 0x04, (byte) 0x3E, (byte) 0x8F, (byte) 0x66, (byte) 0x3F, (byte) 0x48, (byte) 0x60, (byte) 0xEE, (byte) 0x12, (byte) 0xBF, (byte) 0x2D, (byte) 0x5B, (byte) 0x0B, (byte) 0x74, (byte) 0x74, (byte) 0xD6, (byte) 0xE6, (byte) 0x94, (byte) 0xF9, (byte) 0x1E, (byte) 0x6D, (byte) 0xBE, (byte) 0x11, (byte) 0x59, (byte) 0x74, (byte) 0xA3, (byte) 0x92, (byte) 0x6F, (byte) 0x12, (byte) 0xFE, (byte) 0xE5, (byte) 0xE4, (byte) 0x38, (byte) 0x77, (byte) 0x7C, (byte) 0xB6, (byte) 0xA9, (byte) 0x32, (byte) 0xDF, (byte) 0x8C, (byte) 0xD8, (byte) 0xBE, (byte) 0xC4, (byte) 0xD0, (byte) 0x73, (byte) 0xB9, (byte) 0x31, (byte) 0xBA, (byte) 0x3B, (byte) 0xC8, (byte) 0x32, (byte) 0xB6, (byte) 0x8D, (byte) 0x9D, (byte) 0xD3, (byte) 0x00, (byte) 0x74, (byte) 0x1F, (byte) 0xA7, (byte) 0xBF, (byte) 0x8A, (byte) 0xFC, (byte) 0x47, (byte) 0xED, (byte) 0x25, (byte) 0x76, (byte) 0xF6, (byte) 0x93, (byte) 0x6B, (byte) 0xA4, (byte) 0x24, (byte) 0x66, (byte) 0x3A, (byte) 0xAB, (byte) 0x63, (byte) 0x9C, (byte) 0x5A, (byte) 0xE4, (byte) 0xF5, (byte) 0x68, (byte) 0x34, (byte) 0x23, (byte) 0xB4, (byte) 0x74, (byte) 0x2B, (byte) 0xF1, (byte) 0xC9, (byte) 0x78, (byte) 0x23, (byte) 0x8F, (byte) 0x16, (byte) 0xCB, (byte) 0xE3, (byte) 0x9D, (byte) 0x65, (byte) 0x2D, (byte) 0xE3, (byte) 0xFD, (byte) 0xB8, (byte) 0xBE, (byte) 0xFC, (byte) 0x84, (byte) 0x8A, (byte) 0xD9, (byte) 0x22, (byte) 0x22, (byte) 0x2E, (byte) 0x04, (byte) 0xA4, (byte) 0x03, (byte) 0x7C, (byte) 0x07, (byte) 0x13, (byte) 0xEB, (byte) 0x57, (byte) 0xA8, (byte) 0x1A, (byte) 0x23, (byte) 0xF0, (byte) 0xC7, (byte) 0x34, (byte) 0x73, (byte) 0xFC, (byte) 0x64, (byte) 0x6C, (byte) 0xEA, (byte) 0x30, (byte) 0x6B, (byte) 0x4B, (byte) 0xCB, (byte) 0xC8, (byte) 0x86, (byte) 0x2F, (byte) 0x83, (byte) 0x85, (byte) 0xDD, (byte) 0xFA, (byte) 0x9D, (byte) 0x4B, (byte) 0x7F, (byte) 0xA2, (byte) 0xC0, (byte) 0x87, (byte) 0xE8, (byte) 0x79, (byte) 0x68, (byte) 0x33, (byte) 0x03, (byte) 0xED, (byte) 0x5B, (byte) 0xDD, (byte) 0x3A, (byte) 0x06, (byte) 0x2B, (byte) 0x3C, (byte) 0xF5, (byte) 0xB3, (byte) 0xA2, (byte) 0x78, (byte) 0xA6, (byte) 0x6D, (byte) 0x2A, (byte) 0x13, (byte) 0xF8, (byte) 0x3F, (byte) 0x44, (byte) 0xF8, (byte) 0x2D, (byte) 0xDF, (byte) 0x31, (byte) 0x0E, (byte) 0xE0, (byte) 0x74, (byte) 0xAB, (byte) 0x6A, (byte) 0x36, (byte) 0x45, (byte) 0x97, (byte) 0xE8, (byte) 0x99, (byte) 0xA0, (byte) 0x25, (byte) 0x5D, (byte) 0xC1, (byte) 0x64, (byte) 0xF3, (byte) 0x1C, (byte) 0xC5, (byte) 0x08, (byte) 0x46, (byte) 0x85, (byte) 0x1D, (byte) 0xF9, (byte) 0xAB, (byte) 0x48, (byte) 0x19, (byte) 0x5D, (byte) 0xED, (byte) 0x7E, (byte) 0xA1, (byte) 0xB1, (byte) 0xD5, (byte) 0x10, (byte) 0xBD, (byte) 0x7E, (byte) 0xE7, (byte) 0x4D, (byte) 0x73, (byte) 0xFA, (byte) 0xF3, (byte) 0x6B, (byte) 0xC3, (byte) 0x1E, (byte) 0xCF, (byte) 0xA2, (byte) 0x68, (byte) 0x35, (byte) 0x90, (byte) 0x46, (byte) 0xF4, (byte) 0xEB, (byte) 0x87, (byte) 0x9F, (byte) 0x92, (byte) 0x40, (byte) 0x09, (byte) 0x43, (byte) 0x8B, (byte) 0x48, (byte) 0x1C, (byte) 0x6C, (byte) 0xD7, (byte) 0x88, (byte) 0x9A, (byte) 0x00, (byte) 0x2E, (byte) 0xD5, (byte) 0xEE, (byte) 0x38, (byte) 0x2B, (byte) 0xC9, (byte) 0x19, (byte) 0x0D, (byte) 0xA6, (byte) 0xFC, (byte) 0x02, (byte) 0x6E, (byte) 0x47, (byte) 0x95, (byte) 0x58, (byte) 0xE4, (byte) 0x47, (byte) 0x56, (byte) 0x77, (byte) 0xE9, (byte) 0xAA, (byte) 0x9E, (byte) 0x30, (byte) 0x50, (byte) 0xE2, (byte) 0x76, (byte) 0x56, (byte) 0x94, (byte) 0xDF, (byte) 0xC8, (byte) 0x1F, (byte) 0x56, (byte) 0xE8, (byte) 0x80, (byte) 0xB9, (byte) 0x6E, (byte) 0x71, (byte) 0x60, (byte) 0xC9, (byte) 0x80, (byte) 0xDD, (byte) 0x98, (byte) 0xED, (byte) 0xD3, (byte) 0xDF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; @Override byte[] G() { return g; } @Override byte[] P() { return p; } @Override String sha_name() { return "sha-512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGEX.java000066400000000000000000000174741465436372100236360ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.math.BigInteger; abstract class DHGEX extends KeyExchange { private static final int SSH_MSG_KEX_DH_GEX_GROUP = 31; private static final int SSH_MSG_KEX_DH_GEX_INIT = 32; private static final int SSH_MSG_KEX_DH_GEX_REPLY = 33; private static final int SSH_MSG_KEX_DH_GEX_REQUEST = 34; int min; int preferred; int max; private int state; DH dh; byte[] V_S; byte[] V_C; byte[] I_S; byte[] I_C; private Buffer buf; private Packet packet; private byte[] p; private byte[] g; private byte[] e; protected String hash; @Override public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { this.V_S = V_S; this.V_C = V_C; this.I_S = I_S; this.I_C = I_C; try { Class c = Class.forName(session.getConfig(hash)).asSubclass(HASH.class); sha = c.getDeclaredConstructor().newInstance(); sha.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } buf = new Buffer(); packet = new Packet(buf); try { Class c = Class.forName(session.getConfig("dh")).asSubclass(DH.class); min = Integer.parseInt(session.getConfig("dhgex_min")); max = Integer.parseInt(session.getConfig("dhgex_max")); preferred = Integer.parseInt(session.getConfig("dhgex_preferred")); if (min <= 0 || max <= 0 || preferred <= 0 || preferred < min || preferred > max) { throw new JSchException( "Invalid DHGEX sizes: min=" + min + " max=" + max + " preferred=" + preferred); } dh = c.getDeclaredConstructor().newInstance(); dh.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } packet.reset(); buf.putByte((byte) SSH_MSG_KEX_DH_GEX_REQUEST); buf.putInt(min); buf.putInt(preferred); buf.putInt(max); session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_DH_GEX_REQUEST(" + min + "<" + preferred + "<" + max + ") sent"); session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_GROUP"); } state = SSH_MSG_KEX_DH_GEX_GROUP; } @Override public boolean next(Buffer _buf) throws Exception { int i, j; switch (state) { case SSH_MSG_KEX_DH_GEX_GROUP: // byte SSH_MSG_KEX_DH_GEX_GROUP(31) // mpint p, safe prime // mpint g, generator for subgroup in GF (p) _buf.getInt(); _buf.getByte(); j = _buf.getByte(); if (j != SSH_MSG_KEX_DH_GEX_GROUP) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_DH_GEX_GROUP " + j); } return false; } p = _buf.getMPInt(); g = _buf.getMPInt(); int bits = new BigInteger(1, p).bitLength(); if (bits < min || bits > max) { return false; } dh.setP(p); dh.setG(g); // The client responds with: // byte SSH_MSG_KEX_DH_GEX_INIT(32) // mpint e <- g^x mod p // x is a random number (1 < x < (p-1)/2) e = dh.getE(); packet.reset(); buf.putByte((byte) SSH_MSG_KEX_DH_GEX_INIT); buf.putMPInt(e); session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_DH_GEX_INIT sent"); session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_REPLY"); } state = SSH_MSG_KEX_DH_GEX_REPLY; return true; // break; case SSH_MSG_KEX_DH_GEX_REPLY: // The server responds with: // byte SSH_MSG_KEX_DH_GEX_REPLY(33) // string server public host key and certificates (K_S) // mpint f // string signature of H j = _buf.getInt(); j = _buf.getByte(); j = _buf.getByte(); if (j != SSH_MSG_KEX_DH_GEX_REPLY) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_DH_GEX_REPLY " + j); } return false; } K_S = _buf.getString(); byte[] f = _buf.getMPInt(); byte[] sig_of_H = _buf.getString(); dh.setF(f); dh.checkRange(); K = encodeAsMPInt(normalize(dh.getK())); // The hash H is computed as the HASH hash of the concatenation of the // following: // string V_C, the client's version string (CR and NL excluded) // string V_S, the server's version string (CR and NL excluded) // string I_C, the payload of the client's SSH_MSG_KEXINIT // string I_S, the payload of the server's SSH_MSG_KEXINIT // string K_S, the host key // uint32 min, minimal size in bits of an acceptable group // uint32 n, preferred size in bits of the group the server should send // uint32 max, maximal size in bits of an acceptable group // mpint p, safe prime // mpint g, generator for subgroup // mpint e, exchange value sent by the client // mpint f, exchange value sent by the server // mpint K, the shared secret // This value is called the exchange hash, and it is used to authenti- // cate the key exchange. buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putInt(min); buf.putInt(preferred); buf.putInt(max); buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f); byte[] foo = new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.length); sha.update(K, 0, K.length); H = sha.digest(); // System.err.print("H -> "); dump(H, 0, H.length); i = 0; j = 0; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); String alg = Util.byte2str(K_S, i, j); i += j; boolean result = verify(alg, K_S, i, sig_of_H); state = STATE_END; return result; } return false; } @Override public int getState() { return state; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGEX1.java000066400000000000000000000030631465436372100237040ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHGEX1 extends DHGEX { DHGEX1() { hash = "sha-1"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGEX224.java000066400000000000000000000030711465436372100240520ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHGEX224 extends DHGEX { DHGEX224() { hash = "sha-224"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGEX256.java000066400000000000000000000030711465436372100240570ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHGEX256 extends DHGEX { DHGEX256() { hash = "sha-256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGEX384.java000066400000000000000000000030711465436372100240610ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHGEX384 extends DHGEX { DHGEX384() { hash = "sha-384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGEX512.java000066400000000000000000000030711465436372100240520ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class DHGEX512 extends DHGEX { DHGEX512() { hash = "sha-512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHGN.java000066400000000000000000000132051465436372100235030ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class DHGN extends KeyExchange { private static final int SSH_MSG_KEXDH_INIT = 30; private static final int SSH_MSG_KEXDH_REPLY = 31; private int state; DH dh; byte[] V_S; byte[] V_C; byte[] I_S; byte[] I_C; byte[] e; private Buffer buf; private Packet packet; abstract byte[] G(); abstract byte[] P(); abstract String sha_name(); @Override public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { this.V_S = V_S; this.V_C = V_C; this.I_S = I_S; this.I_C = I_C; try { Class c = Class.forName(session.getConfig(sha_name())).asSubclass(HASH.class); sha = c.getDeclaredConstructor().newInstance(); sha.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } buf = new Buffer(); packet = new Packet(buf); try { Class c = Class.forName(session.getConfig("dh")).asSubclass(DH.class); dh = c.getDeclaredConstructor().newInstance(); dh.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } dh.setP(P()); dh.setG(G()); // The client responds with: // byte SSH_MSG_KEXDH_INIT(30) // mpint e <- g^x mod p // x is a random number (1 < x < (p-1)/2) e = dh.getE(); packet.reset(); buf.putByte((byte) SSH_MSG_KEXDH_INIT); buf.putMPInt(e); if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-( return; } session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_KEXDH_INIT sent"); session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEXDH_REPLY"); } state = SSH_MSG_KEXDH_REPLY; } @Override public boolean next(Buffer _buf) throws Exception { int i, j; switch (state) { case SSH_MSG_KEXDH_REPLY: // The server responds with: // byte SSH_MSG_KEXDH_REPLY(31) // string server public host key and certificates (K_S) // mpint f // string signature of H j = _buf.getInt(); j = _buf.getByte(); j = _buf.getByte(); if (j != SSH_MSG_KEXDH_REPLY) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEXDH_REPLY " + j); } return false; } K_S = _buf.getString(); byte[] f = _buf.getMPInt(); byte[] sig_of_H = _buf.getString(); dh.setF(f); dh.checkRange(); K = encodeAsMPInt(normalize(dh.getK())); // The hash H is computed as the HASH hash of the concatenation of the // following: // string V_C, the client's version string (CR and NL excluded) // string V_S, the server's version string (CR and NL excluded) // string I_C, the payload of the client's SSH_MSG_KEXINIT // string I_S, the payload of the server's SSH_MSG_KEXINIT // string K_S, the host key // mpint e, exchange value sent by the client // mpint f, exchange value sent by the server // mpint K, the shared secret // This value is called the exchange hash, and it is used to authenti- // cate the key exchange. buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putMPInt(e); buf.putMPInt(f); byte[] foo = new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.length); sha.update(K, 0, K.length); H = sha.digest(); // System.err.print("H -> "); //dump(H, 0, H.length); i = 0; j = 0; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); String alg = Util.byte2str(K_S, i, j); i += j; boolean result = verify(alg, K_S, i, sig_of_H); state = STATE_END; return result; } return false; } @Override public int getState() { return state; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHXEC.java000066400000000000000000000153731465436372100236260ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class DHXEC extends KeyExchange { private static final int SSH_MSG_KEX_ECDH_INIT = 30; private static final int SSH_MSG_KEX_ECDH_REPLY = 31; private int state; byte[] Q_C; byte[] V_S; byte[] V_C; byte[] I_S; byte[] I_C; byte[] e; private Buffer buf; private Packet packet; private XDH xdh; protected String sha_name; protected String curve_name; protected int key_len; @Override public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { this.V_S = V_S; this.V_C = V_C; this.I_S = I_S; this.I_C = I_C; try { Class c = Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class); sha = c.getDeclaredConstructor().newInstance(); sha.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } buf = new Buffer(); packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_KEX_ECDH_INIT); try { Class c = Class.forName(session.getConfig("xdh")).asSubclass(XDH.class); xdh = c.getDeclaredConstructor().newInstance(); xdh.init(curve_name, key_len); Q_C = xdh.getQ(); buf.putString(Q_C); } catch (Exception | NoClassDefFoundError e) { throw new JSchException(e.toString(), e); } if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-( return; } session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent"); session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY"); } state = SSH_MSG_KEX_ECDH_REPLY; } @Override public boolean next(Buffer _buf) throws Exception { int i, j; switch (state) { case SSH_MSG_KEX_ECDH_REPLY: // The server responds with: // byte SSH_MSG_KEX_ECDH_REPLY // string K_S, server's public host key // string Q_S, server's ephemeral public key octet string // string the signature on the exchange hash j = _buf.getInt(); j = _buf.getByte(); j = _buf.getByte(); if (j != SSH_MSG_KEX_ECDH_REPLY) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_ECDH_REPLY " + j); } return false; } K_S = _buf.getString(); byte[] Q_S = _buf.getString(); // RFC 5656, // 4. ECDH Key Exchange // All elliptic curve public keys MUST be validated after they are // received. An example of a validation algorithm can be found in // Section 3.2.2 of [SEC1]. If a key fails validation, // the key exchange MUST fail. if (!xdh.validate(Q_S)) { return false; } K = encodeAsMPInt(normalize(xdh.getSecret(Q_S))); byte[] sig_of_H = _buf.getString(); // The hash H is computed as the HASH hash of the concatenation of the // following: // string V_C, client's identification string (CR and LF excluded) // string V_S, server's identification string (CR and LF excluded) // string I_C, payload of the client's SSH_MSG_KEXINIT // string I_S, payload of the server's SSH_MSG_KEXINIT // string K_S, server's public host key // string Q_C, client's ephemeral public key octet string // string Q_S, server's ephemeral public key octet string // mpint K, shared secret // This value is called the exchange hash, and it is used to authenti- // cate the key exchange. // RFC 8731, // 3.1. Shared Secret Encoding // The shared secret, K, is defined in [RFC4253] and [RFC5656] as an // integer encoded as a multiple precision integer (mpint). // Curve25519/448 outputs a binary string X, which is the 32- or 56-byte // point obtained by scalar multiplication of the other side's public // key and the local private key scalar. The 32 or 56 bytes of X are // converted into K by interpreting the octets as an unsigned fixed- // length integer encoded in network byte order. // // The mpint K is then encoded using the process described in Section 5 // of [RFC4251], and the resulting bytes are fed as described in // [RFC4253] to the key exchange method's hash function to generate // encryption keys. buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putString(Q_C); buf.putString(Q_S); byte[] foo = new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.length); sha.update(K, 0, K.length); H = sha.digest(); i = 0; j = 0; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); String alg = Util.byte2str(K_S, i, j); i += j; boolean result = verify(alg, K_S, i, sig_of_H); state = STATE_END; return result; } return false; } @Override public int getState() { return state; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/DHXECKEM.java000066400000000000000000000175261465436372100241650ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class DHXECKEM extends KeyExchange { private static final int SSH_MSG_KEX_ECDH_INIT = 30; private static final int SSH_MSG_KEX_ECDH_REPLY = 31; private int state; byte[] Q_C; byte[] V_S; byte[] V_C; byte[] I_S; byte[] I_C; byte[] e; private Buffer buf; private Packet packet; private KEM kem; private XDH xdh; protected String kem_name; protected String sha_name; protected String curve_name; protected int kem_pubkey_len; protected int kem_encap_len; protected int xec_key_len; @Override public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { this.V_S = V_S; this.V_C = V_C; this.I_S = I_S; this.I_C = I_C; try { Class c = Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class); sha = c.getDeclaredConstructor().newInstance(); sha.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } buf = new Buffer(); packet = new Packet(buf); packet.reset(); // command + string len + Q_C len buf.checkFreeSize(1 + 4 + kem_pubkey_len + xec_key_len); buf.putByte((byte) SSH_MSG_KEX_ECDH_INIT); try { Class k = Class.forName(session.getConfig(kem_name)).asSubclass(KEM.class); kem = k.getDeclaredConstructor().newInstance(); kem.init(); Class c = Class.forName(session.getConfig("xdh")).asSubclass(XDH.class); xdh = c.getDeclaredConstructor().newInstance(); xdh.init(curve_name, xec_key_len); byte[] kem_public_key_C = kem.getPublicKey(); byte[] xec_public_key_C = xdh.getQ(); Q_C = new byte[kem_pubkey_len + xec_key_len]; System.arraycopy(kem_public_key_C, 0, Q_C, 0, kem_pubkey_len); System.arraycopy(xec_public_key_C, 0, Q_C, kem_pubkey_len, xec_key_len); buf.putString(Q_C); } catch (Exception | NoClassDefFoundError e) { throw new JSchException(e.toString(), e); } if (V_S == null) { // This is a really ugly hack for Session.checkKexes ;-( return; } session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent"); session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY"); } state = SSH_MSG_KEX_ECDH_REPLY; } @Override public boolean next(Buffer _buf) throws Exception { int i, j; switch (state) { case SSH_MSG_KEX_ECDH_REPLY: // The server responds with: // byte SSH_MSG_KEX_ECDH_REPLY // string K_S, server's public host key // string Q_S, server's ephemeral public key octet string // string the signature on the exchange hash j = _buf.getInt(); j = _buf.getByte(); j = _buf.getByte(); if (j != SSH_MSG_KEX_ECDH_REPLY) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "type: must be SSH_MSG_KEX_ECDH_REPLY " + j); } return false; } K_S = _buf.getString(); byte[] Q_S = _buf.getString(); if (Q_S.length != kem_encap_len + xec_key_len) { return false; } byte[] encapsulation = new byte[kem_encap_len]; byte[] xec_public_key_S = new byte[xec_key_len]; System.arraycopy(Q_S, 0, encapsulation, 0, kem_encap_len); System.arraycopy(Q_S, kem_encap_len, xec_public_key_S, 0, xec_key_len); // RFC 5656, // 4. ECDH Key Exchange // All elliptic curve public keys MUST be validated after they are // received. An example of a validation algorithm can be found in // Section 3.2.2 of [SEC1]. If a key fails validation, // the key exchange MUST fail. if (!xdh.validate(xec_public_key_S)) { return false; } byte[] tmp = null; try { tmp = kem.decapsulate(encapsulation); sha.update(tmp, 0, tmp.length); } finally { Util.bzero(tmp); } try { tmp = normalize(xdh.getSecret(xec_public_key_S)); sha.update(tmp, 0, tmp.length); } finally { Util.bzero(tmp); } K = encodeAsString(sha.digest()); byte[] sig_of_H = _buf.getString(); // The hash H is computed as the HASH hash of the concatenation of the // following: // string V_C, client's identification string (CR and LF excluded) // string V_S, server's identification string (CR and LF excluded) // string I_C, payload of the client's SSH_MSG_KEXINIT // string I_S, payload of the server's SSH_MSG_KEXINIT // string K_S, server's public host key // string Q_C, client's ephemeral public key octet string // string Q_S, server's ephemeral public key octet string // string K, shared secret // draft-josefsson-ntruprime-ssh-02, // 3. Key Exchange Method: sntrup761x25519-sha512 // ... // The SSH_MSG_KEX_ECDH_REPLY's signature value is computed as described // in [RFC5656] with the following changes. Instead of encoding the // shared secret K as 'mpint', it MUST be encoded as 'string'. The // shared secret K value MUST be the 64-byte output octet string of the // SHA-512 hash computed with the input as the 32-byte octet string key // output from the key encapsulation mechanism of sntrup761 concatenated // with the 32-byte octet string of X25519(a, X25519(b, 9)) = X25519(b, // X25519(a, 9)). buf.reset(); buf.putString(V_C); buf.putString(V_S); buf.putString(I_C); buf.putString(I_S); buf.putString(K_S); buf.putString(Q_C); buf.putString(Q_S); byte[] foo = new byte[buf.getLength()]; buf.getByte(foo); sha.update(foo, 0, foo.length); sha.update(K, 0, K.length); H = sha.digest(); i = 0; j = 0; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); String alg = Util.byte2str(K_S, i, j); i += j; boolean result = verify(alg, K_S, i, sig_of_H); state = STATE_END; return result; } return false; } @Override public int getState() { return state; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ECDH.java000066400000000000000000000033101465436372100234620ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface ECDH { void init(int size) throws Exception; byte[] getSecret(byte[] r, byte[] s) throws Exception; byte[] getQ() throws Exception; boolean validate(byte[] r, byte[] s) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java000066400000000000000000000033261465436372100266270ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.InputStream; import java.io.OutputStream; public interface ForwardedTCPIPDaemon extends Runnable { void setChannel(ChannelForwardedTCPIP channel, InputStream in, OutputStream out); void setArg(Object[] arg); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/GSSContext.java000066400000000000000000000034201465436372100247620ustar00rootroot00000000000000/* * Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface GSSContext { public void create(String user, String host) throws JSchException; public boolean isEstablished(); public byte[] init(byte[] token, int s, int l) throws JSchException; public byte[] getMIC(byte[] message, int s, int l); public void dispose(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/HASH.java000066400000000000000000000033241465436372100235070ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface HASH { void init() throws Exception; int getBlockSize(); void update(byte[] foo, int start, int len) throws Exception; byte[] digest() throws Exception; default String name() { return ""; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/HostKey.java000066400000000000000000000125311465436372100243520ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Locale; public class HostKey { private static final byte[][] names = {Util.str2byte("ssh-dss"), Util.str2byte("ssh-rsa"), Util.str2byte("ecdsa-sha2-nistp256"), Util.str2byte("ecdsa-sha2-nistp384"), Util.str2byte("ecdsa-sha2-nistp521"), Util.str2byte("ssh-ed25519"), Util.str2byte("ssh-ed448")}; public static final int UNKNOWN = -1; public static final int GUESS = 0; public static final int SSHDSS = 1; public static final int SSHRSA = 2; public static final int ECDSA256 = 3; public static final int ECDSA384 = 4; public static final int ECDSA521 = 5; public static final int ED25519 = 6; public static final int ED448 = 7; protected String marker; protected String host; protected int type; protected byte[] key; protected String comment; public HostKey(String host, byte[] key) throws JSchException { this(host, GUESS, key); } public HostKey(String host, int type, byte[] key) throws JSchException { this(host, type, key, null); } public HostKey(String host, int type, byte[] key, String comment) throws JSchException { this("", host, type, key, comment); } public HostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException { this.marker = marker; this.host = host; if (type == GUESS) { if (key[8] == 'd') { this.type = SSHDSS; } else if (key[8] == 'r') { this.type = SSHRSA; } else if (key[8] == 'e' && key[10] == '2') { this.type = ED25519; } else if (key[8] == 'e' && key[10] == '4') { this.type = ED448; } else if (key[8] == 'a' && key[20] == '2') { this.type = ECDSA256; } else if (key[8] == 'a' && key[20] == '3') { this.type = ECDSA384; } else if (key[8] == 'a' && key[20] == '5') { this.type = ECDSA521; } else { throw new JSchException("invalid key type"); } } else { this.type = type; } this.key = key; this.comment = comment; } public String getHost() { return host; } public String getType() { if (type == SSHDSS || type == SSHRSA || type == ED25519 || type == ED448 || type == ECDSA256 || type == ECDSA384 || type == ECDSA521) { return Util.byte2str(names[type - 1]); } return "UNKNOWN"; } protected static int name2type(String name) { for (int i = 0; i < names.length; i++) { if (Util.byte2str(names[i]).equals(name)) { return i + 1; } } return UNKNOWN; } public String getKey() { return Util.byte2str(Util.toBase64(key, 0, key.length, true)); } public String getFingerPrint(JSch jsch) { HASH hash = null; try { String _c = JSch.getConfig("FingerprintHash").toLowerCase(Locale.ROOT); Class c = Class.forName(JSch.getConfig(_c)).asSubclass(HASH.class); hash = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { if (jsch.getInstanceLogger().isEnabled(Logger.ERROR)) { jsch.getInstanceLogger().log(Logger.ERROR, "getFingerPrint: " + e.getMessage(), e); } } return Util.getFingerPrint(hash, key, false, true); } public String getComment() { return comment; } public String getMarker() { return marker; } boolean isMatched(String _host) { return isIncluded(_host); } private boolean isIncluded(String _host) { int i = 0; String hosts = this.host; int hostslen = hosts.length(); int hostlen = _host.length(); int j; while (i < hostslen) { j = hosts.indexOf(',', i); if (j == -1) { if (hostlen != hostslen - i) return false; return hosts.regionMatches(true, i, _host, 0, hostlen); } if (hostlen == (j - i)) { if (hosts.regionMatches(true, i, _host, 0, hostlen)) return true; } i = j + 1; } return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/HostKeyRepository.java000066400000000000000000000062141465436372100264530ustar00rootroot00000000000000/* * Copyright (c) 2004-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface HostKeyRepository { final int OK = 0; final int NOT_INCLUDED = 1; final int CHANGED = 2; /** * Checks if host is included with the key. * * @return #NOT_INCLUDED, #OK or #CHANGED * @see #NOT_INCLUDED * @see #OK * @see #CHANGED */ int check(String host, byte[] key); /** * Adds a host key hostkey * * @param hostkey a host key to be added * @param ui a user interface for showing messages or promping inputs. * @see UserInfo */ void add(HostKey hostkey, UserInfo ui); /** * Removes a host key if there exists mached key with host, type. * * @see #remove(String host, String type, byte[] key) */ void remove(String host, String type); /** * Removes a host key if there exists a matched key with host, type and * key. */ void remove(String host, String type, byte[] key); /** * Returns id of this repository. * * @return identity in String */ String getKnownHostsRepositoryID(); /** * Retuns a list for host keys managed in this repository. * * @see #getHostKey(String host, String type) */ HostKey[] getHostKey(); /** * Retuns a list for host keys managed in this repository. * * @param host a hostname used in searching host keys. If null is given, every host * key will be listed. * @param type a key type used in searching host keys, and it should be "ssh-dss" or "ssh-rsa". If * null is given, a key type type will not be ignored. */ HostKey[] getHostKey(String host, String type); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/IO.java000066400000000000000000000076321465436372100233010ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.SocketException; class IO { InputStream in; OutputStream out; OutputStream out_ext; private boolean in_dontclose = false; private boolean out_dontclose = false; private boolean out_ext_dontclose = false; void setOutputStream(OutputStream out) { this.out = out; } void setOutputStream(OutputStream out, boolean dontclose) { this.out_dontclose = dontclose; setOutputStream(out); } void setExtOutputStream(OutputStream out) { this.out_ext = out; } void setExtOutputStream(OutputStream out, boolean dontclose) { this.out_ext_dontclose = dontclose; setExtOutputStream(out); } void setInputStream(InputStream in) { this.in = in; } void setInputStream(InputStream in, boolean dontclose) { this.in_dontclose = dontclose; setInputStream(in); } void put(Packet p) throws IOException, SocketException { out.write(p.buffer.buffer, 0, p.buffer.index); out.flush(); } void put(byte[] array, int begin, int length) throws IOException { out.write(array, begin, length); out.flush(); } void put_ext(byte[] array, int begin, int length) throws IOException { out_ext.write(array, begin, length); out_ext.flush(); } int getByte() throws IOException { return in.read(); } void getByte(byte[] array) throws IOException { getByte(array, 0, array.length); } void getByte(byte[] array, int begin, int length) throws IOException { do { int completed = in.read(array, begin, length); if (completed < 0) { throw new IOException("End of IO Stream Read"); } begin += completed; length -= completed; } while (length > 0); } void out_close() { try { if (out != null && !out_dontclose) out.close(); out = null; } catch (Exception ee) { } } void close() { try { if (in != null && !in_dontclose) in.close(); in = null; } catch (Exception ee) { } out_close(); try { if (out_ext != null && !out_ext_dontclose) out_ext.close(); out_ext = null; } catch (Exception ee) { } } /* * void finalize() throws Throwable{ try{ if(in!=null) in.close(); } catch(Exception ee){} try{ * if(out!=null) out.close(); } catch(Exception ee){} try{ if(out_ext!=null) out_ext.close(); } * catch(Exception ee){} } */ } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Identity.java000066400000000000000000000105671465436372100245640ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface Identity { /** * Decrypts this identity with the specified pass-phrase. * * @param passphrase the pass-phrase for this identity. * @return true if the decryption is succeeded or this identity is not cyphered. */ public boolean setPassphrase(byte[] passphrase) throws JSchException; /** * Returns the public-key blob. * * @return the public-key blob */ public byte[] getPublicKeyBlob(); /** * Signs on data with this identity, and returns the result. * *

* IMPORTANT NOTE:
* The {@link #getSignature(byte[], String)} method should be overridden to ensure {@code ssh-rsa} * type public keys function with the {@code rsa-sha2-256} or {@code rsa-sha2-512} signature * algorithms. * * @param data data to be signed * @return the signature * @see #getSignature(byte[], String) */ public byte[] getSignature(byte[] data); /** * Signs on data with this identity, and returns the result. * *

* IMPORTANT NOTE:
* The default implementation of this method simply calls {@link #getSignature(byte[])}, which * will fail with {@code ssh-rsa} type public keys when utilized with the {@code rsa-sha2-256} or * {@code rsa-sha2-512} signature algorithms:
* it exists only to maintain backwards compatibility of this interface. * *

* This default method should be overridden by implementations to ensure the {@code rsa-sha2-256} * and {@code rsa-sha2-512} signature algorithms function correctly. * * @param data data to be signed * @param alg signature algorithm to use * @return the signature * @since 0.1.57 * @see #getSignature(byte[]) */ public default byte[] getSignature(byte[] data, String alg) { return getSignature(data); } /** * This method is deprecated and the default implmentation of this method will throw an * {@link UnsupportedOperationException}. * * @deprecated The decryption should be done automatically in {@link #setPassphrase(byte[])} * @return true if the decryption is succeeded or this identity is not cyphered. * @see #setPassphrase(byte[]) */ @Deprecated public default boolean decrypt() { throw new UnsupportedOperationException("not implemented"); } /** * Returns the name of the key algorithm. * * @return the name of the key algorithm */ public String getAlgName(); /** * Returns the name of this identity. It will be useful to identify this object in the * {@link IdentityRepository}. * * @return the name of this identity */ public String getName(); /** * Returns true if this identity is cyphered. * * @return true if this identity is cyphered. */ public boolean isEncrypted(); /** Disposes internally allocated data, like byte array for the private key. */ public void clear(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/IdentityFile.java000066400000000000000000000103431465436372100253540ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class IdentityFile implements Identity { private KeyPair kpair; private String identity; static IdentityFile newInstance(String prvfile, String pubfile, JSch.InstanceLogger instLogger) throws JSchException { KeyPair kpair = KeyPair.load(instLogger, prvfile, pubfile); return new IdentityFile(prvfile, kpair); } static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch.InstanceLogger instLogger) throws JSchException { KeyPair kpair = KeyPair.load(instLogger, prvkey, pubkey); return new IdentityFile(name, kpair); } private IdentityFile(String name, KeyPair kpair) { this.identity = name; this.kpair = kpair; } /** * Decrypts this identity with the specified pass-phrase. * * @param passphrase the pass-phrase for this identity. * @return true if the decryption is succeeded or this identity is not cyphered. */ @Override public boolean setPassphrase(byte[] passphrase) throws JSchException { return kpair.decrypt(passphrase); } /** * Returns the public-key blob. * * @return the public-key blob */ @Override public byte[] getPublicKeyBlob() { return kpair.getPublicKeyBlob(); } /** * Signs on data with this identity, and returns the result. * * @param data data to be signed * @return the signature */ @Override public byte[] getSignature(byte[] data) { return kpair.getSignature(data); } /** * Signs on data with this identity, and returns the result. * * @param data data to be signed * @param alg signature algorithm to use * @return the signature */ @Override public byte[] getSignature(byte[] data, String alg) { return kpair.getSignature(data, alg); } /** * Returns the name of the key algorithm. * * @return the name of the key algorithm */ @Override public String getAlgName() { return kpair.getKeyTypeString(); } /** * Returns the name of this identity. It will be useful to identify this object in the * {@link IdentityRepository}. * * @return the name of this identity */ @Override public String getName() { return identity; } /** * Returns true if this identity is cyphered. * * @return true if this identity is cyphered. */ @Override public boolean isEncrypted() { return kpair.isEncrypted(); } /** Disposes internally allocated data, like byte array for the private key. */ @Override public void clear() { kpair.dispose(); kpair = null; } /** * Returns an instance of {@link KeyPair} used in this {@link Identity}. * * @return an instance of {@link KeyPair} used in this {@link Identity}. */ public KeyPair getKeyPair() { return kpair; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/IdentityRepository.java000066400000000000000000000035731465436372100266630ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Vector; public interface IdentityRepository { public static final int UNAVAILABLE = 0; public static final int NOTRUNNING = 1; public static final int RUNNING = 2; public String getName(); public int getStatus(); public Vector getIdentities(); public boolean add(byte[] identity); public boolean remove(byte[] blob); public void removeAll(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java000066400000000000000000000071251465436372100302210ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Vector; /** * JSch will accept ciphered keys, but some implementations of IdentityRepository can not. For * example, IdentityRepository for ssh-agent and pageant only accept plain keys. The following class * has been introduced to cache ciphered keys for them, and pass them whenever they are de-ciphered. */ class IdentityRepositoryWrapper implements IdentityRepository { private IdentityRepository ir; private Vector cache = new Vector<>(); private boolean keep_in_cache = false; IdentityRepositoryWrapper(IdentityRepository ir) { this(ir, false); } IdentityRepositoryWrapper(IdentityRepository ir, boolean keep_in_cache) { this.ir = ir; this.keep_in_cache = keep_in_cache; } @Override public String getName() { return ir.getName(); } @Override public int getStatus() { return ir.getStatus(); } @Override public boolean add(byte[] identity) { return ir.add(identity); } @Override public boolean remove(byte[] blob) { return ir.remove(blob); } @Override public void removeAll() { cache.removeAllElements(); ir.removeAll(); } @Override public Vector getIdentities() { Vector result = new Vector<>(); for (int i = 0; i < cache.size(); i++) { Identity identity = cache.elementAt(i); result.add(identity); } Vector tmp = ir.getIdentities(); for (int i = 0; i < tmp.size(); i++) { result.add(tmp.elementAt(i)); } return result; } void add(Identity identity) { if (!keep_in_cache && !identity.isEncrypted() && (identity instanceof IdentityFile)) { try { ir.add(((IdentityFile) identity).getKeyPair().forSSHAgent()); } catch (JSchException e) { // an exception will not be thrown. } } else cache.addElement(identity); } void check() { if (cache.size() > 0) { Object[] identities = cache.toArray(); for (int i = 0; i < identities.length; i++) { Identity identity = (Identity) (identities[i]); cache.removeElement(identity); add(identity); } } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSch.java000066400000000000000000000722311465436372100236160ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.InputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; public class JSch { /** The version number. */ public static final String VERSION = Version.getVersion(); static Hashtable config = new Hashtable<>(); static { config.put("kex", Util.getSystemProperty("jsch.kex", "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256")); config.put("server_host_key", Util.getSystemProperty("jsch.server_host_key", "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256")); config.put("prefer_known_host_key_types", Util.getSystemProperty("jsch.prefer_known_host_key_types", "yes")); config.put("enable_strict_kex", Util.getSystemProperty("jsch.enable_strict_kex", "yes")); config.put("require_strict_kex", Util.getSystemProperty("jsch.require_strict_kex", "no")); config.put("enable_server_sig_algs", Util.getSystemProperty("jsch.enable_server_sig_algs", "yes")); config.put("enable_ext_info_in_auth", Util.getSystemProperty("jsch.enable_ext_info_in_auth", "yes")); config.put("cipher.s2c", Util.getSystemProperty("jsch.cipher", "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com")); config.put("cipher.c2s", Util.getSystemProperty("jsch.cipher", "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com")); config.put("mac.s2c", Util.getSystemProperty("jsch.mac", "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1")); config.put("mac.c2s", Util.getSystemProperty("jsch.mac", "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1")); config.put("compression.s2c", Util.getSystemProperty("jsch.compression", "none")); config.put("compression.c2s", Util.getSystemProperty("jsch.compression", "none")); config.put("lang.s2c", Util.getSystemProperty("jsch.lang", "")); config.put("lang.c2s", Util.getSystemProperty("jsch.lang", "")); config.put("dhgex_min", Util.getSystemProperty("jsch.dhgex_min", "2048")); config.put("dhgex_max", Util.getSystemProperty("jsch.dhgex_max", "8192")); config.put("dhgex_preferred", Util.getSystemProperty("jsch.dhgex_preferred", "3072")); config.put("compression_level", Util.getSystemProperty("jsch.compression_level", "6")); config.put("diffie-hellman-group-exchange-sha1", "com.jcraft.jsch.DHGEX1"); config.put("diffie-hellman-group1-sha1", "com.jcraft.jsch.DHG1"); config.put("diffie-hellman-group14-sha1", "com.jcraft.jsch.DHG14"); config.put("diffie-hellman-group-exchange-sha256", "com.jcraft.jsch.DHGEX256"); config.put("diffie-hellman-group-exchange-sha224@ssh.com", "com.jcraft.jsch.DHGEX224"); config.put("diffie-hellman-group-exchange-sha384@ssh.com", "com.jcraft.jsch.DHGEX384"); config.put("diffie-hellman-group-exchange-sha512@ssh.com", "com.jcraft.jsch.DHGEX512"); config.put("diffie-hellman-group14-sha256", "com.jcraft.jsch.DHG14256"); config.put("diffie-hellman-group15-sha512", "com.jcraft.jsch.DHG15"); config.put("diffie-hellman-group16-sha512", "com.jcraft.jsch.DHG16"); config.put("diffie-hellman-group17-sha512", "com.jcraft.jsch.DHG17"); config.put("diffie-hellman-group18-sha512", "com.jcraft.jsch.DHG18"); config.put("diffie-hellman-group14-sha256@ssh.com", "com.jcraft.jsch.DHG14256"); config.put("diffie-hellman-group14-sha224@ssh.com", "com.jcraft.jsch.DHG14224"); config.put("diffie-hellman-group15-sha256@ssh.com", "com.jcraft.jsch.DHG15256"); config.put("diffie-hellman-group15-sha384@ssh.com", "com.jcraft.jsch.DHG15384"); config.put("diffie-hellman-group16-sha512@ssh.com", "com.jcraft.jsch.DHG16"); config.put("diffie-hellman-group16-sha384@ssh.com", "com.jcraft.jsch.DHG16384"); config.put("diffie-hellman-group18-sha512@ssh.com", "com.jcraft.jsch.DHG18"); config.put("ecdsa-sha2-nistp256", "com.jcraft.jsch.jce.SignatureECDSA256"); config.put("ecdsa-sha2-nistp384", "com.jcraft.jsch.jce.SignatureECDSA384"); config.put("ecdsa-sha2-nistp521", "com.jcraft.jsch.jce.SignatureECDSA521"); config.put("ecdh-sha2-nistp256", "com.jcraft.jsch.DHEC256"); config.put("ecdh-sha2-nistp384", "com.jcraft.jsch.DHEC384"); config.put("ecdh-sha2-nistp521", "com.jcraft.jsch.DHEC521"); config.put("ecdh-sha2-nistp", "com.jcraft.jsch.jce.ECDHN"); config.put("curve25519-sha256", "com.jcraft.jsch.DH25519"); config.put("curve25519-sha256@libssh.org", "com.jcraft.jsch.DH25519"); config.put("curve448-sha512", "com.jcraft.jsch.DH448"); config.put("sntrup761x25519-sha512@openssh.com", "com.jcraft.jsch.DH25519SNTRUP761"); config.put("sntrup761", "com.jcraft.jsch.bc.SNTRUP761"); config.put("dh", "com.jcraft.jsch.jce.DH"); config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC"); config.put("blowfish-cbc", "com.jcraft.jsch.jce.BlowfishCBC"); config.put("hmac-sha1", "com.jcraft.jsch.jce.HMACSHA1"); config.put("hmac-sha1-96", "com.jcraft.jsch.jce.HMACSHA196"); config.put("hmac-sha2-256", "com.jcraft.jsch.jce.HMACSHA256"); config.put("hmac-sha2-512", "com.jcraft.jsch.jce.HMACSHA512"); config.put("hmac-md5", "com.jcraft.jsch.jce.HMACMD5"); config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596"); config.put("hmac-sha1-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA1ETM"); config.put("hmac-sha1-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA196ETM"); config.put("hmac-sha2-256-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA256ETM"); config.put("hmac-sha2-512-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA512ETM"); config.put("hmac-md5-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD5ETM"); config.put("hmac-md5-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD596ETM"); config.put("hmac-sha256-2@ssh.com", "com.jcraft.jsch.jce.HMACSHA2562SSHCOM"); config.put("hmac-sha224@ssh.com", "com.jcraft.jsch.jce.HMACSHA224SSHCOM"); config.put("hmac-sha256@ssh.com", "com.jcraft.jsch.jce.HMACSHA256SSHCOM"); config.put("hmac-sha384@ssh.com", "com.jcraft.jsch.jce.HMACSHA384SSHCOM"); config.put("hmac-sha512@ssh.com", "com.jcraft.jsch.jce.HMACSHA512SSHCOM"); config.put("sha-1", "com.jcraft.jsch.jce.SHA1"); config.put("sha-224", "com.jcraft.jsch.jce.SHA224"); config.put("sha-256", "com.jcraft.jsch.jce.SHA256"); config.put("sha-384", "com.jcraft.jsch.jce.SHA384"); config.put("sha-512", "com.jcraft.jsch.jce.SHA512"); config.put("md5", "com.jcraft.jsch.jce.MD5"); config.put("sha1", "com.jcraft.jsch.jce.SHA1"); config.put("sha224", "com.jcraft.jsch.jce.SHA224"); config.put("sha256", "com.jcraft.jsch.jce.SHA256"); config.put("sha384", "com.jcraft.jsch.jce.SHA384"); config.put("sha512", "com.jcraft.jsch.jce.SHA512"); config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA"); config.put("ssh-rsa", "com.jcraft.jsch.jce.SignatureRSA"); config.put("rsa-sha2-256", "com.jcraft.jsch.jce.SignatureRSASHA256"); config.put("rsa-sha2-512", "com.jcraft.jsch.jce.SignatureRSASHA512"); config.put("ssh-rsa-sha224@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA224SSHCOM"); config.put("ssh-rsa-sha256@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA256SSHCOM"); config.put("ssh-rsa-sha384@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA384SSHCOM"); config.put("ssh-rsa-sha512@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA512SSHCOM"); config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA"); config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA"); config.put("keypairgen.ecdsa", "com.jcraft.jsch.jce.KeyPairGenECDSA"); config.put("random", "com.jcraft.jsch.jce.Random"); config.put("hmac-ripemd160", "com.jcraft.jsch.bc.HMACRIPEMD160"); config.put("hmac-ripemd160@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160OpenSSH"); config.put("hmac-ripemd160-etm@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160ETM"); config.put("none", "com.jcraft.jsch.CipherNone"); config.put("aes128-gcm@openssh.com", "com.jcraft.jsch.jce.AES128GCM"); config.put("aes256-gcm@openssh.com", "com.jcraft.jsch.jce.AES256GCM"); config.put("aes128-cbc", "com.jcraft.jsch.jce.AES128CBC"); config.put("aes192-cbc", "com.jcraft.jsch.jce.AES192CBC"); config.put("aes256-cbc", "com.jcraft.jsch.jce.AES256CBC"); config.put("rijndael-cbc@lysator.liu.se", "com.jcraft.jsch.jce.AES256CBC"); config.put("chacha20-poly1305@openssh.com", "com.jcraft.jsch.bc.ChaCha20Poly1305"); config.put("cast128-cbc", "com.jcraft.jsch.bc.CAST128CBC"); config.put("cast128-ctr", "com.jcraft.jsch.bc.CAST128CTR"); config.put("twofish128-cbc", "com.jcraft.jsch.bc.Twofish128CBC"); config.put("twofish192-cbc", "com.jcraft.jsch.bc.Twofish192CBC"); config.put("twofish256-cbc", "com.jcraft.jsch.bc.Twofish256CBC"); config.put("twofish-cbc", "com.jcraft.jsch.bc.Twofish256CBC"); config.put("twofish128-ctr", "com.jcraft.jsch.bc.Twofish128CTR"); config.put("twofish192-ctr", "com.jcraft.jsch.bc.Twofish192CTR"); config.put("twofish256-ctr", "com.jcraft.jsch.bc.Twofish256CTR"); config.put("seed-cbc@ssh.com", "com.jcraft.jsch.bc.SEEDCBC"); config.put("aes128-ctr", "com.jcraft.jsch.jce.AES128CTR"); config.put("aes192-ctr", "com.jcraft.jsch.jce.AES192CTR"); config.put("aes256-ctr", "com.jcraft.jsch.jce.AES256CTR"); config.put("3des-ctr", "com.jcraft.jsch.jce.TripleDESCTR"); config.put("blowfish-ctr", "com.jcraft.jsch.jce.BlowfishCTR"); config.put("arcfour", "com.jcraft.jsch.jce.ARCFOUR"); config.put("arcfour128", "com.jcraft.jsch.jce.ARCFOUR128"); config.put("arcfour256", "com.jcraft.jsch.jce.ARCFOUR256"); config.put("userauth.none", "com.jcraft.jsch.UserAuthNone"); config.put("userauth.password", "com.jcraft.jsch.UserAuthPassword"); config.put("userauth.keyboard-interactive", "com.jcraft.jsch.UserAuthKeyboardInteractive"); config.put("userauth.publickey", "com.jcraft.jsch.UserAuthPublicKey"); config.put("userauth.gssapi-with-mic", "com.jcraft.jsch.UserAuthGSSAPIWithMIC"); config.put("gssapi-with-mic.krb5", "com.jcraft.jsch.jgss.GSSContextKrb5"); config.put("zlib", "com.jcraft.jsch.jzlib.Compression"); config.put("zlib@openssh.com", "com.jcraft.jsch.jzlib.Compression"); config.put("pbkdf", "com.jcraft.jsch.jce.PBKDF"); config.put("pbkdf2-hmac-sha1", "com.jcraft.jsch.jce.PBKDF2HMACSHA1"); config.put("pbkdf2-hmac-sha224", "com.jcraft.jsch.jce.PBKDF2HMACSHA224"); config.put("pbkdf2-hmac-sha256", "com.jcraft.jsch.jce.PBKDF2HMACSHA256"); config.put("pbkdf2-hmac-sha384", "com.jcraft.jsch.jce.PBKDF2HMACSHA384"); config.put("pbkdf2-hmac-sha512", "com.jcraft.jsch.jce.PBKDF2HMACSHA512"); config.put("pbkdf2-hmac-sha512-224", "com.jcraft.jsch.jce.PBKDF2HMACSHA512224"); config.put("pbkdf2-hmac-sha512-256", "com.jcraft.jsch.jce.PBKDF2HMACSHA512256"); config.put("bcrypt", "com.jcraft.jsch.jbcrypt.JBCrypt"); config.put("argon2", "com.jcraft.jsch.bc.Argon2"); config.put("scrypt", "com.jcraft.jsch.bc.SCrypt"); if (JavaVersion.getVersion() >= 11) { config.put("xdh", "com.jcraft.jsch.jce.XDH"); } else { config.put("xdh", "com.jcraft.jsch.bc.XDH"); } if (JavaVersion.getVersion() >= 15) { config.put("keypairgen.eddsa", "com.jcraft.jsch.jce.KeyPairGenEdDSA"); config.put("ssh-ed25519", "com.jcraft.jsch.jce.SignatureEd25519"); config.put("ssh-ed448", "com.jcraft.jsch.jce.SignatureEd448"); } else { config.put("keypairgen.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA"); config.put("ssh-ed25519", "com.jcraft.jsch.bc.SignatureEd25519"); config.put("ssh-ed448", "com.jcraft.jsch.bc.SignatureEd448"); } config.put("keypairgen_fromprivate.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA"); config.put("StrictHostKeyChecking", "ask"); config.put("HashKnownHosts", "no"); config.put("PreferredAuthentications", Util.getSystemProperty("jsch.preferred_authentications", "gssapi-with-mic,publickey,keyboard-interactive,password")); config.put("PubkeyAcceptedAlgorithms", Util.getSystemProperty("jsch.client_pubkey", "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256")); config.put("enable_pubkey_auth_query", Util.getSystemProperty("jsch.enable_pubkey_auth_query", "yes")); config.put("try_additional_pubkey_algorithms", Util.getSystemProperty("jsch.try_additional_pubkey_algorithms", "yes")); config.put("enable_auth_none", Util.getSystemProperty("jsch.enable_auth_none", "yes")); config.put("use_sftp_write_flush_workaround", Util.getSystemProperty("jsch.use_sftp_write_flush_workaround", "yes")); config.put("CheckCiphers", Util.getSystemProperty("jsch.check_ciphers", "chacha20-poly1305@openssh.com")); config.put("CheckMacs", Util.getSystemProperty("jsch.check_macs", "")); config.put("CheckKexes", Util.getSystemProperty("jsch.check_kexes", "sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,curve448-sha512")); config.put("CheckSignatures", Util.getSystemProperty("jsch.check_signatures", "ssh-ed25519,ssh-ed448")); config.put("FingerprintHash", Util.getSystemProperty("jsch.fingerprint_hash", "sha256")); config.put("MaxAuthTries", Util.getSystemProperty("jsch.max_auth_tries", "6")); config.put("ClearAllForwardings", "no"); } final InstanceLogger instLogger = new InstanceLogger(); private Vector sessionPool = new Vector<>(); private IdentityRepository defaultIdentityRepository = new LocalIdentityRepository(instLogger); private IdentityRepository identityRepository = defaultIdentityRepository; private ConfigRepository configRepository = null; /** * Sets the identityRepository, which will be referred in the public key * authentication. * * @param identityRepository if null is given, the default repository, which usually * refers to ~/.ssh/, will be used. * @see #getIdentityRepository() */ public synchronized void setIdentityRepository(IdentityRepository identityRepository) { if (identityRepository == null) { this.identityRepository = defaultIdentityRepository; } else { this.identityRepository = identityRepository; } } public synchronized IdentityRepository getIdentityRepository() { return this.identityRepository; } public ConfigRepository getConfigRepository() { return this.configRepository; } public void setConfigRepository(ConfigRepository configRepository) { this.configRepository = configRepository; } private HostKeyRepository known_hosts = null; static final Logger DEVNULL = new Logger() { @Override public boolean isEnabled(int level) { return false; } @Override public void log(int level, String message) {} }; static Logger logger = DEVNULL; public JSch() {} /** * Instantiates the Session object with host. The user name and port * number will be retrieved from ConfigRepository. If user name is not given, the system property * "user.name" will be referred. * * @param host hostname * @throws JSchException if username or host are invalid. * @return the instance of Session class. * @see #getSession(String username, String host, int port) * @see com.jcraft.jsch.Session * @see com.jcraft.jsch.ConfigRepository */ public Session getSession(String host) throws JSchException { return getSession(null, host, 22); } /** * Instantiates the Session object with username and host. * The TCP port 22 will be used in making the connection. Note that the TCP connection must not be * established until Session#connect(). * * @param username user name * @param host hostname * @throws JSchException if username or host are invalid. * @return the instance of Session class. * @see #getSession(String username, String host, int port) * @see com.jcraft.jsch.Session */ public Session getSession(String username, String host) throws JSchException { return getSession(username, host, 22); } /** * Instantiates the Session object with given username, * host and port. Note that the TCP connection must not be established * until Session#connect(). * * @param username user name * @param host hostname * @param port port number * @throws JSchException if username or host are invalid. * @return the instance of Session class. * @see #getSession(String username, String host, int port) * @see com.jcraft.jsch.Session */ public Session getSession(String username, String host, int port) throws JSchException { if (host == null) { throw new JSchException("host must not be null."); } Session s = new Session(this, username, host, port); return s; } protected void addSession(Session session) { synchronized (sessionPool) { sessionPool.addElement(session); } } protected boolean removeSession(Session session) { synchronized (sessionPool) { return sessionPool.remove(session); } } /** * Sets the hostkey repository. * * @param hkrepo * @see com.jcraft.jsch.HostKeyRepository * @see com.jcraft.jsch.KnownHosts */ public void setHostKeyRepository(HostKeyRepository hkrepo) { known_hosts = hkrepo; } /** * Sets the instance of KnownHosts, which refers to filename. * * @param filename filename of known_hosts file. * @throws JSchException if the given filename is invalid. * @see com.jcraft.jsch.KnownHosts */ public void setKnownHosts(String filename) throws JSchException { if (known_hosts == null) known_hosts = new KnownHosts(this); if (known_hosts instanceof KnownHosts) { synchronized (known_hosts) { ((KnownHosts) known_hosts).setKnownHosts(filename); } } } /** * Sets the instance of KnownHosts generated with stream. * * @param stream the instance of InputStream from known_hosts file. * @throws JSchException if an I/O error occurs. * @see com.jcraft.jsch.KnownHosts */ public void setKnownHosts(InputStream stream) throws JSchException { if (known_hosts == null) known_hosts = new KnownHosts(this); if (known_hosts instanceof KnownHosts) { synchronized (known_hosts) { ((KnownHosts) known_hosts).setKnownHosts(stream); } } } /** * Returns the current hostkey repository. By the default, this method will the instance of * KnownHosts. * * @return current hostkey repository. * @see com.jcraft.jsch.HostKeyRepository * @see com.jcraft.jsch.KnownHosts */ public HostKeyRepository getHostKeyRepository() { if (known_hosts == null) known_hosts = new KnownHosts(this); return known_hosts; } /** * Sets the private key, which will be referred in the public key authentication. * * @param prvkey filename of the private key. * @throws JSchException if prvkey is invalid. * @see #addIdentity(String prvkey, String passphrase) */ public void addIdentity(String prvkey) throws JSchException { addIdentity(prvkey, (byte[]) null); } /** * Sets the private key, which will be referred in the public key authentication. Before * registering it into identityRepository, it will be deciphered with passphrase. * * @param prvkey filename of the private key. * @param passphrase passphrase for prvkey. * @throws JSchException if passphrase is not right. * @see #addIdentity(String prvkey, byte[] passphrase) */ public void addIdentity(String prvkey, String passphrase) throws JSchException { byte[] _passphrase = null; if (passphrase != null) { _passphrase = Util.str2byte(passphrase); } addIdentity(prvkey, _passphrase); if (_passphrase != null) Util.bzero(_passphrase); } /** * Sets the private key, which will be referred in the public key authentication. Before * registering it into identityRepository, it will be deciphered with passphrase. * * @param prvkey filename of the private key. * @param passphrase passphrase for prvkey. * @throws JSchException if passphrase is not right. * @see #addIdentity(String prvkey, String pubkey, byte[] passphrase) */ public void addIdentity(String prvkey, byte[] passphrase) throws JSchException { Identity identity = IdentityFile.newInstance(prvkey, null, instLogger); addIdentity(identity, passphrase); } /** * Sets the private key, which will be referred in the public key authentication. Before * registering it into identityRepository, it will be deciphered with passphrase. * * @param prvkey filename of the private key. * @param pubkey filename of the public key. * @param passphrase passphrase for prvkey. * @throws JSchException if passphrase is not right. */ public void addIdentity(String prvkey, String pubkey, byte[] passphrase) throws JSchException { Identity identity = IdentityFile.newInstance(prvkey, pubkey, instLogger); addIdentity(identity, passphrase); } /** * Sets the private key, which will be referred in the public key authentication. Before * registering it into identityRepository, it will be deciphered with passphrase. * * @param name name of the identity to be used to retrieve it in the identityRepository. * @param prvkey private key in byte array. * @param pubkey public key in byte array. * @param passphrase passphrase for prvkey. */ public void addIdentity(String name, byte[] prvkey, byte[] pubkey, byte[] passphrase) throws JSchException { Identity identity = IdentityFile.newInstance(name, prvkey, pubkey, instLogger); addIdentity(identity, passphrase); } /** * Sets the private key, which will be referred in the public key authentication. Before * registering it into identityRepository, it will be deciphered with passphrase. * * @param identity private key. * @param passphrase passphrase for identity. * @throws JSchException if passphrase is not right. */ public void addIdentity(Identity identity, byte[] passphrase) throws JSchException { if (passphrase != null) { try { byte[] goo = new byte[passphrase.length]; System.arraycopy(passphrase, 0, goo, 0, passphrase.length); passphrase = goo; identity.setPassphrase(passphrase); } finally { Util.bzero(passphrase); } } if (identityRepository instanceof LocalIdentityRepository) { ((LocalIdentityRepository) identityRepository).add(identity); } else if (identity instanceof IdentityFile && !identity.isEncrypted()) { identityRepository.add(((IdentityFile) identity).getKeyPair().forSSHAgent()); } else { synchronized (this) { if (!(identityRepository instanceof IdentityRepositoryWrapper)) { setIdentityRepository(new IdentityRepositoryWrapper(identityRepository)); } } ((IdentityRepositoryWrapper) identityRepository).add(identity); } } /** * @deprecated use #removeIdentity(Identity identity) */ @Deprecated public void removeIdentity(String name) throws JSchException { Vector identities = identityRepository.getIdentities(); for (int i = 0; i < identities.size(); i++) { Identity identity = identities.elementAt(i); if (!identity.getName().equals(name)) continue; if (identityRepository instanceof LocalIdentityRepository) { ((LocalIdentityRepository) identityRepository).remove(identity); } else identityRepository.remove(identity.getPublicKeyBlob()); } } /** * Removes the identity from identityRepository. * * @param identity the indentity to be removed. * @throws JSchException if identity is invalid. */ public void removeIdentity(Identity identity) throws JSchException { identityRepository.remove(identity.getPublicKeyBlob()); } /** * Lists names of identities included in the identityRepository. * * @return names of identities * @throws JSchException if identityReposory has problems. */ public Vector getIdentityNames() throws JSchException { Vector foo = new Vector<>(); Vector identities = identityRepository.getIdentities(); for (int i = 0; i < identities.size(); i++) { Identity identity = identities.elementAt(i); foo.addElement(identity.getName()); } return foo; } /** * Removes all identities from identityRepository. * * @throws JSchException if identityReposory has problems. */ public void removeAllIdentity() throws JSchException { identityRepository.removeAll(); } /** * Returns the config value for the specified key. * * @param key key for the configuration. * @return config value */ public static String getConfig(String key) { synchronized (config) { if (key.equals("PubkeyAcceptedKeyTypes")) { key = "PubkeyAcceptedAlgorithms"; } return config.get(key); } } /** * Sets or Overrides the configuration. * * @param newconf configurations */ public static void setConfig(Hashtable newconf) { synchronized (config) { for (Enumeration e = newconf.keys(); e.hasMoreElements();) { String newkey = e.nextElement(); String key = (newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); config.put(key, newconf.get(newkey)); } } } /** * Sets or Overrides the configuration. * * @param key key for the configuration * @param value value for the configuration */ public static void setConfig(String key, String value) { if (key.equals("PubkeyAcceptedKeyTypes")) { config.put("PubkeyAcceptedAlgorithms", value); } else { config.put(key, value); } } /** * Sets the logger * * @param logger logger or null if no logging should take place * @see com.jcraft.jsch.Logger */ public static void setLogger(Logger logger) { if (logger == null) logger = DEVNULL; JSch.logger = logger; } /** * Returns a logger to be used for this particular instance of JSch * * @return The logger that is used by this instance. If no particular logger has been set, the * statically set logger is returned. */ public Logger getInstanceLogger() { return instLogger.getLogger(); } /** * Sets a logger to be used for this particular instance of JSch * * @param logger The logger to be used or null if the statically set logger should be * used */ public void setInstanceLogger(Logger logger) { instLogger.setLogger(logger); } /** * Returns the statically set logger, i.e. the logger being used by all JSch instances without * explicitly set logger. * * @return The logger */ public static Logger getLogger() { return logger; } static class InstanceLogger { private Logger logger; private InstanceLogger() {} Logger getLogger() { if (logger == null) { return JSch.logger; } return logger; } void setLogger(Logger logger) { this.logger = logger; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java000066400000000000000000000043161465436372100277040ustar00rootroot00000000000000package com.jcraft.jsch; import java.util.Locale; /** * Extension of {@link JSchException} to indicate when a connection fails during algorithm * negotiation. */ public class JSchAlgoNegoFailException extends JSchException { private static final long serialVersionUID = -1L; private final String algorithmName; private final String jschProposal; private final String serverProposal; JSchAlgoNegoFailException(int algorithmIndex, String jschProposal, String serverProposal) { super(failString(algorithmIndex, jschProposal, serverProposal)); algorithmName = algorithmNameFromIndex(algorithmIndex); this.jschProposal = jschProposal; this.serverProposal = serverProposal; } /** Get the algorithm name. */ public String getAlgorithmName() { return algorithmName; } /** Get the JSch algorithm proposal. */ public String getJSchProposal() { return jschProposal; } /** Get the server algorithm proposal. */ public String getServerProposal() { return serverProposal; } private static String failString(int algorithmIndex, String jschProposal, String serverProposal) { return String.format(Locale.ROOT, "Algorithm negotiation fail: algorithmName=\"%s\" jschProposal=\"%s\" serverProposal=\"%s\"", algorithmNameFromIndex(algorithmIndex), jschProposal, serverProposal); } private static String algorithmNameFromIndex(int algorithmIndex) { switch (algorithmIndex) { case KeyExchange.PROPOSAL_KEX_ALGS: return "kex"; case KeyExchange.PROPOSAL_SERVER_HOST_KEY_ALGS: return "server_host_key"; case KeyExchange.PROPOSAL_ENC_ALGS_CTOS: return "cipher.c2s"; case KeyExchange.PROPOSAL_ENC_ALGS_STOC: return "cipher.s2c"; case KeyExchange.PROPOSAL_MAC_ALGS_CTOS: return "mac.c2s"; case KeyExchange.PROPOSAL_MAC_ALGS_STOC: return "mac.s2c"; case KeyExchange.PROPOSAL_COMP_ALGS_CTOS: return "compression.c2s"; case KeyExchange.PROPOSAL_COMP_ALGS_STOC: return "compression.s2c"; case KeyExchange.PROPOSAL_LANG_CTOS: return "lang.c2s"; case KeyExchange.PROPOSAL_LANG_STOC: return "lang.s2c"; default: return ""; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java000066400000000000000000000034401465436372100274210ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class JSchAuthCancelException extends JSchException { private static final long serialVersionUID = -1L; String method; JSchAuthCancelException() { super(); } JSchAuthCancelException(String s) { super(s); this.method = s; } public String getMethod() { return method; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchChangedHostKeyException.java000066400000000000000000000033361465436372100302560ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchChangedHostKeyException extends JSchHostKeyException { private static final long serialVersionUID = -1L; JSchChangedHostKeyException() { super(); } JSchChangedHostKeyException(String s) { super(s); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchException.java000066400000000000000000000033751465436372100255000ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchException extends Exception { private static final long serialVersionUID = -1L; public JSchException() { super(); } public JSchException(String s) { super(s); } public JSchException(String s, Throwable e) { super(s, e); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchHostKeyException.java000066400000000000000000000033131465436372100267770ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public abstract class JSchHostKeyException extends JSchException { private static final long serialVersionUID = -1L; JSchHostKeyException() { super(); } JSchHostKeyException(String s) { super(s); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java000066400000000000000000000034651465436372100276370ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class JSchPartialAuthException extends JSchException { private static final long serialVersionUID = -1L; String methods; public JSchPartialAuthException() { super(); } public JSchPartialAuthException(String s) { super(s); this.methods = s; } public String getMethods() { return methods; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchProxyException.java000066400000000000000000000033431465436372100265350ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchProxyException extends JSchException { private static final long serialVersionUID = -1L; public JSchProxyException(String s) { super(s); } public JSchProxyException(String s, Throwable e) { super(s, e); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchRevokedHostKeyException.java000066400000000000000000000033361465436372100303240ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchRevokedHostKeyException extends JSchHostKeyException { private static final long serialVersionUID = -1L; JSchRevokedHostKeyException() { super(); } JSchRevokedHostKeyException(String s) { super(s); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchSessionDisconnectException.java000066400000000000000000000042261465436372100310520ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchSessionDisconnectException extends JSchException { private static final long serialVersionUID = -1L; // RFC 4253 11.1. private final int reasonCode; // RFC 4250 4.2.2. private final String description; private final String languageTag; JSchSessionDisconnectException(String s, int reasonCode, String description, String languageTag) { super(s); this.reasonCode = reasonCode; this.description = description; this.languageTag = languageTag; } public int getReasonCode() { return reasonCode; } public String getDescription() { return description; } public String getLanguageTag() { return languageTag; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchStrictKexException.java000066400000000000000000000033101465436372100273260ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchStrictKexException extends JSchException { private static final long serialVersionUID = -1L; JSchStrictKexException() { super(); } JSchStrictKexException(String s) { super(s); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JSchUnknownHostKeyException.java000066400000000000000000000033361465436372100303640ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class JSchUnknownHostKeyException extends JSchHostKeyException { private static final long serialVersionUID = -1L; JSchUnknownHostKeyException() { super(); } JSchUnknownHostKeyException(String s) { super(s); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JUnixSocketFactory.java000066400000000000000000000053641465436372100265300ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.file.Path; import org.newsclub.net.unix.AFUNIXServerSocketChannel; import org.newsclub.net.unix.AFUNIXSocketAddress; import org.newsclub.net.unix.AFUNIXSocketChannel; public class JUnixSocketFactory implements USocketFactory { @SuppressWarnings("try") public JUnixSocketFactory() throws AgentProxyException { // Check to confirm that junixsocket library is available try (AFUNIXSocketChannel foo = AFUNIXSocketChannel.open()) { } catch (IOException | NoClassDefFoundError e) { throw new AgentProxyException("junixsocket library unavailable", e); } } @Override public SocketChannel connect(Path path) throws IOException { AFUNIXSocketAddress sockAddr = AFUNIXSocketAddress.of(path); AFUNIXSocketChannel sock = AFUNIXSocketChannel.open(); sock.configureBlocking(true); sock.connect(sockAddr); return sock; } @Override public ServerSocketChannel bind(Path path) throws IOException { AFUNIXSocketAddress sockAddr = AFUNIXSocketAddress.of(path); AFUNIXServerSocketChannel sock = AFUNIXServerSocketChannel.open(); sock.configureBlocking(true); sock.bind(sockAddr); return sock; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JavaVersion.java000066400000000000000000000001451465436372100252110ustar00rootroot00000000000000package com.jcraft.jsch; final class JavaVersion { static int getVersion() { return 8; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JplLogger.java000066400000000000000000000011511465436372100246450ustar00rootroot00000000000000package com.jcraft.jsch; public class JplLogger implements com.jcraft.jsch.Logger { public JplLogger() { throw new UnsupportedOperationException("JplLogger requires Java9+."); } @Override public boolean isEnabled(int level) { throw new UnsupportedOperationException("JplLogger requires Java9+."); } @Override public void log(int level, String message) { throw new UnsupportedOperationException("JplLogger requires Java9+."); } @Override public void log(int level, String message, Throwable cause) { throw new UnsupportedOperationException("JplLogger requires Java9+."); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/JulLogger.java000066400000000000000000000021201465436372100246470ustar00rootroot00000000000000package com.jcraft.jsch; import java.util.logging.Level; import java.util.logging.Logger; public class JulLogger implements com.jcraft.jsch.Logger { private static final Logger logger = Logger.getLogger(JSch.class.getName()); public JulLogger() {} @Override public boolean isEnabled(int level) { return logger.isLoggable(getLevel(level)); } @Override public void log(int level, String message) { log(level, message, null); } @Override public void log(int level, String message, Throwable cause) { if (cause == null) { logger.log(getLevel(level), message); return; } logger.log(getLevel(level), message, cause); } static Level getLevel(int level) { switch (level) { case com.jcraft.jsch.Logger.DEBUG: return Level.FINE; case com.jcraft.jsch.Logger.INFO: return Level.INFO; case com.jcraft.jsch.Logger.WARN: return Level.WARNING; case com.jcraft.jsch.Logger.ERROR: case com.jcraft.jsch.Logger.FATAL: return Level.SEVERE; default: return Level.FINER; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KDF.java000066400000000000000000000030601465436372100233650ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface KDF { byte[] getKey(byte[] pass, int size); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KEM.java000066400000000000000000000032211465436372100233740ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface KEM { void init() throws Exception; byte[] getPublicKey() throws Exception; byte[] decapsulate(byte[] encapsulation) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyExchange.java000066400000000000000000000402701465436372100251600ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Locale; public abstract class KeyExchange { static final int PROPOSAL_KEX_ALGS = 0; static final int PROPOSAL_SERVER_HOST_KEY_ALGS = 1; static final int PROPOSAL_ENC_ALGS_CTOS = 2; static final int PROPOSAL_ENC_ALGS_STOC = 3; static final int PROPOSAL_MAC_ALGS_CTOS = 4; static final int PROPOSAL_MAC_ALGS_STOC = 5; static final int PROPOSAL_COMP_ALGS_CTOS = 6; static final int PROPOSAL_COMP_ALGS_STOC = 7; static final int PROPOSAL_LANG_CTOS = 8; static final int PROPOSAL_LANG_STOC = 9; static final int PROPOSAL_MAX = 10; static final String[] PROPOSAL_NAMES = {"KEX algorithms", "host key algorithms", "ciphers c2s", "ciphers s2c", "MACs c2s", "MACs s2c", "compression c2s", "compression s2c", "languages c2s", "languages s2c"}; // static String kex_algs="diffie-hellman-group-exchange-sha1"+ // ",diffie-hellman-group1-sha1"; // static String kex="diffie-hellman-group-exchange-sha1"; static String kex = "diffie-hellman-group1-sha1"; static String server_host_key = "ssh-rsa,ssh-dss"; static String enc_c2s = "blowfish-cbc"; static String enc_s2c = "blowfish-cbc"; static String mac_c2s = "hmac-md5"; // hmac-md5,hmac-sha1,hmac-ripemd160, // hmac-sha1-96,hmac-md5-96 static String mac_s2c = "hmac-md5"; // static String comp_c2s="none"; // zlib // static String comp_s2c="none"; static String lang_c2s = ""; static String lang_s2c = ""; public static final int STATE_END = 0; protected Session session = null; protected HASH sha = null; protected byte[] K = null; protected byte[] H = null; protected byte[] K_S = null; public abstract void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception; void doInit(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { this.session = session; init(session, V_S, V_C, I_S, I_C); } public abstract boolean next(Buffer buf) throws Exception; public abstract int getState(); protected final int RSA = 0; protected final int DSS = 1; protected final int ECDSA = 2; protected final int EDDSA = 3; private int type = 0; private String key_alg_name = ""; public String getKeyType() { if (type == DSS) return "DSA"; if (type == RSA) return "RSA"; if (type == EDDSA) return "EDDSA"; return "ECDSA"; } public String getKeyAlgorithName() { return key_alg_name; } protected static String[] guess(Session session, byte[] I_S, byte[] I_C) throws Exception { String[] guess = new String[PROPOSAL_MAX]; Buffer sb = new Buffer(I_S); sb.setOffSet(17); Buffer cb = new Buffer(I_C); cb.setOffSet(17); if (session.getLogger().isEnabled(Logger.INFO)) { for (int i = 0; i < PROPOSAL_MAX; i++) { session.getLogger().log(Logger.INFO, "server proposal: " + PROPOSAL_NAMES[i] + ": " + Util.byte2str(sb.getString())); } for (int i = 0; i < PROPOSAL_MAX; i++) { session.getLogger().log(Logger.INFO, "client proposal: " + PROPOSAL_NAMES[i] + ": " + Util.byte2str(cb.getString())); } sb.setOffSet(17); cb.setOffSet(17); } for (int i = 0; i < PROPOSAL_MAX; i++) { byte[] sp = sb.getString(); // server proposal byte[] cp = cb.getString(); // client proposal int j = 0; int k = 0; loop: while (j < cp.length) { while (j < cp.length && cp[j] != ',') j++; if (k == j) throw new JSchAlgoNegoFailException(i, Util.byte2str(cp), Util.byte2str(sp)); String algorithm = Util.byte2str(cp, k, j - k); int l = 0; int m = 0; while (l < sp.length) { while (l < sp.length && sp[l] != ',') l++; if (m == l) throw new JSchAlgoNegoFailException(i, Util.byte2str(cp), Util.byte2str(sp)); if (algorithm.equals(Util.byte2str(sp, m, l - m))) { guess[i] = algorithm; break loop; } l++; m = l; } j++; k = j; } if (j == 0) { guess[i] = ""; } else if (guess[i] == null) { throw new JSchAlgoNegoFailException(i, Util.byte2str(cp), Util.byte2str(sp)); } } boolean _s2cAEAD = false; boolean _c2sAEAD = false; try { Class _s2cclazz = Class.forName(session.getConfig(guess[PROPOSAL_ENC_ALGS_STOC])).asSubclass(Cipher.class); Cipher _s2ccipher = _s2cclazz.getDeclaredConstructor().newInstance(); _s2cAEAD = _s2ccipher.isAEAD(); if (_s2cAEAD) { guess[PROPOSAL_MAC_ALGS_STOC] = null; } Class _c2sclazz = Class.forName(session.getConfig(guess[PROPOSAL_ENC_ALGS_CTOS])).asSubclass(Cipher.class); Cipher _c2scipher = _c2sclazz.getDeclaredConstructor().newInstance(); _c2sAEAD = _c2scipher.isAEAD(); if (_c2sAEAD) { guess[PROPOSAL_MAC_ALGS_CTOS] = null; } } catch (Exception | NoClassDefFoundError e) { throw new JSchException(e.toString(), e); } if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "kex: algorithm: " + guess[PROPOSAL_KEX_ALGS]); session.getLogger().log(Logger.INFO, "kex: host key algorithm: " + guess[PROPOSAL_SERVER_HOST_KEY_ALGS]); session.getLogger().log(Logger.INFO, "kex: server->client" + " cipher: " + guess[PROPOSAL_ENC_ALGS_STOC] + " MAC: " + (_s2cAEAD ? ("") : (guess[PROPOSAL_MAC_ALGS_STOC])) + " compression: " + guess[PROPOSAL_COMP_ALGS_STOC]); session.getLogger().log(Logger.INFO, "kex: client->server" + " cipher: " + guess[PROPOSAL_ENC_ALGS_CTOS] + " MAC: " + (_c2sAEAD ? ("") : (guess[PROPOSAL_MAC_ALGS_CTOS])) + " compression: " + guess[PROPOSAL_COMP_ALGS_CTOS]); } return guess; } public String getFingerPrint() { HASH hash = null; try { String _c = session.getConfig("FingerprintHash").toLowerCase(Locale.ROOT); Class c = Class.forName(session.getConfig(_c)).asSubclass(HASH.class); hash = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "getFingerPrint: " + e.getMessage(), e); } } return Util.getFingerPrint(hash, getHostKey(), true, false); } byte[] getK() { return K; } void clearK() { Util.bzero(K); K = null; } byte[] getH() { return H; } HASH getHash() { return sha; } byte[] getHostKey() { return K_S; } /* * It seems JCE included in Oracle's Java7u6(and later) has suddenly changed its behavior. The * secrete generated by KeyAgreement#generateSecret() may start with 0, even if it is a positive * value. See https://bugs.openjdk.org/browse/JDK-7146728. */ protected byte[] normalize(byte[] secret) { // This should be a timing safe version of the following: // if (secret.length > 1 && secret[0] == 0 && (secret[1] & 0x80) == 0) { // byte[] tmp = new byte[secret.length - 1]; // System.arraycopy(secret, 1, tmp, 0, tmp.length); // Util.bzero(secret); // return normalize(tmp); // } else { // return secret; // } int len = secret.length; if (len < 2) { return secret; } // secret[0] == 0 int a = 0; int s0 = secret[0] & 0xff; for (int i = 0; i < 8; i++) { int j = s0 >>> i; j &= 0x1; a |= j; } a ^= 0x1; // (secret[1..n] & 0x80) == 0 && secret[1..n] != 0 int offset = 0; for (int i = 1; i < len; i++) { int j = secret[i] & 0x80; j >>>= 7; j ^= 0x1; a &= j; offset += a; j = secret[i] & 0x7f; for (int k = 0; k < 7; k++) { int l = j >>> k; l &= 0x1; l ^= 0x1; a &= l; } } len -= offset; // Try to remain timing safe by performing an allocation + copy for leading bytes removed byte[] foo = new byte[len]; byte[] bar = new byte[offset]; System.arraycopy(secret, 0, bar, 0, offset); System.arraycopy(secret, offset, foo, 0, len); Util.bzero(secret); return foo; } protected boolean verify(String alg, byte[] K_S, int index, byte[] sig_of_H) throws Exception { int i, j; i = index; boolean result = false; if (alg.equals("ssh-rsa")) { byte[] tmp; byte[] ee; byte[] n; type = RSA; key_alg_name = alg; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; ee = tmp; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; n = tmp; SignatureRSA sig = null; Buffer buf = new Buffer(sig_of_H); String foo = Util.byte2str(buf.getString()); try { Class c = Class.forName(session.getConfig(foo)).asSubclass(SignatureRSA.class); sig = c.getDeclaredConstructor().newInstance(); sig.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } sig.setPubKey(ee, n); sig.update(H); result = sig.verify(sig_of_H); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "ssh_rsa_verify: " + foo + " signature " + result); } } else if (alg.equals("ssh-dss")) { byte[] q = null; byte[] tmp; byte[] p; byte[] g; byte[] f; type = DSS; key_alg_name = alg; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; p = tmp; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; q = tmp; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; g = tmp; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; f = tmp; SignatureDSA sig = null; try { Class c = Class.forName(session.getConfig("signature.dss")).asSubclass(SignatureDSA.class); sig = c.getDeclaredConstructor().newInstance(); sig.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } sig.setPubKey(f, p, q, g); sig.update(H); result = sig.verify(sig_of_H); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "ssh_dss_verify: signature " + result); } } else if (alg.equals("ecdsa-sha2-nistp256") || alg.equals("ecdsa-sha2-nistp384") || alg.equals("ecdsa-sha2-nistp521")) { byte[] tmp; byte[] r; byte[] s; // RFC 5656, type = ECDSA; key_alg_name = alg; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); i++; tmp = new byte[(j - 1) / 2]; System.arraycopy(K_S, i, tmp, 0, tmp.length); i += (j - 1) / 2; r = tmp; tmp = new byte[(j - 1) / 2]; System.arraycopy(K_S, i, tmp, 0, tmp.length); i += (j - 1) / 2; s = tmp; SignatureECDSA sig = null; try { Class c = Class.forName(session.getConfig(alg)).asSubclass(SignatureECDSA.class); sig = c.getDeclaredConstructor().newInstance(); sig.init(); } catch (Exception e) { throw new JSchException(e.toString(), e); } sig.setPubKey(r, s); sig.update(H); result = sig.verify(sig_of_H); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "ssh_ecdsa_verify: " + alg + " signature " + result); } } else if (alg.equals("ssh-ed25519") || alg.equals("ssh-ed448")) { byte[] tmp; // RFC 8709, type = EDDSA; key_alg_name = alg; j = ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) | ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff); tmp = new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i += j; SignatureEdDSA sig = null; try { Class c = Class.forName(session.getConfig(alg)).asSubclass(SignatureEdDSA.class); sig = c.getDeclaredConstructor().newInstance(); sig.init(); } catch (Exception | NoClassDefFoundError e) { throw new JSchException(e.toString(), e); } sig.setPubKey(tmp); sig.update(H); result = sig.verify(sig_of_H); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "ssh_eddsa_verify: " + alg + " signature " + result); } } else { if (session.getLogger().isEnabled(Logger.ERROR)) { session.getLogger().log(Logger.ERROR, "unknown alg: " + alg); } } return result; } protected byte[] encodeAsMPInt(byte[] raw) { int i = (raw[0] & 0x80) >>> 7; int len = raw.length + i; byte[] foo = new byte[len + 4]; // Try to remain timing safe by performing an extra allocation when i == 0 byte[] bar = new byte[i ^ 0x1]; foo[0] = (byte) (len >>> 24); foo[1] = (byte) (len >>> 16); foo[2] = (byte) (len >>> 8); foo[3] = (byte) (len); System.arraycopy(raw, 0, foo, 4 + i, len - i); Util.bzero(raw); return foo; } protected byte[] encodeAsString(byte[] raw) { int len = raw.length; byte[] foo = new byte[len + 4]; foo[0] = (byte) (len >>> 24); foo[1] = (byte) (len >>> 16); foo[2] = (byte) (len >>> 8); foo[3] = (byte) (len); System.arraycopy(raw, 0, foo, 4, len); Util.bzero(raw); return foo; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPair.java000066400000000000000000001432401465436372100243320ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public abstract class KeyPair { /** DEFERRED should not be be used. */ public static final int DEFERRED = -1; public static final int ERROR = 0; public static final int DSA = 1; public static final int RSA = 2; public static final int ECDSA = 3; public static final int UNKNOWN = 4; public static final int ED25519 = 5; public static final int ED448 = 6; static final int VENDOR_OPENSSH = 0; static final int VENDOR_FSECURE = 1; static final int VENDOR_PUTTY = 2; static final int VENDOR_PKCS8 = 3; static final int VENDOR_OPENSSH_V1 = 4; static final int VENDOR_PUTTY_V3 = 5; int vendor = VENDOR_OPENSSH; private static final byte[] AUTH_MAGIC = Util.str2byte("openssh-key-v1\0"); private static final byte[] cr = Util.str2byte("\n"); public static KeyPair genKeyPair(JSch jsch, int type) throws JSchException { return genKeyPair(jsch, type, 1024); } public static KeyPair genKeyPair(JSch jsch, int type, int key_size) throws JSchException { KeyPair kpair = null; if (type == DSA) { kpair = new KeyPairDSA(jsch.instLogger); } else if (type == RSA) { kpair = new KeyPairRSA(jsch.instLogger); } else if (type == ECDSA) { kpair = new KeyPairECDSA(jsch.instLogger); } else if (type == ED25519) { kpair = new KeyPairEd25519(jsch.instLogger); } else if (type == ED448) { kpair = new KeyPairEd448(jsch.instLogger); } if (kpair != null) { kpair.generate(key_size); } return kpair; } abstract void generate(int key_size) throws JSchException; abstract byte[] getBegin(); abstract byte[] getEnd(); public abstract int getKeySize(); public abstract byte[] getSignature(byte[] data); public abstract byte[] getSignature(byte[] data, String alg); public abstract Signature getVerifier(); public abstract Signature getVerifier(String alg); public abstract byte[] forSSHAgent() throws JSchException; public String getPublicKeyComment() { return publicKeyComment; } public void setPublicKeyComment(String publicKeyComment) { this.publicKeyComment = publicKeyComment; } protected String publicKeyComment = "no comment"; JSch.InstanceLogger instLogger; protected Cipher cipher; private KDF kdf; private HASH sha1; private HASH hash; private Random random; private byte[] passphrase; KeyPair(JSch.InstanceLogger instLogger) { this.instLogger = instLogger; } static byte[][] header = {Util.str2byte("Proc-Type: 4,ENCRYPTED"), Util.str2byte("DEK-Info: DES-EDE3-CBC,")}; abstract byte[] getPrivateKey(); /** * Writes the plain private key to the given output stream. * * @param out output stream * @see #writePrivateKey(OutputStream out, byte[] passphrase) */ public void writePrivateKey(OutputStream out) { this.writePrivateKey(out, null); } /** * Writes the cyphered private key to the given output stream. * * @param out output stream * @param passphrase a passphrase to encrypt the private key */ public void writePrivateKey(OutputStream out, byte[] passphrase) { if (passphrase == null) passphrase = this.passphrase; byte[] plain = getPrivateKey(); byte[][] _iv = new byte[1][]; byte[] encoded = encrypt(plain, _iv, passphrase); if (encoded != plain) Util.bzero(plain); byte[] iv = _iv[0]; byte[] prv = Util.toBase64(encoded, 0, encoded.length, true); try { out.write(getBegin()); out.write(cr); if (passphrase != null) { out.write(header[0]); out.write(cr); out.write(header[1]); for (int i = 0; i < iv.length; i++) { out.write(b2a((byte) ((iv[i] >>> 4) & 0x0f))); out.write(b2a((byte) (iv[i] & 0x0f))); } out.write(cr); out.write(cr); } int i = 0; while (i < prv.length) { if (i + 64 < prv.length) { out.write(prv, i, 64); out.write(cr); i += 64; continue; } out.write(prv, i, prv.length - i); out.write(cr); break; } out.write(getEnd()); out.write(cr); // out.close(); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to write private key", e); } } } private static byte[] space = Util.str2byte(" "); abstract byte[] getKeyTypeName(); public abstract int getKeyType(); /** * Wrapper to provide the String representation of {@code #getKeyTypeName()}. * * @return the standard SSH key type string */ public String getKeyTypeString() { return Util.byte2str(getKeyTypeName()); } /** * Returns the blob of the public key. * * @return blob of the public key */ public byte[] getPublicKeyBlob() { // TODO JSchException should be thrown // if(publickeyblob == null) // throw new JSchException("public-key blob is not available"); return publickeyblob; } /** * Writes the public key with the specified comment to the output stream. * * @param out output stream * @param comment comment */ public void writePublicKey(OutputStream out, String comment) { byte[] pubblob = getPublicKeyBlob(); byte[] pub = Util.toBase64(pubblob, 0, pubblob.length, true); try { out.write(getKeyTypeName()); out.write(space); out.write(pub, 0, pub.length); out.write(space); out.write(Util.str2byte(comment)); out.write(cr); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to write public key", e); } } } /** * Writes the public key with the specified comment to the file. * * @param name file name * @param comment comment * @see #writePublicKey(OutputStream out, String comment) */ public void writePublicKey(String name, String comment) throws FileNotFoundException, IOException { try (OutputStream fos = new FileOutputStream(name)) { writePublicKey(fos, comment); } } /** * Writes the public key with the specified comment to the output stream in the format defined in * http://www.ietf.org/rfc/rfc4716.txt * * @param out output stream * @param comment comment */ public void writeSECSHPublicKey(OutputStream out, String comment) { byte[] pubblob = getPublicKeyBlob(); byte[] pub = Util.toBase64(pubblob, 0, pubblob.length, true); try { out.write(Util.str2byte("---- BEGIN SSH2 PUBLIC KEY ----")); out.write(cr); out.write(Util.str2byte("Comment: \"" + comment + "\"")); out.write(cr); int index = 0; while (index < pub.length) { int len = 70; if ((pub.length - index) < len) len = pub.length - index; out.write(pub, index, len); out.write(cr); index += len; } out.write(Util.str2byte("---- END SSH2 PUBLIC KEY ----")); out.write(cr); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to write public key", e); } } } /** * Writes the public key with the specified comment to the output stream in the format defined in * http://www.ietf.org/rfc/rfc4716.txt * * @param name file name * @param comment comment * @see #writeSECSHPublicKey(OutputStream out, String comment) */ public void writeSECSHPublicKey(String name, String comment) throws FileNotFoundException, IOException { try (OutputStream fos = new FileOutputStream(name)) { writeSECSHPublicKey(fos, comment); } } /** * Writes the plain private key to the file. * * @param name file name * @see #writePrivateKey(String name, byte[] passphrase) */ public void writePrivateKey(String name) throws FileNotFoundException, IOException { this.writePrivateKey(name, null); } /** * Writes the cyphered private key to the file. * * @param name file name * @param passphrase a passphrase to encrypt the private key * @see #writePrivateKey(OutputStream out, byte[] passphrase) */ public void writePrivateKey(String name, byte[] passphrase) throws FileNotFoundException, IOException { try (OutputStream fos = new FileOutputStream(name)) { writePrivateKey(fos, passphrase); } } /** * Returns the finger-print of the public key. * * @return finger print */ public String getFingerPrint() { if (hash == null) hash = genHash(); byte[] kblob = getPublicKeyBlob(); if (kblob == null) return null; return Util.getFingerPrint(hash, kblob, false, true); } private byte[] encrypt(byte[] plain, byte[][] _iv, byte[] passphrase) { if (passphrase == null) return plain; if (cipher == null) cipher = genCipher(); byte[] iv = _iv[0] = new byte[cipher.getIVSize()]; if (random == null) random = genRandom(); random.fill(iv, 0, iv.length); byte[] key = genKey(passphrase, iv); byte[] encoded = plain; // PKCS#5Padding { // int bsize=cipher.getBlockSize(); int bsize = cipher.getIVSize(); byte[] foo = new byte[(encoded.length / bsize + 1) * bsize]; System.arraycopy(encoded, 0, foo, 0, encoded.length); int padding = bsize - encoded.length % bsize; for (int i = foo.length - 1; (foo.length - padding) <= i; i--) { foo[i] = (byte) padding; } encoded = foo; } try { cipher.init(Cipher.ENCRYPT_MODE, key, iv); cipher.update(encoded, 0, encoded.length, encoded, 0); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to encrypt key", e); } } Util.bzero(key); return encoded; } abstract boolean parse(byte[] data); private byte[] decrypt(byte[] data, byte[] passphrase, byte[] iv) { try { byte[] key = genKey(passphrase, iv); cipher.init(Cipher.DECRYPT_MODE, key, iv); Util.bzero(key); byte[] plain = new byte[data.length]; cipher.update(data, 0, data.length, plain, 0); return plain; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to decrypt key", e); } } return null; } int writeSEQUENCE(byte[] buf, int index, int len) { buf[index++] = 0x30; index = writeLength(buf, index, len); return index; } int writeINTEGER(byte[] buf, int index, byte[] data) { buf[index++] = 0x02; index = writeLength(buf, index, data.length); System.arraycopy(data, 0, buf, index, data.length); index += data.length; return index; } int writeOCTETSTRING(byte[] buf, int index, byte[] data) { buf[index++] = 0x04; index = writeLength(buf, index, data.length); System.arraycopy(data, 0, buf, index, data.length); index += data.length; return index; } int writeDATA(byte[] buf, byte n, int index, byte[] data) { buf[index++] = n; index = writeLength(buf, index, data.length); System.arraycopy(data, 0, buf, index, data.length); index += data.length; return index; } int countLength(int len) { int i = 1; if (len <= 0x7f) return i; while (len > 0) { len >>>= 8; i++; } return i; } int writeLength(byte[] data, int index, int len) { int i = countLength(len) - 1; if (i == 0) { data[index++] = (byte) len; return index; } data[index++] = (byte) (0x80 | i); int j = index + i; while (i > 0) { data[index + i - 1] = (byte) (len & 0xff); len >>>= 8; i--; } return j; } private Random genRandom() { if (random == null) { try { Class c = Class.forName(JSch.getConfig("random")).asSubclass(Random.class); random = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create random", e); } } } return random; } private HASH genHash() { try { Class c = Class.forName(JSch.getConfig("md5")).asSubclass(HASH.class); hash = c.getDeclaredConstructor().newInstance(); hash.init(); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create hash", e); } } return hash; } private Cipher genCipher() { try { Class c = Class.forName(JSch.getConfig("3des-cbc")).asSubclass(Cipher.class); cipher = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create cipher", e); } } return cipher; } /* * hash is MD5 h(0) <- hash(passphrase, iv); h(n) <- hash(h(n-1), passphrase, iv); key <- * (h(0),...,h(n))[0,..,key.length]; */ synchronized byte[] genKey(byte[] passphrase, byte[] iv) { if (cipher == null) cipher = genCipher(); if (hash == null) hash = genHash(); byte[] key = new byte[cipher.getBlockSize()]; int hsize = hash.getBlockSize(); byte[] hn = new byte[key.length / hsize * hsize + (key.length % hsize == 0 ? 0 : hsize)]; try { byte[] tmp = null; if (vendor == VENDOR_OPENSSH) { for (int index = 0; index + hsize <= hn.length;) { if (tmp != null) { hash.update(tmp, 0, tmp.length); } hash.update(passphrase, 0, passphrase.length); hash.update(iv, 0, iv.length > 8 ? 8 : iv.length); tmp = hash.digest(); System.arraycopy(tmp, 0, hn, index, tmp.length); index += tmp.length; } System.arraycopy(hn, 0, key, 0, key.length); } else if (vendor == VENDOR_OPENSSH_V1) { tmp = kdf.getKey(passphrase, cipher.getBlockSize() + cipher.getIVSize()); System.arraycopy(tmp, 0, key, 0, key.length); System.arraycopy(tmp, key.length, iv, 0, iv.length); Util.bzero(tmp); } else if (vendor == VENDOR_FSECURE) { for (int index = 0; index + hsize <= hn.length;) { if (tmp != null) { hash.update(tmp, 0, tmp.length); } hash.update(passphrase, 0, passphrase.length); tmp = hash.digest(); System.arraycopy(tmp, 0, hn, index, tmp.length); index += tmp.length; } System.arraycopy(hn, 0, key, 0, key.length); } else if (vendor == VENDOR_PUTTY) { byte[] i = new byte[4]; sha1.update(i, 0, i.length); sha1.update(passphrase, 0, passphrase.length); tmp = sha1.digest(); System.arraycopy(tmp, 0, key, 0, tmp.length); Util.bzero(tmp); i[3] = (byte) 1; sha1.update(i, 0, i.length); sha1.update(passphrase, 0, passphrase.length); tmp = sha1.digest(); System.arraycopy(tmp, 0, key, tmp.length, key.length - tmp.length); Util.bzero(tmp); } else if (vendor == VENDOR_PUTTY_V3) { tmp = kdf.getKey(passphrase, cipher.getBlockSize() + cipher.getIVSize() + 32); System.arraycopy(tmp, 0, key, 0, key.length); System.arraycopy(tmp, key.length, iv, 0, iv.length); Util.bzero(tmp); } } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to generate key from passphrase", e); } } return key; } /** * @deprecated use #writePrivateKey(OutputStream out, byte[] passphrase) */ @Deprecated public void setPassphrase(String passphrase) { if (passphrase == null || passphrase.length() == 0) { setPassphrase((byte[]) null); } else { setPassphrase(Util.str2byte(passphrase)); } } /** * @deprecated use #writePrivateKey(String name, byte[] passphrase) */ @Deprecated public void setPassphrase(byte[] passphrase) { if (passphrase != null && passphrase.length == 0) passphrase = null; this.passphrase = passphrase; } protected boolean encrypted = false; protected byte[] data = null; private byte[] iv = null; private byte[] publickeyblob = null; public boolean isEncrypted() { return encrypted; } public boolean decrypt(String _passphrase) { if (_passphrase == null || _passphrase.length() == 0) { return !encrypted; } return decrypt(Util.str2byte(_passphrase)); } public boolean decrypt(byte[] _passphrase) { if (!encrypted) { return true; } if (_passphrase == null) { return !encrypted; } byte[] bar = new byte[_passphrase.length]; System.arraycopy(_passphrase, 0, bar, 0, bar.length); _passphrase = bar; byte[] foo = null; try { foo = decrypt(data, _passphrase, iv); if (parse(foo)) { encrypted = false; Util.bzero(data); } } finally { Util.bzero(_passphrase); Util.bzero(foo); } return !encrypted; } public static KeyPair load(JSch jsch, String prvkey) throws JSchException { String pubkey = prvkey + ".pub"; if (!new File(pubkey).exists()) { pubkey = null; } return load(jsch.instLogger, prvkey, pubkey); } public static KeyPair load(JSch jsch, String prvfile, String pubfile) throws JSchException { return load(jsch.instLogger, prvfile, pubfile); } static KeyPair load(JSch.InstanceLogger instLogger, String prvfile, String pubfile) throws JSchException { byte[] prvkey = null; byte[] pubkey = null; try { prvkey = Util.fromFile(prvfile); } catch (IOException e) { throw new JSchException(e.toString(), e); } String _pubfile = pubfile; if (pubfile == null) { _pubfile = prvfile + ".pub"; } try { pubkey = Util.fromFile(_pubfile); } catch (IOException e) { if (pubfile != null) { throw new JSchException(e.toString(), e); } } try { return load(instLogger, prvkey, pubkey); } finally { Util.bzero(prvkey); } } public static KeyPair load(JSch jsch, byte[] prvkey, byte[] pubkey) throws JSchException { return load(jsch.instLogger, prvkey, pubkey); } static KeyPair load(JSch.InstanceLogger instLogger, byte[] prvkey, byte[] pubkey) throws JSchException { byte[] iv = new byte[8]; // 8 boolean encrypted = true; byte[] data = null; byte[] publickeyblob = null; int type = ERROR; int vendor = VENDOR_OPENSSH; String publicKeyComment = ""; Cipher cipher = null; // prvkey from "ssh-add" command on the remote. if (pubkey == null && prvkey != null && (prvkey.length > 11 && prvkey[0] == 0 && prvkey[1] == 0 && prvkey[2] == 0 && // length of key type string (prvkey[3] == 7 || prvkey[3] == 9 || prvkey[3] == 11 || prvkey[3] == 19))) { Buffer buf = new Buffer(prvkey); buf.skip(prvkey.length); // for using Buffer#available() String _type = Util.byte2str(buf.getString()); // ssh-rsa or ssh-dss buf.rewind(); KeyPair kpair = null; if (_type.equals("ssh-rsa")) { kpair = KeyPairRSA.fromSSHAgent(instLogger, buf); } else if (_type.equals("ssh-dss")) { kpair = KeyPairDSA.fromSSHAgent(instLogger, buf); } else if (_type.equals("ecdsa-sha2-nistp256") || _type.equals("ecdsa-sha2-nistp384") || _type.equals("ecdsa-sha2-nistp521")) { kpair = KeyPairECDSA.fromSSHAgent(instLogger, buf); } else if (_type.equals("ssh-ed25519")) { kpair = KeyPairEd25519.fromSSHAgent(instLogger, buf); } else if (_type.equals("ssh-ed448")) { kpair = KeyPairEd448.fromSSHAgent(instLogger, buf); } else { throw new JSchException("privatekey: invalid key " + _type); } return kpair; } try { byte[] buf = prvkey; if (buf != null) { KeyPair ppk = loadPPK(instLogger, buf); if (ppk != null) return ppk; } int len = (buf != null ? buf.length : 0); int i = 0; // skip garbage lines. while (i < len) { if (buf[i] == '-' && i + 4 < len && buf[i + 1] == '-' && buf[i + 2] == '-' && buf[i + 3] == '-' && buf[i + 4] == '-') { break; } i++; } while (i < len) { if (buf[i] == 'B' && i + 3 < len && buf[i + 1] == 'E' && buf[i + 2] == 'G' && buf[i + 3] == 'I') { i += 6; if (i + 2 >= len) throw new JSchException("invalid privatekey"); if (buf[i] == 'D' && buf[i + 1] == 'S' && buf[i + 2] == 'A') { type = DSA; } else if (buf[i] == 'R' && buf[i + 1] == 'S' && buf[i + 2] == 'A') { type = RSA; } else if (buf[i] == 'E' && buf[i + 1] == 'C') { type = ECDSA; } else if (buf[i] == 'S' && buf[i + 1] == 'S' && buf[i + 2] == 'H') { // FSecure type = UNKNOWN; vendor = VENDOR_FSECURE; } else if (i + 6 < len && buf[i] == 'P' && buf[i + 1] == 'R' && buf[i + 2] == 'I' && buf[i + 3] == 'V' && buf[i + 4] == 'A' && buf[i + 5] == 'T' && buf[i + 6] == 'E') { type = UNKNOWN; vendor = VENDOR_PKCS8; encrypted = false; i += 3; } else if (i + 8 < len && buf[i] == 'E' && buf[i + 1] == 'N' && buf[i + 2] == 'C' && buf[i + 3] == 'R' && buf[i + 4] == 'Y' && buf[i + 5] == 'P' && buf[i + 6] == 'T' && buf[i + 7] == 'E' && buf[i + 8] == 'D') { type = UNKNOWN; vendor = VENDOR_PKCS8; i += 5; } else if (isOpenSSHPrivateKey(buf, i, len)) { type = UNKNOWN; vendor = VENDOR_OPENSSH_V1; } else { throw new JSchException("invalid privatekey"); } i += 3; continue; } if (buf[i] == 'A' && i + 7 < len && buf[i + 1] == 'E' && buf[i + 2] == 'S' && buf[i + 3] == '-' && buf[i + 4] == '2' && buf[i + 5] == '5' && buf[i + 6] == '6' && buf[i + 7] == '-') { i += 8; if (Session.checkCipher(JSch.getConfig("aes256-cbc"))) { Class c = Class.forName(JSch.getConfig("aes256-cbc")).asSubclass(Cipher.class); cipher = c.getDeclaredConstructor().newInstance(); // key=new byte[cipher.getBlockSize()]; iv = new byte[cipher.getIVSize()]; } else { throw new JSchException("privatekey: aes256-cbc is not available"); } continue; } if (buf[i] == 'A' && i + 7 < len && buf[i + 1] == 'E' && buf[i + 2] == 'S' && buf[i + 3] == '-' && buf[i + 4] == '1' && buf[i + 5] == '9' && buf[i + 6] == '2' && buf[i + 7] == '-') { i += 8; if (Session.checkCipher(JSch.getConfig("aes192-cbc"))) { Class c = Class.forName(JSch.getConfig("aes192-cbc")).asSubclass(Cipher.class); cipher = c.getDeclaredConstructor().newInstance(); // key=new byte[cipher.getBlockSize()]; iv = new byte[cipher.getIVSize()]; } else { throw new JSchException("privatekey: aes192-cbc is not available"); } continue; } if (buf[i] == 'A' && i + 7 < len && buf[i + 1] == 'E' && buf[i + 2] == 'S' && buf[i + 3] == '-' && buf[i + 4] == '1' && buf[i + 5] == '2' && buf[i + 6] == '8' && buf[i + 7] == '-') { i += 8; if (Session.checkCipher(JSch.getConfig("aes128-cbc"))) { Class c = Class.forName(JSch.getConfig("aes128-cbc")).asSubclass(Cipher.class); cipher = c.getDeclaredConstructor().newInstance(); // key=new byte[cipher.getBlockSize()]; iv = new byte[cipher.getIVSize()]; } else { throw new JSchException("privatekey: aes128-cbc is not available"); } continue; } if (buf[i] == 'C' && i + 3 < len && buf[i + 1] == 'B' && buf[i + 2] == 'C' && buf[i + 3] == ',') { i += 4; for (int ii = 0; ii < iv.length; ii++) { iv[ii] = (byte) (((a2b(buf[i++]) << 4) & 0xf0) + (a2b(buf[i++]) & 0xf)); } continue; } if (buf[i] == '\r' && i + 1 < buf.length && buf[i + 1] == '\n') { i++; continue; } if (buf[i] == '\n' && i + 1 < buf.length) { if (buf[i + 1] == '\n') { i += 2; break; } if (buf[i + 1] == '\r' && i + 2 < buf.length && buf[i + 2] == '\n') { i += 3; break; } boolean inheader = false; for (int j = i + 1; j < buf.length; j++) { if (buf[j] == '\n') break; // if(buf[j]=='\r') break; if (buf[j] == ':') { inheader = true; break; } } if (!inheader) { i++; if (vendor != VENDOR_PKCS8) encrypted = false; // no passphrase break; } } i++; } if (buf != null) { if (type == ERROR) { throw new JSchException("invalid privatekey"); } int start = i; while (i < len) { if (buf[i] == '-') { break; } i++; } if ((len - i) == 0 || (i - start) == 0) { throw new JSchException("invalid privatekey"); } // The content of 'buf' will be changed, so it should be copied. byte[] tmp = new byte[i - start]; System.arraycopy(buf, start, tmp, 0, tmp.length); byte[] _buf = tmp; start = 0; i = 0; int _len = _buf.length; while (i < _len) { if (_buf[i] == '\n') { boolean xd = (i > 0 && _buf[i - 1] == '\r'); // ignore \n (or \r\n) System.arraycopy(_buf, i + 1, _buf, i - (xd ? 1 : 0), _len - (i + 1)); if (xd) { _len--; i--; } _len--; continue; } if (_buf[i] == '-') { break; } i++; } if (i - start > 0) data = Util.fromBase64(_buf, start, i - start); Util.bzero(_buf); } if (vendor == VENDOR_OPENSSH_V1) { return loadOpenSSHKeyv1(instLogger, data); } else if (data != null && data.length > 4 && // FSecure data[0] == (byte) 0x3f && data[1] == (byte) 0x6f && data[2] == (byte) 0xf9 && data[3] == (byte) 0xeb) { Buffer _buf = new Buffer(data); _buf.getInt(); // 0x3f6ff9be _buf.getInt(); byte[] _type = _buf.getString(); String _cipher = Util.byte2str(_buf.getString()); if (_cipher.equals("3des-cbc")) { _buf.getInt(); byte[] foo = new byte[data.length - _buf.getOffSet()]; _buf.getByte(foo); data = foo; encrypted = true; throw new JSchException( "cipher " + _cipher + " is not supported for this privatekey format"); } else if (_cipher.equals("none")) { _buf.getInt(); _buf.getInt(); encrypted = false; byte[] foo = new byte[data.length - _buf.getOffSet()]; _buf.getByte(foo); data = foo; } else { throw new JSchException( "cipher " + _cipher + " is not supported for this privatekey format"); } } if (pubkey != null) { try { buf = pubkey; len = buf.length; if (buf.length > 4 && // FSecure's public key buf[0] == '-' && buf[1] == '-' && buf[2] == '-' && buf[3] == '-') { boolean valid = true; i = 0; do { i++; } while (buf.length > i && buf[i] != '\n'); if (buf.length <= i) { valid = false; } while (valid) { if (buf[i] == '\n') { boolean inheader = false; for (int j = i + 1; j < buf.length; j++) { if (buf[j] == '\n') break; if (buf[j] == ':') { inheader = true; break; } } if (!inheader) { i++; break; } } i++; } if (buf.length <= i) { valid = false; } int start = i; while (valid && i < len) { if (buf[i] == '\n') { System.arraycopy(buf, i + 1, buf, i, len - i - 1); len--; continue; } if (buf[i] == '-') { break; } i++; } if (valid) { publickeyblob = Util.fromBase64(buf, start, i - start); if (prvkey == null || type == UNKNOWN) { if (publickeyblob[8] == 'd') { type = DSA; } else if (publickeyblob[8] == 'r') { type = RSA; } } } } else { if (buf[0] == 's' && buf[1] == 's' && buf[2] == 'h' && buf[3] == '-') { if (prvkey == null && buf.length > 7) { if (buf[4] == 'd') { type = DSA; } else if (buf[4] == 'r') { type = RSA; } else if (buf[4] == 'e' && buf[6] == '2') { type = ED25519; } else if (buf[4] == 'e' && buf[6] == '4') { type = ED448; } } i = 0; while (i < len) { if (buf[i] == ' ') break; i++; } i++; if (i < len) { int start = i; while (i < len) { if (buf[i] == ' ') break; i++; } publickeyblob = Util.fromBase64(buf, start, i - start); } if (i++ < len) { int start = i; while (i < len) { if (buf[i] == '\n') break; i++; } if (i > 0 && buf[i - 1] == '\r') i--; if (start < i) { publicKeyComment = Util.byte2str(buf, start, i - start); } } } else if (buf[0] == 'e' && buf[1] == 'c' && buf[2] == 'd' && buf[3] == 's') { if (prvkey == null && buf.length > 7) { type = ECDSA; } i = 0; while (i < len) { if (buf[i] == ' ') break; i++; } i++; if (i < len) { int start = i; while (i < len) { if (buf[i] == ' ') break; i++; } publickeyblob = Util.fromBase64(buf, start, i - start); } if (i++ < len) { int start = i; while (i < len) { if (buf[i] == '\n') break; i++; } if (i > 0 && buf[i - 1] == '\r') i--; if (start < i) { publicKeyComment = Util.byte2str(buf, start, i - start); } } } } } catch (Exception ee) { if (instLogger.getLogger().isEnabled(Logger.WARN)) { instLogger.getLogger().log(Logger.WARN, "failed to parse public key", ee); } } } KeyPair kpair = null; if (type == DSA) { kpair = new KeyPairDSA(instLogger); } else if (type == RSA) { kpair = new KeyPairRSA(instLogger); } else if (type == ECDSA) { kpair = new KeyPairECDSA(instLogger, pubkey); } else if (type == ED25519) { kpair = new KeyPairEd25519(instLogger, pubkey, null); } else if (type == ED448) { kpair = new KeyPairEd448(instLogger, pubkey, null); } else if (vendor == VENDOR_PKCS8) { kpair = new KeyPairPKCS8(instLogger); } if (kpair != null) { kpair.encrypted = encrypted; kpair.publickeyblob = publickeyblob; kpair.vendor = vendor; kpair.publicKeyComment = publicKeyComment; kpair.cipher = cipher; if (encrypted) { kpair.encrypted = true; kpair.iv = iv; kpair.data = data; } else { if (kpair.parse(data)) { kpair.encrypted = false; } else { throw new JSchException("invalid privatekey"); } } } return kpair; } catch (Exception | NoClassDefFoundError e) { Util.bzero(data); if (e instanceof JSchException) throw (JSchException) e; throw new JSchException(e.toString(), e); } } static KeyPair loadOpenSSHKeyv1(JSch.InstanceLogger instLogger, byte[] data) throws JSchException { if (data == null) { throw new JSchException("invalid privatekey"); } Buffer buffer = new Buffer(data); byte[] magic = new byte[AUTH_MAGIC.length]; buffer.getByte(magic); if (!Util.arraysequals(AUTH_MAGIC, magic)) { throw new JSchException("Invalid openssh v1 format."); } String cipherName = Util.byte2str(buffer.getString()); String kdfName = Util.byte2str(buffer.getString()); // string kdfname byte[] kdfOptions = buffer.getString(); // string kdfoptions int nrKeys = buffer.getInt(); // int number of keys N; Should be 1 if (nrKeys != 1) { throw new JSchException("We don't support having more than 1 key in the file (yet)."); } byte[] publickeyblob = buffer.getString(); KeyPair kpair = parsePubkeyBlob(instLogger, publickeyblob, null); kpair.encrypted = !"none".equals(cipherName); kpair.publickeyblob = publickeyblob; kpair.vendor = VENDOR_OPENSSH_V1; kpair.publicKeyComment = ""; kpair.data = buffer.getString(); try { if (!kpair.encrypted) { if (!kpair.parse(kpair.data)) { throw new JSchException("invalid privatekey"); } else { Util.bzero(kpair.data); } } else { if (Session.checkCipher(JSch.getConfig(cipherName))) { try { Class c = Class.forName(JSch.getConfig(cipherName)).asSubclass(Cipher.class); kpair.cipher = c.getDeclaredConstructor().newInstance(); kpair.iv = new byte[kpair.cipher.getIVSize()]; } catch (Exception | NoClassDefFoundError e) { throw new JSchException("cipher " + cipherName + " is not available", e); } } else { throw new JSchException("cipher " + cipherName + " is not available"); } try { Buffer kdfOpts = new Buffer(kdfOptions); byte[] salt = kdfOpts.getString(); int rounds = kdfOpts.getInt(); Class c = Class.forName(JSch.getConfig(kdfName)).asSubclass(BCrypt.class); BCrypt bcrypt = c.getDeclaredConstructor().newInstance(); bcrypt.init(salt, rounds); kpair.kdf = bcrypt; } catch (Exception | NoClassDefFoundError e) { throw new JSchException("kdf " + kdfName + " is not available", e); } } return kpair; } catch (Exception e) { Util.bzero(kpair.data); throw e; } } private static boolean isOpenSSHPrivateKey(byte[] buf, int i, int len) { String ident = "OPENSSH PRIVATE KEY-----"; return i + ident.length() < len && ident.equals(Util.byte2str(Arrays.copyOfRange(buf, i, i + ident.length()))); } private static byte a2b(byte c) { if ('0' <= c && c <= '9') return (byte) (c - '0'); return (byte) (c - 'a' + 10); } private static byte b2a(byte c) { if (0 <= c && c <= 9) return (byte) (c + '0'); return (byte) (c - 10 + 'A'); } public void dispose() { Util.bzero(passphrase); } @SuppressWarnings("deprecation") @Override public void finalize() { dispose(); } static KeyPair loadPPK(JSch.InstanceLogger instLogger, byte[] buf) throws JSchException { byte[] pubkey = null; byte[] prvkey = null; byte[] _prvkey = null; int lines = 0; Buffer buffer = new Buffer(buf); Map v = new HashMap<>(); while (true) { if (!parseHeader(buffer, v)) break; } int ppkVersion; String typ = v.get("PuTTY-User-Key-File-2"); if (typ == null) { typ = v.get("PuTTY-User-Key-File-3"); if (typ == null) { return null; } else { ppkVersion = VENDOR_PUTTY_V3; } } else { ppkVersion = VENDOR_PUTTY; } try { lines = Integer.parseInt(v.get("Public-Lines")); pubkey = parseLines(buffer, lines); while (true) { if (!parseHeader(buffer, v)) break; } lines = Integer.parseInt(v.get("Private-Lines")); _prvkey = parseLines(buffer, lines); while (true) { if (!parseHeader(buffer, v)) break; } prvkey = Util.fromBase64(_prvkey, 0, _prvkey.length); pubkey = Util.fromBase64(pubkey, 0, pubkey.length); KeyPair kpair = parsePubkeyBlob(instLogger, pubkey, typ); kpair.encrypted = !v.get("Encryption").equals("none"); kpair.publickeyblob = pubkey; kpair.vendor = ppkVersion; kpair.publicKeyComment = v.get("Comment"); if (kpair.encrypted) { if (Session.checkCipher(JSch.getConfig("aes256-cbc"))) { try { Class c = Class.forName(JSch.getConfig("aes256-cbc")).asSubclass(Cipher.class); kpair.cipher = c.getDeclaredConstructor().newInstance(); kpair.iv = new byte[kpair.cipher.getIVSize()]; } catch (Exception | NoClassDefFoundError e) { throw new JSchException("The cipher 'aes256-cbc' is required, but it is not available.", e); } } else { throw new JSchException("The cipher 'aes256-cbc' is required, but it is not available."); } if (ppkVersion == VENDOR_PUTTY) { try { Class c = Class.forName(JSch.getConfig("sha-1")).asSubclass(HASH.class); HASH sha1 = c.getDeclaredConstructor().newInstance(); sha1.init(); kpair.sha1 = sha1; } catch (Exception | NoClassDefFoundError e) { throw new JSchException("'sha-1' is required, but it is not available.", e); } } else { String argonTypeStr = v.get("Key-Derivation"); String saltStr = v.get("Argon2-Salt"); if (argonTypeStr == null || saltStr == null || (saltStr != null && saltStr.length() % 2 != 0)) { throw new JSchException("Invalid argon2 params."); } int argonType; switch (argonTypeStr) { case "Argon2d": argonType = Argon2.ARGON2D; break; case "Argon2i": argonType = Argon2.ARGON2I; break; case "Argon2id": argonType = Argon2.ARGON2ID; break; default: throw new JSchException("Invalid argon2 params."); } try { int memory = Integer.parseInt(v.get("Argon2-Memory")); int passes = Integer.parseInt(v.get("Argon2-Passes")); int parallelism = Integer.parseInt(v.get("Argon2-Parallelism")); byte[] salt = new byte[saltStr.length() / 2]; for (int i = 0; i < salt.length; i++) { int j = i * 2; salt[i] = (byte) Integer.parseInt(saltStr.substring(j, j + 2), 16); } Class c = Class.forName(JSch.getConfig("argon2")).asSubclass(Argon2.class); Argon2 argon2 = c.getDeclaredConstructor().newInstance(); argon2.init(salt, passes, argonType, new byte[0], new byte[0], memory, parallelism, Argon2.V13); kpair.kdf = argon2; } catch (NumberFormatException e) { throw new JSchException("Invalid argon2 params.", e); } catch (Exception | NoClassDefFoundError e) { throw new JSchException("'argon2' is required, but it is not available.", e); } } kpair.data = prvkey; } else { kpair.data = prvkey; if (!kpair.parse(prvkey)) { throw new JSchException("invalid privatekey"); } else { Util.bzero(prvkey); } } return kpair; } catch (Exception e) { Util.bzero(prvkey); throw e; } finally { Util.bzero(_prvkey); } } private static KeyPair parsePubkeyBlob(JSch.InstanceLogger instLogger, byte[] pubkeyblob, String typ) throws JSchException { Buffer _buf = new Buffer(pubkeyblob); _buf.skip(pubkeyblob.length); String pubkeyType = Util.byte2str(_buf.getString()); if (typ == null || typ.equals("")) { typ = pubkeyType; } else if (!typ.equals(pubkeyType)) { throw new JSchException( "pubkeyblob type [" + pubkeyType + "] does not match expected type [" + typ + "]"); } if (typ.equals("ssh-rsa")) { byte[] pub_array = new byte[_buf.getInt()]; _buf.getByte(pub_array); byte[] n_array = new byte[_buf.getInt()]; _buf.getByte(n_array); return new KeyPairRSA(instLogger, n_array, pub_array, null); } else if (typ.equals("ssh-dss")) { byte[] p_array = new byte[_buf.getInt()]; _buf.getByte(p_array); byte[] q_array = new byte[_buf.getInt()]; _buf.getByte(q_array); byte[] g_array = new byte[_buf.getInt()]; _buf.getByte(g_array); byte[] y_array = new byte[_buf.getInt()]; _buf.getByte(y_array); return new KeyPairDSA(instLogger, p_array, q_array, g_array, y_array, null); } else if (typ.equals("ecdsa-sha2-nistp256") || typ.equals("ecdsa-sha2-nistp384") || typ.equals("ecdsa-sha2-nistp521")) { byte[] name = _buf.getString(); // nistpXXX int len = _buf.getInt(); int x04 = _buf.getByte(); // in case of x04 it is uncompressed // https://tools.ietf.org/html/rfc5480#page-7 byte[] r_array = new byte[(len - 1) / 2]; byte[] s_array = new byte[(len - 1) / 2]; _buf.getByte(r_array); _buf.getByte(s_array); return new KeyPairECDSA(instLogger, name, r_array, s_array, null); } else if (typ.equals("ssh-ed25519") || typ.equals("ssh-ed448")) { byte[] pub_array = new byte[_buf.getInt()]; _buf.getByte(pub_array); if (typ.equals("ssh-ed25519")) { return new KeyPairEd25519(instLogger, pub_array, null); } else { return new KeyPairEd448(instLogger, pub_array, null); } } else { throw new JSchException("key type " + typ + " is not supported"); } } private static byte[] parseLines(Buffer buffer, int lines) { byte[] buf = buffer.buffer; int index = buffer.index; byte[] data = null; int i = index; while (lines-- > 0) { while (buf.length > i) { byte c = buf[i++]; if (c == '\r' || c == '\n') { int len = i - index - 1; if (data == null) { data = new byte[len]; System.arraycopy(buf, index, data, 0, len); } else if (len > 0) { byte[] tmp = new byte[data.length + len]; System.arraycopy(data, 0, tmp, 0, data.length); System.arraycopy(buf, index, tmp, data.length, len); Util.bzero(data); // clear data = tmp; } break; } } if (i < buf.length && buf[i] == '\n') i++; index = i; } if (data != null) buffer.index = index; return data; } private static boolean parseHeader(Buffer buffer, Map v) { byte[] buf = buffer.buffer; int index = buffer.index; String key = null; String value = null; for (int i = index; i < buf.length; i++) { if (buf[i] == '\r' || buf[i] == '\n') { if (i + 1 < buf.length && buf[i + 1] == '\n') { i++; } break; } if (buf[i] == ':') { key = Util.byte2str(buf, index, i - index); i++; if (i < buf.length && buf[i] == ' ') { i++; } index = i; break; } } if (key == null) return false; for (int i = index; i < buf.length; i++) { if (buf[i] == '\r' || buf[i] == '\n') { value = Util.byte2str(buf, index, i - index); i++; if (i < buf.length && buf[i] == '\n') { i++; } index = i; break; } } if (value != null) { v.put(key, value); buffer.index = index; } return (key != null && value != null); } void copy(KeyPair kpair) { this.publickeyblob = kpair.publickeyblob; this.vendor = kpair.vendor; this.publicKeyComment = kpair.publicKeyComment; this.cipher = kpair.cipher; } static class ASN1Exception extends Exception { private static final long serialVersionUID = -1L; } static class ASN1 { byte[] buf; int start; int length; ASN1(byte[] buf) throws ASN1Exception { this(buf, 0, buf.length); } ASN1(byte[] buf, int start, int length) throws ASN1Exception { this.buf = buf; this.start = start; this.length = length; if (start + length > buf.length) throw new ASN1Exception(); } int getType() { return buf[start] & 0xff; } boolean isSEQUENCE() { return getType() == (0x30 & 0xff); } boolean isINTEGER() { return getType() == (0x02 & 0xff); } boolean isOBJECT() { return getType() == (0x06 & 0xff); } boolean isOCTETSTRING() { return getType() == (0x04 & 0xff); } boolean isNULL() { return getType() == (0x05 & 0xff); } boolean isBITSTRING() { return getType() == (0x03 & 0xff); } boolean isCONTEXTPRIMITIVE(int tag) { if ((tag & ~0xff) != 0 || (tag & 0x60) != 0) { throw new IllegalArgumentException(); } return getType() == ((tag | 0x80) & 0xff); } boolean isCONTEXTCONSTRUCTED(int tag) { if ((tag & ~0xff) != 0 || (tag & 0x40) != 0) { throw new IllegalArgumentException(); } return getType() == ((tag | 0xa0) & 0xff); } private int getLength(int[] indexp) { int index = indexp[0]; int length = buf[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (buf[index++] & 0xff); } } indexp[0] = index; return length; } byte[] getContent() { int[] indexp = new int[1]; indexp[0] = start + 1; int length = getLength(indexp); int index = indexp[0]; byte[] tmp = new byte[length]; System.arraycopy(buf, index, tmp, 0, tmp.length); return tmp; } ASN1[] getContents() throws ASN1Exception { int typ = buf[start]; int[] indexp = new int[1]; indexp[0] = start + 1; int length = getLength(indexp); if (typ == 0x05) { return new ASN1[0]; } int index = indexp[0]; List values = new ArrayList<>(); while (length > 0) { index++; length--; int tmp = index; indexp[0] = index; int l = getLength(indexp); index = indexp[0]; length -= (index - tmp); values.add(new ASN1(buf, tmp - 1, 1 + (index - tmp) + l)); index += l; length -= l; } ASN1[] result = new ASN1[values.size()]; values.toArray(result); return result; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairDSA.java000066400000000000000000000303051465436372100246570ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.math.BigInteger; class KeyPairDSA extends KeyPair { private byte[] P_array; private byte[] Q_array; private byte[] G_array; private byte[] pub_array; private byte[] prv_array; // private int key_size=0; private int key_size = 1024; KeyPairDSA(JSch.InstanceLogger instLogger) { this(instLogger, null, null, null, null, null); } KeyPairDSA(JSch.InstanceLogger instLogger, byte[] P_array, byte[] Q_array, byte[] G_array, byte[] pub_array, byte[] prv_array) { super(instLogger); this.P_array = P_array; this.Q_array = Q_array; this.G_array = G_array; this.pub_array = pub_array; this.prv_array = prv_array; if (P_array != null) key_size = (new BigInteger(P_array)).bitLength(); } @Override void generate(int key_size) throws JSchException { this.key_size = key_size; try { Class c = Class.forName(JSch.getConfig("keypairgen.dsa")).asSubclass(KeyPairGenDSA.class); KeyPairGenDSA keypairgen = c.getDeclaredConstructor().newInstance(); keypairgen.init(key_size); P_array = keypairgen.getP(); Q_array = keypairgen.getQ(); G_array = keypairgen.getG(); pub_array = keypairgen.getY(); prv_array = keypairgen.getX(); keypairgen = null; } catch (Exception e) { throw new JSchException(e.toString(), e); } } private static final byte[] begin = Util.str2byte("-----BEGIN DSA PRIVATE KEY-----"); private static final byte[] end = Util.str2byte("-----END DSA PRIVATE KEY-----"); @Override byte[] getBegin() { return begin; } @Override byte[] getEnd() { return end; } @Override byte[] getPrivateKey() { int content = 1 + countLength(1) + 1 + // INTEGER 1 + countLength(P_array.length) + P_array.length + // INTEGER P 1 + countLength(Q_array.length) + Q_array.length + // INTEGER Q 1 + countLength(G_array.length) + G_array.length + // INTEGER G 1 + countLength(pub_array.length) + pub_array.length + // INTEGER pub 1 + countLength(prv_array.length) + prv_array.length; // INTEGER prv int total = 1 + countLength(content) + content; // SEQUENCE byte[] plain = new byte[total]; int index = 0; index = writeSEQUENCE(plain, index, content); index = writeINTEGER(plain, index, new byte[1]); // 0 index = writeINTEGER(plain, index, P_array); index = writeINTEGER(plain, index, Q_array); index = writeINTEGER(plain, index, G_array); index = writeINTEGER(plain, index, pub_array); index = writeINTEGER(plain, index, prv_array); return plain; } @Override boolean parse(byte[] plain) { try { if (vendor == VENDOR_FSECURE) { if (plain[0] != 0x30) { // FSecure Buffer buf = new Buffer(plain); buf.getInt(); P_array = buf.getMPIntBits(); G_array = buf.getMPIntBits(); Q_array = buf.getMPIntBits(); pub_array = buf.getMPIntBits(); prv_array = buf.getMPIntBits(); if (P_array != null) key_size = (new BigInteger(P_array)).bitLength(); return true; } return false; } else if (vendor == VENDOR_PUTTY || vendor == VENDOR_PUTTY_V3) { Buffer buf = new Buffer(plain); buf.skip(plain.length); try { byte[][] tmp = buf.getBytes(1, ""); prv_array = tmp[0]; } catch (JSchException e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } return true; } // OPENSSH Key v1 Format else if (vendor == VENDOR_OPENSSH_V1) { final Buffer prvKEyBuffer = new Buffer(plain); int checkInt1 = prvKEyBuffer.getInt(); // uint32 checkint1 int checkInt2 = prvKEyBuffer.getInt(); // uint32 checkint2 if (checkInt1 != checkInt2) { throw new JSchException("check failed"); } // The private key section contains both the public key and the private key String keyType = Util.byte2str(prvKEyBuffer.getString()); // string keytype P_array = prvKEyBuffer.getMPInt(); Q_array = prvKEyBuffer.getMPInt(); G_array = prvKEyBuffer.getMPInt(); pub_array = prvKEyBuffer.getMPInt(); prv_array = prvKEyBuffer.getMPInt(); publicKeyComment = Util.byte2str(prvKEyBuffer.getString()); // if(P_array!=null) key_size = (new BigInteger(P_array)).bitLength(); return true; } int index = 0; int length = 0; if (plain[index] != 0x30) return false; index++; // SEQUENCE length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } if (plain[index] != 0x02) return false; index++; // INTEGER length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } P_array = new byte[length]; System.arraycopy(plain, index, P_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } Q_array = new byte[length]; System.arraycopy(plain, index, Q_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } G_array = new byte[length]; System.arraycopy(plain, index, G_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } pub_array = new byte[length]; System.arraycopy(plain, index, pub_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } prv_array = new byte[length]; System.arraycopy(plain, index, prv_array, 0, length); index += length; if (P_array != null) key_size = (new BigInteger(P_array)).bitLength(); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } return true; } @Override public byte[] getPublicKeyBlob() { byte[] foo = super.getPublicKeyBlob(); if (foo != null) return foo; if (P_array == null) return null; byte[][] tmp = new byte[5][]; tmp[0] = sshdss; tmp[1] = P_array; tmp[2] = Q_array; tmp[3] = G_array; tmp[4] = pub_array; return Buffer.fromBytes(tmp).buffer; } private static final byte[] sshdss = Util.str2byte("ssh-dss"); @Override byte[] getKeyTypeName() { return sshdss; } @Override public int getKeyType() { return DSA; } @Override public int getKeySize() { return key_size; } @Override public byte[] getSignature(byte[] data) { try { Class c = Class.forName(JSch.getConfig("signature.dss")).asSubclass(SignatureDSA.class); SignatureDSA dsa = c.getDeclaredConstructor().newInstance(); dsa.init(); dsa.setPrvKey(prv_array, P_array, Q_array, G_array); dsa.update(data); byte[] sig = dsa.sign(); byte[][] tmp = new byte[2][]; tmp[0] = sshdss; tmp[1] = sig; return Buffer.fromBytes(tmp).buffer; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to generate signature", e); } } return null; } @Override public byte[] getSignature(byte[] data, String alg) { return getSignature(data); } @Override public Signature getVerifier() { try { Class c = Class.forName(JSch.getConfig("signature.dss")).asSubclass(SignatureDSA.class); SignatureDSA dsa = c.getDeclaredConstructor().newInstance(); dsa.init(); if (pub_array == null && P_array == null && getPublicKeyBlob() != null) { Buffer buf = new Buffer(getPublicKeyBlob()); buf.getString(); P_array = buf.getString(); Q_array = buf.getString(); G_array = buf.getString(); pub_array = buf.getString(); } dsa.setPubKey(pub_array, P_array, Q_array, G_array); return dsa; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create verifier", e); } } return null; } @Override public Signature getVerifier(String alg) { return getVerifier(); } static KeyPair fromSSHAgent(JSch.InstanceLogger instLogger, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(7, "invalid key format"); byte[] P_array = tmp[1]; byte[] Q_array = tmp[2]; byte[] G_array = tmp[3]; byte[] pub_array = tmp[4]; byte[] prv_array = tmp[5]; KeyPairDSA kpair = new KeyPairDSA(instLogger, P_array, Q_array, G_array, pub_array, prv_array); kpair.publicKeyComment = Util.byte2str(tmp[6]); kpair.vendor = VENDOR_OPENSSH; return kpair; } @Override public byte[] forSSHAgent() throws JSchException { if (isEncrypted()) { throw new JSchException("key is encrypted."); } Buffer buf = new Buffer(); buf.putString(sshdss); buf.putString(P_array); buf.putString(Q_array); buf.putString(G_array); buf.putString(pub_array); buf.putString(prv_array); buf.putString(Util.str2byte(publicKeyComment)); byte[] result = new byte[buf.getLength()]; buf.getByte(result, 0, result.length); return result; } @Override public void dispose() { super.dispose(); Util.bzero(prv_array); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairECDSA.java000066400000000000000000000343541465436372100250770ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Arrays; class KeyPairECDSA extends KeyPair { private static byte[][] oids = {{(byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, // 256 (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07}, {(byte) 0x06, (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, // 384 (byte) 0x00, (byte) 0x22}, {(byte) 0x06, (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, // 521 (byte) 0x00, (byte) 0x23},}; private static String[] names = {"nistp256", "nistp384", "nistp521"}; private byte[] name = Util.str2byte(names[0]); private byte[] r_array; private byte[] s_array; private byte[] prv_array; private int key_size = 256; KeyPairECDSA(JSch.InstanceLogger instLogger) { this(instLogger, null, null, null, null); } KeyPairECDSA(JSch.InstanceLogger instLogger, byte[] pubkey) { this(instLogger, null, null, null, null); if (pubkey != null) { byte[] name = new byte[8]; System.arraycopy(pubkey, 11, name, 0, 8); if (Util.array_equals(name, Util.str2byte("nistp384"))) { key_size = 384; this.name = name; } if (Util.array_equals(name, Util.str2byte("nistp521"))) { key_size = 521; this.name = name; } } } KeyPairECDSA(JSch.InstanceLogger instLogger, byte[] name, byte[] r_array, byte[] s_array, byte[] prv_array) { super(instLogger); if (name != null) this.name = name; this.r_array = r_array; this.s_array = s_array; this.prv_array = prv_array; if (prv_array != null) key_size = prv_array.length >= 64 ? 521 : (prv_array.length >= 48 ? 384 : 256); } @Override void generate(int key_size) throws JSchException { this.key_size = key_size; try { Class c = Class.forName(JSch.getConfig("keypairgen.ecdsa")).asSubclass(KeyPairGenECDSA.class); KeyPairGenECDSA keypairgen = c.getDeclaredConstructor().newInstance(); keypairgen.init(key_size); prv_array = keypairgen.getD(); r_array = keypairgen.getR(); s_array = keypairgen.getS(); name = Util.str2byte(names[prv_array.length >= 64 ? 2 : (prv_array.length >= 48 ? 1 : 0)]); keypairgen = null; } catch (Exception e) { throw new JSchException(e.toString(), e); } } private static final byte[] begin = Util.str2byte("-----BEGIN EC PRIVATE KEY-----"); private static final byte[] end = Util.str2byte("-----END EC PRIVATE KEY-----"); @Override byte[] getBegin() { return begin; } @Override byte[] getEnd() { return end; } @Override byte[] getPrivateKey() { byte[] tmp = new byte[1]; tmp[0] = 1; byte[] oid = oids[(r_array.length >= 64) ? 2 : ((r_array.length >= 48) ? 1 : 0)]; byte[] point = toPoint(r_array, s_array); int bar = ((point.length + 1) & 0x80) == 0 ? 3 : 4; byte[] foo = new byte[point.length + bar]; System.arraycopy(point, 0, foo, bar, point.length); foo[0] = 0x03; // BITSTRING if (bar == 3) { foo[1] = (byte) (point.length + 1); } else { foo[1] = (byte) 0x81; foo[2] = (byte) (point.length + 1); } point = foo; int content = 1 + countLength(tmp.length) + tmp.length + 1 + countLength(prv_array.length) + prv_array.length + 1 + countLength(oid.length) + oid.length + 1 + countLength(point.length) + point.length; int total = 1 + countLength(content) + content; // SEQUENCE byte[] plain = new byte[total]; int index = 0; index = writeSEQUENCE(plain, index, content); index = writeINTEGER(plain, index, tmp); index = writeOCTETSTRING(plain, index, prv_array); index = writeDATA(plain, (byte) 0xa0, index, oid); index = writeDATA(plain, (byte) 0xa1, index, point); return plain; } @Override boolean parse(byte[] plain) { try { if (vendor == VENDOR_FSECURE) { /* * if(plain[0]!=0x30){ // FSecure return true; } return false; */ return false; } else if (vendor == VENDOR_PUTTY || vendor == VENDOR_PUTTY_V3) { Buffer buf = new Buffer(plain); buf.skip(plain.length); try { byte[][] tmp = buf.getBytes(1, ""); prv_array = tmp[0]; key_size = prv_array.length >= 64 ? 521 : (prv_array.length >= 48 ? 384 : 256); } catch (JSchException e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } return true; } // OPENSSH Key v1 Format if (vendor == VENDOR_OPENSSH_V1) { final Buffer prvKeyBuffer = new Buffer(plain); int checkInt1 = prvKeyBuffer.getInt(); // uint32 checkint1 int checkInt2 = prvKeyBuffer.getInt(); // uint32 checkint2 if (checkInt1 != checkInt2) { throw new JSchException("check failed"); } String keyType = Util.byte2str(prvKeyBuffer.getString()); // string keytype name = prvKeyBuffer.getString(); if (!Arrays.asList(names).contains(Util.byte2str(name))) { throw new IllegalArgumentException("unknown curve name " + Util.byte2str(name)); } final int keyLen = prvKeyBuffer.getInt(); final int x04 = prvKeyBuffer.getByte(); // in case of x04 it is uncompressed // https://tools.ietf.org/html/rfc5480#page-7 final byte[] x = new byte[(keyLen - 1) / 2]; final byte[] y = new byte[(keyLen - 1) / 2]; prvKeyBuffer.getByte(x); prvKeyBuffer.getByte(y); prv_array = prvKeyBuffer.getString(); publicKeyComment = Util.byte2str(prvKeyBuffer.getString()); r_array = x; s_array = y; key_size = x.length >= 64 ? 521 : (x.length >= 48 ? 384 : 256); return true; } int index = 0; int length = 0; if (plain[index] != 0x30) return false; index++; // SEQUENCE length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } if (plain[index] != 0x02) return false; index++; // INTEGER length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } index += length; index++; // 0x04 length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } prv_array = new byte[length]; System.arraycopy(plain, index, prv_array, 0, length); index += length; index++; // 0xa0 length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } byte[] oid_array = new byte[length]; System.arraycopy(plain, index, oid_array, 0, length); index += length; for (int i = 0; i < oids.length; i++) { if (Util.array_equals(oids[i], oid_array)) { name = Util.str2byte(names[i]); break; } } index++; // 0xa1 length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } byte[] Q_array = new byte[length]; System.arraycopy(plain, index, Q_array, 0, length); index += length; byte[][] tmp = fromPoint(Q_array); r_array = tmp[0]; s_array = tmp[1]; if (prv_array != null) key_size = prv_array.length >= 64 ? 521 : (prv_array.length >= 48 ? 384 : 256); } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } return true; } @Override public byte[] getPublicKeyBlob() { byte[] foo = super.getPublicKeyBlob(); if (foo != null) return foo; if (r_array == null) return null; byte[][] tmp = new byte[3][]; tmp[0] = Util.str2byte("ecdsa-sha2-" + Util.byte2str(name)); tmp[1] = name; tmp[2] = new byte[1 + r_array.length + s_array.length]; tmp[2][0] = 4; // POINT_CONVERSION_UNCOMPRESSED System.arraycopy(r_array, 0, tmp[2], 1, r_array.length); System.arraycopy(s_array, 0, tmp[2], 1 + r_array.length, s_array.length); return Buffer.fromBytes(tmp).buffer; } @Override byte[] getKeyTypeName() { return Util.str2byte("ecdsa-sha2-" + Util.byte2str(name)); } @Override public int getKeyType() { return ECDSA; } @Override public int getKeySize() { return key_size; } @Override public byte[] getSignature(byte[] data) { try { Class c = Class.forName(JSch.getConfig("ecdsa-sha2-" + Util.byte2str(name))) .asSubclass(SignatureECDSA.class); SignatureECDSA ecdsa = c.getDeclaredConstructor().newInstance(); ecdsa.init(); ecdsa.setPrvKey(prv_array); ecdsa.update(data); byte[] sig = ecdsa.sign(); byte[][] tmp = new byte[2][]; tmp[0] = Util.str2byte("ecdsa-sha2-" + Util.byte2str(name)); tmp[1] = sig; return Buffer.fromBytes(tmp).buffer; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to generate signature", e); } } return null; } @Override public byte[] getSignature(byte[] data, String al) { return getSignature(data); } @Override public Signature getVerifier() { try { Class c = Class.forName(JSch.getConfig("ecdsa-sha2-" + Util.byte2str(name))) .asSubclass(SignatureECDSA.class); final SignatureECDSA ecdsa = c.getDeclaredConstructor().newInstance(); ecdsa.init(); if (r_array == null && s_array == null && getPublicKeyBlob() != null) { Buffer buf = new Buffer(getPublicKeyBlob()); buf.getString(); // ecdsa-sha2-nistp256 buf.getString(); // nistp256 byte[][] tmp = fromPoint(buf.getString()); r_array = tmp[0]; s_array = tmp[1]; } ecdsa.setPubKey(r_array, s_array); return ecdsa; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create verifier", e); } } return null; } @Override public Signature getVerifier(String alg) { return getVerifier(); } static KeyPair fromSSHAgent(JSch.InstanceLogger instLogger, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(5, "invalid key format"); byte[] name = tmp[1]; // nistp256 byte[][] foo = fromPoint(tmp[2]); byte[] r_array = foo[0]; byte[] s_array = foo[1]; byte[] prv_array = tmp[3]; KeyPairECDSA kpair = new KeyPairECDSA(instLogger, name, r_array, s_array, prv_array); kpair.publicKeyComment = Util.byte2str(tmp[4]); kpair.vendor = VENDOR_OPENSSH; return kpair; } @Override public byte[] forSSHAgent() throws JSchException { if (isEncrypted()) { throw new JSchException("key is encrypted."); } Buffer buf = new Buffer(); buf.putString(Util.str2byte("ecdsa-sha2-" + Util.byte2str(name))); buf.putString(name); buf.putString(toPoint(r_array, s_array)); buf.putString(prv_array); buf.putString(Util.str2byte(publicKeyComment)); byte[] result = new byte[buf.getLength()]; buf.getByte(result, 0, result.length); return result; } static byte[] toPoint(byte[] r_array, byte[] s_array) { byte[] tmp = new byte[1 + r_array.length + s_array.length]; tmp[0] = 0x04; System.arraycopy(r_array, 0, tmp, 1, r_array.length); System.arraycopy(s_array, 0, tmp, 1 + r_array.length, s_array.length); return tmp; } static byte[][] fromPoint(byte[] point) { int i = 0; while (point[i] != 4) i++; i++; byte[][] tmp = new byte[2][]; byte[] r_array = new byte[(point.length - i) / 2]; byte[] s_array = new byte[(point.length - i) / 2]; // point[0] == 0x04 == POINT_CONVERSION_UNCOMPRESSED System.arraycopy(point, i, r_array, 0, r_array.length); System.arraycopy(point, i + r_array.length, s_array, 0, s_array.length); tmp[0] = r_array; tmp[1] = s_array; return tmp; } @Override public void dispose() { super.dispose(); Util.bzero(prv_array); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairEd25519.java000066400000000000000000000047641465436372100252200ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Arrays; class KeyPairEd25519 extends KeyPairEdDSA { private static int keySize = 32; KeyPairEd25519(JSch.InstanceLogger instLogger) { this(instLogger, null, null); } KeyPairEd25519(JSch.InstanceLogger instLogger, byte[] pub_array, byte[] prv_array) { super(instLogger, pub_array, prv_array); } @Override public int getKeyType() { return ED25519; } @Override public int getKeySize() { return keySize; } @Override String getSshName() { return "ssh-ed25519"; } @Override String getJceName() { return "Ed25519"; } static KeyPair fromSSHAgent(JSch.InstanceLogger instLogger, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(4, "invalid key format"); byte[] pub_array = tmp[1]; byte[] prv_array = Arrays.copyOf(tmp[2], keySize); KeyPairEd25519 kpair = new KeyPairEd25519(instLogger, pub_array, prv_array); kpair.publicKeyComment = Util.byte2str(tmp[3]); kpair.vendor = VENDOR_OPENSSH; return kpair; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairEd448.java000066400000000000000000000047441465436372100250500ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Arrays; class KeyPairEd448 extends KeyPairEdDSA { private static int keySize = 57; KeyPairEd448(JSch.InstanceLogger instLogger) { this(instLogger, null, null); } KeyPairEd448(JSch.InstanceLogger instLogger, byte[] pub_array, byte[] prv_array) { super(instLogger, pub_array, prv_array); } @Override public int getKeyType() { return ED448; } @Override public int getKeySize() { return keySize; } @Override String getSshName() { return "ssh-ed448"; } @Override String getJceName() { return "Ed448"; } static KeyPair fromSSHAgent(JSch.InstanceLogger instLogger, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(4, "invalid key format"); byte[] pub_array = tmp[1]; byte[] prv_array = Arrays.copyOf(tmp[2], keySize); KeyPairEd448 kpair = new KeyPairEd448(instLogger, pub_array, prv_array); kpair.publicKeyComment = Util.byte2str(tmp[3]); kpair.vendor = VENDOR_OPENSSH; return kpair; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java000066400000000000000000000176111465436372100251350ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Arrays; abstract class KeyPairEdDSA extends KeyPair { private byte[] pub_array; private byte[] prv_array; KeyPairEdDSA(JSch.InstanceLogger instLogger, byte[] pub_array, byte[] prv_array) { super(instLogger); this.pub_array = pub_array; this.prv_array = prv_array; } abstract String getSshName(); abstract String getJceName(); @Override void generate(int key_size) throws JSchException { try { Class c = Class.forName(JSch.getConfig("keypairgen.eddsa")).asSubclass(KeyPairGenEdDSA.class); KeyPairGenEdDSA keypairgen = c.getDeclaredConstructor().newInstance(); keypairgen.init(getJceName(), getKeySize()); pub_array = keypairgen.getPub(); prv_array = keypairgen.getPrv(); keypairgen = null; } catch (Exception | NoClassDefFoundError e) { throw new JSchException(e.toString(), e); } } // These methods appear to be for writing keys to a file. // And since writing VENDOR_OPENSSH_V1 isn't supported yet, have these methods fail. @Override byte[] getBegin() { throw new UnsupportedOperationException(); } @Override byte[] getEnd() { throw new UnsupportedOperationException(); } @Override byte[] getPrivateKey() { throw new UnsupportedOperationException(); } @Override boolean parse(byte[] plain) { if (vendor == VENDOR_PUTTY || vendor == VENDOR_PUTTY_V3) { Buffer buf = new Buffer(plain); buf.skip(plain.length); try { byte[][] tmp = buf.getBytes(1, ""); prv_array = tmp[0]; } catch (JSchException e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } return true; } else if (vendor == VENDOR_OPENSSH_V1) { try { // OPENSSH Key v1 Format final Buffer buf = new Buffer(plain); int checkInt1 = buf.getInt(); // uint32 checkint1 int checkInt2 = buf.getInt(); // uint32 checkint2 if (checkInt1 != checkInt2) { throw new JSchException("check failed"); } String keyType = Util.byte2str(buf.getString()); // string keytype pub_array = buf.getString(); // public key // OpenSSH stores private key in first half of string and duplicate copy of public key in // second half of string byte[] tmp = buf.getString(); // secret key (private key + public key) prv_array = Arrays.copyOf(tmp, getKeySize()); publicKeyComment = Util.byte2str(buf.getString()); return true; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } } else if (vendor == VENDOR_PKCS8) { try { Class c = Class.forName(JSch.getConfig("keypairgen_fromprivate.eddsa")) .asSubclass(KeyPairGenEdDSA.class); KeyPairGenEdDSA keypairgen = c.getDeclaredConstructor().newInstance(); keypairgen.init(getJceName(), plain); pub_array = keypairgen.getPub(); prv_array = keypairgen.getPrv(); return true; } catch (Exception | NoClassDefFoundError e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } } else { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key"); } return false; } } @Override public byte[] getPublicKeyBlob() { byte[] foo = super.getPublicKeyBlob(); if (foo != null) return foo; if (pub_array == null) return null; byte[][] tmp = new byte[2][]; tmp[0] = getKeyTypeName(); tmp[1] = pub_array; return Buffer.fromBytes(tmp).buffer; } @Override byte[] getKeyTypeName() { return Util.str2byte(getSshName()); } @Override public byte[] getSignature(byte[] data) { return getSignature(data, getSshName()); } @Override public byte[] getSignature(byte[] data, String alg) { try { Class c = Class.forName(JSch.getConfig(alg)).asSubclass(SignatureEdDSA.class); SignatureEdDSA eddsa = c.getDeclaredConstructor().newInstance(); eddsa.init(); eddsa.setPrvKey(prv_array); eddsa.update(data); byte[] sig = eddsa.sign(); byte[][] tmp = new byte[2][]; tmp[0] = Util.str2byte(alg); tmp[1] = sig; return Buffer.fromBytes(tmp).buffer; } catch (Exception | NoClassDefFoundError e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to generate signature", e); } } return null; } @Override public Signature getVerifier() { return getVerifier(getSshName()); } @Override public Signature getVerifier(String alg) { try { Class c = Class.forName(JSch.getConfig(alg)).asSubclass(SignatureEdDSA.class); SignatureEdDSA eddsa = c.getDeclaredConstructor().newInstance(); eddsa.init(); if (pub_array == null && getPublicKeyBlob() != null) { Buffer buf = new Buffer(getPublicKeyBlob()); buf.getString(); pub_array = buf.getString(); } eddsa.setPubKey(pub_array); return eddsa; } catch (Exception | NoClassDefFoundError e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create verifier", e); } } return null; } @Override public byte[] forSSHAgent() throws JSchException { if (isEncrypted()) { throw new JSchException("key is encrypted."); } Buffer buf = new Buffer(); buf.putString(getKeyTypeName()); buf.putString(pub_array); byte[] tmp = new byte[prv_array.length + pub_array.length]; System.arraycopy(prv_array, 0, tmp, 0, prv_array.length); System.arraycopy(pub_array, 0, tmp, prv_array.length, pub_array.length); buf.putString(tmp); buf.putString(Util.str2byte(publicKeyComment)); byte[] result = new byte[buf.getLength()]; buf.getByte(result, 0, result.length); return result; } @Override public void dispose() { super.dispose(); Util.bzero(prv_array); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java000066400000000000000000000032301465436372100253060ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface KeyPairGenDSA { void init(int key_size) throws Exception; byte[] getX(); byte[] getY(); byte[] getP(); byte[] getQ(); byte[] getG(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java000066400000000000000000000031661465436372100255260ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface KeyPairGenECDSA { void init(int key_size) throws Exception; byte[] getD(); byte[] getR(); byte[] getS(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java000066400000000000000000000033471465436372100255700ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface KeyPairGenEdDSA { void init(String name, int keylen) throws Exception; byte[] getPub(); byte[] getPrv(); default void init(String name, byte[] prv) throws Exception { throw new UnsupportedOperationException(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java000066400000000000000000000033201465436372100253240ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface KeyPairGenRSA { void init(int key_size) throws Exception; byte[] getD(); byte[] getE(); byte[] getN(); byte[] getC(); byte[] getEP(); byte[] getEQ(); byte[] getP(); byte[] getQ(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java000066400000000000000000000717141465436372100251110ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; class KeyPairPKCS8 extends KeyPair { private static final byte[] rsaEncryption = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01}; private static final byte[] dsaEncryption = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04, (byte) 0x01}; private static final byte[] ecPublicKey = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01}; private static final byte[] ed25519 = {(byte) 0x2b, (byte) 0x65, (byte) 0x70}; private static final byte[] ed448 = {(byte) 0x2b, (byte) 0x65, (byte) 0x71}; private static final byte[] secp256r1 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07}; private static final byte[] secp384r1 = {(byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22}; private static final byte[] secp521r1 = {(byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x23}; private static final byte[] pbes2 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x0d}; private static final byte[] pbkdf2 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x0c}; private static final byte[] scrypt = {(byte) 0x2b, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x01, (byte) 0xda, (byte) 0x47, (byte) 0x04, (byte) 0x0b}; private static final byte[] hmacWithSha1 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x07}; private static final byte[] hmacWithSha224 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x08}; private static final byte[] hmacWithSha256 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x09}; private static final byte[] hmacWithSha384 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x0a}; private static final byte[] hmacWithSha512 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x0b}; private static final byte[] hmacWithSha512224 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x0c}; private static final byte[] hmacWithSha512256 = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x02, (byte) 0x0d}; private static final byte[] aes128cbc = {(byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x65, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x02}; private static final byte[] aes192cbc = {(byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x65, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x16}; private static final byte[] aes256cbc = {(byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x65, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x2a}; private static final byte[] descbc = {(byte) 0x2b, (byte) 0x0e, (byte) 0x03, (byte) 0x02, (byte) 0x07}; private static final byte[] des3cbc = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x03, (byte) 0x07}; private static final byte[] rc2cbc = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x03, (byte) 0x02}; private static final byte[] rc5cbc = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x03, (byte) 0x09}; private static final byte[] pbeWithMD2AndDESCBC = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x01}; private static final byte[] pbeWithMD2AndRC2CBC = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x04}; private static final byte[] pbeWithMD5AndDESCBC = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x03}; private static final byte[] pbeWithMD5AndRC2CBC = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x06}; private static final byte[] pbeWithSHA1AndDESCBC = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x0a}; private static final byte[] pbeWithSHA1AndRC2CBC = {(byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x05, (byte) 0x0b}; private KeyPair kpair = null; KeyPairPKCS8(JSch.InstanceLogger instLogger) { super(instLogger); } @Override void generate(int key_size) throws JSchException {} private static final byte[] begin = Util.str2byte("-----BEGIN DSA PRIVATE KEY-----"); private static final byte[] end = Util.str2byte("-----END DSA PRIVATE KEY-----"); @Override byte[] getBegin() { return begin; } @Override byte[] getEnd() { return end; } @Override byte[] getPrivateKey() { return null; } @Override boolean parse(byte[] plain) { /* * from RFC5208 PrivateKeyInfo ::= SEQUENCE { version Version, privateKeyAlgorithm * PrivateKeyAlgorithmIdentifier, privateKey PrivateKey, attributes [0] IMPLICIT Attributes * OPTIONAL } Version ::= INTEGER PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier * PrivateKey ::= OCTET STRING Attributes ::= SET OF Attribute } */ byte[] _data = null; byte[] prv_array = null; byte[] _plain = null; KeyPair _key = null; try { ASN1[] contents; ASN1 asn1 = new ASN1(plain); if (!asn1.isSEQUENCE()) { throw new ASN1Exception(); } contents = asn1.getContents(); if (contents.length < 3 || contents.length > 4) { throw new ASN1Exception(); } if (!contents[0].isINTEGER()) { throw new ASN1Exception(); } if (!contents[1].isSEQUENCE()) { throw new ASN1Exception(); } if (!contents[2].isOCTETSTRING()) { throw new ASN1Exception(); } // attributes [0] IMPLICIT Attributes OPTIONAL if (contents.length > 3 && !contents[3].isCONTEXTCONSTRUCTED(0)) { throw new ASN1Exception(); } int version = parseASN1IntegerAsInt(contents[0].getContent()); if (version != 0) { throw new ASN1Exception(); } ASN1 privateKeyAlgorithm = contents[1]; ASN1 privateKey = contents[2]; contents = privateKeyAlgorithm.getContents(); if (contents.length == 0) { throw new ASN1Exception(); } if (!contents[0].isOBJECT()) { throw new ASN1Exception(); } byte[] privateKeyAlgorithmID = contents[0].getContent(); _data = privateKey.getContent(); KeyPair _kpair = null; if (Util.array_equals(privateKeyAlgorithmID, rsaEncryption)) { if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[1].isNULL()) { throw new ASN1Exception(); } _kpair = new KeyPairRSA(instLogger); _kpair.copy(this); if (_kpair.parse(_data)) { kpair = _kpair; return true; } else { throw new JSchException("failed to parse RSA"); } } else if (Util.array_equals(privateKeyAlgorithmID, dsaEncryption)) { List values = new ArrayList<>(3); if (contents.length > 1 && contents[1].isSEQUENCE()) { contents = contents[1].getContents(); if (contents.length != 3) { throw new ASN1Exception(); } if (!contents[0].isINTEGER()) { throw new ASN1Exception(); } if (!contents[1].isINTEGER()) { throw new ASN1Exception(); } if (!contents[2].isINTEGER()) { throw new ASN1Exception(); } values.add(contents[0].getContent()); values.add(contents[1].getContent()); values.add(contents[2].getContent()); } asn1 = new ASN1(_data); if (values.size() == 0) { // embedded DSA parameters format /* * SEQUENCE SEQUENCE INTEGER // P_array INTEGER // Q_array INTEGER // G_array INTEGER // * prv_array */ if (!asn1.isSEQUENCE()) { throw new ASN1Exception(); } contents = asn1.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[0].isSEQUENCE()) { throw new ASN1Exception(); } if (!contents[1].isINTEGER()) { throw new ASN1Exception(); } prv_array = contents[1].getContent(); contents = contents[0].getContents(); if (contents.length != 3) { throw new ASN1Exception(); } if (!contents[0].isINTEGER()) { throw new ASN1Exception(); } if (!contents[1].isINTEGER()) { throw new ASN1Exception(); } if (!contents[2].isINTEGER()) { throw new ASN1Exception(); } values.add(contents[0].getContent()); values.add(contents[1].getContent()); values.add(contents[2].getContent()); } else { /* * INTEGER // prv_array */ if (!asn1.isINTEGER()) { throw new ASN1Exception(); } prv_array = asn1.getContent(); } byte[] P_array = values.get(0); byte[] Q_array = values.get(1); byte[] G_array = values.get(2); // Y = g^X mode p byte[] pub_array = (new BigInteger(G_array)) .modPow(new BigInteger(prv_array), new BigInteger(P_array)).toByteArray(); _key = new KeyPairDSA(instLogger, P_array, Q_array, G_array, pub_array, prv_array); _plain = _key.getPrivateKey(); _kpair = new KeyPairDSA(instLogger); _kpair.copy(this); if (_kpair.parse(_plain)) { kpair = _kpair; return true; } else { throw new JSchException("failed to parse DSA"); } } else if (Util.array_equals(privateKeyAlgorithmID, ecPublicKey)) { if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[1].isOBJECT()) { throw new ASN1Exception(); } byte[] namedCurve = contents[1].getContent(); byte[] name; if (!Util.array_equals(namedCurve, secp256r1)) { name = Util.str2byte("nistp256"); } else if (!Util.array_equals(namedCurve, secp384r1)) { name = Util.str2byte("nistp384"); } else if (!Util.array_equals(namedCurve, secp521r1)) { name = Util.str2byte("nistp521"); } else { throw new JSchException("unsupported named curve oid: " + Util.toHex(namedCurve)); } ASN1 ecPrivateKey = new ASN1(_data); if (!ecPrivateKey.isSEQUENCE()) { throw new ASN1Exception(); } // ECPrivateKey ::= SEQUENCE { // version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), // privateKey OCTET STRING, // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, // publicKey [1] BIT STRING OPTIONAL // } contents = ecPrivateKey.getContents(); if (contents.length < 3 || contents.length > 4) { throw new ASN1Exception(); } if (!contents[0].isINTEGER()) { throw new ASN1Exception(); } if (!contents[1].isOCTETSTRING()) { throw new ASN1Exception(); } version = parseASN1IntegerAsInt(contents[0].getContent()); if (version != 1) { throw new ASN1Exception(); } prv_array = contents[1].getContent(); // publicKey is required here since there is no other way to derive it. ASN1 publicKey; if (contents.length == 3) { publicKey = contents[2]; } else { publicKey = contents[3]; // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL if (!contents[2].isCONTEXTCONSTRUCTED(0)) { throw new ASN1Exception(); } // NamedCurve isn't required here since it is already known. // But if it is included, they should be the same... ASN1[] goo = contents[2].getContents(); if (goo.length != 1) { throw new ASN1Exception(); } if (!goo[0].isOBJECT()) { throw new ASN1Exception(); } if (!Util.array_equals(goo[0].getContent(), namedCurve)) { throw new ASN1Exception(); } } // publicKey [1] BIT STRING OPTIONAL if (!publicKey.isCONTEXTCONSTRUCTED(1)) { throw new ASN1Exception(); } contents = publicKey.getContents(); if (contents.length != 1) { throw new ASN1Exception(); } if (!contents[0].isBITSTRING()) { throw new ASN1Exception(); } byte[] Q_array = contents[0].getContent(); byte[][] tmp = KeyPairECDSA.fromPoint(Q_array); byte[] r_array = tmp[0]; byte[] s_array = tmp[1]; _key = new KeyPairECDSA(instLogger, name, r_array, s_array, prv_array); _plain = _key.getPrivateKey(); _kpair = new KeyPairECDSA(instLogger); _kpair.copy(this); if (_kpair.parse(_plain)) { kpair = _kpair; return true; } else { throw new JSchException("failed to parse ECDSA"); } } else if (Util.array_equals(privateKeyAlgorithmID, ed25519) || Util.array_equals(privateKeyAlgorithmID, ed448)) { if (contents.length != 1) { throw new ASN1Exception(); } ASN1 curvePrivateKey = new ASN1(_data); if (!curvePrivateKey.isOCTETSTRING()) { throw new ASN1Exception(); } prv_array = curvePrivateKey.getContent(); if (Util.array_equals(privateKeyAlgorithmID, ed25519)) { _kpair = new KeyPairEd25519(instLogger); } else { _kpair = new KeyPairEd448(instLogger); } _kpair.copy(this); if (_kpair.parse(prv_array)) { kpair = _kpair; return true; } else { throw new JSchException("failed to parse EdDSA"); } } else { throw new JSchException( "unsupported privateKeyAlgorithm oid: " + Util.toHex(privateKeyAlgorithmID)); } } catch (ASN1Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "PKCS8: failed to parse key: ASN1 parsing error", e); } return false; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "PKCS8: failed to parse key: " + e.getMessage(), e); } return false; } finally { Util.bzero(_data); Util.bzero(prv_array); Util.bzero(_plain); if (_key != null) { _key.dispose(); } } } @Override public byte[] getPublicKeyBlob() { if (kpair != null) { return kpair.getPublicKeyBlob(); } else { return super.getPublicKeyBlob(); } } @Override byte[] getKeyTypeName() { if (kpair != null) { return kpair.getKeyTypeName(); } else { return new byte[0]; } } @Override public int getKeyType() { if (kpair != null) { return kpair.getKeyType(); } else { return UNKNOWN; } } @Override public int getKeySize() { return kpair.getKeySize(); } @Override public byte[] getSignature(byte[] data) { return kpair.getSignature(data); } @Override public byte[] getSignature(byte[] data, String alg) { return kpair.getSignature(data, alg); } @Override public Signature getVerifier() { return kpair.getVerifier(); } @Override public Signature getVerifier(String alg) { return kpair.getVerifier(alg); } @Override public byte[] forSSHAgent() throws JSchException { return kpair.forSSHAgent(); } @Override public boolean decrypt(byte[] _passphrase) { if (!isEncrypted()) { return true; } if (_passphrase == null) { return !isEncrypted(); } /* * SEQUENCE SEQUENCE OBJECT :PBES2 SEQUENCE SEQUENCE OBJECT :PBKDF2 SEQUENCE OCTET STRING [HEX * DUMP]:E4E24ADC9C00BD4D INTEGER :0800 SEQUENCE OBJECT :aes-128-cbc OCTET STRING [HEX * DUMP]:5B66E6B3BF03944C92317BC370CC3AD0 OCTET STRING [HEX DUMP]: * * or * * SEQUENCE SEQUENCE OBJECT :PBES2 SEQUENCE SEQUENCE OBJECT :PBKDF2 SEQUENCE OCTET STRING [HEX * DUMP]:E4E24ADC9C00BD4D INTEGER :0800 SEQUENCE OBJECT :hmacWithSHA256 NULL SEQUENCE OBJECT * :aes-128-cbc OCTET STRING [HEX DUMP]:5B66E6B3BF03944C92317BC370CC3AD0 OCTET STRING [HEX * DUMP]: * * or * * SEQUENCE SEQUENCE OBJECT :pbeWithMD5AndDES-CBC SEQUENCE OCTET STRING [HEX * DUMP]:DBF75ECB69E3C0FC INTEGER :0800 OCTET STRING [HEX DUMP] */ byte[] _data = null; byte[] key = null; byte[] plain = null; try { ASN1[] contents; ASN1 asn1 = new ASN1(data); if (!asn1.isSEQUENCE()) { throw new ASN1Exception(); } contents = asn1.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[0].isSEQUENCE()) { throw new ASN1Exception(); } if (!contents[1].isOCTETSTRING()) { throw new ASN1Exception(); } _data = contents[1].getContent(); ASN1 pbes = contents[0]; contents = pbes.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[0].isOBJECT()) { throw new ASN1Exception(); } if (!contents[1].isSEQUENCE()) { throw new ASN1Exception(); } byte[] pbesid = contents[0].getContent(); ASN1 pbesparam = contents[1]; String kdfname; KDF kdfinst; byte[] encryptfuncid; ASN1 encryptparams; if (Util.array_equals(pbesid, pbes2)) { contents = pbesparam.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } ASN1 kdf = contents[0]; ASN1 encryptfunc = contents[1]; if (!kdf.isSEQUENCE()) { throw new ASN1Exception(); } if (!encryptfunc.isSEQUENCE()) { throw new ASN1Exception(); } contents = encryptfunc.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[0].isOBJECT()) { throw new ASN1Exception(); } encryptfuncid = contents[0].getContent(); encryptparams = contents[1]; contents = kdf.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[0].isOBJECT()) { throw new ASN1Exception(); } if (!contents[1].isSEQUENCE()) { throw new ASN1Exception(); } byte[] kdfid = contents[0].getContent(); if (Util.array_equals(kdfid, pbkdf2)) { ASN1 pbkdf2func = contents[1]; if (!pbkdf2func.isSEQUENCE()) { throw new ASN1Exception(); } ASN1 prf = null; contents = pbkdf2func.getContents(); if (contents.length < 2 || contents.length > 4) { throw new ASN1Exception(); } if (!contents[0].isOCTETSTRING()) { throw new ASN1Exception(); } if (!contents[1].isINTEGER()) { throw new ASN1Exception(); } if (contents.length == 4) { if (!contents[2].isINTEGER()) { throw new ASN1Exception(); } if (!contents[3].isSEQUENCE()) { throw new ASN1Exception(); } prf = contents[3]; } else if (contents.length == 3) { if (contents[2].isSEQUENCE()) { prf = contents[2]; } else if (!contents[2].isINTEGER()) { throw new ASN1Exception(); } } byte[] prfid = null; byte[] salt = contents[0].getContent(); int iterations = parseASN1IntegerAsInt(contents[1].getContent()); if (prf != null) { contents = prf.getContents(); if (contents.length != 2) { throw new ASN1Exception(); } if (!contents[0].isOBJECT()) { throw new ASN1Exception(); } if (!contents[1].isNULL()) { throw new ASN1Exception(); } prfid = contents[0].getContent(); } kdfname = getPBKDF2Name(prfid); PBKDF2 pbkdf2kdf = getPBKDF2(kdfname); pbkdf2kdf.init(salt, iterations); kdfinst = pbkdf2kdf; } else if (Util.array_equals(kdfid, scrypt)) { contents = contents[1].getContents(); if (contents.length < 4 || contents.length > 5) { throw new ASN1Exception(); } if (!contents[0].isOCTETSTRING()) { throw new ASN1Exception(); } if (!contents[1].isINTEGER()) { throw new ASN1Exception(); } if (!contents[2].isINTEGER()) { throw new ASN1Exception(); } if (!contents[3].isINTEGER()) { throw new ASN1Exception(); } if (contents.length > 4 && !contents[4].isINTEGER()) { throw new ASN1Exception(); } byte[] salt = contents[0].getContent(); int cost = parseASN1IntegerAsInt(contents[1].getContent()); int blocksize = parseASN1IntegerAsInt(contents[2].getContent()); int parallel = parseASN1IntegerAsInt(contents[3].getContent()); kdfname = "scrypt"; SCrypt scryptkdf = getSCrypt(); scryptkdf.init(salt, cost, blocksize, parallel); kdfinst = scryptkdf; } else { throw new JSchException("unsupported kdf oid: " + Util.toHex(kdfid)); } } else { String message; if (Util.array_equals(pbesid, pbeWithMD2AndDESCBC)) { message = "pbeWithMD2AndDES-CBC unsupported"; } else if (Util.array_equals(pbesid, pbeWithMD2AndRC2CBC)) { message = "pbeWithMD2AndRC2-CBC unsupported"; } else if (Util.array_equals(pbesid, pbeWithMD5AndDESCBC)) { message = "pbeWithMD5AndDES-CBC unsupported"; } else if (Util.array_equals(pbesid, pbeWithMD5AndRC2CBC)) { message = "pbeWithMD5AndRC2-CBC unsupported"; } else if (Util.array_equals(pbesid, pbeWithSHA1AndDESCBC)) { message = "pbeWithSHA1AndDES-CBC unsupported"; } else if (Util.array_equals(pbesid, pbeWithSHA1AndRC2CBC)) { message = "pbeWithSHA1AndRC2-CBC unsupported"; } else { message = "unsupported encryption oid: " + Util.toHex(pbesid); } throw new JSchException(message); } byte[][] ivp = new byte[1][]; Cipher cipher = getCipher(encryptfuncid, encryptparams, ivp); byte[] iv = ivp[0]; key = kdfinst.getKey(_passphrase, cipher.getBlockSize()); if (key == null) { throw new JSchException("failed to generate key from KDF " + kdfname); } cipher.init(Cipher.DECRYPT_MODE, key, iv); plain = new byte[_data.length]; cipher.update(_data, 0, _data.length, plain, 0); if (parse(plain)) { encrypted = false; Util.bzero(data); return true; } else { throw new JSchException("failed to parse decrypted key"); } } catch (ASN1Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "PKCS8: failed to decrypt key: ASN1 parsing error", e); } return false; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "PKCS8: failed to decrypt key: " + e.getMessage(), e); } return false; } finally { Util.bzero(_data); Util.bzero(key); Util.bzero(plain); } } static String getPBKDF2Name(byte[] id) throws JSchException { String name = null; if (id == null || Util.array_equals(id, hmacWithSha1)) { name = "pbkdf2-hmac-sha1"; } else if (Util.array_equals(id, hmacWithSha224)) { name = "pbkdf2-hmac-sha224"; } else if (Util.array_equals(id, hmacWithSha256)) { name = "pbkdf2-hmac-sha256"; } else if (Util.array_equals(id, hmacWithSha384)) { name = "pbkdf2-hmac-sha384"; } else if (Util.array_equals(id, hmacWithSha512)) { name = "pbkdf2-hmac-sha512"; } else if (Util.array_equals(id, hmacWithSha512224)) { name = "pbkdf2-hmac-sha512-224"; } else if (Util.array_equals(id, hmacWithSha512256)) { name = "pbkdf2-hmac-sha512-256"; } if (name == null) { throw new JSchException("unsupported pbkdf2 function oid: " + Util.toHex(id)); } return name; } static PBKDF2 getPBKDF2(String name) throws JSchException { try { Class c = Class.forName(JSch.getConfig(name)).asSubclass(PBKDF2.class); return c.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new JSchException(name + " is not supported", e); } } static SCrypt getSCrypt() throws JSchException { try { Class c = Class.forName(JSch.getConfig("scrypt")).asSubclass(SCrypt.class); return c.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new JSchException("scrypt is not supported", e); } } static Cipher getCipher(byte[] id, ASN1 encryptparams, byte[][] ivp) throws Exception { String name = null; if (Util.array_equals(id, aes128cbc)) { name = "aes128-cbc"; } else if (Util.array_equals(id, aes192cbc)) { name = "aes192-cbc"; } else if (Util.array_equals(id, aes256cbc)) { name = "aes256-cbc"; } else if (Util.array_equals(id, descbc)) { throw new JSchException("unsupported cipher function: des-cbc"); } else if (Util.array_equals(id, des3cbc)) { throw new JSchException("unsupported cipher function: 3des-cbc"); } else if (Util.array_equals(id, rc2cbc)) { throw new JSchException("unsupported cipher function: rc2-cbc"); } else if (Util.array_equals(id, rc5cbc)) { throw new JSchException("unsupported cipher function: rc5-cbc"); } if (name == null) { throw new JSchException("unsupported cipher function oid: " + Util.toHex(id)); } if (!encryptparams.isOCTETSTRING()) { throw new ASN1Exception(); } ivp[0] = encryptparams.getContent(); try { Class c = Class.forName(JSch.getConfig(name)).asSubclass(Cipher.class); return c.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new JSchException(name + " is not supported", e); } } static int parseASN1IntegerAsInt(byte[] content) { BigInteger b = new BigInteger(content); // https://github.com/mwiede/jsch/issues/392 not using intValueExact() because of Android // incompatibility. if (b.bitLength() <= 31) { return b.intValue(); } else { throw new ArithmeticException("BigInteger out of int range"); } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KeyPairRSA.java000066400000000000000000000364451465436372100247100ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.math.BigInteger; class KeyPairRSA extends KeyPair { private byte[] n_array; // modulus p multiply q private byte[] pub_array; // e private byte[] prv_array; // d e^-1 mod (p-1)(q-1) private byte[] p_array; // prime p private byte[] q_array; // prime q private byte[] ep_array; // prime exponent p dmp1 == prv mod (p-1) private byte[] eq_array; // prime exponent q dmq1 == prv mod (q-1) private byte[] c_array; // coefficient iqmp == modinv(q, p) == q^-1 mod p private int key_size = 1024; KeyPairRSA(JSch.InstanceLogger instLogger) { this(instLogger, null, null, null); } KeyPairRSA(JSch.InstanceLogger instLogger, byte[] n_array, byte[] pub_array, byte[] prv_array) { super(instLogger); this.n_array = n_array; this.pub_array = pub_array; this.prv_array = prv_array; if (n_array != null) { key_size = (new BigInteger(n_array)).bitLength(); } } @Override void generate(int key_size) throws JSchException { this.key_size = key_size; try { Class c = Class.forName(JSch.getConfig("keypairgen.rsa")).asSubclass(KeyPairGenRSA.class); KeyPairGenRSA keypairgen = c.getDeclaredConstructor().newInstance(); keypairgen.init(key_size); pub_array = keypairgen.getE(); prv_array = keypairgen.getD(); n_array = keypairgen.getN(); p_array = keypairgen.getP(); q_array = keypairgen.getQ(); ep_array = keypairgen.getEP(); eq_array = keypairgen.getEQ(); c_array = keypairgen.getC(); keypairgen = null; } catch (Exception e) { throw new JSchException(e.toString(), e); } } private static final byte[] begin = Util.str2byte("-----BEGIN RSA PRIVATE KEY-----"); private static final byte[] end = Util.str2byte("-----END RSA PRIVATE KEY-----"); @Override byte[] getBegin() { return begin; } @Override byte[] getEnd() { return end; } @Override byte[] getPrivateKey() { int content = 1 + countLength(1) + 1 + // INTEGER 1 + countLength(n_array.length) + n_array.length + // INTEGER N 1 + countLength(pub_array.length) + pub_array.length + // INTEGER pub 1 + countLength(prv_array.length) + prv_array.length + // INTEGER prv 1 + countLength(p_array.length) + p_array.length + // INTEGER p 1 + countLength(q_array.length) + q_array.length + // INTEGER q 1 + countLength(ep_array.length) + ep_array.length + // INTEGER ep 1 + countLength(eq_array.length) + eq_array.length + // INTEGER eq 1 + countLength(c_array.length) + c_array.length; // INTEGER c int total = 1 + countLength(content) + content; // SEQUENCE byte[] plain = new byte[total]; int index = 0; index = writeSEQUENCE(plain, index, content); index = writeINTEGER(plain, index, new byte[1]); // 0 index = writeINTEGER(plain, index, n_array); index = writeINTEGER(plain, index, pub_array); index = writeINTEGER(plain, index, prv_array); index = writeINTEGER(plain, index, p_array); index = writeINTEGER(plain, index, q_array); index = writeINTEGER(plain, index, ep_array); index = writeINTEGER(plain, index, eq_array); index = writeINTEGER(plain, index, c_array); return plain; } @Override boolean parse(byte[] plain) { try { int index = 0; int length = 0; if (vendor == VENDOR_PUTTY || vendor == VENDOR_PUTTY_V3) { Buffer buf = new Buffer(plain); buf.skip(plain.length); try { byte[][] tmp = buf.getBytes(4, ""); prv_array = tmp[0]; p_array = tmp[1]; q_array = tmp[2]; c_array = tmp[3]; } catch (JSchException e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } getEPArray(); getEQArray(); return true; } if (vendor == VENDOR_FSECURE) { if (plain[index] != 0x30) { // FSecure Buffer buf = new Buffer(plain); pub_array = buf.getMPIntBits(); prv_array = buf.getMPIntBits(); n_array = buf.getMPIntBits(); byte[] u_array = buf.getMPIntBits(); p_array = buf.getMPIntBits(); q_array = buf.getMPIntBits(); if (n_array != null) { key_size = (new BigInteger(n_array)).bitLength(); } getEPArray(); getEQArray(); getCArray(); return true; } if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key"); } return false; } // OPENSSH Key v1 Format if (vendor == VENDOR_OPENSSH_V1) { final Buffer prvKEyBuffer = new Buffer(plain); int checkInt1 = prvKEyBuffer.getInt(); // uint32 checkint1 int checkInt2 = prvKEyBuffer.getInt(); // uint32 checkint2 if (checkInt1 != checkInt2) { throw new JSchException("check failed"); } String keyType = Util.byte2str(prvKEyBuffer.getString()); // string keytype n_array = prvKEyBuffer.getMPInt(); // Modulus pub_array = prvKEyBuffer.getMPInt(); // Public Exponent prv_array = prvKEyBuffer.getMPInt(); // Private Exponent c_array = prvKEyBuffer.getMPInt(); // iqmp (q^-1 mod p) p_array = prvKEyBuffer.getMPInt(); // p (Prime 1) q_array = prvKEyBuffer.getMPInt(); // q (Prime 2) if (n_array != null) { key_size = (new BigInteger(n_array)).bitLength(); } publicKeyComment = Util.byte2str(prvKEyBuffer.getString()); getEPArray(); getEQArray(); return true; } /* * Key must be in the following ASN.1 DER encoding, RSAPrivateKey ::= SEQUENCE { version * Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d * prime1 INTEGER, -- p prime2 INTEGER, -- q exponent1 INTEGER, -- d mod (p-1) exponent2 * INTEGER, -- d mod (q-1) coefficient INTEGER, -- (inverse of q) mod p otherPrimeInfos * OtherPrimeInfos OPTIONAL } */ index++; // SEQUENCE length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } if (plain[index] != 0x02) return false; index++; // INTEGER length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } n_array = new byte[length]; System.arraycopy(plain, index, n_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } pub_array = new byte[length]; System.arraycopy(plain, index, pub_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } prv_array = new byte[length]; System.arraycopy(plain, index, prv_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } p_array = new byte[length]; System.arraycopy(plain, index, p_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } q_array = new byte[length]; System.arraycopy(plain, index, q_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } ep_array = new byte[length]; System.arraycopy(plain, index, ep_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } eq_array = new byte[length]; System.arraycopy(plain, index, eq_array, 0, length); index += length; index++; length = plain[index++] & 0xff; if ((length & 0x80) != 0) { int foo = length & 0x7f; length = 0; while (foo-- > 0) { length = (length << 8) + (plain[index++] & 0xff); } } c_array = new byte[length]; System.arraycopy(plain, index, c_array, 0, length); index += length; if (n_array != null) { key_size = (new BigInteger(n_array)).bitLength(); } } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to parse key", e); } return false; } return true; } @Override public byte[] getPublicKeyBlob() { byte[] foo = super.getPublicKeyBlob(); if (foo != null) return foo; if (pub_array == null) return null; byte[][] tmp = new byte[3][]; tmp[0] = sshrsa; tmp[1] = pub_array; tmp[2] = n_array; return Buffer.fromBytes(tmp).buffer; } private static final byte[] sshrsa = Util.str2byte("ssh-rsa"); @Override byte[] getKeyTypeName() { return sshrsa; } @Override public int getKeyType() { return RSA; } @Override public int getKeySize() { return key_size; } @Override public byte[] getSignature(byte[] data) { return getSignature(data, "ssh-rsa"); } @Override public byte[] getSignature(byte[] data, String alg) { try { Class c = Class.forName(JSch.getConfig(alg)).asSubclass(SignatureRSA.class); SignatureRSA rsa = c.getDeclaredConstructor().newInstance(); rsa.init(); rsa.setPrvKey(prv_array, n_array); rsa.update(data); byte[] sig = rsa.sign(); byte[][] tmp = new byte[2][]; tmp[0] = Util.str2byte(alg); tmp[1] = sig; return Buffer.fromBytes(tmp).buffer; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to generate signature", e); } } return null; } @Override public Signature getVerifier() { return getVerifier("ssh-rsa"); } @Override public Signature getVerifier(String alg) { try { Class c = Class.forName(JSch.getConfig(alg)).asSubclass(SignatureRSA.class); SignatureRSA rsa = c.getDeclaredConstructor().newInstance(); rsa.init(); if (pub_array == null && n_array == null && getPublicKeyBlob() != null) { Buffer buf = new Buffer(getPublicKeyBlob()); buf.getString(); pub_array = buf.getString(); n_array = buf.getString(); } rsa.setPubKey(pub_array, n_array); return rsa; } catch (Exception e) { if (instLogger.getLogger().isEnabled(Logger.ERROR)) { instLogger.getLogger().log(Logger.ERROR, "failed to create verifier", e); } } return null; } static KeyPair fromSSHAgent(JSch.InstanceLogger instLogger, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(8, "invalid key format"); byte[] n_array = tmp[1]; byte[] pub_array = tmp[2]; byte[] prv_array = tmp[3]; KeyPairRSA kpair = new KeyPairRSA(instLogger, n_array, pub_array, prv_array); kpair.c_array = tmp[4]; // iqmp kpair.p_array = tmp[5]; kpair.q_array = tmp[6]; kpair.publicKeyComment = Util.byte2str(tmp[7]); kpair.vendor = VENDOR_OPENSSH; return kpair; } @Override public byte[] forSSHAgent() throws JSchException { if (isEncrypted()) { throw new JSchException("key is encrypted."); } Buffer buf = new Buffer(); buf.putString(sshrsa); buf.putString(n_array); buf.putString(pub_array); buf.putString(prv_array); buf.putString(getCArray()); buf.putString(p_array); buf.putString(q_array); buf.putString(Util.str2byte(publicKeyComment)); byte[] result = new byte[buf.getLength()]; buf.getByte(result, 0, result.length); return result; } private byte[] getEPArray() { if (ep_array == null) { ep_array = (new BigInteger(prv_array)).mod(new BigInteger(p_array).subtract(BigInteger.ONE)) .toByteArray(); } return ep_array; } private byte[] getEQArray() { if (eq_array == null) { eq_array = (new BigInteger(prv_array)).mod(new BigInteger(q_array).subtract(BigInteger.ONE)) .toByteArray(); } return eq_array; } private byte[] getCArray() { if (c_array == null) { c_array = (new BigInteger(q_array)).modInverse(new BigInteger(p_array)).toByteArray(); } return c_array; } @Override public void dispose() { super.dispose(); Util.bzero(prv_array); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/KnownHosts.java000066400000000000000000000443321465436372100251050ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Vector; class KnownHosts implements HostKeyRepository { private JSch jsch = null; private String known_hosts = null; private Vector pool = null; MAC hmacsha1; KnownHosts(JSch jsch) { super(); this.jsch = jsch; getHMACSHA1(); pool = new Vector<>(); } void setKnownHosts(String filename) throws JSchException { try { known_hosts = filename; InputStream fis = new FileInputStream(Util.checkTilde(filename)); setKnownHosts(fis); } catch (FileNotFoundException e) { // The non-existing file should be allowed. } } void setKnownHosts(InputStream input) throws JSchException { pool.removeAllElements(); StringBuilder sb = new StringBuilder(); byte i; int j; boolean error = false; try (InputStream fis = input) { String host; String key = null; int type; byte[] buf = new byte[1024]; int bufl = 0; loop: while (true) { bufl = 0; while (true) { j = fis.read(); if (j == -1) { if (bufl == 0) { break loop; } break; } if (j == 0x0d) { continue; } if (j == 0x0a) { break; } if (buf.length <= bufl) { if (bufl > 1024 * 10) break; // too long... byte[] newbuf = new byte[buf.length * 2]; System.arraycopy(buf, 0, newbuf, 0, buf.length); buf = newbuf; } buf[bufl++] = (byte) j; } j = 0; while (j < bufl) { i = buf[j]; if (i == ' ' || i == '\t') { j++; continue; } if (i == '#') { addInvalidLine(Util.byte2str(buf, 0, bufl)); continue loop; } break; } if (j >= bufl) { addInvalidLine(Util.byte2str(buf, 0, bufl)); continue loop; } sb.setLength(0); while (j < bufl) { i = buf[j++]; if (i == 0x20 || i == '\t') { break; } sb.append((char) i); } host = sb.toString(); if (j >= bufl || host.length() == 0) { addInvalidLine(Util.byte2str(buf, 0, bufl)); continue loop; } while (j < bufl) { i = buf[j]; if (i == ' ' || i == '\t') { j++; continue; } break; } String marker = ""; if (host.charAt(0) == '@') { marker = host; sb.setLength(0); while (j < bufl) { i = buf[j++]; if (i == 0x20 || i == '\t') { break; } sb.append((char) i); } host = sb.toString(); if (j >= bufl || host.length() == 0) { addInvalidLine(Util.byte2str(buf, 0, bufl)); continue loop; } while (j < bufl) { i = buf[j]; if (i == ' ' || i == '\t') { j++; continue; } break; } } sb.setLength(0); type = -1; while (j < bufl) { i = buf[j++]; if (i == 0x20 || i == '\t') { break; } sb.append((char) i); } String tmp = sb.toString(); if (HostKey.name2type(tmp) != HostKey.UNKNOWN) { type = HostKey.name2type(tmp); } else { j = bufl; } if (j >= bufl) { addInvalidLine(Util.byte2str(buf, 0, bufl)); continue loop; } while (j < bufl) { i = buf[j]; if (i == ' ' || i == '\t') { j++; continue; } break; } sb.setLength(0); while (j < bufl) { i = buf[j++]; if (i == 0x0d) { continue; } if (i == 0x0a) { break; } if (i == 0x20 || i == '\t') { break; } sb.append((char) i); } key = sb.toString(); if (key.length() == 0) { addInvalidLine(Util.byte2str(buf, 0, bufl)); continue loop; } while (j < bufl) { i = buf[j]; if (i == ' ' || i == '\t') { j++; continue; } break; } /** * "man sshd" has following descriptions, Note that the lines in these files are typically * hundreds of characters long, and you definitely don't want to type in the host keys by * hand. Rather, generate them by a script, ssh-keyscan(1) or by taking * /usr/local/etc/ssh_host_key.pub and adding the host names at the front. This means that a * comment is allowed to appear at the end of each key entry. */ String comment = null; if (j < bufl) { sb.setLength(0); while (j < bufl) { i = buf[j++]; if (i == 0x0d) { continue; } if (i == 0x0a) { break; } sb.append((char) i); } comment = sb.toString(); } // System.err.println(host); // System.err.println("|"+key+"|"); HostKey hk = null; hk = new HashedHostKey(marker, host, type, Util.fromBase64(Util.str2byte(key), 0, key.length()), comment); pool.addElement(hk); } if (error) { throw new JSchException("KnownHosts: invalid format"); } } catch (Exception e) { if (e instanceof JSchException) throw (JSchException) e; throw new JSchException(e.toString(), e); } } private void addInvalidLine(String line) throws JSchException { HostKey hk = new HostKey(line, HostKey.UNKNOWN, null); pool.addElement(hk); } String getKnownHostsFile() { return known_hosts; } @Override public String getKnownHostsRepositoryID() { return known_hosts; } @Override public int check(String host, byte[] key) { int result = NOT_INCLUDED; if (host == null) { return result; } HostKey hk = null; try { hk = new HostKey(host, HostKey.GUESS, key); } catch (Exception e) { // unsupported key jsch.getInstanceLogger().log(Logger.DEBUG, "exception while trying to read key while checking host '" + host + "'", e); return result; } synchronized (pool) { for (int i = 0; i < pool.size(); i++) { HostKey _hk = pool.elementAt(i); if (_hk.isMatched(host) && _hk.type == hk.type) { if (Util.array_equals(_hk.key, key)) { return OK; } result = CHANGED; } } } if (result == NOT_INCLUDED && host.startsWith("[") && host.indexOf("]:") > 1) { return check(host.substring(1, host.indexOf("]:")), key); } return result; } @Override public void add(HostKey hostkey, UserInfo userinfo) { int type = hostkey.type; String host = hostkey.getHost(); // byte[] key=hostkey.key; HostKey hk = null; synchronized (pool) { for (int i = 0; i < pool.size(); i++) { hk = pool.elementAt(i); if (hk.isMatched(host) && hk.type == type) { /* * if(Util.array_equals(hk.key, key)){ return; } if(hk.host.equals(host)){ hk.key=key; * return; } else{ hk.host=deleteSubString(hk.host, host); break; } */ } } } hk = hostkey; pool.addElement(hk); syncKnownHostsFile(userinfo); } void syncKnownHostsFile(UserInfo userinfo) { String khFilename = getKnownHostsRepositoryID(); if (khFilename == null) { return; } boolean doSync = true; File goo = new File(Util.checkTilde(khFilename)); if (!goo.exists()) { doSync = false; if (userinfo != null) { doSync = userinfo .promptYesNo(khFilename + " does not exist.\n" + "Are you sure you want to create it?"); goo = goo.getParentFile(); if (doSync && goo != null && !goo.exists()) { doSync = userinfo.promptYesNo("The parent directory " + goo + " does not exist.\n" + "Are you sure you want to create it?"); if (doSync) { if (!goo.mkdirs()) { userinfo.showMessage(goo + " has not been created."); doSync = false; } else { userinfo.showMessage( goo + " has been succesfully created.\nPlease check its access permission."); } } } if (goo == null) doSync = false; } } if (!doSync) { return; } try { sync(khFilename); } catch (Exception e) { jsch.getInstanceLogger().log(Logger.ERROR, "unable to sync known host file " + goo.getPath(), e); } } @Override public HostKey[] getHostKey() { return getHostKey(null, (String) null); } @Override public HostKey[] getHostKey(String host, String type) { synchronized (pool) { List v = new ArrayList<>(); for (int i = 0; i < pool.size(); i++) { HostKey hk = pool.elementAt(i); if (hk.type == HostKey.UNKNOWN) continue; if (host == null || (hk.isMatched(host) && (type == null || hk.getType().equals(type)))) { v.add(hk); } } HostKey[] foo = new HostKey[v.size()]; for (int i = 0; i < v.size(); i++) { foo[i] = v.get(i); } if (host != null && host.startsWith("[") && host.indexOf("]:") > 1) { HostKey[] tmp = getHostKey(host.substring(1, host.indexOf("]:")), type); if (tmp.length > 0) { HostKey[] bar = new HostKey[foo.length + tmp.length]; System.arraycopy(foo, 0, bar, 0, foo.length); System.arraycopy(tmp, 0, bar, foo.length, tmp.length); foo = bar; } } return foo; } } @Override public void remove(String host, String type) { remove(host, type, null); } @Override public void remove(String host, String type, byte[] key) { boolean sync = false; synchronized (pool) { for (int i = 0; i < pool.size(); i++) { HostKey hk = pool.elementAt(i); if (host == null || (hk.isMatched(host) && (type == null || (hk.getType().equals(type) && (key == null || Util.array_equals(key, hk.key)))))) { String hosts = hk.getHost(); if (host == null || hosts.equals(host) || ((hk instanceof HashedHostKey) && ((HashedHostKey) hk).isHashed())) { pool.removeElement(hk); i--; } else { hk.host = deleteSubString(hosts, host); } sync = true; } } } if (sync) { try { sync(); } catch (Exception e) { } ; } } void sync() throws IOException { if (known_hosts != null) sync(known_hosts); } synchronized void sync(String foo) throws IOException { if (foo == null) return; try (FileOutputStream fos = new FileOutputStream(Util.checkTilde(foo))) { dump(fos); } } private static final byte[] space = {(byte) 0x20}; private static final byte[] lf = Util.str2byte("\n"); void dump(OutputStream out) { try { HostKey hk; synchronized (pool) { for (int i = 0; i < pool.size(); i++) { hk = pool.elementAt(i); dumpHostKey(out, hk); } } } catch (Exception e) { jsch.getInstanceLogger().log(Logger.ERROR, "unable to dump known hosts", e); } } void dumpHostKey(OutputStream out, HostKey hk) throws IOException { String marker = hk.getMarker(); String host = hk.getHost(); String type = hk.getType(); String comment = hk.getComment(); if (type.equals("UNKNOWN")) { out.write(Util.str2byte(host)); out.write(lf); return; } if (marker.length() != 0) { out.write(Util.str2byte(marker)); out.write(space); } out.write(Util.str2byte(host)); out.write(space); out.write(Util.str2byte(type)); out.write(space); out.write(Util.str2byte(hk.getKey())); if (comment != null) { out.write(space); out.write(Util.str2byte(comment)); } out.write(lf); } String deleteSubString(String hosts, String host) { int i = 0; int hostlen = host.length(); int hostslen = hosts.length(); int j; while (i < hostslen) { j = hosts.indexOf(',', i); if (j == -1) break; if (!host.equals(hosts.substring(i, j))) { i = j + 1; continue; } return hosts.substring(0, i) + hosts.substring(j + 1); } if (hosts.endsWith(host) && hostslen - i == hostlen) { return hosts.substring(0, (hostlen == hostslen) ? 0 : hostslen - hostlen - 1); } return hosts; } MAC getHMACSHA1() throws IllegalArgumentException { if (hmacsha1 == null) { hmacsha1 = createHMAC(JSch.getConfig("hmac-sha1")); } return hmacsha1; } MAC createHMAC(String hmacClassname) throws IllegalArgumentException { try { Class c = Class.forName(hmacClassname).asSubclass(MAC.class); return c.getDeclaredConstructor().newInstance(); } catch (Exception e) { jsch.getInstanceLogger().log(Logger.ERROR, "unable to instantiate HMAC-class " + hmacClassname, e); throw new IllegalArgumentException("instantiation of " + hmacClassname + " lead to an error", e); } } HostKey createHashedHostKey(String host, byte[] key) throws JSchException { HashedHostKey hhk = new HashedHostKey(host, key); hhk.hash(); return hhk; } class HashedHostKey extends HostKey { private static final String HASH_MAGIC = "|1|"; private static final String HASH_DELIM = "|"; private boolean hashed = false; byte[] salt = null; byte[] hash = null; HashedHostKey(String host, byte[] key) throws JSchException { this(host, GUESS, key); } HashedHostKey(String host, int type, byte[] key) throws JSchException { this("", host, type, key, null); } HashedHostKey(String marker, String host, int type, byte[] key, String comment) throws JSchException { super(marker, host, type, key, comment); if (this.host.startsWith(HASH_MAGIC) && this.host.substring(HASH_MAGIC.length()).indexOf(HASH_DELIM) > 0) { String data = this.host.substring(HASH_MAGIC.length()); String _salt = data.substring(0, data.indexOf(HASH_DELIM)); String _hash = data.substring(data.indexOf(HASH_DELIM) + 1); salt = Util.fromBase64(Util.str2byte(_salt), 0, _salt.length()); hash = Util.fromBase64(Util.str2byte(_hash), 0, _hash.length()); int blockSize = hmacsha1.getBlockSize(); if (salt.length != blockSize || hash.length != blockSize) { salt = null; hash = null; return; } hashed = true; } } @Override boolean isMatched(String _host) { if (!hashed) { return super.isMatched(_host); } try { synchronized (hmacsha1) { hmacsha1.init(salt); byte[] foo = Util.str2byte(_host); hmacsha1.update(foo, 0, foo.length); byte[] bar = new byte[hmacsha1.getBlockSize()]; hmacsha1.doFinal(bar, 0); return Util.array_equals(hash, bar); } } catch (Exception e) { jsch.getInstanceLogger().log(Logger.ERROR, "an error occurred while trying to check hash for host " + _host, e); } return false; } boolean isHashed() { return hashed; } void hash() { if (hashed) return; if (salt == null) { Random random = Session.random; synchronized (random) { salt = new byte[hmacsha1.getBlockSize()]; random.fill(salt, 0, salt.length); } } try { synchronized (hmacsha1) { hmacsha1.init(salt); byte[] foo = Util.str2byte(host); hmacsha1.update(foo, 0, foo.length); hash = new byte[hmacsha1.getBlockSize()]; hmacsha1.doFinal(hash, 0); } } catch (Exception e) { jsch.getInstanceLogger().log(Logger.ERROR, "an error occurred while trying to calculate the hash for host " + host, e); salt = null; hash = null; return; } host = HASH_MAGIC + Util.byte2str(Util.toBase64(salt, 0, salt.length, true)) + HASH_DELIM + Util.byte2str(Util.toBase64(hash, 0, hash.length, true)); hashed = true; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java000066400000000000000000000113441465436372100276310ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Vector; class LocalIdentityRepository implements IdentityRepository { private static final String name = "Local Identity Repository"; private Vector identities = new Vector<>(); private JSch.InstanceLogger instLogger; LocalIdentityRepository(JSch.InstanceLogger instLogger) { this.instLogger = instLogger; } @Override public String getName() { return name; } @Override public int getStatus() { return RUNNING; } @Override public synchronized Vector getIdentities() { removeDupulicates(); Vector v = new Vector<>(); for (int i = 0; i < identities.size(); i++) { v.addElement(identities.elementAt(i)); } return v; } public synchronized void add(Identity identity) { if (!identities.contains(identity)) { byte[] blob1 = identity.getPublicKeyBlob(); if (blob1 == null) { identities.addElement(identity); return; } for (int i = 0; i < identities.size(); i++) { byte[] blob2 = identities.elementAt(i).getPublicKeyBlob(); if (blob2 != null && Util.array_equals(blob1, blob2)) { if (!identity.isEncrypted() && identities.elementAt(i).isEncrypted()) { remove(blob2); } else { return; } } } identities.addElement(identity); } } @Override public synchronized boolean add(byte[] identity) { try { Identity _identity = IdentityFile.newInstance("from remote:", identity, null, instLogger); add(_identity); return true; } catch (JSchException e) { return false; } } synchronized void remove(Identity identity) { if (identities.contains(identity)) { identities.removeElement(identity); identity.clear(); } else { remove(identity.getPublicKeyBlob()); } } @Override public synchronized boolean remove(byte[] blob) { if (blob == null) return false; for (int i = 0; i < identities.size(); i++) { Identity _identity = identities.elementAt(i); byte[] _blob = _identity.getPublicKeyBlob(); if (_blob == null || !Util.array_equals(blob, _blob)) continue; identities.removeElement(_identity); _identity.clear(); return true; } return false; } @Override public synchronized void removeAll() { for (int i = 0; i < identities.size(); i++) { Identity identity = identities.elementAt(i); identity.clear(); } identities.removeAllElements(); } private void removeDupulicates() { Vector v = new Vector<>(); int len = identities.size(); if (len == 0) return; for (int i = 0; i < len; i++) { Identity foo = identities.elementAt(i); byte[] foo_blob = foo.getPublicKeyBlob(); if (foo_blob == null) continue; for (int j = i + 1; j < len; j++) { Identity bar = identities.elementAt(j); byte[] bar_blob = bar.getPublicKeyBlob(); if (bar_blob == null) continue; if (Util.array_equals(foo_blob, bar_blob) && foo.isEncrypted() == bar.isEncrypted()) { v.addElement(foo_blob); break; } } } for (int i = 0; i < v.size(); i++) { remove(v.elementAt(i)); } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Log4j2Logger.java000066400000000000000000000022551465436372100251670ustar00rootroot00000000000000package com.jcraft.jsch; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Log4j2Logger implements com.jcraft.jsch.Logger { private static final Logger logger = LogManager.getLogger(JSch.class); public Log4j2Logger() {} @Override public boolean isEnabled(int level) { return logger.isEnabled(getLevel(level)); } @Override public void log(int level, String message) { logger.log(getLevel(level), message); } @Override public void log(int level, String message, Throwable cause) { if (cause == null) { logger.log(getLevel(level), message); return; } logger.log(getLevel(level), message, cause); } static Level getLevel(int level) { switch (level) { case com.jcraft.jsch.Logger.DEBUG: return Level.DEBUG; case com.jcraft.jsch.Logger.INFO: return Level.INFO; case com.jcraft.jsch.Logger.WARN: return Level.WARN; case com.jcraft.jsch.Logger.ERROR: return Level.ERROR; case com.jcraft.jsch.Logger.FATAL: return Level.FATAL; default: return Level.TRACE; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Logger.java000066400000000000000000000050041465436372100242000ustar00rootroot00000000000000/* * Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.PrintWriter; import java.io.StringWriter; public interface Logger { public final int DEBUG = 0; public final int INFO = 1; public final int WARN = 2; public final int ERROR = 3; public final int FATAL = 4; public boolean isEnabled(int level); public void log(int level, String message); public default void log(int level, String message, Throwable cause) { if (!isEnabled(level)) { return; } if (cause != null) { StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw, true)) { cause.printStackTrace(pw); } message += System.lineSeparator() + sw.toString(); } log(level, message); } /* * public final Logger SIMPLE_LOGGER=new Logger(){ public boolean isEnabled(int level){return * true;} public void log(int level, String message){System.err.println(message);} }; final Logger * DEVNULL=new Logger(){ public boolean isEnabled(int level){return false;} public void log(int * level, String message){} }; */ } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/MAC.java000066400000000000000000000034031465436372100233620ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface MAC { String getName(); int getBlockSize(); void init(byte[] key) throws Exception; void update(byte[] foo, int start, int len); void update(int foo); void doFinal(byte[] buf, int offset); default boolean isEtM() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/OpenSSHConfig.java000066400000000000000000000240151465436372100253710ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Hashtable; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.Vector; import java.util.stream.Collectors; import java.util.stream.Stream; /** * This class implements ConfigRepository interface, and parses OpenSSH's configuration file. The * following keywords will be recognized, * *

    *
  • Host
  • *
  • User
  • *
  • Hostname
  • *
  • Port
  • *
  • PreferredAuthentications
  • *
  • PubkeyAcceptedAlgorithms
  • *
  • FingerprintHash
  • *
  • IdentityFile
  • *
  • NumberOfPasswordPrompts
  • *
  • ConnectTimeout
  • *
  • HostKeyAlias
  • *
  • UserKnownHostsFile
  • *
  • KexAlgorithms
  • *
  • HostKeyAlgorithms
  • *
  • Ciphers
  • *
  • Macs
  • *
  • Compression
  • *
  • CompressionLevel
  • *
  • ForwardAgent
  • *
  • RequestTTY
  • *
  • ServerAliveInterval
  • *
  • LocalForward
  • *
  • RemoteForward
  • *
  • ClearAllForwardings
  • *
* * @see ConfigRepository */ public class OpenSSHConfig implements ConfigRepository { private static final Set keysWithListAdoption = Stream .of("KexAlgorithms", "Ciphers", "HostKeyAlgorithms", "MACs", "PubkeyAcceptedAlgorithms", "PubkeyAcceptedKeyTypes") .map(string -> string.toUpperCase(Locale.ROOT)).collect(Collectors.toSet()); /** * Parses the given string, and returns an instance of ConfigRepository. * * @param conf string, which includes OpenSSH's config * @return an instanceof OpenSSHConfig */ public static OpenSSHConfig parse(String conf) throws IOException { try (Reader r = new StringReader(conf)) { try (BufferedReader br = new BufferedReader(r)) { return new OpenSSHConfig(br); } } } /** * Parses the given file, and returns an instance of ConfigRepository. * * @param file OpenSSH's config file * @return an instanceof OpenSSHConfig */ public static OpenSSHConfig parseFile(String file) throws IOException { try (BufferedReader br = Files.newBufferedReader(Paths.get(Util.checkTilde(file)), StandardCharsets.UTF_8)) { return new OpenSSHConfig(br); } } OpenSSHConfig(BufferedReader br) throws IOException { _parse(br); } private final Hashtable> config = new Hashtable<>(); private final Vector hosts = new Vector<>(); private void _parse(BufferedReader br) throws IOException { String host = ""; Vector kv = new Vector<>(); String l = null; while ((l = br.readLine()) != null) { l = l.trim(); if (l.length() == 0 || l.startsWith("#")) continue; String[] key_value = l.split("[= \t]", 2); for (int i = 0; i < key_value.length; i++) key_value[i] = key_value[i].trim(); if (key_value.length <= 1) continue; if (key_value[0].equalsIgnoreCase("Host")) { config.put(host, kv); hosts.addElement(host); host = key_value[1]; kv = new Vector<>(); } else { kv.addElement(key_value); } } config.put(host, kv); hosts.addElement(host); } @Override public Config getConfig(String host) { return new MyConfig(host); } /** * Returns mapping of jsch config property names to OpenSSH property names. * * @return map */ static Hashtable getKeymap() { return keymap; } private static final Hashtable keymap = new Hashtable<>(); static { keymap.put("kex", "KexAlgorithms"); keymap.put("server_host_key", "HostKeyAlgorithms"); keymap.put("cipher.c2s", "Ciphers"); keymap.put("cipher.s2c", "Ciphers"); keymap.put("mac.c2s", "Macs"); keymap.put("mac.s2c", "Macs"); keymap.put("compression.s2c", "Compression"); keymap.put("compression.c2s", "Compression"); keymap.put("compression_level", "CompressionLevel"); keymap.put("MaxAuthTries", "NumberOfPasswordPrompts"); } class MyConfig implements Config { private String host; private Vector> _configs = new Vector<>(); MyConfig(String host) { this.host = host; _configs.addElement(config.get("")); byte[] _host = Util.str2byte(host); if (hosts.size() > 1) { for (int i = 1; i < hosts.size(); i++) { boolean anyPositivePatternMatches = false; boolean anyNegativePatternMatches = false; String patterns[] = hosts.elementAt(i).split("[ \t]"); for (int j = 0; j < patterns.length; j++) { boolean negate = false; String foo = patterns[j].trim(); if (foo.startsWith("!")) { negate = true; foo = foo.substring(1).trim(); } if (Util.glob(Util.str2byte(foo), _host)) { if (negate) { anyNegativePatternMatches = true; } else { anyPositivePatternMatches = true; } } } if (anyPositivePatternMatches && !anyNegativePatternMatches) { _configs.addElement(config.get(hosts.elementAt(i))); } } } } private String find(String key) { String originalKey = key; if (keymap.get(key) != null) { key = keymap.get(key); } key = key.toUpperCase(Locale.ROOT); String value = null; for (int i = 0; i < _configs.size(); i++) { Vector v = _configs.elementAt(i); for (int j = 0; j < v.size(); j++) { String[] kv = v.elementAt(j); if (kv[0].toUpperCase(Locale.ROOT).equals(key)) { value = kv[1]; break; } } if (value != null) break; } // TODO: The following change should be applied, // but it is breaking changes. // The consensus is required to enable it. /* * if(value!=null && (key.equals("SERVERALIVEINTERVAL") || key.equals("CONNECTTIMEOUT"))){ try * { int timeout = Integer.parseInt(value); value = Integer.toString(timeout*1000); } catch * (NumberFormatException e) { } } */ if (keysWithListAdoption.contains(key) && value != null && (value.startsWith("+") || value.startsWith("-") || value.startsWith("^"))) { String origConfig = JSch.getConfig(originalKey).trim(); if (value.startsWith("+")) { value = origConfig + "," + value.substring(1).trim(); } else if (value.startsWith("-")) { List algList = Arrays.stream(Util.split(origConfig, ",")).collect(Collectors.toList()); for (String alg : Util.split(value.substring(1).trim(), ",")) { algList.remove(alg.trim()); } value = String.join(",", algList); } else if (value.startsWith("^")) { value = value.substring(1).trim() + "," + origConfig; } } return value; } private String[] multiFind(String key) { key = key.toUpperCase(Locale.ROOT); Vector value = new Vector<>(); for (int i = 0; i < _configs.size(); i++) { Vector v = _configs.elementAt(i); for (int j = 0; j < v.size(); j++) { String[] kv = v.elementAt(j); if (kv[0].toUpperCase(Locale.ROOT).equals(key)) { String foo = kv[1]; if (foo != null) { value.remove(foo); value.addElement(foo); } } } } String[] result = new String[value.size()]; value.toArray(result); return result; } @Override public String getHostname() { return find("Hostname"); } @Override public String getUser() { return find("User"); } @Override public int getPort() { String foo = find("Port"); int port = -1; try { port = Integer.parseInt(foo); } catch (NumberFormatException e) { // wrong format } return port; } @Override public String getValue(String key) { if (key.equals("compression.s2c") || key.equals("compression.c2s")) { String foo = find(key); if (foo == null || foo.equals("no")) return "none,zlib@openssh.com,zlib"; return "zlib@openssh.com,zlib,none"; } return find(key); } @Override public String[] getValues(String key) { return multiFind(key); } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/PBKDF.java000066400000000000000000000031651465436372100236150ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; /** Use PBKDF2 instead. */ @Deprecated public interface PBKDF { byte[] getKey(byte[] pass, byte[] salt, int iteration, int size); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/PBKDF2.java000066400000000000000000000031211465436372100236670ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface PBKDF2 extends KDF { void init(byte[] salt, int iteration) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Packet.java000066400000000000000000000073611465436372100242000ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class Packet { private static Random random = null; static void setRandom(Random foo) { random = foo; } Buffer buffer; byte[] ba4 = new byte[4]; Packet(Buffer buffer) { this.buffer = buffer; } void reset() { buffer.index = 5; } void padding(int bsize, boolean includePktLen) { int len = buffer.index; if (!includePktLen) { len -= 4; } int pad = (-len) & (bsize - 1); if (pad < bsize) { pad += bsize; } len += pad; if (includePktLen) { len -= 4; } ba4[0] = (byte) (len >>> 24); ba4[1] = (byte) (len >>> 16); ba4[2] = (byte) (len >>> 8); ba4[3] = (byte) (len); System.arraycopy(ba4, 0, buffer.buffer, 0, 4); buffer.buffer[4] = (byte) pad; synchronized (random) { random.fill(buffer.buffer, buffer.index, pad); } buffer.skip(pad); // buffer.putPad(pad); /* * for(int i=0; i AGENT_MAX_MSGLEN) { throw new AgentProxyException("Query too large."); } HWND hwnd = user32.FindWindow("Pageant", "Pageant"); if (hwnd == null) { throw new AgentProxyException("Pageant is not runnning."); } String mapname = String.format(Locale.ROOT, "PageantRequest%08x", kernel32.GetCurrentThreadId()); HANDLE sharedFile = null; Pointer sharedMemory = null; try { // TODO SECURITY_ATTRIBUTES psa = null; sharedFile = kernel32.CreateFileMapping(WinBase.INVALID_HANDLE_VALUE, psa, WinNT.PAGE_READWRITE, 0, AGENT_MAX_MSGLEN, mapname); if (sharedFile == null || sharedFile == WinBase.INVALID_HANDLE_VALUE) { throw new AgentProxyException("Unable to create shared file mapping."); } sharedMemory = kernel32.MapViewOfFile(sharedFile, WinNT.SECTION_MAP_WRITE, 0, 0, 0); if (sharedMemory == null) { throw new AgentProxyException("Unable to create shared file mapping."); } sharedMemory.write(0, buffer.buffer, 0, buffer.getLength()); COPYDATASTRUCT cds = createCDS(mapname); long rcode = sendMessage(hwnd, cds); // Dummy read to make sure COPYDATASTRUCT isn't GC'd early long foo = cds.dwData.longValue(); buffer.rewind(); if (rcode != 0) { sharedMemory.read(0, buffer.buffer, 0, 4); // length int i = buffer.getInt(); if (i <= 0 || i > AGENT_MAX_MSGLEN - 4) { throw new AgentProxyException("Illegal length: " + i); } buffer.rewind(); buffer.checkFreeSize(i); sharedMemory.read(4, buffer.buffer, 0, i); } else { throw new AgentProxyException( "User32.SendMessage() returned 0 with cds.dwData: " + Long.toHexString(foo)); } } finally { if (sharedMemory != null) kernel32.UnmapViewOfFile(sharedMemory); if (sharedFile != null) kernel32.CloseHandle(sharedFile); } } static COPYDATASTRUCT createCDS(String mapname) { Memory foo = new Memory(mapname.length() + 1); foo.setString(0, mapname, "US-ASCII"); COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.dwData = new ULONG_PTR(AGENT_COPYDATA_ID); cds.cbData = (int) foo.size(); cds.lpData = foo; cds.write(); return cds; } long sendMessage(HWND hwnd, COPYDATASTRUCT cds) { LPARAM data = new LPARAM(Pointer.nativeValue(cds.getPointer())); LRESULT result = user32.SendMessage(hwnd, WinUser.WM_COPYDATA, null, data); return result.longValue(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/PortWatcher.java000066400000000000000000000204571465436372100252340ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.util.Vector; class PortWatcher { private static Vector pool = new Vector<>(); private static InetAddress anyLocalAddress = null; static { // 0.0.0.0 /* * try{ anyLocalAddress=InetAddress.getByAddress(new byte[4]); } catch(UnknownHostException e){ * } */ try { anyLocalAddress = InetAddress.getByName("0.0.0.0"); } catch (UnknownHostException e) { } } Session session; int lport; int rport; String host; InetAddress boundaddress; Runnable thread; ServerSocket ss; int connectTimeout = 0; private String socketPath; PortWatcher(Session session, String address, int lport, String socketPath, ServerSocketFactory ssf) throws JSchException { this.session = session; this.lport = lport; this.socketPath = socketPath; bindLocalPort(address, lport, ssf); } private void bindLocalPort(String address, int lport, ServerSocketFactory ssf) throws JSchException { try { boundaddress = InetAddress.getByName(address); ss = (ssf == null) ? new ServerSocket(lport, 0, boundaddress) : ssf.createServerSocket(lport, 0, boundaddress); } catch (Exception e) { String message = "PortForwardingL: local port " + address + ":" + lport + " cannot be bound."; throw new JSchException(message, e); } if (lport == 0) { int assigned = ss.getLocalPort(); if (assigned != -1) this.lport = assigned; } } static String[] getPortForwarding(Session session) { Vector foo = new Vector<>(); synchronized (pool) { for (int i = 0; i < pool.size(); i++) { PortWatcher p = pool.elementAt(i); if (p.session == session) { foo.addElement(p.lport + ":" + p.host + ":" + p.rport); } } } String[] bar = new String[foo.size()]; for (int i = 0; i < foo.size(); i++) { bar[i] = foo.elementAt(i); } return bar; } static PortWatcher getPort(Session session, String address, int lport) throws JSchException { InetAddress addr; try { addr = InetAddress.getByName(address); } catch (UnknownHostException uhe) { throw new JSchException("PortForwardingL: invalid address " + address + " specified.", uhe); } synchronized (pool) { for (int i = 0; i < pool.size(); i++) { PortWatcher p = pool.elementAt(i); if (p.session == session && p.lport == lport) { if (/* p.boundaddress.isAnyLocalAddress() || */ (anyLocalAddress != null && p.boundaddress.equals(anyLocalAddress)) || p.boundaddress.equals(addr)) return p; } } return null; } } private static String normalize(String address) { if (address != null) { if (address.length() == 0 || address.equals("*")) address = "0.0.0.0"; else if (address.equals("localhost")) address = "127.0.0.1"; } return address; } static PortWatcher addPort(Session session, String address, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException { address = normalize(address); if (getPort(session, address, lport) != null) { throw new JSchException( "PortForwardingL: local port " + address + ":" + lport + " is already registered."); } PortWatcher pw = new PortWatcher(session, address, lport, host, rport, ssf); pool.addElement(pw); return pw; } static void delPort(Session session, String address, int lport) throws JSchException { address = normalize(address); PortWatcher pw = getPort(session, address, lport); if (pw == null) { throw new JSchException( "PortForwardingL: local port " + address + ":" + lport + " is not registered."); } pw.delete(); pool.removeElement(pw); } static void delPort(Session session) { synchronized (pool) { PortWatcher[] foo = new PortWatcher[pool.size()]; int count = 0; for (int i = 0; i < pool.size(); i++) { PortWatcher p = pool.elementAt(i); if (p.session == session) { p.delete(); foo[count++] = p; } } for (int i = 0; i < count; i++) { PortWatcher p = foo[i]; pool.removeElement(p); } } } PortWatcher(Session session, String address, int lport, String host, int rport, ServerSocketFactory factory) throws JSchException { this.session = session; this.lport = lport; this.host = host; this.rport = rport; bindLocalPort(address, lport, factory); } public static PortWatcher addSocket(Session session, String bindAddress, int lport, String socketPath, ServerSocketFactory ssf) throws JSchException { String address = normalize(bindAddress); if (getPort(session, address, lport) != null) { throw new JSchException( "PortForwardingL: local port " + address + ":" + lport + " is already registered."); } PortWatcher pw = new PortWatcher(session, address, lport, socketPath, ssf); pool.addElement(pw); return pw; } void run() { thread = this::run; try { while (thread != null) { Socket socket = ss.accept(); socket.setTcpNoDelay(true); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); if (socketPath != null && socketPath.length() > 0) { ChannelDirectStreamLocal channel = new ChannelDirectStreamLocal(); channel.setSession(session); channel.init(); channel.setInputStream(in); channel.setOutputStream(out); session.addChannel(channel); channel.setSocketPath(socketPath); channel.setOrgIPAddress(socket.getInetAddress().getHostAddress()); channel.setOrgPort(socket.getPort()); channel.connect(connectTimeout); } else { ChannelDirectTCPIP channel = new ChannelDirectTCPIP(); channel.setSession(session); channel.init(); channel.setInputStream(in); channel.setOutputStream(out); session.addChannel(channel); channel.setHost(host); channel.setPort(rport); channel.setOrgIPAddress(socket.getInetAddress().getHostAddress()); channel.setOrgPort(socket.getPort()); channel.connect(connectTimeout); if (channel.exitstatus != -1) { } } } } catch (Exception e) { // System.err.println("! "+e); } delete(); } void delete() { thread = null; try { if (ss != null) ss.close(); ss = null; } catch (Exception e) { } } void setConnectTimeout(int connectTimeout) { this.connectTimeout = connectTimeout; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Proxy.java000066400000000000000000000034531465436372100241100ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public interface Proxy { void connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception; InputStream getInputStream(); OutputStream getOutputStream(); Socket getSocket(); void close(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ProxyHTTP.java000066400000000000000000000134241465436372100246070ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class ProxyHTTP implements Proxy { private static int DEFAULTPORT = 80; private String proxy_host; private int proxy_port; private InputStream in; private OutputStream out; private Socket socket; private String user; private String passwd; public ProxyHTTP(String proxy_host) { int port = DEFAULTPORT; String host = proxy_host; if (proxy_host.indexOf(':') != -1) { try { host = proxy_host.substring(0, proxy_host.indexOf(':')); port = Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':') + 1)); } catch (Exception e) { } } this.proxy_host = host; this.proxy_port = port; } public ProxyHTTP(String proxy_host, int proxy_port) { this.proxy_host = proxy_host; this.proxy_port = proxy_port; } public void setUserPasswd(String user, String passwd) { this.user = user; this.passwd = passwd; } @Override public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException { try { if (socket_factory == null) { socket = Util.createSocket(proxy_host, proxy_port, timeout); in = socket.getInputStream(); out = socket.getOutputStream(); } else { socket = socket_factory.createSocket(proxy_host, proxy_port); in = socket_factory.getInputStream(socket); out = socket_factory.getOutputStream(socket); } if (timeout > 0) { socket.setSoTimeout(timeout); } socket.setTcpNoDelay(true); out.write(Util.str2byte("CONNECT " + host + ":" + port + " HTTP/1.0\r\n")); if (user != null && passwd != null) { byte[] code = Util.str2byte(user + ":" + passwd); code = Util.toBase64(code, 0, code.length, true); out.write(Util.str2byte("Proxy-Authorization: Basic ")); out.write(code); out.write(Util.str2byte("\r\n")); } out.write(Util.str2byte("\r\n")); out.flush(); int foo = 0; StringBuilder sb = new StringBuilder(); while (foo >= 0) { foo = in.read(); if (foo != 13) { sb.append((char) foo); continue; } foo = in.read(); if (foo != 10) { continue; } break; } if (foo < 0) { throw new IOException(); } String response = sb.toString(); String reason = "Unknow reason"; int code = -1; try { foo = response.indexOf(' '); int bar = response.indexOf(' ', foo + 1); code = Integer.parseInt(response.substring(foo + 1, bar)); reason = response.substring(bar + 1); } catch (Exception e) { } if (code != 200) { throw new IOException("proxy error: " + reason); } /* * while(foo>=0){ foo=in.read(); if(foo!=13) continue; foo=in.read(); if(foo!=10) continue; * foo=in.read(); if(foo!=13) continue; foo=in.read(); if(foo!=10) continue; break; } */ int count = 0; while (true) { count = 0; while (foo >= 0) { foo = in.read(); if (foo != 13) { count++; continue; } foo = in.read(); if (foo != 10) { continue; } break; } if (foo < 0) { throw new IOException(); } if (count == 0) break; } } catch (RuntimeException e) { throw e; } catch (Exception e) { try { if (socket != null) socket.close(); } catch (Exception eee) { } String message = "ProxyHTTP: " + e.toString(); throw new JSchProxyException(message, e); } } @Override public InputStream getInputStream() { return in; } @Override public OutputStream getOutputStream() { return out; } @Override public Socket getSocket() { return socket; } @Override public void close() { try { if (in != null) in.close(); if (out != null) out.close(); if (socket != null) socket.close(); } catch (Exception e) { } in = null; out = null; socket = null; } public static int getDefaultPort() { return DEFAULTPORT; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ProxySOCKS4.java000066400000000000000000000165541465436372100250050ustar00rootroot00000000000000/* * Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file depends on following documents, - SOCKS: A protocol for TCP proxy across firewalls, * Ying-Da Lee http://www.socks.nec.com/protocol/socks4.protocol */ package com.jcraft.jsch; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class ProxySOCKS4 implements Proxy { private static int DEFAULTPORT = 1080; private String proxy_host; private int proxy_port; private InputStream in; private OutputStream out; private Socket socket; private String user; private String passwd; public ProxySOCKS4(String proxy_host) { int port = DEFAULTPORT; String host = proxy_host; if (proxy_host.indexOf(':') != -1) { try { host = proxy_host.substring(0, proxy_host.indexOf(':')); port = Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':') + 1)); } catch (Exception e) { } } this.proxy_host = host; this.proxy_port = port; } public ProxySOCKS4(String proxy_host, int proxy_port) { this.proxy_host = proxy_host; this.proxy_port = proxy_port; } public void setUserPasswd(String user, String passwd) { this.user = user; this.passwd = passwd; } @Override public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException { try { if (socket_factory == null) { socket = Util.createSocket(proxy_host, proxy_port, timeout); // socket=new Socket(proxy_host, proxy_port); in = socket.getInputStream(); out = socket.getOutputStream(); } else { socket = socket_factory.createSocket(proxy_host, proxy_port); in = socket_factory.getInputStream(socket); out = socket_factory.getOutputStream(socket); } if (timeout > 0) { socket.setSoTimeout(timeout); } socket.setTcpNoDelay(true); byte[] buf = new byte[1024]; int index = 0; /* * 1) CONNECT * * The client connects to the SOCKS server and sends a CONNECT request when it wants to * establish a connection to an application server. The client includes in the request packet * the IP address and the port number of the destination host, and userid, in the following * format. * * +----+----+----+----+----+----+----+----+----+----+....+----+ | VN | CD | DSTPORT | DSTIP | * USERID |NULL| +----+----+----+----+----+----+----+----+----+----+....+----+ # of bytes: 1 1 * 2 4 variable 1 * * VN is the SOCKS protocol version number and should be 4. CD is the SOCKS command code and * should be 1 for CONNECT request. NULL is a byte of all zero bits. */ index = 0; buf[index++] = 4; buf[index++] = 1; buf[index++] = (byte) (port >>> 8); buf[index++] = (byte) (port & 0xff); try { InetAddress addr = InetAddress.getByName(host); byte[] byteAddress = addr.getAddress(); for (int i = 0; i < byteAddress.length; i++) { buf[index++] = byteAddress[i]; } } catch (UnknownHostException uhe) { throw new JSchProxyException("ProxySOCKS4: " + uhe.toString(), uhe); } if (user != null) { System.arraycopy(Util.str2byte(user), 0, buf, index, user.length()); index += user.length(); } buf[index++] = 0; out.write(buf, 0, index); /* * The SOCKS server checks to see whether such a request should be granted based on any * combination of source IP address, destination IP address, destination port number, the * userid, and information it may obtain by consulting IDENT, cf. RFC 1413. If the request is * granted, the SOCKS server makes a connection to the specified port of the destination host. * A reply packet is sent to the client when this connection is established, or when the * request is rejected or the operation fails. * * +----+----+----+----+----+----+----+----+ | VN | CD | DSTPORT | DSTIP | * +----+----+----+----+----+----+----+----+ # of bytes: 1 1 2 4 * * VN is the version of the reply code and should be 0. CD is the result code with one of the * following values: * * 90: request granted 91: request rejected or failed 92: request rejected becasue SOCKS * server cannot connect to identd on the client 93: request rejected because the client * program and identd report different user-ids * * The remaining fields are ignored. */ int len = 8; int s = 0; while (s < len) { int i = in.read(buf, s, len - s); if (i <= 0) { throw new JSchProxyException("ProxySOCKS4: stream is closed"); } s += i; } if (buf[0] != 0) { throw new JSchProxyException("ProxySOCKS4: server returns VN " + buf[0]); } if (buf[1] != 90) { try { socket.close(); } catch (Exception eee) { } String message = "ProxySOCKS4: server returns CD " + buf[1]; throw new JSchProxyException(message); } } catch (RuntimeException e) { throw e; } catch (Exception e) { try { if (socket != null) socket.close(); } catch (Exception eee) { } throw new JSchProxyException("ProxySOCKS4: " + e.toString(), e); } } @Override public InputStream getInputStream() { return in; } @Override public OutputStream getOutputStream() { return out; } @Override public Socket getSocket() { return socket; } @Override public void close() { try { if (in != null) in.close(); if (out != null) out.close(); if (socket != null) socket.close(); } catch (Exception e) { } in = null; out = null; socket = null; } public static int getDefaultPort() { return DEFAULTPORT; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ProxySOCKS5.java000066400000000000000000000255671465436372100250120ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file depends on following documents, - RFC 1928 SOCKS Protocol Verseion 5 - RFC 1929 * Username/Password Authentication for SOCKS V5. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class ProxySOCKS5 implements Proxy { private static int DEFAULTPORT = 1080; private String proxy_host; private int proxy_port; private InputStream in; private OutputStream out; private Socket socket; private String user; private String passwd; public ProxySOCKS5(String proxy_host) { int port = DEFAULTPORT; String host = proxy_host; if (proxy_host.indexOf(':') != -1) { try { host = proxy_host.substring(0, proxy_host.indexOf(':')); port = Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':') + 1)); } catch (Exception e) { } } this.proxy_host = host; this.proxy_port = port; } public ProxySOCKS5(String proxy_host, int proxy_port) { this.proxy_host = proxy_host; this.proxy_port = proxy_port; } public void setUserPasswd(String user, String passwd) { this.user = user; this.passwd = passwd; } @Override public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException { try { if (socket_factory == null) { socket = Util.createSocket(proxy_host, proxy_port, timeout); // socket=new Socket(proxy_host, proxy_port); in = socket.getInputStream(); out = socket.getOutputStream(); } else { socket = socket_factory.createSocket(proxy_host, proxy_port); in = socket_factory.getInputStream(socket); out = socket_factory.getOutputStream(socket); } if (timeout > 0) { socket.setSoTimeout(timeout); } socket.setTcpNoDelay(true); byte[] buf = new byte[1024]; int index = 0; /* * +----+----------+----------+ |VER | NMETHODS | METHODS | +----+----------+----------+ | 1 | * 1 | 1 to 255 | +----+----------+----------+ * * The VER field is set to X'05' for this version of the protocol. The NMETHODS field contains * the number of method identifier octets that appear in the METHODS field. * * The values currently defined for METHOD are: * * o X'00' NO AUTHENTICATION REQUIRED o X'01' GSSAPI o X'02' USERNAME/PASSWORD o X'03' to * X'7F' IANA ASSIGNED o X'80' to X'FE' RESERVED FOR PRIVATE METHODS o X'FF' NO ACCEPTABLE * METHODS */ buf[index++] = 5; buf[index++] = 2; buf[index++] = 0; // NO AUTHENTICATION REQUIRED buf[index++] = 2; // USERNAME/PASSWORD out.write(buf, 0, index); /* * The server selects from one of the methods given in METHODS, and sends a METHOD selection * message: * * +----+--------+ |VER | METHOD | +----+--------+ | 1 | 1 | +----+--------+ */ // in.read(buf, 0, 2); fill(in, buf, 2); boolean check = false; switch ((buf[1]) & 0xff) { case 0: // NO AUTHENTICATION REQUIRED check = true; break; case 2: // USERNAME/PASSWORD if (user == null || passwd == null) break; /* * Once the SOCKS V5 server has started, and the client has selected the Username/Password * Authentication protocol, the Username/Password subnegotiation begins. This begins with * the client producing a Username/Password request: * * +----+------+----------+------+----------+ |VER | ULEN | UNAME | PLEN | PASSWD | * +----+------+----------+------+----------+ | 1 | 1 | 1 to 255 | 1 | 1 to 255 | * +----+------+----------+------+----------+ * * The VER field contains the current version of the subnegotiation, which is X'01'. The * ULEN field contains the length of the UNAME field that follows. The UNAME field * contains the username as known to the source operating system. The PLEN field contains * the length of the PASSWD field that follows. The PASSWD field contains the password * association with the given UNAME. */ index = 0; buf[index++] = 1; buf[index++] = (byte) (user.length()); System.arraycopy(Util.str2byte(user), 0, buf, index, user.length()); index += user.length(); buf[index++] = (byte) (passwd.length()); System.arraycopy(Util.str2byte(passwd), 0, buf, index, passwd.length()); index += passwd.length(); out.write(buf, 0, index); /* * The server verifies the supplied UNAME and PASSWD, and sends the following response: * * +----+--------+ |VER | STATUS | +----+--------+ | 1 | 1 | +----+--------+ * * A STATUS field of X'00' indicates success. If the server returns a `failure' (STATUS * value other than X'00') status, it MUST close the connection. */ // in.read(buf, 0, 2); fill(in, buf, 2); if (buf[1] == 0) check = true; break; default: } if (!check) { try { socket.close(); } catch (Exception eee) { } throw new JSchProxyException("fail in SOCKS5 proxy"); } /* * The SOCKS request is formed as follows: * * +----+-----+-------+------+----------+----------+ |VER | CMD | RSV | ATYP | DST.ADDR | * DST.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable * | 2 | +----+-----+-------+------+----------+----------+ * * Where: * * o VER protocol version: X'05' o CMD o CONNECT X'01' o BIND X'02' o UDP ASSOCIATE X'03' o * RSV RESERVED o ATYP address type of following address o IP V4 address: X'01' o DOMAINNAME: * X'03' o IP V6 address: X'04' o DST.ADDR desired destination address o DST.PORT desired * destination port in network octet order */ index = 0; buf[index++] = 5; buf[index++] = 1; // CONNECT buf[index++] = 0; byte[] hostb = Util.str2byte(host); int len = hostb.length; buf[index++] = 3; // DOMAINNAME buf[index++] = (byte) (len); System.arraycopy(hostb, 0, buf, index, len); index += len; buf[index++] = (byte) (port >>> 8); buf[index++] = (byte) (port & 0xff); out.write(buf, 0, index); /* * The SOCKS request information is sent by the client as soon as it has established a * connection to the SOCKS server, and completed the authentication negotiations. The server * evaluates the request, and returns a reply formed as follows: * * +----+-----+-------+------+----------+----------+ |VER | REP | RSV | ATYP | BND.ADDR | * BND.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable * | 2 | +----+-----+-------+------+----------+----------+ * * Where: * * o VER protocol version: X'05' o REP Reply field: o X'00' succeeded o X'01' general SOCKS * server failure o X'02' connection not allowed by ruleset o X'03' Network unreachable o * X'04' Host unreachable o X'05' Connection refused o X'06' TTL expired o X'07' Command not * supported o X'08' Address type not supported o X'09' to X'FF' unassigned o RSV RESERVED o * ATYP address type of following address o IP V4 address: X'01' o DOMAINNAME: X'03' o IP V6 * address: X'04' o BND.ADDR server bound address o BND.PORT server bound port in network * octet order */ // in.read(buf, 0, 4); fill(in, buf, 4); if (buf[1] != 0) { try { socket.close(); } catch (Exception eee) { } throw new JSchProxyException("ProxySOCKS5: server returns " + buf[1]); } switch (buf[3] & 0xff) { case 1: // in.read(buf, 0, 6); fill(in, buf, 6); break; case 3: // in.read(buf, 0, 1); fill(in, buf, 1); // in.read(buf, 0, buf[0]+2); fill(in, buf, (buf[0] & 0xff) + 2); break; case 4: // in.read(buf, 0, 18); fill(in, buf, 18); break; default: } } catch (RuntimeException e) { throw e; } catch (Exception e) { try { if (socket != null) socket.close(); } catch (Exception eee) { } String message = "ProxySOCKS5: " + e.toString(); throw new JSchProxyException(message, e); } } @Override public InputStream getInputStream() { return in; } @Override public OutputStream getOutputStream() { return out; } @Override public Socket getSocket() { return socket; } @Override public void close() { try { if (in != null) in.close(); if (out != null) out.close(); if (socket != null) socket.close(); } catch (Exception e) { } in = null; out = null; socket = null; } public static int getDefaultPort() { return DEFAULTPORT; } private void fill(InputStream in, byte[] buf, int len) throws JSchException, IOException { int s = 0; while (s < len) { int i = in.read(buf, s, len - s); if (i <= 0) { throw new JSchProxyException("ProxySOCKS5: stream is closed"); } s += i; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Random.java000066400000000000000000000030701465436372100242020ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface Random { void fill(byte[] foo, int start, int len); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Request.java000066400000000000000000000051171465436372100244160ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; abstract class Request { private boolean reply = false; private Session session = null; private Channel channel = null; void request(Session session, Channel channel) throws Exception { this.session = session; this.channel = channel; if (channel.connectTimeout > 0) { setReply(true); } } boolean waitForReply() { return reply; } void setReply(boolean reply) { this.reply = reply; } void write(Packet packet) throws Exception { if (reply) { channel.reply = -1; } session.write(packet); if (reply) { long start = System.currentTimeMillis(); long timeout = channel.connectTimeout; while (channel.isConnected() && channel.reply == -1) { try { Thread.sleep(10); } catch (Exception ee) { } if (timeout > 0L && (System.currentTimeMillis() - start) > timeout) { channel.reply = 0; throw new JSchException("channel request: timeout"); } } if (channel.reply == 0) { throw new JSchException("failed to send channel request"); } } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java000066400000000000000000000042751465436372100274240ustar00rootroot00000000000000/* * Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestAgentForwarding extends Request { @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); setReply(false); Buffer buf = new Buffer(); Packet packet = new Packet(buf); // byte SSH_MSG_CHANNEL_REQUEST(98) // uint32 recipient channel // string request type // "auth-agent-req@openssh.com" // boolean want reply // 0 packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("auth-agent-req@openssh.com")); buf.putByte((byte) (waitForReply() ? 1 : 0)); write(packet); session.agent_forwarding = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestEnv.java000066400000000000000000000042101465436372100250600ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestEnv extends Request { byte[] name = new byte[0]; byte[] value = new byte[0]; void setEnv(byte[] name, byte[] value) { this.name = name; this.value = value; } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); setReply(false); Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("env")); buf.putByte((byte) 0); buf.putString(name); buf.putString(value); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestExec.java000066400000000000000000000044361465436372100252260ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestExec extends Request { private byte[] command = new byte[0]; RequestExec(byte[] command) { this.command = command; } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); // send // byte SSH_MSG_CHANNEL_REQUEST(98) // uint32 recipient channel // string request type // "exec" // boolean want reply // 0 // string command packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("exec")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.checkFreeSize(4 + command.length); buf.putString(command); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestPtyReq.java000066400000000000000000000051461465436372100255650ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestPtyReq extends Request { private String ttype = "vt100"; private int tcol = 80; private int trow = 24; private int twp = 640; private int thp = 480; private byte[] terminal_mode = Util.empty; void setCode(String cookie) {} void setTType(String ttype) { this.ttype = ttype; } void setTerminalMode(byte[] terminal_mode) { this.terminal_mode = terminal_mode; } void setTSize(int tcol, int trow, int twp, int thp) { this.tcol = tcol; this.trow = trow; this.twp = twp; this.thp = thp; } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("pty-req")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.putString(Util.str2byte(ttype)); buf.putInt(tcol); buf.putInt(trow); buf.putInt(twp); buf.putInt(thp); buf.putString(terminal_mode); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestSftp.java000066400000000000000000000040301465436372100252440ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestSftp extends Request { RequestSftp() { setReply(true); } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("subsystem")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.putString(Util.str2byte("sftp")); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestShell.java000066400000000000000000000041321465436372100254020ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestShell extends Request { @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); // send // byte SSH_MSG_CHANNEL_REQUEST(98) // uint32 recipient channel // string request type // "shell" // boolean want reply // 0 packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("shell")); buf.putByte((byte) (waitForReply() ? 1 : 0)); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestSignal.java000066400000000000000000000041151465436372100255510ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestSignal extends Request { private String signal = "KILL"; public void setSignal(String foo) { signal = foo; } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("signal")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.putString(Util.str2byte(signal)); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestSubsystem.java000066400000000000000000000043641465436372100263400ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestSubsystem extends Request { private String subsystem = null; public void request(Session session, Channel channel, String subsystem, boolean want_reply) throws Exception { setReply(want_reply); this.subsystem = subsystem; this.request(session, channel); } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("subsystem")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.putString(Util.str2byte(subsystem)); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestWindowChange.java000066400000000000000000000051501465436372100267110ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestWindowChange extends Request { int width_columns = 80; int height_rows = 24; int width_pixels = 640; int height_pixels = 480; void setSize(int col, int row, int wp, int hp) { this.width_columns = col; this.height_rows = row; this.width_pixels = wp; this.height_pixels = hp; } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); // byte SSH_MSG_CHANNEL_REQUEST // uint32 recipient_channel // string "window-change" // boolean FALSE // uint32 terminal width, columns // uint32 terminal height, rows // uint32 terminal width, pixels // uint32 terminal height, pixels packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("window-change")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.putInt(width_columns); buf.putInt(height_rows); buf.putInt(width_pixels); buf.putInt(height_pixels); write(packet); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/RequestX11.java000066400000000000000000000050321465436372100247040ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class RequestX11 extends Request { public void setCookie(String cookie) { ChannelX11.cookie = Util.str2byte(cookie); } @Override public void request(Session session, Channel channel) throws Exception { super.request(session, channel); Buffer buf = new Buffer(); Packet packet = new Packet(buf); // byte SSH_MSG_CHANNEL_REQUEST(98) // uint32 recipient channel // string request type // "x11-req" // boolean want reply // 0 // boolean single connection // string x11 authentication protocol // "MIT-MAGIC-COOKIE-1". // string x11 authentication cookie // uint32 x11 screen number packet.reset(); buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("x11-req")); buf.putByte((byte) (waitForReply() ? 1 : 0)); buf.putByte((byte) 0); buf.putString(Util.str2byte("MIT-MAGIC-COOKIE-1")); buf.putString(ChannelX11.getFakedCookie(session)); buf.putInt(0); write(packet); session.x11_forwarding = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SCrypt.java000066400000000000000000000031511465436372100242060ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface SCrypt extends KDF { void init(byte[] salt, int cost, int blocksize, int parallel) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SSHAgentConnector.java000066400000000000000000000113251465436372100262530ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.file.Path; import java.nio.file.Paths; public class SSHAgentConnector implements AgentConnector { private static final int MAX_AGENT_REPLY_LEN = 256 * 1024; private USocketFactory factory; private Path usocketPath; public SSHAgentConnector() throws AgentProxyException { this(getUSocketFactory(), getSshAuthSocket()); } public SSHAgentConnector(Path usocketPath) throws AgentProxyException { this(getUSocketFactory(), usocketPath); } public SSHAgentConnector(USocketFactory factory) throws AgentProxyException { this(factory, getSshAuthSocket()); } public SSHAgentConnector(USocketFactory factory, Path usocketPath) { this.factory = factory; this.usocketPath = usocketPath; } @Override public String getName() { return "ssh-agent"; } @Override @SuppressWarnings("try") public boolean isAvailable() { try (SocketChannel foo = open()) { return true; } catch (IOException e) { return false; } } private SocketChannel open() throws IOException { return factory.connect(usocketPath); } @Override public void query(Buffer buffer) throws AgentProxyException { try (SocketChannel sock = open()) { writeFull(sock, buffer, 0, buffer.getLength()); buffer.rewind(); int i = readFull(sock, buffer, 0, 4); // length i = buffer.getInt(); if (i <= 0 || i > MAX_AGENT_REPLY_LEN) { throw new AgentProxyException("Illegal length: " + i); } buffer.rewind(); buffer.checkFreeSize(i); i = readFull(sock, buffer, 0, i); } catch (IOException e) { throw new AgentProxyException(e.toString(), e); } } private static USocketFactory getUSocketFactory() throws AgentProxyException { try { return new UnixDomainSocketFactory(); } catch (AgentProxyException e) { try { return new JUnixSocketFactory(); } catch (NoClassDefFoundError ee) { AgentProxyException eee = new AgentProxyException("junixsocket library unavailable"); eee.addSuppressed(e); eee.addSuppressed(ee); throw eee; } catch (AgentProxyException ee) { ee.addSuppressed(e); throw e; } } } private static Path getSshAuthSocket() throws AgentProxyException { String ssh_auth_sock = Util.getSystemEnv("SSH_AUTH_SOCK"); if (ssh_auth_sock == null) { throw new AgentProxyException("SSH_AUTH_SOCK is not defined."); } return Paths.get(ssh_auth_sock); } private static int readFull(SocketChannel sock, Buffer buffer, int s, int len) throws IOException { ByteBuffer bb = ByteBuffer.wrap(buffer.buffer, s, len); int _len = len; while (len > 0) { int j = sock.read(bb); if (j < 0) return -1; if (j > 0) { len -= j; } } return _len; } private static int writeFull(SocketChannel sock, Buffer buffer, int s, int len) throws IOException { ByteBuffer bb = ByteBuffer.wrap(buffer.buffer, s, len); int _len = len; while (len > 0) { int j = sock.write(bb); if (j < 0) return -1; if (j > 0) { len -= j; } } return _len; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/ServerSocketFactory.java000066400000000000000000000033401465436372100267310ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; public interface ServerSocketFactory { public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Session.java000066400000000000000000003340761465436372100244220ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.Vector; import javax.crypto.AEADBadTagException; public class Session { // http://ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-01.txt static final int SSH_MSG_DISCONNECT = 1; static final int SSH_MSG_IGNORE = 2; static final int SSH_MSG_UNIMPLEMENTED = 3; static final int SSH_MSG_DEBUG = 4; static final int SSH_MSG_SERVICE_REQUEST = 5; static final int SSH_MSG_SERVICE_ACCEPT = 6; static final int SSH_MSG_EXT_INFO = 7; static final int SSH_MSG_KEXINIT = 20; static final int SSH_MSG_NEWKEYS = 21; static final int SSH_MSG_KEXDH_INIT = 30; static final int SSH_MSG_KEXDH_REPLY = 31; static final int SSH_MSG_KEX_DH_GEX_GROUP = 31; static final int SSH_MSG_KEX_DH_GEX_INIT = 32; static final int SSH_MSG_KEX_DH_GEX_REPLY = 33; static final int SSH_MSG_KEX_DH_GEX_REQUEST = 34; static final int SSH_MSG_GLOBAL_REQUEST = 80; static final int SSH_MSG_REQUEST_SUCCESS = 81; static final int SSH_MSG_REQUEST_FAILURE = 82; static final int SSH_MSG_CHANNEL_OPEN = 90; static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91; static final int SSH_MSG_CHANNEL_OPEN_FAILURE = 92; static final int SSH_MSG_CHANNEL_WINDOW_ADJUST = 93; static final int SSH_MSG_CHANNEL_DATA = 94; static final int SSH_MSG_CHANNEL_EXTENDED_DATA = 95; static final int SSH_MSG_CHANNEL_EOF = 96; static final int SSH_MSG_CHANNEL_CLOSE = 97; static final int SSH_MSG_CHANNEL_REQUEST = 98; static final int SSH_MSG_CHANNEL_SUCCESS = 99; static final int SSH_MSG_CHANNEL_FAILURE = 100; private static final int PACKET_MAX_SIZE = 256 * 1024; private byte[] V_S; // server version private byte[] V_C = Util.str2byte("SSH-2.0-JSCH_" + JSch.VERSION); // client version private byte[] I_C; // the payload of the client's SSH_MSG_KEXINIT private byte[] I_S; // the payload of the server's SSH_MSG_KEXINIT private byte[] K_S; // the host key private byte[] session_id; private byte[] IVc2s; private byte[] IVs2c; private byte[] Ec2s; private byte[] Es2c; private byte[] MACc2s; private byte[] MACs2c; // RFC 4253 6.4. each direction must run independently hence we have an incoming and outgoing // sequence number private int seqi = 0; private int seqo = 0; String[] guess = null; private Cipher s2ccipher; private Cipher c2scipher; private MAC s2cmac; private MAC c2smac; // private byte[] mac_buf; private byte[] s2cmac_result1; private byte[] s2cmac_result2; private Compression deflater; private Compression inflater; private IO io; private Socket socket; private int timeout = 0; private volatile boolean isConnected = false; private volatile boolean doExtInfo = false; private boolean enable_server_sig_algs = true; private boolean enable_ext_info_in_auth = true; private volatile boolean initialKex = true; private volatile boolean doStrictKex = false; private boolean enable_strict_kex = true; private boolean require_strict_kex = false; private volatile boolean isAuthed = false; private Thread connectThread = null; private Object lock = new Object(); boolean x11_forwarding = false; boolean agent_forwarding = false; InputStream in = null; OutputStream out = null; static Random random; Buffer buf; Packet packet; SocketFactory socket_factory = null; private Hashtable config = null; private Proxy proxy = null; private UserInfo userinfo; private String hostKeyAlias = null; private int serverAliveInterval = 0; private int serverAliveCountMax = 1; private IdentityRepository identityRepository = null; private HostKeyRepository hostkeyRepository = null; private volatile String[] serverSigAlgs = null; private volatile boolean sshBugSigType74 = false; protected boolean daemon_thread = false; private volatile long kex_start_time = 0L; int max_auth_tries = 6; int auth_failures = 0; String host = "127.0.0.1"; String org_host = "127.0.0.1"; int port = 22; String username = null; byte[] password = null; JSch jsch; Logger logger; Session(JSch jsch, String username, String host, int port) throws JSchException { super(); this.jsch = jsch; buf = new Buffer(); packet = new Packet(buf); this.username = username; this.org_host = this.host = host; this.port = port; applyConfig(); if (this.username == null) { this.username = Util.getSystemProperty("user.name"); } if (this.username == null) { throw new JSchException("username is not given."); } } public void connect() throws JSchException { connect(timeout); } public void connect(int connectTimeout) throws JSchException { if (isConnected) { throw new JSchException("session is already connected"); } initialKex = true; io = new IO(); if (random == null) { try { Class c = Class.forName(getConfig("random")).asSubclass(Random.class); random = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new JSchException(e.toString(), e); } } Packet.setRandom(random); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Connecting to " + host + " port " + port); } try { int i, j; if (proxy == null) { InputStream in; OutputStream out; if (socket_factory == null) { socket = Util.createSocket(host, port, connectTimeout); in = socket.getInputStream(); out = socket.getOutputStream(); } else { socket = socket_factory.createSocket(host, port); in = socket_factory.getInputStream(socket); out = socket_factory.getOutputStream(socket); } // if(timeout>0){ socket.setSoTimeout(timeout); } socket.setTcpNoDelay(true); io.setInputStream(in); io.setOutputStream(out); } else { synchronized (proxy) { proxy.connect(socket_factory, host, port, connectTimeout); io.setInputStream(proxy.getInputStream()); io.setOutputStream(proxy.getOutputStream()); socket = proxy.getSocket(); } } if (connectTimeout > 0 && socket != null) { socket.setSoTimeout(connectTimeout); } isConnected = true; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Connection established"); } jsch.addSession(this); { // Some Cisco devices will miss to read '\n' if it is sent separately. byte[] foo = new byte[V_C.length + 2]; System.arraycopy(V_C, 0, foo, 0, V_C.length); foo[foo.length - 2] = (byte) '\r'; foo[foo.length - 1] = (byte) '\n'; io.put(foo, 0, foo.length); } while (true) { i = 0; j = 0; while (i < buf.buffer.length) { j = io.getByte(); if (j < 0) break; buf.buffer[i] = (byte) j; i++; if (j == 10) break; } if (j < 0) { throw new JSchException("connection is closed by foreign host"); } if (buf.buffer[i - 1] == 10) { // 0x0a i--; if (i > 0 && buf.buffer[i - 1] == 13) { // 0x0d i--; } } if (i <= 3 || ((i != buf.buffer.length) && (buf.buffer[0] != 'S' || buf.buffer[1] != 'S' || buf.buffer[2] != 'H' || buf.buffer[3] != '-'))) { // It must not start with 'SSH-' // System.err.println(new String(buf.buffer, 0, i); continue; } if (i == buf.buffer.length || i < 7 || // SSH-1.99 or SSH-2.0 (buf.buffer[4] == '1' && buf.buffer[6] != '9') // SSH-1.5 ) { throw new JSchException("invalid server's version string"); } break; } V_S = new byte[i]; System.arraycopy(buf.buffer, 0, V_S, 0, i); // System.err.println("V_S: ("+i+") ["+new String(V_S)+"]"); String _v_s = Util.byte2str(V_S); sshBugSigType74 = _v_s.startsWith("SSH-2.0-OpenSSH_7.4"); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Remote version string: " + _v_s); getLogger().log(Logger.INFO, "Local version string: " + Util.byte2str(V_C)); } enable_server_sig_algs = getConfig("enable_server_sig_algs").equals("yes"); enable_ext_info_in_auth = getConfig("enable_ext_info_in_auth").equals("yes"); enable_strict_kex = getConfig("enable_strict_kex").equals("yes"); require_strict_kex = getConfig("require_strict_kex").equals("yes"); send_kexinit(); buf = read(buf); if (buf.getCommand() != SSH_MSG_KEXINIT) { in_kex = false; throw new JSchException("invalid protocol: " + buf.getCommand()); } if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "SSH_MSG_KEXINIT received"); } KeyExchange kex = receive_kexinit(buf); while (true) { buf = read(buf); if (kex.getState() == buf.getCommand()) { kex_start_time = System.currentTimeMillis(); boolean result = kex.next(buf); if (!result) { // System.err.println("verify: "+result); in_kex = false; throw new JSchException("verify: " + result); } } else { in_kex = false; throw new JSchException("invalid protocol(kex): " + buf.getCommand()); } if (kex.getState() == KeyExchange.STATE_END) { break; } } try { long tmp = System.currentTimeMillis(); in_prompt = true; checkHost(host, port, kex); in_prompt = false; kex_start_time += (System.currentTimeMillis() - tmp); } catch (JSchException ee) { in_kex = false; in_prompt = false; throw ee; } send_newkeys(); // receive SSH_MSG_NEWKEYS(21) buf = read(buf); // System.err.println("read: 21 ? "+buf.getCommand()); if (buf.getCommand() == SSH_MSG_NEWKEYS) { if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "SSH_MSG_NEWKEYS received"); } receive_newkeys(buf, kex); initialKex = false; } else { in_kex = false; throw new JSchException("invalid protocol(newkeys): " + buf.getCommand()); } if (enable_server_sig_algs && enable_ext_info_in_auth && doExtInfo) { send_extinfo(); } try { String s = getConfig("MaxAuthTries"); if (s != null) { max_auth_tries = Integer.parseInt(s); } } catch (NumberFormatException e) { throw new JSchException("MaxAuthTries: " + getConfig("MaxAuthTries"), e); } boolean auth = false; boolean auth_cancel = false; UserAuthNone uan = null; try { Class c = Class.forName(getConfig("userauth.none")).asSubclass(UserAuthNone.class); uan = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new JSchException(e.toString(), e); } auth = uan.start(this); String cmethods = getConfig("PreferredAuthentications"); String[] cmethoda = Util.split(cmethods, ","); String smethods = null; if (!auth) { smethods = uan.getMethods(); if (smethods != null) { smethods = smethods.toLowerCase(Locale.ROOT); } else { // methods: publickey,password,keyboard-interactive // smethods = "publickey,password,keyboard-interactive"; smethods = cmethods; } } String[] smethoda = Util.split(smethods, ","); int methodi = 0; loop: while (true) { while (!auth && cmethoda != null && methodi < cmethoda.length) { String method = cmethoda[methodi++]; boolean acceptable = false; for (int k = 0; k < smethoda.length; k++) { if (smethoda[k].equals(method)) { acceptable = true; break; } } if (!acceptable) { continue; } // System.err.println(" method: " + method); if (getLogger().isEnabled(Logger.INFO)) { String str = "Authentications that can continue: "; for (int k = methodi - 1; k < cmethoda.length; k++) { str += cmethoda[k]; if (k + 1 < cmethoda.length) str += ","; } getLogger().log(Logger.INFO, str); getLogger().log(Logger.INFO, "Next authentication method: " + method); } UserAuth ua = null; try { Class c = null; if (getConfig("userauth." + method) != null) { c = Class.forName(getConfig("userauth." + method)).asSubclass(UserAuth.class); ua = c.getDeclaredConstructor().newInstance(); } } catch (Exception e) { if (getLogger().isEnabled(Logger.WARN)) { getLogger().log(Logger.WARN, "failed to load " + method + " method"); } } if (ua != null) { auth_cancel = false; try { auth = ua.start(this); if (auth && getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Authentication succeeded (" + method + ")."); } } catch (JSchAuthCancelException ee) { auth_cancel = true; } catch (JSchPartialAuthException ee) { String tmp = smethods; smethods = ee.getMethods(); smethoda = Util.split(smethods, ","); if (!tmp.equals(smethods)) { methodi = 0; } // System.err.println("PartialAuth: " + methods); auth_cancel = false; continue loop; } catch (RuntimeException ee) { throw ee; } catch (JSchException ee) { throw ee; } catch (Exception ee) { // SSH_MSG_DISCONNECT: Too many authentication failures // System.err.println("ee: " + ee); if (getLogger().isEnabled(Logger.WARN)) { getLogger().log(Logger.WARN, "an exception during authentication\n" + ee.toString()); } break loop; } } } break; } if (!auth) { if (auth_failures >= max_auth_tries) { if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Login trials exceeds " + max_auth_tries); } } throw new JSchException( (auth_cancel ? "Auth cancel" : "Auth fail") + " for methods '" + smethods + "'"); } if (socket != null && (connectTimeout > 0 || timeout > 0)) { socket.setSoTimeout(timeout); } isAuthed = true; synchronized (lock) { if (isConnected) { connectThread = new Thread(this::run); connectThread.setName("Connect thread " + host + " session"); if (daemon_thread) { connectThread.setDaemon(daemon_thread); } connectThread.start(); requestPortForwarding(); } else { // The session has been already down and // we don't have to start new thread. } } } catch (Exception e) { in_kex = false; try { if (isConnected) { String message = e.toString(); packet.reset(); buf.checkFreeSize(1 + 4 * 3 + message.length() + 2 + getBufferMargin()); buf.putByte((byte) SSH_MSG_DISCONNECT); buf.putInt(3); buf.putString(Util.str2byte(message)); buf.putString(Util.str2byte("en")); write(packet); } } catch (Exception ee) { } try { disconnect(); } catch (Exception ee) { } isConnected = false; // e.printStackTrace(); if (e instanceof RuntimeException) throw (RuntimeException) e; if (e instanceof JSchException) throw (JSchException) e; throw new JSchException("Session.connect: " + e, e); } finally { Util.bzero(this.password); this.password = null; } } private KeyExchange receive_kexinit(Buffer buf) throws Exception { int j = buf.getInt(); if (j != buf.getLength()) { // packet was compressed and buf.getByte(); // j is the size of deflated packet. I_S = new byte[buf.index - 5]; } else { I_S = new byte[j - 1 - buf.getByte()]; } System.arraycopy(buf.buffer, buf.s, I_S, 0, I_S.length); if (initialKex) { if (enable_strict_kex || require_strict_kex) { doStrictKex = checkServerStrictKex(); if (doStrictKex) { if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Doing strict KEX"); } if (seqi != 1) { throw new JSchStrictKexException("KEXINIT not first packet from server"); } } else if (require_strict_kex) { throw new JSchStrictKexException("Strict KEX not supported by server"); } } if (enable_server_sig_algs) { doExtInfo = checkServerExtInfo(); if (doExtInfo && getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "ext-info messaging supported by server"); } } } if (!in_kex) { // We are in rekeying activated by the remote! send_kexinit(); } guess = KeyExchange.guess(this, I_S, I_C); if (guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("ext-info-c") || guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("ext-info-s") || guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("kex-strict-c-v00@openssh.com") || guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("kex-strict-s-v00@openssh.com")) { throw new JSchException("Invalid Kex negotiated: " + guess[KeyExchange.PROPOSAL_KEX_ALGS]); } if (!isAuthed && (guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS].equals("none") || (guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC].equals("none")))) { throw new JSchException( "NONE Cipher should not be chosen before authentification is successed."); } KeyExchange kex = null; try { Class c = Class .forName(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS])).asSubclass(KeyExchange.class); kex = c.getDeclaredConstructor().newInstance(); } catch (Exception | NoClassDefFoundError e) { throw new JSchException(e.toString(), e); } kex.doInit(this, V_S, V_C, I_S, I_C); return kex; } private boolean checkServerStrictKex() { Buffer sb = new Buffer(I_S); sb.setOffSet(17); byte[] sp = sb.getString(); // server proposal int l = 0; int m = 0; while (l < sp.length) { while (l < sp.length && sp[l] != ',') l++; if (m == l) continue; if ("kex-strict-s-v00@openssh.com".equals(Util.byte2str(sp, m, l - m))) { return true; } l++; m = l; } return false; } private boolean checkServerExtInfo() { Buffer sb = new Buffer(I_S); sb.setOffSet(17); byte[] sp = sb.getString(); // server proposal int l = 0; int m = 0; while (l < sp.length) { while (l < sp.length && sp[l] != ',') l++; if (m == l) continue; if ("ext-info-s".equals(Util.byte2str(sp, m, l - m))) { return true; } l++; m = l; } return false; } private volatile boolean in_kex = false; private volatile boolean in_prompt = false; private volatile String[] not_available_shks = null; public String[] getUnavailableSignatures() { return not_available_shks; } public void rekey() throws Exception { send_kexinit(); } private void send_kexinit() throws Exception { if (in_kex) return; String cipherc2s = getConfig("cipher.c2s"); String ciphers2c = getConfig("cipher.s2c"); String[] not_available_ciphers = checkCiphers(getConfig("CheckCiphers")); if (not_available_ciphers != null && not_available_ciphers.length > 0) { if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "cipher.c2s proposal before removing unavailable algos is: " + cipherc2s); getLogger().log(Logger.DEBUG, "cipher.s2c proposal before removing unavailable algos is: " + ciphers2c); } cipherc2s = Util.diffString(cipherc2s, not_available_ciphers); ciphers2c = Util.diffString(ciphers2c, not_available_ciphers); if (cipherc2s == null || ciphers2c == null) { throw new JSchException("There are not any available ciphers."); } if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "cipher.c2s proposal after removing unavailable algos is: " + cipherc2s); getLogger().log(Logger.DEBUG, "cipher.s2c proposal after removing unavailable algos is: " + ciphers2c); } } String macc2s = getConfig("mac.c2s"); String macs2c = getConfig("mac.s2c"); String[] not_available_macs = checkMacs(getConfig("CheckMacs")); if (not_available_macs != null && not_available_macs.length > 0) { if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "mac.c2s proposal before removing unavailable algos is: " + macc2s); getLogger().log(Logger.DEBUG, "mac.s2c proposal before removing unavailable algos is: " + macs2c); } macc2s = Util.diffString(macc2s, not_available_macs); macs2c = Util.diffString(macs2c, not_available_macs); if (macc2s == null || macs2c == null) { throw new JSchException("There are not any available macs."); } if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "mac.c2s proposal after removing unavailable algos is: " + macc2s); getLogger().log(Logger.DEBUG, "mac.s2c proposal after removing unavailable algos is: " + macs2c); } } String kex = getConfig("kex"); String[] not_available_kexes = checkKexes(getConfig("CheckKexes")); if (not_available_kexes != null && not_available_kexes.length > 0) { if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "kex proposal before removing unavailable algos is: " + kex); } kex = Util.diffString(kex, not_available_kexes); if (kex == null) { throw new JSchException("There are not any available kexes."); } if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "kex proposal after removing unavailable algos is: " + kex); } } if (enable_server_sig_algs && !isAuthed) { kex += ",ext-info-c"; } if ((enable_strict_kex || require_strict_kex) && initialKex) { kex += ",kex-strict-c-v00@openssh.com"; } String server_host_key = getConfig("server_host_key"); String[] not_available_shks = checkSignatures(getConfig("CheckSignatures")); // Cache for UserAuthPublicKey this.not_available_shks = not_available_shks; if (not_available_shks != null && not_available_shks.length > 0) { if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "server_host_key proposal before removing unavailable algos is: " + server_host_key); } server_host_key = Util.diffString(server_host_key, not_available_shks); if (server_host_key == null) { throw new JSchException("There are not any available sig algorithm."); } if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "server_host_key proposal after removing unavailable algos is: " + server_host_key); } } String prefer_hkr = getConfig("prefer_known_host_key_types"); if (prefer_hkr.equals("yes")) { if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "server_host_key proposal before known_host reordering is: " + server_host_key); } HostKeyRepository hkr = getHostKeyRepository(); String chost = host; if (hostKeyAlias != null) { chost = hostKeyAlias; } if (hostKeyAlias == null && port != 22) { chost = ("[" + chost + "]:" + port); } HostKey[] hks = hkr.getHostKey(chost, null); if (hks != null && hks.length > 0) { List pref_shks = new ArrayList<>(); List shks = new ArrayList<>(Arrays.asList(Util.split(server_host_key, ","))); Iterator it = shks.iterator(); while (it.hasNext()) { String algo = it.next(); String type = algo; if (type.equals("rsa-sha2-256") || type.equals("rsa-sha2-512") || type.equals("ssh-rsa-sha224@ssh.com") || type.equals("ssh-rsa-sha256@ssh.com") || type.equals("ssh-rsa-sha384@ssh.com") || type.equals("ssh-rsa-sha512@ssh.com")) { type = "ssh-rsa"; } for (HostKey hk : hks) { if (hk.getType().equals(type)) { pref_shks.add(algo); it.remove(); break; } } } if (pref_shks.size() > 0) { pref_shks.addAll(shks); server_host_key = String.join(",", pref_shks); } } if (getLogger().isEnabled(Logger.DEBUG)) { getLogger().log(Logger.DEBUG, "server_host_key proposal after known_host reordering is: " + server_host_key); } } kex_start_time = System.currentTimeMillis(); in_kex = true; // byte SSH_MSG_KEXINIT(20) // byte[16] cookie (random bytes) // string kex_algorithms // string server_host_key_algorithms // string encryption_algorithms_client_to_server // string encryption_algorithms_server_to_client // string mac_algorithms_client_to_server // string mac_algorithms_server_to_client // string compression_algorithms_client_to_server // string compression_algorithms_server_to_client // string languages_client_to_server // string languages_server_to_client Buffer buf = new Buffer(); // send_kexinit may be invoked Packet packet = new Packet(buf); // by user thread. packet.reset(); buf.putByte((byte) SSH_MSG_KEXINIT); synchronized (random) { random.fill(buf.buffer, buf.index, 16); buf.skip(16); } buf.putString(Util.str2byte(kex)); buf.putString(Util.str2byte(server_host_key)); buf.putString(Util.str2byte(cipherc2s)); buf.putString(Util.str2byte(ciphers2c)); buf.putString(Util.str2byte(getConfig("mac.c2s"))); buf.putString(Util.str2byte(getConfig("mac.s2c"))); buf.putString(Util.str2byte(getConfig("compression.c2s"))); buf.putString(Util.str2byte(getConfig("compression.s2c"))); buf.putString(Util.str2byte(getConfig("lang.c2s"))); buf.putString(Util.str2byte(getConfig("lang.s2c"))); buf.putByte((byte) 0); buf.putInt(0); buf.setOffSet(5); I_C = new byte[buf.getLength()]; buf.getByte(I_C); write(packet); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "SSH_MSG_KEXINIT sent"); } } private void send_newkeys() throws Exception { // send SSH_MSG_NEWKEYS(21) packet.reset(); buf.putByte((byte) SSH_MSG_NEWKEYS); write(packet); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "SSH_MSG_NEWKEYS sent"); } } private void send_extinfo() throws Exception { // send SSH_MSG_EXT_INFO(7) packet.reset(); buf.putByte((byte) SSH_MSG_EXT_INFO); buf.putInt(1); buf.putString(Util.str2byte("ext-info-in-auth@openssh.com")); buf.putString(Util.str2byte("0")); write(packet); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "SSH_MSG_EXT_INFO sent"); } } private void checkHost(String chost, int port, KeyExchange kex) throws JSchException { String shkc = getConfig("StrictHostKeyChecking"); if (hostKeyAlias != null) { chost = hostKeyAlias; } // System.err.println("shkc: "+shkc); byte[] K_S = kex.getHostKey(); String key_type = kex.getKeyType(); String key_fprint = kex.getFingerPrint(); if (hostKeyAlias == null && port != 22) { chost = ("[" + chost + "]:" + port); } HostKeyRepository hkr = getHostKeyRepository(); String hkh = getConfig("HashKnownHosts"); if (hkh.equals("yes") && (hkr instanceof KnownHosts)) { hostkey = ((KnownHosts) hkr).createHashedHostKey(chost, K_S); } else { hostkey = new HostKey(chost, K_S); } int i = 0; synchronized (hkr) { i = hkr.check(chost, K_S); } boolean insert = false; if ((shkc.equals("ask") || shkc.equals("yes")) && i == HostKeyRepository.CHANGED) { String file = null; synchronized (hkr) { file = hkr.getKnownHostsRepositoryID(); } if (file == null) { file = "known_hosts"; } boolean b = false; if (userinfo != null) { String message = "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n" + "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n" + "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n" + "It is also possible that the " + key_type + " host key has just been changed.\n" + "The fingerprint for the " + key_type + " key sent by the remote host " + chost + " is\n" + key_fprint + ".\n" + "Please contact your system administrator.\n" + "Add correct host key in " + file + " to get rid of this message."; if (shkc.equals("ask")) { b = userinfo .promptYesNo(message + "\nDo you want to delete the old key and insert the new key?"); } else { // shkc.equals("yes") userinfo.showMessage(message); } } if (!b) { throw new JSchException("HostKey has been changed: " + chost); } synchronized (hkr) { hkr.remove(chost, kex.getKeyAlgorithName(), null); insert = true; } } if ((shkc.equals("ask") || shkc.equals("yes")) && (i != HostKeyRepository.OK) && !insert) { if (shkc.equals("yes")) { throw new JSchException("reject HostKey: " + chost); } // System.err.println("finger-print: "+key_fprint); if (userinfo != null) { boolean foo = userinfo.promptYesNo("The authenticity of host '" + chost + "' can't be established.\n" + key_type + " key fingerprint is " + key_fprint + ".\n" + "Are you sure you want to continue connecting?"); if (!foo) { throw new JSchException("reject HostKey: " + chost); } insert = true; } else { if (i == HostKeyRepository.NOT_INCLUDED) throw new JSchUnknownHostKeyException( "UnknownHostKey: " + chost + ". " + key_type + " key fingerprint is " + key_fprint); else throw new JSchChangedHostKeyException("HostKey has been changed: " + chost); } } if (shkc.equals("no") && HostKeyRepository.NOT_INCLUDED == i) { insert = true; } if (i == HostKeyRepository.OK) { HostKey[] keys = hkr.getHostKey(chost, kex.getKeyAlgorithName()); String _key = Util.byte2str(Util.toBase64(K_S, 0, K_S.length, true)); for (int j = 0; j < keys.length; j++) { if (keys[j].getKey().equals(_key) && keys[j].getMarker().equals("@revoked")) { if (userinfo != null) { userinfo.showMessage("The " + key_type + " host key for " + chost + " is marked as revoked.\n" + "This could mean that a stolen key is being used to " + "impersonate this host."); } if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Host '" + chost + "' has provided revoked key."); } throw new JSchRevokedHostKeyException("revoked HostKey: " + chost); } } } if (i == HostKeyRepository.OK && getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Host '" + chost + "' is known and matches the " + key_type + " host key"); } if (insert && getLogger().isEnabled(Logger.WARN)) { getLogger().log(Logger.WARN, "Permanently added '" + chost + "' (" + key_type + ") to the list of known hosts."); } if (insert) { synchronized (hkr) { hkr.add(hostkey, userinfo); } } } // public void start(){ (new Thread(this)).start(); } public Channel openChannel(String type) throws JSchException { if (!isConnected) { throw new JSchException("session is down"); } try { Channel channel = Channel.getChannel(type, this); addChannel(channel); channel.init(); if (channel instanceof ChannelSession) { applyConfigChannel((ChannelSession) channel); } return channel; } catch (Exception e) { // e.printStackTrace(); } return null; } // encode will bin invoked in write with synchronization. void encode(Packet packet) throws Exception { // System.err.println("encode: "+packet.buffer.getCommand()); // System.err.println(" "+packet.buffer.index); // if(packet.buffer.getCommand()==96){ // Thread.dumpStack(); // } if (deflater != null) { compress_len[0] = packet.buffer.index; packet.buffer.buffer = deflater.compress(packet.buffer.buffer, 5, compress_len); packet.buffer.index = compress_len[0]; } int bsize = 8; if (c2scipher != null) { // bsize=c2scipher.getIVSize(); bsize = c2scipher_size; } boolean isChaCha20 = (c2scipher != null && c2scipher.isChaCha20()); boolean isAEAD = (c2scipher != null && c2scipher.isAEAD()); boolean isEtM = (!isChaCha20 && !isAEAD && c2scipher != null && c2smac != null && c2smac.isEtM()); packet.padding(bsize, !(isChaCha20 || isAEAD || isEtM)); byte[] buf = packet.buffer.buffer; if (isChaCha20) { // init cipher with seq number c2scipher.update(seqo); // encrypt packet length field c2scipher.update(buf, 0, 4, buf, 0); // encrypt rest of packet & add tag c2scipher.doFinal(buf, 0, packet.buffer.index, buf, 0); packet.buffer.skip(c2scipher.getTagSize()); } else if (isAEAD) { c2scipher.updateAAD(buf, 0, 4); c2scipher.doFinal(buf, 4, packet.buffer.index - 4, buf, 4); packet.buffer.skip(c2scipher.getTagSize()); } else if (isEtM) { c2scipher.update(buf, 4, packet.buffer.index - 4, buf, 4); c2smac.update(seqo); c2smac.update(packet.buffer.buffer, 0, packet.buffer.index); c2smac.doFinal(packet.buffer.buffer, packet.buffer.index); packet.buffer.skip(c2smac.getBlockSize()); } else { if (c2smac != null) { c2smac.update(seqo); c2smac.update(packet.buffer.buffer, 0, packet.buffer.index); c2smac.doFinal(packet.buffer.buffer, packet.buffer.index); } if (c2scipher != null) { c2scipher.update(buf, 0, packet.buffer.index, buf, 0); } if (c2smac != null) { packet.buffer.skip(c2smac.getBlockSize()); } } } int[] uncompress_len = new int[1]; int[] compress_len = new int[1]; private int s2ccipher_size = 8; private int c2scipher_size = 8; Buffer read(Buffer buf) throws Exception { int j = 0; boolean isChaCha20 = (s2ccipher != null && s2ccipher.isChaCha20()); boolean isAEAD = (s2ccipher != null && s2ccipher.isAEAD()); boolean isEtM = (!isChaCha20 && !isAEAD && s2ccipher != null && s2cmac != null && s2cmac.isEtM()); while (true) { buf.reset(); if (isChaCha20) { // read encrypted packet length field io.getByte(buf.buffer, buf.index, 4); buf.index += 4; // init cipher with seq number s2ccipher.update(seqi); // decrypt packet length field byte[] tmp = new byte[4]; s2ccipher.update(buf.buffer, 0, 4, tmp, 0); j = ((tmp[0] << 24) & 0xff000000) | ((tmp[1] << 16) & 0x00ff0000) | ((tmp[2] << 8) & 0x0000ff00) | ((tmp[3]) & 0x000000ff); // RFC 4253 6.1. Maximum Packet Length if (j < 5 || j > PACKET_MAX_SIZE) { start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); } j += s2ccipher.getTagSize(); if ((buf.index + j) > buf.buffer.length) { byte[] foo = new byte[buf.index + j]; System.arraycopy(buf.buffer, 0, foo, 0, buf.index); buf.buffer = foo; } if ((j % s2ccipher_size) != 0) { String message = "Bad packet length " + j; if (getLogger().isEnabled(Logger.FATAL)) { getLogger().log(Logger.FATAL, message); } start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE - s2ccipher_size); } io.getByte(buf.buffer, buf.index, j); // subtract tag size now that whole packet has been fetched j -= s2ccipher.getTagSize(); buf.index += (j); try { s2ccipher.doFinal(buf.buffer, 0, j + 4, buf.buffer, 0); } catch (AEADBadTagException e) { throw new JSchException("Packet corrupt", e); } // overwrite encrypted packet length field with decrypted version System.arraycopy(tmp, 0, buf.buffer, 0, 4); } else if (isAEAD || isEtM) { io.getByte(buf.buffer, buf.index, 4); buf.index += 4; j = ((buf.buffer[0] << 24) & 0xff000000) | ((buf.buffer[1] << 16) & 0x00ff0000) | ((buf.buffer[2] << 8) & 0x0000ff00) | ((buf.buffer[3]) & 0x000000ff); // RFC 4253 6.1. Maximum Packet Length if (j < 5 || j > PACKET_MAX_SIZE) { start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); } if (isAEAD) { j += s2ccipher.getTagSize(); } if ((buf.index + j) > buf.buffer.length) { byte[] foo = new byte[buf.index + j]; System.arraycopy(buf.buffer, 0, foo, 0, buf.index); buf.buffer = foo; } if ((j % s2ccipher_size) != 0) { String message = "Bad packet length " + j; if (getLogger().isEnabled(Logger.FATAL)) { getLogger().log(Logger.FATAL, message); } start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE - s2ccipher_size); } io.getByte(buf.buffer, buf.index, j); buf.index += (j); if (isAEAD) { try { s2ccipher.updateAAD(buf.buffer, 0, 4); s2ccipher.doFinal(buf.buffer, 4, j, buf.buffer, 4); } catch (AEADBadTagException e) { throw new JSchException("Packet corrupt", e); } // don't include AEAD tag size in buf so that decompression works below buf.index -= s2ccipher.getTagSize(); } else { s2cmac.update(seqi); s2cmac.update(buf.buffer, 0, buf.index); s2cmac.doFinal(s2cmac_result1, 0); io.getByte(s2cmac_result2, 0, s2cmac_result2.length); if (!Util.arraysequals(s2cmac_result1, s2cmac_result2)) { throw new JSchException("Packet corrupt"); } s2ccipher.update(buf.buffer, 4, j, buf.buffer, 4); } } else { io.getByte(buf.buffer, buf.index, s2ccipher_size); buf.index += s2ccipher_size; if (s2ccipher != null) { s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0); } j = ((buf.buffer[0] << 24) & 0xff000000) | ((buf.buffer[1] << 16) & 0x00ff0000) | ((buf.buffer[2] << 8) & 0x0000ff00) | ((buf.buffer[3]) & 0x000000ff); // RFC 4253 6.1. Maximum Packet Length if (j < 5 || j > PACKET_MAX_SIZE) { start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); } int need = j + 4 - s2ccipher_size; // if(need<0){ // throw new IOException("invalid data"); // } if ((buf.index + need) > buf.buffer.length) { byte[] foo = new byte[buf.index + need]; System.arraycopy(buf.buffer, 0, foo, 0, buf.index); buf.buffer = foo; } if ((need % s2ccipher_size) != 0) { String message = "Bad packet length " + need; if (getLogger().isEnabled(Logger.FATAL)) { getLogger().log(Logger.FATAL, message); } start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE - s2ccipher_size); } if (need > 0) { io.getByte(buf.buffer, buf.index, need); buf.index += (need); if (s2ccipher != null) { s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size); } } if (s2cmac != null) { s2cmac.update(seqi); s2cmac.update(buf.buffer, 0, buf.index); s2cmac.doFinal(s2cmac_result1, 0); io.getByte(s2cmac_result2, 0, s2cmac_result2.length); if (!Util.arraysequals(s2cmac_result1, s2cmac_result2)) { if (need + s2ccipher_size > PACKET_MAX_SIZE) { throw new IOException("MAC Error"); } start_discard(buf, s2ccipher, s2cmac, buf.index, PACKET_MAX_SIZE - need - s2ccipher_size); continue; } } } if (++seqi == 0 && (enable_strict_kex || require_strict_kex) && initialKex) { throw new JSchStrictKexException("incoming sequence number wrapped during initial KEX"); } if (inflater != null) { // inflater.uncompress(buf); int pad = buf.buffer[4]; uncompress_len[0] = buf.index - 5 - pad; byte[] foo = inflater.uncompress(buf.buffer, 5, uncompress_len); if (foo != null) { buf.buffer = foo; buf.index = 5 + uncompress_len[0]; } else { if (getLogger().isEnabled(Logger.ERROR)) { getLogger().log(Logger.ERROR, "fail in inflater"); } break; } } int type = buf.getCommand() & 0xff; // System.err.println("read: "+type); if (type == SSH_MSG_DISCONNECT) { buf.rewind(); buf.getInt(); buf.getShort(); int reason_code = buf.getInt(); byte[] description_array = buf.getString(); byte[] language_tag_array = buf.getString(); String description = Util.byte2str(description_array); String language_tag = Util.byte2str(language_tag_array); throw new JSchSessionDisconnectException( "SSH_MSG_DISCONNECT: " + reason_code + " " + description + " " + language_tag, reason_code, description, language_tag); // break; } else if (initialKex && doStrictKex) { break; } else if (type == SSH_MSG_IGNORE) { } else if (type == SSH_MSG_UNIMPLEMENTED) { buf.rewind(); buf.getInt(); buf.getShort(); int reason_id = buf.getInt(); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Received SSH_MSG_UNIMPLEMENTED for " + reason_id); } } else if (type == SSH_MSG_DEBUG) { buf.rewind(); buf.getInt(); buf.getShort(); /* * byte always_display=(byte)buf.getByte(); byte[] message=buf.getString(); byte[] * language_tag=buf.getString(); System.err.println("SSH_MSG_DEBUG:"+ * " "+Util.byte2str(message)+ " "+Util.byte2str(language_tag)); */ } else if (type == SSH_MSG_CHANNEL_WINDOW_ADJUST) { buf.rewind(); buf.getInt(); buf.getShort(); Channel c = Channel.getChannel(buf.getInt(), this); if (c == null) { } else { c.addRemoteWindowSize(buf.getUInt()); } } else if (type == SSH_MSG_EXT_INFO) { buf.rewind(); buf.getInt(); buf.getShort(); boolean ignore = false; if (!enable_server_sig_algs) { ignore = true; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO while enable_server_sig_algs != yes"); } } else if (isAuthed) { ignore = true; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO received after SSH_MSG_USERAUTH_SUCCESS"); } } else if (in_kex) { ignore = true; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO received before SSH_MSG_NEWKEYS"); } } else { if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "SSH_MSG_EXT_INFO received"); } } long num_extensions = buf.getUInt(); for (long i = 0; i < num_extensions; i++) { byte[] ext_name = buf.getString(); byte[] ext_value = buf.getString(); if (!ignore && Util.byte2str(ext_name).equals("server-sig-algs")) { String foo = Util.byte2str(ext_value); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "server-sig-algs=<" + foo + ">"); } if (sshBugSigType74) { if (!foo.isEmpty()) { foo += ",rsa-sha2-256,rsa-sha2-512"; } else { foo = "rsa-sha2-256,rsa-sha2-512"; } if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "OpenSSH 7.4 detected: adding rsa-sha2-256 & rsa-sha2-512 to server-sig-algs"); } } serverSigAlgs = Util.split(foo, ","); } } } else if (type == UserAuth.SSH_MSG_USERAUTH_SUCCESS) { isAuthed = true; if (inflater == null && deflater == null) { String method; method = guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; initDeflater(method); method = guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; initInflater(method); } break; } else { break; } } buf.rewind(); return buf; } private void start_discard(Buffer buf, Cipher cipher, MAC mac, int mac_already, int discard) throws JSchException { if (!cipher.isCBC() || (mac != null && mac.isEtM())) { throw new JSchException("Packet corrupt"); } if (mac != null) { mac.update(seqi); mac.update(buf.buffer, 0, mac_already); } IOException ioe = null; try { while (discard > 0) { buf.reset(); int len = discard > buf.buffer.length ? buf.buffer.length : discard; io.getByte(buf.buffer, 0, len); if (mac != null) { mac.update(buf.buffer, 0, len); } discard -= len; } } catch (IOException e) { ioe = e; if (getLogger().isEnabled(Logger.ERROR)) { getLogger().log(Logger.ERROR, "start_discard finished early due to " + e.getMessage(), e); } } if (mac != null) { mac.doFinal(buf.buffer, 0); } JSchException e = new JSchException("Packet corrupt"); if (ioe != null) { e.addSuppressed(ioe); } throw e; } byte[] getSessionId() { return session_id; } private void receive_newkeys(Buffer buf, KeyExchange kex) throws Exception { try { updateKeys(kex); } finally { kex.clearK(); } in_kex = false; if (doStrictKex) { seqi = 0; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Reset incoming sequence number after receiving SSH_MSG_NEWKEYS for strict KEX"); } } } private void updateKeys(KeyExchange kex) throws Exception { byte[] K = kex.getK(); byte[] H = kex.getH(); HASH hash = kex.getHash(); if (session_id == null) { session_id = new byte[H.length]; System.arraycopy(H, 0, session_id, 0, H.length); } /* * Initial IV client to server: HASH (K || H || "A" || session_id) Initial IV server to client: * HASH (K || H || "B" || session_id) Encryption key client to server: HASH (K || H || "C" || * session_id) Encryption key server to client: HASH (K || H || "D" || session_id) Integrity key * client to server: HASH (K || H || "E" || session_id) Integrity key server to client: HASH (K * || H || "F" || session_id) */ buf.reset(); buf.putByte(K); buf.putByte(H); buf.putByte((byte) 0x41); buf.putByte(session_id); hash.update(buf.buffer, 0, buf.index); IVc2s = hash.digest(); int j = buf.index - session_id.length - 1; buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); IVs2c = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); Ec2s = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); Es2c = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); MACc2s = hash.digest(); buf.buffer[j]++; hash.update(buf.buffer, 0, buf.index); MACs2c = hash.digest(); try { Class cc; Class cm; String method; method = guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC]; cc = Class.forName(getConfig(method)).asSubclass(Cipher.class); s2ccipher = cc.getDeclaredConstructor().newInstance(); while (s2ccipher.getBlockSize() > Es2c.length) { buf.reset(); buf.putByte(K); buf.putByte(H); buf.putByte(Es2c); hash.update(buf.buffer, 0, buf.index); byte[] foo = hash.digest(); byte[] bar = new byte[Es2c.length + foo.length]; System.arraycopy(Es2c, 0, bar, 0, Es2c.length); System.arraycopy(foo, 0, bar, Es2c.length, foo.length); Es2c = bar; } s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c); s2ccipher_size = s2ccipher.getIVSize(); if (!s2ccipher.isAEAD()) { method = guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]; cm = Class.forName(getConfig(method)).asSubclass(MAC.class); s2cmac = cm.getDeclaredConstructor().newInstance(); MACs2c = expandKey(buf, K, H, MACs2c, hash, s2cmac.getBlockSize()); s2cmac.init(MACs2c); // mac_buf=new byte[s2cmac.getBlockSize()]; s2cmac_result1 = new byte[s2cmac.getBlockSize()]; s2cmac_result2 = new byte[s2cmac.getBlockSize()]; } method = guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS]; cc = Class.forName(getConfig(method)).asSubclass(Cipher.class); c2scipher = cc.getDeclaredConstructor().newInstance(); while (c2scipher.getBlockSize() > Ec2s.length) { buf.reset(); buf.putByte(K); buf.putByte(H); buf.putByte(Ec2s); hash.update(buf.buffer, 0, buf.index); byte[] foo = hash.digest(); byte[] bar = new byte[Ec2s.length + foo.length]; System.arraycopy(Ec2s, 0, bar, 0, Ec2s.length); System.arraycopy(foo, 0, bar, Ec2s.length, foo.length); Ec2s = bar; } c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s); c2scipher_size = c2scipher.getIVSize(); if (!c2scipher.isAEAD()) { method = guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]; cm = Class.forName(getConfig(method)).asSubclass(MAC.class); c2smac = cm.getDeclaredConstructor().newInstance(); MACc2s = expandKey(buf, K, H, MACc2s, hash, c2smac.getBlockSize()); c2smac.init(MACc2s); } method = guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; initDeflater(method); method = guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; initInflater(method); } catch (Exception | NoClassDefFoundError e) { if (e instanceof JSchException) throw e; throw new JSchException(e.toString(), e); // System.err.println("updatekeys: "+e); } } /* * RFC 4253 7.2. Output from Key Exchange If the key length needed is longer than the output of * the HASH, the key is extended by computing HASH of the concatenation of K and H and the entire * key so far, and appending the resulting bytes (as many as HASH generates) to the key. This * process is repeated until enough key material is available; the key is taken from the beginning * of this value. In other words: K1 = HASH(K || H || X || session_id) (X is e.g., "A") K2 = * HASH(K || H || K1) K3 = HASH(K || H || K1 || K2) ... key = K1 || K2 || K3 || ... */ private byte[] expandKey(Buffer buf, byte[] K, byte[] H, byte[] key, HASH hash, int required_length) throws Exception { byte[] result = key; int size = hash.getBlockSize(); while (result.length < required_length) { buf.reset(); buf.putByte(K); buf.putByte(H); buf.putByte(result); hash.update(buf.buffer, 0, buf.index); byte[] tmp = new byte[result.length + size]; System.arraycopy(result, 0, tmp, 0, result.length); System.arraycopy(hash.digest(), 0, tmp, result.length, size); Util.bzero(result); result = tmp; } return result; } /* synchronized */ void write(Packet packet, Channel c, int length) throws Exception { long t = getTimeout(); while (true) { if (in_kex) { if (t > 0L && (System.currentTimeMillis() - kex_start_time) > t) { throw new JSchException("timeout in waiting for rekeying process."); } try { Thread.sleep(10); } catch (InterruptedException e) { } ; continue; } synchronized (c) { if (c.rwsize < length) { try { c.notifyme++; c.wait(100); } catch (InterruptedException e) { } finally { c.notifyme--; } } if (in_kex) { continue; } if (c.rwsize >= length) { c.rwsize -= length; break; } } if (c.close || !c.isConnected()) { throw new IOException("channel is broken"); } boolean sendit = false; int s = 0; byte command = 0; int recipient = -1; synchronized (c) { if (c.rwsize > 0) { long len = c.rwsize; if (len > length) { len = length; } if (len != length) { s = packet.shift((int) len, (c2scipher != null ? c2scipher_size : 8), (c2smac != null ? c2smac.getBlockSize() : 0)); } command = packet.buffer.getCommand(); recipient = c.getRecipient(); length -= (int) len; c.rwsize -= len; sendit = true; } } if (sendit) { _write(packet); if (length == 0) { return; } packet.unshift(command, recipient, s, length); } synchronized (c) { if (in_kex) { continue; } if (c.rwsize >= length) { c.rwsize -= length; break; } // try{ // System.out.println("1wait: "+c.rwsize); // c.notifyme++; // c.wait(100); // } // catch(InterruptedException e){ // } // finally{ // c.notifyme--; // } } } _write(packet); } void write(Packet packet) throws Exception { // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand())); long t = getTimeout(); while (in_kex) { if (t > 0L && (System.currentTimeMillis() - kex_start_time) > t && !in_prompt) { throw new JSchException("timeout in waiting for rekeying process."); } byte command = packet.buffer.getCommand(); // System.err.println("command: "+command); if (command == SSH_MSG_KEXINIT || command == SSH_MSG_NEWKEYS || command == SSH_MSG_KEXDH_INIT || command == SSH_MSG_KEXDH_REPLY || command == SSH_MSG_KEX_DH_GEX_GROUP || command == SSH_MSG_KEX_DH_GEX_INIT || command == SSH_MSG_KEX_DH_GEX_REPLY || command == SSH_MSG_KEX_DH_GEX_REQUEST || command == SSH_MSG_DISCONNECT) { break; } try { Thread.sleep(10); } catch (InterruptedException e) { } ; } _write(packet); } private void _write(Packet packet) throws Exception { boolean initialKex = this.initialKex; boolean doStrictKex = this.doStrictKex; boolean enable_strict_kex = this.enable_strict_kex; boolean require_strict_kex = this.require_strict_kex; boolean resetSeqo = packet.buffer.getCommand() == SSH_MSG_NEWKEYS && doStrictKex; synchronized (lock) { encode(packet); if (io != null) { io.put(packet); if (++seqo == 0 && (enable_strict_kex || require_strict_kex) && initialKex) { throw new JSchStrictKexException("outgoing sequence number wrapped during initial KEX"); } if (resetSeqo) { seqo = 0; } } } if (resetSeqo && io != null && getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Reset outgoing sequence number after sending SSH_MSG_NEWKEYS for strict KEX"); } } Runnable thread; void run() { thread = this::run; byte[] foo; Buffer buf = new Buffer(); Packet packet = new Packet(buf); int i = 0; Channel channel; int[] start = new int[1]; int[] length = new int[1]; KeyExchange kex = null; int stimeout = 0; try { while (isConnected && thread != null) { try { buf = read(buf); stimeout = 0; } catch (InterruptedIOException /* SocketTimeoutException */ ee) { if (!in_kex && stimeout < serverAliveCountMax) { sendKeepAliveMsg(); stimeout++; continue; } else if (in_kex && stimeout < serverAliveCountMax) { stimeout++; continue; } throw ee; } int msgType = buf.getCommand() & 0xff; if (kex != null && kex.getState() == msgType) { kex_start_time = System.currentTimeMillis(); boolean result = kex.next(buf); if (!result) { throw new JSchException("verify: " + result); } continue; } switch (msgType) { case SSH_MSG_KEXINIT: // System.err.println("KEXINIT"); kex = receive_kexinit(buf); break; case SSH_MSG_NEWKEYS: // System.err.println("NEWKEYS"); send_newkeys(); receive_newkeys(buf, kex); kex = null; break; case SSH_MSG_CHANNEL_DATA: buf.getInt(); buf.getByte(); buf.getByte(); i = buf.getInt(); channel = Channel.getChannel(i, this); foo = buf.getString(start, length); if (channel == null) { break; } if (length[0] == 0) { break; } try { channel.write(foo, start[0], length[0]); } catch (Exception e) { // System.err.println(e); try { channel.disconnect(); } catch (Exception ee) { } break; } int len = length[0]; channel.setLocalWindowSize(channel.lwsize - len); if (channel.lwsize < channel.lwsize_max / 2) { packet.reset(); buf.putByte((byte) SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.putInt(channel.getRecipient()); buf.putInt(channel.lwsize_max - channel.lwsize); synchronized (channel) { if (!channel.close) write(packet); } channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_EXTENDED_DATA: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); buf.getInt(); // data_type_code == 1 foo = buf.getString(start, length); // System.err.println("stderr: "+new String(foo,start[0],length[0])); if (channel == null) { break; } if (length[0] == 0) { break; } channel.write_ext(foo, start[0], length[0]); len = length[0]; channel.setLocalWindowSize(channel.lwsize - len); if (channel.lwsize < channel.lwsize_max / 2) { packet.reset(); buf.putByte((byte) SSH_MSG_CHANNEL_WINDOW_ADJUST); buf.putInt(channel.getRecipient()); buf.putInt(channel.lwsize_max - channel.lwsize); synchronized (channel) { if (!channel.close) write(packet); } channel.setLocalWindowSize(channel.lwsize_max); } break; case SSH_MSG_CHANNEL_WINDOW_ADJUST: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); if (channel == null) { break; } channel.addRemoteWindowSize(buf.getUInt()); break; case SSH_MSG_CHANNEL_EOF: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); if (channel != null) { // channel.eof_remote=true; // channel.eof(); channel.eof_remote(); } /* * packet.reset(); buf.putByte((byte)SSH_MSG_CHANNEL_EOF); * buf.putInt(channel.getRecipient()); write(packet); */ break; case SSH_MSG_CHANNEL_CLOSE: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); if (channel != null) { // channel.close(); channel.disconnect(); } /* * if(Channel.pool.size()==0){ thread=null; } */ break; case SSH_MSG_CHANNEL_OPEN_CONFIRMATION: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); int r = buf.getInt(); long rws = buf.getUInt(); int rps = buf.getInt(); if (channel != null) { channel.setRemoteWindowSize(rws); channel.setRemotePacketSize(rps); channel.open_confirmation = true; channel.setRecipient(r); } break; case SSH_MSG_CHANNEL_OPEN_FAILURE: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); if (channel != null) { int reason_code = buf.getInt(); // foo=buf.getString(); // additional textual information // foo=buf.getString(); // language tag channel.setExitStatus(reason_code); channel.close = true; channel.eof_remote = true; channel.setRecipient(0); } break; case SSH_MSG_CHANNEL_REQUEST: buf.getInt(); buf.getShort(); i = buf.getInt(); foo = buf.getString(); boolean reply = (buf.getByte() != 0); channel = Channel.getChannel(i, this); if (channel != null) { byte reply_type = (byte) SSH_MSG_CHANNEL_FAILURE; if ((Util.byte2str(foo)).equals("exit-status")) { i = buf.getInt(); // exit-status channel.setExitStatus(i); reply_type = (byte) SSH_MSG_CHANNEL_SUCCESS; } if (reply) { packet.reset(); buf.putByte(reply_type); buf.putInt(channel.getRecipient()); write(packet); } } else { } break; case SSH_MSG_CHANNEL_OPEN: buf.getInt(); buf.getShort(); foo = buf.getString(); String ctyp = Util.byte2str(foo); if (!"forwarded-tcpip".equals(ctyp) && !("x11".equals(ctyp) && x11_forwarding) && !("auth-agent@openssh.com".equals(ctyp) && agent_forwarding)) { // System.err.println("Session.run: CHANNEL OPEN "+ctyp); // throw new IOException("Session.run: CHANNEL OPEN "+ctyp); packet.reset(); buf.putByte((byte) SSH_MSG_CHANNEL_OPEN_FAILURE); buf.putInt(buf.getInt()); buf.putInt(Channel.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED); buf.putString(Util.empty); buf.putString(Util.empty); write(packet); } else { channel = Channel.getChannel(ctyp, this); addChannel(channel); channel.getData(buf); channel.init(); Thread tmp = new Thread(channel::run); tmp.setName("Channel " + ctyp + " " + host); if (daemon_thread) { tmp.setDaemon(daemon_thread); } tmp.start(); } break; case SSH_MSG_CHANNEL_SUCCESS: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); if (channel == null) { break; } channel.reply = 1; break; case SSH_MSG_CHANNEL_FAILURE: buf.getInt(); buf.getShort(); i = buf.getInt(); channel = Channel.getChannel(i, this); if (channel == null) { break; } channel.reply = 0; break; case SSH_MSG_GLOBAL_REQUEST: buf.getInt(); buf.getShort(); foo = buf.getString(); // request name reply = (buf.getByte() != 0); if (reply) { packet.reset(); buf.putByte((byte) SSH_MSG_REQUEST_FAILURE); write(packet); } break; case SSH_MSG_REQUEST_FAILURE: case SSH_MSG_REQUEST_SUCCESS: Thread t = grr.getThread(); if (t != null) { grr.setReply(msgType == SSH_MSG_REQUEST_SUCCESS ? 1 : 0); if (msgType == SSH_MSG_REQUEST_SUCCESS && grr.getPort() == 0) { buf.getInt(); buf.getShort(); grr.setPort(buf.getInt()); } t.interrupt(); } break; default: // System.err.println("Session.run: unsupported type "+msgType); throw new IOException("Unknown SSH message type " + msgType); } } } catch (Exception e) { in_kex = false; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Caught an exception, leaving main loop due to " + e.getMessage()); } // System.err.println("# Session.run"); // e.printStackTrace(); } try { disconnect(); } catch (NullPointerException e) { // System.err.println("@1"); // e.printStackTrace(); } catch (Exception e) { // System.err.println("@2"); // e.printStackTrace(); } isConnected = false; } public void disconnect() { if (!isConnected) return; // System.err.println(this+": disconnect"); // Thread.dumpStack(); if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "Disconnecting from " + host + " port " + port); } /* * for(int i=0; ilport is * 0, the tcp port will be allocated. * * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @return an allocated local TCP port number * @see #setPortForwardingL(String bind_address, int lport, String host, int rport, * ServerSocketFactory ssf, int connectTimeout) */ public int setPortForwardingL(int lport, String host, int rport) throws JSchException { return setPortForwardingL("127.0.0.1", lport, host, rport); } /** * Registers the local port forwarding. If bind_address is an empty string or '*', * the port should be available from all interfaces. If bind_address is * "localhost" or null, the listening port will be bound for local use * only. If lport is 0, the tcp port will be allocated. * * @param bind_address bind address for local port forwarding * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @return an allocated local TCP port number * @see #setPortForwardingL(String bind_address, int lport, String host, int rport, * ServerSocketFactory ssf, int connectTimeout) */ public int setPortForwardingL(String bind_address, int lport, String host, int rport) throws JSchException { return setPortForwardingL(bind_address, lport, host, rport, null); } /** * Registers the local port forwarding. If bind_address is an empty string or * "*", the port should be available from all interfaces. If * bind_address is "localhost" or null, the listening port * will be bound for local use only. If lport is 0, the tcp port will be * allocated. * * @param bind_address bind address for local port forwarding * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @param ssf socket factory * @return an allocated local TCP port number * @see #setPortForwardingL(String bind_address, int lport, String host, int rport, * ServerSocketFactory ssf, int connectTimeout) */ public int setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException { return setPortForwardingL(bind_address, lport, host, rport, ssf, 0); } /** * Registers the local port forwarding. If bind_address is an empty string or * "*", the port should be available from all interfaces. If * bind_address is "localhost" or null, the listening port * will be bound for local use only. If lport is 0, the tcp port will be * allocated. * * @param bind_address bind address for local port forwarding * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @param ssf socket factory * @param connectTimeout timeout for establishing port connection * @return an allocated local TCP port number */ public int setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) throws JSchException { PortWatcher pw = PortWatcher.addPort(this, bind_address, lport, host, rport, ssf); pw.setConnectTimeout(connectTimeout); Thread tmp = new Thread(pw::run); tmp.setName("PortWatcher Thread for " + host); if (daemon_thread) { tmp.setDaemon(daemon_thread); } tmp.start(); return pw.lport; } public int setSocketForwardingL(String bindAddress, int lport, String socketPath, ServerSocketFactory ssf, int connectTimeout) throws JSchException { PortWatcher pw = PortWatcher.addSocket(this, bindAddress, lport, socketPath, ssf); pw.setConnectTimeout(connectTimeout); Thread tmp = new Thread(pw::run); tmp.setName("PortWatcher Thread for " + host); if (daemon_thread) { tmp.setDaemon(daemon_thread); } tmp.start(); return pw.lport; } /** * Cancels the local port forwarding assigned at local TCP port lport on loopback * interface. * * @param lport local TCP port */ public void delPortForwardingL(int lport) throws JSchException { delPortForwardingL("127.0.0.1", lport); } /** * Cancels the local port forwarding assigned at local TCP port lport on * bind_address interface. * * @param bind_address bind_address of network interfaces * @param lport local TCP port */ public void delPortForwardingL(String bind_address, int lport) throws JSchException { PortWatcher.delPort(this, bind_address, lport); } /** * Lists the registered local port forwarding. * * @return a list of "lport:host:hostport" */ public String[] getPortForwardingL() throws JSchException { return PortWatcher.getPortForwarding(this); } /** * Registers the remote port forwarding for the loopback interface of the remote. * * @param rport remote port * @param host host address * @param lport local port * @see #setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory * sf) */ public void setPortForwardingR(int rport, String host, int lport) throws JSchException { setPortForwardingR(null, rport, host, lport, (SocketFactory) null); } /** * Registers the remote port forwarding. If bind_address is an empty string or * "*", the port should be available from all interfaces. If * bind_address is "localhost" or is not given, the listening port will * be bound for local use only. Note that if GatewayPorts is "no" on the * remote, "localhost" is always used as a bind_address. * * @param bind_address bind address * @param rport remote port * @param host host address * @param lport local port * @see #setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory * sf) */ public void setPortForwardingR(String bind_address, int rport, String host, int lport) throws JSchException { setPortForwardingR(bind_address, rport, host, lport, (SocketFactory) null); } /** * Registers the remote port forwarding for the loopback interface of the remote. * * @param rport remote port * @param host host address * @param lport local port * @param sf socket factory * @see #setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory * sf) */ public void setPortForwardingR(int rport, String host, int lport, SocketFactory sf) throws JSchException { setPortForwardingR(null, rport, host, lport, sf); } // TODO: This method should return the integer value as the assigned port. /** * Registers the remote port forwarding. If bind_address is an empty string or * "*", the port should be available from all interfaces. If * bind_address is "localhost" or is not given, the listening port will * be bound for local use only. Note that if GatewayPorts is "no" on the * remote, "localhost" is always used as a bind_address. If rport is * 0, the TCP port will be allocated on the remote. * * @param bind_address bind address * @param rport remote port * @param host host address * @param lport local port * @param sf socket factory */ public void setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) throws JSchException { int allocated = _setPortForwardingR(bind_address, rport); ChannelForwardedTCPIP.addPort(this, bind_address, rport, allocated, host, lport, sf); } /** * Registers the remote port forwarding for the loopback interface of the remote. The TCP * connection to rport on the remote will be forwarded to an instance of the class * daemon. The class specified by daemon must implement * ForwardedTCPIPDaemon. * * @param rport remote port * @param daemon class name, which implements "ForwardedTCPIPDaemon" * @see #setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) */ public void setPortForwardingR(int rport, String daemon) throws JSchException { setPortForwardingR(null, rport, daemon, null); } /** * Registers the remote port forwarding for the loopback interface of the remote. The TCP * connection to rport on the remote will be forwarded to an instance of the class * daemon with the argument arg. The class specified by * daemon must implement ForwardedTCPIPDaemon. * * @param rport remote port * @param daemon class name, which implements "ForwardedTCPIPDaemon" * @param arg arguments for "daemon" * @see #setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) */ public void setPortForwardingR(int rport, String daemon, Object[] arg) throws JSchException { setPortForwardingR(null, rport, daemon, arg); } /** * Registers the remote port forwarding. If bind_address is an empty string or * "*", the port should be available from all interfaces. If * bind_address is "localhost" or is not given, the listening port will * be bound for local use only. Note that if GatewayPorts is "no" on the * remote, "localhost" is always used as a bind_address. The TCP connection to * rport on the remote will be forwarded to an instance of the class * daemon with the argument arg. The class specified by * daemon must implement ForwardedTCPIPDaemon. * * @param bind_address bind address * @param rport remote port * @param daemon class name, which implements "ForwardedTCPIPDaemon" * @param arg arguments for "daemon" * @see #setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) */ public void setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) throws JSchException { int allocated = _setPortForwardingR(bind_address, rport); ChannelForwardedTCPIP.addPort(this, bind_address, rport, allocated, daemon, arg); } /** * Lists the registered remote port forwarding. * * @return a list of "rport:host:hostport" */ public String[] getPortForwardingR() throws JSchException { return ChannelForwardedTCPIP.getPortForwarding(this); } static class Forwarding { String bind_address = null; int port = -1; String host = null; int hostport = -1; String socketPath = null; } /** * The given argument may be "[bind_address:]port:host:hostport" or "[bind_address:]port * host:hostport", which is from LocalForward command of ~/.ssh/config . Also allows * "[bind_address:]port:socketPath" or "[bind_address:]port socketPath" for socket forwarding. */ Forwarding parseForwarding(String conf) throws JSchException { String[] tmp = conf.split(" "); if (tmp.length > 1) { // "[bind_address:]port host:hostport" Vector foo = new Vector<>(); for (int i = 0; i < tmp.length; i++) { if (tmp[i].length() == 0) continue; foo.addElement(tmp[i].trim()); } StringBuilder sb = new StringBuilder(); // join for (int i = 0; i < foo.size(); i++) { sb.append(foo.elementAt(i)); if (i + 1 < foo.size()) sb.append(":"); } conf = sb.toString(); } String org = conf; Forwarding f = new Forwarding(); try { if (conf.lastIndexOf(":") == -1) throw new JSchException("parseForwarding: " + org); try { f.hostport = Integer.parseInt(conf.substring(conf.lastIndexOf(":") + 1)); conf = conf.substring(0, conf.lastIndexOf(":")); if (conf.lastIndexOf(":") == -1) throw new JSchException("parseForwarding: " + org); f.host = conf.substring(conf.lastIndexOf(":") + 1); } catch (NumberFormatException e) { f.socketPath = conf.substring(conf.lastIndexOf(":") + 1); } conf = conf.substring(0, conf.lastIndexOf(":")); if (conf.lastIndexOf(":") != -1) { f.port = Integer.parseInt(conf.substring(conf.lastIndexOf(":") + 1)); conf = conf.substring(0, conf.lastIndexOf(":")); if (conf.length() == 0 || conf.equals("*")) conf = "0.0.0.0"; if (conf.equals("localhost")) conf = "127.0.0.1"; f.bind_address = conf; } else { f.port = Integer.parseInt(conf); f.bind_address = "127.0.0.1"; } } catch (NumberFormatException e) { throw new JSchException("parseForwarding: " + e.toString(), e); } return f; } /** * Registers the local port forwarding. The argument should be in the format like * "[bind_address:]port:host:hostport". If bind_address is an empty string or * "*", the port should be available from all interfaces. If * bind_address is "localhost" or is not given, the listening port will * be bound for local use only. * * @param conf configuration of local port forwarding * @return an assigned port number * @see #setPortForwardingL(String bind_address, int lport, String host, int rport) */ public int setPortForwardingL(String conf) throws JSchException { Forwarding f = parseForwarding(conf); return setPortForwardingL(f.bind_address, f.port, f.host, f.hostport); } /** * Registers the remote port forwarding. The argument should be in the format like * "[bind_address:]port:host:hostport". If the bind_address is not given, the default is to only * bind to loopback addresses. If the bind_address is "*" or an empty string, then * the forwarding is requested to listen on all interfaces. Note that if GatewayPorts * is "no" on the remote, "localhost" is always used for bind_address. * If the specified remote is "0", the TCP port will be allocated on the remote. * * @param conf configuration of remote port forwarding * @return an allocated TCP port on the remote. * @see #setPortForwardingR(String bind_address, int rport, String host, int rport) */ public int setPortForwardingR(String conf) throws JSchException { Forwarding f = parseForwarding(conf); int allocated = _setPortForwardingR(f.bind_address, f.port); ChannelForwardedTCPIP.addPort(this, f.bind_address, f.port, allocated, f.host, f.hostport, null); return allocated; } /** * Instantiates an instance of stream-forwarder to host:port. Set I/O * stream to the given channel, and then invoke Channel#connect() method. * * @param host remote host, which the given stream will be plugged to. * @param port remote port, which the given stream will be plugged to. */ public Channel getStreamForwarder(String host, int port) throws JSchException { ChannelDirectTCPIP channel = new ChannelDirectTCPIP(); channel.init(); this.addChannel(channel); channel.setHost(host); channel.setPort(port); return channel; } private static class GlobalRequestReply { private Thread thread = null; private int reply = -1; private int port = 0; void setThread(Thread thread) { this.thread = thread; this.reply = -1; } Thread getThread() { return thread; } void setReply(int reply) { this.reply = reply; } int getReply() { return this.reply; } int getPort() { return this.port; } void setPort(int port) { this.port = port; } } private GlobalRequestReply grr = new GlobalRequestReply(); private int _setPortForwardingR(String bind_address, int rport) throws JSchException { synchronized (grr) { Buffer buf = new Buffer(200); // ?? Packet packet = new Packet(buf); String address_to_bind = ChannelForwardedTCPIP.normalize(bind_address); grr.setThread(Thread.currentThread()); grr.setPort(rport); try { // byte SSH_MSG_GLOBAL_REQUEST 80 // string "tcpip-forward" // boolean want_reply // string address_to_bind // uint32 port number to bind packet.reset(); buf.putByte((byte) SSH_MSG_GLOBAL_REQUEST); buf.putString(Util.str2byte("tcpip-forward")); buf.putByte((byte) 1); buf.putString(Util.str2byte(address_to_bind)); buf.putInt(rport); write(packet); } catch (Exception e) { grr.setThread(null); throw new JSchException(e.toString(), e); } int count = 0; int reply = grr.getReply(); while (count < 10 && reply == -1) { try { Thread.sleep(1000); } catch (Exception e) { } count++; reply = grr.getReply(); } grr.setThread(null); if (reply != 1) { throw new JSchException("remote port forwarding failed for listen port " + rport); } rport = grr.getPort(); } return rport; } /** * Cancels the remote port forwarding assigned at remote TCP port rport. * * @param rport remote TCP port */ public void delPortForwardingR(int rport) throws JSchException { this.delPortForwardingR(null, rport); } /** * Cancels the remote port forwarding assigned at remote TCP port rport bound on the * interface at bind_address. * * @param bind_address bind address of the interface on the remote * @param rport remote TCP port */ public void delPortForwardingR(String bind_address, int rport) throws JSchException { ChannelForwardedTCPIP.delPort(this, bind_address, rport); } private void initDeflater(String method) throws JSchException { Compression odeflater = deflater; if (method.equals("none")) { deflater = null; if (odeflater != null) { odeflater.end(); } return; } String foo = getConfig(method); if (foo != null) { if (method.equals("zlib") || (isAuthed && method.equals("zlib@openssh.com"))) { try { Class c = Class.forName(foo).asSubclass(Compression.class); deflater = c.getDeclaredConstructor().newInstance(); int level = 6; try { level = Integer.parseInt(getConfig("compression_level")); } catch (Exception ee) { } deflater.init(Compression.DEFLATER, level, this); } catch (Exception ee) { throw new JSchException(ee.toString(), ee); // System.err.println(foo+" isn't accessible."); } finally { if (odeflater != null) { odeflater.end(); } } } } } private void initInflater(String method) throws JSchException { Compression oinflater = inflater; if (method.equals("none")) { inflater = null; if (oinflater != null) { oinflater.end(); } return; } String foo = getConfig(method); if (foo != null) { if (method.equals("zlib") || (isAuthed && method.equals("zlib@openssh.com"))) { try { Class c = Class.forName(foo).asSubclass(Compression.class); inflater = c.getDeclaredConstructor().newInstance(); inflater.init(Compression.INFLATER, 0, this); } catch (Exception ee) { throw new JSchException(ee.toString(), ee); // System.err.println(foo+" isn't accessible."); } finally { if (oinflater != null) { oinflater.end(); } } } } } void addChannel(Channel channel) { channel.setSession(this); } String[] getServerSigAlgs() { return serverSigAlgs; } public void setProxy(Proxy proxy) { this.proxy = proxy; } public void setHost(String host) { this.host = host; } public void setPort(int port) { this.port = port; } void setUserName(String username) { this.username = username; } public void setUserInfo(UserInfo userinfo) { this.userinfo = userinfo; } public UserInfo getUserInfo() { return userinfo; } public void setInputStream(InputStream in) { this.in = in; } public void setOutputStream(OutputStream out) { this.out = out; } public void setX11Host(String host) { ChannelX11.setHost(host); } public void setX11Port(int port) { ChannelX11.setPort(port); } public void setX11Cookie(String cookie) { ChannelX11.setCookie(cookie); } public void setPassword(String password) { if (password != null) this.password = Util.str2byte(password); } public void setPassword(byte[] password) { if (password != null) { this.password = new byte[password.length]; System.arraycopy(password, 0, this.password, 0, password.length); } } public void setConfig(Properties newconf) { Hashtable foo = new Hashtable<>(); for (String key : newconf.stringPropertyNames()) { foo.put(key, newconf.getProperty(key)); } setConfig(foo); } public void setConfig(Hashtable newconf) { synchronized (lock) { if (config == null) config = new Hashtable<>(); for (Enumeration e = newconf.keys(); e.hasMoreElements();) { String newkey = e.nextElement(); String key = (newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); String value = newconf.get(newkey); config.put(key, value); } } } public void setConfig(String key, String value) { synchronized (lock) { if (config == null) { config = new Hashtable<>(); } if (key.equals("PubkeyAcceptedKeyTypes")) { config.put("PubkeyAcceptedAlgorithms", value); } else { config.put(key, value); } } } public String getConfig(String key) { if (key.equals("PubkeyAcceptedKeyTypes")) { key = "PubkeyAcceptedAlgorithms"; } Object foo = null; if (config != null) { foo = config.get(key); if (foo instanceof String) return (String) foo; } foo = JSch.getConfig(key); if (foo instanceof String) return (String) foo; return null; } public void setSocketFactory(SocketFactory sfactory) { socket_factory = sfactory; } public boolean isConnected() { return isConnected; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) throws JSchException { if (socket == null) { if (timeout < 0) { throw new JSchException("invalid timeout value"); } this.timeout = timeout; return; } try { socket.setSoTimeout(timeout); this.timeout = timeout; } catch (Exception e) { throw new JSchException(e.toString(), e); } } public String getServerVersion() { return Util.byte2str(V_S); } public String getClientVersion() { return Util.byte2str(V_C); } public void setClientVersion(String cv) { V_C = Util.str2byte(cv); } public void sendIgnore() throws Exception { Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_IGNORE); write(packet); } private static final byte[] keepalivemsg = Util.str2byte("keepalive@jcraft.com"); public void sendKeepAliveMsg() throws Exception { Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_GLOBAL_REQUEST); buf.putString(keepalivemsg); buf.putByte((byte) 1); write(packet); } private static final byte[] nomoresessions = Util.str2byte("no-more-sessions@openssh.com"); public void noMoreSessionChannels() throws Exception { Buffer buf = new Buffer(); Packet packet = new Packet(buf); packet.reset(); buf.putByte((byte) SSH_MSG_GLOBAL_REQUEST); buf.putString(nomoresessions); buf.putByte((byte) 0); write(packet); } private HostKey hostkey = null; public HostKey getHostKey() { return hostkey; } public String getHost() { return host; } public String getUserName() { return username; } public int getPort() { return port; } public void setHostKeyAlias(String hostKeyAlias) { this.hostKeyAlias = hostKeyAlias; } public String getHostKeyAlias() { return hostKeyAlias; } /** * Sets the interval to send a keep-alive message. If zero is specified, any keep-alive message * must not be sent. The default interval is zero. * * @param interval the specified interval, in milliseconds. * @see #getServerAliveInterval() */ public void setServerAliveInterval(int interval) throws JSchException { setTimeout(interval); this.serverAliveInterval = interval; } /** * Returns setting for the interval to send a keep-alive message. * * @see #setServerAliveInterval(int) */ public int getServerAliveInterval() { return this.serverAliveInterval; } /** * Sets the number of keep-alive messages which may be sent without receiving any messages back * from the server. If this threshold is reached while keep-alive messages are being sent, the * connection will be disconnected. The default value is one. * * @param count the specified count * @see #getServerAliveCountMax() */ public void setServerAliveCountMax(int count) { this.serverAliveCountMax = count; } /** * Returns setting for the threshold to send keep-alive messages. * * @see #setServerAliveCountMax(int) */ public int getServerAliveCountMax() { return this.serverAliveCountMax; } public void setDaemonThread(boolean enable) { this.daemon_thread = enable; } private String[] checkCiphers(String ciphers) { if (ciphers == null || ciphers.length() == 0) return null; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "CheckCiphers: " + ciphers); } String cipherc2s = getConfig("cipher.c2s"); String ciphers2c = getConfig("cipher.s2c"); Vector result = new Vector<>(); String[] _ciphers = Util.split(ciphers, ","); for (int i = 0; i < _ciphers.length; i++) { String cipher = _ciphers[i]; if (ciphers2c.indexOf(cipher) == -1 && cipherc2s.indexOf(cipher) == -1) continue; if (!checkCipher(getConfig(cipher))) { result.addElement(cipher); } } if (result.size() == 0) return null; String[] foo = new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); if (getLogger().isEnabled(Logger.INFO)) { for (int i = 0; i < foo.length; i++) { getLogger().log(Logger.INFO, foo[i] + " is not available."); } } return foo; } static boolean checkCipher(String cipher) { try { Class c = Class.forName(cipher).asSubclass(Cipher.class); Cipher _c = c.getDeclaredConstructor().newInstance(); _c.init(Cipher.ENCRYPT_MODE, new byte[_c.getBlockSize()], new byte[_c.getIVSize()]); return true; } catch (Exception | NoClassDefFoundError e) { return false; } } private String[] checkMacs(String macs) { if (macs == null || macs.length() == 0) return null; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "CheckMacs: " + macs); } String macc2s = getConfig("mac.c2s"); String macs2c = getConfig("mac.s2c"); Vector result = new Vector<>(); String[] _macs = Util.split(macs, ","); for (int i = 0; i < _macs.length; i++) { String mac = _macs[i]; if (macs2c.indexOf(mac) == -1 && macc2s.indexOf(mac) == -1) continue; if (!checkMac(getConfig(mac))) { result.addElement(mac); } } if (result.size() == 0) return null; String[] foo = new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); if (getLogger().isEnabled(Logger.INFO)) { for (int i = 0; i < foo.length; i++) { getLogger().log(Logger.INFO, foo[i] + " is not available."); } } return foo; } static boolean checkMac(String mac) { try { Class c = Class.forName(mac).asSubclass(MAC.class); MAC _c = c.getDeclaredConstructor().newInstance(); _c.init(new byte[_c.getBlockSize()]); return true; } catch (Exception | NoClassDefFoundError e) { return false; } } private String[] checkKexes(String kexes) { if (kexes == null || kexes.length() == 0) return null; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "CheckKexes: " + kexes); } Vector result = new Vector<>(); String[] _kexes = Util.split(kexes, ","); for (int i = 0; i < _kexes.length; i++) { if (!checkKex(this, getConfig(_kexes[i]))) { result.addElement(_kexes[i]); } } if (result.size() == 0) return null; String[] foo = new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); if (getLogger().isEnabled(Logger.INFO)) { for (int i = 0; i < foo.length; i++) { getLogger().log(Logger.INFO, foo[i] + " is not available."); } } return foo; } static boolean checkKex(Session s, String kex) { try { Class c = Class.forName(kex).asSubclass(KeyExchange.class); KeyExchange _c = c.getDeclaredConstructor().newInstance(); _c.doInit(s, null, null, null, null); return true; } catch (Exception | NoClassDefFoundError e) { return false; } } private String[] checkSignatures(String sigs) { if (sigs == null || sigs.length() == 0) return null; if (getLogger().isEnabled(Logger.INFO)) { getLogger().log(Logger.INFO, "CheckSignatures: " + sigs); } Vector result = new Vector<>(); String[] _sigs = Util.split(sigs, ","); for (int i = 0; i < _sigs.length; i++) { try { Class c = Class.forName(JSch.getConfig(_sigs[i])).asSubclass(Signature.class); final Signature sig = c.getDeclaredConstructor().newInstance(); sig.init(); } catch (Exception | NoClassDefFoundError e) { result.addElement(_sigs[i]); } } if (result.size() == 0) return null; String[] foo = new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); if (getLogger().isEnabled(Logger.INFO)) { for (int i = 0; i < foo.length; i++) { getLogger().log(Logger.INFO, foo[i] + " is not available."); } } return foo; } /** * Sets the identityRepository, which will be referred in the public key authentication. The * default value is null. * * @param identityRepository * @see #getIdentityRepository() */ public void setIdentityRepository(IdentityRepository identityRepository) { this.identityRepository = identityRepository; } /** * Gets the identityRepository. If this.identityRepository is null, * JSch#getIdentityRepository() will be invoked. * * @see JSch#getIdentityRepository() */ IdentityRepository getIdentityRepository() { if (identityRepository == null) return jsch.getIdentityRepository(); return identityRepository; } /** * Sets the hostkeyRepository, which will be referred in checking host keys. * * @param hostkeyRepository * @see #getHostKeyRepository() */ public void setHostKeyRepository(HostKeyRepository hostkeyRepository) { this.hostkeyRepository = hostkeyRepository; } /** * Gets the hostkeyRepository. If this.hostkeyRepository is null, * JSch#getHostKeyRepository() will be invoked. * * @see JSch#getHostKeyRepository() */ public HostKeyRepository getHostKeyRepository() { if (hostkeyRepository == null) return jsch.getHostKeyRepository(); return hostkeyRepository; } /* * // setProxyCommand("ssh -l user2 host2 -o 'ProxyCommand ssh user1@host1 nc host2 22' nc %h %p") * public void setProxyCommand(String command){ setProxy(new ProxyCommand(command)); } * * class ProxyCommand implements Proxy { String command; Process p = null; InputStream in = null; * OutputStream out = null; ProxyCommand(String command){ this.command = command; } public void * connect(SocketFactory socket_factory, String host, int port, int timeout) throws Exception { * String _command = command.replace("%h", host); _command = _command.replace("%p", new * Integer(port).toString()); p = Runtime.getRuntime().exec(_command); in = p.getInputStream(); * out = p.getOutputStream(); } public Socket getSocket() { return null; } public InputStream * getInputStream() { return in; } public OutputStream getOutputStream() { return out; } public * void close() { try{ if(p!=null){ p.getErrorStream().close(); p.getOutputStream().close(); * p.getInputStream().close(); p.destroy(); p=null; } } catch(IOException e){ } } } */ private void applyConfig() throws JSchException { ConfigRepository configRepository = jsch.getConfigRepository(); if (configRepository == null) { return; } ConfigRepository.Config config = configRepository.getConfig(org_host); String value = null; if (username == null) { value = config.getUser(); if (value != null) username = value; } value = config.getHostname(); if (value != null) host = value; int port = config.getPort(); if (port != -1) this.port = port; checkConfig(config, "kex"); checkConfig(config, "server_host_key"); checkConfig(config, "prefer_known_host_key_types"); checkConfig(config, "enable_server_sig_algs"); checkConfig(config, "enable_ext_info_in_auth"); checkConfig(config, "enable_strict_kex"); checkConfig(config, "require_strict_kex"); checkConfig(config, "enable_pubkey_auth_query"); checkConfig(config, "try_additional_pubkey_algorithms"); checkConfig(config, "enable_auth_none"); checkConfig(config, "use_sftp_write_flush_workaround"); checkConfig(config, "cipher.c2s"); checkConfig(config, "cipher.s2c"); checkConfig(config, "mac.c2s"); checkConfig(config, "mac.s2c"); checkConfig(config, "compression.c2s"); checkConfig(config, "compression.s2c"); checkConfig(config, "compression_level"); checkConfig(config, "StrictHostKeyChecking"); checkConfig(config, "HashKnownHosts"); checkConfig(config, "PreferredAuthentications"); checkConfig(config, "PubkeyAcceptedAlgorithms"); checkConfig(config, "FingerprintHash"); checkConfig(config, "MaxAuthTries"); checkConfig(config, "ClearAllForwardings"); value = config.getValue("HostKeyAlias"); if (value != null) this.setHostKeyAlias(value); value = config.getValue("UserKnownHostsFile"); if (value != null) { KnownHosts kh = new KnownHosts(jsch); kh.setKnownHosts(value); this.setHostKeyRepository(kh); } String[] values = config.getValues("IdentityFile"); if (values != null) { String[] global = configRepository.getConfig("").getValues("IdentityFile"); if (global != null) { for (int i = 0; i < global.length; i++) { jsch.addIdentity(global[i]); } } else { global = new String[0]; } if (values.length - global.length > 0) { IdentityRepositoryWrapper ir = new IdentityRepositoryWrapper(jsch.getIdentityRepository(), true); for (int i = 0; i < values.length; i++) { String ifile = values[i]; for (int j = 0; j < global.length; j++) { if (!ifile.equals(global[j])) continue; ifile = null; break; } if (ifile == null) continue; Identity identity = IdentityFile.newInstance(ifile, null, jsch.instLogger); ir.add(identity); } this.setIdentityRepository(ir); } } value = config.getValue("ServerAliveInterval"); if (value != null) { try { this.setServerAliveInterval(Integer.parseInt(value)); } catch (NumberFormatException e) { } } value = config.getValue("ConnectTimeout"); if (value != null) { try { setTimeout(Integer.parseInt(value)); } catch (NumberFormatException e) { } } value = config.getValue("MaxAuthTries"); if (value != null) { setConfig("MaxAuthTries", value); } value = config.getValue("ClearAllForwardings"); if (value != null) { setConfig("ClearAllForwardings", value); } } private void applyConfigChannel(ChannelSession channel) throws JSchException { ConfigRepository configRepository = jsch.getConfigRepository(); if (configRepository == null) { return; } ConfigRepository.Config config = configRepository.getConfig(org_host); String value = null; value = config.getValue("ForwardAgent"); if (value != null) { channel.setAgentForwarding(value.equals("yes")); } value = config.getValue("RequestTTY"); if (value != null) { channel.setPty(value.equals("yes")); } } private void requestPortForwarding() throws JSchException { if (getConfig("ClearAllForwardings").equals("yes")) return; ConfigRepository configRepository = jsch.getConfigRepository(); if (configRepository == null) { return; } ConfigRepository.Config config = configRepository.getConfig(org_host); String[] values = config.getValues("LocalForward"); if (values != null) { for (int i = 0; i < values.length; i++) { setPortForwardingL(values[i]); } } values = config.getValues("RemoteForward"); if (values != null) { for (int i = 0; i < values.length; i++) { setPortForwardingR(values[i]); } } } private void checkConfig(ConfigRepository.Config config, String key) { String value = config.getValue(key); if (value == null && key.equals("PubkeyAcceptedAlgorithms")) value = config.getValue("PubkeyAcceptedKeyTypes"); if (value != null) this.setConfig(key, value); } /** * Returns the logger being used by this instance of Session. If no particular logger has been * set, the instance logger of the jsch instance is returned this session belongs to. * * @return The logger */ public Logger getLogger() { if (logger != null) { return logger; } return jsch.getInstanceLogger(); } /** * Sets the logger being used by this instance of Session * * @param logger The logger or null if the instance logger of this instance's jsch * instance should be used */ public void setLogger(Logger logger) { this.logger = logger; } int getBufferMargin() { int buffer_margin = 32 + // maximum padding length 32; // margin for deflater; deflater may inflate data Cipher _c2scipher = c2scipher; MAC _c2smac = c2smac; // maximum mac length int mac_length = 20; if (_c2scipher != null && (_c2scipher.isChaCha20() || _c2scipher.isAEAD())) { if (_c2scipher.getTagSize() > mac_length) { mac_length = _c2scipher.getTagSize(); } } else if (_c2smac != null) { if (_c2smac.getBlockSize() > mac_length) { mac_length = _c2smac.getBlockSize(); } } buffer_margin += mac_length; return buffer_margin; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SftpATTRS.java000066400000000000000000000244441465436372100245240ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; /* * uint32 flags uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE uint32 uid present only if * flag SSH_FILEXFER_ATTR_UIDGID uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID uint32 * permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS uint32 atime present only if flag * SSH_FILEXFER_ACMODTIME uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME uint32 * extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED string extended_type string * extended_data ... more extended data (extended_type - extended_data pairs), so that number of * pairs equals extended_count */ public class SftpATTRS { static final int S_ISUID = 04000; // set user ID on execution static final int S_ISGID = 02000; // set group ID on execution static final int S_ISVTX = 01000; // sticky bit ****** NOT DOCUMENTED ***** static final int S_IRUSR = 00400; // read by owner static final int S_IWUSR = 00200; // write by owner static final int S_IXUSR = 00100; // execute/search by owner static final int S_IREAD = 00400; // read by owner static final int S_IWRITE = 00200; // write by owner static final int S_IEXEC = 00100; // execute/search by owner static final int S_IRGRP = 00040; // read by group static final int S_IWGRP = 00020; // write by group static final int S_IXGRP = 00010; // execute/search by group static final int S_IROTH = 00004; // read by others static final int S_IWOTH = 00002; // write by others static final int S_IXOTH = 00001; // execute/search by others private static final int pmask = 0xFFF; public String getPermissionsString() { StringBuilder buf = new StringBuilder(10); if (isDir()) buf.append('d'); else if (isLink()) buf.append('l'); else buf.append('-'); if ((permissions & S_IRUSR) != 0) buf.append('r'); else buf.append('-'); if ((permissions & S_IWUSR) != 0) buf.append('w'); else buf.append('-'); if ((permissions & S_ISUID) != 0) buf.append('s'); else if ((permissions & S_IXUSR) != 0) buf.append('x'); else buf.append('-'); if ((permissions & S_IRGRP) != 0) buf.append('r'); else buf.append('-'); if ((permissions & S_IWGRP) != 0) buf.append('w'); else buf.append('-'); if ((permissions & S_ISGID) != 0) buf.append('s'); else if ((permissions & S_IXGRP) != 0) buf.append('x'); else buf.append('-'); if ((permissions & S_IROTH) != 0) buf.append('r'); else buf.append('-'); if ((permissions & S_IWOTH) != 0) buf.append('w'); else buf.append('-'); if ((permissions & S_IXOTH) != 0) buf.append('x'); else buf.append('-'); return (buf.toString()); } public String getAtimeString() { return toDateString(Integer.toUnsignedLong(atime)); } public String getMtimeString() { return toDateString(Integer.toUnsignedLong(mtime)); } private static DateTimeFormatter DTF = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT); static String toDateString(long epochSeconds) { Instant instant = Instant.ofEpochSecond(epochSeconds); ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); return DTF.format(zdt); } public static final int SSH_FILEXFER_ATTR_SIZE = 0x00000001; public static final int SSH_FILEXFER_ATTR_UIDGID = 0x00000002; public static final int SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004; public static final int SSH_FILEXFER_ATTR_ACMODTIME = 0x00000008; public static final int SSH_FILEXFER_ATTR_EXTENDED = 0x80000000; static final int S_IFMT = 0xf000; static final int S_IFIFO = 0x1000; static final int S_IFCHR = 0x2000; static final int S_IFDIR = 0x4000; static final int S_IFBLK = 0x6000; static final int S_IFREG = 0x8000; static final int S_IFLNK = 0xa000; static final int S_IFSOCK = 0xc000; int flags = 0; long size; int uid; int gid; int permissions; int atime; int mtime; String[] extended = null; private SftpATTRS() {} static SftpATTRS getATTR(Buffer buf) { SftpATTRS attr = new SftpATTRS(); attr.flags = buf.getInt(); if ((attr.flags & SSH_FILEXFER_ATTR_SIZE) != 0) { attr.size = buf.getLong(); } if ((attr.flags & SSH_FILEXFER_ATTR_UIDGID) != 0) { attr.uid = buf.getInt(); attr.gid = buf.getInt(); } if ((attr.flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0) { attr.permissions = buf.getInt(); } if ((attr.flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) { attr.atime = buf.getInt(); } if ((attr.flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) { attr.mtime = buf.getInt(); } if ((attr.flags & SSH_FILEXFER_ATTR_EXTENDED) != 0) { int count = buf.getInt(); if (count > 0) { attr.extended = new String[count * 2]; for (int i = 0; i < count; i++) { attr.extended[i * 2] = Util.byte2str(buf.getString()); attr.extended[i * 2 + 1] = Util.byte2str(buf.getString()); } } } return attr; } int length() { int len = 4; if ((flags & SSH_FILEXFER_ATTR_SIZE) != 0) { len += 8; } if ((flags & SSH_FILEXFER_ATTR_UIDGID) != 0) { len += 8; } if ((flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0) { len += 4; } if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) { len += 8; } if ((flags & SSH_FILEXFER_ATTR_EXTENDED) != 0) { len += 4; int count = extended.length / 2; if (count > 0) { for (int i = 0; i < count; i++) { len += 4; len += extended[i * 2].length(); len += 4; len += extended[i * 2 + 1].length(); } } } return len; } void dump(Buffer buf) { buf.putInt(flags); if ((flags & SSH_FILEXFER_ATTR_SIZE) != 0) { buf.putLong(size); } if ((flags & SSH_FILEXFER_ATTR_UIDGID) != 0) { buf.putInt(uid); buf.putInt(gid); } if ((flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0) { buf.putInt(permissions); } if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) { buf.putInt(atime); } if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0) { buf.putInt(mtime); } if ((flags & SSH_FILEXFER_ATTR_EXTENDED) != 0) { int count = extended.length / 2; if (count > 0) { for (int i = 0; i < count; i++) { buf.putString(Util.str2byte(extended[i * 2])); buf.putString(Util.str2byte(extended[i * 2 + 1])); } } } } void setFLAGS(int flags) { this.flags = flags; } public void setSIZE(long size) { flags |= SSH_FILEXFER_ATTR_SIZE; this.size = size; } public void setUIDGID(int uid, int gid) { flags |= SSH_FILEXFER_ATTR_UIDGID; this.uid = uid; this.gid = gid; } public void setACMODTIME(int atime, int mtime) { flags |= SSH_FILEXFER_ATTR_ACMODTIME; this.atime = atime; this.mtime = mtime; } public void setPERMISSIONS(int permissions) { flags |= SSH_FILEXFER_ATTR_PERMISSIONS; permissions = (this.permissions & ~pmask) | (permissions & pmask); this.permissions = permissions; } private boolean isType(int mask) { return (flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0 && (permissions & S_IFMT) == mask; } public boolean isReg() { return isType(S_IFREG); } public boolean isDir() { return isType(S_IFDIR); } public boolean isChr() { return isType(S_IFCHR); } public boolean isBlk() { return isType(S_IFBLK); } public boolean isFifo() { return isType(S_IFIFO); } public boolean isLink() { return isType(S_IFLNK); } public boolean isSock() { return isType(S_IFSOCK); } public int getFlags() { return flags; } public long getSize() { return size; } public int getUId() { return uid; } public int getGId() { return gid; } public int getPermissions() { return permissions; } public int getATime() { return atime; } public int getMTime() { return mtime; } public String[] getExtended() { return extended; } @Override public String toString() { return (getPermissionsString() + " " + getUId() + " " + getGId() + " " + getSize() + " " + getMtimeString()); } /* * public String toString(){ return (((flags&SSH_FILEXFER_ATTR_SIZE)!=0) ? ("size:"+size+" ") : * "")+ (((flags&SSH_FILEXFER_ATTR_UIDGID)!=0) ? ("uid:"+uid+",gid:"+gid+" ") : "")+ * (((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0) ? * ("permissions:0x"+Integer.toHexString(permissions)+" ") : "")+ * (((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0) ? ("atime:"+atime+",mtime:"+mtime+" ") : "")+ * (((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0) ? ("extended:?"+" ") : ""); } */ } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SftpException.java000066400000000000000000000036001465436372100255540ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class SftpException extends Exception { private static final long serialVersionUID = -1L; public int id; public SftpException(int id, String message) { super(message); this.id = id; } public SftpException(int id, String message, Throwable e) { super(message, e); this.id = id; } @Override public String toString() { return id + ": " + getMessage(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SftpProgressMonitor.java000066400000000000000000000033631465436372100270000ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface SftpProgressMonitor { public static final int PUT = 0; public static final int GET = 1; public static final long UNKNOWN_SIZE = -1L; void init(int op, String src, String dest, long max); boolean count(long count); void end(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SftpStatVFS.java000066400000000000000000000075561465436372100251260ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class SftpStatVFS { /* * It seems data is serializsed according to sys/statvfs.h; for example, * http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/statvfs.h.html */ private long bsize; private long frsize; private long blocks; private long bfree; private long bavail; private long files; private long ffree; private long favail; private long fsid; private long flag; private long namemax; int flags = 0; long size; int uid; int gid; int permissions; int atime; int mtime; String[] extended = null; private SftpStatVFS() {} static SftpStatVFS getStatVFS(Buffer buf) { SftpStatVFS statvfs = new SftpStatVFS(); statvfs.bsize = buf.getLong(); statvfs.frsize = buf.getLong(); statvfs.blocks = buf.getLong(); statvfs.bfree = buf.getLong(); statvfs.bavail = buf.getLong(); statvfs.files = buf.getLong(); statvfs.ffree = buf.getLong(); statvfs.favail = buf.getLong(); statvfs.fsid = buf.getLong(); int flag = (int) buf.getLong(); statvfs.namemax = buf.getLong(); statvfs.flag = (flag & 1 /* SSH2_FXE_STATVFS_ST_RDONLY */) != 0 ? 1 /* ST_RDONLY */ : 0; statvfs.flag |= (flag & 2 /* SSH2_FXE_STATVFS_ST_NOSUID */) != 0 ? 2 /* ST_NOSUID */ : 0; return statvfs; } public long getBlockSize() { return bsize; } public long getFragmentSize() { return frsize; } public long getBlocks() { return blocks; } public long getFreeBlocks() { return bfree; } public long getAvailBlocks() { return bavail; } public long getINodes() { return files; } public long getFreeINodes() { return ffree; } public long getAvailINodes() { return favail; } public long getFileSystemID() { return fsid; } public long getMountFlag() { return flag; } public long getMaximumFilenameLength() { return namemax; } public long getSize() { return getFragmentSize() * getBlocks() / 1024; } public long getUsed() { return getFragmentSize() * (getBlocks() - getFreeBlocks()) / 1024; } public long getAvailForNonRoot() { return getFragmentSize() * getAvailBlocks() / 1024; } public long getAvail() { return getFragmentSize() * getFreeBlocks() / 1024; } public int getCapacity() { return (int) (100 * (getBlocks() - getFreeBlocks()) / getBlocks()); } // public String toString() { return ""; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Signature.java000066400000000000000000000032541465436372100247270ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface Signature { void init() throws Exception; void update(byte[] H) throws Exception; boolean verify(byte[] sig) throws Exception; byte[] sign() throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SignatureDSA.java000066400000000000000000000032721465436372100252570ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface SignatureDSA extends Signature { void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception; void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SignatureECDSA.java000066400000000000000000000032121465436372100254610ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface SignatureECDSA extends Signature { void setPubKey(byte[] r, byte[] s) throws Exception; void setPrvKey(byte[] s) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SignatureEdDSA.java000066400000000000000000000032101465436372100255200ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface SignatureEdDSA extends Signature { void setPubKey(byte[] y_arr) throws Exception; void setPrvKey(byte[] bytes) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SignatureRSA.java000066400000000000000000000032221465436372100252700ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface SignatureRSA extends Signature { void setPubKey(byte[] e, byte[] n) throws Exception; void setPrvKey(byte[] d, byte[] n) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Slf4jLogger.java000066400000000000000000000030101465436372100250760ustar00rootroot00000000000000package com.jcraft.jsch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** JSch logger to log entries using the SLF4J framework */ public class Slf4jLogger implements com.jcraft.jsch.Logger { private static final Logger logger = LoggerFactory.getLogger(JSch.class); public Slf4jLogger() {} @Override public boolean isEnabled(int level) { switch (level) { case com.jcraft.jsch.Logger.DEBUG: return logger.isDebugEnabled(); case com.jcraft.jsch.Logger.INFO: return logger.isInfoEnabled(); case com.jcraft.jsch.Logger.WARN: return logger.isWarnEnabled(); case com.jcraft.jsch.Logger.ERROR: case com.jcraft.jsch.Logger.FATAL: return logger.isErrorEnabled(); default: return logger.isTraceEnabled(); } } @Override public void log(int level, String message) { log(level, message, null); } @Override public void log(int level, String message, Throwable cause) { if (!isEnabled(level)) { return; } switch (level) { case com.jcraft.jsch.Logger.DEBUG: logger.debug(message, cause); break; case com.jcraft.jsch.Logger.INFO: logger.info(message, cause); break; case com.jcraft.jsch.Logger.WARN: logger.warn(message, cause); break; case com.jcraft.jsch.Logger.ERROR: case com.jcraft.jsch.Logger.FATAL: logger.error(message, cause); break; default: logger.trace(message, cause); break; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/SocketFactory.java000066400000000000000000000036261465436372100255510ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public interface SocketFactory { public Socket createSocket(String host, int port) throws IOException, UnknownHostException; public InputStream getInputStream(Socket socket) throws IOException; public OutputStream getOutputStream(Socket socket) throws IOException; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UIKeyboardInteractive.java000066400000000000000000000032341465436372100271600ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface UIKeyboardInteractive { String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/USocketFactory.java000066400000000000000000000034161465436372100256730ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.file.Path; public interface USocketFactory { SocketChannel connect(Path path) throws IOException; ServerSocketChannel bind(Path path) throws IOException; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UnixDomainSocketFactory.java000066400000000000000000000042471465436372100275450ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.file.Path; public class UnixDomainSocketFactory implements USocketFactory { public UnixDomainSocketFactory() throws AgentProxyException { throw new AgentProxyException("UnixDomainSocketFactory requires Java16+."); } @Override public SocketChannel connect(Path path) throws IOException { throw new UnsupportedOperationException("UnixDomainSocketFactory requires Java16+."); } @Override public ServerSocketChannel bind(Path path) throws IOException { throw new UnsupportedOperationException("UnixDomainSocketFactory requires Java16+."); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserAuth.java000066400000000000000000000044321465436372100245250ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public abstract class UserAuth { protected static final int SSH_MSG_USERAUTH_REQUEST = 50; protected static final int SSH_MSG_USERAUTH_FAILURE = 51; protected static final int SSH_MSG_USERAUTH_SUCCESS = 52; protected static final int SSH_MSG_USERAUTH_BANNER = 53; protected static final int SSH_MSG_USERAUTH_INFO_REQUEST = 60; protected static final int SSH_MSG_USERAUTH_INFO_RESPONSE = 61; protected static final int SSH_MSG_USERAUTH_PK_OK = 60; protected UserInfo userinfo; protected Packet packet; protected Buffer buf; protected String username; public boolean start(Session session) throws Exception { this.userinfo = session.getUserInfo(); this.packet = session.packet; this.buf = packet.getBuffer(); this.username = session.getUserName(); return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java000066400000000000000000000156541465436372100266310ustar00rootroot00000000000000/* * Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class UserAuthGSSAPIWithMIC extends UserAuth { private static final int SSH_MSG_USERAUTH_GSSAPI_RESPONSE = 60; private static final int SSH_MSG_USERAUTH_GSSAPI_TOKEN = 61; private static final int SSH_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE = 63; private static final int SSH_MSG_USERAUTH_GSSAPI_ERROR = 64; private static final int SSH_MSG_USERAUTH_GSSAPI_ERRTOK = 65; private static final int SSH_MSG_USERAUTH_GSSAPI_MIC = 66; private static final byte[][] supported_oid = { // OID 1.2.840.113554.1.2.2 in DER {(byte) 0x6, (byte) 0x9, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x12, (byte) 0x1, (byte) 0x2, (byte) 0x2}}; private static final String[] supported_method = {"gssapi-with-mic.krb5"}; @Override public boolean start(Session session) throws Exception { super.start(session); byte[] _username = Util.str2byte(username); packet.reset(); // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name(in ISO-10646 UTF-8 encoding) // string service name(in US-ASCII) // string "gssapi"(US-ASCII) // uint32 n, the number of OIDs client supports // string[n] mechanism OIDS buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("gssapi-with-mic")); buf.putInt(supported_oid.length); for (int i = 0; i < supported_oid.length; i++) { buf.putString(supported_oid[i]); } session.write(packet); String method = null; int command; while (true) { buf = session.read(buf); command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_FAILURE) { return false; } if (command == SSH_MSG_USERAUTH_GSSAPI_RESPONSE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] message = buf.getString(); for (int i = 0; i < supported_oid.length; i++) { if (Util.array_equals(message, supported_oid[i])) { method = supported_method[i]; break; } } if (method == null) { return false; } break; // success } if (command == SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = Util.byte2str(_message); if (userinfo != null) { userinfo.showMessage(message); } continue; } return false; } GSSContext context = null; try { Class c = Class.forName(session.getConfig(method)).asSubclass(GSSContext.class); context = c.getDeclaredConstructor().newInstance(); } catch (Exception e) { return false; } try { context.create(username, session.host); } catch (JSchException e) { return false; } byte[] token = new byte[0]; while (!context.isEstablished()) { try { token = context.init(token, 0, token.length); } catch (JSchException e) { // TODO // ERRTOK should be sent? // byte SSH_MSG_USERAUTH_GSSAPI_ERRTOK // string error token return false; } if (token != null) { packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_GSSAPI_TOKEN); buf.putString(token); session.write(packet); } if (!context.isEstablished()) { buf = session.read(buf); command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_GSSAPI_ERROR) { // uint32 major_status // uint32 minor_status // string message // string language tag buf = session.read(buf); command = buf.getCommand() & 0xff; // return false; } else if (command == SSH_MSG_USERAUTH_GSSAPI_ERRTOK) { // string error token buf = session.read(buf); command = buf.getCommand() & 0xff; // return false; } if (command == SSH_MSG_USERAUTH_FAILURE) { return false; } buf.getInt(); buf.getByte(); buf.getByte(); token = buf.getString(); } } Buffer mbuf = new Buffer(); // string session identifier // byte SSH_MSG_USERAUTH_REQUEST // string user name // string service // string "gssapi-with-mic" mbuf.putString(session.getSessionId()); mbuf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); mbuf.putString(_username); mbuf.putString(Util.str2byte("ssh-connection")); mbuf.putString(Util.str2byte("gssapi-with-mic")); byte[] mic = context.getMIC(mbuf.buffer, 0, mbuf.getLength()); if (mic == null) { return false; } packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_GSSAPI_MIC); buf.putString(mic); session.write(packet); context.dispose(); buf = session.read(buf); command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_SUCCESS) { return true; } else if (command == SSH_MSG_USERAUTH_FAILURE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo = buf.getString(); int partial_success = buf.getByte(); // System.err.println(new String(foo)+ // " partial_success:"+(partial_success!=0)); if (partial_success != 0) { throw new JSchPartialAuthException(Util.byte2str(foo)); } } return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java000066400000000000000000000155231465436372100304070ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.Locale; class UserAuthKeyboardInteractive extends UserAuth { @Override public boolean start(Session session) throws Exception { super.start(session); if (userinfo != null && !(userinfo instanceof UIKeyboardInteractive)) { return false; } String dest = username + "@" + session.host; if (session.port != 22) { dest += (":" + session.port); } byte[] password = session.password; boolean cancel = false; byte[] _username = null; _username = Util.str2byte(username); while (true) { if (session.auth_failures >= session.max_auth_tries) { return false; } // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name (ISO-10646 UTF-8, as defined in [RFC-2279]) // string service name (US-ASCII) "ssh-userauth" ? "ssh-connection" // string "keyboard-interactive" (US-ASCII) // string language tag (as defined in [RFC-3066]) // string submethods (ISO-10646 UTF-8) packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); // buf.putString("ssh-userauth".getBytes()); buf.putString(Util.str2byte("keyboard-interactive")); buf.putString(Util.empty); buf.putString(Util.empty); session.write(packet); boolean firsttime = true; loop: while (true) { buf = session.read(buf); int command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_SUCCESS) { return true; } if (command == SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = Util.byte2str(_message); if (userinfo != null) { userinfo.showMessage(message); } continue loop; } if (command == SSH_MSG_USERAUTH_FAILURE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo = buf.getString(); int partial_success = buf.getByte(); // System.err.println(new String(foo)+ // " partial_success:"+(partial_success!=0)); if (partial_success != 0) { throw new JSchPartialAuthException(Util.byte2str(foo)); } if (firsttime) { return false; // throw new JSchException("USERAUTH KI is not supported"); // cancel=true; // ?? } session.auth_failures++; break; } if (command == SSH_MSG_USERAUTH_INFO_REQUEST) { firsttime = false; buf.getInt(); buf.getByte(); buf.getByte(); String name = Util.byte2str(buf.getString()); String instruction = Util.byte2str(buf.getString()); String languate_tag = Util.byte2str(buf.getString()); int num = buf.getInt(); String[] prompt = new String[num]; boolean[] echo = new boolean[num]; for (int i = 0; i < num; i++) { prompt[i] = Util.byte2str(buf.getString()); echo[i] = (buf.getByte() != 0); } byte[][] response = null; if (password != null && prompt.length == 1 && !echo[0] && prompt[0].toLowerCase(Locale.ROOT).indexOf("password:") >= 0) { response = new byte[1][]; response[0] = password; password = null; } else if (num > 0 || (name.length() > 0 || instruction.length() > 0)) { if (userinfo != null) { UIKeyboardInteractive kbi = (UIKeyboardInteractive) userinfo; String[] _response = kbi.promptKeyboardInteractive(dest, name, instruction, prompt, echo); if (_response != null) { response = new byte[_response.length][]; for (int i = 0; i < _response.length; i++) { response[i] = _response[i] != null ? Util.str2byte(_response[i]) : Util.empty; } } } } // byte SSH_MSG_USERAUTH_INFO_RESPONSE(61) // int num-responses // string response[1] (ISO-10646 UTF-8) // ... // string response[num-responses] (ISO-10646 UTF-8) packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_INFO_RESPONSE); if (num > 0 && (response == null || // cancel num != response.length)) { if (response == null) { // working around the bug in OpenSSH ;-< buf.putInt(num); for (int i = 0; i < num; i++) { buf.putString(Util.empty); } } else { buf.putInt(0); } if (response == null) cancel = true; } else { buf.putInt(num); for (int i = 0; i < num; i++) { buf.putString(response[i]); } } session.write(packet); /* * if(cancel) break; */ continue loop; } // throw new JSchException("USERAUTH fail ("+command+")"); return false; } if (cancel) { throw new JSchAuthCancelException("keyboard-interactive"); // break; } } // return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserAuthNone.java000066400000000000000000000107611465436372100253470ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public class UserAuthNone extends UserAuth { protected static final int SSH_MSG_SERVICE_REQUEST = 5; protected static final int SSH_MSG_SERVICE_ACCEPT = 6; private String methods; @Override public boolean start(Session session) throws Exception { super.start(session); // send // byte SSH_MSG_SERVICE_REQUEST(5) // string service name "ssh-userauth" packet.reset(); buf.putByte((byte) SSH_MSG_SERVICE_REQUEST); buf.putString(Util.str2byte("ssh-userauth")); session.write(packet); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_SERVICE_REQUEST sent"); } // receive // byte SSH_MSG_SERVICE_ACCEPT(6) // string service name buf = session.read(buf); int command = buf.getCommand(); boolean result = (command == SSH_MSG_SERVICE_ACCEPT); if (session.getLogger().isEnabled(Logger.INFO)) { session.getLogger().log(Logger.INFO, "SSH_MSG_SERVICE_ACCEPT received"); } if (!result) return false; if (!session.getConfig("enable_auth_none").equals("yes")) return false; byte[] _username = null; _username = Util.str2byte(username); // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name // string service name ("ssh-connection") // string "none" packet.reset(); buf.putByte((byte) UserAuth.SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("none")); session.write(packet); loop: while (true) { buf = session.read(buf); command = buf.getCommand() & 0xff; if (command == UserAuth.SSH_MSG_USERAUTH_SUCCESS) { return true; } if (command == UserAuth.SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = Util.byte2str(_message); if (userinfo != null) { try { userinfo.showMessage(message); } catch (RuntimeException ee) { } } continue loop; } if (command == UserAuth.SSH_MSG_USERAUTH_FAILURE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo = buf.getString(); int partial_success = buf.getByte(); setMethods(Util.byte2str(foo)); // System.err.println("UserAuthNone: " + methods + " partial_success:" + (partial_success != // 0)); // if (partial_success != 0) { // throw new JSchPartialAuthException(new String(foo)); // } break; } else { // System.err.println("USERAUTH fail (" + command + ")"); throw new JSchException("USERAUTH fail (" + command + ")"); } } // throw new JSchException("USERAUTH fail"); return false; } protected String getMethods() { return methods; } protected void setMethods(String methods) { this.methods = methods; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserAuthPassword.java000066400000000000000000000151461465436372100262540ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; class UserAuthPassword extends UserAuth { private final int SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60; @Override public boolean start(Session session) throws Exception { super.start(session); byte[] password = session.password; String dest = username + "@" + session.host; if (session.port != 22) { dest += (":" + session.port); } try { while (true) { if (session.auth_failures >= session.max_auth_tries) { return false; } if (password == null) { if (userinfo == null) { // throw new JSchException("USERAUTH fail"); return false; } if (!userinfo.promptPassword("Password for " + dest)) { throw new JSchAuthCancelException("password"); // break; } String _password = userinfo.getPassword(); if (_password == null) { throw new JSchAuthCancelException("password"); // break; } password = Util.str2byte(_password); } byte[] _username = null; _username = Util.str2byte(username); // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name // string service name ("ssh-connection") // string "password" // boolen FALSE // string plaintext password (ISO-10646 UTF-8) packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("password")); buf.putByte((byte) 0); buf.putString(password); session.write(packet); loop: while (true) { buf = session.read(buf); int command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_SUCCESS) { return true; } if (command == SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = Util.byte2str(_message); if (userinfo != null) { userinfo.showMessage(message); } continue loop; } if (command == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] instruction = buf.getString(); byte[] tag = buf.getString(); if (userinfo == null || !(userinfo instanceof UIKeyboardInteractive)) { if (userinfo != null) { userinfo.showMessage("Password must be changed."); } return false; } UIKeyboardInteractive kbi = (UIKeyboardInteractive) userinfo; String[] response; String name = "Password Change Required"; String[] prompt = {"New Password: "}; boolean[] echo = {false}; response = kbi.promptKeyboardInteractive(dest, name, Util.byte2str(instruction), prompt, echo); if (response == null) { throw new JSchAuthCancelException("password"); } byte[] newpassword = response[0] != null ? Util.str2byte(response[0]) : Util.empty; // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name // string service name ("ssh-connection") // string "password" // boolen TRUE // string plaintext old password (ISO-10646 UTF-8) // string plaintext new password (ISO-10646 UTF-8) packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("password")); buf.putByte((byte) 1); buf.putString(password); buf.putString(newpassword); Util.bzero(newpassword); response = null; session.write(packet); continue loop; } if (command == SSH_MSG_USERAUTH_FAILURE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo = buf.getString(); int partial_success = buf.getByte(); // System.err.println(new String(foo)+ // " partial_success:"+(partial_success!=0)); if (partial_success != 0) { throw new JSchPartialAuthException(Util.byte2str(foo)); } session.auth_failures++; break; } else { // System.err.println("USERAUTH fail ("+buf.getCommand()+")"); // throw new JSchException("USERAUTH fail ("+buf.getCommand()+")"); return false; } } if (password != null) { Util.bzero(password); password = null; } } } finally { if (password != null) { Util.bzero(password); password = null; } } // throw new JSchException("USERAUTH fail"); // return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java000066400000000000000000000374141465436372100263430ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Vector; class UserAuthPublicKey extends UserAuth { @Override public boolean start(Session session) throws Exception { super.start(session); Vector identities = session.getIdentityRepository().getIdentities(); synchronized (identities) { if (identities.size() <= 0) { return false; } String pkmethodstr = session.getConfig("PubkeyAcceptedAlgorithms"); if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, "PubkeyAcceptedAlgorithms = " + pkmethodstr); } String[] not_available_pka = session.getUnavailableSignatures(); List not_available_pks = (not_available_pka != null && not_available_pka.length > 0 ? Arrays.asList(not_available_pka) : Collections.emptyList()); if (!not_available_pks.isEmpty()) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, "Signature algorithms unavailable for non-agent identities = " + not_available_pks); } } List pkmethods = Arrays.asList(Util.split(pkmethodstr, ",")); if (pkmethods.isEmpty()) { return false; } String[] server_sig_algs = session.getServerSigAlgs(); if (server_sig_algs != null && server_sig_algs.length > 0) { List _known = new ArrayList<>(); List _unknown = new ArrayList<>(); for (String pkmethod : pkmethods) { boolean add = false; for (String server_sig_alg : server_sig_algs) { if (pkmethod.equals(server_sig_alg)) { add = true; break; } } if (add) { _known.add(pkmethod); } else { _unknown.add(pkmethod); } } if (!_known.isEmpty()) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, "PubkeyAcceptedAlgorithms in server-sig-algs = " + _known); } } if (!_unknown.isEmpty()) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, "PubkeyAcceptedAlgorithms not in server-sig-algs = " + _unknown); } } if (!_known.isEmpty() && !_unknown.isEmpty()) { boolean success = _start(session, identities, _known, not_available_pks); if (success) { return true; } return _start(session, identities, _unknown, not_available_pks); } } else { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, "No server-sig-algs found, using PubkeyAcceptedAlgorithms = " + pkmethods); } } return _start(session, identities, pkmethods, not_available_pks); } } private boolean _start(Session session, List identities, List pkmethods, List not_available_pks) throws Exception { if (session.auth_failures >= session.max_auth_tries) { return false; } boolean use_pk_auth_query = session.getConfig("enable_pubkey_auth_query").equals("yes"); boolean try_other_pkmethods = session.getConfig("try_additional_pubkey_algorithms").equals("yes"); List rsamethods = new ArrayList<>(); List nonrsamethods = new ArrayList<>(); for (String pkmethod : pkmethods) { if (pkmethod.equals("ssh-rsa") || pkmethod.equals("rsa-sha2-256") || pkmethod.equals("rsa-sha2-512") || pkmethod.equals("ssh-rsa-sha224@ssh.com") || pkmethod.equals("ssh-rsa-sha256@ssh.com") || pkmethod.equals("ssh-rsa-sha384@ssh.com") || pkmethod.equals("ssh-rsa-sha512@ssh.com")) { rsamethods.add(pkmethod); } else { nonrsamethods.add(pkmethod); } } byte[] _username = Util.str2byte(username); int command; iloop: for (Identity identity : identities) { if (session.auth_failures >= session.max_auth_tries) { return false; } // System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); decryptKey(session, identity); // System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); String _ipkmethod = identity.getAlgName(); List ipkmethods = null; if (_ipkmethod.equals("ssh-rsa")) { ipkmethods = new ArrayList<>(rsamethods); } else if (nonrsamethods.contains(_ipkmethod)) { ipkmethods = new ArrayList<>(1); ipkmethods.add(_ipkmethod); } if (ipkmethods == null || ipkmethods.isEmpty()) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, _ipkmethod + " cannot be used as public key type for identity " + identity.getName()); } continue iloop; } ipkmethodloop: while (!ipkmethods.isEmpty() && session.auth_failures < session.max_auth_tries) { byte[] pubkeyblob = identity.getPublicKeyBlob(); List pkmethodsuccesses = null; if (pubkeyblob != null && use_pk_auth_query) { command = SSH_MSG_USERAUTH_FAILURE; Iterator it = ipkmethods.iterator(); loop3: while (it.hasNext()) { String ipkmethod = it.next(); it.remove(); if (not_available_pks.contains(ipkmethod) && !(identity instanceof AgentIdentity)) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, ipkmethod + " not available for identity " + identity.getName()); } continue loop3; } // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name // string service name ("ssh-connection") // string "publickey" // boolen FALSE // string public key algorithm name // string public key blob packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("publickey")); buf.putByte((byte) 0); buf.putString(Util.str2byte(ipkmethod)); buf.putString(pubkeyblob); session.write(packet); loop1: while (true) { buf = session.read(buf); command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_PK_OK) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, ipkmethod + " preauth success"); } pkmethodsuccesses = new ArrayList<>(1); pkmethodsuccesses.add(ipkmethod); break loop3; } else if (command == SSH_MSG_USERAUTH_FAILURE) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, ipkmethod + " preauth failure"); } continue loop3; } else if (command == SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = Util.byte2str(_message); if (userinfo != null) { userinfo.showMessage(message); } continue loop1; } else { // System.err.println("USERAUTH fail ("+command+")"); // throw new JSchException("USERAUTH fail ("+command+")"); if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, ipkmethod + " preauth failure command (" + command + ")"); } continue loop3; } } } if (command != SSH_MSG_USERAUTH_PK_OK) { continue iloop; } } if (identity.isEncrypted()) continue iloop; if (pubkeyblob == null) pubkeyblob = identity.getPublicKeyBlob(); // System.err.println("UserAuthPublicKey: pubkeyblob="+pubkeyblob); if (pubkeyblob == null) continue iloop; if (pkmethodsuccesses == null) pkmethodsuccesses = ipkmethods; if (pkmethodsuccesses.isEmpty()) continue iloop; Iterator it = pkmethodsuccesses.iterator(); loop4: while (it.hasNext() && session.auth_failures < session.max_auth_tries) { String pkmethodsuccess = it.next(); it.remove(); if (not_available_pks.contains(pkmethodsuccess) && !(identity instanceof AgentIdentity)) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, pkmethodsuccess + " not available for identity " + identity.getName()); } continue loop4; } // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name // string service name ("ssh-connection") // string "publickey" // boolen TRUE // string public key algorithm name // string public key blob // string signature packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("publickey")); buf.putByte((byte) 1); buf.putString(Util.str2byte(pkmethodsuccess)); buf.putString(pubkeyblob); // byte[] tmp=new byte[buf.index-5]; // System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length); // buf.putString(signature); byte[] sid = session.getSessionId(); int sidlen = sid.length; byte[] tmp = new byte[4 + sidlen + buf.index - 5]; tmp[0] = (byte) (sidlen >>> 24); tmp[1] = (byte) (sidlen >>> 16); tmp[2] = (byte) (sidlen >>> 8); tmp[3] = (byte) (sidlen); System.arraycopy(sid, 0, tmp, 4, sidlen); System.arraycopy(buf.buffer, 5, tmp, 4 + sidlen, buf.index - 5); byte[] signature = identity.getSignature(tmp, pkmethodsuccess); if (signature == null) { // for example, too long key length. if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, pkmethodsuccess + " signature failure"); } continue loop4; } buf.putString(signature); session.write(packet); loop2: while (true) { buf = session.read(buf); command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_SUCCESS) { if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, pkmethodsuccess + " auth success"); } return true; } else if (command == SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = Util.byte2str(_message); if (userinfo != null) { userinfo.showMessage(message); } continue loop2; } else if (command == SSH_MSG_USERAUTH_FAILURE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo = buf.getString(); int partial_success = buf.getByte(); // System.err.println(new String(foo)+ // " partial_success:"+(partial_success!=0)); if (partial_success != 0) { throw new JSchPartialAuthException(Util.byte2str(foo)); } session.auth_failures++; if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, pkmethodsuccess + " auth failure"); } if (session.auth_failures >= session.max_auth_tries) { return false; } else if (try_other_pkmethods) { break loop2; } else { continue iloop; } } // System.err.println("USERAUTH fail ("+command+")"); // throw new JSchException("USERAUTH fail ("+command+")"); if (session.getLogger().isEnabled(Logger.DEBUG)) { session.getLogger().log(Logger.DEBUG, pkmethodsuccess + " auth failure command (" + command + ")"); } break loop2; } } } } return false; } private void decryptKey(Session session, Identity identity) throws JSchException { byte[] passphrase = null; int count = 5; while (true) { if ((identity.isEncrypted() && passphrase == null)) { if (userinfo == null) throw new JSchException("USERAUTH fail"); if (identity.isEncrypted() && !userinfo.promptPassphrase("Passphrase for " + identity.getName())) { throw new JSchAuthCancelException("publickey"); // throw new JSchException("USERAUTH cancel"); // break; } String _passphrase = userinfo.getPassphrase(); if (_passphrase != null) { passphrase = Util.str2byte(_passphrase); } } if (!identity.isEncrypted() || passphrase != null) { if (identity.setPassphrase(passphrase)) { if (passphrase != null && (session.getIdentityRepository() instanceof IdentityRepositoryWrapper)) { ((IdentityRepositoryWrapper) session.getIdentityRepository()).check(); } break; } } Util.bzero(passphrase); passphrase = null; count--; if (count == 0) break; } Util.bzero(passphrase); passphrase = null; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/UserInfo.java000066400000000000000000000033451465436372100245210ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface UserInfo { String getPassphrase(); String getPassword(); boolean promptPassword(String message); boolean promptPassphrase(String message); boolean promptYesNo(String message); void showMessage(String message); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/Util.java000066400000000000000000000346641465436372100237140ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Vector; class Util { private static final byte[] b64 = Util.str2byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="); private static byte val(byte foo) { if (foo == '=') return 0; for (int j = 0; j < b64.length; j++) { if (foo == b64[j]) return (byte) j; } return 0; } static byte[] fromBase64(byte[] buf, int start, int length) throws JSchException { try { byte[] foo = new byte[length]; int j = 0; for (int i = start; i < start + length; i += 4) { foo[j] = (byte) ((val(buf[i]) << 2) | ((val(buf[i + 1]) & 0x30) >>> 4)); if (buf[i + 2] == (byte) '=') { j++; break; } foo[j + 1] = (byte) (((val(buf[i + 1]) & 0x0f) << 4) | ((val(buf[i + 2]) & 0x3c) >>> 2)); if (buf[i + 3] == (byte) '=') { j += 2; break; } foo[j + 2] = (byte) (((val(buf[i + 2]) & 0x03) << 6) | (val(buf[i + 3]) & 0x3f)); j += 3; } byte[] bar = new byte[j]; System.arraycopy(foo, 0, bar, 0, j); return bar; } catch (ArrayIndexOutOfBoundsException e) { throw new JSchException("fromBase64: invalid base64 data", e); } } static byte[] toBase64(byte[] buf, int start, int length, boolean include_pad) { byte[] tmp = new byte[length * 2]; int i, j, k; int foo = (length / 3) * 3 + start; i = 0; for (j = start; j < foo; j += 3) { k = (buf[j] >>> 2) & 0x3f; tmp[i++] = b64[k]; k = (buf[j] & 0x03) << 4 | (buf[j + 1] >>> 4) & 0x0f; tmp[i++] = b64[k]; k = (buf[j + 1] & 0x0f) << 2 | (buf[j + 2] >>> 6) & 0x03; tmp[i++] = b64[k]; k = buf[j + 2] & 0x3f; tmp[i++] = b64[k]; } foo = (start + length) - foo; if (foo == 1) { k = (buf[j] >>> 2) & 0x3f; tmp[i++] = b64[k]; k = ((buf[j] & 0x03) << 4) & 0x3f; tmp[i++] = b64[k]; if (include_pad) { tmp[i++] = (byte) '='; tmp[i++] = (byte) '='; } } else if (foo == 2) { k = (buf[j] >>> 2) & 0x3f; tmp[i++] = b64[k]; k = (buf[j] & 0x03) << 4 | (buf[j + 1] >>> 4) & 0x0f; tmp[i++] = b64[k]; k = ((buf[j + 1] & 0x0f) << 2) & 0x3f; tmp[i++] = b64[k]; if (include_pad) { tmp[i++] = (byte) '='; } } byte[] bar = new byte[i]; System.arraycopy(tmp, 0, bar, 0, i); return bar; // return sun.misc.BASE64Encoder().encode(buf); } static String[] split(String foo, String split) { if (foo == null) return null; byte[] buf = Util.str2byte(foo); Vector bar = new Vector<>(); int start = 0; int index; while (true) { index = foo.indexOf(split, start); if (index >= 0) { bar.addElement(Util.byte2str(buf, start, index - start)); start = index + 1; continue; } bar.addElement(Util.byte2str(buf, start, buf.length - start)); break; } String[] result = new String[bar.size()]; for (int i = 0; i < result.length; i++) { result[i] = bar.elementAt(i); } return result; } static boolean glob(byte[] pattern, byte[] name) { return glob0(pattern, 0, name, 0); } private static boolean glob0(byte[] pattern, int pattern_index, byte[] name, int name_index) { if (name.length > 0 && name[0] == '.') { if (pattern.length > 0 && pattern[0] == '.') { if (pattern.length == 2 && pattern[1] == '*') return true; return glob(pattern, pattern_index + 1, name, name_index + 1); } return false; } return glob(pattern, pattern_index, name, name_index); } private static boolean glob(byte[] pattern, int pattern_index, byte[] name, int name_index) { // System.err.println("glob: "+new String(pattern)+", "+pattern_index+" "+new String(name)+", // "+name_index); int patternlen = pattern.length; if (patternlen == 0) return false; int namelen = name.length; int i = pattern_index; int j = name_index; while (i < patternlen && j < namelen) { if (pattern[i] == '\\') { if (i + 1 == patternlen) return false; i++; if (pattern[i] != name[j]) return false; i += skipUTF8Char(pattern[i]); j += skipUTF8Char(name[j]); continue; } if (pattern[i] == '*') { while (i < patternlen) { if (pattern[i] == '*') { i++; continue; } break; } if (patternlen == i) return true; byte foo = pattern[i]; if (foo == '?') { while (j < namelen) { if (glob(pattern, i, name, j)) { return true; } j += skipUTF8Char(name[j]); } return false; } else if (foo == '\\') { if (i + 1 == patternlen) return false; i++; foo = pattern[i]; while (j < namelen) { if (foo == name[j]) { if (glob(pattern, i + skipUTF8Char(foo), name, j + skipUTF8Char(name[j]))) { return true; } } j += skipUTF8Char(name[j]); } return false; } while (j < namelen) { if (foo == name[j]) { if (glob(pattern, i, name, j)) { return true; } } j += skipUTF8Char(name[j]); } return false; } if (pattern[i] == '?') { i++; j += skipUTF8Char(name[j]); continue; } if (pattern[i] != name[j]) return false; i += skipUTF8Char(pattern[i]); j += skipUTF8Char(name[j]); if (!(j < namelen)) { // name is end if (!(i < patternlen)) { // pattern is end return true; } if (pattern[i] == '*') { break; } } continue; } if (i == patternlen && j == namelen) return true; if (!(j < namelen) && // name is end pattern[i] == '*') { boolean ok = true; while (i < patternlen) { if (pattern[i++] != '*') { ok = false; break; } } return ok; } return false; } static String quote(String path) { byte[] _path = str2byte(path); int count = 0; for (int i = 0; i < _path.length; i++) { byte b = _path[i]; if (b == '\\' || b == '?' || b == '*') count++; } if (count == 0) return path; byte[] _path2 = new byte[_path.length + count]; for (int i = 0, j = 0; i < _path.length; i++) { byte b = _path[i]; if (b == '\\' || b == '?' || b == '*') { _path2[j++] = '\\'; } _path2[j++] = b; } return byte2str(_path2); } static String unquote(String path) { byte[] foo = str2byte(path); byte[] bar = unquote(foo); if (foo.length == bar.length) return path; return byte2str(bar); } static byte[] unquote(byte[] path) { int pathlen = path.length; int i = 0; while (i < pathlen) { if (path[i] == '\\') { if (i + 1 == pathlen) break; System.arraycopy(path, i + 1, path, i, path.length - (i + 1)); pathlen--; i++; continue; } i++; } if (pathlen == path.length) return path; byte[] foo = new byte[pathlen]; System.arraycopy(path, 0, foo, 0, pathlen); return foo; } private static String[] chars = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; static String getFingerPrint(HASH hash, byte[] data, boolean include_prefix, boolean force_hex) { try { hash.init(); hash.update(data, 0, data.length); byte[] foo = hash.digest(); StringBuilder sb = new StringBuilder(); if (include_prefix) { sb.append(hash.name()); sb.append(":"); } if (force_hex || hash.name().equals("MD5")) { int bar; for (int i = 0; i < foo.length; i++) { bar = foo[i] & 0xff; sb.append(chars[(bar >>> 4) & 0xf]); sb.append(chars[(bar) & 0xf]); if (i + 1 < foo.length) sb.append(":"); } } else { byte[] b64str = toBase64(foo, 0, foo.length, false); sb.append(byte2str(b64str, 0, b64str.length)); } return sb.toString(); } catch (Exception e) { return "???"; } } static boolean array_equals(byte[] foo, byte bar[]) { int i = foo.length; if (i != bar.length) return false; for (int j = 0; j < i; j++) { if (foo[j] != bar[j]) return false; } // try{while(true){i--; if(foo[i]!=bar[i])return false;}}catch(Exception e){} return true; } static Socket createSocket(String host, int port, int timeout) throws JSchException { Socket socket = new Socket(); try { socket.connect(new InetSocketAddress(host, port), timeout); return socket; } catch (Exception e) { try { socket.close(); } catch (Exception ignore) { } String message = e instanceof SocketTimeoutException ? "timeout: socket is not established" : e.toString(); throw new JSchException(message, e); } } static byte[] str2byte(String str, Charset encoding) { if (str == null) return null; return str.getBytes(encoding); } static byte[] str2byte(String str) { return str2byte(str, StandardCharsets.UTF_8); } static String byte2str(byte[] str, Charset encoding) { return byte2str(str, 0, str.length, encoding); } static String byte2str(byte[] str, int s, int l, Charset encoding) { return new String(str, s, l, encoding); } static String byte2str(byte[] str) { return byte2str(str, 0, str.length, StandardCharsets.UTF_8); } static String byte2str(byte[] str, int s, int l) { return byte2str(str, s, l, StandardCharsets.UTF_8); } static String toHex(byte[] str) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < str.length; i++) { String foo = Integer.toHexString(str[i] & 0xff); sb.append("0x" + (foo.length() == 1 ? "0" : "") + foo); if (i + 1 < str.length) sb.append(":"); } return sb.toString(); } static final byte[] empty = str2byte(""); /* * static byte[] char2byte(char[] foo){ int len=0; for(int i=0; i>>8); bar[j++]=(byte)foo[i]; } } return bar; } */ static void bzero(byte[] foo) { if (foo == null) return; for (int i = 0; i < foo.length; i++) foo[i] = 0; } static String diffString(String str, String[] not_available) { String[] stra = Util.split(str, ","); String result = null; loop: for (int i = 0; i < stra.length; i++) { for (int j = 0; j < not_available.length; j++) { if (stra[i].equals(not_available[j])) { continue loop; } } if (result == null) { result = stra[i]; } else { result = result + "," + stra[i]; } } return result; } static String checkTilde(String str) { try { if (str.startsWith("~")) { str = str.replace("~", System.getProperty("user.home")); } } catch (SecurityException e) { } return str; } private static int skipUTF8Char(byte b) { if ((byte) (b & 0x80) == 0) return 1; if ((byte) (b & 0xe0) == (byte) 0xc0) return 2; if ((byte) (b & 0xf0) == (byte) 0xe0) return 3; return 1; } static byte[] fromFile(String _file) throws IOException { _file = checkTilde(_file); File file = new File(_file); try (InputStream fis = new FileInputStream(_file)) { byte[] result = new byte[(int) (file.length())]; int len = 0; while (true) { int i = fis.read(result, len, result.length - len); if (i <= 0) break; len += i; } return result; } } static boolean arraysequals(byte[] a, byte[] b) { if (a.length != b.length) return false; int res = 0; for (int i = 0; i < a.length; i++) { res |= a[i] ^ b[i]; } return res == 0; } static String getSystemEnv(String name) { try { return System.getenv(name); } catch (SecurityException e) { return null; } } static String getSystemProperty(String key) { try { return System.getProperty(key); } catch (SecurityException e) { return null; } } static String getSystemProperty(String key, String def) { try { return System.getProperty(key, def); } catch (SecurityException e) { return def; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/XDH.java000066400000000000000000000033021465436372100234030ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; public interface XDH { void init(String name, int keylen) throws Exception; byte[] getSecret(byte[] u) throws Exception; byte[] getQ() throws Exception; boolean validate(byte[] u) throws Exception; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/annotations/000077500000000000000000000000001465436372100244545ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/annotations/SuppressForbiddenApi.java000066400000000000000000000006741465436372100314210ustar00rootroot00000000000000package com.jcraft.jsch.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.CLASS) @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) public @interface SuppressForbiddenApi { String[] value(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/000077500000000000000000000000001465436372100225035ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Argon2.java000066400000000000000000000063151465436372100245030ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.JSchException; import org.bouncycastle.crypto.generators.Argon2BytesGenerator; import org.bouncycastle.crypto.params.Argon2Parameters; public class Argon2 implements com.jcraft.jsch.Argon2 { private Argon2BytesGenerator generator; @Override public void init(byte[] salt, int iteration, int type, byte[] additional, byte[] secret, int memory, int parallelism, int version) throws Exception { switch (type) { case com.jcraft.jsch.Argon2.ARGON2D: type = Argon2Parameters.ARGON2_d; break; case com.jcraft.jsch.Argon2.ARGON2I: type = Argon2Parameters.ARGON2_i; break; case com.jcraft.jsch.Argon2.ARGON2ID: type = Argon2Parameters.ARGON2_id; break; default: throw new JSchException("Invalid argon2 type."); } switch (version) { case com.jcraft.jsch.Argon2.V10: version = Argon2Parameters.ARGON2_VERSION_10; break; case com.jcraft.jsch.Argon2.V13: version = Argon2Parameters.ARGON2_VERSION_13; break; default: throw new JSchException("Invalid argon2 version."); } try { Argon2Parameters params = new Argon2Parameters.Builder(type).withSalt(salt) .withAdditional(additional).withSecret(secret).withIterations(iteration) .withMemoryAsKB(memory).withParallelism(parallelism).withVersion(version).build(); generator = new Argon2BytesGenerator(); generator.init(params); } catch (NoClassDefFoundError e) { throw new JSchException("argon2 unavailable", e); } } @Override public byte[] getKey(byte[] pass, int size) { byte[] key = new byte[size]; generator.generateBytes(pass, key); return key; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/CAST128CBC.java000066400000000000000000000060341465436372100246460ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Cipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.engines.CAST5Engine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class CAST128CBC implements Cipher { private static final int ivsize = 8; private static final int bsize = 16; private BufferedBlockCipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { ParametersWithIV keyspec = new ParametersWithIV(new KeyParameter(key, 0, key.length), iv, 0, iv.length); cipher = new DefaultBufferedBlockCipher(CBCBlockCipher.newInstance(new CAST5Engine())); cipher.init(mode == ENCRYPT_MODE, keyspec); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.processBytes(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/CAST128CTR.java000066400000000000000000000056741465436372100247200ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Cipher; import org.bouncycastle.crypto.engines.CAST5Engine; import org.bouncycastle.crypto.modes.CTRModeCipher; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class CAST128CTR implements Cipher { private static final int ivsize = 8; private static final int bsize = 16; private CTRModeCipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { ParametersWithIV keyspec = new ParametersWithIV(new KeyParameter(key, 0, key.length), iv, 0, iv.length); cipher = SICBlockCipher.newInstance(new CAST5Engine()); cipher.init(mode == ENCRYPT_MODE, keyspec); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.processBytes(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/ChaCha20Poly1305.java000066400000000000000000000122551465436372100260010ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Cipher; import java.nio.ByteBuffer; import javax.crypto.AEADBadTagException; import org.bouncycastle.crypto.engines.ChaChaEngine; import org.bouncycastle.crypto.macs.Poly1305; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class ChaCha20Poly1305 implements Cipher { // Actually the block size, not IV size private static final int ivsize = 8; // Actually the key size, not block size private static final int bsize = 64; private static final int tagsize = 16; private ChaChaEngine header_cipher; private ChaChaEngine main_cipher; private KeyParameter K_1_spec; private KeyParameter K_2_spec; private int mode; private Poly1305 poly1305; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public int getTagSize() { return tagsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } byte[] K_1 = new byte[bsize / 2]; byte[] K_2 = new byte[bsize / 2]; System.arraycopy(key, bsize / 2, K_1, 0, bsize / 2); System.arraycopy(key, 0, K_2, 0, bsize / 2); this.mode = mode; try { K_1_spec = new KeyParameter(K_1, 0, K_1.length); K_2_spec = new KeyParameter(K_2, 0, K_2.length); header_cipher = new ChaChaEngine(); main_cipher = new ChaChaEngine(); poly1305 = new Poly1305(); } catch (Exception e) { header_cipher = null; main_cipher = null; K_1_spec = null; K_2_spec = null; throw e; } } @Override public void update(int foo) throws Exception { ByteBuffer nonce = ByteBuffer.allocate(8); nonce.putLong(0, foo); header_cipher.init(this.mode == ENCRYPT_MODE, new ParametersWithIV(K_1_spec, nonce.array(), 0, nonce.array().length)); main_cipher.init(this.mode == ENCRYPT_MODE, new ParametersWithIV(K_2_spec, nonce.array(), 0, nonce.array().length)); // Trying to reinit the cipher again with same nonce results in InvalidKeyException // So just read entire first 64-byte block, which should increment global counter from 0->1 byte[] poly_key = new byte[64]; main_cipher.processBytes(poly_key, 0, poly_key.length, poly_key, 0); poly1305.init(new KeyParameter(poly_key, 0, 32)); } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { header_cipher.processBytes(foo, s1, len, bar, s2); } @Override public void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { if (this.mode == DECRYPT_MODE) { byte[] actual_tag = new byte[tagsize]; System.arraycopy(foo, len, actual_tag, 0, tagsize); byte[] expected_tag = new byte[tagsize]; poly1305.update(foo, s1, len); poly1305.doFinal(expected_tag, 0); if (!arraysequals(actual_tag, expected_tag)) { throw new AEADBadTagException("Tag mismatch"); } } main_cipher.processBytes(foo, s1 + 4, len - 4, bar, s2 + 4); if (this.mode == ENCRYPT_MODE) { poly1305.update(bar, s2, len); poly1305.doFinal(bar, len); } } @Override public boolean isCBC() { return false; } @Override public boolean isAEAD() { return true; } @Override public boolean isChaCha20() { return true; } private static boolean arraysequals(byte[] a, byte[] b) { if (a.length != b.length) return false; int res = 0; for (int i = 0; i < a.length; i++) { res |= a[i] ^ b[i]; } return res == 0; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/HMAC.java000066400000000000000000000053131465436372100240600ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.MAC; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; abstract class HMAC implements MAC { protected String name; protected int bsize; protected Digest digest; protected boolean etm; private HMac mac; @Override public int getBlockSize() { return bsize; }; @Override public void init(byte[] key) throws Exception { if (key.length > bsize) { byte[] tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, bsize); key = tmp; } KeyParameter skey = new KeyParameter(key, 0, key.length); mac = new HMac(digest); mac.init(skey); } private final byte[] tmp = new byte[4]; @Override public void update(int i) { tmp[0] = (byte) (i >>> 24); tmp[1] = (byte) (i >>> 16); tmp[2] = (byte) (i >>> 8); tmp[3] = (byte) i; update(tmp, 0, 4); } @Override public void update(byte foo[], int s, int l) { mac.update(foo, s, l); } @Override public void doFinal(byte[] buf, int offset) { mac.doFinal(buf, offset); } @Override public String getName() { return name; } @Override public boolean isEtM() { return etm; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/HMACRIPEMD160.java000066400000000000000000000033071465436372100252110ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import org.bouncycastle.crypto.digests.RIPEMD160Digest; public class HMACRIPEMD160 extends HMAC { public HMACRIPEMD160() { name = "hmac-ripemd160"; bsize = 20; digest = new RIPEMD160Digest(); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/HMACRIPEMD160ETM.java000066400000000000000000000032111465436372100255510ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class HMACRIPEMD160ETM extends HMACRIPEMD160 { public HMACRIPEMD160ETM() { name = "hmac-ripemd160-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/HMACRIPEMD160OpenSSH.java000066400000000000000000000031751465436372100264140ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class HMACRIPEMD160OpenSSH extends HMACRIPEMD160 { public HMACRIPEMD160OpenSSH() { name = "hmac-ripemd160@openssh.com"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/KeyPairGenEdDSA.java000066400000000000000000000065061465436372100261540ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters; public class KeyPairGenEdDSA implements com.jcraft.jsch.KeyPairGenEdDSA { byte[] prv; // private byte[] pub; // public int keylen; String name; @Override public void init(String name, int keylen) throws Exception { if (!name.equals("Ed25519") && !name.equals("Ed448")) { throw new NoSuchAlgorithmException("invalid curve " + name); } this.keylen = keylen; this.name = name; if (name.equals("Ed25519")) { Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(new SecureRandom()); pub = privateKey.generatePublicKey().getEncoded(); prv = privateKey.getEncoded(); } else { Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters(new SecureRandom()); pub = privateKey.generatePublicKey().getEncoded(); prv = privateKey.getEncoded(); } } @Override public byte[] getPrv() { return prv; } @Override public byte[] getPub() { return pub; } @Override public void init(String name, byte[] prv) throws Exception { if (!name.equals("Ed25519") && !name.equals("Ed448")) { throw new NoSuchAlgorithmException("invalid curve " + name); } this.name = name; if (name.equals("Ed25519")) { Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(prv); pub = privateKey.generatePublicKey().getEncoded(); this.prv = privateKey.getEncoded(); } else { Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters(prv); pub = privateKey.generatePublicKey().getEncoded(); this.prv = privateKey.getEncoded(); } this.keylen = this.prv.length; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/SCrypt.java000066400000000000000000000044131465436372100245740ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.JSchException; public class SCrypt implements com.jcraft.jsch.SCrypt { private Class ignore; private byte[] salt; private int cost; private int blocksize; private int parallel; @Override public void init(byte[] salt, int cost, int blocksize, int parallel) throws Exception { try { ignore = org.bouncycastle.crypto.generators.SCrypt.class; this.salt = salt; this.cost = cost; this.blocksize = blocksize; this.parallel = parallel; } catch (NoClassDefFoundError e) { throw new JSchException("scrypt unavailable", e); } } @Override public byte[] getKey(byte[] pass, int size) { return org.bouncycastle.crypto.generators.SCrypt.generate(pass, salt, cost, blocksize, parallel, size); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/SEEDCBC.java000066400000000000000000000060301465436372100243750ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Cipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.engines.SEEDEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; public class SEEDCBC implements Cipher { private static final int ivsize = 16; private static final int bsize = 16; private BufferedBlockCipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { ParametersWithIV keyspec = new ParametersWithIV(new KeyParameter(key, 0, key.length), iv, 0, iv.length); cipher = new DefaultBufferedBlockCipher(CBCBlockCipher.newInstance(new SEEDEngine())); cipher.init(mode == ENCRYPT_MODE, keyspec); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.processBytes(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/SNTRUP761.java000066400000000000000000000072141465436372100246430ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.KEM; import com.jcraft.jsch.annotations.SuppressForbiddenApi; import java.lang.reflect.Constructor; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMExtractor; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKeyGenerationParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKeyPairGenerator; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePublicKeyParameters; public class SNTRUP761 implements KEM { SNTRUPrimeKEMExtractor extractor; SNTRUPrimePublicKeyParameters publicKey; @Override public void init() throws Exception { SNTRUPrimeKeyPairGenerator kpg = new SNTRUPrimeKeyPairGenerator(); kpg.init(new SNTRUPrimeKeyGenerationParameters(new SecureRandom(), sntrup761())); AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); extractor = new SNTRUPrimeKEMExtractor((SNTRUPrimePrivateKeyParameters) kp.getPrivate()); publicKey = (SNTRUPrimePublicKeyParameters) kp.getPublic(); } @Override public byte[] getPublicKey() throws Exception { return publicKey.getEncoded(); } @Override public byte[] decapsulate(byte[] encapsulation) throws Exception { return extractor.extractSecret(encapsulation); } // Bouncy Castle before 1.78 defines sharedKeyBytes differently than OpenSSH (16 instead of 32) // https://github.com/bcgit/bc-java/issues/1554 // https://github.com/bcgit/bc-java/commit/db3ae60 @SuppressForbiddenApi("jdk-reflection") static SNTRUPrimeParameters sntrup761() throws Exception { if (SNTRUPrimeParameters.sntrup761.getSessionKeySize() == 32 * 8) { return SNTRUPrimeParameters.sntrup761; } Constructor c = SNTRUPrimeParameters.class.getDeclaredConstructor(String.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class); c.setAccessible(true); return c.newInstance("sntrup761", 761, 4591, 286, 1158, 1007, 1158, 1763, 32); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/SignatureEd25519.java000066400000000000000000000033321465436372100261670ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class SignatureEd25519 extends SignatureEdDSA { @Override String getName() { return "ssh-ed25519"; } @Override String getAlgo() { return "Ed25519"; } @Override int getKeylen() { return 32; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/SignatureEd448.java000066400000000000000000000033241465436372100260220ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class SignatureEd448 extends SignatureEdDSA { @Override String getName() { return "ssh-ed448"; } @Override String getAlgo() { return "Ed448"; } @Override int getKeylen() { return 57; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/SignatureEdDSA.java000066400000000000000000000106451465436372100261160ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Buffer; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed448PublicKeyParameters; import org.bouncycastle.crypto.signers.Ed25519Signer; import org.bouncycastle.crypto.signers.Ed448Signer; abstract class SignatureEdDSA implements com.jcraft.jsch.SignatureEdDSA { Signer signature; abstract String getName(); abstract String getAlgo(); abstract int getKeylen(); @Override public void init() throws Exception { if (!getAlgo().equals("Ed25519") && !getAlgo().equals("Ed448")) { throw new NoSuchAlgorithmException("invalid curve " + getAlgo()); } if (getAlgo().equals("Ed25519")) { signature = new Ed25519Signer(); } else { signature = new Ed448Signer(new byte[0]); } } @Override public void setPubKey(byte[] y_arr) throws Exception { try { if (getAlgo().equals("Ed25519")) { Ed25519PublicKeyParameters pubKey = new Ed25519PublicKeyParameters(y_arr, 0); signature.init(false, pubKey); } else { Ed448PublicKeyParameters pubKey = new Ed448PublicKeyParameters(y_arr, 0); signature.init(false, pubKey); } } catch (Exception e) { throw new InvalidKeyException(e); } } @Override public void setPrvKey(byte[] bytes) throws Exception { try { if (getAlgo().equals("Ed25519")) { Ed25519PrivateKeyParameters prvKey = new Ed25519PrivateKeyParameters(bytes, 0); signature.init(true, prvKey); } else { Ed448PrivateKeyParameters prvKey = new Ed448PrivateKeyParameters(bytes, 0); signature.init(true, prvKey); } } catch (Exception e) { throw new InvalidKeyException(e); } } @Override public byte[] sign() throws Exception { try { return signature.generateSignature(); } catch (Exception e) { throw new SignatureException(e); } } @Override public void update(byte[] foo) throws Exception { try { signature.update(foo, 0, foo.length); } catch (Exception e) { throw new SignatureException(e); } } @Override public boolean verify(byte[] sig) throws Exception { int i = 0; int j = 0; byte[] tmp; Buffer buf = new Buffer(sig); String foo = new String(buf.getString(), StandardCharsets.UTF_8); if (foo.equals(getName())) { j = buf.getInt(); i = buf.getOffSet(); tmp = new byte[j]; System.arraycopy(sig, i, tmp, 0, j); sig = tmp; } try { return signature.verifySignature(sig); } catch (Exception e) { throw new SignatureException(e); } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Twofish128CBC.java000066400000000000000000000032141465436372100255340ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class Twofish128CBC extends TwofishCBC { private static final int bsize = 16; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Twofish128CTR.java000066400000000000000000000032141465436372100255750ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class Twofish128CTR extends TwofishCTR { private static final int bsize = 16; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Twofish192CBC.java000066400000000000000000000032141465436372100255350ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class Twofish192CBC extends TwofishCBC { private static final int bsize = 24; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Twofish192CTR.java000066400000000000000000000032141465436372100255760ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class Twofish192CTR extends TwofishCTR { private static final int bsize = 24; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Twofish256CBC.java000066400000000000000000000032141465436372100255360ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class Twofish256CBC extends TwofishCBC { private static final int bsize = 32; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/Twofish256CTR.java000066400000000000000000000032141465436372100255770ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; public class Twofish256CTR extends TwofishCTR { private static final int bsize = 32; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/TwofishCBC.java000066400000000000000000000057331465436372100253110ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Cipher; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.DefaultBufferedBlockCipher; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; abstract class TwofishCBC implements Cipher { private static final int ivsize = 16; private BufferedBlockCipher cipher; @Override public int getIVSize() { return ivsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } int bsize = getBlockSize(); if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { ParametersWithIV keyspec = new ParametersWithIV(new KeyParameter(key, 0, key.length), iv, 0, iv.length); cipher = new DefaultBufferedBlockCipher(CBCBlockCipher.newInstance(new TwofishEngine())); cipher.init(mode == ENCRYPT_MODE, keyspec); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.processBytes(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/TwofishCTR.java000066400000000000000000000055731465436372100253540ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import com.jcraft.jsch.Cipher; import org.bouncycastle.crypto.engines.TwofishEngine; import org.bouncycastle.crypto.modes.CTRModeCipher; import org.bouncycastle.crypto.modes.SICBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; abstract class TwofishCTR implements Cipher { private static final int ivsize = 16; private CTRModeCipher cipher; @Override public int getIVSize() { return ivsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } int bsize = getBlockSize(); if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { ParametersWithIV keyspec = new ParametersWithIV(new KeyParameter(key, 0, key.length), iv, 0, iv.length); cipher = SICBlockCipher.newInstance(new TwofishEngine()); cipher.init(mode == ENCRYPT_MODE, keyspec); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.processBytes(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/bc/XDH.java000066400000000000000000000105371465436372100237770ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.bc; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import org.bouncycastle.crypto.params.X25519PrivateKeyParameters; import org.bouncycastle.crypto.params.X25519PublicKeyParameters; import org.bouncycastle.crypto.params.X448PrivateKeyParameters; import org.bouncycastle.crypto.params.X448PublicKeyParameters; public class XDH implements com.jcraft.jsch.XDH { byte[] Q_array; Object privateKey; int keylen; String name; @Override public void init(String name, int keylen) throws Exception { if (!name.equals("X25519") && !name.equals("X448")) { throw new NoSuchAlgorithmException("invalid curve " + name); } this.keylen = keylen; this.name = name; if (name.equals("X25519")) { X25519PrivateKeyParameters privateKey = new X25519PrivateKeyParameters(new SecureRandom()); Q_array = privateKey.generatePublicKey().getEncoded(); this.privateKey = privateKey; } else { X448PrivateKeyParameters privateKey = new X448PrivateKeyParameters(new SecureRandom()); Q_array = privateKey.generatePublicKey().getEncoded(); this.privateKey = privateKey; } } @Override public byte[] getQ() throws Exception { return Q_array; } @Override public byte[] getSecret(byte[] Q) throws Exception { byte[] secret = new byte[keylen]; if (name.equals("X25519")) { X25519PublicKeyParameters publicKey = null; try { publicKey = new X25519PublicKeyParameters(Q, 0); } catch (Exception e) { throw new InvalidKeyException(e); } X25519PrivateKeyParameters privateKey = (X25519PrivateKeyParameters) this.privateKey; try { privateKey.generateSecret(publicKey, secret, 0); } catch (Exception e) { throw new IllegalStateException(e); } } else { X448PublicKeyParameters publicKey = null; try { publicKey = new X448PublicKeyParameters(Q, 0); } catch (Exception e) { throw new InvalidKeyException(e); } X448PrivateKeyParameters privateKey = (X448PrivateKeyParameters) this.privateKey; try { privateKey.generateSecret(publicKey, secret, 0); } catch (Exception e) { throw new IllegalStateException(e); } } return secret; } // https://cr.yp.to/ecdh.html#validate // RFC 8731, // 3. Key Exchange Methods // Clients and servers MUST // also abort if the length of the received public keys are not the // expected lengths. An abort for these purposes is defined as a // disconnect (SSH_MSG_DISCONNECT) of the session and SHOULD use the // SSH_DISCONNECT_KEY_EXCHANGE_FAILED reason for the message // [IANA-REASON]. No further validation is required beyond what is // described in [RFC7748]. @Override public boolean validate(byte[] u) throws Exception { return u.length == keylen; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jbcrypt/000077500000000000000000000000001465436372100235745ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jbcrypt/BCrypt.java000066400000000000000000000755321465436372100256560ustar00rootroot00000000000000// Copyright (c) 2006 Damien Miller // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package com.jcraft.jsch.jbcrypt; import java.nio.charset.StandardCharsets; import java.security.DigestException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; /** * BCrypt implements OpenBSD-style Blowfish password hashing using the scheme described in "A * Future-Adaptable Password Scheme" by Niels Provos and David Mazieres. * *

* This password hashing system tries to thwart off-line password cracking using a * computationally-intensive hashing algorithm, based on Bruce Schneier's Blowfish cipher. The work * factor of the algorithm is parameterised, so it can be increased as computers get faster. * *

* Usage is really simple. To hash a password for the first time, call the hashpw method with a * random salt, like this: * *

* * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
*
* *

* To check whether a plaintext password matches one that has been hashed previously, use the * checkpw method: * *

* * if (BCrypt.checkpw(candidate_password, stored_hash))
*     System.out.println("It matches");
* else
*     System.out.println("It does not match");
*
* *

* The gensalt() method takes an optional parameter (log_rounds) that determines the computational * complexity of the hashing: * *

* * String strong_salt = BCrypt.gensalt(10)
* String stronger_salt = BCrypt.gensalt(12)
*
* *

* The amount of work increases exponentially (2**log_rounds), so each increment is twice as much * work. The default log_rounds is 10, and the valid range is 4 to 30. * * @author Damien Miller * @version 0.2 */ public class BCrypt { // BCrypt parameters private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; private static final int BCRYPT_SALT_LEN = 16; // Blowfish parameters private static final int BLOWFISH_NUM_ROUNDS = 16; // Initial contents of key schedule private static final int P_orig[] = {0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b}; private static final int S_orig[] = {0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}; // OpenBSD IV: "OxychromaticBlowfishSwatDynamite" in big endian private static final int[] openbsd_iv = new int[] {0x4f787963, 0x68726f6d, 0x61746963, 0x426c6f77, 0x66697368, 0x53776174, 0x44796e61, 0x6d697465,}; // bcrypt IV: "OrpheanBeholderScryDoubt". The C implementation calls // this "ciphertext", but it is really plaintext or an IV. We keep // the name to make code comparison easier. private static final int bf_crypt_ciphertext[] = {0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274}; // Table for Base64 encoding private static final char base64_code[] = {'.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; // Table for Base64 decoding private static final byte index_64[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1}; // Expanded Blowfish key private int P[]; private int S[]; /** * Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note that this is * *not* compatible with the standard MIME-base64 encoding. * * @param d the byte array to encode * @param len the number of bytes to encode * @return base64-encoded string * @exception IllegalArgumentException if the length is invalid */ private static String encode_base64(byte d[], int len) throws IllegalArgumentException { int off = 0; StringBuilder rs = new StringBuilder(); int c1, c2; if (len <= 0 || len > d.length) throw new IllegalArgumentException("Invalid len"); while (off < len) { c1 = d[off++] & 0xff; rs.append(base64_code[(c1 >> 2) & 0x3f]); c1 = (c1 & 0x03) << 4; if (off >= len) { rs.append(base64_code[c1 & 0x3f]); break; } c2 = d[off++] & 0xff; c1 |= (c2 >> 4) & 0x0f; rs.append(base64_code[c1 & 0x3f]); c1 = (c2 & 0x0f) << 2; if (off >= len) { rs.append(base64_code[c1 & 0x3f]); break; } c2 = d[off++] & 0xff; c1 |= (c2 >> 6) & 0x03; rs.append(base64_code[c1 & 0x3f]); rs.append(base64_code[c2 & 0x3f]); } return rs.toString(); } /** * Look up the 3 bits base64-encoded by the specified character, range-checking againt conversion * table * * @param x the base64-encoded value * @return the decoded value of x */ private static byte char64(char x) { if ((int) x < 0 || (int) x > index_64.length) return -1; return index_64[(int) x]; } /** * Decode a string encoded using bcrypt's base64 scheme to a byte array. Note that this is *not* * compatible with the standard MIME-base64 encoding. * * @param s the string to decode * @param maxolen the maximum number of bytes to decode * @return an array containing the decoded bytes * @throws IllegalArgumentException if maxolen is invalid */ private static byte[] decode_base64(String s, int maxolen) throws IllegalArgumentException { StringBuilder rs = new StringBuilder(); int off = 0, slen = s.length(), olen = 0; byte ret[]; byte c1, c2, c3, c4, o; if (maxolen <= 0) throw new IllegalArgumentException("Invalid maxolen"); while (off < slen - 1 && olen < maxolen) { c1 = char64(s.charAt(off++)); c2 = char64(s.charAt(off++)); if (c1 == -1 || c2 == -1) break; o = (byte) (c1 << 2); o |= (byte) ((c2 & 0x30) >> 4); rs.append((char) o); if (++olen >= maxolen || off >= slen) break; c3 = char64(s.charAt(off++)); if (c3 == -1) break; o = (byte) ((c2 & 0x0f) << 4); o |= (byte) ((c3 & 0x3c) >> 2); rs.append((char) o); if (++olen >= maxolen || off >= slen) break; c4 = char64(s.charAt(off++)); o = (byte) ((c3 & 0x03) << 6); o |= c4; rs.append((char) o); ++olen; } ret = new byte[olen]; for (off = 0; off < olen; off++) ret[off] = (byte) rs.charAt(off); return ret; } /** * Blowfish encipher a single 64-bit block encoded as two 32-bit halves * * @param lr an array containing the two 32-bit half blocks * @param off the position in the array of the blocks */ private final void encipher(int lr[], int off) { int i, n, l = lr[off], r = lr[off + 1]; l ^= P[0]; for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { // Feistel substitution on left word n = S[(l >> 24) & 0xff]; n += S[0x100 | ((l >> 16) & 0xff)]; n ^= S[0x200 | ((l >> 8) & 0xff)]; n += S[0x300 | (l & 0xff)]; r ^= n ^ P[++i]; // Feistel substitution on right word n = S[(r >> 24) & 0xff]; n += S[0x100 | ((r >> 16) & 0xff)]; n ^= S[0x200 | ((r >> 8) & 0xff)]; n += S[0x300 | (r & 0xff)]; l ^= n ^ P[++i]; } lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; lr[off + 1] = l; } /** * Cycically extract a word of key material * * @param data the string to extract the data from * @param offp a "pointer" (as a one-entry array) to the current offset into data * @return the next word of material from data */ private static int streamtoword(byte data[], int offp[]) { int i; int word = 0; int off = offp[0]; for (i = 0; i < 4; i++) { word = (word << 8) | (data[off] & 0xff); off = (off + 1) % data.length; } offp[0] = off; return word; } /** Initialise the Blowfish key schedule */ private void init_key() { P = P_orig.clone(); S = S_orig.clone(); } /** * Key the Blowfish cipher * * @param key an array containing the key */ private void key(byte key[]) { int i; int koffp[] = {0}; int lr[] = {0, 0}; int plen = P.length, slen = S.length; for (i = 0; i < plen; i++) P[i] = P[i] ^ streamtoword(key, koffp); for (i = 0; i < plen; i += 2) { encipher(lr, 0); P[i] = lr[0]; P[i + 1] = lr[1]; } for (i = 0; i < slen; i += 2) { encipher(lr, 0); S[i] = lr[0]; S[i + 1] = lr[1]; } } /** * Perform the "enhanced key schedule" step described by Provos and Mazieres in "A * Future-Adaptable Password Scheme" http://www.openbsd.org/papers/bcrypt-paper.ps * * @param data salt information * @param key password information */ private void ekskey(byte data[], byte key[]) { int i; int koffp[] = {0}, doffp[] = {0}; int lr[] = {0, 0}; int plen = P.length, slen = S.length; for (i = 0; i < plen; i++) P[i] = P[i] ^ streamtoword(key, koffp); for (i = 0; i < plen; i += 2) { lr[0] ^= streamtoword(data, doffp); lr[1] ^= streamtoword(data, doffp); encipher(lr, 0); P[i] = lr[0]; P[i + 1] = lr[1]; } for (i = 0; i < slen; i += 2) { lr[0] ^= streamtoword(data, doffp); lr[1] ^= streamtoword(data, doffp); encipher(lr, 0); S[i] = lr[0]; S[i + 1] = lr[1]; } } /** Compatibility with new OpenBSD function. */ public void hash(byte[] hpass, byte[] hsalt, byte[] output) { init_key(); ekskey(hsalt, hpass); for (int i = 0; i < 64; i++) { key(hsalt); key(hpass); } int[] buf = new int[openbsd_iv.length]; System.arraycopy(openbsd_iv, 0, buf, 0, openbsd_iv.length); for (int i = 0; i < 8; i += 2) { for (int j = 0; j < 64; j++) { encipher(buf, i); } } for (int i = 0, j = 0; i < buf.length; i++) { // Output of this is little endian output[j++] = (byte) (buf[i] & 0xff); output[j++] = (byte) ((buf[i] >> 8) & 0xff); output[j++] = (byte) ((buf[i] >> 16) & 0xff); output[j++] = (byte) ((buf[i] >> 24) & 0xff); } } /** Compatibility with new OpenBSD function. */ public void pbkdf(byte[] password, byte[] salt, int rounds, byte[] output) { try { MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); int nblocks = (output.length + 31) / 32; byte[] hpass = sha512.digest(password); byte[] hsalt = new byte[64]; byte[] block_b = new byte[4]; byte[] out = new byte[32]; byte[] tmp = new byte[32]; for (int block = 1; block <= nblocks; block++) { // Block count is in big endian block_b[0] = (byte) ((block >> 24) & 0xFF); block_b[1] = (byte) ((block >> 16) & 0xFF); block_b[2] = (byte) ((block >> 8) & 0xFF); block_b[3] = (byte) (block & 0xFF); sha512.reset(); sha512.update(salt); sha512.update(block_b); sha512.digest(hsalt, 0, hsalt.length); hash(hpass, hsalt, out); System.arraycopy(out, 0, tmp, 0, out.length); for (int round = 1; round < rounds; round++) { sha512.reset(); sha512.update(tmp); sha512.digest(hsalt, 0, hsalt.length); hash(hpass, hsalt, tmp); for (int i = 0; i < tmp.length; i++) { out[i] ^= tmp[i]; } } for (int i = 0; i < out.length; i++) { int idx = i * nblocks + (block - 1); if (idx < output.length) { output[idx] = out[i]; } } } } catch (DigestException e) { throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } /** * Perform the central password hashing step in the bcrypt scheme * * @param password the password to hash * @param salt the binary salt to hash with the password * @param log_rounds the binary logarithm of the number of rounds of hashing to apply * @param cdata the plaintext to encrypt * @return an array containing the binary hashed password */ public byte[] crypt_raw(byte password[], byte salt[], int log_rounds, int cdata[]) { int rounds, i, j; int clen = cdata.length; byte ret[]; if (log_rounds < 4 || log_rounds > 30) throw new IllegalArgumentException("Bad number of rounds"); rounds = 1 << log_rounds; if (salt.length != BCRYPT_SALT_LEN) throw new IllegalArgumentException("Bad salt length"); init_key(); ekskey(salt, password); for (i = 0; i != rounds; i++) { key(password); key(salt); } for (i = 0; i < 64; i++) { for (j = 0; j < (clen >> 1); j++) encipher(cdata, j << 1); } ret = new byte[clen * 4]; for (i = 0, j = 0; i < clen; i++) { ret[j++] = (byte) ((cdata[i] >> 24) & 0xff); ret[j++] = (byte) ((cdata[i] >> 16) & 0xff); ret[j++] = (byte) ((cdata[i] >> 8) & 0xff); ret[j++] = (byte) (cdata[i] & 0xff); } return ret; } /** * Hash a password using the OpenBSD bcrypt scheme * * @param password the password to hash * @param salt the salt to hash with (perhaps generated using BCrypt.gensalt) * @return the hashed password */ public static String hashpw(String password, String salt) { BCrypt B; String real_salt; byte passwordb[], saltb[], hashed[]; char minor = (char) 0; int rounds, off = 0; StringBuilder rs = new StringBuilder(); if (salt.charAt(0) != '$' || salt.charAt(1) != '2') throw new IllegalArgumentException("Invalid salt version"); if (salt.charAt(2) == '$') off = 3; else { minor = salt.charAt(2); if (minor != 'a' || salt.charAt(3) != '$') throw new IllegalArgumentException("Invalid salt revision"); off = 4; } // Extract number of rounds if (salt.charAt(off + 2) > '$') throw new IllegalArgumentException("Missing salt rounds"); rounds = Integer.parseInt(salt.substring(off, off + 2)); real_salt = salt.substring(off + 3, off + 25); passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes(StandardCharsets.UTF_8); saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); B = new BCrypt(); hashed = B.crypt_raw(passwordb, saltb, rounds, bf_crypt_ciphertext.clone()); rs.append("$2"); if (minor >= 'a') rs.append(minor); rs.append("$"); if (rounds < 10) rs.append("0"); if (rounds > 30) { throw new IllegalArgumentException("rounds exceeds maximum (30)"); } rs.append(Integer.toString(rounds)); rs.append("$"); rs.append(encode_base64(saltb, saltb.length)); rs.append(encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1)); return rs.toString(); } /** * Generate a salt for use with the BCrypt.hashpw() method * * @param log_rounds the log2 of the number of rounds of hashing to apply - the work factor * therefore increases as 2**log_rounds. * @param random an instance of SecureRandom to use * @return an encoded salt value */ public static String gensalt(int log_rounds, SecureRandom random) { StringBuilder rs = new StringBuilder(); byte rnd[] = new byte[BCRYPT_SALT_LEN]; random.nextBytes(rnd); rs.append("$2a$"); if (log_rounds < 10) rs.append("0"); if (log_rounds > 30) { throw new IllegalArgumentException("log_rounds exceeds maximum (30)"); } rs.append(Integer.toString(log_rounds)); rs.append("$"); rs.append(encode_base64(rnd, rnd.length)); return rs.toString(); } /** * Generate a salt for use with the BCrypt.hashpw() method * * @param log_rounds the log2 of the number of rounds of hashing to apply - the work factor * therefore increases as 2**log_rounds. * @return an encoded salt value */ public static String gensalt(int log_rounds) { return gensalt(log_rounds, new SecureRandom()); } /** * Generate a salt for use with the BCrypt.hashpw() method, selecting a reasonable default for the * number of hashing rounds to apply * * @return an encoded salt value */ public static String gensalt() { return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); } /** * Check that a plaintext password matches a previously hashed one * * @param plaintext the plaintext password to verify * @param hashed the previously-hashed password * @return true if the passwords match, false otherwise */ public static boolean checkpw(String plaintext, String hashed) { String try_pw = hashpw(plaintext, hashed); byte hashed_bytes[] = hashed.getBytes(StandardCharsets.UTF_8); byte try_bytes[] = try_pw.getBytes(StandardCharsets.UTF_8); if (hashed_bytes.length != try_bytes.length) return false; byte ret = 0; for (int i = 0; i < try_bytes.length; i++) ret |= (byte) (hashed_bytes[i] ^ try_bytes[i]); return ret == 0; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jbcrypt/JBCrypt.java000066400000000000000000000036771465436372100257710ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jbcrypt; public class JBCrypt implements com.jcraft.jsch.BCrypt { private BCrypt bcrypt; private byte[] salt; private int iteration; @Override public void init(byte[] salt, int iteration) throws Exception { bcrypt = new BCrypt(); this.salt = salt; this.iteration = iteration; } @Override public byte[] getKey(byte[] pass, int size) { byte[] key = new byte[size]; bcrypt.pbkdf(pass, salt, iteration, key); return key; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/000077500000000000000000000000001465436372100226605ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES128CBC.java000066400000000000000000000054661465436372100247110ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES128CBC implements com.jcraft.jsch.Cipher { private static final int ivsize = 16; private static final int bsize = 16; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), keyspec, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES128CTR.java000066400000000000000000000054671465436372100247530ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES128CTR implements com.jcraft.jsch.Cipher { private static final int ivsize = 16; private static final int bsize = 16; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/CTR/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), keyspec, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES128GCM.java000066400000000000000000000032601465436372100247160ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class AES128GCM extends AESGCM { // Actually the key size, not block size private static final int bsize = 16; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES192CBC.java000066400000000000000000000054651465436372100247110ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES192CBC implements com.jcraft.jsch.Cipher { private static final int ivsize = 16; private static final int bsize = 24; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), keyspec, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES192CTR.java000066400000000000000000000054661465436372100247530ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES192CTR implements com.jcraft.jsch.Cipher { private static final int ivsize = 16; private static final int bsize = 24; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/CTR/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), keyspec, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES256CBC.java000066400000000000000000000054651465436372100247120ustar00rootroot00000000000000/* * Copyright (c) 2005-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES256CBC implements com.jcraft.jsch.Cipher { private static final int ivsize = 16; private static final int bsize = 32; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), keyspec, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES256CTR.java000066400000000000000000000054661465436372100247540ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES256CTR implements com.jcraft.jsch.Cipher { private static final int ivsize = 16; private static final int bsize = 32; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/CTR/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), keyspec, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AES256GCM.java000066400000000000000000000032601465436372100247200ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class AES256GCM extends AESGCM { // Actually the key size, not block size private static final int bsize = 32; @Override public int getBlockSize() { return bsize; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/AESGCM.java000066400000000000000000000073361465436372100244730ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.nio.ByteBuffer; import javax.crypto.Cipher; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; abstract class AESGCM implements com.jcraft.jsch.Cipher { // Actually the block size, not IV size private static final int ivsize = 16; private static final int tagsize = 16; private Cipher cipher; private SecretKeySpec keyspec; private int mode; private ByteBuffer iv; private long initcounter; @Override public int getIVSize() { return ivsize; } @Override public int getTagSize() { return tagsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > 12) { tmp = new byte[12]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } int bsize = getBlockSize(); if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } this.mode = ((mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE); this.iv = ByteBuffer.wrap(iv); this.initcounter = this.iv.getLong(4); try { keyspec = new SecretKeySpec(key, "AES"); cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(this.mode, keyspec, new GCMParameterSpec(tagsize * 8, iv)); } catch (Exception e) { cipher = null; keyspec = null; this.iv = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public void updateAAD(byte[] foo, int s1, int len) throws Exception { cipher.updateAAD(foo, s1, len); } @Override public void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.doFinal(foo, s1, len, bar, s2); long newcounter = iv.getLong(4) + 1; if (newcounter == initcounter) { throw new IllegalStateException("GCM IV would be reused"); } iv.putLong(4, newcounter); cipher.init(mode, keyspec, new GCMParameterSpec(tagsize * 8, iv.array())); } @Override public boolean isCBC() { return false; } @Override public boolean isAEAD() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java000066400000000000000000000051301465436372100246230ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class ARCFOUR implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 16; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), _key); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java000066400000000000000000000053731465436372100250670ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class ARCFOUR128 implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 16; private static final int skip = 1536; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), _key); byte[] foo = new byte[1]; for (int i = 0; i < skip; i++) { cipher.update(foo, 0, 1, foo, 0); } } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/ARCFOUR256.java000066400000000000000000000053731465436372100250710ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class ARCFOUR256 implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 32; private static final int skip = 1536; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), _key); byte[] foo = new byte[1]; for (int i = 0; i < skip; i++) { cipher.update(foo, 0, 1, foo, 0); } } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/BlowfishCBC.java000066400000000000000000000054551465436372100256210ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class BlowfishCBC implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 16; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec skeySpec = new SecretKeySpec(key, "Blowfish"); cipher = Cipher.getInstance("Blowfish/CBC/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), skeySpec, new IvParameterSpec(iv)); } catch (Exception e) { throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/BlowfishCTR.java000066400000000000000000000054561465436372100256630ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class BlowfishCTR implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 32; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { SecretKeySpec skeySpec = new SecretKeySpec(key, "Blowfish"); cipher = Cipher.getInstance("Blowfish/CTR/NoPadding"); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), skeySpec, new IvParameterSpec(iv)); } catch (Exception e) { throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/DH.java000066400000000000000000000074431465436372100240260ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.JSchException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import javax.crypto.KeyAgreement; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; public class DH implements com.jcraft.jsch.DH { BigInteger p; BigInteger g; BigInteger e; // my public key byte[] e_array; BigInteger f; // your public key private KeyPairGenerator myKpairGen; private KeyAgreement myKeyAgree; @Override public void init() throws Exception { myKpairGen = KeyPairGenerator.getInstance("DH"); myKeyAgree = KeyAgreement.getInstance("DH"); } @Override public byte[] getE() throws Exception { if (e == null) { DHParameterSpec dhSkipParamSpec = new DHParameterSpec(p, g); myKpairGen.initialize(dhSkipParamSpec); KeyPair myKpair = myKpairGen.generateKeyPair(); myKeyAgree.init(myKpair.getPrivate()); e = ((DHPublicKey) (myKpair.getPublic())).getY(); e_array = e.toByteArray(); } return e_array; } @Override public byte[] getK() throws Exception { KeyFactory myKeyFac = KeyFactory.getInstance("DH"); DHPublicKeySpec keySpec = new DHPublicKeySpec(f, p, g); PublicKey yourPubKey = myKeyFac.generatePublic(keySpec); myKeyAgree.doPhase(yourPubKey, true); return myKeyAgree.generateSecret(); } @Override public void setP(byte[] p) { setP(new BigInteger(1, p)); } @Override public void setG(byte[] g) { setG(new BigInteger(1, g)); } @Override public void setF(byte[] f) { setF(new BigInteger(1, f)); } void setP(BigInteger p) { this.p = p; } void setG(BigInteger g) { this.g = g; } void setF(BigInteger f) { this.f = f; } // e, f must be in [1, p-1]. @Override public void checkRange() throws Exception { /* * checkRange(e); checkRange(f); */ } private void checkRange(BigInteger tmp) throws Exception { BigInteger one = BigInteger.ONE; BigInteger p_1 = p.subtract(one); // !(1 bsize) { byte[] tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, bsize); key = tmp; } SecretKeySpec skey = new SecretKeySpec(key, algorithm); mac = Mac.getInstance(algorithm); mac.init(skey); } private final byte[] tmp = new byte[4]; @Override public void update(int i) { tmp[0] = (byte) (i >>> 24); tmp[1] = (byte) (i >>> 16); tmp[2] = (byte) (i >>> 8); tmp[3] = (byte) i; update(tmp, 0, 4); } @Override public void update(byte foo[], int s, int l) { mac.update(foo, s, l); } @Override public void doFinal(byte[] buf, int offset) { try { mac.doFinal(buf, offset); } catch (ShortBufferException e) { if (JSch.getLogger().isEnabled(Logger.ERROR)) { JSch.getLogger().log(Logger.ERROR, e.getMessage(), e); } } } @Override public String getName() { return name; } @Override public boolean isEtM() { return etm; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACMD5.java000066400000000000000000000031641465436372100245450ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACMD5 extends HMAC { public HMACMD5() { name = "hmac-md5"; bsize = 16; algorithm = "HmacMD5"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACMD596.java000066400000000000000000000035221465436372100247220ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACMD596 extends HMACMD5 { public HMACMD596() { name = "hmac-md5-96"; } @Override public int getBlockSize() { return 12; }; private final byte[] _buf16 = new byte[16]; @Override public void doFinal(byte[] buf, int offset) { super.doFinal(_buf16, 0); System.arraycopy(_buf16, 0, buf, offset, 12); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java000066400000000000000000000031731465436372100252720ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACMD596ETM extends HMACMD596 { public HMACMD596ETM() { name = "hmac-md5-96-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACMD5ETM.java000066400000000000000000000031621465436372100251110ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACMD5ETM extends HMACMD5 { public HMACMD5ETM() { name = "hmac-md5-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA1.java000066400000000000000000000031701465436372100246510ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA1 extends HMAC { public HMACSHA1() { name = "hmac-sha1"; bsize = 20; algorithm = "HmacSHA1"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java000066400000000000000000000035271465436372100250360ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA196 extends HMACSHA1 { public HMACSHA196() { name = "hmac-sha1-96"; } @Override public int getBlockSize() { return 12; }; private final byte[] _buf20 = new byte[20]; @Override public void doFinal(byte[] buf, int offset) { super.doFinal(_buf20, 0); System.arraycopy(_buf20, 0, buf, offset, 12); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java000066400000000000000000000032001465436372100253700ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA196ETM extends HMACSHA196 { public HMACSHA196ETM() { name = "hmac-sha1-96-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java000066400000000000000000000031661465436372100252240ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA1ETM extends HMACSHA1 { public HMACSHA1ETM() { name = "hmac-sha1-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java000066400000000000000000000032241465436372100257350ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA224SSHCOM extends HMAC { public HMACSHA224SSHCOM() { name = "hmac-sha224@ssh.com"; bsize = 28; algorithm = "HmacSHA224"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA256.java000066400000000000000000000032021465436372100250210ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA256 extends HMAC { public HMACSHA256() { name = "hmac-sha2-256"; bsize = 32; algorithm = "HmacSHA256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java000066400000000000000000000032301465436372100260210ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA2562SSHCOM extends HMAC { public HMACSHA2562SSHCOM() { name = "hmac-sha256-2@ssh.com"; bsize = 32; algorithm = "HmacSHA256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java000066400000000000000000000032001465436372100253650ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA256ETM extends HMACSHA256 { public HMACSHA256ETM() { name = "hmac-sha2-256-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA256SSHCOM.java000066400000000000000000000035451465436372100257500ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; // This MAC appears to use a shortened keysize of 16 bytes instead of 32 bytes. // See discussion at https://github.com/ronf/asyncssh/issues/399. public class HMACSHA256SSHCOM extends HMAC { public HMACSHA256SSHCOM() { name = "hmac-sha256@ssh.com"; bsize = 16; algorithm = "HmacSHA256"; } @Override public int getBlockSize() { return 32; }; } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java000066400000000000000000000032241465436372100257440ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA384SSHCOM extends HMAC { public HMACSHA384SSHCOM() { name = "hmac-sha384@ssh.com"; bsize = 48; algorithm = "HmacSHA384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA512.java000066400000000000000000000032021465436372100250140ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA512 extends HMAC { public HMACSHA512() { name = "hmac-sha2-512"; bsize = 64; algorithm = "HmacSHA512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java000066400000000000000000000032001465436372100253600ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA512ETM extends HMACSHA512 { public HMACSHA512ETM() { name = "hmac-sha2-512-etm@openssh.com"; etm = true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java000066400000000000000000000032241465436372100257350ustar00rootroot00000000000000/* * Copyright (c) 2012-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class HMACSHA512SSHCOM extends HMAC { public HMACSHA512SSHCOM() { name = "hmac-sha512@ssh.com"; bsize = 64; algorithm = "HmacSHA512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java000066400000000000000000000055201465436372100260530ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.DSAKey; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; public class KeyPairGenDSA implements com.jcraft.jsch.KeyPairGenDSA { byte[] x; // private byte[] y; // public byte[] p; byte[] q; byte[] g; @Override public void init(int key_size) throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); keyGen.initialize(key_size, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); PublicKey pubKey = pair.getPublic(); PrivateKey prvKey = pair.getPrivate(); x = ((DSAPrivateKey) prvKey).getX().toByteArray(); y = ((DSAPublicKey) pubKey).getY().toByteArray(); DSAParams params = ((DSAKey) prvKey).getParams(); p = params.getP().toByteArray(); q = params.getQ().toByteArray(); g = params.getG().toByteArray(); } @Override public byte[] getX() { return x; } @Override public byte[] getY() { return y; } @Override public byte[] getP() { return p; } @Override public byte[] getQ() { return q; } @Override public byte[] getG() { return g; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java000066400000000000000000000074751465436372100262760ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.JSchException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; public class KeyPairGenECDSA implements com.jcraft.jsch.KeyPairGenECDSA { byte[] d; byte[] r; byte[] s; ECPublicKey pubKey; ECPrivateKey prvKey; ECParameterSpec params; @Override public void init(int key_size) throws Exception { String name = null; if (key_size == 256) name = "secp256r1"; else if (key_size == 384) name = "secp384r1"; else if (key_size == 521) name = "secp521r1"; else throw new JSchException("unsupported key size: " + key_size); for (int i = 0; i < 1000; i++) { KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); ECGenParameterSpec ecsp = new ECGenParameterSpec(name); kpg.initialize(ecsp); KeyPair kp = kpg.genKeyPair(); prvKey = (ECPrivateKey) kp.getPrivate(); pubKey = (ECPublicKey) kp.getPublic(); params = pubKey.getParams(); d = prvKey.getS().toByteArray(); ECPoint w = pubKey.getW(); r = w.getAffineX().toByteArray(); s = w.getAffineY().toByteArray(); if (r.length != s.length) continue; if (key_size == 256 && r.length == 32) break; if (key_size == 384 && r.length == 48) break; if (key_size == 521 && r.length == 66) break; } if (d.length < r.length) { d = insert0(d); } } @Override public byte[] getD() { return d; } @Override public byte[] getR() { return r; } @Override public byte[] getS() { return s; } ECPublicKey getPublicKey() { return pubKey; } ECPrivateKey getPrivateKey() { return prvKey; } private byte[] insert0(byte[] buf) { // if ((buf[0] & 0x80) == 0) return buf; byte[] tmp = new byte[buf.length + 1]; System.arraycopy(buf, 0, tmp, 1, buf.length); Util.bzero(buf); return tmp; } private byte[] chop0(byte[] buf) { if (buf[0] != 0 || (buf[1] & 0x80) == 0) return buf; byte[] tmp = new byte[buf.length - 1]; System.arraycopy(buf, 1, tmp, 0, tmp.length); Util.bzero(buf); return tmp; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/KeyPairGenEdDSA.java000066400000000000000000000041211465436372100263200ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class KeyPairGenEdDSA implements com.jcraft.jsch.KeyPairGenEdDSA { public KeyPairGenEdDSA() { throw new UnsupportedOperationException("KeyPairGenEdDSA requires Java15+."); } @Override public void init(String name, int keylen) throws Exception { throw new UnsupportedOperationException("KeyPairGenEdDSA requires Java15+."); } @Override public byte[] getPrv() { throw new UnsupportedOperationException("KeyPairGenEdDSA requires Java15+."); } @Override public byte[] getPub() { throw new UnsupportedOperationException("KeyPairGenEdDSA requires Java15+."); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/KeyPairGenRSA.java000066400000000000000000000065141465436372100260750ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; public class KeyPairGenRSA implements com.jcraft.jsch.KeyPairGenRSA { byte[] d; // private byte[] e; // public byte[] n; byte[] c; // coefficient byte[] ep; // exponent p byte[] eq; // exponent q byte[] p; // prime p byte[] q; // prime q @Override public void init(int key_size) throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(key_size, new SecureRandom()); KeyPair pair = keyGen.generateKeyPair(); PublicKey pubKey = pair.getPublic(); PrivateKey prvKey = pair.getPrivate(); d = ((RSAPrivateKey) prvKey).getPrivateExponent().toByteArray(); e = ((RSAPublicKey) pubKey).getPublicExponent().toByteArray(); n = ((RSAPrivateKey) prvKey).getModulus().toByteArray(); c = ((RSAPrivateCrtKey) prvKey).getCrtCoefficient().toByteArray(); ep = ((RSAPrivateCrtKey) prvKey).getPrimeExponentP().toByteArray(); eq = ((RSAPrivateCrtKey) prvKey).getPrimeExponentQ().toByteArray(); p = ((RSAPrivateCrtKey) prvKey).getPrimeP().toByteArray(); q = ((RSAPrivateCrtKey) prvKey).getPrimeQ().toByteArray(); } @Override public byte[] getD() { return d; } @Override public byte[] getE() { return e; } @Override public byte[] getN() { return n; } @Override public byte[] getC() { return c; } @Override public byte[] getEP() { return ep; } @Override public byte[] getEQ() { return eq; } @Override public byte[] getP() { return p; } @Override public byte[] getQ() { return q; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/MD5.java000066400000000000000000000040321465436372100241070ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.HASH; import java.security.MessageDigest; public class MD5 implements HASH { MessageDigest md; @Override public int getBlockSize() { return 16; } @Override public void init() throws Exception { md = MessageDigest.getInstance("MD5"); } @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } @Override public byte[] digest() throws Exception { return md.digest(); } @Override public String name() { return "MD5"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF.java000066400000000000000000000045021465436372100243520ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; /** Use PBKDF2 instead. */ @Deprecated public class PBKDF implements com.jcraft.jsch.PBKDF { @Override public byte[] getKey(byte[] _pass, byte[] salt, int iterations, int size) { char[] pass = new char[_pass.length]; for (int i = 0; i < _pass.length; i++) { pass[i] = (char) (_pass[i] & 0xff); } try { PBEKeySpec spec = new PBEKeySpec(pass, salt, iterations, size * 8); SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); byte[] key = skf.generateSecret(spec).getEncoded(); return key; } catch (InvalidKeySpecException e) { } catch (NoSuchAlgorithmException e) { } return null; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2.java000066400000000000000000000046061465436372100244410ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.security.spec.InvalidKeySpecException; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; abstract class PBKDF2 implements com.jcraft.jsch.PBKDF2 { private SecretKeyFactory skf; private byte[] salt; private int iterations; abstract String getName(); @Override public void init(byte[] salt, int iterations) throws Exception { skf = SecretKeyFactory.getInstance(getName()); this.salt = salt; this.iterations = iterations; } @Override public byte[] getKey(byte[] _pass, int size) { char[] pass = new char[_pass.length]; for (int i = 0; i < _pass.length; i++) { pass[i] = (char) (_pass[i] & 0xff); } try { PBEKeySpec spec = new PBEKeySpec(pass, salt, iterations, size * 8); byte[] key = skf.generateSecret(spec).getEncoded(); return key; } catch (InvalidKeySpecException e) { } return null; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA1.java000066400000000000000000000031501465436372100255000ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA1 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA1"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA224.java000066400000000000000000000031541465436372100256530ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA224 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA224"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA256.java000066400000000000000000000031541465436372100256600ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA256 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA384.java000066400000000000000000000031541465436372100256620ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA384 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA512.java000066400000000000000000000031541465436372100256530ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA512 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA512224.java000066400000000000000000000031631465436372100261030ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA512224 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA512/224"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/PBKDF2HMACSHA512256.java000066400000000000000000000031631465436372100261100ustar00rootroot00000000000000/* * Copyright (c) 2013-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class PBKDF2HMACSHA512256 extends PBKDF2 { @Override String getName() { return "PBKDF2WithHmacSHA512/256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/Random.java000066400000000000000000000056741465436372100247570ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.security.SecureRandom; public class Random implements com.jcraft.jsch.Random { private byte[] tmp = new byte[16]; private SecureRandom random = null; public Random() { // We hope that 'new SecureRandom()' will use NativePRNG algorithm // on Sun's Java5 for GNU/Linux and Solaris. // It seems NativePRNG refers to /dev/urandom and it must not be blocked, // but NativePRNG is slower than SHA1PRNG ;-< // TIPS: By adding option '-Djava.security.egd=file:/dev/./urandom' // SHA1PRNG will be used instead of NativePRNG. // On MacOSX, 'new SecureRandom()' will use NativePRNG algorithm and // it is also slower than SHA1PRNG. // On Windows, 'new SecureRandom()' will use SHA1PRNG algorithm. random = new SecureRandom(); /* * try{ random=SecureRandom.getInstance("SHA1PRNG"); return; } catch(NoSuchAlgorithmException * e){ // System.err.println(e); } * * // The following code is for IBM's JCE try{ * random=SecureRandom.getInstance("IBMSecureRandom"); return; } catch(NoSuchAlgorithmException * ee){ //System.err.println(ee); } */ } @Override public void fill(byte[] foo, int start, int len) { /* * // This case will not become true in our usage. if(start==0 && foo.length==len){ * random.nextBytes(foo); return; } */ if (len > tmp.length) { tmp = new byte[len]; } random.nextBytes(tmp); System.arraycopy(tmp, 0, foo, start, len); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SHA1.java000066400000000000000000000040361465436372100242220ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.HASH; import java.security.MessageDigest; public class SHA1 implements HASH { MessageDigest md; @Override public int getBlockSize() { return 20; } @Override public void init() throws Exception { md = MessageDigest.getInstance("SHA-1"); } @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } @Override public byte[] digest() throws Exception { return md.digest(); } @Override public String name() { return "SHA1"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SHA224.java000066400000000000000000000040441465436372100243700ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.HASH; import java.security.MessageDigest; public class SHA224 implements HASH { MessageDigest md; @Override public int getBlockSize() { return 28; } @Override public void init() throws Exception { md = MessageDigest.getInstance("SHA-224"); } @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } @Override public byte[] digest() throws Exception { return md.digest(); } @Override public String name() { return "SHA224"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SHA256.java000066400000000000000000000040441465436372100243750ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.HASH; import java.security.MessageDigest; public class SHA256 implements HASH { MessageDigest md; @Override public int getBlockSize() { return 32; } @Override public void init() throws Exception { md = MessageDigest.getInstance("SHA-256"); } @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } @Override public byte[] digest() throws Exception { return md.digest(); } @Override public String name() { return "SHA256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SHA384.java000066400000000000000000000040441465436372100243770ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.HASH; import java.security.MessageDigest; public class SHA384 implements HASH { MessageDigest md; @Override public int getBlockSize() { return 48; } @Override public void init() throws Exception { md = MessageDigest.getInstance("SHA-384"); } @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } @Override public byte[] digest() throws Exception { return md.digest(); } @Override public String name() { return "SHA384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SHA512.java000066400000000000000000000040441465436372100243700ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.HASH; import java.security.MessageDigest; public class SHA512 implements HASH { MessageDigest md; @Override public int getBlockSize() { return 64; } @Override public void init() throws Exception { md = MessageDigest.getInstance("SHA-512"); } @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } @Override public byte[] digest() throws Exception { return md.digest(); } @Override public String name() { return "SHA512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java000066400000000000000000000132041465436372100260140ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.Buffer; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; public class SignatureDSA implements com.jcraft.jsch.SignatureDSA { Signature signature; KeyFactory keyFactory; @Override public void init() throws Exception { signature = Signature.getInstance("SHA1withDSA"); keyFactory = KeyFactory.getInstance("DSA"); } @Override public void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception { DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec(new BigInteger(y), new BigInteger(p), new BigInteger(q), new BigInteger(g)); PublicKey pubKey = keyFactory.generatePublic(dsaPubKeySpec); signature.initVerify(pubKey); } @Override public void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception { DSAPrivateKeySpec dsaPrivKeySpec = new DSAPrivateKeySpec(new BigInteger(x), new BigInteger(p), new BigInteger(q), new BigInteger(g)); PrivateKey prvKey = keyFactory.generatePrivate(dsaPrivKeySpec); signature.initSign(prvKey); } @Override public byte[] sign() throws Exception { byte[] sig = signature.sign(); /* * System.err.print("sign["+sig.length+"] "); for(int i=0; i 1 && secret[0] == 0 && (secret[1] & 0x80) == 0) { byte[] tmp = new byte[secret.length - 1]; System.arraycopy(secret, 1, tmp, 0, tmp.length); return normalize(tmp); } else { return secret; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java000066400000000000000000000031651465436372100264660ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureECDSA256 extends SignatureECDSAN { @Override String getName() { return "ecdsa-sha2-nistp256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java000066400000000000000000000031651465436372100264700ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureECDSA384 extends SignatureECDSAN { @Override String getName() { return "ecdsa-sha2-nistp384"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java000066400000000000000000000031651465436372100264610ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureECDSA521 extends SignatureECDSAN { @Override String getName() { return "ecdsa-sha2-nistp521"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java000066400000000000000000000160611465436372100263460ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.Buffer; import com.jcraft.jsch.SignatureECDSA; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.ECPublicKeySpec; abstract class SignatureECDSAN implements SignatureECDSA { Signature signature; KeyFactory keyFactory; abstract String getName(); @Override public void init() throws Exception { String name = getName(); String foo = "SHA256withECDSA"; if (name.equals("ecdsa-sha2-nistp384")) foo = "SHA384withECDSA"; else if (name.equals("ecdsa-sha2-nistp521")) foo = "SHA512withECDSA"; signature = Signature.getInstance(foo); keyFactory = KeyFactory.getInstance("EC"); } @Override public void setPubKey(byte[] r, byte[] s) throws Exception { // r and s must be unsigned values. r = insert0(r); s = insert0(s); String name = "secp256r1"; if (r.length >= 64) name = "secp521r1"; else if (r.length >= 48) name = "secp384r1"; AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); param.init(new ECGenParameterSpec(name)); ECParameterSpec ecparam = param.getParameterSpec(ECParameterSpec.class); ECPoint w = new ECPoint(new BigInteger(1, r), new BigInteger(1, s)); PublicKey pubKey = keyFactory.generatePublic(new ECPublicKeySpec(w, ecparam)); signature.initVerify(pubKey); } @Override public void setPrvKey(byte[] d) throws Exception { // d must be unsigned value. d = insert0(d); String name = "secp256r1"; if (d.length >= 64) name = "secp521r1"; else if (d.length >= 48) name = "secp384r1"; AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); param.init(new ECGenParameterSpec(name)); ECParameterSpec ecparam = param.getParameterSpec(ECParameterSpec.class); BigInteger _d = new BigInteger(1, d); PrivateKey prvKey = keyFactory.generatePrivate(new ECPrivateKeySpec(_d, ecparam)); signature.initSign(prvKey); } @Override public byte[] sign() throws Exception { byte[] sig = signature.sign(); // It seems that the output from SunEC is in ASN.1, // so we have to convert it. if (sig[0] == 0x30 && // in ASN.1 ((sig[1] + 2 == sig.length) || ((sig[1] & 0x80) != 0 && (sig[2] & 0xff) + 3 == sig.length))) { // 2bytes for len int index = 3; if ((sig[1] & 0x80) != 0 && (sig[2] & 0xff) + 3 == sig.length) index = 4; byte[] r = new byte[sig[index]]; byte[] s = new byte[sig[index + 2 + sig[index]]]; System.arraycopy(sig, index + 1, r, 0, r.length); System.arraycopy(sig, index + 3 + sig[index], s, 0, s.length); r = chop0(r); s = chop0(s); Buffer buf = new Buffer(); buf.putMPInt(r); buf.putMPInt(s); sig = new byte[buf.getLength()]; buf.setOffSet(0); buf.getByte(sig); } return sig; } @Override public void update(byte[] foo) throws Exception { signature.update(foo); } @Override public boolean verify(byte[] sig) throws Exception { // It seems that SunEC expects ASN.1 data, // so we have to convert it. if (!(sig[0] == 0x30 && // not in ASN.1 ((sig[1] + 2 == sig.length) || ((sig[1] & 0x80) != 0 && (sig[2] & 0xff) + 3 == sig.length)))) { Buffer b = new Buffer(sig); b.getString(); // ecdsa-sha2-nistp256 b.getInt(); byte[] r = b.getMPInt(); byte[] s = b.getMPInt(); r = trimLeadingZeros(insert0(r)); s = trimLeadingZeros(insert0(s)); byte[] asn1 = null; if (r.length < 64) { asn1 = new byte[6 + r.length + s.length]; asn1[0] = (byte) 0x30; asn1[1] = (byte) (4 + r.length + s.length); asn1[2] = (byte) 0x02; asn1[3] = (byte) r.length; System.arraycopy(r, 0, asn1, 4, r.length); asn1[r.length + 4] = (byte) 0x02; asn1[r.length + 5] = (byte) s.length; System.arraycopy(s, 0, asn1, (6 + r.length), s.length); } else { asn1 = new byte[6 + r.length + s.length + 1]; asn1[0] = (byte) 0x30; asn1[1] = (byte) 0x81; asn1[2] = (byte) (4 + r.length + s.length); asn1[3] = (byte) 0x02; asn1[4] = (byte) r.length; System.arraycopy(r, 0, asn1, 5, r.length); asn1[r.length + 5] = (byte) 0x02; asn1[r.length + 6] = (byte) s.length; System.arraycopy(s, 0, asn1, (7 + r.length), s.length); } sig = asn1; } return signature.verify(sig); } private static byte[] insert0(byte[] buf) { if ((buf[0] & 0x80) == 0) return buf; byte[] tmp = new byte[buf.length + 1]; System.arraycopy(buf, 0, tmp, 1, buf.length); Util.bzero(buf); return tmp; } private static byte[] chop0(byte[] buf) { if (buf[0] != 0) return buf; byte[] tmp = new byte[buf.length - 1]; System.arraycopy(buf, 1, tmp, 0, tmp.length); Util.bzero(buf); return tmp; } private static byte[] trimLeadingZeros(byte[] buf) { if (buf.length < 2) return buf; int i = 0; while (i < buf.length - 1) { if (buf[i] == 0 && (buf[i + 1] & 0x80) == 0) i++; else break; } if (i == 0) return buf; byte[] tmp = new byte[buf.length - i]; System.arraycopy(buf, i, tmp, 0, tmp.length); Util.bzero(buf); return tmp; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureEd25519.java000066400000000000000000000051241465436372100263450ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.SignatureEdDSA; public class SignatureEd25519 implements SignatureEdDSA { public SignatureEd25519() { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } @Override public void init() throws Exception { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } @Override public void setPubKey(byte[] y_arr) throws Exception { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } @Override public void setPrvKey(byte[] bytes) throws Exception { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } @Override public byte[] sign() throws Exception { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } @Override public void update(byte[] foo) throws Exception { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } @Override public boolean verify(byte[] sig) throws Exception { throw new UnsupportedOperationException("SignatureEd25519 requires Java15+."); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureEd448.java000066400000000000000000000051021465436372100261730ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.SignatureEdDSA; public class SignatureEd448 implements SignatureEdDSA { public SignatureEd448() { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } @Override public void init() throws Exception { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } @Override public void setPubKey(byte[] y_arr) throws Exception { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } @Override public void setPrvKey(byte[] bytes) throws Exception { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } @Override public byte[] sign() throws Exception { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } @Override public void update(byte[] foo) throws Exception { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } @Override public boolean verify(byte[] sig) throws Exception { throw new UnsupportedOperationException("SignatureEd448 requires Java15+."); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSA.java000066400000000000000000000031421465436372100260320ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSA extends SignatureRSAN { @Override String getName() { return "ssh-rsa"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSAN.java000066400000000000000000000100001465436372100261370ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.Buffer; import com.jcraft.jsch.SignatureRSA; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; abstract class SignatureRSAN implements SignatureRSA { Signature signature; KeyFactory keyFactory; abstract String getName(); @Override public void init() throws Exception { String name = getName(); String foo = "SHA1withRSA"; if (name.equals("rsa-sha2-256") || name.equals("ssh-rsa-sha256@ssh.com")) foo = "SHA256withRSA"; else if (name.equals("rsa-sha2-512") || name.equals("ssh-rsa-sha512@ssh.com")) foo = "SHA512withRSA"; else if (name.equals("ssh-rsa-sha384@ssh.com")) foo = "SHA384withRSA"; else if (name.equals("ssh-rsa-sha224@ssh.com")) foo = "SHA224withRSA"; signature = Signature.getInstance(foo); keyFactory = KeyFactory.getInstance("RSA"); } @Override public void setPubKey(byte[] e, byte[] n) throws Exception { RSAPublicKeySpec rsaPubKeySpec = new RSAPublicKeySpec(new BigInteger(n), new BigInteger(e)); PublicKey pubKey = keyFactory.generatePublic(rsaPubKeySpec); signature.initVerify(pubKey); } @Override public void setPrvKey(byte[] d, byte[] n) throws Exception { RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(new BigInteger(n), new BigInteger(d)); PrivateKey prvKey = keyFactory.generatePrivate(rsaPrivKeySpec); signature.initSign(prvKey); } @Override public byte[] sign() throws Exception { byte[] sig = signature.sign(); return sig; } @Override public void update(byte[] foo) throws Exception { signature.update(foo); } @Override public boolean verify(byte[] sig) throws Exception { int i = 0; int j = 0; byte[] tmp; Buffer buf = new Buffer(sig); String foo = new String(buf.getString(), StandardCharsets.UTF_8); if (foo.equals("ssh-rsa") || foo.equals("rsa-sha2-256") || foo.equals("rsa-sha2-512") || foo.equals("ssh-rsa-sha224@ssh.com") || foo.equals("ssh-rsa-sha256@ssh.com") || foo.equals("ssh-rsa-sha384@ssh.com") || foo.equals("ssh-rsa-sha512@ssh.com")) { if (!foo.equals(getName())) return false; j = buf.getInt(); i = buf.getOffSet(); tmp = new byte[j]; System.arraycopy(sig, i, tmp, 0, j); sig = tmp; } return signature.verify(sig); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA224SSHCOM.java000066400000000000000000000031751465436372100275410ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSASHA224SSHCOM extends SignatureRSAN { @Override String getName() { return "ssh-rsa-sha224@ssh.com"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA256.java000066400000000000000000000031551465436372100266270ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSASHA256 extends SignatureRSAN { @Override String getName() { return "rsa-sha2-256"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA256SSHCOM.java000066400000000000000000000031751465436372100275460ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSASHA256SSHCOM extends SignatureRSAN { @Override String getName() { return "ssh-rsa-sha256@ssh.com"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA384SSHCOM.java000066400000000000000000000031751465436372100275500ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSASHA384SSHCOM extends SignatureRSAN { @Override String getName() { return "ssh-rsa-sha384@ssh.com"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA512.java000066400000000000000000000031551465436372100266220ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSASHA512 extends SignatureRSAN { @Override String getName() { return "rsa-sha2-512"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA512SSHCOM.java000066400000000000000000000031751465436372100275410ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureRSASHA512SSHCOM extends SignatureRSAN { @Override String getName() { return "ssh-rsa-sha512@ssh.com"; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/TripleDESCBC.java000066400000000000000000000064441465436372100256360ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; public class TripleDESCBC implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 24; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = Cipher.getInstance("DESede/CBC/NoPadding"); /* * // The following code does not work on IBM's JDK 1.4.1 SecretKeySpec skeySpec = new * SecretKeySpec(key, "DESede"); cipher.init((mode==com.jcraft.jsch.Cipher.ENCRYPT_MODE? * Cipher.ENCRYPT_MODE: Cipher.DECRYPT_MODE), skeySpec, new IvParameterSpec(iv)); */ DESedeKeySpec keyspec = new DESedeKeySpec(key); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede"); SecretKey _key = keyfactory.generateSecret(keyspec); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), _key, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return true; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/TripleDESCTR.java000066400000000000000000000064451465436372100257000ustar00rootroot00000000000000/* * Copyright (c) 2008-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; public class TripleDESCTR implements com.jcraft.jsch.Cipher { private static final int ivsize = 8; private static final int bsize = 24; private Cipher cipher; @Override public int getIVSize() { return ivsize; } @Override public int getBlockSize() { return bsize; } @Override public void init(int mode, byte[] key, byte[] iv) throws Exception { byte[] tmp; if (iv.length > ivsize) { tmp = new byte[ivsize]; System.arraycopy(iv, 0, tmp, 0, tmp.length); iv = tmp; } if (key.length > bsize) { tmp = new byte[bsize]; System.arraycopy(key, 0, tmp, 0, tmp.length); key = tmp; } try { cipher = Cipher.getInstance("DESede/CTR/NoPadding"); /* * // The following code does not work on IBM's JDK 1.4.1 SecretKeySpec skeySpec = new * SecretKeySpec(key, "DESede"); cipher.init((mode==com.jcraft.jsch.Cipher.ENCRYPT_MODE? * Cipher.ENCRYPT_MODE: Cipher.DECRYPT_MODE), skeySpec, new IvParameterSpec(iv)); */ DESedeKeySpec keyspec = new DESedeKeySpec(key); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede"); SecretKey _key = keyfactory.generateSecret(keyspec); cipher.init( (mode == com.jcraft.jsch.Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE), _key, new IvParameterSpec(iv)); } catch (Exception e) { cipher = null; throw e; } } @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception { cipher.update(foo, s1, len, bar, s2); } @Override public boolean isCBC() { return false; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/Util.java000066400000000000000000000032061465436372100244410ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; class Util { static void bzero(byte[] foo) { if (foo == null) return; for (int i = 0; i < foo.length; i++) foo[i] = 0; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jce/XDH.java000066400000000000000000000042661465436372100241560ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class XDH implements com.jcraft.jsch.XDH { public XDH() { throw new UnsupportedOperationException("XDH requires Java11+."); } @Override public void init(String name, int keylen) throws Exception { throw new UnsupportedOperationException("XDH requires Java11+."); } @Override public byte[] getQ() throws Exception { throw new UnsupportedOperationException("XDH requires Java11+."); } @Override public byte[] getSecret(byte[] Q) throws Exception { throw new UnsupportedOperationException("XDH requires Java11+."); } @Override public boolean validate(byte[] u) throws Exception { throw new UnsupportedOperationException("XDH requires Java11+."); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jgss/000077500000000000000000000000001465436372100230655ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jgss/GSSContextKrb5.java000066400000000000000000000133221465436372100264560ustar00rootroot00000000000000/* * Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jgss; import com.jcraft.jsch.JSchException; import java.net.InetAddress; import java.net.UnknownHostException; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; import org.ietf.jgss.GSSName; import org.ietf.jgss.MessageProp; import org.ietf.jgss.Oid; public class GSSContextKrb5 implements com.jcraft.jsch.GSSContext { private static final String pUseSubjectCredsOnly = "javax.security.auth.useSubjectCredsOnly"; private static String useSubjectCredsOnly = getSystemProperty(pUseSubjectCredsOnly); private GSSContext context = null; @Override public void create(String user, String host) throws JSchException { try { // RFC 1964 Oid krb5 = new Oid("1.2.840.113554.1.2.2"); // Kerberos Principal Name Form Oid principalName = new Oid("1.2.840.113554.1.2.2.1"); GSSManager mgr = GSSManager.getInstance(); GSSCredential crd = null; /* * try{ GSSName _user=mgr.createName(user, principalName); crd=mgr.createCredential(_user, * GSSCredential.DEFAULT_LIFETIME, krb5, GSSCredential.INITIATE_ONLY); } catch(GSSException * crdex){ } */ String cname = host; try { cname = InetAddress.getByName(cname).getCanonicalHostName(); } catch (UnknownHostException e) { } GSSName _host = mgr.createName("host/" + cname, principalName); context = mgr.createContext(_host, krb5, crd, GSSContext.DEFAULT_LIFETIME); // RFC4462 3.4. GSS-API Session // // When calling GSS_Init_sec_context(), the client MUST set // integ_req_flag to "true" to request that per-message integrity // protection be supported for this context. In addition, // deleg_req_flag MAY be set to "true" to request access delegation, if // requested by the user. // // Since the user authentication process by its nature authenticates // only the client, the setting of mutual_req_flag is not needed for // this process. This flag SHOULD be set to "false". // TODO: OpenSSH's sshd does accepts 'false' for mutual_req_flag // context.requestMutualAuth(false); context.requestMutualAuth(true); context.requestConf(true); context.requestInteg(true); // for MIC context.requestCredDeleg(true); context.requestAnonymity(false); return; } catch (GSSException ex) { throw new JSchException(ex.toString(), ex); } } @Override public boolean isEstablished() { return context.isEstablished(); } @Override public byte[] init(byte[] token, int s, int l) throws JSchException { try { // Without setting "javax.security.auth.useSubjectCredsOnly" to "false", // Sun's JVM for Un*x will show messages to stderr in // processing context.initSecContext(). // This hack is not thread safe ;-<. // If that property is explicitly given as "true" or "false", // this hack must not be invoked. if (useSubjectCredsOnly == null) { setSystemProperty(pUseSubjectCredsOnly, "false"); } return context.initSecContext(token, 0, l); } catch (GSSException ex) { throw new JSchException(ex.toString(), ex); } catch (SecurityException ex) { throw new JSchException(ex.toString(), ex); } finally { if (useSubjectCredsOnly == null) { // By the default, it must be "true". setSystemProperty(pUseSubjectCredsOnly, "true"); } } } @Override public byte[] getMIC(byte[] message, int s, int l) { try { MessageProp prop = new MessageProp(0, true); return context.getMIC(message, s, l, prop); } catch (GSSException ex) { return null; } } @Override public void dispose() { try { context.dispose(); } catch (GSSException ex) { } } private static String getSystemProperty(String key) { try { return System.getProperty(key); } catch (Exception e) { // We are not allowed to get the System properties. return null; } } private static void setSystemProperty(String key, String value) { try { System.setProperty(key, value); } catch (Exception e) { // We are not allowed to set the System properties. } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/juz/000077500000000000000000000000001465436372100227275ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/juz/Compression.java000066400000000000000000000104151465436372100260740ustar00rootroot00000000000000package com.jcraft.jsch.juz; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Logger; import com.jcraft.jsch.Session; import java.util.function.Supplier; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; /** * This example demonstrates the packet compression without using jzlib[1]. * *

* The ssh protocol adopts zlib[2] for the packet compression. Fortunately, JDK has provided wrapper * classes for zlib(j.u.z.{Deflater, Inflater}), but it does not expose enough functionality of * zlib, unfortunately; it must not allow to compress data with SYNC_FLUSH. So, JSch has been using * jzlib by the default. After 12 years of bug parade entry[3] filing, Java7 has revised * j.u.z.Deflater, and SYNC_FLUSH has been supported at last. This example shows how to enable the * packet compression by using JDK's java.util.zip package. * *

* [1] http://www.jcraft.com/jzlib/ [2] http://www.zlib.net/ [3] * https://bugs.openjdk.java.net/browse/JDK-4206909 */ public class Compression implements com.jcraft.jsch.Compression { private static final int BUF_SIZE = 4096; private final int buffer_margin = 32 + 20; // AES256 + HMACSHA1 private Deflater deflater; private Inflater inflater; private byte[] tmpbuf = new byte[BUF_SIZE]; private byte[] inflated_buf; private Session session; public Compression() {} private void logMessage(int level, Supplier message) { Logger logger = session == null ? JSch.getLogger() : session.getLogger(); if (!logger.isEnabled(level)) { return; } logger.log(level, message.get()); } @Override public void end() { inflated_buf = null; if (inflater != null) { inflater.end(); inflater = null; } if (deflater != null) { deflater.end(); deflater = null; } session = null; } @Override public void init(int type, int level, Session session) { this.session = session; init(type, level); } @Override public void init(int type, int level) { if (type == DEFLATER) { deflater = new Deflater(level); } else if (type == INFLATER) { inflater = new Inflater(); inflated_buf = new byte[BUF_SIZE]; } logMessage(Logger.DEBUG, () -> "zlib using " + this.getClass().getCanonicalName()); } @Override public byte[] compress(byte[] buf, int start, int[] end) { // There may be a bug in j.u.z.Deflater. // It seems to me that if the size of buffer for Deflater#deflate() is // not enough, that method will return weird value ;-( if (tmpbuf.length < end[0]) { tmpbuf = new byte[end[0] * 2]; } deflater.setInput(buf, start, end[0] - start); byte[] obuf = buf; // output buffer int obuflen = start; // length of output buffer do { int result = deflater.deflate(tmpbuf, 0, tmpbuf.length, Deflater.SYNC_FLUSH); // deflation of delfated data may inflate it. if (obuf.length < obuflen + result + buffer_margin) { byte[] tmp = new byte[(obuflen + result + buffer_margin) * 2]; System.arraycopy(obuf, 0, tmp, 0, obuf.length); obuf = tmp; } System.arraycopy(tmpbuf, 0, obuf, obuflen, result); obuflen += result; } while (!deflater.needsInput()); end[0] = obuflen; return obuf; } @Override public byte[] uncompress(byte[] buf, int start, int[] len) { inflater.setInput(buf, start, len[0]); int inflated_end = 0; try { do { int result = inflater.inflate(tmpbuf, 0, tmpbuf.length); if (inflated_buf.length < inflated_end + result) { byte[] tmp = new byte[inflated_end + result]; System.arraycopy(inflated_buf, 0, tmp, 0, inflated_end); inflated_buf = tmp; } System.arraycopy(tmpbuf, 0, inflated_buf, inflated_end, result); inflated_end += result; } while (inflater.getRemaining() > 0); } catch (DataFormatException e) { logMessage(Logger.WARN, () -> "an exception during uncompress\n" + e.toString()); } if (buf.length < inflated_buf.length + start) { byte[] tmp = new byte[inflated_buf.length + start]; System.arraycopy(buf, 0, tmp, 0, start); buf = tmp; } System.arraycopy(inflated_buf, 0, buf, start, inflated_end); len[0] = inflated_end; return buf; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/000077500000000000000000000000001465436372100232315ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Adler32.java000066400000000000000000000076661465436372100253070ustar00rootroot00000000000000/* * Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class Adler32 implements Checksum { // largest prime smaller than 65536 private static final int BASE = 65521; // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 private static final int NMAX = 5552; private long s1 = 1L; private long s2 = 0L; @Override public void reset(long init) { s1 = init & 0xffff; s2 = (init >> 16) & 0xffff; } @Override public void reset() { s1 = 1L; s2 = 0L; } @Override public long getValue() { return ((s2 << 16) | s1); } @Override public void update(byte[] buf, int index, int len) { if (len == 1) { s1 += buf[index++] & 0xff; s2 += s1; s1 %= BASE; s2 %= BASE; return; } int len1 = len / NMAX; int len2 = len % NMAX; while (len1-- > 0) { int k = NMAX; len -= k; while (k-- > 0) { s1 += buf[index++] & 0xff; s2 += s1; } s1 %= BASE; s2 %= BASE; } int k = len2; len -= k; while (k-- > 0) { s1 += buf[index++] & 0xff; s2 += s1; } s1 %= BASE; s2 %= BASE; } @Override public Adler32 copy() { Adler32 foo = new Adler32(); foo.s1 = this.s1; foo.s2 = this.s2; return foo; } // The following logic has come from zlib.1.2. static long combine(long adler1, long adler2, long len2) { long BASEL = (long) BASE; long sum1; long sum2; long rem; // unsigned int rem = len2 % BASEL; sum1 = adler1 & 0xffffL; sum2 = rem * sum1; sum2 %= BASEL; // MOD(sum2); sum1 += (adler2 & 0xffffL) + BASEL - 1; sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; if (sum1 >= BASEL) sum1 -= BASEL; if (sum1 >= BASEL) sum1 -= BASEL; if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); if (sum2 >= BASEL) sum2 -= BASEL; return sum1 | (sum2 << 16); } /* * private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); void update(byte[] buf, int * index, int len){ if(buf==null) {adler.reset();} else{adler.update(buf, index, len);} } void * reset(){ adler.reset(); } void reset(long init){ if(init==1L){ adler.reset(); } else{ * System.err.println("unsupported operation"); } } long getValue(){ return adler.getValue(); } */ } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/CRC32.java000066400000000000000000000115601465436372100246530ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class CRC32 implements Checksum { /* * The following logic has come from RFC1952. */ private int v = 0; private static int[] crc_table = null; static { crc_table = new int[256]; for (int n = 0; n < 256; n++) { int c = n; for (int k = 8; --k >= 0;) { if ((c & 1) != 0) c = 0xedb88320 ^ (c >>> 1); else c = c >>> 1; } crc_table[n] = c; } } @Override public void update(byte[] buf, int index, int len) { int c = ~v; while (--len >= 0) c = crc_table[(c ^ buf[index++]) & 0xff] ^ (c >>> 8); v = ~c; } @Override public void reset() { v = 0; } @Override public void reset(long vv) { v = (int) (vv & 0xffffffffL); } @Override public long getValue() { return v & 0xffffffffL; } // The following logic has come from zlib.1.2. private static final int GF2_DIM = 32; static long combine(long crc1, long crc2, long len2) { long row; long[] even = new long[GF2_DIM]; long[] odd = new long[GF2_DIM]; // degenerate case (also disallow negative lengths) if (len2 <= 0) return crc1; // put operator for one zero bit in odd odd[0] = 0xedb88320L; // CRC-32 polynomial row = 1; for (int n = 1; n < GF2_DIM; n++) { odd[n] = row; row <<= 1; } // put operator for two zero bits in even gf2_matrix_square(even, odd); // put operator for four zero bits in odd gf2_matrix_square(odd, even); // apply len2 zeros to crc1 (first square will put the operator for one // zero byte, eight zero bits, in even) do { // apply zeros operator for this bit of len2 gf2_matrix_square(even, odd); if ((len2 & 1) != 0) crc1 = gf2_matrix_times(even, crc1); len2 >>= 1; // if no more bits set, then done if (len2 == 0) break; // another iteration of the loop with odd and even swapped gf2_matrix_square(odd, even); if ((len2 & 1) != 0) crc1 = gf2_matrix_times(odd, crc1); len2 >>= 1; // if no more bits set, then done } while (len2 != 0); /* return combined crc */ crc1 ^= crc2; return crc1; } private static long gf2_matrix_times(long[] mat, long vec) { long sum = 0; int index = 0; while (vec != 0) { if ((vec & 1) != 0) sum ^= mat[index]; vec >>= 1; index++; } return sum; } static final void gf2_matrix_square(long[] square, long[] mat) { for (int n = 0; n < GF2_DIM; n++) square[n] = gf2_matrix_times(mat, mat[n]); } /* * private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); * * void update(byte[] buf, int index, int len){ if(buf==null) {crc32.reset();} * else{crc32.update(buf, index, len);} } void reset(){ crc32.reset(); } void reset(long init){ * if(init==0L){ crc32.reset(); } else{ System.err.println("unsupported operation"); } } long * getValue(){ return crc32.getValue(); } */ @Override public CRC32 copy() { CRC32 foo = new CRC32(); foo.v = this.v; return foo; } static int[] getCRC32Table() { int[] tmp = new int[crc_table.length]; System.arraycopy(crc_table, 0, tmp, 0, tmp.length); return tmp; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Checksum.java000066400000000000000000000035001465436372100256340ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; interface Checksum { void update(byte[] buf, int index, int len); void reset(); void reset(long init); long getValue(); Checksum copy(); } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Compression.java000066400000000000000000000133571465436372100264060ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jzlib; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Logger; import com.jcraft.jsch.Session; import java.io.UncheckedIOException; import java.util.function.Supplier; public class Compression implements com.jcraft.jsch.Compression { private static final int BUF_SIZE = 4096; private final int buffer_margin = 32 + 20; // AES256 + HMACSHA1 private Deflater deflater; private Inflater inflater; private byte[] tmpbuf = new byte[BUF_SIZE]; private byte[] inflated_buf; private Session session; public Compression() {} private void logMessage(int level, Supplier message) { Logger logger = session == null ? JSch.getLogger() : session.getLogger(); if (!logger.isEnabled(level)) { return; } logger.log(level, message.get()); } @Override public void end() { inflated_buf = null; if (inflater != null) { inflater.end(); inflater = null; } if (deflater != null) { deflater.end(); deflater = null; } session = null; } @Override public void init(int type, int level, Session session) { this.session = session; init(type, level); } public void init(int type, int level) throws UncheckedIOException { if (type == DEFLATER) { try { deflater = new Deflater(level); } catch (GZIPException e) { throw new UncheckedIOException(e); } } else if (type == INFLATER) { inflater = new Inflater(); inflated_buf = new byte[BUF_SIZE]; } logMessage(Logger.DEBUG, () -> "zlib using " + this.getClass().getCanonicalName()); } @Override public byte[] compress(byte[] buf, int start, int[] len) { deflater.next_in = buf; deflater.next_in_index = start; deflater.avail_in = len[0] - start; int outputlen = start; byte[] outputbuf = buf; int tmp = 0; do { deflater.next_out = tmpbuf; deflater.next_out_index = 0; deflater.avail_out = BUF_SIZE; int status = deflater.deflate(JZlib.Z_PARTIAL_FLUSH); switch (status) { case JZlib.Z_OK: tmp = BUF_SIZE - deflater.avail_out; if (outputbuf.length < outputlen + tmp + buffer_margin) { byte[] foo = new byte[(outputlen + tmp + buffer_margin) * 2]; System.arraycopy(outputbuf, 0, foo, 0, outputbuf.length); outputbuf = foo; } System.arraycopy(tmpbuf, 0, outputbuf, outputlen, tmp); outputlen += tmp; break; default: logMessage(Logger.WARN, () -> "compress: deflate returnd " + status); } } while (deflater.avail_out == 0); len[0] = outputlen; return outputbuf; } @Override public byte[] uncompress(byte[] buffer, int start, int[] length) { int inflated_end = 0; inflater.next_in = buffer; inflater.next_in_index = start; inflater.avail_in = length[0]; while (true) { inflater.next_out = tmpbuf; inflater.next_out_index = 0; inflater.avail_out = BUF_SIZE; int status = inflater.inflate(JZlib.Z_PARTIAL_FLUSH); switch (status) { case JZlib.Z_OK: if (inflated_buf.length < inflated_end + BUF_SIZE - inflater.avail_out) { int len = inflated_buf.length * 2; if (len < inflated_end + BUF_SIZE - inflater.avail_out) len = inflated_end + BUF_SIZE - inflater.avail_out; byte[] foo = new byte[len]; System.arraycopy(inflated_buf, 0, foo, 0, inflated_end); inflated_buf = foo; } System.arraycopy(tmpbuf, 0, inflated_buf, inflated_end, BUF_SIZE - inflater.avail_out); inflated_end += (BUF_SIZE - inflater.avail_out); length[0] = inflated_end; break; case JZlib.Z_BUF_ERROR: if (inflated_end > buffer.length - start) { byte[] foo = new byte[inflated_end + start]; System.arraycopy(buffer, 0, foo, 0, start); System.arraycopy(inflated_buf, 0, foo, start, inflated_end); buffer = foo; } else { System.arraycopy(inflated_buf, 0, buffer, start, inflated_end); } length[0] = inflated_end; return buffer; default: logMessage(Logger.WARN, () -> "compress: deflate returnd " + status); return null; } } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Deflate.java000066400000000000000000001643721465436372100254550ustar00rootroot00000000000000/* * Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class Deflate implements Cloneable { private static final int MAX_MEM_LEVEL = 9; private static final int Z_DEFAULT_COMPRESSION = -1; private static final int MAX_WBITS = 15; // 32K LZ77 window private static final int DEF_MEM_LEVEL = 8; static class Config { int good_length; // reduce lazy search above this match length int max_lazy; // do not perform lazy search above this match length int nice_length; // quit search above this match length int max_chain; int func; Config(int good_length, int max_lazy, int nice_length, int max_chain, int func) { this.good_length = good_length; this.max_lazy = max_lazy; this.nice_length = nice_length; this.max_chain = max_chain; this.func = func; } } private static final int STORED = 0; private static final int FAST = 1; private static final int SLOW = 2; private static final Config[] config_table; static { config_table = new Config[10]; // good lazy nice chain config_table[0] = new Config(0, 0, 0, 0, STORED); config_table[1] = new Config(4, 4, 8, 4, FAST); config_table[2] = new Config(4, 5, 16, 8, FAST); config_table[3] = new Config(4, 6, 32, 32, FAST); config_table[4] = new Config(4, 4, 16, 16, SLOW); config_table[5] = new Config(8, 16, 32, 32, SLOW); config_table[6] = new Config(8, 16, 128, 128, SLOW); config_table[7] = new Config(8, 32, 128, 256, SLOW); config_table[8] = new Config(32, 128, 258, 1024, SLOW); config_table[9] = new Config(32, 258, 258, 4096, SLOW); } private static final String[] z_errmsg = {"need dictionary", // Z_NEED_DICT 2 "stream end", // Z_STREAM_END 1 "", // Z_OK 0 "file error", // Z_ERRNO (-1) "stream error", // Z_STREAM_ERROR (-2) "data error", // Z_DATA_ERROR (-3) "insufficient memory", // Z_MEM_ERROR (-4) "buffer error", // Z_BUF_ERROR (-5) "incompatible version", // Z_VERSION_ERROR (-6) ""}; // block not completed, need more input or more output private static final int NeedMore = 0; // block flush performed private static final int BlockDone = 1; // finish started, need only more output at next deflate private static final int FinishStarted = 2; // finish done, accept no more input or output private static final int FinishDone = 3; // preset dictionary flag in zlib header private static final int PRESET_DICT = 0x20; private static final int Z_FILTERED = 1; private static final int Z_HUFFMAN_ONLY = 2; private static final int Z_DEFAULT_STRATEGY = 0; private static final int Z_NO_FLUSH = 0; private static final int Z_PARTIAL_FLUSH = 1; private static final int Z_SYNC_FLUSH = 2; private static final int Z_FULL_FLUSH = 3; private static final int Z_FINISH = 4; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; private static final int INIT_STATE = 42; private static final int BUSY_STATE = 113; private static final int FINISH_STATE = 666; // The deflate compression method private static final int Z_DEFLATED = 8; private static final int STORED_BLOCK = 0; private static final int STATIC_TREES = 1; private static final int DYN_TREES = 2; // The three kinds of block type private static final int Z_BINARY = 0; private static final int Z_ASCII = 1; private static final int Z_UNKNOWN = 2; private static final int Buf_size = 8 * 2; // repeat previous bit length 3-6 times (2 bits of repeat count) private static final int REP_3_6 = 16; // repeat a zero length 3-10 times (3 bits of repeat count) private static final int REPZ_3_10 = 17; // repeat a zero length 11-138 times (7 bits of repeat count) private static final int REPZ_11_138 = 18; private static final int MIN_MATCH = 3; private static final int MAX_MATCH = 258; private static final int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); private static final int MAX_BITS = 15; private static final int D_CODES = 30; private static final int BL_CODES = 19; private static final int LENGTH_CODES = 29; private static final int LITERALS = 256; private static final int L_CODES = (LITERALS + 1 + LENGTH_CODES); private static final int HEAP_SIZE = (2 * L_CODES + 1); private static final int END_BLOCK = 256; ZStream strm; // pointer back to this zlib stream int status; // as the name implies byte[] pending_buf; // output still pending int pending_buf_size; // size of pending_buf int pending_out; // next pending byte to output to the stream int pending; // nb of bytes in the pending buffer int wrap = 1; byte data_type; // UNKNOWN, BINARY or ASCII byte method; // STORED (for zip only) or DEFLATED int last_flush; // value of flush param for previous deflate call int w_size; // LZ77 window size (32K by default) int w_bits; // log2(w_size) (8..16) int w_mask; // w_size - 1 byte[] window; // Sliding window. Input bytes are read into the second half of the window, // and move to the first half later to keep a dictionary of at least wSize // bytes. With this organization, matches are limited to a distance of // wSize-MAX_MATCH bytes, but this ensures that IO is always // performed with a length multiple of the block size. Also, it limits // the window size to 64K, which is quite useful on MSDOS. // To do: use the user input buffer as sliding window. int window_size; // Actual size of window: 2*wSize, except when the user input buffer // is directly used as sliding window. short[] prev; // Link to older string with same hash index. To limit the size of this // array to 64K, this link is maintained only for the last 32K strings. // An index in this array is thus a window index modulo 32K. short[] head; // Heads of the hash chains or NIL. int ins_h; // hash index of string to be inserted int hash_size; // number of elements in hash table int hash_bits; // log2(hash_size) int hash_mask; // hash_size-1 // Number of bits by which ins_h must be shifted at each input // step. It must be such that after MIN_MATCH steps, the oldest // byte no longer takes part in the hash key, that is: // hash_shift * MIN_MATCH >= hash_bits int hash_shift; // Window position at the beginning of the current output block. Gets // negative when the window is moved backwards. int block_start; int match_length; // length of best match int prev_match; // previous match int match_available; // set if previous match exists int strstart; // start of string to insert int match_start; // start of matching string int lookahead; // number of valid bytes ahead in window // Length of the best match at previous step. Matches not greater than this // are discarded. This is used in the lazy match evaluation. int prev_length; // To speed up deflation, hash chains are never searched beyond this // length. A higher limit improves compression ratio but degrades the speed. int max_chain_length; // Attempt to find a better match only when the current match is strictly // smaller than this value. This mechanism is used only for compression // levels >= 4. int max_lazy_match; // Insert new strings in the hash table only if the match length is not // greater than this length. This saves time but degrades compression. // max_insert_length is used only for compression levels <= 3. int level; // compression level (1..9) int strategy; // favor or force Huffman coding // Use a faster search when the previous match is longer than this int good_match; // Stop searching when current match exceeds this int nice_match; short[] dyn_ltree; // literal and length tree short[] dyn_dtree; // distance tree short[] bl_tree; // Huffman tree for bit lengths Tree l_desc = new Tree(); // desc for literal tree Tree d_desc = new Tree(); // desc for distance tree Tree bl_desc = new Tree(); // desc for bit length tree // number of codes at each bit length for an optimal tree short[] bl_count = new short[MAX_BITS + 1]; // working area to be used in Tree#gen_codes() short[] next_code = new short[MAX_BITS + 1]; // heap used to build the Huffman trees int[] heap = new int[2 * L_CODES + 1]; int heap_len; // number of elements in the heap int heap_max; // element of largest frequency // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. // The same heap array is used to build all trees. // Depth of each subtree used as tie breaker for trees of equal frequency byte[] depth = new byte[2 * L_CODES + 1]; byte[] l_buf; // index for literals or lengths */ // Size of match buffer for literals/lengths. There are 4 reasons for // limiting lit_bufsize to 64K: // - frequencies can be kept in 16 bit counters // - if compression is not successful for the first block, all input // data is still in the window so we can still emit a stored block even // when input comes from standard input. (This can also be done for // all blocks if lit_bufsize is not greater than 32K.) // - if compression is not successful for a file smaller than 64K, we can // even emit a stored file instead of a stored block (saving 5 bytes). // This is applicable only for zip (not gzip or zlib). // - creating new Huffman trees less frequently may not provide fast // adaptation to changes in the input data statistics. (Take for // example a binary file with poorly compressible code followed by // a highly compressible string table.) Smaller buffer sizes give // fast adaptation but have of course the overhead of transmitting // trees more frequently. // - I can't count above 4 int lit_bufsize; int last_lit; // running index in l_buf // Buffer for distances. To simplify the code, d_buf and l_buf have // the same number of elements. To use different lengths, an extra flag // array would be necessary. int d_buf; // index of pendig_buf int opt_len; // bit length of current block with optimal trees int static_len; // bit length of current block with static trees int matches; // number of string matches in current block int last_eob_len; // bit length of EOB code for last block // Output buffer. bits are inserted starting at the bottom (least // significant bits). short bi_buf; // Number of valid bits in bi_buf. All bits above the last valid bit // are always zero. int bi_valid; GZIPHeader gheader = null; Deflate(ZStream strm) { this.strm = strm; dyn_ltree = new short[HEAP_SIZE * 2]; dyn_dtree = new short[(2 * D_CODES + 1) * 2]; // distance tree bl_tree = new short[(2 * BL_CODES + 1) * 2]; // Huffman tree for bit lengths } void lm_init() { window_size = 2 * w_size; head[hash_size - 1] = 0; for (int i = 0; i < hash_size - 1; i++) { head[i] = 0; } // Set the default configuration parameters: max_lazy_match = Deflate.config_table[level].max_lazy; good_match = Deflate.config_table[level].good_length; nice_match = Deflate.config_table[level].nice_length; max_chain_length = Deflate.config_table[level].max_chain; strstart = 0; block_start = 0; lookahead = 0; match_length = prev_length = MIN_MATCH - 1; match_available = 0; ins_h = 0; } // Initialize the tree data structures for a new zlib stream. void tr_init() { l_desc.dyn_tree = dyn_ltree; l_desc.stat_desc = StaticTree.static_l_desc; d_desc.dyn_tree = dyn_dtree; d_desc.stat_desc = StaticTree.static_d_desc; bl_desc.dyn_tree = bl_tree; bl_desc.stat_desc = StaticTree.static_bl_desc; bi_buf = 0; bi_valid = 0; last_eob_len = 8; // enough lookahead for inflate // Initialize the first block of the first file: init_block(); } void init_block() { // Initialize the trees. for (int i = 0; i < L_CODES; i++) dyn_ltree[i * 2] = 0; for (int i = 0; i < D_CODES; i++) dyn_dtree[i * 2] = 0; for (int i = 0; i < BL_CODES; i++) bl_tree[i * 2] = 0; dyn_ltree[END_BLOCK * 2] = 1; opt_len = static_len = 0; last_lit = matches = 0; } // Restore the heap property by moving down the tree starting at node k, // exchanging a node with the smallest of its two sons if necessary, stopping // when the heap property is re-established (each father smaller than its // two sons). void pqdownheap(short[] tree, // the tree to restore int k // node to move down ) { int v = heap[k]; int j = k << 1; // left son of k while (j <= heap_len) { // Set j to the smallest of the two sons: if (j < heap_len && smaller(tree, heap[j + 1], heap[j], depth)) { j++; } // Exit if v is smaller than both sons if (smaller(tree, v, heap[j], depth)) break; // Exchange v with the smallest son heap[k] = heap[j]; k = j; // And continue down the tree, setting j to the left son of k j <<= 1; } heap[k] = v; } static boolean smaller(short[] tree, int n, int m, byte[] depth) { short tn2 = tree[n * 2]; short tm2 = tree[m * 2]; return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m])); } // Scan a literal or distance tree to determine the frequencies of the codes // in the bit length tree. void scan_tree(short[] tree, // the tree to be scanned int max_code // and its largest code of non zero frequency ) { int n; // iterates over all tree elements int prevlen = -1; // last emitted length int curlen; // length of current code int nextlen = tree[0 * 2 + 1]; // length of next code int count = 0; // repeat count of the current code int max_count = 7; // max repeat count int min_count = 4; // min repeat count if (nextlen == 0) { max_count = 138; min_count = 3; } tree[(max_code + 1) * 2 + 1] = (short) 0xffff; // guard for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1]; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { bl_tree[curlen * 2] += (short) count; } else if (curlen != 0) { if (curlen != prevlen) bl_tree[curlen * 2]++; bl_tree[REP_3_6 * 2]++; } else if (count <= 10) { bl_tree[REPZ_3_10 * 2]++; } else { bl_tree[REPZ_11_138 * 2]++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138; min_count = 3; } else if (curlen == nextlen) { max_count = 6; min_count = 3; } else { max_count = 7; min_count = 4; } } } // Construct the Huffman tree for the bit lengths and return the index in // bl_order of the last bit length code to send. int build_bl_tree() { int max_blindex; // index of last bit length code of non zero freq // Determine the bit length frequencies for literal and distance trees scan_tree(dyn_ltree, l_desc.max_code); scan_tree(dyn_dtree, d_desc.max_code); // Build the bit length tree: bl_desc.build_tree(this); // opt_len now includes the length of the tree representations, except // the lengths of the bit lengths codes and the 5+5+4 bits for the counts. // Determine the number of bit length codes to send. The pkzip format // requires that at least 4 bit length codes be sent. (appnote.txt says // 3 but the actual value used is 4.) for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0) break; } // Update opt_len to include the bit length tree and counts opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; return max_blindex; } // Send the header for a block using dynamic Huffman trees: the counts, the // lengths of the bit length codes, the literal tree and the distance tree. // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. void send_all_trees(int lcodes, int dcodes, int blcodes) { int rank; // index in bl_order send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt send_bits(dcodes - 1, 5); send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt for (rank = 0; rank < blcodes; rank++) { send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3); } send_tree(dyn_ltree, lcodes - 1); // literal tree send_tree(dyn_dtree, dcodes - 1); // distance tree } // Send a literal or distance tree in compressed form, using the codes in // bl_tree. void send_tree(short[] tree, // the tree to be sent int max_code // and its largest code of non zero frequency ) { int n; // iterates over all tree elements int prevlen = -1; // last emitted length int curlen; // length of current code int nextlen = tree[0 * 2 + 1]; // length of next code int count = 0; // repeat count of the current code int max_count = 7; // max repeat count int min_count = 4; // min repeat count if (nextlen == 0) { max_count = 138; min_count = 3; } for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1]; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(curlen, bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(curlen, bl_tree); count--; } send_code(REP_3_6, bl_tree); send_bits(count - 3, 2); } else if (count <= 10) { send_code(REPZ_3_10, bl_tree); send_bits(count - 3, 3); } else { send_code(REPZ_11_138, bl_tree); send_bits(count - 11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138; min_count = 3; } else if (curlen == nextlen) { max_count = 6; min_count = 3; } else { max_count = 7; min_count = 4; } } } // Output a byte on the stream. // IN assertion: there is enough room in pending_buf. final void put_byte(byte[] p, int start, int len) { System.arraycopy(p, start, pending_buf, pending, len); pending += len; } final void put_byte(byte c) { pending_buf[pending++] = c; } final void put_short(int w) { put_byte((byte) (w /* &0xff */)); put_byte((byte) (w >>> 8)); } final void putShortMSB(int b) { put_byte((byte) (b >> 8)); put_byte((byte) (b /* &0xff */)); } final void send_code(int c, short[] tree) { int c2 = c * 2; send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff)); } void send_bits(int value, int length) { int len = length; if (bi_valid > Buf_size - len) { int val = value; // bi_buf |= (val << bi_valid); bi_buf |= (short) ((val << bi_valid) & 0xffff); put_short(bi_buf); bi_buf = (short) (val >>> (Buf_size - bi_valid)); bi_valid += len - Buf_size; } else { // bi_buf |= (value) << bi_valid; bi_buf |= (short) (((value) << bi_valid) & 0xffff); bi_valid += len; } } // Send one empty static block to give enough lookahead for inflate. // This takes 10 bits, of which 7 may remain in the bit buffer. // The current inflate code requires 9 bits of lookahead. If the // last two codes for the previous block (real code plus EOB) were coded // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode // the last real code. In this case we send two empty static blocks instead // of one. (There are no problems if the previous block is stored or fixed.) // To simplify the code, we assume the worst case of last real code encoded // on one bit only. void _tr_align() { send_bits(STATIC_TREES << 1, 3); send_code(END_BLOCK, StaticTree.static_ltree); bi_flush(); // Of the 10 bits for the empty block, we have already sent // (10 - bi_valid) bits. The lookahead for the last real code (before // the EOB of the previous block) was thus at least one plus the length // of the EOB plus what we have just sent of the empty static block. if (1 + last_eob_len + 10 - bi_valid < 9) { send_bits(STATIC_TREES << 1, 3); send_code(END_BLOCK, StaticTree.static_ltree); bi_flush(); } last_eob_len = 7; } // Save the match info and tally the frequency counts. Return true if // the current block must be flushed. boolean _tr_tally(int dist, // distance of matched string int lc // match length-MIN_MATCH or unmatched char (if dist==0) ) { pending_buf[d_buf + last_lit * 2] = (byte) (dist >>> 8); pending_buf[d_buf + last_lit * 2 + 1] = (byte) dist; l_buf[last_lit] = (byte) lc; last_lit++; if (dist == 0) { // lc is the unmatched char dyn_ltree[lc * 2]++; } else { matches++; // Here, lc is the match length - MIN_MATCH dist--; // dist = match distance - 1 dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++; dyn_dtree[Tree.d_code(dist) * 2]++; } if ((last_lit & 0x1fff) == 0 && level > 2) { // Compute an upper bound for the compressed length int out_length = last_lit * 8; int in_length = strstart - block_start; int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (int) dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]); } out_length >>>= 3; if ((matches < (last_lit / 2)) && out_length < in_length / 2) return true; } return (last_lit == lit_bufsize - 1); // We avoid equality with lit_bufsize because of wraparound at 64K // on 16 bit machines and because stored blocks are restricted to // 64K-1 bytes. } // Send the block data compressed using the given Huffman trees void compress_block(short[] ltree, short[] dtree) { int dist; // distance of matched string int lc; // match length or unmatched char (if dist == 0) int lx = 0; // running index in l_buf int code; // the code to send int extra; // number of extra bits to send if (last_lit != 0) { do { dist = ((pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (pending_buf[d_buf + lx * 2 + 1] & 0xff); lc = (l_buf[lx]) & 0xff; lx++; if (dist == 0) { send_code(lc, ltree); // send a literal byte } else { // Here, lc is the match length - MIN_MATCH code = Tree._length_code[lc]; send_code(code + LITERALS + 1, ltree); // send the length code extra = Tree.extra_lbits[code]; if (extra != 0) { lc -= Tree.base_length[code]; send_bits(lc, extra); // send the extra length bits } dist--; // dist is now the match distance - 1 code = Tree.d_code(dist); send_code(code, dtree); // send the distance code extra = Tree.extra_dbits[code]; if (extra != 0) { dist -= Tree.base_dist[code]; send_bits(dist, extra); // send the extra distance bits } } // literal or match pair ? // Check that the overlay between pending_buf and d_buf+l_buf is ok: } while (lx < last_lit); } send_code(END_BLOCK, ltree); last_eob_len = ltree[END_BLOCK * 2 + 1]; } // Set the data type to ASCII or BINARY, using a crude approximation: // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. // IN assertion: the fields freq of dyn_ltree are set and the total of all // frequencies does not exceed 64K (to fit in an int on 16 bit machines). void set_data_type() { int n = 0; int ascii_freq = 0; int bin_freq = 0; while (n < 7) { bin_freq += dyn_ltree[n * 2]; n++; } while (n < 128) { ascii_freq += dyn_ltree[n * 2]; n++; } while (n < LITERALS) { bin_freq += dyn_ltree[n * 2]; n++; } data_type = (byte) (bin_freq > (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); } // Flush the bit buffer, keeping at most 7 bits in it. void bi_flush() { if (bi_valid == 16) { put_short(bi_buf); bi_buf = 0; bi_valid = 0; } else if (bi_valid >= 8) { put_byte((byte) bi_buf); bi_buf >>>= 8; bi_valid -= 8; } } // Flush the bit buffer and align the output on a byte boundary void bi_windup() { if (bi_valid > 8) { put_short(bi_buf); } else if (bi_valid > 0) { put_byte((byte) bi_buf); } bi_buf = 0; bi_valid = 0; } // Copy a stored block, storing first the length and its // one's complement if requested. void copy_block(int buf, // the input data int len, // its length boolean header // true if block header must be written ) { int index = 0; bi_windup(); // align on byte boundary last_eob_len = 8; // enough lookahead for inflate if (header) { put_short((short) len); put_short((short) ~len); } // while(len--!=0) { // put_byte(window[buf+index]); // index++; // } put_byte(window, buf, len); } void flush_block_only(boolean eof) { _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof); block_start = strstart; strm.flush_pending(); } // Copy without compression as much as possible from the input stream, return // the current block state. // This function does not insert new strings in the dictionary since // uncompressible data is probably not useful. This function is used // only for the level=0 compression option. // NOTE: this function should be optimized to avoid extra copying from // window to pending_buf. int deflate_stored(int flush) { // Stored blocks are limited to 0xffff bytes, pending_buf is limited // to pending_buf_size, and each stored block has a 5 byte header: int max_block_size = 0xffff; int max_start; if (max_block_size > pending_buf_size - 5) { max_block_size = pending_buf_size - 5; } // Copy as much as possible from input to output: while (true) { // Fill the window as much as possible: if (lookahead <= 1) { fill_window(); if (lookahead == 0 && flush == Z_NO_FLUSH) return NeedMore; if (lookahead == 0) break; // flush the current block } strstart += lookahead; lookahead = 0; // Emit a stored block if pending_buf will be full: max_start = block_start + max_block_size; if (strstart == 0 || strstart >= max_start) { // strstart == 0 is possible when wraparound on 16-bit machine lookahead = strstart - max_start; strstart = max_start; flush_block_only(false); if (strm.avail_out == 0) return NeedMore; } // Flush if we may have to slide, otherwise block_start may become // negative and the data will be gone: if (strstart - block_start >= w_size - MIN_LOOKAHEAD) { flush_block_only(false); if (strm.avail_out == 0) return NeedMore; } } flush_block_only(flush == Z_FINISH); if (strm.avail_out == 0) return (flush == Z_FINISH) ? FinishStarted : NeedMore; return flush == Z_FINISH ? FinishDone : BlockDone; } // Send a stored block void _tr_stored_block(int buf, // input block int stored_len, // length of input block boolean eof // true if this is the last block for a file ) { send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type copy_block(buf, stored_len, true); // with header } // Determine the best encoding for the current block: dynamic trees, static // trees or store, and output the encoded block to the zip file. void _tr_flush_block(int buf, // input block, or NULL if too old int stored_len, // length of input block boolean eof // true if this is the last block for a file ) { int opt_lenb, static_lenb; // opt_len and static_len in bytes int max_blindex = 0; // index of last bit length code of non zero freq // Build the Huffman trees unless a stored block is forced if (level > 0) { // Check if the file is ascii or binary if (data_type == Z_UNKNOWN) set_data_type(); // Construct the literal and distance trees l_desc.build_tree(this); d_desc.build_tree(this); // At this point, opt_len and static_len are the total bit lengths of // the compressed block data, excluding the tree representations. // Build the bit length tree for the above two trees, and get the index // in bl_order of the last bit length code to send. max_blindex = build_bl_tree(); // Determine the best encoding. Compute first the block length in bytes opt_lenb = (opt_len + 3 + 7) >>> 3; static_lenb = (static_len + 3 + 7) >>> 3; if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { opt_lenb = static_lenb = stored_len + 5; // force a stored block } if (stored_len + 4 <= opt_lenb && buf != -1) { // 4: two words for the lengths // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. // Otherwise we can't have processed more than WSIZE input bytes since // the last block flush, because compression would have been // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to // transform a block into a stored block. _tr_stored_block(buf, stored_len, eof); } else if (static_lenb == opt_lenb) { send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3); compress_block(StaticTree.static_ltree, StaticTree.static_dtree); } else { send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3); send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1); compress_block(dyn_ltree, dyn_dtree); } // The above check is made mod 2^32, for files larger than 512 MB // and uLong implemented on 32 bits. init_block(); if (eof) { bi_windup(); } } // Fill the window when the lookahead becomes insufficient. // Updates strstart and lookahead. // // IN assertion: lookahead < MIN_LOOKAHEAD // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD // At least one byte has been read, or avail_in == 0; reads are // performed for at least two bytes (required for the zip translate_eol // option -- not supported here). void fill_window() { int n, m; int p; int more; // Amount of free space at the end of the window. do { more = (window_size - lookahead - strstart); // Deal with !@#$% 64K limit: if (more == 0 && strstart == 0 && lookahead == 0) { more = w_size; } else if (more == -1) { // Very unlikely, but possible on 16 bit machine if strstart == 0 // and lookahead == 1 (input done one byte at time) more--; // If the window is almost full and there is insufficient lookahead, // move the upper half to the lower one to make room in the upper half. } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) { System.arraycopy(window, w_size, window, 0, w_size); match_start -= w_size; strstart -= w_size; // we now have strstart >= MAX_DIST block_start -= w_size; // Slide the hash table (could be avoided with 32 bit values // at the expense of memory usage). We slide even when level == 0 // to keep the hash table consistent if we switch back to level > 0 // later. (Using level 0 permanently is not an optimal usage of // zlib, so we don't care about this pathological case.) n = hash_size; p = n; do { m = (head[--p] & 0xffff); head[p] = (m >= w_size ? (short) (m - w_size) : 0); } while (--n != 0); n = w_size; p = n; do { m = (prev[--p] & 0xffff); prev[p] = (m >= w_size ? (short) (m - w_size) : 0); // If n is not on any hash chain, prev[n] is garbage but // its value will never be used. } while (--n != 0); more += w_size; } if (strm.avail_in == 0) return; // If there was no sliding: // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && // more == window_size - lookahead - strstart // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) // => more >= window_size - 2*WSIZE + 2 // In the BIG_MEM or MMAP case (not yet supported), // window_size == input_size + MIN_LOOKAHEAD && // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. // Otherwise, window_size == 2*WSIZE so more >= 2. // If there was sliding, more >= WSIZE. So in all cases, more >= 2. n = strm.read_buf(window, strstart + lookahead, more); lookahead += n; // Initialize the hash value now that we have some input: if (lookahead >= MIN_MATCH) { ins_h = window[strstart] & 0xff; ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; } // If the whole input has less than MIN_MATCH bytes, ins_h is garbage, // but this is not important since only literal bytes will be emitted. } while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0); } // Compress as much as possible from the input stream, return the current // block state. // This function does not perform lazy evaluation of matches and inserts // new strings in the dictionary only for unmatched strings or for short // matches. It is used only for the fast compression options. int deflate_fast(int flush) { // short hash_head = 0; // head of the hash chain int hash_head = 0; // head of the hash chain boolean bflush; // set if current block must be flushed while (true) { // Make sure that we always have enough lookahead, except // at the end of the input file. We need MAX_MATCH bytes // for the next match, plus MIN_MATCH bytes to insert the // string following the next match. if (lookahead < MIN_LOOKAHEAD) { fill_window(); if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return NeedMore; } if (lookahead == 0) break; // flush the current block } // Insert the string window[strstart .. strstart+2] in the // dictionary, and set hash_head to the head of the hash chain: if (lookahead >= MIN_MATCH) { ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; // prev[strstart&w_mask]=hash_head=head[ins_h]; hash_head = (head[ins_h] & 0xffff); prev[strstart & w_mask] = head[ins_h]; head[ins_h] = (short) strstart; } // Find the longest match, discarding those <= prev_length. // At this point we have always match_length < MIN_MATCH if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) { // To simplify the code, we prevent matches with the string // of window index 0 (in particular we have to avoid a match // of the string with itself at the start of the input file). if (strategy != Z_HUFFMAN_ONLY) { match_length = longest_match(hash_head); } // longest_match() sets match_start } if (match_length >= MIN_MATCH) { // check_match(strstart, match_start, match_length); bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH); lookahead -= match_length; // Insert new strings in the hash table only if the match length // is not too large. This saves time but degrades compression. if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) { match_length--; // string at strstart already in hash table do { strstart++; ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; // prev[strstart&w_mask]=hash_head=head[ins_h]; hash_head = (head[ins_h] & 0xffff); prev[strstart & w_mask] = head[ins_h]; head[ins_h] = (short) strstart; // strstart never exceeds WSIZE-MAX_MATCH, so there are // always MIN_MATCH bytes ahead. } while (--match_length != 0); strstart++; } else { strstart += match_length; match_length = 0; ins_h = window[strstart] & 0xff; ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; // If lookahead < MIN_MATCH, ins_h is garbage, but it does not // matter since it will be recomputed at next deflate call. } } else { // No match, output a literal byte bflush = _tr_tally(0, window[strstart] & 0xff); lookahead--; strstart++; } if (bflush) { flush_block_only(false); if (strm.avail_out == 0) return NeedMore; } } flush_block_only(flush == Z_FINISH); if (strm.avail_out == 0) { if (flush == Z_FINISH) return FinishStarted; else return NeedMore; } return flush == Z_FINISH ? FinishDone : BlockDone; } // Same as above, but achieves better compression. We use a lazy // evaluation for matches: a match is finally adopted only if there is // no better match at the next window position. int deflate_slow(int flush) { // short hash_head = 0; // head of hash chain int hash_head = 0; // head of hash chain boolean bflush; // set if current block must be flushed // Process the input block. while (true) { // Make sure that we always have enough lookahead, except // at the end of the input file. We need MAX_MATCH bytes // for the next match, plus MIN_MATCH bytes to insert the // string following the next match. if (lookahead < MIN_LOOKAHEAD) { fill_window(); if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return NeedMore; } if (lookahead == 0) break; // flush the current block } // Insert the string window[strstart .. strstart+2] in the // dictionary, and set hash_head to the head of the hash chain: if (lookahead >= MIN_MATCH) { ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; // prev[strstart&w_mask]=hash_head=head[ins_h]; hash_head = (head[ins_h] & 0xffff); prev[strstart & w_mask] = head[ins_h]; head[ins_h] = (short) strstart; } // Find the longest match, discarding those <= prev_length. prev_length = match_length; prev_match = match_start; match_length = MIN_MATCH - 1; if (hash_head != 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) { // To simplify the code, we prevent matches with the string // of window index 0 (in particular we have to avoid a match // of the string with itself at the start of the input file). if (strategy != Z_HUFFMAN_ONLY) { match_length = longest_match(hash_head); } // longest_match() sets match_start if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) { // If prev_match is also MIN_MATCH, match_start is garbage // but we will ignore the current match anyway. match_length = MIN_MATCH - 1; } } // If there was a match at the previous step and the current // match is not better, output the previous match: if (prev_length >= MIN_MATCH && match_length <= prev_length) { int max_insert = strstart + lookahead - MIN_MATCH; // Do not insert strings in hash table beyond this. // check_match(strstart-1, prev_match, prev_length); bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); // Insert in hash table all strings up to the end of the match. // strstart-1 and strstart are already inserted. If there is not // enough lookahead, the last two strings are not inserted in // the hash table. lookahead -= prev_length - 1; prev_length -= 2; do { if (++strstart <= max_insert) { ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; // prev[strstart&w_mask]=hash_head=head[ins_h]; hash_head = (head[ins_h] & 0xffff); prev[strstart & w_mask] = head[ins_h]; head[ins_h] = (short) strstart; } } while (--prev_length != 0); match_available = 0; match_length = MIN_MATCH - 1; strstart++; if (bflush) { flush_block_only(false); if (strm.avail_out == 0) return NeedMore; } } else if (match_available != 0) { // If there was no match at the previous position, output a // single literal. If there was a match but the current match // is longer, truncate the previous match to a single literal. bflush = _tr_tally(0, window[strstart - 1] & 0xff); if (bflush) { flush_block_only(false); } strstart++; lookahead--; if (strm.avail_out == 0) return NeedMore; } else { // There is no previous match to compare with, wait for // the next step to decide. match_available = 1; strstart++; lookahead--; } } if (match_available != 0) { bflush = _tr_tally(0, window[strstart - 1] & 0xff); match_available = 0; } flush_block_only(flush == Z_FINISH); if (strm.avail_out == 0) { if (flush == Z_FINISH) return FinishStarted; else return NeedMore; } return flush == Z_FINISH ? FinishDone : BlockDone; } int longest_match(int cur_match) { int chain_length = max_chain_length; // max hash chain length int scan = strstart; // current string int match; // matched string int len; // length of current match int best_len = prev_length; // best match length so far int limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0; int nice_match = this.nice_match; // Stop when cur_match becomes <= limit. To simplify the code, // we prevent matches with the string of window index 0. int wmask = w_mask; int strend = strstart + MAX_MATCH; byte scan_end1 = window[scan + best_len - 1]; byte scan_end = window[scan + best_len]; // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. // It is easy to get rid of this optimization if necessary. // Do not waste too much time if we already have a good match: if (prev_length >= good_match) { chain_length >>= 2; } // Do not look for matches beyond the end of the input. This is necessary // to make deflate deterministic. if (nice_match > lookahead) nice_match = lookahead; do { match = cur_match; // Skip to next match if the match length cannot increase // or if the match length is less than 2: if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan] || window[++match] != window[scan + 1]) continue; // The check at best_len-1 can be removed because it will be made // again later. (This heuristic is not always a win.) // It is not necessary to compare scan[2] and match[2] since they // are always equal when the other bytes match, given that // the hash keys are equal and that HASH_BITS >= 8. scan += 2; match++; // We check for insufficient lookahead only every 8th comparison; // the 256th check will be made at strstart+258. do { } while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend); len = MAX_MATCH - strend - scan; scan = strend - MAX_MATCH; if (len > best_len) { match_start = cur_match; best_len = len; if (len >= nice_match) break; scan_end1 = window[scan + best_len - 1]; scan_end = window[scan + best_len]; } } while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0); if (best_len <= lookahead) return best_len; return lookahead; } int deflateInit(int level, int bits, int memlevel) { return deflateInit(level, Z_DEFLATED, bits, memlevel, Z_DEFAULT_STRATEGY); } int deflateInit(int level, int bits) { return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); } int deflateInit(int level) { return deflateInit(level, MAX_WBITS); } private int deflateInit(int level, int method, int windowBits, int memLevel, int strategy) { int wrap = 1; // byte[] my_version=ZLIB_VERSION; // // if (version == null || version[0] != my_version[0] // || stream_size != sizeof(z_stream)) { // return Z_VERSION_ERROR; // } strm.msg = null; if (level == Z_DEFAULT_COMPRESSION) level = 6; if (windowBits < 0) { // undocumented feature: suppress zlib header wrap = 0; windowBits = -windowBits; } else if (windowBits > 15) { wrap = 2; windowBits -= 16; strm.adler = new CRC32(); } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } strm.dstate = this; this.wrap = wrap; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; hash_bits = memLevel + 7; hash_size = 1 << hash_bits; hash_mask = hash_size - 1; hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); window = new byte[w_size * 2]; prev = new short[w_size]; head = new short[hash_size]; lit_bufsize = 1 << (memLevel + 6); // 16K elements by default // We overlay pending_buf and d_buf+l_buf. This works since the average // output size for (length,distance) codes is <= 24 bits. pending_buf = new byte[lit_bufsize * 3]; pending_buf_size = lit_bufsize * 3; d_buf = lit_bufsize; l_buf = new byte[lit_bufsize]; this.level = level; this.strategy = strategy; this.method = (byte) method; return deflateReset(); } int deflateReset() { strm.total_in = strm.total_out = 0; strm.msg = null; // strm.data_type = Z_UNKNOWN; pending = 0; pending_out = 0; if (wrap < 0) { wrap = -wrap; } status = (wrap == 0) ? BUSY_STATE : INIT_STATE; strm.adler.reset(); last_flush = Z_NO_FLUSH; tr_init(); lm_init(); return Z_OK; } int deflateEnd() { if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } // Deallocate in reverse order of allocations: pending_buf = null; l_buf = null; head = null; prev = null; window = null; // free // dstate=null; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } int deflateParams(int _level, int _strategy) { int err = Z_OK; if (_level == Z_DEFAULT_COMPRESSION) { _level = 6; } if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } if (config_table[level].func != config_table[_level].func && strm.total_in != 0) { // Flush the last buffer: err = strm.deflate(Z_PARTIAL_FLUSH); } if (level != _level) { level = _level; max_lazy_match = config_table[level].max_lazy; good_match = config_table[level].good_length; nice_match = config_table[level].nice_length; max_chain_length = config_table[level].max_chain; } strategy = _strategy; return err; } int deflateSetDictionary(byte[] dictionary, int dictLength) { int length = dictLength; int index = 0; if (dictionary == null || status != INIT_STATE) return Z_STREAM_ERROR; strm.adler.update(dictionary, 0, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > w_size - MIN_LOOKAHEAD) { length = w_size - MIN_LOOKAHEAD; index = dictLength - length; // use the tail of the dictionary } System.arraycopy(dictionary, index, window, 0, length); strstart = length; block_start = length; // Insert all strings in the hash table (except for the last two bytes). // s->lookahead stays null, so s->ins_h will be recomputed at the next // call of fill_window. ins_h = window[0] & 0xff; ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask; for (int n = 0; n <= length - MIN_MATCH; n++) { ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; prev[n & w_mask] = head[ins_h]; head[ins_h] = (short) n; } return Z_OK; } int deflate(int flush) { int old_flush; if (flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } if (strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == FINISH_STATE && flush != Z_FINISH)) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)]; return Z_STREAM_ERROR; } if (strm.avail_out == 0) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)]; return Z_BUF_ERROR; } old_flush = last_flush; last_flush = flush; // Write the zlib header if (status == INIT_STATE) { if (wrap == 2) { getGZIPHeader().put(this); status = BUSY_STATE; strm.adler.reset(); } else { int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8; int level_flags = ((level - 1) & 0xff) >> 1; if (level_flags > 3) level_flags = 3; header |= (level_flags << 6); if (strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); status = BUSY_STATE; putShortMSB(header); // Save the adler32 of the preset dictionary: if (strstart != 0) { long adler = strm.adler.getValue(); putShortMSB((int) (adler >>> 16)); putShortMSB((int) (adler & 0xffff)); } strm.adler.reset(); } } // Flush as much pending output as possible if (pending != 0) { strm.flush_pending(); if (strm.avail_out == 0) { // Since avail_out is 0, deflate will be called again with // more output space, but possibly with both pending and // avail_in equal to zero. There won't be anything to do, // but this is not an error situation so make sure we // return OK instead of BUF_ERROR at next call of deflate: last_flush = -1; return Z_OK; } // Make sure there is something to do and avoid duplicate consecutive // flushes. For repeated and useless calls with Z_FINISH, we keep // returning Z_STREAM_END instead of Z_BUFF_ERROR. } else if (strm.avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)]; return Z_BUF_ERROR; } // User must not provide more input after the first FINISH: if (status == FINISH_STATE && strm.avail_in != 0) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)]; return Z_BUF_ERROR; } // Start a new block or continue the current one. if (strm.avail_in != 0 || lookahead != 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) { int bstate = -1; switch (config_table[level].func) { case STORED: bstate = deflate_stored(flush); break; case FAST: bstate = deflate_fast(flush); break; case SLOW: bstate = deflate_slow(flush); break; default: } if (bstate == FinishStarted || bstate == FinishDone) { status = FINISH_STATE; } if (bstate == NeedMore || bstate == FinishStarted) { if (strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR next call, see above } return Z_OK; // If flush != Z_NO_FLUSH && avail_out == 0, the next call // of deflate should use the same flush parameter to make sure // that the flush is complete. So we don't have to output an // empty block here, this will be done at next call. This also // ensures that for a very small output buffer, we emit at most // one empty block. } if (bstate == BlockDone) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(); } else { // FULL_FLUSH or SYNC_FLUSH _tr_stored_block(0, 0, false); // For a full flush, this empty block will be recognized // as a special marker by inflate_sync(). if (flush == Z_FULL_FLUSH) { // state.head[s.hash_size-1]=0; for (int i = 0; i < hash_size /*-1*/; i++) // forget history head[i] = 0; } } strm.flush_pending(); if (strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR at next call, see above return Z_OK; } } } if (flush != Z_FINISH) return Z_OK; if (wrap <= 0) return Z_STREAM_END; if (wrap == 2) { long adler = strm.adler.getValue(); put_byte((byte) (adler & 0xff)); put_byte((byte) ((adler >> 8) & 0xff)); put_byte((byte) ((adler >> 16) & 0xff)); put_byte((byte) ((adler >> 24) & 0xff)); put_byte((byte) (strm.total_in & 0xff)); put_byte((byte) ((strm.total_in >> 8) & 0xff)); put_byte((byte) ((strm.total_in >> 16) & 0xff)); put_byte((byte) ((strm.total_in >> 24) & 0xff)); getGZIPHeader().setCRC(adler); } else { // Write the zlib trailer (adler32) long adler = strm.adler.getValue(); putShortMSB((int) (adler >>> 16)); putShortMSB((int) (adler & 0xffff)); } strm.flush_pending(); // If avail_out is zero, the application will call deflate again // to flush the rest. if (wrap > 0) wrap = -wrap; // write the trailer only once! return pending != 0 ? Z_OK : Z_STREAM_END; } static int deflateCopy(ZStream dest, ZStream src) { if (src.dstate == null) { return Z_STREAM_ERROR; } if (src.next_in != null) { dest.next_in = new byte[src.next_in.length]; System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); } dest.next_in_index = src.next_in_index; dest.avail_in = src.avail_in; dest.total_in = src.total_in; if (src.next_out != null) { dest.next_out = new byte[src.next_out.length]; System.arraycopy(src.next_out, 0, dest.next_out, 0, src.next_out.length); } dest.next_out_index = src.next_out_index; dest.avail_out = src.avail_out; dest.total_out = src.total_out; dest.msg = src.msg; dest.data_type = src.data_type; dest.adler = src.adler.copy(); try { dest.dstate = (Deflate) src.dstate.clone(); dest.dstate.strm = dest; } catch (CloneNotSupportedException e) { // } return Z_OK; } @Override public Object clone() throws CloneNotSupportedException { Deflate dest = (Deflate) super.clone(); dest.pending_buf = dup(dest.pending_buf); dest.l_buf = dup(dest.l_buf); dest.window = dup(dest.window); dest.prev = dup(dest.prev); dest.head = dup(dest.head); dest.dyn_ltree = dup(dest.dyn_ltree); dest.dyn_dtree = dup(dest.dyn_dtree); dest.bl_tree = dup(dest.bl_tree); dest.bl_count = dup(dest.bl_count); dest.next_code = dup(dest.next_code); dest.heap = dup(dest.heap); dest.depth = dup(dest.depth); dest.l_desc.dyn_tree = dest.dyn_ltree; dest.d_desc.dyn_tree = dest.dyn_dtree; dest.bl_desc.dyn_tree = dest.bl_tree; /* * dest.l_desc.stat_desc = StaticTree.static_l_desc; dest.d_desc.stat_desc = * StaticTree.static_d_desc; dest.bl_desc.stat_desc = StaticTree.static_bl_desc; */ if (dest.gheader != null) { dest.gheader = (GZIPHeader) dest.gheader.clone(); } return dest; } private byte[] dup(byte[] buf) { byte[] foo = new byte[buf.length]; System.arraycopy(buf, 0, foo, 0, foo.length); return foo; } private short[] dup(short[] buf) { short[] foo = new short[buf.length]; System.arraycopy(buf, 0, foo, 0, foo.length); return foo; } private int[] dup(int[] buf) { int[] foo = new int[buf.length]; System.arraycopy(buf, 0, foo, 0, foo.length); return foo; } synchronized GZIPHeader getGZIPHeader() { if (gheader == null) { gheader = new GZIPHeader(); } return gheader; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Deflater.java000066400000000000000000000124341465436372100256260ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class Deflater extends ZStream { private static final int MAX_WBITS = 15; // 32K LZ77 window private static final int DEF_WBITS = MAX_WBITS; private static final int Z_NO_FLUSH = 0; private static final int Z_PARTIAL_FLUSH = 1; private static final int Z_SYNC_FLUSH = 2; private static final int Z_FULL_FLUSH = 3; private static final int Z_FINISH = 4; private static final int MAX_MEM_LEVEL = 9; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; private boolean finished = false; Deflater() { super(); } Deflater(int level) throws GZIPException { this(level, MAX_WBITS); } Deflater(int level, boolean nowrap) throws GZIPException { this(level, MAX_WBITS, nowrap); } Deflater(int level, int bits) throws GZIPException { this(level, bits, false); } Deflater(int level, int bits, boolean nowrap) throws GZIPException { super(); int ret = init(level, bits, nowrap); if (ret != Z_OK) throw new GZIPException(ret + ": " + msg); } Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { super(); int ret = init(level, bits, memlevel, wrapperType); if (ret != Z_OK) throw new GZIPException(ret + ": " + msg); } Deflater(int level, int bits, int memlevel) throws GZIPException { super(); int ret = init(level, bits, memlevel); if (ret != Z_OK) throw new GZIPException(ret + ": " + msg); } int init(int level) { return init(level, MAX_WBITS); } int init(int level, boolean nowrap) { return init(level, MAX_WBITS, nowrap); } int init(int level, int bits) { return init(level, bits, false); } int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) { if (bits < 9 || bits > 15) { return Z_STREAM_ERROR; } if (wrapperType == JZlib.W_NONE) { bits *= -1; } else if (wrapperType == JZlib.W_GZIP) { bits += 16; } else if (wrapperType == JZlib.W_ANY) { return Z_STREAM_ERROR; } else if (wrapperType == JZlib.W_ZLIB) { } return init(level, bits, memlevel); } int init(int level, int bits, int memlevel) { finished = false; dstate = new Deflate(this); return dstate.deflateInit(level, bits, memlevel); } int init(int level, int bits, boolean nowrap) { finished = false; dstate = new Deflate(this); return dstate.deflateInit(level, nowrap ? -bits : bits); } @Override int deflate(int flush) { if (dstate == null) { return Z_STREAM_ERROR; } int ret = dstate.deflate(flush); if (ret == Z_STREAM_END) finished = true; return ret; } @Override int end() { finished = true; if (dstate == null) return Z_STREAM_ERROR; int ret = dstate.deflateEnd(); dstate = null; free(); return ret; } int params(int level, int strategy) { if (dstate == null) return Z_STREAM_ERROR; return dstate.deflateParams(level, strategy); } int setDictionary(byte[] dictionary, int dictLength) { if (dstate == null) return Z_STREAM_ERROR; return dstate.deflateSetDictionary(dictionary, dictLength); } @Override boolean finished() { return finished; } int copy(Deflater src) { this.finished = src.finished; return Deflate.deflateCopy(this, src); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java000066400000000000000000000121171465436372100302210ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jzlib; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; final class DeflaterOutputStream extends FilterOutputStream { protected final Deflater deflater; protected byte[] buffer; private boolean closed = false; private boolean syncFlush = false; private final byte[] buf1 = new byte[1]; protected boolean mydeflater = false; private boolean close_out = true; protected static final int DEFAULT_BUFSIZE = 512; DeflaterOutputStream(OutputStream out) throws IOException { this(out, new Deflater(JZlib.Z_DEFAULT_COMPRESSION), DEFAULT_BUFSIZE, true); mydeflater = true; } DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { this(out, def, DEFAULT_BUFSIZE, true); } DeflaterOutputStream(OutputStream out, Deflater deflater, int size) throws IOException { this(out, deflater, size, true); } DeflaterOutputStream(OutputStream out, Deflater deflater, int size, boolean close_out) throws IOException { super(out); if (out == null || deflater == null) { throw new NullPointerException(); } else if (size <= 0) { throw new IllegalArgumentException("buffer size must be greater than 0"); } this.deflater = deflater; buffer = new byte[size]; this.close_out = close_out; } @Override public void write(int b) throws IOException { buf1[0] = (byte) (b & 0xff); write(buf1, 0, 1); } @Override public void write(byte[] b, int off, int len) throws IOException { if (deflater.finished()) { throw new IOException("finished"); } else if (off < 0 || len < 0 || off + len > b.length) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } else { int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; deflater.setInput(b, off, len, true); while (deflater.avail_in > 0) { int err = deflate(flush); if (err == JZlib.Z_STREAM_END) break; } } } void finish() throws IOException { while (!deflater.finished()) { deflate(JZlib.Z_FINISH); } } @Override public void close() throws IOException { if (!closed) { finish(); if (mydeflater) { deflater.end(); } if (close_out) out.close(); closed = true; } } @SuppressWarnings("fallthrough") protected int deflate(int flush) throws IOException { deflater.setOutput(buffer, 0, buffer.length); int err = deflater.deflate(flush); switch (err) { case JZlib.Z_OK: case JZlib.Z_STREAM_END: break; case JZlib.Z_BUF_ERROR: if (deflater.avail_in <= 0 && flush != JZlib.Z_FINISH) { // flush() without any data break; } default: throw new IOException( "failed to deflate: error=" + err + " avail_out=" + deflater.avail_out); } int len = deflater.next_out_index; if (len > 0) { out.write(buffer, 0, len); } return err; } @Override public void flush() throws IOException { if (syncFlush && !deflater.finished()) { while (true) { int err = deflate(JZlib.Z_SYNC_FLUSH); if (deflater.next_out_index < buffer.length) break; if (err == JZlib.Z_STREAM_END) break; } } out.flush(); } long getTotalIn() { return deflater.getTotalIn(); } long getTotalOut() { return deflater.getTotalOut(); } void setSyncFlush(boolean syncFlush) { this.syncFlush = syncFlush; } boolean getSyncFlush() { return this.syncFlush; } Deflater getDeflater() { return deflater; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java000066400000000000000000000035771465436372100265400ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; import java.io.IOException; final class GZIPException extends IOException { private static final long serialVersionUID = -1L; GZIPException() { super(); } GZIPException(String s) { super(s); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java000066400000000000000000000125271465436372100257650ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; import java.nio.charset.StandardCharsets; /** * @see http://www.ietf.org/rfc/rfc1952.txt */ final class GZIPHeader implements Cloneable { static final byte OS_MSDOS = (byte) 0x00; static final byte OS_AMIGA = (byte) 0x01; static final byte OS_VMS = (byte) 0x02; static final byte OS_UNIX = (byte) 0x03; static final byte OS_ATARI = (byte) 0x05; static final byte OS_OS2 = (byte) 0x06; static final byte OS_MACOS = (byte) 0x07; static final byte OS_TOPS20 = (byte) 0x0a; static final byte OS_WIN32 = (byte) 0x0b; static final byte OS_VMCMS = (byte) 0x04; static final byte OS_ZSYSTEM = (byte) 0x08; static final byte OS_CPM = (byte) 0x09; static final byte OS_QDOS = (byte) 0x0c; static final byte OS_RISCOS = (byte) 0x0d; static final byte OS_UNKNOWN = (byte) 0xff; boolean text = false; private boolean fhcrc = false; int xflags; int os = 255; byte[] extra; byte[] name; byte[] comment; int hcrc; long crc; boolean done = false; long mtime = 0; void setModifiedTime(long mtime) { this.mtime = mtime; } long getModifiedTime() { return mtime; } void setOS(int os) { if ((0 <= os && os <= 13) || os == 255) this.os = os; else throw new IllegalArgumentException("os: " + os); } int getOS() { return os; } void setName(String name) { this.name = name.getBytes(StandardCharsets.ISO_8859_1); } String getName() { if (name == null) return ""; return new String(name, StandardCharsets.ISO_8859_1); } void setComment(String comment) { this.comment = comment.getBytes(StandardCharsets.ISO_8859_1); } String getComment() { if (comment == null) return ""; return new String(comment, StandardCharsets.ISO_8859_1); } void setCRC(long crc) { this.crc = crc; } long getCRC() { return crc; } void put(Deflate d) { int flag = 0; if (text) { flag |= 1; // FTEXT } if (fhcrc) { flag |= 2; // FHCRC } if (extra != null) { flag |= 4; // FEXTRA } if (name != null) { flag |= 8; // FNAME } if (comment != null) { flag |= 16; // FCOMMENT } int xfl = 0; if (d.level == JZlib.Z_BEST_SPEED) { xfl |= 4; } else if (d.level == JZlib.Z_BEST_COMPRESSION) { xfl |= 2; } d.put_short((short) 0x8b1f); // ID1 ID2 d.put_byte((byte) 8); // CM(Compression Method) d.put_byte((byte) flag); d.put_byte((byte) mtime); d.put_byte((byte) (mtime >> 8)); d.put_byte((byte) (mtime >> 16)); d.put_byte((byte) (mtime >> 24)); d.put_byte((byte) xfl); d.put_byte((byte) os); if (extra != null) { d.put_byte((byte) extra.length); d.put_byte((byte) (extra.length >> 8)); d.put_byte(extra, 0, extra.length); } if (name != null) { d.put_byte(name, 0, name.length); d.put_byte((byte) 0); } if (comment != null) { d.put_byte(comment, 0, comment.length); d.put_byte((byte) 0); } } @Override public Object clone() throws CloneNotSupportedException { GZIPHeader gheader = (GZIPHeader) super.clone(); byte[] tmp; if (gheader.extra != null) { tmp = new byte[gheader.extra.length]; System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); gheader.extra = tmp; } if (gheader.name != null) { tmp = new byte[gheader.name.length]; System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); gheader.name = tmp; } if (gheader.comment != null) { tmp = new byte[gheader.comment.length]; System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); gheader.comment = tmp; } return gheader; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java000066400000000000000000000452151465436372100257550ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class InfBlocks { private static final int MANY = 1440; // And'ing with mask[n] masks the lower n bits private static final int[] inflate_mask = {0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff}; // Table for deflate from PKZIP's appnote.txt. static final int[] border = { // Order of the bit length code lengths 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; private static final int TYPE = 0; // get type bits (3, including end bit) private static final int LENS = 1; // get lengths for stored private static final int STORED = 2; // processing stored block private static final int TABLE = 3; // get table lengths private static final int BTREE = 4; // get bit lengths tree for a dynamic block private static final int DTREE = 5; // get length, distance trees for a dynamic block private static final int CODES = 6; // processing fixed or dynamic block private static final int DRY = 7; // output remaining window bytes private static final int DONE = 8; // finished last block, done private static final int BAD = 9; // ot a data error--stuck here int mode; // current inflate_block mode int left; // if STORED, bytes left to copy int table; // table lengths (14 bits) int index; // index into blens (or border) int[] blens; // bit lengths of codes int[] bb = new int[1]; // bit length tree depth int[] tb = new int[1]; // bit length decoding tree int[] bl = new int[1]; int[] bd = new int[1]; int[][] tl = new int[1][]; int[][] td = new int[1][]; int[] tli = new int[1]; // tl_index int[] tdi = new int[1]; // td_index private final InfCodes codes; // if CODES, current state int last; // true if this block is the last block // mode independent information int bitk; // bits in bit buffer int bitb; // bit buffer int[] hufts; // single malloc for tree space byte[] window; // sliding window int end; // one byte after sliding window int read; // window read pointer int write; // window write pointer private boolean check; private final InfTree inftree = new InfTree(); private final ZStream z; InfBlocks(ZStream z, int w) { this.z = z; this.codes = new InfCodes(this.z, this); hufts = new int[MANY * 3]; window = new byte[w]; end = w; this.check = (z.istate.wrap == 0) ? false : true; mode = TYPE; reset(); } void reset() { if (mode == BTREE || mode == DTREE) { } if (mode == CODES) { codes.free(z); } mode = TYPE; bitk = 0; bitb = 0; read = write = 0; if (check) { z.adler.reset(); } } @SuppressWarnings("fallthrough") int proc(int r) { int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer // copy input/output information to locals (UPDATE macro restores) { p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk; } { q = write; m = (q < read ? read - q - 1 : end - q); } // process input based on current state while (true) { switch (mode) { case TYPE: while (k < (3)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & 7; last = t & 1; switch (t >>> 1) { case 0: // stored { b >>>= (3); k -= (3); } t = k & 7; // go to byte boundary { b >>>= (t); k -= (t); } mode = LENS; // get length of stored block break; case 1: // fixed InfTree.inflate_trees_fixed(bl, bd, tl, td, z); codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); { b >>>= (3); k -= (3); } mode = CODES; break; case 2: // dynamic { b >>>= (3); k -= (3); } mode = TABLE; break; case 3: // illegal { b >>>= (3); k -= (3); } mode = BAD; z.msg = "invalid block type"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } break; case LENS: while (k < (32)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) { mode = BAD; z.msg = "invalid stored block lengths"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } left = (b & 0xffff); b = k = 0; // dump bits mode = left != 0 ? STORED : (last != 0 ? DRY : TYPE); break; case STORED: if (n == 0) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } if (m == 0) { if (q == end && read != 0) { q = 0; m = (q < read ? read - q - 1 : end - q); } if (m == 0) { write = q; r = inflate_flush(r); q = write; m = (q < read ? read - q - 1 : end - q); if (q == end && read != 0) { q = 0; m = (q < read ? read - q - 1 : end - q); } if (m == 0) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } } } r = Z_OK; t = left; if (t > n) t = n; if (t > m) t = m; System.arraycopy(z.next_in, p, window, q, t); p += t; n -= t; q += t; m -= t; if ((left -= t) != 0) break; mode = last != 0 ? DRY : TYPE; break; case TABLE: while (k < (14)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } table = t = (b & 0x3fff); if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { mode = BAD; z.msg = "too many length or distance symbols"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if (blens == null || blens.length < t) { blens = new int[t]; } else { for (int i = 0; i < t; i++) { blens[i] = 0; } } { b >>>= (14); k -= (14); } index = 0; mode = BTREE; case BTREE: while (index < 4 + (table >>> 10)) { while (k < (3)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } blens[border[index++]] = b & 7; { b >>>= (3); k -= (3); } } while (index < 19) { blens[border[index++]] = 0; } bb[0] = 7; t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); if (t != Z_OK) { r = t; if (r == Z_DATA_ERROR) { blens = null; mode = BAD; } bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } index = 0; mode = DTREE; case DTREE: while (true) { t = table; if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { break; } int[] h; int i, j, c; t = bb[0]; while (k < (t)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } if (tb[0] == -1) { // System.err.println("null..."); } t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1]; c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2]; if (c < 16) { b >>>= (t); k -= (t); blens[index++] = c; } else { // c == 16..18 i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; while (k < (t + i)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } ; n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } b >>>= (t); k -= (t); j += (b & inflate_mask[i]); b >>>= (i); k -= (i); i = index; t = table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { blens = null; mode = BAD; z.msg = "invalid bit length repeat"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } c = c == 16 ? blens[i - 1] : 0; do { blens[i++] = c; } while (--j != 0); index = i; } } tb[0] = -1; { bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tli, tdi, hufts, z); if (t != Z_OK) { if (t == Z_DATA_ERROR) { blens = null; mode = BAD; } r = t; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); } mode = CODES; case CODES: bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; if ((r = codes.proc(r)) != Z_STREAM_END) { return inflate_flush(r); } r = Z_OK; codes.free(z); p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk; q = write; m = (q < read ? read - q - 1 : end - q); if (last == 0) { mode = TYPE; break; } mode = DRY; case DRY: write = q; r = inflate_flush(r); q = write; m = (q < read ? read - q - 1 : end - q); if (read != write) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } mode = DONE; case DONE: r = Z_STREAM_END; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); case BAD: r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); default: r = Z_STREAM_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return inflate_flush(r); } } } void free() { reset(); window = null; hufts = null; // ZFREE(z, s); } void set_dictionary(byte[] d, int start, int n) { System.arraycopy(d, start, window, 0, n); read = write = n; } // Returns true if inflate is currently at the end of a block generated // by Z_SYNC_FLUSH or Z_FULL_FLUSH. int sync_point() { return mode == LENS ? 1 : 0; } // copy as much as possible from the sliding window to the output area int inflate_flush(int r) { int n; int p; int q; // local copies of source and destination pointers p = z.next_out_index; q = read; // compute number of bytes to copy as far as end of window n = ((q <= write ? write : end) - q); if (n > z.avail_out) n = z.avail_out; if (n != 0 && r == Z_BUF_ERROR) r = Z_OK; // update counters z.avail_out -= n; z.total_out += n; // update check information if (check && n > 0) { z.adler.update(window, q, n); } // copy as far as end of window System.arraycopy(window, q, z.next_out, p, n); p += n; q += n; // see if more to copy at beginning of window if (q == end) { // wrap pointers q = 0; if (write == end) write = 0; // compute bytes to copy n = write - q; if (n > z.avail_out) n = z.avail_out; if (n != 0 && r == Z_BUF_ERROR) r = Z_OK; // update counters z.avail_out -= n; z.total_out += n; // update check information if (check && n > 0) { z.adler.update(window, q, n); } // copy System.arraycopy(window, q, z.next_out, p, n); p += n; q += n; } // update pointers z.next_out_index = p; read = q; // done return r; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java000066400000000000000000000502521465436372100255720ustar00rootroot00000000000000/* * Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class InfCodes { private static final int[] inflate_mask = {0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff}; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; // waiting for "i:"=input, // "o:"=output, // "x:"=nothing private static final int START = 0; // x: set up for LEN private static final int LEN = 1; // i: get length/literal/eob next private static final int LENEXT = 2; // i: getting length extra (have base) private static final int DIST = 3; // i: get distance next private static final int DISTEXT = 4; // i: getting distance extra private static final int COPY = 5; // o: copying bytes in window, waiting for space private static final int LIT = 6; // o: got literal, waiting for output space private static final int WASH = 7; // o: got eob, possibly still output waiting private static final int END = 8; // x: got eob and all data flushed private static final int BADCODE = 9; // x: got error int mode; // current inflate_codes mode // mode dependent information int len; int[] tree; // pointer into tree int tree_index = 0; int need; // bits needed int lit; // if EXT or COPY, where and how much int get; // bits to get for extra int dist; // distance back to copy from byte lbits; // ltree bits decoded per branch byte dbits; // dtree bits decoder per branch int[] ltree; // literal/length/eob tree int ltree_index; // literal/length/eob tree int[] dtree; // distance tree int dtree_index; // distance tree private final ZStream z; private final InfBlocks s; InfCodes(ZStream z, InfBlocks s) { this.z = z; this.s = s; } void init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index) { mode = START; lbits = (byte) bl; dbits = (byte) bd; ltree = tl; ltree_index = tl_index; dtree = td; dtree_index = td_index; tree = null; } @SuppressWarnings("fallthrough") int proc(int r) { int j; // temporary storage int[] t; // temporary pointer int tindex; // temporary pointer int e; // extra bits or operation int b = 0; // bit buffer int k = 0; // bits in bit buffer int p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; // process input and output based on current state while (true) { switch (mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case START: // x: set up for LEN if (m >= 258 && n >= 10) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (r != Z_OK) { mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = LEN; case LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b >>>= (tree[tindex + 1]); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) { // literal lit = tree[tindex + 2]; mode = LIT; break; } if ((e & 16) != 0) { // length get = e & 15; len = tree[tindex + 2]; mode = LENEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block mode = WASH; break; } mode = BADCODE; // invalid code z.msg = "invalid literal/length code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); case LENEXT: // i: getting length extra (have base) j = get; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } len += (b & inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = DIST; case DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b >>= tree[tindex + 1]; k -= tree[tindex + 1]; e = (tree[tindex]); if ((e & 16) != 0) { // distance get = e & 15; dist = tree[tindex + 2]; mode = DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = BADCODE; // invalid code z.msg = "invalid distance code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); case DISTEXT: // i: getting distance extra j = get; while (k < (j)) { if (n != 0) r = Z_OK; else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } dist += (b & inflate_mask[j]); b >>= j; k -= j; mode = COPY; case COPY: // o: copying bytes in window, waiting for space f = q - dist; while (f < 0) { // modulo window size-"while" instead f += s.end; // of "if" handles invalid distances } while (len != 0) { if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.write = q; r = s.inflate_flush(r); q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } } } s.window[q++] = s.window[f++]; m--; if (f == s.end) f = 0; len--; } mode = START; break; case LIT: // o: got literal, waiting for output space if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.write = q; r = s.inflate_flush(r); q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } } } r = Z_OK; s.window[q++] = (byte) lit; m--; mode = START; break; case WASH: // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; // can always return one } s.write = q; r = s.inflate_flush(r); q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (s.read != s.write) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } mode = END; case END: r = Z_STREAM_END; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); case BADCODE: // x: got error r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); default: r = Z_STREAM_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.inflate_flush(r); } } } void free(ZStream z) { // ZFREE(z, c); } // Called with number of bytes left to write in window at least 258 // (the maximum string length) and number of input bytes available // at least ten. The ten bytes are six bytes for the longest length/ // distance pair plus four bytes for overloading the bit buffer. int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tp_index; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer int tp_index_t_3; // (tp_index+t)*3 // load input, output, bit values p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; // initialize masks ml = inflate_mask[bl]; md = inflate_mask[bd]; // do until not enough input or output space for fast loop do { // assume called with m >= 258 && n >= 10 // get literal/length code while (k < (20)) { // max bits for literal/length code n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & ml; tp = tl; tp_index = tl_index; tp_index_t_3 = (tp_index + t) * 3; if ((e = tp[tp_index_t_3]) == 0) { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); s.window[q++] = (byte) tp[tp_index_t_3 + 2]; m--; continue; } do { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); if ((e & 16) != 0) { e &= 15; c = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < (15)) { // max bits for distance code n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } t = b & md; tp = td; tp_index = td_index; tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; do { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); if ((e & 16) != 0) { // get extra bits to add to distance base e &= 15; while (k < (e)) { // get extra bits (up to 13) n--; b |= (z.next_in[p++] & 0xff) << k; k += 8; } d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); b >>= (e); k -= (e); // do the copy m -= c; if (q >= d) { // offset before dest // just copy r = q - d; if (q - r > 0 && 2 > (q - r)) { s.window[q++] = s.window[r++]; // minimum count is three, s.window[q++] = s.window[r++]; // so unroll loop a little c -= 2; } else { System.arraycopy(s.window, r, s.window, q, 2); q += 2; r += 2; c -= 2; } } else { // else offset after destination r = q - d; do { r += s.end; // force pointer in window } while (r < 0); // covers invalid distances e = s.end - r; if (c > e) { // if source crosses, c -= e; // wrapped copy if (q - r > 0 && e > (q - r)) { do { s.window[q++] = s.window[r++]; } while (--e != 0); } else { System.arraycopy(s.window, r, s.window, q, e); q += e; r += e; e = 0; } r = 0; // copy rest from start of window } } // copy all or what's left if (q - r > 0 && c > (q - r)) { do { s.window[q++] = s.window[r++]; } while (--c != 0); } else { System.arraycopy(s.window, r, s.window, q, c); q += c; r += c; c = 0; } break; } else if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & inflate_mask[e]); tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; } else { z.msg = "invalid distance code"; c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_DATA_ERROR; } } while (true); break; } if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & inflate_mask[e]); tp_index_t_3 = (tp_index + t) * 3; if ((e = tp[tp_index_t_3]) == 0) { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); s.window[q++] = (byte) tp[tp_index_t_3 + 2]; m--; break; } } else if ((e & 32) != 0) { c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_STREAM_END; } else { z.msg = "invalid literal/length code"; c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_DATA_ERROR; } } while (true); } while (m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_OK; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/InfTree.java000066400000000000000000000447661465436372100254510ustar00rootroot00000000000000/* * Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class InfTree { private static final int MANY = 1440; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; static final int fixed_bl = 9; static final int fixed_bd = 5; static final int[] fixed_tl = {96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; static final int[] fixed_td = {80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577}; // Tables for deflate from PKZIP's appnote.txt. static final int[] cplens = { // Copy lengths for literal codes 257..285 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; // see note #13 above about 258 static final int[] cplext = { // Extra bits for literal codes 257..285 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid }; static final int[] cpdist = { // Copy offsets for distance codes 0..29 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; static final int[] cpdext = { // Extra bits for distance codes 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; // If BMAX needs to be larger than 16, then h and x[] should be uLong. static final int BMAX = 15; // maximum bit length of any code int[] hn = null; // hufts used in space int[] v = null; // work area for huft_build int[] c = null; // bit length count table int[] r = null; // table entry for structure assignment int[] u = null; // table stack int[] x = null; // bit offsets, then code stack private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) int bindex, int n, // number of codes (assumed <= 288) int s, // number of simple-valued codes (0..s-1) int[] d, // list of base values for non-simple codes int[] e, // list of extra bits for non-simple codes int[] t, // result: starting table int[] m, // maximum lookup bits, returns actual int[] hp, // space for trees int[] hn, // hufts used in space int[] v // working area: values in order of bit length ) { // Given a list of code lengths and a maximum table size, make a set of // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR // if the given code set is incomplete (the tables are still built in this // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of // lengths), or Z_MEM_ERROR if not enough memory. int a; // counter for codes of length k int f; // i repeats in table every f entries int g; // maximum code length int h; // table level int i; // counter, current code int j; // counter int k; // number of bits in current code int l; // bits per table (returned in m) int mask; // (1 << w) - 1, to avoid cc -O bug on HP int p; // pointer into c[], b[], or v[] int q; // points to current table int w; // bits before this table == (l * h) int xp; // pointer into x int y; // number of dummy codes added int z; // number of entries in current table // Generate counts for each bit length p = 0; i = n; do { c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX } while (i != 0); if (c[0] == n) { // null input--all zero length codes t[0] = -1; m[0] = 0; return Z_OK; } // Find minimum and maximum length, bound *m by those l = m[0]; for (j = 1; j <= BMAX; j++) if (c[j] != 0) break; k = j; // minimum code length if (l < j) { l = j; } for (i = BMAX; i != 0; i--) { if (c[i] != 0) break; } g = i; // maximum code length if (l > i) { l = i; } m[0] = l; // Adjust last length count to fill out codes, if needed for (y = 1 << j; j < i; j++, y <<= 1) { if ((y -= c[j]) < 0) { return Z_DATA_ERROR; } } if ((y -= c[i]) < 0) { return Z_DATA_ERROR; } c[i] += y; // Generate starting offsets into the value table for each length x[1] = j = 0; p = 1; xp = 2; while (--i != 0) { // note that i == g from above x[xp] = (j += c[p]); xp++; p++; } // Make a table of values in order of bit lengths i = 0; p = 0; do { if ((j = b[bindex + p]) != 0) { v[x[j]++] = i; } p++; } while (++i < n); n = x[g]; // set n to length of v // Generate the Huffman codes and for each, make the table entries x[0] = i = 0; // first Huffman code is zero p = 0; // grab values in bit order h = -1; // no tables yet--level -1 w = -l; // bits decoded == (l * h) u[0] = 0; // just to keep compilers happy q = 0; // ditto z = 0; // ditto // go through the bit lengths (k already is bits in shortest code) for (; k <= g; k++) { a = c[k]; while (a-- != 0) { // here i is the Huffman code of length k bits for value *p // make tables up to required level while (k > w + l) { h++; w += l; // previous table always l bits // compute minimum size table less than or equal to l bits z = g - w; z = (z > l) ? l : z; // table size upper limit if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table // too few codes for k-w bit table f -= a + 1; // deduct codes from patterns left xp = k; if (j < z) { while (++j < z) { // try smaller tables up to z bits if ((f <<= 1) <= c[++xp]) break; // enough codes to use up j bits f -= c[xp]; // else deduct codes from patterns } } } z = 1 << j; // table entries for j-bit table // allocate new table if (hn[0] + z > MANY) { // (note: doesn't matter for fixed) return Z_DATA_ERROR; // overflow of MANY } u[h] = q = /* hp+ */ hn[0]; // DEBUG hn[0] += z; // connect to last table, if there is one if (h != 0) { x[h] = i; // save pattern for backing up r[0] = (byte) j; // bits in this table r[1] = (byte) l; // bits to dump before this table j = i >>> (w - l); r[2] = q - u[h - 1] - j; // offset to this table System.arraycopy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table } else { t[0] = q; // first table is returned result } } // set up table entry in r r[1] = (byte) (k - w); if (p >= n) { r[0] = 128 + 64; // out of values--invalid code } else if (v[p] < s) { r[0] = (byte) (v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block r[2] = v[p++]; // simple code is just the value } else { r[0] = (byte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists r[2] = d[v[p++] - s]; } // fill code-like entries with r f = 1 << (k - w); for (j = i >>> w; j < z; j += f) { System.arraycopy(r, 0, hp, (q + j) * 3, 3); } // backwards increment the k-bit code i for (j = 1 << (k - 1); (i & j) != 0; j >>>= 1) { i ^= j; } i ^= j; // backup over finished tables mask = (1 << w) - 1; // needed on HP, cc -O bug while ((i & mask) != x[h]) { h--; // don't need to update q w -= l; mask = (1 << w) - 1; } } } // Return Z_BUF_ERROR if we were given an incomplete table return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } int inflate_trees_bits(int[] c, // 19 code lengths int[] bb, // bits tree desired/actual depth int[] tb, // bits tree result int[] hp, // space for trees ZStream z // for messages ) { int result; initWorkArea(19); hn[0] = 0; result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); if (result == Z_DATA_ERROR) { z.msg = "oversubscribed dynamic bit lengths tree"; } else if (result == Z_BUF_ERROR || bb[0] == 0) { z.msg = "incomplete dynamic bit lengths tree"; result = Z_DATA_ERROR; } return result; } int inflate_trees_dynamic(int nl, // number of literal/length codes int nd, // number of distance codes int[] c, // that many (total) code lengths int[] bl, // literal desired/actual bit depth int[] bd, // distance desired/actual bit depth int[] tl, // literal/length tree result int[] td, // distance tree result int[] hp, // space for trees ZStream z // for messages ) { int result; // build literal/length tree initWorkArea(288); hn[0] = 0; result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); if (result != Z_OK || bl[0] == 0) { if (result == Z_DATA_ERROR) { z.msg = "oversubscribed literal/length tree"; } else if (result != Z_MEM_ERROR) { z.msg = "incomplete literal/length tree"; result = Z_DATA_ERROR; } return result; } // build distance tree initWorkArea(288); result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); if (result != Z_OK || (bd[0] == 0 && nl > 257)) { if (result == Z_DATA_ERROR) { z.msg = "oversubscribed distance tree"; } else if (result == Z_BUF_ERROR) { z.msg = "incomplete distance tree"; result = Z_DATA_ERROR; } else if (result != Z_MEM_ERROR) { z.msg = "empty distance tree with lengths"; result = Z_DATA_ERROR; } return result; } return Z_OK; } static int inflate_trees_fixed(int[] bl, // literal desired/actual bit depth int[] bd, // distance desired/actual bit depth int[][] tl, // literal/length tree result int[][] td, // distance tree result ZStream z // for memory allocation ) { bl[0] = fixed_bl; bd[0] = fixed_bd; tl[0] = fixed_tl; td[0] = fixed_td; return Z_OK; } private void initWorkArea(int vsize) { if (hn == null) { hn = new int[1]; v = new int[vsize]; c = new int[BMAX + 1]; r = new int[3]; u = new int[BMAX]; x = new int[BMAX + 1]; } if (v.length < vsize) { v = new int[vsize]; } for (int i = 0; i < vsize; i++) { v[i] = 0; } for (int i = 0; i < BMAX + 1; i++) { c[i] = 0; } for (int i = 0; i < 3; i++) { r[i] = 0; } System.arraycopy(c, 0, u, 0, BMAX); System.arraycopy(c, 0, x, 0, BMAX + 1); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Inflate.java000066400000000000000000000524741465436372100254720ustar00rootroot00000000000000/* * Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; import java.io.ByteArrayOutputStream; final class Inflate { private static final int MAX_WBITS = 15; // 32K LZ77 window // preset dictionary flag in zlib header private static final int PRESET_DICT = 0x20; static final int Z_NO_FLUSH = 0; static final int Z_PARTIAL_FLUSH = 1; static final int Z_SYNC_FLUSH = 2; static final int Z_FULL_FLUSH = 3; static final int Z_FINISH = 4; private static final int Z_DEFLATED = 8; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; private static final int METHOD = 0; // waiting for method byte private static final int FLAG = 1; // waiting for flag byte private static final int DICT4 = 2; // four dictionary check bytes to go private static final int DICT3 = 3; // three dictionary check bytes to go private static final int DICT2 = 4; // two dictionary check bytes to go private static final int DICT1 = 5; // one dictionary check byte to go private static final int DICT0 = 6; // waiting for inflateSetDictionary private static final int BLOCKS = 7; // decompressing blocks private static final int CHECK4 = 8; // four check bytes to go private static final int CHECK3 = 9; // three check bytes to go private static final int CHECK2 = 10; // two check bytes to go private static final int CHECK1 = 11; // one check byte to go private static final int DONE = 12; // finished check, done private static final int BAD = 13; // got an error--stay here private static final int HEAD = 14; private static final int LENGTH = 15; private static final int TIME = 16; private static final int OS = 17; private static final int EXLEN = 18; private static final int EXTRA = 19; private static final int NAME = 20; private static final int COMMENT = 21; private static final int HCRC = 22; private static final int FLAGS = 23; static final int INFLATE_ANY = 0x40000000; int mode; // current inflate mode // mode dependent information int method; // if FLAGS, method byte // if CHECK, check values to compare long was = -1; // computed check value long need; // stream check value // if BAD, inflateSync's marker bytes count int marker; // mode independent information int wrap; // flag for no wrapper // 0: no wrapper // 1: zlib header // 2: gzip header // 4: auto detection int wbits; // log2(window size) (8..15, defaults to 15) InfBlocks blocks; // current inflate_blocks state private final ZStream z; private int flags; private int need_bytes = -1; private byte[] crcbuf = new byte[4]; GZIPHeader gheader = null; int inflateReset() { if (z == null) return Z_STREAM_ERROR; z.total_in = z.total_out = 0; z.msg = null; this.mode = HEAD; this.need_bytes = -1; this.blocks.reset(); return Z_OK; } int inflateEnd() { if (blocks != null) { blocks.free(); } return Z_OK; } Inflate(ZStream z) { this.z = z; } int inflateInit(int w) { z.msg = null; blocks = null; // handle undocumented wrap option (no zlib header or check) wrap = 0; if (w < 0) { w = -w; } else if ((w & INFLATE_ANY) != 0) { wrap = 4; w &= ~INFLATE_ANY; if (w < 48) w &= 15; } else if ((w & ~31) != 0) { // for example, DEF_WBITS + 32 wrap = 4; // zlib and gzip wrapped data should be accepted. w &= 15; } else { wrap = (w >> 4) + 1; if (w < 48) w &= 15; } if (w < 8 || w > 15) { inflateEnd(); return Z_STREAM_ERROR; } if (blocks != null && wbits != w) { blocks.free(); blocks = null; } // set window size wbits = w; this.blocks = new InfBlocks(z, 1 << w); // reset state inflateReset(); return Z_OK; } @SuppressWarnings("fallthrough") int inflate(int f) { int hold = 0; int r; int b; if (z == null || z.next_in == null) { if (f == Z_FINISH && this.mode == HEAD) return Z_OK; return Z_STREAM_ERROR; } f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; r = Z_BUF_ERROR; while (true) { switch (this.mode) { case HEAD: if (wrap == 0) { this.mode = BLOCKS; break; } try { r = readBytes(2, r, f); } catch (Return e) { return e.r; } if ((wrap == 4 || (wrap & 2) != 0) && this.need == 0x8b1fL) { // gzip header if (wrap == 4) { wrap = 2; } z.adler = new CRC32(); checksum(2, this.need); if (gheader == null) gheader = new GZIPHeader(); this.mode = FLAGS; break; } if ((wrap & 2) != 0) { this.mode = BAD; z.msg = "incorrect header check"; break; } flags = 0; this.method = ((int) this.need) & 0xff; b = ((int) (this.need >> 8)) & 0xff; if (((wrap & 1) == 0 || // check if zlib header allowed (((this.method << 8) + b) % 31) != 0) && (this.method & 0xf) != Z_DEFLATED) { if (wrap == 4) { z.next_in_index -= 2; z.avail_in += 2; z.total_in -= 2; wrap = 0; this.mode = BLOCKS; break; } this.mode = BAD; z.msg = "incorrect header check"; // since zlib 1.2, it is allowted to inflateSync for this case. /* * this.marker = 5; // can't try inflateSync */ break; } if ((this.method & 0xf) != Z_DEFLATED) { this.mode = BAD; z.msg = "unknown compression method"; // since zlib 1.2, it is allowted to inflateSync for this case. /* * this.marker = 5; // can't try inflateSync */ break; } if (wrap == 4) { wrap = 1; } if ((this.method >> 4) + 8 > this.wbits) { this.mode = BAD; z.msg = "invalid window size"; // since zlib 1.2, it is allowted to inflateSync for this case. /* * this.marker = 5; // can't try inflateSync */ break; } z.adler = new Adler32(); if ((b & PRESET_DICT) == 0) { this.mode = BLOCKS; break; } this.mode = DICT4; case DICT4: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; this.mode = DICT3; case DICT3: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; this.mode = DICT2; case DICT2: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; this.mode = DICT1; case DICT1: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need += (z.next_in[z.next_in_index++] & 0xffL); z.adler.reset(this.need); this.mode = DICT0; return Z_NEED_DICT; case DICT0: this.mode = BAD; z.msg = "need dictionary"; this.marker = 0; // can try inflateSync return Z_STREAM_ERROR; case BLOCKS: r = this.blocks.proc(r); if (r == Z_DATA_ERROR) { this.mode = BAD; this.marker = 0; // can try inflateSync break; } if (r == Z_OK) { r = f; } if (r != Z_STREAM_END) { return r; } r = f; this.was = z.adler.getValue(); this.blocks.reset(); if (this.wrap == 0) { this.mode = DONE; break; } this.mode = CHECK4; case CHECK4: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; this.mode = CHECK3; case CHECK3: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; this.mode = CHECK2; case CHECK2: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; this.mode = CHECK1; case CHECK1: if (z.avail_in == 0) return r; r = f; z.avail_in--; z.total_in++; this.need += (z.next_in[z.next_in_index++] & 0xffL); if (flags != 0) { // gzip this.need = ((this.need & 0xff000000) >> 24 | (this.need & 0x00ff0000) >> 8 | (this.need & 0x0000ff00) << 8 | (this.need & 0x0000ffff) << 24) & 0xffffffffL; } if (((int) (this.was)) != ((int) (this.need))) { z.msg = "incorrect data check"; // chack is delayed /* * this.mode = BAD; this.marker = 5; // can't try inflateSync break; */ } else if (flags != 0 && gheader != null) { gheader.crc = this.need; } this.mode = LENGTH; case LENGTH: if (wrap != 0 && flags != 0) { try { r = readBytes(4, r, f); } catch (Return e) { return e.r; } if (z.msg != null && z.msg.equals("incorrect data check")) { this.mode = BAD; this.marker = 5; // can't try inflateSync break; } if (this.need != (z.total_out & 0xffffffffL)) { z.msg = "incorrect length check"; this.mode = BAD; break; } z.msg = null; } else { if (z.msg != null && z.msg.equals("incorrect data check")) { this.mode = BAD; this.marker = 5; // can't try inflateSync break; } } this.mode = DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; case FLAGS: try { r = readBytes(2, r, f); } catch (Return e) { return e.r; } flags = ((int) this.need) & 0xffff; if ((flags & 0xff) != Z_DEFLATED) { z.msg = "unknown compression method"; this.mode = BAD; break; } if ((flags & 0xe000) != 0) { z.msg = "unknown header flags set"; this.mode = BAD; break; } if ((flags & 0x0200) != 0) { checksum(2, this.need); } this.mode = TIME; case TIME: try { r = readBytes(4, r, f); } catch (Return e) { return e.r; } if (gheader != null) { gheader.setModifiedTime(this.need); } if ((flags & 0x0200) != 0) { checksum(4, this.need); } this.mode = OS; case OS: try { r = readBytes(2, r, f); } catch (Return e) { return e.r; } if (gheader != null) { gheader.xflags = ((int) this.need) & 0xff; gheader.os = (((int) this.need) >> 8) & 0xff; } if ((flags & 0x0200) != 0) { checksum(2, this.need); } this.mode = EXLEN; case EXLEN: if ((flags & 0x0400) != 0) { try { r = readBytes(2, r, f); } catch (Return e) { return e.r; } if (gheader != null) { gheader.extra = new byte[((int) this.need) & 0xffff]; } if ((flags & 0x0200) != 0) { checksum(2, this.need); } } else if (gheader != null) { gheader.extra = null; } this.mode = EXTRA; case EXTRA: if ((flags & 0x0400) != 0) { try { r = readBytes(r, f); if (gheader != null) { byte[] foo = tmp_string.toByteArray(); tmp_string = null; if (foo.length == gheader.extra.length) { System.arraycopy(foo, 0, gheader.extra, 0, foo.length); } else { z.msg = "bad extra field length"; this.mode = BAD; break; } } } catch (Return e) { return e.r; } } else if (gheader != null) { gheader.extra = null; } this.mode = NAME; case NAME: if ((flags & 0x0800) != 0) { try { r = readString(r, f); if (gheader != null) { gheader.name = tmp_string.toByteArray(); } tmp_string = null; } catch (Return e) { return e.r; } } else if (gheader != null) { gheader.name = null; } this.mode = COMMENT; case COMMENT: if ((flags & 0x1000) != 0) { try { r = readString(r, f); if (gheader != null) { gheader.comment = tmp_string.toByteArray(); } tmp_string = null; } catch (Return e) { return e.r; } } else if (gheader != null) { gheader.comment = null; } this.mode = HCRC; case HCRC: if ((flags & 0x0200) != 0) { try { r = readBytes(2, r, f); } catch (Return e) { return e.r; } if (gheader != null) { gheader.hcrc = (int) (this.need & 0xffff); } if (this.need != (z.adler.getValue() & 0xffffL)) { this.mode = BAD; z.msg = "header crc mismatch"; this.marker = 5; // can't try inflateSync break; } } z.adler = new CRC32(); this.mode = BLOCKS; break; default: return Z_STREAM_ERROR; } } } int inflateSetDictionary(byte[] dictionary, int dictLength) { if (z == null || (this.mode != DICT0 && this.wrap != 0)) { return Z_STREAM_ERROR; } int index = 0; int length = dictLength; if (this.mode == DICT0) { long adler_need = z.adler.getValue(); z.adler.reset(); z.adler.update(dictionary, 0, dictLength); if (z.adler.getValue() != adler_need) { return Z_DATA_ERROR; } } z.adler.reset(); if (length >= (1 << this.wbits)) { length = (1 << this.wbits) - 1; index = dictLength - length; } this.blocks.set_dictionary(dictionary, index, length); this.mode = BLOCKS; return Z_OK; } private static byte[] mark = {(byte) 0, (byte) 0, (byte) 0xff, (byte) 0xff}; int inflateSync() { int n; // number of bytes to look at int p; // pointer to bytes int m; // number of marker bytes found in a row long r, w; // temporaries to save total_in and total_out // set up if (z == null) return Z_STREAM_ERROR; if (this.mode != BAD) { this.mode = BAD; this.marker = 0; } if ((n = z.avail_in) == 0) return Z_BUF_ERROR; p = z.next_in_index; m = this.marker; // search while (n != 0 && m < 4) { if (z.next_in[p] == mark[m]) { m++; } else if (z.next_in[p] != 0) { m = 0; } else { m = 4 - m; } p++; n--; } // restore z.total_in += p - z.next_in_index; z.next_in_index = p; z.avail_in = n; this.marker = m; // return no joy or set up to restart on a new block if (m != 4) { return Z_DATA_ERROR; } r = z.total_in; w = z.total_out; inflateReset(); z.total_in = r; z.total_out = w; this.mode = BLOCKS; return Z_OK; } // Returns true if inflate is currently at the end of a block generated // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH // but removes the length bytes of the resulting empty stored block. When // decompressing, PPP checks that at the end of input packet, inflate is // waiting for these length bytes. int inflateSyncPoint() { if (z == null || this.blocks == null) return Z_STREAM_ERROR; return this.blocks.sync_point(); } private int readBytes(int n, int r, int f) throws Return { if (need_bytes == -1) { need_bytes = n; this.need = 0; } while (need_bytes > 0) { if (z.avail_in == 0) { throw new Return(r); } ; r = f; z.avail_in--; z.total_in++; this.need = this.need | ((z.next_in[z.next_in_index++] & 0xff) << ((n - need_bytes) * 8)); need_bytes--; } if (n == 2) { this.need &= 0xffffL; } else if (n == 4) { this.need &= 0xffffffffL; } need_bytes = -1; return r; } static class Return extends Exception { private static final long serialVersionUID = -1L; int r; Return(int r) { this.r = r; } } private ByteArrayOutputStream tmp_string = null; private int readString(int r, int f) throws Return { if (tmp_string == null) { tmp_string = new ByteArrayOutputStream(); } int b = 0; do { if (z.avail_in == 0) { throw new Return(r); } ; r = f; z.avail_in--; z.total_in++; b = z.next_in[z.next_in_index]; if (b != 0) tmp_string.write(z.next_in, z.next_in_index, 1); z.adler.update(z.next_in, z.next_in_index, 1); z.next_in_index++; } while (b != 0); return r; } private int readBytes(int r, int f) throws Return { if (tmp_string == null) { tmp_string = new ByteArrayOutputStream(); } int b = 0; while (this.need > 0) { if (z.avail_in == 0) { throw new Return(r); } ; r = f; z.avail_in--; z.total_in++; b = z.next_in[z.next_in_index]; tmp_string.write(z.next_in, z.next_in_index, 1); z.adler.update(z.next_in, z.next_in_index, 1); z.next_in_index++; this.need--; } return r; } private void checksum(int n, long v) { for (int i = 0; i < n; i++) { crcbuf[i] = (byte) (v & 0xff); v >>= 8; } z.adler.update(crcbuf, 0, n); } GZIPHeader getGZIPHeader() { return gheader; } boolean inParsingHeader() { switch (mode) { case HEAD: case DICT4: case DICT3: case DICT2: case DICT1: case FLAGS: case TIME: case OS: case EXLEN: case EXTRA: case NAME: case COMMENT: case HCRC: return true; default: return false; } } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Inflater.java000066400000000000000000000122031465436372100256360ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class Inflater extends ZStream { private static final int MAX_WBITS = 15; // 32K LZ77 window private static final int DEF_WBITS = MAX_WBITS; private static final int Z_NO_FLUSH = 0; private static final int Z_PARTIAL_FLUSH = 1; private static final int Z_SYNC_FLUSH = 2; private static final int Z_FULL_FLUSH = 3; private static final int Z_FINISH = 4; private static final int MAX_MEM_LEVEL = 9; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; private int param_w = -1; private JZlib.WrapperType param_wrapperType = null; private boolean param_nowrap = false; Inflater() { super(); init(); } Inflater(JZlib.WrapperType wrapperType) throws GZIPException { this(DEF_WBITS, wrapperType); } Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { super(); param_w = w; param_wrapperType = wrapperType; int ret = init(w, wrapperType); if (ret != Z_OK) throw new GZIPException(ret + ": " + msg); } Inflater(int w) throws GZIPException { this(w, false); } Inflater(boolean nowrap) throws GZIPException { this(DEF_WBITS, nowrap); } Inflater(int w, boolean nowrap) throws GZIPException { super(); param_w = w; param_nowrap = nowrap; int ret = init(w, nowrap); if (ret != Z_OK) throw new GZIPException(ret + ": " + msg); } void reset() { finished = false; if (param_wrapperType != null) { init(param_w, param_wrapperType); } else { init(param_w, param_nowrap); } } private boolean finished = false; int init() { return init(DEF_WBITS); } int init(JZlib.WrapperType wrapperType) { return init(DEF_WBITS, wrapperType); } int init(int w, JZlib.WrapperType wrapperType) { boolean nowrap = false; if (wrapperType == JZlib.W_NONE) { nowrap = true; } else if (wrapperType == JZlib.W_GZIP) { w += 16; } else if (wrapperType == JZlib.W_ANY) { w |= Inflate.INFLATE_ANY; } else if (wrapperType == JZlib.W_ZLIB) { } return init(w, nowrap); } int init(boolean nowrap) { return init(DEF_WBITS, nowrap); } int init(int w) { return init(w, false); } int init(int w, boolean nowrap) { finished = false; istate = new Inflate(this); return istate.inflateInit(nowrap ? -w : w); } @Override int inflate(int f) { if (istate == null) return Z_STREAM_ERROR; int ret = istate.inflate(f); if (ret == Z_STREAM_END) finished = true; return ret; } @Override int end() { finished = true; if (istate == null) return Z_STREAM_ERROR; int ret = istate.inflateEnd(); // istate = null; return ret; } int sync() { if (istate == null) return Z_STREAM_ERROR; return istate.inflateSync(); } int syncPoint() { if (istate == null) return Z_STREAM_ERROR; return istate.inflateSyncPoint(); } int setDictionary(byte[] dictionary, int dictLength) { if (istate == null) return Z_STREAM_ERROR; return istate.inflateSetDictionary(dictionary, dictLength); } @Override boolean finished() { return istate.mode == 12 /* DONE */; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java000066400000000000000000000154751465436372100300500ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jzlib; import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; final class InflaterInputStream extends FilterInputStream { protected final Inflater inflater; protected byte[] buf; private boolean closed = false; protected boolean eof = false; private boolean close_in = true; protected static final int DEFAULT_BUFSIZE = 512; InflaterInputStream(InputStream in) throws IOException { this(in, false); } InflaterInputStream(InputStream in, boolean nowrap) throws IOException { this(in, new Inflater(nowrap)); myinflater = true; } InflaterInputStream(InputStream in, Inflater inflater) throws IOException { this(in, inflater, DEFAULT_BUFSIZE); } InflaterInputStream(InputStream in, Inflater inflater, int size) throws IOException { this(in, inflater, size, true); } InflaterInputStream(InputStream in, Inflater inflater, int size, boolean close_in) throws IOException { super(in); if (in == null || inflater == null) { throw new NullPointerException(); } else if (size <= 0) { throw new IllegalArgumentException("buffer size must be greater than 0"); } this.inflater = inflater; buf = new byte[size]; this.close_in = close_in; } protected boolean myinflater = false; private byte[] byte1 = new byte[1]; @Override public int read() throws IOException { if (closed) { throw new IOException("Stream closed"); } return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; } @Override public int read(byte[] b, int off, int len) throws IOException { if (closed) { throw new IOException("Stream closed"); } if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } else if (eof) { return -1; } int n = 0; inflater.setOutput(b, off, len); while (!eof) { if (inflater.avail_in == 0) fill(); int err = inflater.inflate(JZlib.Z_NO_FLUSH); n += inflater.next_out_index - off; off = inflater.next_out_index; switch (err) { case JZlib.Z_DATA_ERROR: throw new IOException(inflater.msg); case JZlib.Z_STREAM_END: case JZlib.Z_NEED_DICT: eof = true; if (err == JZlib.Z_NEED_DICT) return -1; break; default: } if (inflater.avail_out == 0) break; } return n; } @Override public int available() throws IOException { if (closed) { throw new IOException("Stream closed"); } if (eof) { return 0; } else { return 1; } } private byte[] b = new byte[512]; @Override public long skip(long n) throws IOException { if (n < 0) { throw new IllegalArgumentException("negative skip length"); } if (closed) { throw new IOException("Stream closed"); } int max = (int) Math.min(n, Integer.MAX_VALUE); int total = 0; while (total < max) { int len = max - total; if (len > b.length) { len = b.length; } len = read(b, 0, len); if (len == -1) { eof = true; break; } total += len; } return total; } @Override public void close() throws IOException { if (!closed) { if (myinflater) inflater.end(); if (close_in) in.close(); closed = true; } } protected void fill() throws IOException { if (closed) { throw new IOException("Stream closed"); } int len = in.read(buf, 0, buf.length); if (len == -1) { if (inflater.istate.wrap == 0 && !inflater.finished()) { buf[0] = 0; len = 1; } else if (inflater.istate.was != -1) { // in reading trailer throw new IOException("footer is not found"); } else { throw new EOFException("Unexpected end of ZLIB input stream"); } } inflater.setInput(buf, 0, len, true); } @Override public boolean markSupported() { return false; } @Override public synchronized void mark(int readlimit) {} @Override public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } long getTotalIn() { return inflater.getTotalIn(); } long getTotalOut() { return inflater.getTotalOut(); } byte[] getAvailIn() { if (inflater.avail_in <= 0) return null; byte[] tmp = new byte[inflater.avail_in]; System.arraycopy(inflater.next_in, inflater.next_in_index, tmp, 0, inflater.avail_in); return tmp; } void readHeader() throws IOException { byte[] empty = "".getBytes(StandardCharsets.UTF_8); inflater.setInput(empty, 0, 0, false); inflater.setOutput(empty, 0, 0); int err = inflater.inflate(JZlib.Z_NO_FLUSH); if (!inflater.istate.inParsingHeader()) { return; } byte[] b1 = new byte[1]; do { int i = in.read(b1); if (i <= 0) throw new IOException("no input"); inflater.setInput(b1); err = inflater.inflate(JZlib.Z_NO_FLUSH); if (err != 0 /* Z_OK */) throw new IOException(inflater.msg); } while (inflater.istate.inParsingHeader()); } Inflater getInflater() { return inflater; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/JZlib.java000066400000000000000000000065301465436372100251120ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class JZlib { private static final String version = "1.1.3"; static String version() { return version; } static final int MAX_WBITS = 15; // 32K LZ77 window static final int DEF_WBITS = MAX_WBITS; enum WrapperType { NONE, ZLIB, GZIP, ANY } static final WrapperType W_NONE = WrapperType.NONE; static final WrapperType W_ZLIB = WrapperType.ZLIB; static final WrapperType W_GZIP = WrapperType.GZIP; static final WrapperType W_ANY = WrapperType.ANY; // compression levels static final int Z_NO_COMPRESSION = 0; static final int Z_BEST_SPEED = 1; static final int Z_BEST_COMPRESSION = 9; static final int Z_DEFAULT_COMPRESSION = (-1); // compression strategy static final int Z_FILTERED = 1; static final int Z_HUFFMAN_ONLY = 2; static final int Z_DEFAULT_STRATEGY = 0; static final int Z_NO_FLUSH = 0; static final int Z_PARTIAL_FLUSH = 1; static final int Z_SYNC_FLUSH = 2; static final int Z_FULL_FLUSH = 3; static final int Z_FINISH = 4; static final int Z_OK = 0; static final int Z_STREAM_END = 1; static final int Z_NEED_DICT = 2; static final int Z_ERRNO = -1; static final int Z_STREAM_ERROR = -2; static final int Z_DATA_ERROR = -3; static final int Z_MEM_ERROR = -4; static final int Z_BUF_ERROR = -5; static final int Z_VERSION_ERROR = -6; // The three kinds of block type static final byte Z_BINARY = 0; static final byte Z_ASCII = 1; static final byte Z_UNKNOWN = 2; static long adler32_combine(long adler1, long adler2, long len2) { return Adler32.combine(adler1, adler2, len2); } static long crc32_combine(long crc1, long crc2, long len2) { return CRC32.combine(crc1, crc2, len2); } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java000066400000000000000000000127671465436372100261600ustar00rootroot00000000000000/* * Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class StaticTree { private static final int MAX_BITS = 15; private static final int BL_CODES = 19; private static final int D_CODES = 30; private static final int LITERALS = 256; private static final int LENGTH_CODES = 29; private static final int L_CODES = (LITERALS + 1 + LENGTH_CODES); // Bit length codes must not exceed MAX_BL_BITS bits static final int MAX_BL_BITS = 7; static final short[] static_ltree = {12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8}; static final short[] static_dtree = {0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5}; static StaticTree static_l_desc = new StaticTree(static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); static StaticTree static_d_desc = new StaticTree(static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS); static StaticTree static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS); short[] static_tree; // static tree or null int[] extra_bits; // extra bits for each code or null int extra_base; // base index for extra_bits int elems; // max number of elements in the tree int max_length; // max bit length for the codes private StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length) { this.static_tree = static_tree; this.extra_bits = extra_bits; this.extra_base = extra_base; this.elems = elems; this.max_length = max_length; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/Tree.java000066400000000000000000000352451465436372100250040ustar00rootroot00000000000000/* * Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; final class Tree { private static final int MAX_BITS = 15; private static final int BL_CODES = 19; private static final int D_CODES = 30; private static final int LITERALS = 256; private static final int LENGTH_CODES = 29; private static final int L_CODES = (LITERALS + 1 + LENGTH_CODES); private static final int HEAP_SIZE = (2 * L_CODES + 1); // Bit length codes must not exceed MAX_BL_BITS bits static final int MAX_BL_BITS = 7; // end of block literal code static final int END_BLOCK = 256; // repeat previous bit length 3-6 times (2 bits of repeat count) static final int REP_3_6 = 16; // repeat a zero length 3-10 times (3 bits of repeat count) static final int REPZ_3_10 = 17; // repeat a zero length 11-138 times (7 bits of repeat count) static final int REPZ_11_138 = 18; // extra bits for each length code static final int[] extra_lbits = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; // extra bits for each distance code static final int[] extra_dbits = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; // extra bits for each bit length code static final int[] extra_blbits = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; static final byte[] bl_order = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; // The lengths of the bit length codes are sent in order of decreasing // probability, to avoid transmitting the lengths for unused bit // length codes. static final int Buf_size = 8 * 2; // see definition of array dist_code below static final int DIST_CODE_LEN = 512; static final byte[] _dist_code = {0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29}; static final byte[] _length_code = {0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28}; static final int[] base_length = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0}; static final int[] base_dist = {0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576}; // Mapping from a distance to a distance code. dist is the distance - 1 and // must not have side effects. _dist_code[256] and _dist_code[257] are never // used. static int d_code(int dist) { return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]); } short[] dyn_tree; // the dynamic tree int max_code; // largest code with non zero frequency StaticTree stat_desc; // the corresponding static tree // Compute the optimal bit lengths for a tree and update the total bit length // for the current block. // IN assertion: the fields freq and dad are set, heap[heap_max] and // above are the tree nodes sorted by increasing frequency. // OUT assertions: the field len is set to the optimal bit length, the // array bl_count contains the frequencies for each bit length. // The length opt_len is updated; static_len is also updated if stree is // not null. void gen_bitlen(Deflate s) { short[] tree = dyn_tree; short[] stree = stat_desc.static_tree; int[] extra = stat_desc.extra_bits; int base = stat_desc.extra_base; int max_length = stat_desc.max_length; int h; // heap index int n, m; // iterate over the tree elements int bits; // bit length int xbits; // extra bits short f; // frequency int overflow = 0; // number of elements with bit length too large for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; // In a first pass, compute the optimal bit lengths (which may // overflow in the case of the bit length tree). tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { n = s.heap[h]; bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; if (bits > max_length) { bits = max_length; overflow++; } tree[n * 2 + 1] = (short) bits; // We overwrite tree[n*2+1] which is no longer needed if (n > max_code) continue; // not a leaf node s.bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n - base]; f = tree[n * 2]; s.opt_len += f * (bits + xbits); if (stree != null) s.static_len += f * (stree[n * 2 + 1] + xbits); } if (overflow == 0) return; // This happens for example on obj2 and pic of the Calgary corpus // Find the first bit length which could increase: do { bits = max_length - 1; while (s.bl_count[bits] == 0) bits--; s.bl_count[bits]--; // move one leaf down the tree s.bl_count[bits + 1] += 2; // move one overflow item as its brother s.bl_count[max_length]--; // The brother of the overflow item also moves one step up, // but this does not affect bl_count[max_length] overflow -= 2; } while (overflow > 0); for (bits = max_length; bits != 0; bits--) { n = s.bl_count[bits]; while (n != 0) { m = s.heap[--h]; if (m > max_code) continue; if (tree[m * 2 + 1] != bits) { s.opt_len += (int) (((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); tree[m * 2 + 1] = (short) bits; } n--; } } } // Construct one Huffman tree and assigns the code bit strings and lengths. // Update the total bit length for the current block. // IN assertion: the field freq is set for all tree elements. // OUT assertions: the fields len and code are set to the optimal bit length // and corresponding code. The length opt_len is updated; static_len is // also updated if stree is not null. The field max_code is set. void build_tree(Deflate s) { short[] tree = dyn_tree; short[] stree = stat_desc.static_tree; int elems = stat_desc.elems; int n, m; // iterate over heap elements int max_code = -1; // largest code with non zero frequency int node; // new node being created // Construct the initial heap, with least frequent element in // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. // heap[0] is not used. s.heap_len = 0; s.heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n * 2] != 0) { s.heap[++s.heap_len] = max_code = n; s.depth[n] = 0; } else { tree[n * 2 + 1] = 0; } } // The pkzip format requires that at least one distance code exists, // and that at least one bit should be sent even if there is only one // possible code. So to avoid special checks later on we force at least // two codes of non zero frequency. while (s.heap_len < 2) { node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); tree[node * 2] = 1; s.depth[node] = 0; s.opt_len--; if (stree != null) s.static_len -= stree[node * 2 + 1]; // node is 0 or 1 so it does not have extra bits } this.max_code = max_code; // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, // establish sub-heaps of increasing lengths: for (n = s.heap_len / 2; n >= 1; n--) s.pqdownheap(tree, n); // Construct the Huffman tree by repeatedly combining the least two // frequent nodes. node = elems; // next internal node of the tree do { // n = node of least frequency n = s.heap[1]; s.heap[1] = s.heap[s.heap_len--]; s.pqdownheap(tree, 1); m = s.heap[1]; // m = node of next least frequency s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency s.heap[--s.heap_max] = m; // Create a new node father of n and m tree[node * 2] = (short) (tree[n * 2] + tree[m * 2]); s.depth[node] = (byte) (Math.max(s.depth[n], s.depth[m]) + 1); tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; // and insert the new node in the heap s.heap[1] = node++; s.pqdownheap(tree, 1); } while (s.heap_len >= 2); s.heap[--s.heap_max] = s.heap[1]; // At this point, the fields freq and dad are set. We can now // generate the bit lengths. gen_bitlen(s); // The field len is now set, we can generate the bit codes gen_codes(tree, max_code, s.bl_count, s.next_code); } // Generate the codes for a given tree and bit counts (which need not be // optimal). // IN assertion: the array bl_count contains the bit length statistics for // the given tree and the field len is set for all tree elements. // OUT assertion: the field code is set for all tree elements of non // zero code length. private static final void gen_codes(short[] tree, // the tree to decorate int max_code, // largest code with non zero frequency short[] bl_count, // number of codes at each bit length short[] next_code) { short code = 0; // running code value int bits; // bit index int n; // code index // The distribution counts are first used to generate the code values // without bit reversal. next_code[0] = 0; for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); } // Check that the bit counts in bl_count are consistent. The last code // must be all ones. // Assert (code + bl_count[MAX_BITS]-1 == (1<>>= 1; res <<= 1; } while (--len > 0); return res >>> 1; } } mwiede-jsch-c8efa3f/src/main/java/com/jcraft/jsch/jzlib/ZStream.java000066400000000000000000000237671465436372100255000ustar00rootroot00000000000000/* * Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors Jean-loup * Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) and contributors of zlib. */ package com.jcraft.jsch.jzlib; class ZStream { private static final int MAX_WBITS = 15; // 32K LZ77 window private static final int DEF_WBITS = MAX_WBITS; private static final int Z_NO_FLUSH = 0; private static final int Z_PARTIAL_FLUSH = 1; private static final int Z_SYNC_FLUSH = 2; private static final int Z_FULL_FLUSH = 3; private static final int Z_FINISH = 4; private static final int MAX_MEM_LEVEL = 9; private static final int Z_OK = 0; private static final int Z_STREAM_END = 1; private static final int Z_NEED_DICT = 2; private static final int Z_ERRNO = -1; private static final int Z_STREAM_ERROR = -2; private static final int Z_DATA_ERROR = -3; private static final int Z_MEM_ERROR = -4; private static final int Z_BUF_ERROR = -5; private static final int Z_VERSION_ERROR = -6; byte[] next_in; // next input byte int next_in_index; int avail_in; // number of bytes available at next_in long total_in; // total nb of input bytes read so far byte[] next_out; // next output byte should be put there int next_out_index; int avail_out; // remaining free space at next_out long total_out; // total nb of bytes output so far String msg; Deflate dstate; Inflate istate; int data_type; // best guess about the data type: ascii or binary Checksum adler; ZStream() { this(new Adler32()); } ZStream(Checksum adler) { this.adler = adler; } int inflateInit() { return inflateInit(DEF_WBITS); } int inflateInit(boolean nowrap) { return inflateInit(DEF_WBITS, nowrap); } int inflateInit(int w) { return inflateInit(w, false); } int inflateInit(JZlib.WrapperType wrapperType) { return inflateInit(DEF_WBITS, wrapperType); } int inflateInit(int w, JZlib.WrapperType wrapperType) { boolean nowrap = false; if (wrapperType == JZlib.W_NONE) { nowrap = true; } else if (wrapperType == JZlib.W_GZIP) { w += 16; } else if (wrapperType == JZlib.W_ANY) { w |= Inflate.INFLATE_ANY; } else if (wrapperType == JZlib.W_ZLIB) { } return inflateInit(w, nowrap); } int inflateInit(int w, boolean nowrap) { istate = new Inflate(this); return istate.inflateInit(nowrap ? -w : w); } int inflate(int f) { if (istate == null) return Z_STREAM_ERROR; return istate.inflate(f); } int inflateEnd() { if (istate == null) return Z_STREAM_ERROR; int ret = istate.inflateEnd(); // istate = null; return ret; } int inflateSync() { if (istate == null) return Z_STREAM_ERROR; return istate.inflateSync(); } int inflateSyncPoint() { if (istate == null) return Z_STREAM_ERROR; return istate.inflateSyncPoint(); } int inflateSetDictionary(byte[] dictionary, int dictLength) { if (istate == null) return Z_STREAM_ERROR; return istate.inflateSetDictionary(dictionary, dictLength); } boolean inflateFinished() { return istate.mode == 12 /* DONE */; } int deflateInit(int level) { return deflateInit(level, MAX_WBITS); } int deflateInit(int level, boolean nowrap) { return deflateInit(level, MAX_WBITS, nowrap); } int deflateInit(int level, int bits) { return deflateInit(level, bits, false); } int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) { if (bits < 9 || bits > 15) { return Z_STREAM_ERROR; } if (wrapperType == JZlib.W_NONE) { bits *= -1; } else if (wrapperType == JZlib.W_GZIP) { bits += 16; } else if (wrapperType == JZlib.W_ANY) { return Z_STREAM_ERROR; } else if (wrapperType == JZlib.W_ZLIB) { } return this.deflateInit(level, bits, memlevel); } int deflateInit(int level, int bits, int memlevel) { dstate = new Deflate(this); return dstate.deflateInit(level, bits, memlevel); } int deflateInit(int level, int bits, boolean nowrap) { dstate = new Deflate(this); return dstate.deflateInit(level, nowrap ? -bits : bits); } int deflate(int flush) { if (dstate == null) { return Z_STREAM_ERROR; } return dstate.deflate(flush); } int deflateEnd() { if (dstate == null) return Z_STREAM_ERROR; int ret = dstate.deflateEnd(); dstate = null; return ret; } int deflateParams(int level, int strategy) { if (dstate == null) return Z_STREAM_ERROR; return dstate.deflateParams(level, strategy); } int deflateSetDictionary(byte[] dictionary, int dictLength) { if (dstate == null) return Z_STREAM_ERROR; return dstate.deflateSetDictionary(dictionary, dictLength); } // Flush as much pending output as possible. All deflate() output goes // through this function so some applications may wish to modify it // to avoid allocating a large strm->next_out buffer and copying into it. // (See also read_buf()). void flush_pending() { int len = dstate.pending; if (len > avail_out) len = avail_out; if (len == 0) return; if (dstate.pending_buf.length <= dstate.pending_out || next_out.length <= next_out_index || dstate.pending_buf.length < (dstate.pending_out + len) || next_out.length < (next_out_index + len)) { // System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ // ", "+next_out.length+", "+next_out_index+", "+len); // System.out.println("avail_out="+avail_out); } System.arraycopy(dstate.pending_buf, dstate.pending_out, next_out, next_out_index, len); next_out_index += len; dstate.pending_out += len; total_out += len; avail_out -= len; dstate.pending -= len; if (dstate.pending == 0) { dstate.pending_out = 0; } } // Read a new buffer from the current input stream, update the adler32 // and total number of bytes read. All deflate() input goes through // this function so some applications may wish to modify it to avoid // allocating a large strm->next_in buffer and copying from it. // (See also flush_pending()). int read_buf(byte[] buf, int start, int size) { int len = avail_in; if (len > size) len = size; if (len == 0) return 0; avail_in -= len; if (dstate.wrap != 0) { adler.update(next_in, next_in_index, len); } System.arraycopy(next_in, next_in_index, buf, start, len); next_in_index += len; total_in += len; return len; } long getAdler() { return adler.getValue(); } void free() { next_in = null; next_out = null; msg = null; } void setOutput(byte[] buf) { setOutput(buf, 0, buf.length); } void setOutput(byte[] buf, int off, int len) { next_out = buf; next_out_index = off; avail_out = len; } void setInput(byte[] buf) { setInput(buf, 0, buf.length, false); } void setInput(byte[] buf, boolean append) { setInput(buf, 0, buf.length, append); } void setInput(byte[] buf, int off, int len, boolean append) { if (len <= 0 && append && next_in != null) return; if (avail_in > 0 && append) { byte[] tmp = new byte[avail_in + len]; System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); System.arraycopy(buf, off, tmp, avail_in, len); next_in = tmp; next_in_index = 0; avail_in += len; } else { next_in = buf; next_in_index = off; avail_in = len; } } byte[] getNextIn() { return next_in; } void setNextIn(byte[] next_in) { this.next_in = next_in; } int getNextInIndex() { return next_in_index; } void setNextInIndex(int next_in_index) { this.next_in_index = next_in_index; } int getAvailIn() { return avail_in; } void setAvailIn(int avail_in) { this.avail_in = avail_in; } byte[] getNextOut() { return next_out; } void setNextOut(byte[] next_out) { this.next_out = next_out; } int getNextOutIndex() { return next_out_index; } void setNextOutIndex(int next_out_index) { this.next_out_index = next_out_index; } int getAvailOut() { return avail_out; } void setAvailOut(int avail_out) { this.avail_out = avail_out; } long getTotalOut() { return total_out; } long getTotalIn() { return total_in; } String getMessage() { return msg; } // Those methods are expected to be override by Inflater and Deflater. // In the future, they will become abstract methods. int end() { return Z_OK; } boolean finished() { return false; } } mwiede-jsch-c8efa3f/src/main/java10/000077500000000000000000000000001465436372100173025ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java10/com/000077500000000000000000000000001465436372100200605ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java10/com/jcraft/000077500000000000000000000000001465436372100213315ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java10/com/jcraft/jsch/000077500000000000000000000000001465436372100222605ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java10/com/jcraft/jsch/JavaVersion.java000066400000000000000000000001771465436372100253570ustar00rootroot00000000000000package com.jcraft.jsch; final class JavaVersion { static int getVersion() { return Runtime.version().feature(); } } mwiede-jsch-c8efa3f/src/main/java11/000077500000000000000000000000001465436372100173035ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java11/com/000077500000000000000000000000001465436372100200615ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java11/com/jcraft/000077500000000000000000000000001465436372100213325ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java11/com/jcraft/jsch/000077500000000000000000000000001465436372100222615ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java11/com/jcraft/jsch/jce/000077500000000000000000000000001465436372100230225ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java11/com/jcraft/jsch/jce/XDH.java000066400000000000000000000112261465436372100243120ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.security.interfaces.XECPublicKey; import java.security.spec.NamedParameterSpec; import java.security.spec.XECPublicKeySpec; import java.util.Arrays; import javax.crypto.KeyAgreement; public class XDH implements com.jcraft.jsch.XDH { byte[] Q_array; XECPublicKey publicKey; int keylen; private KeyAgreement myKeyAgree; @Override public void init(String name, int keylen) throws Exception { this.keylen = keylen; myKeyAgree = KeyAgreement.getInstance("XDH"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH"); NamedParameterSpec paramSpec = new NamedParameterSpec(name); kpg.initialize(paramSpec); KeyPair kp = kpg.genKeyPair(); publicKey = (XECPublicKey) kp.getPublic(); Q_array = rotate(publicKey.getU().toByteArray()); myKeyAgree.init(kp.getPrivate()); } @Override public byte[] getQ() throws Exception { return Q_array; } @Override public byte[] getSecret(byte[] Q) throws Exception { // The u coordinate in BigInteger format needs to be a positive value. // So zero extend the little-endian input before rotating into big-endian. // This should ensure that we end up with a positive BigInteger value. Q = rotate(Q); byte[] u = new byte[keylen + 1]; System.arraycopy(Q, 0, u, 1, keylen); XECPublicKeySpec spec = new XECPublicKeySpec(publicKey.getParams(), new BigInteger(u)); KeyFactory kf = KeyFactory.getInstance("XDH"); PublicKey theirPublicKey = kf.generatePublic(spec); myKeyAgree.doPhase(theirPublicKey, true); return myKeyAgree.generateSecret(); } // https://cr.yp.to/ecdh.html#validate // RFC 8731, // 3. Key Exchange Methods // Clients and servers MUST // also abort if the length of the received public keys are not the // expected lengths. An abort for these purposes is defined as a // disconnect (SSH_MSG_DISCONNECT) of the session and SHOULD use the // SSH_DISCONNECT_KEY_EXCHANGE_FAILED reason for the message // [IANA-REASON]. No further validation is required beyond what is // described in [RFC7748]. @Override public boolean validate(byte[] u) throws Exception { return u.length == keylen; } // RFC 7748, // 5. The X25519 and X448 Functions // The u-coordinates are elements of the underlying field GF(2^255 - 19) // or GF(2^448 - 2^224 - 1) and are encoded as an array of bytes, u, in // little-endian order such that u[0] + 256*u[1] + 256^2*u[2] + ... + // 256^(n-1)*u[n-1] is congruent to the value modulo p and u[n-1] is // minimal. When receiving such an array, implementations of X25519 // (but not X448) MUST mask the most significant bit in the final byte. // This is done to preserve compatibility with point formats that // reserve the sign bit for use in other protocols and to increase // resistance to implementation fingerprinting. private byte[] rotate(byte[] in) { int len = in.length; byte[] out = new byte[len]; for (int i = 0; i < len; i++) { out[i] = in[len - i - 1]; } return Arrays.copyOf(out, keylen); } } mwiede-jsch-c8efa3f/src/main/java15/000077500000000000000000000000001465436372100173075ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java15/com/000077500000000000000000000000001465436372100200655ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/000077500000000000000000000000001465436372100213365ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/jsch/000077500000000000000000000000001465436372100222655ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/jsch/jce/000077500000000000000000000000001465436372100230265ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/jsch/jce/KeyPairGenEdDSA.java000066400000000000000000000053141465436372100264730ustar00rootroot00000000000000/* * Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.EdECPrivateKey; import java.security.interfaces.EdECPublicKey; import java.security.spec.EdECPoint; import java.util.Arrays; public class KeyPairGenEdDSA implements com.jcraft.jsch.KeyPairGenEdDSA { byte[] prv; // private byte[] pub; // public int keylen; @Override public void init(String name, int keylen) throws Exception { this.keylen = keylen; KeyPairGenerator keyGen = KeyPairGenerator.getInstance(name); KeyPair pair = keyGen.generateKeyPair(); EdECPublicKey pubKey = (EdECPublicKey) pair.getPublic(); EdECPrivateKey prvKey = (EdECPrivateKey) pair.getPrivate(); EdECPoint point = pubKey.getPoint(); prv = prvKey.getBytes().get(); pub = rotate(point.getY().toByteArray()); if (point.isXOdd()) { pub[pub.length - 1] |= (byte) 0x80; } } @Override public byte[] getPrv() { return prv; } @Override public byte[] getPub() { return pub; } private byte[] rotate(byte[] in) { int len = in.length; byte[] out = new byte[len]; for (int i = 0; i < len; i++) { out[i] = in[len - i - 1]; } return Arrays.copyOf(out, keylen); } } mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/jsch/jce/SignatureEd25519.java000066400000000000000000000033331465436372100265130ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureEd25519 extends SignatureEdDSA { @Override String getName() { return "ssh-ed25519"; } @Override String getAlgo() { return "Ed25519"; } @Override int getKeylen() { return 32; } } mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/jsch/jce/SignatureEd448.java000066400000000000000000000033251465436372100263460ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; public class SignatureEd448 extends SignatureEdDSA { @Override String getName() { return "ssh-ed448"; } @Override String getAlgo() { return "Ed448"; } @Override int getKeylen() { return 57; } } mwiede-jsch-c8efa3f/src/main/java15/com/jcraft/jsch/jce/SignatureEdDSA.java000066400000000000000000000114571465436372100264430ustar00rootroot00000000000000/* * Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; import com.jcraft.jsch.Buffer; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.EdECPoint; import java.security.spec.EdECPrivateKeySpec; import java.security.spec.EdECPublicKeySpec; import java.security.spec.NamedParameterSpec; import java.util.Arrays; abstract class SignatureEdDSA implements com.jcraft.jsch.SignatureEdDSA { Signature signature; KeyFactory keyFactory; abstract String getName(); abstract String getAlgo(); abstract int getKeylen(); @Override public void init() throws Exception { signature = Signature.getInstance("EdDSA"); keyFactory = KeyFactory.getInstance("EdDSA"); } // RFC 8032, // 5.1. Ed25519ph, Ed25519ctx, and Ed25519 // ... // 5.1.3. Decoding // Decoding a point, given as a 32-octet string, is a little more // complicated. // // 1. First, interpret the string as an integer in little-endian // representation. Bit 255 of this number is the least significant // bit of the x-coordinate and denote this value x_0. The // y-coordinate is recovered simply by clearing this bit. If the // resulting value is >= p, decoding fails. // // 5.2. Ed448ph and Ed448 // ... // 5.2.3. Decoding // Decoding a point, given as a 57-octet string, is a little more // complicated. // // 1. First, interpret the string as an integer in little-endian // representation. Bit 455 of this number is the least significant // bit of the x-coordinate and denote this value x_0. The // y-coordinate is recovered simply by clearing this bit. If the // resulting value is >= p, decoding fails. @Override public void setPubKey(byte[] y_arr) throws Exception { y_arr = rotate(y_arr); boolean xOdd = (y_arr[0] & 0x80) != 0; y_arr[0] &= 0x7f; BigInteger y = new BigInteger(y_arr); NamedParameterSpec paramSpec = new NamedParameterSpec(getAlgo()); EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdECPoint(xOdd, y)); PublicKey pubKey = keyFactory.generatePublic(pubSpec); signature.initVerify(pubKey); } @Override public void setPrvKey(byte[] bytes) throws Exception { NamedParameterSpec paramSpec = new NamedParameterSpec(getAlgo()); EdECPrivateKeySpec privSpec = new EdECPrivateKeySpec(paramSpec, bytes); PrivateKey prvKey = keyFactory.generatePrivate(privSpec); signature.initSign(prvKey); } @Override public byte[] sign() throws Exception { byte[] sig = signature.sign(); return sig; } @Override public void update(byte[] foo) throws Exception { signature.update(foo); } @Override public boolean verify(byte[] sig) throws Exception { int i = 0; int j = 0; byte[] tmp; Buffer buf = new Buffer(sig); String foo = new String(buf.getString(), StandardCharsets.UTF_8); if (foo.equals(getName())) { j = buf.getInt(); i = buf.getOffSet(); tmp = new byte[j]; System.arraycopy(sig, i, tmp, 0, j); sig = tmp; } return signature.verify(sig); } private byte[] rotate(byte[] in) { int len = in.length; byte[] out = new byte[len]; for (int i = 0; i < len; i++) { out[i] = in[len - i - 1]; } return Arrays.copyOf(out, getKeylen()); } } mwiede-jsch-c8efa3f/src/main/java16/000077500000000000000000000000001465436372100173105ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java16/com/000077500000000000000000000000001465436372100200665ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java16/com/jcraft/000077500000000000000000000000001465436372100213375ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java16/com/jcraft/jsch/000077500000000000000000000000001465436372100222665ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java16/com/jcraft/jsch/UnixDomainSocketFactory.java000066400000000000000000000046761465436372100277220ustar00rootroot00000000000000/* * Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided with * the distribution. * * 3. The names of the authors may not be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch; import java.io.IOException; import java.net.StandardProtocolFamily; import java.net.UnixDomainSocketAddress; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.file.Path; public class UnixDomainSocketFactory implements USocketFactory { public UnixDomainSocketFactory() throws AgentProxyException {} @Override public SocketChannel connect(Path path) throws IOException { UnixDomainSocketAddress sockAddr = UnixDomainSocketAddress.of(path); SocketChannel sock = SocketChannel.open(StandardProtocolFamily.UNIX); sock.configureBlocking(true); sock.connect(sockAddr); return sock; } @Override public ServerSocketChannel bind(Path path) throws IOException { UnixDomainSocketAddress sockAddr = UnixDomainSocketAddress.of(path); ServerSocketChannel sock = ServerSocketChannel.open(StandardProtocolFamily.UNIX); sock.configureBlocking(true); sock.bind(sockAddr); return sock; } } mwiede-jsch-c8efa3f/src/main/java9/000077500000000000000000000000001465436372100172325ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java9/com/000077500000000000000000000000001465436372100200105ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java9/com/jcraft/000077500000000000000000000000001465436372100212615ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java9/com/jcraft/jsch/000077500000000000000000000000001465436372100222105ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/main/java9/com/jcraft/jsch/JavaVersion.java000066400000000000000000000003411465436372100253000ustar00rootroot00000000000000package com.jcraft.jsch; import com.jcraft.jsch.annotations.SuppressForbiddenApi; final class JavaVersion { @SuppressForbiddenApi("jdk-deprecated") static int getVersion() { return Runtime.version().major(); } } mwiede-jsch-c8efa3f/src/main/java9/com/jcraft/jsch/JplLogger.java000066400000000000000000000021501465436372100247360ustar00rootroot00000000000000package com.jcraft.jsch; import java.lang.System.Logger; import java.lang.System.Logger.Level; public class JplLogger implements com.jcraft.jsch.Logger { private static final Logger logger = System.getLogger(JSch.class.getName()); public JplLogger() {} @Override public boolean isEnabled(int level) { return logger.isLoggable(getLevel(level)); } @Override public void log(int level, String message) { logger.log(getLevel(level), message); } @Override public void log(int level, String message, Throwable cause) { if (cause == null) { logger.log(getLevel(level), message); return; } logger.log(getLevel(level), message, cause); } private static Level getLevel(int level) { switch (level) { case com.jcraft.jsch.Logger.DEBUG: return Level.DEBUG; case com.jcraft.jsch.Logger.INFO: return Level.INFO; case com.jcraft.jsch.Logger.WARN: return Level.WARNING; case com.jcraft.jsch.Logger.ERROR: case com.jcraft.jsch.Logger.FATAL: return Level.ERROR; default: return Level.TRACE; } } } mwiede-jsch-c8efa3f/src/main/java9/module-info.java000066400000000000000000000005431465436372100223150ustar00rootroot00000000000000module com.jcraft.jsch { exports com.jcraft.jsch; requires static com.sun.jna; requires static com.sun.jna.platform; requires static java.logging; requires static java.security.jgss; requires static org.apache.logging.log4j; requires static org.bouncycastle.provider; requires static org.newsclub.net.unix; requires static org.slf4j; } mwiede-jsch-c8efa3f/src/test/000077500000000000000000000000001465436372100162535ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/000077500000000000000000000000001465436372100171745ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/com/000077500000000000000000000000001465436372100177525ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/com/jcraft/000077500000000000000000000000001465436372100212235ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/000077500000000000000000000000001465436372100221525ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/AbstractBufferMargin.java000066400000000000000000000231711465436372100270540ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.input.BoundedInputStream; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public abstract class AbstractBufferMargin { // Python can be slow for DH group 18 private static final int timeout = 10000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(AbstractBufferMargin.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd; protected AbstractBufferMargin(int maxPktSize) { sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("asyncsshd.py", "docker/asyncsshd.py") .withFileFromClasspath("ssh_host_ed448_key", "docker/ssh_host_ed448_key") .withFileFromClasspath("ssh_host_ed448_key.pub", "docker/ssh_host_ed448_key.pub") .withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.asyncssh") .withBuildArg("MAX_PKTSIZE", Integer.toString(maxPktSize))) .withExposedPorts(22); } @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } protected void doTestSftp(String cipher, String mac, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("cipher.s2c", cipher); session.setConfig("cipher.c2s", cipher); session.setConfig("mac.s2c", mac); session.setConfig("mac.c2s", mac); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); doSftp(session, true); } protected void doTestScp(String cipher, String mac, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("cipher.s2c", cipher); session.setConfig("cipher.c2s", cipher); session.setConfig("mac.s2c", mac); session.setConfig("mac.c2s", mac); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); doScp(session, true); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void doScp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelExec scp; scp = (ChannelExec) session.openChannel("exec"); try (InputStream is = scp.getInputStream()) { try (OutputStream os = scp.getOutputStream()) { scp.setCommand("scp -t /root/test"); scp.connect(timeout); checkAck(is); String cmd = "C0644 102400 test\n"; os.write(cmd.getBytes(UTF_8)); os.flush(); checkAck(is); Files.copy(in, os); os.flush(); sendAck(os); checkAck(is); } } while (scp.isConnected()) { Thread.sleep(100L); } scp = (ChannelExec) session.openChannel("exec"); try (OutputStream os = scp.getOutputStream()) { try (InputStream is = scp.getInputStream()) { scp.setCommand("scp -f /root/test"); scp.connect(timeout); sendAck(os); int c = checkAck(is); if (c == 'C') { byte[] buf = new byte[17]; is.read(buf, 0, 17); sendAck(os); Files.copy( BoundedInputStream.builder().setMaxCount(100L * 1024L).setInputStream(is).get(), out); checkAck(is); sendAck(os); } } } while (scp.isConnected()) { Thread.sleep(100L); } session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private static int checkAck(InputStream is) throws IOException { int b = is.read(); if (b == 0) { return b; } else if (b == -1) { throw new IOException("no response"); } StringBuilder sb = new StringBuilder(); if (b == 1 || b == 2) { int c = is.read(); while (c > 0 && c != '\n') { sb.append((char) c); c = is.read(); } } switch (b) { case 1: throw new IOException("error: " + sb); case 2: throw new IOException("fatal error: " + sb); default: return b; } } private static void sendAck(OutputStream os) throws IOException { byte[] ack = new byte[1]; ack[0] = 0; os.write(ack); os.flush(); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/Algorithms2IT.java000066400000000000000000000366441465436372100254620ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.JRE.JAVA_11; import static org.junit.jupiter.api.condition.JRE.JAVA_15; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class Algorithms2IT { // Python can be slow for DH group 18 private static final int timeout = 10000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(Algorithms2IT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("asyncsshd.py", "docker/asyncsshd.py") .withFileFromClasspath("ssh_host_ed448_key", "docker/ssh_host_ed448_key") .withFileFromClasspath("ssh_host_ed448_key.pub", "docker/ssh_host_ed448_key.pub") .withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.asyncssh")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test @EnabledForJreRange(min = JAVA_11) public void testJava11KEXs() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("xdh", "com.jcraft.jsch.jce.XDH"); session.setConfig("kex", "curve448-sha512"); doSftp(session, true); String expected = "kex: algorithm: curve448-sha512.*"; checkLogs(expected); } @Test public void testBCKEXs() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("xdh", "com.jcraft.jsch.bc.XDH"); session.setConfig("kex", "curve448-sha512"); doSftp(session, true); String expected = "kex: algorithm: curve448-sha512.*"; checkLogs(expected); } @ParameterizedTest @ValueSource(strings = {"curve448-sha512", "diffie-hellman-group17-sha512", "diffie-hellman-group15-sha512", "diffie-hellman-group18-sha512@ssh.com", "diffie-hellman-group16-sha512@ssh.com", "diffie-hellman-group16-sha384@ssh.com", "diffie-hellman-group15-sha384@ssh.com", "diffie-hellman-group15-sha256@ssh.com", "diffie-hellman-group14-sha256@ssh.com", "diffie-hellman-group14-sha224@ssh.com", "diffie-hellman-group-exchange-sha512@ssh.com", "diffie-hellman-group-exchange-sha384@ssh.com", "diffie-hellman-group-exchange-sha224@ssh.com"}) public void testKEXs(String kex) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("kex", kex); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); checkLogs(expected); } @ParameterizedTest @CsvSource(value = {"diffie-hellman-group-exchange-sha256,1024", "diffie-hellman-group-exchange-sha1,1024", "diffie-hellman-group-exchange-sha512@ssh.com,1024", "diffie-hellman-group-exchange-sha512@ssh.com,2048", "diffie-hellman-group-exchange-sha512@ssh.com,4096", "diffie-hellman-group-exchange-sha512@ssh.com,6144", "diffie-hellman-group-exchange-sha512@ssh.com,8192", "diffie-hellman-group-exchange-sha384@ssh.com,1024", "diffie-hellman-group-exchange-sha384@ssh.com,2048", "diffie-hellman-group-exchange-sha384@ssh.com,4096", "diffie-hellman-group-exchange-sha384@ssh.com,6144", "diffie-hellman-group-exchange-sha384@ssh.com,8192", "diffie-hellman-group-exchange-sha224@ssh.com,1024", "diffie-hellman-group-exchange-sha224@ssh.com,2048", "diffie-hellman-group-exchange-sha224@ssh.com,4096", "diffie-hellman-group-exchange-sha224@ssh.com,6144", "diffie-hellman-group-exchange-sha224@ssh.com,8192"}) public void testDHGEXSizes(String kex, String size) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("kex", kex); session.setConfig("dhgex_min", size); session.setConfig("dhgex_max", size); session.setConfig("dhgex_preferred", size); doSftp(session, true); String expectedKex = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); String expectedSizes = String.format(Locale.ROOT, "SSH_MSG_KEX_DH_GEX_REQUEST\\(%s<%s<%s\\) sent", size, size, size); checkLogs(expectedKex); checkLogs(expectedSizes); } @Test @EnabledForJreRange(min = JAVA_15) public void testJava15Ed448() throws Exception { JSch ssh = createEd448Identity(); Session session = createSession(ssh); session.setConfig("keypairgen.eddsa", "com.jcraft.jsch.jce.KeyPairGenEdDSA"); session.setConfig("ssh-ed448", "com.jcraft.jsch.jce.SignatureEd448"); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed448"); session.setConfig("server_host_key", "ssh-ed448"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-ed448.*"; checkLogs(expected); } @Test public void testBCEd448() throws Exception { JSch ssh = createEd448Identity(); Session session = createSession(ssh); session.setConfig("keypairgen.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA"); session.setConfig("ssh-ed448", "com.jcraft.jsch.bc.SignatureEd448"); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed448"); session.setConfig("server_host_key", "ssh-ed448"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-ed448.*"; checkLogs(expected); } @Test public void testEd448() throws Exception { JSch ssh = createEd448Identity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed448"); session.setConfig("server_host_key", "ssh-ed448"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-ed448.*"; checkLogs(expected); } @ParameterizedTest @ValueSource(strings = {"ssh-rsa-sha512@ssh.com", "ssh-rsa-sha384@ssh.com", "ssh-rsa-sha256@ssh.com", "ssh-rsa-sha224@ssh.com"}) public void testRSA(String keyType) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", keyType); session.setConfig("server_host_key", keyType); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: host key algorithm: %s.*", keyType); checkLogs(expected); } @ParameterizedTest @CsvSource(value = {"seed-cbc@ssh.com,none", "seed-cbc@ssh.com,zlib@openssh.com"}) public void testCiphers(String cipher, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("cipher.s2c", cipher); session.setConfig("cipher.c2s", cipher); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); doSftp(session, true); String expectedS2C = String.format(Locale.ROOT, "kex: server->client cipher: %s.*", cipher); String expectedC2S = String.format(Locale.ROOT, "kex: client->server cipher: %s.*", cipher); checkLogs(expectedS2C); checkLogs(expectedC2S); } @ParameterizedTest @CsvSource(value = {"hmac-sha512@ssh.com,none", "hmac-sha512@ssh.com,zlib@openssh.com", "hmac-sha384@ssh.com,none", "hmac-sha384@ssh.com,zlib@openssh.com", "hmac-sha256-2@ssh.com,none", "hmac-sha256-2@ssh.com,zlib@openssh.com", "hmac-sha256@ssh.com,none", "hmac-sha256@ssh.com,zlib@openssh.com", "hmac-sha224@ssh.com,none", "hmac-sha224@ssh.com,zlib@openssh.com"}) public void testMACs(String mac, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("mac.s2c", mac); session.setConfig("mac.c2s", mac); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); // Make sure a non-AEAD cipher is used session.setConfig("cipher.s2c", "aes128-ctr"); session.setConfig("cipher.c2s", "aes128-ctr"); doSftp(session, true); String expectedS2C = String.format(Locale.ROOT, "kex: server->client .* MAC: %s.*", mac); String expectedC2S = String.format(Locale.ROOT, "kex: client->server .* MAC: %s.*", mac); checkLogs(expectedS2C); checkLogs(expectedC2S); } @Test public void testCompressions() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("compression.s2c", "zlib"); session.setConfig("compression.c2s", "zlib"); doSftp(session, true); String expectedS2C = "kex: server->client .* compression: zlib.*"; String expectedC2S = "kex: client->server .* compression: zlib.*"; checkLogs(expectedS2C); checkLogs(expectedC2S); } @ParameterizedTest @ValueSource(strings = {"com.jcraft.jsch.juz.Compression", "com.jcraft.jsch.jzlib.Compression"}) public void testCompressionImpls(String impl) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("compression.s2c", "zlib"); session.setConfig("compression.c2s", "zlib"); session.setConfig("zlib", impl); doSftp(session, true); String expectedImpl = String.format(Locale.ROOT, "zlib using %s", impl); String expectedS2C = "kex: server->client .* compression: zlib.*"; String expectedC2S = "kex: client->server .* compression: zlib.*"; checkLogs(expectedImpl); checkLogs(expectedS2C); checkLogs(expectedC2S); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createEd448Identity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_ed448_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_ed448"), getResourceFile("docker/id_ed448.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/Algorithms3IT.java000066400000000000000000000145731465436372100254600ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class Algorithms3IT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(Algorithms3IT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>(new ImageFromDockerfile() .withFileFromClasspath("dropbear_rsa_host_key", "docker/dropbear_rsa_host_key") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.dropbear")).withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @ParameterizedTest @CsvSource(value = {"3des-ctr,none", "3des-ctr,zlib@openssh.com"}) public void testCiphers(String cipher, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("cipher.s2c", cipher); session.setConfig("cipher.c2s", cipher); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); doSftp(session, true); String expectedS2C = String.format(Locale.ROOT, "kex: server->client cipher: %s.*", cipher); String expectedC2S = String.format(Locale.ROOT, "kex: client->server cipher: %s.*", cipher); checkLogs(expectedS2C); checkLogs(expectedC2S); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); // Dropbear does not support rsa-sha2-512/rsa-sha2-256, so add ssh-rsa String serverHostKey = session.getConfig("server_host_key") + ",ssh-rsa"; String pubkeyAcceptedAlgorithms = session.getConfig("PubkeyAcceptedAlgorithms") + ",ssh-rsa"; session.setConfig("server_host_key", serverHostKey); session.setConfig("PubkeyAcceptedAlgorithms", pubkeyAcceptedAlgorithms); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/Algorithms4IT.java000066400000000000000000000162301465436372100254510ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class Algorithms4IT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(Algorithms4IT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config.openssh96") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.openssh96")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @ParameterizedTest @ValueSource(strings = {"sntrup761x25519-sha512@openssh.com"}) public void testBCKEXs(String kex) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("kex", kex); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); checkLogs(expected); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); // Skip OpenSSH log checks, as log output from Docker falls behind and these assertions // frequently run before they are output // Optional actualSshd = // sshdLogger.getAllLoggingEvents().stream() // .map(LoggingEvent::getFormattedMessage) // .filter(msg -> msg.matches("STDERR: debug1: " + expected)) // .findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); // assertTrue(actualSshd.isPresent(), () -> "sshd: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/AlgorithmsIT.java000066400000000000000000000531511465436372100253700ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.JRE.JAVA_11; import static org.junit.jupiter.api.condition.JRE.JAVA_15; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class AlgorithmsIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(AlgorithmsIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @ParameterizedTest @ValueSource(strings = {"curve25519-sha256", "curve25519-sha256@libssh.org"}) @EnabledForJreRange(min = JAVA_11) public void testJava11KEXs(String kex) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("xdh", "com.jcraft.jsch.jce.XDH"); session.setConfig("kex", kex); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); checkLogs(expected); } @ParameterizedTest @ValueSource(strings = {"curve25519-sha256", "curve25519-sha256@libssh.org"}) public void testBCKEXs(String kex) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("xdh", "com.jcraft.jsch.bc.XDH"); session.setConfig("kex", kex); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); checkLogs(expected); } @ParameterizedTest @ValueSource(strings = {"curve25519-sha256", "curve25519-sha256@libssh.org", "ecdh-sha2-nistp521", "ecdh-sha2-nistp384", "ecdh-sha2-nistp256", "diffie-hellman-group18-sha512", "diffie-hellman-group16-sha512", "diffie-hellman-group14-sha256", "diffie-hellman-group-exchange-sha256", "diffie-hellman-group-exchange-sha1", "diffie-hellman-group14-sha1", "diffie-hellman-group1-sha1"}) public void testKEXs(String kex) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("kex", kex); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); checkLogs(expected); } @ParameterizedTest @CsvSource(value = {"diffie-hellman-group-exchange-sha256,2048", "diffie-hellman-group-exchange-sha256,3072", "diffie-hellman-group-exchange-sha256,4096", "diffie-hellman-group-exchange-sha256,6144", "diffie-hellman-group-exchange-sha256,8192", "diffie-hellman-group-exchange-sha1,2048", "diffie-hellman-group-exchange-sha1,3072", "diffie-hellman-group-exchange-sha1,4096", "diffie-hellman-group-exchange-sha1,6144", "diffie-hellman-group-exchange-sha1,8192"}) public void testDHGEXSizes(String kex, String size) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("kex", kex); session.setConfig("dhgex_min", size); session.setConfig("dhgex_max", size); session.setConfig("dhgex_preferred", size); doSftp(session, true); String expectedKex = String.format(Locale.ROOT, "kex: algorithm: %s.*", kex); String expectedSizes = String.format(Locale.ROOT, "SSH_MSG_KEX_DH_GEX_REQUEST\\(%s<%s<%s\\) sent", size, size, size); checkLogs(expectedKex); checkLogs(expectedSizes); } @Test @EnabledForJreRange(min = JAVA_15) public void testJava15Ed25519() throws Exception { JSch ssh = createEd25519Identity(); Session session = createSession(ssh); session.setConfig("keypairgen.eddsa", "com.jcraft.jsch.jce.KeyPairGenEdDSA"); session.setConfig("ssh-ed25519", "com.jcraft.jsch.jce.SignatureEd25519"); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed25519"); session.setConfig("server_host_key", "ssh-ed25519"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-ed25519.*"; checkLogs(expected); } @Test public void testBCEd25519() throws Exception { JSch ssh = createEd25519Identity(); Session session = createSession(ssh); session.setConfig("keypairgen.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA"); session.setConfig("ssh-ed25519", "com.jcraft.jsch.bc.SignatureEd25519"); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed25519"); session.setConfig("server_host_key", "ssh-ed25519"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-ed25519.*"; checkLogs(expected); } @Test public void testEd25519() throws Exception { JSch ssh = createEd25519Identity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed25519"); session.setConfig("server_host_key", "ssh-ed25519"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-ed25519.*"; checkLogs(expected); } @Test public void testECDSA521() throws Exception { JSch ssh = createECDSA521Identity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp521"); session.setConfig("server_host_key", "ecdsa-sha2-nistp521"); doSftp(session, true); String expected = "kex: host key algorithm: ecdsa-sha2-nistp521.*"; checkLogs(expected); } @Test public void testECDSA384() throws Exception { JSch ssh = createECDSA384Identity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp384"); session.setConfig("server_host_key", "ecdsa-sha2-nistp384"); doSftp(session, true); String expected = "kex: host key algorithm: ecdsa-sha2-nistp384.*"; checkLogs(expected); } @Test public void testECDSA256() throws Exception { JSch ssh = createECDSA256Identity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp256"); session.setConfig("server_host_key", "ecdsa-sha2-nistp256"); doSftp(session, true); String expected = "kex: host key algorithm: ecdsa-sha2-nistp256.*"; checkLogs(expected); } @ParameterizedTest @ValueSource(strings = {"rsa-sha2-512", "rsa-sha2-256", "ssh-rsa"}) public void testRSA(String keyType) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", keyType); session.setConfig("server_host_key", keyType); doSftp(session, true); String expected = String.format(Locale.ROOT, "kex: host key algorithm: %s.*", keyType); checkLogs(expected); } @Test public void testDSA() throws Exception { JSch ssh = createDSAIdentity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-dss"); session.setConfig("server_host_key", "ssh-dss"); doSftp(session, true); String expected = "kex: host key algorithm: ssh-dss.*"; checkLogs(expected); } @ParameterizedTest @CsvSource(value = {"chacha20-poly1305@openssh.com,none", "chacha20-poly1305@openssh.com,zlib@openssh.com", "aes256-gcm@openssh.com,none", "aes256-gcm@openssh.com,zlib@openssh.com", "aes128-gcm@openssh.com,none", "aes128-gcm@openssh.com,zlib@openssh.com", "aes256-ctr,none", "aes256-ctr,zlib@openssh.com", "aes192-ctr,none", "aes192-ctr,zlib@openssh.com", "aes128-ctr,none", "aes128-ctr,zlib@openssh.com", "aes256-cbc,none", "aes256-cbc,zlib@openssh.com", "aes192-cbc,none", "aes192-cbc,zlib@openssh.com", "aes128-cbc,none", "aes128-cbc,zlib@openssh.com", "3des-cbc,none", "3des-cbc,zlib@openssh.com", "blowfish-cbc,none", "blowfish-cbc,zlib@openssh.com", "arcfour,none", "arcfour,zlib@openssh.com", "arcfour256,none", "arcfour256,zlib@openssh.com", "arcfour128,none", "arcfour128,zlib@openssh.com", "rijndael-cbc@lysator.liu.se,none", "rijndael-cbc@lysator.liu.se,zlib@openssh.com", "cast128-cbc,none", "cast128-cbc,zlib@openssh.com"}) public void testCiphers(String cipher, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("cipher.s2c", cipher); session.setConfig("cipher.c2s", cipher); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); doSftp(session, true); String expectedS2C = String.format(Locale.ROOT, "kex: server->client cipher: %s.*", cipher); String expectedC2S = String.format(Locale.ROOT, "kex: client->server cipher: %s.*", cipher); checkLogs(expectedS2C); checkLogs(expectedC2S); } @ParameterizedTest @CsvSource(value = {"hmac-sha2-512-etm@openssh.com,none", "hmac-sha2-512-etm@openssh.com,zlib@openssh.com", "hmac-sha2-256-etm@openssh.com,none", "hmac-sha2-256-etm@openssh.com,zlib@openssh.com", "hmac-sha1-etm@openssh.com,none", "hmac-sha1-etm@openssh.com,zlib@openssh.com", "hmac-sha1-96-etm@openssh.com,none", "hmac-sha1-96-etm@openssh.com,zlib@openssh.com", "hmac-md5-etm@openssh.com,none", "hmac-md5-etm@openssh.com,zlib@openssh.com", "hmac-md5-96-etm@openssh.com,none", "hmac-md5-96-etm@openssh.com,zlib@openssh.com", "hmac-sha2-512,none", "hmac-sha2-512,zlib@openssh.com", "hmac-sha2-256,none", "hmac-sha2-256,zlib@openssh.com", "hmac-sha1,none", "hmac-sha1,zlib@openssh.com", "hmac-sha1-96,none", "hmac-sha1-96,zlib@openssh.com", "hmac-md5,none", "hmac-md5,zlib@openssh.com", "hmac-md5-96,none", "hmac-md5-96,zlib@openssh.com", "hmac-ripemd160,none", "hmac-ripemd160,zlib@openssh.com", "hmac-ripemd160@openssh.com,none", "hmac-ripemd160@openssh.com,zlib@openssh.com", "hmac-ripemd160-etm@openssh.com,none", "hmac-ripemd160-etm@openssh.com,zlib@openssh.com"}) public void testMACs(String mac, String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("mac.s2c", mac); session.setConfig("mac.c2s", mac); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); // Make sure a non-AEAD cipher is used session.setConfig("cipher.s2c", "aes128-ctr"); session.setConfig("cipher.c2s", "aes128-ctr"); doSftp(session, true); String expectedS2C = String.format(Locale.ROOT, "kex: server->client .* MAC: %s.*", mac); String expectedC2S = String.format(Locale.ROOT, "kex: client->server .* MAC: %s.*", mac); checkLogs(expectedS2C); checkLogs(expectedC2S); } @ParameterizedTest @ValueSource(strings = {"zlib@openssh.com", "none"}) public void testCompressions(String compression) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("compression.s2c", compression); session.setConfig("compression.c2s", compression); doSftp(session, true); String expectedS2C = String.format(Locale.ROOT, "kex: server->client .* compression: %s.*", compression); String expectedC2S = String.format(Locale.ROOT, "kex: client->server .* compression: %s.*", compression); checkLogs(expectedS2C); checkLogs(expectedC2S); } @ParameterizedTest @ValueSource(strings = {"com.jcraft.jsch.juz.Compression", "com.jcraft.jsch.jzlib.Compression"}) public void testCompressionImpls(String impl) throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("compression.s2c", "zlib@openssh.com"); session.setConfig("compression.c2s", "zlib@openssh.com"); session.setConfig("zlib@openssh.com", impl); doSftp(session, true); String expectedImpl = String.format(Locale.ROOT, "zlib using %s", impl); String expectedS2C = "kex: server->client .* compression: zlib@openssh\\.com.*"; String expectedC2S = "kex: client->server .* compression: zlib@openssh\\.com.*"; checkLogs(expectedImpl); checkLogs(expectedS2C); checkLogs(expectedC2S); } @ParameterizedTest @ValueSource(strings = { "SHA512:EyyvMhUehzuELz3ySpqMw2UggtNqVmWnTSrQy2x4FLT7aF1lmqKC30oF+VUOLhvTmFHYaDLLN9UnpuGphIltKQ", "SHA384:CMxHNJ/xzOfsmNqw4g6Be+ltVZX3ixtplON7nOspNlji0iMnWzM7X4SelzcpP7Ap", "SHA256:iqNO6JDjrpga8TvgBKGReaKEnGoF/1csoxWp/DV5xJ0", "SHA224:mJNHjKtQuiRHioFZIGj1g/+fcKMOsKmzcokU2w", "SHA1:FO2EB514+YMk4jTFmNGOwscY2Pk", "MD5:3b:50:5b:c5:53:66:8c:2c:98:9b:ee:3f:19:0a:ff:29"}) public void testFingerprintHashes(String fingerprint) throws Exception { String[] split = fingerprint.split(":"); String hash = split[0]; MockUserInfo userInfo = new MockUserInfo(); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-rsa"); session.setConfig("server_host_key", "ssh-rsa"); session.setConfig("StrictHostKeyChecking", "ask"); session.setConfig("FingerprintHash", hash); session.setUserInfo(userInfo); try { doSftp(session, false); } catch (JSchException expected) { } String expected = String.format(Locale.ROOT, "RSA key fingerprint is %s.", fingerprint); List msgs = userInfo.getMessages().stream().map(msg -> msg.split("\n")) .flatMap(Arrays::stream).collect(toList()); Optional actual = msgs.stream().filter(msg -> msg.equals(expected)).findFirst(); if (!actual.isPresent()) { msgs.forEach(System.out::println); printInfo(); } assertTrue(actual.isPresent()); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createECDSA256Identity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_ecdsa256_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_ecdsa256"), getResourceFile("docker/id_ecdsa256.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createECDSA384Identity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_ecdsa384_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_ecdsa384"), getResourceFile("docker/id_ecdsa384.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createECDSA521Identity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_ecdsa521_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_ecdsa521"), getResourceFile("docker/id_ecdsa521.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createDSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_dsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_dsa"), getResourceFile("docker/id_dsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createEd25519Identity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_ed25519_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_ed25519"), getResourceFile("docker/id_ed25519.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); // Skip OpenSSH log checks, as log output from Docker falls behind and these assertions // frequently run before they are output // Optional actualSshd = // sshdLogger.getAllLoggingEvents().stream() // .map(LoggingEvent::getFormattedMessage) // .filter(msg -> msg.matches("STDERR: debug1: " + expected)) // .findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); // assertTrue(actualSshd.isPresent(), () -> "sshd: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/ExtInfoInAuthIT.java000066400000000000000000000217761465436372100257540ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class ExtInfoInAuthIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(ServerSigAlgsIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config.ExtInfoInAuthIT") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.ExtInfoInAuthIT")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test public void testExtInfoInAuthYes() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh, "rsa"); session.setConfig("enable_ext_info_in_auth", "yes"); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-rsa"); doSftp(session, "rsa", true); String expectedServerKex = "server proposal: KEX algorithms: .*,ext-info-s,.*"; String expectedClientKex = "client proposal: KEX algorithms: .*,ext-info-c,.*"; String expected1 = "ext-info messaging supported by server"; String expected2 = "SSH_MSG_EXT_INFO sent"; String expectedServerSigAlgs1 = "server-sig-algs="; String expectedServerSigAlgs2 = "server-sig-algs=<.*ssh-rsa.*>"; String expectedServerSigAlgs3 = "server-sig-algs=<.*ecdsa.*>"; checkLogs(expectedServerKex); checkLogs(expectedClientKex); checkLogs(expected1); checkLogs(expected2); checkLogs(expectedServerSigAlgs1); checkLogs(expectedServerSigAlgs2); checkNoLogs(expectedServerSigAlgs3); } @Test public void testExtInfoInAuthNo() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh, "ecdsa"); session.setConfig("enable_ext_info_in_auth", "no"); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-rsa"); session.setTimeout(timeout); assertThrows(JSchException.class, session::connect, "Auth fail for methods 'publickey'"); String expectedServerKex = "server proposal: KEX algorithms: .*,ext-info-s,.*"; String expectedClientKex = "client proposal: KEX algorithms: .*,ext-info-c,.*"; String expected1 = "ext-info messaging supported by server"; String expected2 = "SSH_MSG_EXT_INFO sent"; String expectedServerSigAlgs1 = "server-sig-algs="; String expectedServerSigAlgs2 = "server-sig-algs=<.*ssh-rsa.*>"; String expectedServerSigAlgs3 = "server-sig-algs=<.*ecdsa.*>"; checkLogs(expectedServerKex); checkLogs(expectedClientKex); checkLogs(expected1); checkNoLogs(expected2); checkLogs(expectedServerSigAlgs1); checkNoLogs(expectedServerSigAlgs2); checkNoLogs(expectedServerSigAlgs3); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh, String username) throws Exception { Session session = ssh.getSession(username, sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, String username, boolean debugException) throws Exception { String testFile = String.format(Locale.ROOT, "/%s/test", username); try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), testFile); sftp.get(testFile, out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private void checkNoLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertFalse(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/JSchAlgoNegoFailExceptionIT.java000066400000000000000000000137041465436372100301750ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class JSchAlgoNegoFailExceptionIT { private static final int timeout = 2000; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile")) .withExposedPorts(22); @ParameterizedTest @CsvSource(delimiter = '|', value = { "kex|curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", "server_host_key|ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss", "cipher.c2s|chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-cbc,blowfish-cbc,arcfour,arcfour256,arcfour128,rijndael-cbc@lysator.liu.se,cast128-cbc", "cipher.s2c|chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-cbc,blowfish-cbc,arcfour,arcfour256,arcfour128,rijndael-cbc@lysator.liu.se,cast128-cbc", "mac.c2s|hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1,hmac-sha1-96-etm@openssh.com,hmac-sha1-96,hmac-md5-etm@openssh.com,hmac-md5,hmac-md5-96-etm@openssh.com,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-ripemd160-etm@openssh.com", "mac.s2c|hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1,hmac-sha1-96-etm@openssh.com,hmac-sha1-96,hmac-md5-etm@openssh.com,hmac-md5,hmac-md5-96-etm@openssh.com,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-ripemd160-etm@openssh.com", "compression.c2s|none,zlib@openssh.com", "compression.s2c|none,zlib@openssh.com", "lang.c2s|''", "lang.s2c|''"}) public void testJSchAlgoNegoFailException(String algorithmName, String serverProposal) throws Exception { String jschProposal = "foo"; JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig(algorithmName, jschProposal); session.setTimeout(timeout); JSchAlgoNegoFailException e = assertThrows(JSchAlgoNegoFailException.class, session::connect); if (algorithmName.equals("kex")) { jschProposal += ",ext-info-c,kex-strict-c-v00@openssh.com"; } String message = String.format(Locale.ROOT, "Algorithm negotiation fail: algorithmName=\"%s\" jschProposal=\"%s\" serverProposal=\"%s\"", algorithmName, jschProposal, serverProposal); assertEquals(message, e.getMessage()); assertEquals(algorithmName, e.getAlgorithmName()); assertEquals(jschProposal, e.getJSchProposal()); assertEquals(serverProposal, e.getServerProposal()); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/JSchStrictKexExceptionIT.java000066400000000000000000000076501465436372100276310ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertThrows; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class JSchStrictKexExceptionIT { private static final int timeout = 2000; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile")) .withExposedPorts(22); @Test public void testEnableStrictKexRequireStrictKex() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_strict_kex", "yes"); session.setConfig("require_strict_kex", "yes"); session.setTimeout(timeout); assertThrows(JSchStrictKexException.class, session::connect, "Strict KEX not supported by server"); } @Test public void testNoEnableStrictKexRequireStrictKex() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_strict_kex", "no"); session.setConfig("require_strict_kex", "yes"); session.setTimeout(timeout); assertThrows(JSchStrictKexException.class, session::connect, "Strict KEX not supported by server"); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/JSchTest.java000066400000000000000000000052261465436372100245110ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; import java.util.Hashtable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class JSchTest { @BeforeEach void resetJsch() { JSch.setLogger(null); } @Test void getPubkeyAcceptedKeyTypes() throws JSchException { JSch.setConfig("PubkeyAcceptedAlgorithms", "JSchTest111"); assertEquals("JSchTest111", JSch.getConfig("PubkeyAcceptedKeyTypes")); assertEquals("JSchTest111", JSch.getConfig("PubkeyAcceptedAlgorithms")); } @Test void setPubkeyAcceptedKeyTypes() throws JSchException { JSch.setConfig("PubkeyAcceptedKeyTypes", "JSchTest222"); assertEquals("JSchTest222", JSch.getConfig("PubkeyAcceptedKeyTypes")); assertEquals("JSchTest222", JSch.getConfig("PubkeyAcceptedAlgorithms")); } @Test void setPubkeyAcceptedKeyTypesHashtable() throws JSchException { Hashtable newconf = new Hashtable<>(); newconf.put("PubkeyAcceptedKeyTypes", "JSchTest333"); JSch.setConfig(newconf); assertEquals("JSchTest333", JSch.getConfig("PubkeyAcceptedKeyTypes")); assertEquals("JSchTest333", JSch.getConfig("PubkeyAcceptedAlgorithms")); } @Test void checkLoggerBehavior() throws Exception { assertSame(JSch.DEVNULL, JSch.logger, "initial static value of logger should be DEVNULL"); JSch jsch = new JSch(); assertSame(JSch.DEVNULL, jsch.getInstanceLogger(), "instance logger should be DEVNULL"); TestLogger staticLogger = new TestLogger(); TestLogger instanceLogger = new TestLogger(); JSch.setLogger(staticLogger); assertSame(staticLogger, JSch.logger, "mismatch with static logger"); assertSame(staticLogger, jsch.getInstanceLogger(), "instance should return static logger"); jsch.setInstanceLogger(instanceLogger); assertSame(staticLogger, JSch.logger, "mismatch with static logger"); assertSame(instanceLogger, jsch.getInstanceLogger(), "instance should return static logger"); jsch.setInstanceLogger(null); assertSame(staticLogger, JSch.logger, "mismatch with static logger"); assertSame(staticLogger, jsch.getInstanceLogger(), "instance should return static logger"); JSch.setLogger(null); assertSame(JSch.DEVNULL, JSch.logger, "static logger should be DEVNULL"); assertSame(JSch.DEVNULL, jsch.getInstanceLogger(), "instance logger should be DEVNULL"); } static final class TestLogger implements Logger { @Override public boolean isEnabled(int level) { return true; } @Override public void log(int level, String message) { // empty } } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/JulLoggerTest.java000066400000000000000000000206771465436372100255630ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.stream.Collectors; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class JulLoggerTest { private static final Logger logger = Logger.getLogger(JSch.class.getName()); private static final ListHandler handler = new ListHandler(); private final Exception testException = new Exception("dummy exception"); @BeforeAll public static void beforeAll() { LogManager.getLogManager().reset(); Arrays.stream(logger.getHandlers()).forEach(logger::removeHandler); logger.addHandler(handler); logger.setLevel(Level.ALL); logger.setUseParentHandlers(false); Logger.getLogger("").setLevel(Level.OFF); } @BeforeEach public void beforeEach() { handler.clear(); } @AfterAll public static void afterAll() { LogManager.getLogManager().reset(); } @Test public void testGetLevel() { assertEquals(Level.FINER, JulLogger.getLevel(-1)); assertEquals(Level.FINE, JulLogger.getLevel(com.jcraft.jsch.Logger.DEBUG)); assertEquals(Level.SEVERE, JulLogger.getLevel(com.jcraft.jsch.Logger.ERROR)); assertEquals(Level.SEVERE, JulLogger.getLevel(com.jcraft.jsch.Logger.FATAL)); assertEquals(Level.INFO, JulLogger.getLevel(com.jcraft.jsch.Logger.INFO)); assertEquals(Level.WARNING, JulLogger.getLevel(com.jcraft.jsch.Logger.WARN)); assertEquals(Level.FINER, JulLogger.getLevel(Integer.MAX_VALUE)); } @Test public void testIsEnabled() { JulLogger jl = new JulLogger(); logger.setLevel(Level.FINEST); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertTrue(jl.isEnabled(-1), "trace should be enabled"); logger.setLevel(Level.FINE); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(jl.isEnabled(-1), "trace should not be enabled"); logger.setLevel(Level.SEVERE); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(jl.isEnabled(-1), "trace should not be enabled"); logger.setLevel(Level.INFO); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(jl.isEnabled(-1), "trace should not be enabled"); logger.setLevel(Level.OFF); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should not be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should not be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(jl.isEnabled(-1), "trace should not be enabled"); logger.setLevel(Level.FINER); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertTrue(jl.isEnabled(-1), "trace should be enabled"); logger.setLevel(Level.WARNING); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(jl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertTrue(jl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(jl.isEnabled(-1), "trace should not be enabled"); } @Test public void testLogging() { JulLogger jl = new JulLogger(); List expectedMessages = Arrays.asList("debug message", "debug message with null cause", "debug message with cause"); List> expectedExceptions = Arrays.asList(Optional.empty(), Optional.ofNullable(null), Optional.of(testException)); logger.setLevel(Level.ALL); jl.log(-1, "debug message"); jl.log(-1, "debug message with null cause", null); jl.log(-1, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); logger.setLevel(Level.ALL); jl.log(com.jcraft.jsch.Logger.FATAL, "debug message"); jl.log(com.jcraft.jsch.Logger.FATAL, "debug message with null cause", null); jl.log(com.jcraft.jsch.Logger.FATAL, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); logger.setLevel(Level.SEVERE); jl.log(-1, "debug message"); jl.log(-1, "debug message with null cause", null); jl.log(-1, "debug message with cause", testException); checkMessages(Collections.emptyList(), Collections.emptyList()); logger.setLevel(Level.SEVERE); jl.log(com.jcraft.jsch.Logger.FATAL, "debug message"); jl.log(com.jcraft.jsch.Logger.FATAL, "debug message with null cause", null); jl.log(com.jcraft.jsch.Logger.FATAL, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); } private void checkMessages(List expectedMessages, List> expectedExceptions) { List records = handler.getRecords(); handler.clear(); List actualMessages = records.stream().map(LogRecord::getMessage).collect(Collectors.toList()); List> actualExceptions = records.stream().map(LogRecord::getThrown) .map(Optional::ofNullable).collect(Collectors.toList()); assertEquals(expectedMessages, actualMessages, "mismatch in logged messages"); assertEquals(expectedExceptions, actualExceptions, "mismatch in logged exceptions"); } public static class ListHandler extends Handler { private final List records; public ListHandler() { super(); records = Collections.synchronizedList(new ArrayList<>()); } @Override public void publish(LogRecord record) { records.add(record); } @Override public void flush() {} @Override public void close() throws SecurityException {} public List getRecords() { return Collections.unmodifiableList(new ArrayList<>(records)); } public void clear() { synchronized (records) { records.clear(); setLevel(Level.ALL); } } } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/KeyExchangeTest.java000066400000000000000000000135541465436372100260600ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import java.util.Arrays; import java.util.Random; import org.junit.jupiter.api.Test; public class KeyExchangeTest { private final Random random = new Random(); private final KeyExchange kex = new TestKex(); @Test public void testNormalize0() { byte[] secret = new byte[0]; doNormalize(secret); } @Test public void testNormalize1() { byte[] secret = new byte[1]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; doNormalize(secret); } } @Test public void testNormalize2() { byte[] secret = new byte[2]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; for (int j = 0; j <= 0xff; j++) { secret[1] = (byte) j; doNormalize(secret); } } } @Test public void testNormalize3() { byte[] secret = new byte[3]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; for (int j = 0; j <= 0xff; j++) { secret[1] = (byte) j; for (int k = 0; k <= 0xff; k++) { secret[2] = (byte) k; doNormalize(secret); } } } } @Test public void testNormalizeRandom() { for (int i = 0; i < 1000000; i++) { byte[] secret = new byte[64]; random.nextBytes(secret); doNormalize(secret); } } @Test public void testEncodeAsMPInt1() { byte[] secret = new byte[1]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; doEncodeAsMPInt(secret); } } @Test public void testEncodeAsMPInt2() { byte[] secret = new byte[2]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; for (int j = 0; j <= 0xff; j++) { secret[1] = (byte) j; doEncodeAsMPInt(secret); } } } @Test public void testEncodeAsMPInt3() { byte[] secret = new byte[3]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; for (int j = 0; j <= 0xff; j++) { secret[1] = (byte) j; for (int k = 0; k <= 0xff; k++) { secret[2] = (byte) k; doEncodeAsMPInt(secret); } } } } @Test public void testEncodeAsMPIntRandom() { for (int i = 0; i < 1000000; i++) { byte[] secret = new byte[64]; random.nextBytes(secret); doEncodeAsMPInt(secret); } } @Test public void testEncodeAsString0() { byte[] secret = new byte[0]; doEncodeAsString(secret); } @Test public void testEncodeAsString1() { byte[] secret = new byte[1]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; doEncodeAsString(secret); } } @Test public void testEncodeAsString2() { byte[] secret = new byte[2]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; for (int j = 0; j <= 0xff; j++) { secret[1] = (byte) j; doEncodeAsString(secret); } } } @Test public void testEncodeAsString3() { byte[] secret = new byte[3]; for (int i = 0; i <= 0xff; i++) { secret[0] = (byte) i; for (int j = 0; j <= 0xff; j++) { secret[1] = (byte) j; for (int k = 0; k <= 0xff; k++) { secret[2] = (byte) k; doEncodeAsString(secret); } } } } @Test public void testEncodeAsStringRandom() { for (int i = 0; i < 1000000; i++) { byte[] secret = new byte[64]; random.nextBytes(secret); doEncodeAsString(secret); } } private void doNormalize(byte[] secret) { byte[] expected = normalize(Arrays.copyOf(secret, secret.length)); byte[] actual = kex.normalize(Arrays.copyOf(secret, secret.length)); try { assertArrayEquals(expected, actual); } catch (Exception e) { System.out.println(" secret = " + Arrays.toString(secret)); System.out.println("expected = " + Arrays.toString(expected)); System.out.println(" actual = " + Arrays.toString(actual)); throw e; } } // Copy of old implementation private static byte[] normalize(byte[] secret) { if (secret.length > 1 && secret[0] == 0 && (secret[1] & 0x80) == 0) { byte[] tmp = new byte[secret.length - 1]; System.arraycopy(secret, 1, tmp, 0, tmp.length); Util.bzero(secret); return normalize(tmp); } else { return secret; } } private void doEncodeAsMPInt(byte[] secret) { Buffer b = new Buffer(); b.putMPInt(secret); byte[] expected = new byte[b.getLength()]; b.getByte(expected); byte[] actual = kex.encodeAsMPInt(Arrays.copyOf(secret, secret.length)); try { assertArrayEquals(expected, actual); } catch (Throwable t) { System.out.println(" secret = " + Arrays.toString(secret)); System.out.println("expected = " + Arrays.toString(expected)); System.out.println(" actual = " + Arrays.toString(actual)); throw t; } } private void doEncodeAsString(byte[] secret) { Buffer b = new Buffer(); b.putString(secret); byte[] expected = new byte[b.getLength()]; b.getByte(expected); byte[] actual = kex.encodeAsString(Arrays.copyOf(secret, secret.length)); try { assertArrayEquals(expected, actual); } catch (Throwable t) { System.out.println(" secret = " + Arrays.toString(secret)); System.out.println("expected = " + Arrays.toString(expected)); System.out.println(" actual = " + Arrays.toString(actual)); throw t; } } static class TestKex extends KeyExchange { @Override public void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { throw new UnsupportedOperationException("Not supported"); } @Override public boolean next(Buffer buf) throws Exception { throw new UnsupportedOperationException("Not supported"); } @Override public int getState() { throw new UnsupportedOperationException("Not supported"); } } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/KeyPair2IT.java000066400000000000000000000111161465436372100247000ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.URISyntaxException; import java.nio.file.Paths; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class KeyPair2IT { // Python can be slow for DH group 18 private static final int timeout = 10000; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("asyncsshd.py", "docker/asyncsshd.py") .withFileFromClasspath("ssh_host_ed448_key", "docker/ssh_host_ed448_key") .withFileFromClasspath("ssh_host_ed448_key.pub", "docker/ssh_host_ed448_key.pub") .withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("authorized_keys", "docker/authorized_keys.KeyPairIT") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.asyncssh")) .withExposedPorts(22); @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPair2Test#keyArgs") void connectWithPublicKey(String path, String password, String keyType) throws Exception { final JSch jSch = createIdentity(path, password); Session session = createSession(jSch); if (keyType != null) { session.setConfig("PubkeyAcceptedAlgorithms", keyType); } try { session.connect(timeout); assertTrue(session.isConnected()); } finally { session.disconnect(); } } @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPair2Test#keyArgs") void connectWithPublicKeyAndUserInfo(String path, String password, String keyType) throws Exception { final JSch jSch = new JSch(); jSch.addIdentity( Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath()); Session session = createSession(jSch); session.setUserInfo(new UserInfo() { @Override public String getPassphrase() { return password; } @Override public String getPassword() { return null; } @Override public boolean promptPassword(String message) { return false; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptYesNo(String message) { return false; } @Override public void showMessage(String message) {} }); if (keyType != null) { session.setConfig("PubkeyAcceptedAlgorithms", keyType); } try { session.connect(timeout); assertTrue(session.isConnected()); } finally { session.disconnect(); } } private JSch createIdentity(String path, String password) throws JSchException, URISyntaxException { JSch ssh = new JSch(); if (password != null) { ssh.addIdentity( Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath(), password); } else { ssh.addIdentity( Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath()); } return ssh; } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "no"); session.setConfig("PreferredAuthentications", "publickey"); return session; } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/KeyPair2Test.java000066400000000000000000000040761465436372100253120ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; class KeyPair2Test { @TempDir public Path tmpDir; static Stream keyArgs() { return Stream.of( // PuTTY v2 keys Arguments.of("ppkv2_ed448_unix.ppk", null, "ssh-ed448"), Arguments.of("ppkv2_ed448_unix_encrypted.ppk", "secret123", "ssh-ed448"), Arguments.of("ppkv2_ed448_windows.ppk", null, "ssh-ed448"), Arguments.of("ppkv2_ed448_windows_encrypted.ppk", "secret123", "ssh-ed448"), // PuTTY v3 keys Arguments.of("ppkv3_ed448_unix.ppk", null, "ssh-ed448"), Arguments.of("ppkv3_ed448_unix_encrypted.ppk", "secret123", "ssh-ed448"), Arguments.of("ppkv3_ed448_windows.ppk", null, "ssh-ed448"), Arguments.of("ppkv3_ed448_windows_encrypted.ppk", "secret123", "ssh-ed448"), // PKCS8 keys Arguments.of("pkcs8_ed448", null, "ssh-ed448"), Arguments.of("pkcs8_ed448_encrypted_scrypt", "secret123", "ssh-ed448")); } @ParameterizedTest @MethodSource("keyArgs") void loadKey(String path, String password, String keyType) throws URISyntaxException, JSchException { final JSch jSch = new JSch(); final String prvkey = Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath(); assertTrue(new File(prvkey).exists()); assertDoesNotThrow(() -> { if (null != password) { jSch.addIdentity(prvkey, password); } else { jSch.addIdentity(prvkey); } }); assertEquals(keyType, jSch.getIdentityRepository().getIdentities().get(0).getAlgName()); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/KeyPairIT.java000066400000000000000000000064031465436372100246210ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.URISyntaxException; import java.nio.file.Paths; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class KeyPairIT { @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys.KeyPairIT") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.KeyPairIT")) .withExposedPorts(22); @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPairTest#keyArgs") void connectWithPublicKey(String path, String password, String keyType) throws Exception { final JSch jSch = createIdentity(path, password); Session session = createSession(jSch); if (keyType != null) { session.setConfig("PubkeyAcceptedAlgorithms", keyType); } try { session.connect(2000); assertTrue(session.isConnected()); } finally { session.disconnect(); } } @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPairTest#keyArgs") void connectWithPublicKeyAndUserInfo(String path, String password, String keyType) throws Exception { final JSch jSch = new JSch(); jSch.addIdentity( Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath()); Session session = createSession(jSch); session.setUserInfo(new UserInfo() { @Override public String getPassphrase() { return password; } @Override public String getPassword() { return null; } @Override public boolean promptPassword(String message) { return false; } @Override public boolean promptPassphrase(String message) { return true; } @Override public boolean promptYesNo(String message) { return false; } @Override public void showMessage(String message) {} }); if (keyType != null) { session.setConfig("PubkeyAcceptedAlgorithms", keyType); } try { session.connect(2000); assertTrue(session.isConnected()); } finally { session.disconnect(); } } private JSch createIdentity(String path, String password) throws JSchException, URISyntaxException { JSch ssh = new JSch(); if (password != null) { ssh.addIdentity( Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath(), password); } else { ssh.addIdentity( Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath()); } return ssh; } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "no"); session.setConfig("PreferredAuthentications", "publickey"); return session; } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/KeyPairTest.java000066400000000000000000000231431465436372100252240ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; class KeyPairTest { @TempDir public Path tmpDir; static Stream keyArgs() { return Stream.of( // docker/id_rsa rsa Arguments.of("docker/id_rsa", null, "ssh-rsa"), // docker/ssh_host_rsa_key openssh format Arguments.of("docker/ssh_host_rsa_key", null, "ssh-rsa"), // encrypted_openssh_private_key_rsa Arguments.of("encrypted_openssh_private_key_rsa", "secret123", "ssh-rsa"), // docker/id_dsa Arguments.of("docker/id_dsa", null, "ssh-dss"), // dsa openssh format Arguments.of("docker/ssh_host_dsa_key", null, "ssh-dss"), // encrypted dsa Arguments.of("encrypted_openssh_private_key_dsa", "secret123", "ssh-dss"), // unencrypted RSA with windows (\r\n) line endings Arguments.of("issue362_rsa", null, "ssh-rsa"), Arguments.of("issue_369_rsa_opensshv1", null, "ssh-rsa"), Arguments.of("issue_369_rsa_pem", null, "ssh-rsa"), Arguments.of("encrypted_issue_369_rsa_opensshv1", "secret123", "ssh-rsa"), Arguments.of("encrypted_issue_369_rsa_pem", "secret123", "ssh-rsa"), // ecdsa EC private key format Arguments.of("docker/id_ecdsa256", null, "ecdsa-sha2-nistp256"), // Arguments.of("docker/id_ecdsa384", null, "ecdsa-sha2-nistp384"), // Arguments.of("docker/id_ecdsa521", null, "ecdsa-sha2-nistp521"), Arguments.of("docker/ssh_host_ecdsa256_key", null, "ecdsa-sha2-nistp256"), Arguments.of("docker/ssh_host_ecdsa384_key", null, "ecdsa-sha2-nistp384"), Arguments.of("docker/ssh_host_ecdsa521_key", null, "ecdsa-sha2-nistp521"), // encrypted ecdsa Arguments.of("encrypted_openssh_private_key_ecdsa", "secret123", "ecdsa-sha2-nistp256"), // PuTTY v2 keys Arguments.of("ppkv2_dsa_unix.ppk", null, "ssh-dss"), Arguments.of("ppkv2_dsa_unix_encrypted.ppk", "secret123", "ssh-dss"), Arguments.of("ppkv2_dsa_windows.ppk", null, "ssh-dss"), Arguments.of("ppkv2_dsa_windows_encrypted.ppk", "secret123", "ssh-dss"), Arguments.of("ppkv2_rsa_unix.ppk", null, "ssh-rsa"), Arguments.of("ppkv2_rsa_unix_encrypted.ppk", "secret123", "ssh-rsa"), Arguments.of("ppkv2_rsa_windows.ppk", null, "ssh-rsa"), Arguments.of("ppkv2_rsa_windows_encrypted.ppk", "secret123", "ssh-rsa"), Arguments.of("ppkv2_ecdsa256_unix.ppk", null, "ecdsa-sha2-nistp256"), Arguments.of("ppkv2_ecdsa256_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), Arguments.of("ppkv2_ecdsa384_unix.ppk", null, "ecdsa-sha2-nistp384"), Arguments.of("ppkv2_ecdsa384_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), Arguments.of("ppkv2_ecdsa521_unix.ppk", null, "ecdsa-sha2-nistp521"), Arguments.of("ppkv2_ecdsa521_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), Arguments.of("ppkv2_ecdsa256_windows.ppk", null, "ecdsa-sha2-nistp256"), Arguments.of("ppkv2_ecdsa256_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), Arguments.of("ppkv2_ecdsa384_windows.ppk", null, "ecdsa-sha2-nistp384"), Arguments.of("ppkv2_ecdsa384_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), Arguments.of("ppkv2_ecdsa521_windows.ppk", null, "ecdsa-sha2-nistp521"), Arguments.of("ppkv2_ecdsa521_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), Arguments.of("ppkv2_ed25519_unix.ppk", null, "ssh-ed25519"), Arguments.of("ppkv2_ed25519_unix_encrypted.ppk", "secret123", "ssh-ed25519"), Arguments.of("ppkv2_ed25519_windows.ppk", null, "ssh-ed25519"), Arguments.of("ppkv2_ed25519_windows_encrypted.ppk", "secret123", "ssh-ed25519"), // PuTTY v3 keys Arguments.of("ppkv3_dsa_unix.ppk", null, "ssh-dss"), Arguments.of("ppkv3_dsa_unix_encrypted.ppk", "secret123", "ssh-dss"), Arguments.of("ppkv3_dsa_windows.ppk", null, "ssh-dss"), Arguments.of("ppkv3_dsa_windows_encrypted.ppk", "secret123", "ssh-dss"), Arguments.of("ppkv3_rsa_unix.ppk", null, "ssh-rsa"), Arguments.of("ppkv3_rsa_unix_encrypted.ppk", "secret123", "ssh-rsa"), Arguments.of("ppkv3_rsa_windows.ppk", null, "ssh-rsa"), Arguments.of("ppkv3_rsa_windows_encrypted.ppk", "secret123", "ssh-rsa"), Arguments.of("ppkv3_ecdsa256_unix.ppk", null, "ecdsa-sha2-nistp256"), Arguments.of("ppkv3_ecdsa256_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), Arguments.of("ppkv3_ecdsa384_unix.ppk", null, "ecdsa-sha2-nistp384"), Arguments.of("ppkv3_ecdsa384_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), Arguments.of("ppkv3_ecdsa521_unix.ppk", null, "ecdsa-sha2-nistp521"), Arguments.of("ppkv3_ecdsa521_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), Arguments.of("ppkv3_ecdsa256_windows.ppk", null, "ecdsa-sha2-nistp256"), Arguments.of("ppkv3_ecdsa256_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), Arguments.of("ppkv3_ecdsa384_windows.ppk", null, "ecdsa-sha2-nistp384"), Arguments.of("ppkv3_ecdsa384_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), Arguments.of("ppkv3_ecdsa521_windows.ppk", null, "ecdsa-sha2-nistp521"), Arguments.of("ppkv3_ecdsa521_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), Arguments.of("ppkv3_ed25519_unix.ppk", null, "ssh-ed25519"), Arguments.of("ppkv3_ed25519_unix_encrypted.ppk", "secret123", "ssh-ed25519"), Arguments.of("ppkv3_ed25519_windows.ppk", null, "ssh-ed25519"), Arguments.of("ppkv3_ed25519_windows_encrypted.ppk", "secret123", "ssh-ed25519"), // PKCS8 keys Arguments.of("pkcs8_dsa", null, "ssh-dss"), Arguments.of("pkcs8_dsa_encrypted_hmacsha1", "secret123", "ssh-dss"), Arguments.of("pkcs8_dsa_encrypted_hmacsha256", "secret123", "ssh-dss"), Arguments.of("pkcs8_rsa", null, "ssh-rsa"), Arguments.of("pkcs8_rsa_encrypted_hmacsha1", "secret123", "ssh-rsa"), Arguments.of("pkcs8_rsa_encrypted_hmacsha256", "secret123", "ssh-rsa"), Arguments.of("pkcs8_ecdsa256", null, "ecdsa-sha2-nistp256"), Arguments.of("pkcs8_ecdsa256_encrypted_scrypt", "secret123", "ecdsa-sha2-nistp256"), Arguments.of("pkcs8_ecdsa384", null, "ecdsa-sha2-nistp384"), Arguments.of("pkcs8_ecdsa384_encrypted_scrypt", "secret123", "ecdsa-sha2-nistp384"), Arguments.of("pkcs8_ecdsa521", null, "ecdsa-sha2-nistp521"), Arguments.of("pkcs8_ecdsa521_encrypted_scrypt", "secret123", "ecdsa-sha2-nistp521"), Arguments.of("pkcs8_ed25519", null, "ssh-ed25519"), Arguments.of("pkcs8_ed25519_encrypted_scrypt", "secret123", "ssh-ed25519")); } @ParameterizedTest @MethodSource("keyArgs") void loadKey(String path, String password, String keyType) throws URISyntaxException, JSchException { final JSch jSch = new JSch(); final String prvkey = Paths.get(ClassLoader.getSystemResource(path).toURI()).toFile().getAbsolutePath(); assertTrue(new File(prvkey).exists()); assertDoesNotThrow(() -> { if (null != password) { jSch.addIdentity(prvkey, password); } else { jSch.addIdentity(prvkey); } }); assertEquals(keyType, jSch.getIdentityRepository().getIdentities().get(0).getAlgName()); } @Test void genKeypair() { final JSch jSch = new JSch(); assertDoesNotThrow(() -> { KeyPair kpair = KeyPair.genKeyPair(jSch, KeyPair.RSA, 1024); kpair.writePrivateKey(tmpDir.resolve("my-private-key").toString()); }); } @Test void genKeypairEncrypted() { final JSch jSch = new JSch(); assertDoesNotThrow(() -> { KeyPair kpair = KeyPair.genKeyPair(jSch, KeyPair.RSA, 1024); kpair.writePrivateKey(tmpDir.resolve("my-private-key-encrypted").toString(), "my-password".getBytes(UTF_8)); }); } @ParameterizedTest @ValueSource(strings = {"encrypted_openssh_private_key_rsa", "encrypted_openssh_private_key_dsa", "encrypted_openssh_private_key_ecdsa"}) void decryptEncryptedOpensshKey(String keyFile) throws URISyntaxException, JSchException { final JSch jSch = new JSch(); final String prvkey = Paths.get(ClassLoader.getSystemResource(keyFile).toURI()).toFile().getAbsolutePath(); assertTrue(new File(prvkey).exists()); IdentityFile identity = IdentityFile.newInstance(prvkey, null, jSch.instLogger); // Decrypt the key file assertTrue(identity.getKeyPair().decrypt("secret123")); // From now on, the pair now longer counts as encrypted assertFalse(identity.getKeyPair().isEncrypted()); assertNotNull(identity.getKeyPair().getPrivateKey()); // An unencrypted key pair should allow #decrypt(null) // com.jcraft.jsch.UserAuthPublicKey relies on this assertTrue(identity.getKeyPair().decrypt((byte[]) null)); assertTrue(identity.getKeyPair().decrypt((String) null)); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/KnownHostsTest.java000066400000000000000000001413471465436372100260040ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import com.jcraft.jsch.KnownHosts.HashedHostKey; import com.jcraft.jsch.jce.HMACSHA256; import com.jcraft.jsch.jce.HMACSHA512; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Hashtable; import java.util.LinkedList; import java.util.Properties; import java.util.function.Function; import java.util.stream.Collectors; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class KnownHostsTest { private static final String rsaKey = "AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkc" + "cKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81e" + "FzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpI" + "oaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G" + "3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="; private static final String hashValue = "|1|F1E1KeoE/eEWhi10WpGv4OdiO6Y=|3988QV0VE8wmZL7suNrYQLITLCg="; private static final String hostLine = "ssh.example.com,192.168.1.61"; private static final byte[] dsaKeyBytes = Util.str2byte(" ssh-dsa"); private static final byte[] rsaKeyBytes = Util.str2byte(" ssh-rsa"); private LinkedList messages; private JSch jsch; private Hashtable orgConfig; private Properties orgProps; @BeforeEach void setupTest() { orgProps = System.getProperties(); Properties myProps = new Properties(orgProps); System.setProperties(myProps); orgConfig = new Hashtable<>(JSch.config); messages = new LinkedList<>(); jsch = new JSch(); jsch.setInstanceLogger(new TestLogger(messages)); } @AfterEach void tearDownTest() { System.setProperties(orgProps); JSch.setConfig(orgConfig); Session.random = null; } @Test void testInstantiationValues() throws Exception { KnownHosts kh = new KnownHosts(jsch); assertNull(kh.getKnownHostsFile(), "check known_hosts filename"); assertNull(kh.getKnownHostsRepositoryID(), "check repository id"); assertNotNull(kh.hmacsha1, "hmac instance not expected to be null"); assertSame(kh.hmacsha1, kh.getHMACSHA1(), "same instance should be returned with call of getHMACSHA1"); assertSame(kh.getHMACSHA1(), kh.getHMACSHA1(), "same instance should be returned with call of getHMACSHA1"); KnownHosts kh2 = new KnownHosts(jsch); assertNotNull(kh2.hmacsha1, "hmac instance not expected to be null"); assertNotSame(kh.hmacsha1, kh2.hmacsha1, "hmac instances should be different in different KH-instances"); } @Test void testSetKnownHostsByFilename() throws Exception { KnownHosts kh = new KnownHosts(jsch) { @Override void setKnownHosts(InputStream input) throws JSchException { messages.add("set known hosts by stream"); StringBuilder sb = new StringBuilder(); int read; try { while ((read = input.read()) != -1) { sb.append((char) read); } messages.add(sb.toString()); } catch (IOException ioe) { throw new JSchException("error while reading hosts file", ioe); } } }; File hostFile = File.createTempFile("setknownhosts", ".txt"); try { try (FileOutputStream fos = new FileOutputStream(hostFile)) { fos.write("some host data".getBytes(ISO_8859_1)); } System.setProperty("user.home", hostFile.getParentFile().getAbsolutePath()); kh.setKnownHosts("some_filename:that can't exist"); assertEquals("some_filename:that can't exist", kh.getKnownHostsFile(), "check known_hosts filename"); assertEquals("some_filename:that can't exist", kh.getKnownHostsRepositoryID(), "check repository id"); assertEquals(0, messages.size(), "expected no messages till now"); kh.setKnownHosts(hostFile.getAbsolutePath()); assertEquals(hostFile.getAbsolutePath(), kh.getKnownHostsFile(), "check known_hosts filename"); assertEquals(hostFile.getAbsolutePath(), kh.getKnownHostsRepositoryID(), "check repository id"); assertEquals(2, messages.size(), "expected no messages after setting"); assertEquals("set known hosts by stream", messages.removeFirst(), "check message"); assertEquals("some host data", messages.removeFirst(), "check message"); File userDirFile = new File("~", hostFile.getName()); assertEquals(hostFile.getAbsolutePath(), Util.checkTilde(userDirFile.getPath()), "check result of userTilde"); kh.setKnownHosts(userDirFile.getPath()); assertEquals(userDirFile.getPath(), kh.getKnownHostsFile(), "check known_hosts filename"); assertEquals(userDirFile.getPath(), kh.getKnownHostsRepositoryID(), "check repository id"); assertEquals(2, messages.size(), "expected 2 messages after setting"); assertEquals("set known hosts by stream", messages.removeFirst(), "check message"); assertEquals("some host data", messages.removeFirst(), "check message"); } finally { hostFile.delete(); } } @Test void testCreateAndGetHMACSHA1() throws Exception { JSch.setConfig("hmac-sha1", "my.hmac.sha1.class.Name"); KnownHosts kh = new KnownHosts(jsch) { @Override MAC createHMAC(String hmacClassname) { messages.add("create hmac instance of class " + hmacClassname); return null; } }; assertNull(kh.hmacsha1, "hmac instance should be null"); assertEquals("create hmac instance of class my.hmac.sha1.class.Name", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); try { new KnownHosts(jsch); fail("exception expected"); } catch (IllegalArgumentException iae) { assertEquals("instantiation of my.hmac.sha1.class.Name lead to an error", iae.getMessage(), "check exception message"); Throwable cause = iae.getCause(); assertNotNull(cause, "cause should not be null"); assertEquals(ClassNotFoundException.class.getName(), cause.getClass().getName(), "unexpected cause"); } assertEquals( "M(3): unable to instantiate HMAC-class my.hmac.sha1.class.Name\r\n" + " java.lang.ClassNotFoundException: my.hmac.sha1.class.Name", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); // it's not SHA-1 but for this test any hashing class will do JSch.setConfig("hmac-sha1", HMACSHA256.class.getName()); kh = new KnownHosts(jsch); assertNotNull(kh.hmacsha1, "hmac instance should not be null"); assertSame(kh.hmacsha1, kh.getHMACSHA1(), "instance shouldn't change"); assertEquals(HMACSHA256.class.getName(), kh.hmacsha1.getClass().getName(), "hmac class mismatch"); MAC currentMAC = kh.hmacsha1; JSch.setConfig("hmac-sha1", HMACSHA512.class.getName()); assertSame(currentMAC, kh.getHMACSHA1(), "instance shouldn't change even with now correct config-entry"); kh = new KnownHosts(jsch); assertNotNull(kh.hmacsha1, "hmac instance should not be null"); assertSame(kh.hmacsha1, kh.getHMACSHA1(), "instance shouldn't change"); assertEquals(HMACSHA512.class.getName(), kh.hmacsha1.getClass().getName(), "hmac class mismatch"); assertEquals("", messages.stream().collect(Collectors.joining("\r\n"))); } @Test void testSetKnownHostsHashedHost() throws Exception { KnownHosts kh = new KnownHosts(jsch); // comment with umlaut to check used charset for dump kh.setKnownHosts( new ByteArrayInputStream((hashValue + " " + "ssh-rsa " + rsaKey + " some comment\r\n" + "# 192.168.1.61 ssh-rsa MYRSAKEY some other commänt").getBytes(UTF_8))); assertEquals(0, messages.size(), "no messages expected"); HostKey[] keys = kh.getHostKey(); checkResultForKeyResult(keys, rsaKey, hashValue, ""); keys = kh.getHostKey("192.168.1.61", "ssh-rsa"); checkResultForKeyResult(keys, rsaKey, hashValue, ""); keys = kh.getHostKey("192.168.1.62", "ssh-rsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); keys = kh.getHostKey("192.168.1.61", "ssh-dsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); ByteArrayOutputStream dump = new ByteArrayOutputStream(); kh.dump(dump); assertEquals( hashValue + " ssh-rsa " + rsaKey + " some comment\n" + "# 192.168.1.61 ssh-rsa MYRSAKEY some other commänt\n" + "", dump.toString("UTF8"), "dump mismatch"); } @Test void testSetKnownHostsDirectHost() throws Exception { KnownHosts kh = new KnownHosts(jsch); kh.setKnownHosts(new ByteArrayInputStream( ("@cert-authority " + hostLine + " " + "ssh-rsa " + rsaKey + " some comment") .getBytes(ISO_8859_1))); assertEquals(0, messages.size(), "no messages expected"); HostKey[] keys = kh.getHostKey(); checkResultForKeyResult(keys, rsaKey, hostLine, "@cert-authority"); keys = kh.getHostKey("192.168.1.61", "ssh-rsa"); checkResultForKeyResult(keys, rsaKey, hostLine, "@cert-authority"); keys = kh.getHostKey("ssh.example.com", "ssh-rsa"); checkResultForKeyResult(keys, rsaKey, hostLine, "@cert-authority"); keys = kh.getHostKey("192.168.1.62", "ssh-rsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); keys = kh.getHostKey("192.168.1.61", "ssh-dsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); ByteArrayOutputStream dump = new ByteArrayOutputStream(); kh.dump(dump); assertEquals("@cert-authority " + hostLine + " ssh-rsa " + rsaKey + " some comment\n" + "", dump.toString("8859_1"), "dump mismatch"); kh.setKnownHosts(new ByteArrayInputStream( ("!ssh.example.com,!192.168.1.61 " + "ssh-rsa " + rsaKey + " some comment") .getBytes(ISO_8859_1))); assertEquals(0, messages.size(), "no messages expected"); keys = kh.getHostKey(); checkResultForKeyResult(keys, rsaKey, "!ssh.example.com,!192.168.1.61", ""); keys = kh.getHostKey("192.168.1.61", "ssh-rsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); keys = kh.getHostKey("ssh.example.com", "ssh-rsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); keys = kh.getHostKey("192.168.1.62", "ssh-rsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); keys = kh.getHostKey("192.168.1.61", "ssh-dsa"); assertNotNull(keys, "actual keys expected"); assertEquals(0, keys.length, "0 keys expected"); dump.reset(); kh.dump(dump); assertEquals("!ssh.example.com,!192.168.1.61" + " ssh-rsa " + rsaKey + " some comment\n" + "", dump.toString("8859_1"), "dump mismatch"); } @Test void testkSyncDump() throws Exception { KnownHosts kh = new KnownHosts(jsch) { @Override synchronized void sync(String foo) throws IOException { messages.add("sync with file '" + foo + "'"); super.sync(foo); } }; File tempFile = File.createTempFile("checksyncdump", ".txt"); try { System.setProperty("user.home", tempFile.getParentFile().getAbsolutePath()); assertNull(kh.getKnownHostsFile(), "known_hosts expected to be null"); kh.sync(); assertEquals(0, messages.size(), "no messages expected"); kh.setKnownHosts(tempFile.getAbsolutePath()); assertEquals(0, messages.size(), "no messages expected"); kh.sync(); assertEquals("sync with file '" + tempFile.getAbsolutePath() + "'", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); kh = new KnownHosts(jsch) { @Override void dump(OutputStream out) { messages.add("stream based dump called with stream: " + out.getClass().getName()); try { out.write("some dump data".getBytes(ISO_8859_1)); } catch (IOException ioe) { Assertions.fail("exception occurred while trying to write dump to tream", ioe); } } }; kh.sync(null); assertEquals(0, messages.size(), "no messages expected"); kh.sync(tempFile.getAbsolutePath()); assertEquals("stream based dump called with stream: java.io.FileOutputStream", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertEquals("some dump data", getContent(tempFile.getAbsolutePath())); assertTrue(tempFile.delete(), "unable to delete '" + tempFile.getAbsolutePath() + "'"); String userPath = new File("~", tempFile.getName()).getPath(); kh.sync(userPath); assertEquals("stream based dump called with stream: java.io.FileOutputStream", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertEquals("some dump data", getContent(tempFile.getAbsolutePath())); assertTrue(tempFile.delete(), "unable to delete '" + tempFile.getAbsolutePath() + "'"); assertTrue(tempFile.mkdir(), "unable to create '" + tempFile.getAbsolutePath() + "'"); try { kh.sync(tempFile.getAbsolutePath()); fail("exception expected"); } catch (FileNotFoundException fnfe) { // expected, details are OS-dependent, so no check of message, etc. } assertEquals(0, messages.size(), "no messages expected"); kh = new KnownHosts(jsch) { @Override void dumpHostKey(OutputStream out, HostKey hk) throws IOException { if (out == null) { throw new NullPointerException("out is null"); } messages.add("dump host key for host " + hk.getHost()); } }; kh.add(kh.new HashedHostKey("host1.example.com", HostKey.SSHRSA, new byte[1]), null); kh.add(kh.new HashedHostKey("host2.example.com", HostKey.SSHRSA, new byte[1]), null); kh.dump(null); assertEquals( "M(3): unable to dump known hosts\r\n" + " java.lang.NullPointerException: out is null", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); kh.dump(new ByteArrayOutputStream()); assertEquals( "dump host key for host host1.example.com\r\n" + "dump host key for host host2.example.com", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); } finally { tempFile.delete(); } } @Test void testDumpHostKey() throws Exception { ByteArrayOutputStream sink = new ByteArrayOutputStream(); KnownHosts kh = new KnownHosts(jsch); kh.dumpHostKey(sink, new HostKey("", "hostwithoutmarker", HostKey.SSHRSA, "rsakey".getBytes(ISO_8859_1), null)); assertEquals("hostwithoutmarker ssh-rsa cnNha2V5\n", sink.toString("utf8"), "check dumped key"); sink.reset(); kh.dumpHostKey(sink, new HostKey("@somemarker", "hostwithmarker", HostKey.SSHRSA, "rsakey".getBytes(ISO_8859_1), null)); assertEquals("@somemarker hostwithmarker ssh-rsa cnNha2V5\n", sink.toString("utf8"), "check dumped key"); sink.reset(); kh.dumpHostKey(sink, new HostKey("", "hostwithoutmarker", HostKey.SSHRSA, "rsakey".getBytes(ISO_8859_1), "some commänt")); assertEquals("hostwithoutmarker ssh-rsa cnNha2V5 some commänt\n", sink.toString("utf8"), "check dumped key"); sink.reset(); kh.dumpHostKey(sink, new HostKey("@somemarker", "hostwithmarker", HostKey.SSHRSA, "rsakey".getBytes(ISO_8859_1), "some commänt")); assertEquals("@somemarker hostwithmarker ssh-rsa cnNha2V5 some commänt\n", sink.toString("utf8"), "check dumped key"); sink.reset(); kh.dumpHostKey(sink, new HostKey("", "hostwithoutmarker", HostKey.UNKNOWN, "rsakey".getBytes(ISO_8859_1), "some commänt")); assertEquals("hostwithoutmarker\n", sink.toString("utf8"), "check dumped key"); sink.reset(); } @Test void testDeleteSubstring() { KnownHosts kh = new KnownHosts(jsch); assertEquals("host1,host2", kh.deleteSubString("todelete,host1,host2", "todelete"), "check result"); assertEquals("host1,host2", kh.deleteSubString("host1,todelete,host2", "todelete"), "check result"); assertEquals("host1,host2,todelete", kh.deleteSubString("host1,todelete,host2,todelete", "todelete"), "check result"); assertEquals("host1,host2", kh.deleteSubString("host1,host2,todelete", "todelete"), "check result"); assertEquals("host1,host2,host3", kh.deleteSubString("host1,host2,host3", "todelete"), "check result"); assertEquals("host1,host2,host3,", kh.deleteSubString("host1,host2,host3,", "todelete"), "check result"); assertEquals("", kh.deleteSubString("todelete", "todelete"), "check result"); assertEquals("nottodelete", kh.deleteSubString("nottodelete", "todelete"), "check result"); } @Test void testCreateHashedKey() throws Exception { Session.random = new NotSoRandomRandom(); KnownHosts kh = new KnownHosts(jsch); kh.hmacsha1 = null; // this will lead to an NPE if the creation uses this instance try { kh.createHashedHostKey("host.example.com", " ssh-rsa".getBytes(ISO_8859_1)); fail("exception expected"); } catch (NullPointerException npe) { // expected but messages differ between java versions, so we don't check the message assertEquals("hash", npe.getStackTrace()[0].getMethodName(), "check hash threw exception"); } kh.hmacsha1 = new HMACSHA256(); HostKey hostKey = kh.createHashedHostKey("host.example.com", " ssh-rsa".getBytes(ISO_8859_1)); assertNotNull(hostKey, "returned host key shouldn't be null"); assertEquals(HashedHostKey.class.getName(), hostKey.getClass().getName(), "check type of returned host key"); HashedHostKey hhk = (HashedHostKey) hostKey; assertEquals( "|1|AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=|mie6rcAf1aPGk6d+HxnkpvO4HaOAH/Y6YWegs+Xog/s=", hhk.getHost(), "host mismatch"); assertEquals("", hhk.getMarker(), "marker mismatch"); assertEquals( "9c:fb:7f:99:79:01:6d:46:68:87:39:15:4f:f5:cc:9d:71:7a:8b:5a:4a:c1:c7:4b:9c:20:a5:91:c2:6a:ff:5a", hhk.getFingerPrint(jsch)); assertEquals(null, hhk.getComment(), "comment mismatch"); assertEquals("ICAgIHNzaC1yc2E=", hhk.getKey(), "key mismatch"); assertEquals("ssh-rsa", hhk.getType(), "type mismatch"); } @Test void testHashedKeyCreation() throws Exception { Session.random = new NotSoRandomRandom(); KnownHosts kh = new KnownHosts(jsch); HashedHostKey hhk; hhk = kh.new HashedHostKey("host.example.com", dsaKeyBytes); checkUnhashedHostKey(hhk, "", "host.example.com", "ssh-dss", null); hhk.hash(); checkSHA1HashResult(hhk, "", "ssh-dss", null); hhk.hash(); checkSHA1HashResult(hhk, "", "ssh-dss", null); hhk = kh.new HashedHostKey("|1|AAECAwQFBgcICQoLDA0ODxAREhM=|/pE4peaossRYDRp6bEWa348eFLI=", dsaKeyBytes); checkSHA1HashResult(hhk, "", "ssh-dss", null); hhk = kh.new HashedHostKey("|1|AAECAwQFBgcICQoLDA0ODxAREhM=/pE4peaossRYDRp6bEWa348eFLI=", dsaKeyBytes); checkUnhashedHostKey(hhk, "", "|1|AAECAwQFBgcICQoLDA0ODxAREhM=/pE4peaossRYDRp6bEWa348eFLI=", "ssh-dss", null); hhk = kh.new HashedHostKey("|1|AAAA|ABCD", dsaKeyBytes); checkUnhashedHostKey(hhk, "", "|1|AAAA|ABCD", "ssh-dss", null); hhk = kh.new HashedHostKey("|1|AAECAwQFBgcICQoLDA0ODxAREhM=|ABCD", HostKey.ED25519, dsaKeyBytes); checkUnhashedHostKey(hhk, "", "|1|AAECAwQFBgcICQoLDA0ODxAREhM=|ABCD", "ssh-ed25519", null); Mac mac = Mac.getInstance("HMACSHA1", new BouncyCastleProvider()); kh.hmacsha1 = new BCHMACSHA1(mac); hhk = kh.new HashedHostKey("@somemarker", "host.example.com", HostKey.ED448, dsaKeyBytes, "some commänt"); checkUnhashedHostKey(hhk, "@somemarker", "host.example.com", "ssh-ed448", "some commänt"); hhk.hash(); checkSHA1HashResult(hhk, "@somemarker", "ssh-ed448", "some commänt"); hhk.hash(); // should have no effect checkSHA1HashResult(hhk, "@somemarker", "ssh-ed448", "some commänt"); hhk = kh.new HashedHostKey(hhk.getHost(), HostKey.ED448, dsaKeyBytes); checkSHA1HashResult(hhk, "", "ssh-ed448", null); } @Test void testHashedHostKeyHashIsMatch() throws Exception { String heyKey = "0x00:0x01:0x02:0x03:0x04:0x05:0x06:0x07:0x08:0x09:0x0a:0x0b:0x0c:0x0d:0x0e:0x0f:0x10:0x11:0x12:0x13"; Session.random = new NotSoRandomRandom() { @Override public void fill(byte[] foo, int start, int len) { messages.add("fill in random called"); super.fill(foo, start, len); } }; KnownHosts kh = new KnownHosts(jsch); boolean[] throwException = new boolean[1]; Mac mac = Mac.getInstance("HMACSHA1", new BouncyCastleProvider()); kh.hmacsha1 = new BCHMACSHA1(mac) { @Override public void init(byte[] key) throws Exception { messages.add("init in mac called with key " + Util.toHex(key)); if (throwException[0]) { throw new IOException("dummy ioe"); } super.init(key); } }; HashedHostKey hhk = kh.new HashedHostKey("@somemarker", "host.example.com", HostKey.ED448, dsaKeyBytes, "some commänt"); checkUnhashedHostKey(hhk, "@somemarker", "host.example.com", "ssh-ed448", "some commänt"); assertEquals(0, messages.size(), "expected no messages"); assertTrue(hhk.isMatched("host.example.com"), "match expected"); assertFalse(hhk.isMatched("otherhost.example.com"), "no match expected"); hhk.hash(); checkSHA1HashResult(hhk, "@somemarker", "ssh-ed448", "some commänt"); assertEquals("fill in random called\r\n" + "init in mac called with key " + heyKey, messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertTrue(hhk.isMatched("host.example.com"), "match expected"); assertEquals("init in mac called with key " + heyKey, messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertFalse(hhk.isMatched("otherhost.example.com"), "no match expected"); assertEquals("init in mac called with key " + heyKey, messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); hhk.hash(); assertEquals(0, messages.size(), "expected no messages"); hhk = kh.new HashedHostKey("@somemarker", "host.example.com", HostKey.ED448, dsaKeyBytes, "some commänt"); hhk.salt = new byte[mac.getMacLength()]; Session.random.fill(hhk.salt, 0, hhk.salt.length); messages.clear(); hhk.hash(); checkSHA1HashResult(hhk, "@somemarker", "ssh-ed448", "some commänt"); assertEquals("init in mac called with key " + heyKey, messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); hhk = kh.new HashedHostKey("@somemarker", "host.example.com", HostKey.ED448, dsaKeyBytes, "some commänt"); throwException[0] = true; checkUnhashedHostKey(hhk, "@somemarker", "host.example.com", "ssh-ed448", "some commänt"); hhk.hash(); checkUnhashedHostKey(hhk, "@somemarker", "host.example.com", "ssh-ed448", "some commänt"); assertEquals("fill in random called\r\n" + "init in mac called with key " + heyKey + "\r\n" + "M(3): an error occurred while trying to calculate the hash for host host.example.com\r\n" + " java.io.IOException: dummy ioe", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); throwException[0] = false; hhk.hash(); checkSHA1HashResult(hhk, "@somemarker", "ssh-ed448", "some commänt"); messages.clear(); throwException[0] = true; assertFalse(hhk.isMatched("host.example.com"), "no match expected"); assertEquals( "init in mac called with key " + heyKey + "\r\n" + "M(3): an error occurred while trying to check hash for host host.example.com\r\n" + " java.io.IOException: dummy ioe", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); } @Test void testSyncKnownHostsFile() throws Exception { boolean[] throwException = new boolean[1]; KnownHosts kh = new KnownHosts(jsch) { @Override void sync() throws IOException { messages.add("sync() called"); throw new IOException("shouldn't be called"); } @Override synchronized void sync(String filename) throws IOException { messages.add("sync called with file " + filename); if (throwException[0]) { throw new RuntimeException("dummy re"); } } }; LinkedList> promptHandlers = new LinkedList<>(); UserInfo checkUI = new UserInfo() { @Override public void showMessage(String message) { messages.add("UIM: " + message); } @Override public boolean promptYesNo(String message) { messages.add("UIPYN: " + message); if (promptHandlers.isEmpty()) { return false; } Function function = promptHandlers.removeFirst(); return function.apply(message).booleanValue(); } @Override public boolean promptPassword(String message) { throw new RuntimeException("promptPassword shouldn't be called"); } @Override public boolean promptPassphrase(String message) { throw new RuntimeException("promptPassphrase shouldn't be called"); } @Override public String getPassword() { throw new RuntimeException("getPassword shouldn't be called"); } @Override public String getPassphrase() { throw new RuntimeException("getPassphrase shouldn't be called"); } }; File tempFile = File.createTempFile("syncknownhostfile", ".dir"); assertTrue(tempFile.delete(), "unable to delete " + tempFile.getAbsolutePath()); File subDirFile = new File(tempFile, "subdir/known_hosts"); String subdirParentAbsPath = subDirFile.getParentFile().getAbsolutePath(); try { assertNull(kh.getKnownHostsRepositoryID(), "repository id should be null"); kh.syncKnownHostsFile(null); assertEquals(0, messages.size(), "no messages expected"); kh.setKnownHosts(tempFile.getAbsolutePath()); assertEquals(tempFile.getAbsolutePath(), kh.getKnownHostsRepositoryID(), "repository id should be the temp file's absolute path"); kh.syncKnownHostsFile(null); assertEquals(0, messages.size(), "no messages expected"); promptHandlers.add((message) -> checkMessageAndReturn( tempFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?", message, false)); kh.syncKnownHostsFile(checkUI); assertEquals( "UIPYN: " + tempFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertFalse(tempFile.exists(), "file shouldn't exist after call"); kh.setKnownHosts(subDirFile.getAbsolutePath()); promptHandlers.add((message) -> checkMessageAndReturn(subDirFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?", message, true)); promptHandlers .add((message) -> checkMessageAndReturn("The parent directory " + subdirParentAbsPath + " does not exist.\n" + "Are you sure you want to create it?", message, false)); kh.syncKnownHostsFile(checkUI); assertEquals( "UIPYN: " + subDirFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?\r\n" + "UIPYN: The parent directory " + subdirParentAbsPath + " does not exist.\n" + "Are you sure you want to create it?", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertFalse(subDirFile.exists(), "file shouldn't exist after call"); assertFalse(tempFile.exists(), "subdir shouldn't exist after call"); assertTrue(tempFile.createNewFile(), "unable to create " + tempFile.getAbsolutePath()); promptHandlers.add((message) -> checkMessageAndReturn(subDirFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?", message, true)); promptHandlers .add((message) -> checkMessageAndReturn("The parent directory " + subdirParentAbsPath + " does not exist.\n" + "Are you sure you want to create it?", message, true)); kh.syncKnownHostsFile(checkUI); assertEquals("UIPYN: " + subDirFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?\r\n" + "UIPYN: The parent directory " + subdirParentAbsPath + " does not exist.\n" + "Are you sure you want to create it?\r\n" + "UIM: " + subdirParentAbsPath + " has not been created.", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertFalse(subDirFile.exists(), "file shouldn't exist after call"); assertTrue(tempFile.isFile(), "subdir should exist as file after call"); assertTrue(tempFile.delete(), "unable to delete " + tempFile.getAbsolutePath()); promptHandlers.add((message) -> checkMessageAndReturn(subDirFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?", message, true)); promptHandlers .add((message) -> checkMessageAndReturn("The parent directory " + subdirParentAbsPath + " does not exist.\n" + "Are you sure you want to create it?", message, true)); kh.syncKnownHostsFile(checkUI); assertEquals( "UIPYN: " + subDirFile.getAbsolutePath() + " does not exist.\n" + "Are you sure you want to create it?\r\n" + "UIPYN: The parent directory " + subdirParentAbsPath + " does not exist.\n" + "Are you sure you want to create it?\r\n" + "UIM: " + subdirParentAbsPath + " has been succesfully created.\n" + "Please check its access permission.\r\n" + "sync called with file " + subDirFile.getAbsolutePath(), messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertFalse(subDirFile.exists(), "file shouldn't exist after call"); assertTrue(tempFile.isDirectory(), "subdir should exist as directory after call"); assertTrue(subDirFile.createNewFile(), "unable to create " + subDirFile.getAbsolutePath()); kh.syncKnownHostsFile(checkUI); assertEquals("sync called with file " + subDirFile.getAbsolutePath(), messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); assertTrue(subDirFile.exists(), "file should exist (we've created it)"); assertTrue(tempFile.isDirectory(), "subdir should exist as directory after call"); throwException[0] = true; kh.syncKnownHostsFile(checkUI); assertEquals( "sync called with file " + subDirFile.getAbsolutePath() + "\r\n" + "M(3): unable to sync known host file " + subDirFile.getAbsolutePath() + "\r\n" + " java.lang.RuntimeException: dummy re", messages.stream().collect(Collectors.joining("\r\n"))); messages.clear(); } finally { if (tempFile != null) { subDirFile.delete(); subDirFile.getParentFile().delete(); tempFile.delete(); } } } @Test public void testCheck() throws Exception { KnownHosts kh = new KnownHosts(jsch); String expectedExceptionMessage = ""; try { new HostKey("host.example.com", HostKey.GUESS, new byte[0]); fail("exception expected"); } catch (Exception e) { expectedExceptionMessage = e.getMessage(); } assertEquals(KnownHosts.NOT_INCLUDED, kh.check(null, new byte[0]), "null host should return NOT_INCLUDED"); assertEquals(0, messages.size(), "no messages expected: " + messages.stream().collect(Collectors.joining("\r\n"))); assertEquals(KnownHosts.NOT_INCLUDED, kh.check("host.example.com", new byte[0]), "empty key should return NOT_INCLUDED"); assertEquals(1, messages.size(), "only one message: " + messages.stream().collect(Collectors.joining("\r\n"))); assertEquals( "M(0): exception while trying to read key while checking host 'host.example.com'\r\n" + " java.lang.ArrayIndexOutOfBoundsException: " + expectedExceptionMessage, messages.removeFirst(), "unexpected message"); addHosts(kh); assertEquals(KnownHosts.NOT_INCLUDED, kh.check("host.example.com", dsaKeyBytes), "type mismatch should return NOT_INCLUDED"); assertEquals(KnownHosts.OK, kh.check("host.example.com", rsaKeyBytes), "fitting key should return OK"); assertEquals(KnownHosts.OK, kh.check("192.277.325.3", rsaKeyBytes), "fitting key should return OK"); assertEquals(KnownHosts.OK, kh.check("192.277.325.5", dsaKeyBytes), "fitting key should return OK"); assertEquals(KnownHosts.OK, kh.check("[192.277.325.5]:123", dsaKeyBytes), "fitting key should return OK"); assertEquals(KnownHosts.NOT_INCLUDED, kh.check("[192.277.325.5:123]", dsaKeyBytes), "invalid syntax should return NOT_INCLUDED"); assertEquals(KnownHosts.NOT_INCLUDED, kh.check("[]:123", dsaKeyBytes), "invalid syntax should return NOT_INCLUDED"); assertEquals(KnownHosts.CHANGED, kh.check("host.example.com", " ssh-rsa1234".getBytes(ISO_8859_1)), "changed key should return CHANGED"); assertEquals(KnownHosts.NOT_INCLUDED, kh.check("host2.example.com", rsaKeyBytes), "host mismatch should return NOT_INCLUDED"); assertEquals(KnownHosts.NOT_INCLUDED, kh.check("192.277.325.5", rsaKeyBytes), "wrong key should return NOT_INCLUDED"); assertEquals(KnownHosts.OK, kh.check("[192.277.325.5]:123", dsaKeyBytes), "fitting key should return OK"); assertEquals(KnownHosts.OK, kh.check("[192.277.325.5]:123", rsaKeyBytes), "fitting key should return OK"); assertEquals(0, messages.size(), "no messages expected: " + getMessagesAsString()); } @Test public void testAddGetRemoveHostKeys() throws Exception { boolean[] throwException = new boolean[1]; Session.random = new NotSoRandomRandom(); KnownHosts kh = new KnownHosts(jsch) { @Override void sync() throws IOException { messages.add("sync"); if (throwException[0]) { messages.add("throw exception"); throw new RuntimeException("dummy re"); } } }; HostKey[] hosts; addHosts(kh); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys"); assertEquals( "host.example.com,192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "[192.277.325.5]:123: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); hosts = kh.getHostKey("nohost.example.com", null); assertEquals(0, hosts.length, "unexpected number of host keys"); hosts = kh.getHostKey("host.example.com", null); assertEquals(1, hosts.length, "unexpected number of host keys"); assertEquals("host.example.com,192.277.325.3: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); hosts = kh.getHostKey("192.277.325.5", null); assertEquals(1, hosts.length, "unexpected number of host keys"); assertEquals("192.277.325.5: key type ssh-dss", getHostKeysString(hosts), "unexpected hosts"); hosts = kh.getHostKey("[192.277.325.5]:123", null); assertEquals(2, hosts.length, "unexpected number of host keys"); assertEquals("[192.277.325.5]:123: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss", getHostKeysString(hosts), "unexpected hosts"); hosts = kh.getHostKey("[192.277.325.5]:123", "ssh-dss"); assertEquals(1, hosts.length, "unexpected number of host keys"); assertEquals("192.277.325.5: key type ssh-dss", getHostKeysString(hosts), "unexpected hosts"); hosts = kh.getHostKey("[192.277.325.5:123]", "ssh-dss"); assertEquals(0, hosts.length, "unexpected number of host keys"); assertEquals(0, messages.size(), "unexpected number of messages: " + getMessagesAsString()); kh.remove(null, null); hosts = kh.getHostKey(); assertEquals(0, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("sync", getMessagesAsString(), "unexpected messages"); addHosts(kh); kh.remove(null, "ssh-dsa"); hosts = kh.getHostKey(); assertEquals(0, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("sync", getMessagesAsString(), "unexpected messages"); addHosts(kh); kh.remove("host.example.com", null); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals( "192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "[192.277.325.5]:123: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("sync", getMessagesAsString(), "unexpected messages"); kh.remove("[192.277.325.5]:123", "ssh-dsa"); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals( "192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "[192.277.325.5]:123: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("", getMessagesAsString(), "unexpected messages"); kh.remove("[192.277.325.5]:123", "ssh-rsa", " ssh-rsa1234".getBytes(ISO_8859_1)); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals( "192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "[192.277.325.5]:123: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("", getMessagesAsString(), "unexpected messages"); kh.remove("[192.277.325.5]:123", "ssh-rsa", rsaKeyBytes); hosts = kh.getHostKey(); assertEquals(2, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss", getHostKeysString(hosts), "unexpected hosts"); assertEquals("sync", getMessagesAsString(), "unexpected messages"); HashedHostKey hhk = kh.new HashedHostKey("hashed.example.com", rsaKeyBytes); kh.add(hhk, null); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "hashed.example.com: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("", getMessagesAsString(), "unexpected messages"); kh.remove("nothashed.example.com", "ssh-rsa"); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "hashed.example.com: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("", getMessagesAsString(), "unexpected messages"); kh.remove("hashed.example.com", "ssh-rsa"); hosts = kh.getHostKey(); assertEquals(2, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss", getHostKeysString(hosts), "unexpected hosts"); assertEquals("sync", getMessagesAsString(), "unexpected messages"); hhk.hash(); kh.add(hhk, null); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals( "192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "|1|AAECAwQFBgcICQoLDA0ODxAREhM=|tfTk2zfUwEOJq8/nQE8s/gLfc58=: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("", getMessagesAsString(), "unexpected messages"); kh.remove("nothashed.example.com", "ssh-rsa"); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals( "192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "|1|AAECAwQFBgcICQoLDA0ODxAREhM=|tfTk2zfUwEOJq8/nQE8s/gLfc58=: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("", getMessagesAsString(), "unexpected messages"); kh.remove("hashed.example.com", "ssh-rsa"); hosts = kh.getHostKey(); assertEquals(2, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss", getHostKeysString(hosts), "unexpected hosts"); assertEquals("sync", getMessagesAsString(), "unexpected messages"); throwException[0] = true; kh.remove("192.277.325.5", "ssh-dss"); hosts = kh.getHostKey(); assertEquals(1, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("192.277.325.3: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("sync\r\n" + "throw exception", getMessagesAsString(), "unexpected messages"); kh.remove(null, null); addHosts(kh); hosts = kh.getHostKey(); assertEquals(3, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals( "host.example.com,192.277.325.3: key type ssh-rsa\r\n" + "192.277.325.5: key type ssh-dss\r\n" + "[192.277.325.5]:123: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); assertEquals("sync\r\n" + "throw exception", getMessagesAsString(), "unexpected messages"); kh.remove("192.277.325.5", null); hosts = kh.getHostKey("[192.277.325.5]:123", null); assertEquals(1, hosts.length, "unexpected number of host keys: " + getHostKeysString(hosts)); assertEquals("[192.277.325.5]:123: key type ssh-rsa", getHostKeysString(hosts), "unexpected hosts"); } private String getMessagesAsString() { try { return messages.stream().collect(Collectors.joining("\r\n")); } finally { messages.clear(); } } private void addHosts(KnownHosts kh) throws JSchException { kh.add(new HostKey("host.example.com,192.277.325.3", rsaKeyBytes), null); kh.add(new HostKey("192.277.325.5", dsaKeyBytes), null); kh.add(new HostKey("[192.277.325.5]:123", rsaKeyBytes), null); } private String getHostKeysString(HostKey[] hosts) { return Arrays.stream(hosts).map(host -> host.getHost() + ": key type " + host.getType()) .collect(Collectors.joining("\r\n")); } private Boolean checkMessageAndReturn(String expectedMessge, String actual, boolean ret) { assertEquals(expectedMessge, actual, "prompted message mismatch"); return Boolean.valueOf(ret); } private void checkUnhashedHostKey(HashedHostKey hhk, String expectedMarker, String expctedHost, String expectedType, String expectedComment) { assertEquals(expctedHost, hhk.getHost(), "host mismatch"); assertEquals(expectedMarker, hhk.getMarker(), "marker mismatch"); assertEquals( "1e:b5:70:92:65:6e:6a:f9:d6:7a:a9:43:00:40:a2:e7:c8:51:35:df:ee:60:19:b7:4b:18:1d:eb:46:48:28:4b", hhk.getFingerPrint(jsch)); assertEquals(expectedComment, hhk.getComment(), "comment mismatch"); assertEquals("ICAgIHNzaC1kc2E=", hhk.getKey(), "key mismatch"); assertEquals(expectedType, hhk.getType(), "type mismatch"); assertFalse(hhk.isHashed(), "key should report itself unhashed"); assertNull(hhk.salt, "salt should be null"); assertNull(hhk.hash, "hash should be null"); } private void checkSHA1HashResult(HashedHostKey hhk, String expectedMarker, String expectedType, String expectedComment) throws UnsupportedEncodingException { assertEquals("|1|AAECAwQFBgcICQoLDA0ODxAREhM=|/pE4peaossRYDRp6bEWa348eFLI=", hhk.getHost(), "host mismatch"); assertEquals(expectedMarker, hhk.getMarker(), "marker mismatch"); assertEquals( "1e:b5:70:92:65:6e:6a:f9:d6:7a:a9:43:00:40:a2:e7:c8:51:35:df:ee:60:19:b7:4b:18:1d:eb:46:48:28:4b", hhk.getFingerPrint(jsch)); assertEquals(expectedComment, hhk.getComment(), "comment mismatch"); assertEquals("ICAgIHNzaC1kc2E=", hhk.getKey(), "key mismatch"); assertEquals(expectedType, hhk.getType(), "type mismatch"); assertTrue(hhk.isHashed(), "key should report itself hashed"); assertEquals("AAECAwQFBgcICQoLDA0ODxAREhM=", new String(Util.toBase64(hhk.salt, 0, hhk.salt.length, true), ISO_8859_1), "salt should be null"); assertEquals("/pE4peaossRYDRp6bEWa348eFLI=", new String(Util.toBase64(hhk.hash, 0, hhk.hash.length, true), ISO_8859_1), "salt should be null"); } private String getContent(String filename) throws IOException { try (FileInputStream fis = new FileInputStream(filename)) { StringBuilder sb = new StringBuilder(); int read; while ((read = fis.read()) != -1) { sb.append((char) read); } return sb.toString(); } } private void checkResultForKeyResult(HostKey[] keys, String rsaKey, String expectedHostResult, String expectedMarker) { assertNotNull(keys, "actual keys expected"); assertEquals(1, keys.length, "1 key expected"); HostKey key = keys[0]; assertEquals("some comment", key.getComment(), "comment mismatch"); assertEquals( "9d:38:5b:83:a9:17:52:92:56:1a:5e:c4:d4:81:8e:0a:ca:51:a2:64:f1:74:20:11:2e:f8:8a:c3:a1:39:49:8f", key.getFingerPrint(jsch), "fingerprint mismatch"); assertEquals(expectedHostResult, key.getHost(), "host mismatch"); assertEquals(rsaKey, key.getKey(), "key mismatch"); assertEquals(expectedMarker, key.getMarker(), "marker mismatch"); assertEquals("ssh-rsa", key.getType(), "type mismatch"); } private static class BCHMACSHA1 implements MAC { private final Mac mac; private BCHMACSHA1(Mac mac) { this.mac = mac; } @Override public void update(int foo) { mac.update((byte) foo); } @Override public void update(byte[] foo, int start, int len) { mac.update(foo, start, len); } @Override public void init(byte[] key) throws Exception { SecretKey k = new SecretKeySpec(key, "hmacsha1"); mac.init(k); } @Override public String getName() { return mac.getAlgorithm(); } @Override public int getBlockSize() { return mac.getMacLength(); } @Override public void doFinal(byte[] buf, int offset) { try { mac.doFinal(buf, offset); } catch (ShortBufferException sbe) { throw new RuntimeException("unable to do final", sbe); } } } private static class NotSoRandomRandom extends com.jcraft.jsch.jce.Random { @Override public void fill(byte[] foo, int start, int len) { for (int i = 0; i < len; i++) { foo[i + start] = (byte) i; } } } private static class TestLogger implements Logger { private final LinkedList messages; private TestLogger(LinkedList messages) { this.messages = messages; } @Override public void log(int level, String message) { messages.add("M(" + level + "): " + message); } @Override public void log(int level, String message, Throwable cause) { if (cause != null) { message += "\r\n " + cause.getClass().getName() + ": " + cause.getMessage(); } messages.add("M(" + level + "): " + message); } @Override public boolean isEnabled(int level) { return true; } } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/Log4j2LoggerTest.java000066400000000000000000000202261465436372100260600ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.test.appender.ListAppender; import org.apache.logging.log4j.core.test.junit.LoggerContextSource; import org.apache.logging.log4j.core.test.junit.Named; import org.apache.logging.log4j.message.Message; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @LoggerContextSource("Log4j2LoggerTest.xml") public class Log4j2LoggerTest { private final Exception testException = new Exception("dummy exception"); private final ListAppender appender; public Log4j2LoggerTest(@Named("List") ListAppender appender) { this.appender = appender; } @BeforeEach public void beforeEach() { appender.clear(); } @Test public void testGetLevel() { assertEquals(Level.TRACE, Log4j2Logger.getLevel(-1)); assertEquals(Level.DEBUG, Log4j2Logger.getLevel(com.jcraft.jsch.Logger.DEBUG)); assertEquals(Level.ERROR, Log4j2Logger.getLevel(com.jcraft.jsch.Logger.ERROR)); assertEquals(Level.FATAL, Log4j2Logger.getLevel(com.jcraft.jsch.Logger.FATAL)); assertEquals(Level.INFO, Log4j2Logger.getLevel(com.jcraft.jsch.Logger.INFO)); assertEquals(Level.WARN, Log4j2Logger.getLevel(com.jcraft.jsch.Logger.WARN)); assertEquals(Level.TRACE, Log4j2Logger.getLevel(Integer.MAX_VALUE)); } @Test public void testIsEnabled() { Log4j2Logger ll = new Log4j2Logger(); setLevel(Level.ALL); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertTrue(ll.isEnabled(-1), "trace should be enabled"); setLevel(Level.DEBUG); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(ll.isEnabled(-1), "trace should not be enabled"); setLevel(Level.ERROR); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(ll.isEnabled(-1), "trace should not be enabled"); setLevel(Level.FATAL); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should not be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(ll.isEnabled(-1), "trace should not be enabled"); setLevel(Level.INFO); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(ll.isEnabled(-1), "trace should not be enabled"); setLevel(Level.OFF); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(ll.isEnabled(-1), "trace should not be enabled"); setLevel(Level.TRACE); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertTrue(ll.isEnabled(-1), "trace should be enabled"); setLevel(Level.WARN); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(ll.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertTrue(ll.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(ll.isEnabled(-1), "trace should not be enabled"); } @Test public void testLogging() { Log4j2Logger ll = new Log4j2Logger(); List expectedMessages = Arrays.asList("debug message", "debug message with null cause", "debug message with cause"); List> expectedExceptions = Arrays.asList(Optional.empty(), Optional.ofNullable(null), Optional.of(testException)); setLevel(Level.TRACE); ll.log(-1, "debug message"); ll.log(-1, "debug message with null cause", null); ll.log(-1, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); setLevel(Level.TRACE); ll.log(com.jcraft.jsch.Logger.FATAL, "debug message"); ll.log(com.jcraft.jsch.Logger.FATAL, "debug message with null cause", null); ll.log(com.jcraft.jsch.Logger.FATAL, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); setLevel(Level.ERROR); ll.log(-1, "debug message"); ll.log(-1, "debug message with null cause", null); ll.log(-1, "debug message with cause", testException); checkMessages(Collections.emptyList(), Collections.emptyList()); setLevel(Level.ERROR); ll.log(com.jcraft.jsch.Logger.FATAL, "debug message"); ll.log(com.jcraft.jsch.Logger.FATAL, "debug message with null cause", null); ll.log(com.jcraft.jsch.Logger.FATAL, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); } private void checkMessages(List expectedMessages, List> expectedExceptions) { List events = appender.getEvents(); appender.clear(); List actualMessages = events.stream().map(LogEvent::getMessage) .map(Message::getFormattedMessage).collect(Collectors.toList()); List> actualExceptions = events.stream().map(LogEvent::getThrown) .map(Optional::ofNullable).collect(Collectors.toList()); assertEquals(expectedMessages, actualMessages, "mismatch in logged messages"); assertEquals(expectedExceptions, actualExceptions, "mismatch in logged exceptions"); } private static void setLevel(Level level) { Configurator.setLevel(JSch.class, level); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/LoggerTest.java000066400000000000000000000035341465436372100251010ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; public class LoggerTest { private final Exception testException = new Exception("dummy exception"); @Test public void testLogging() { List actualMessages = new ArrayList<>(); boolean[] enabledResult = new boolean[1]; Logger logger = new Logger() { @Override public void log(int level, String message) { if (isEnabled(level)) { actualMessages.add(level + ":" + message); } } @Override public boolean isEnabled(int level) { return enabledResult[0]; } }; actualMessages.clear(); enabledResult[0] = false; logger.log(Logger.ERROR, "debug message"); logger.log(Logger.ERROR, "debug message with null cause", null); logger.log(Logger.ERROR, "debug message with cause", testException); assertEquals(Collections.emptyList(), actualMessages, "mismatch in logged messages"); StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw, true)) { testException.printStackTrace(pw); } List expectedMessages = Arrays.asList(Logger.ERROR + ":debug message", Logger.ERROR + ":debug message with null cause", Logger.ERROR + ":debug message with cause" + System.lineSeparator() + sw); actualMessages.clear(); enabledResult[0] = true; logger.log(Logger.ERROR, "debug message"); logger.log(Logger.ERROR, "debug message with null cause", null); logger.log(Logger.ERROR, "debug message with cause", testException); assertEquals(expectedMessages, actualMessages, "mismatch in logged messages"); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/MockUserInfo.java000066400000000000000000000015221465436372100253610ustar00rootroot00000000000000package com.jcraft.jsch; import java.util.ArrayList; import java.util.List; public class MockUserInfo implements UserInfo { private final List messages; public MockUserInfo() { messages = new ArrayList<>(); } @Override public String getPassphrase() { return ""; } @Override public String getPassword() { return ""; } @Override public boolean promptPassword(String message) { messages.add(message); return false; } @Override public boolean promptPassphrase(String message) { messages.add(message); return false; } @Override public boolean promptYesNo(String message) { messages.add(message); return false; } @Override public void showMessage(String message) { messages.add(message); } public List getMessages() { return messages; } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/OpenSSH74ServerSigAlgsIT.java000066400000000000000000000176311465436372100273550ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledOnOs; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @EnabledOnOs(architectures = "x86_64") @Testcontainers public class OpenSSH74ServerSigAlgsIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(OpenSSH74ServerSigAlgsIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.openssh74")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test public void testServerSigAlgs() throws Exception { String algos = "ssh-rsa-sha512@ssh.com,ssh-rsa-sha384@ssh.com,ssh-rsa-sha256@ssh.com,ssh-rsa-sha224@ssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa"; JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", algos); session.setConfig("server_host_key", algos); doSftp(session, true); String expectedKex = "kex: host key algorithm: rsa-sha2-512"; String expectedExtInfo = "SSH_MSG_EXT_INFO received"; String expectedServerSigAlgs = "server-sig-algs="; String expectedOpenSSH74Bug = "OpenSSH 7.4 detected: adding rsa-sha2-256 & rsa-sha2-512 to server-sig-algs"; String expectedPubkeysKnown = "PubkeyAcceptedAlgorithms in server-sig-algs = \\[rsa-sha2-512, rsa-sha2-256, ssh-rsa\\]"; String expectedPubkeysUnknown = "PubkeyAcceptedAlgorithms not in server-sig-algs = \\[ssh-rsa-sha512@ssh.com, ssh-rsa-sha384@ssh.com, ssh-rsa-sha256@ssh.com, ssh-rsa-sha224@ssh.com\\]"; String expectedPreauth = "rsa-sha2-512 preauth success"; String expectedAuth = "rsa-sha2-512 auth success"; checkLogs(expectedKex); checkLogs(expectedExtInfo); checkLogs(expectedServerSigAlgs); checkLogs(expectedOpenSSH74Bug); checkLogs(expectedPubkeysKnown); checkLogs(expectedPubkeysUnknown); checkLogs(expectedPreauth); checkLogs(expectedAuth); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java000066400000000000000000000115401465436372100262630ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Paths; import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; class OpenSSHConfigTest { Map keyMap = OpenSSHConfig.getKeymap().entrySet().stream().collect(Collectors .toMap(entry -> entry.getValue().toUpperCase(Locale.ROOT), Map.Entry::getKey, (s, s2) -> s2)); @Test void parseFile() throws IOException, URISyntaxException { final String configFile = Paths.get(ClassLoader.getSystemResource("config").toURI()).toFile().getAbsolutePath(); final OpenSSHConfig openSSHConfig = OpenSSHConfig.parseFile(configFile); final ConfigRepository.Config config = openSSHConfig.getConfig("host2"); assertNotNull(config); assertEquals("foobar", config.getUser()); assertEquals("host2.somewhere.edu", config.getHostname()); assertEquals("~/.ssh/old_keys/host2_key", config.getValue("IdentityFile")); } @ParameterizedTest @ValueSource(strings = {"MACs", "Macs"}) void parseMacsCaseInsensitive(String key) throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse(key + " someValue"); ConfigRepository.Config config = parse.getConfig(""); assertEquals("someValue", config.getValue("mac.c2s")); assertEquals("someValue", config.getValue("mac.s2c")); } @Test void appendKexAlgorithms() throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse("KexAlgorithms +diffie-hellman-group1-sha1"); ConfigRepository.Config kex = parse.getConfig(""); assertEquals(JSch.getConfig("kex") + "," + "diffie-hellman-group1-sha1", kex.getValue("kex")); } @ParameterizedTest @ValueSource(strings = {"KexAlgorithms", "Ciphers", "HostKeyAlgorithms", "MACs", "PubkeyAcceptedAlgorithms", "PubkeyAcceptedKeyTypes"}) void appendAlgorithms(String key) throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse(key + " +someValue,someValue1"); ConfigRepository.Config config = parse.getConfig(""); String mappedKey = Optional.ofNullable(keyMap.get(key.toUpperCase(Locale.ROOT))).orElse(key); assertEquals(JSch.getConfig(mappedKey) + "," + "someValue,someValue1", config.getValue(mappedKey)); } @ParameterizedTest @ValueSource(strings = {"KexAlgorithms", "Ciphers", "HostKeyAlgorithms", "MACs", "PubkeyAcceptedAlgorithms", "PubkeyAcceptedKeyTypes"}) void prependAlgorithms(String key) throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse(key + " ^someValue,someValue1"); ConfigRepository.Config config = parse.getConfig(""); String mappedKey = Optional.ofNullable(keyMap.get(key.toUpperCase(Locale.ROOT))).orElse(key); assertEquals("someValue,someValue1," + JSch.getConfig(mappedKey), config.getValue(mappedKey)); } @Test void prependKexAlgorithms() throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse("KexAlgorithms ^diffie-hellman-group1-sha1"); ConfigRepository.Config kex = parse.getConfig(""); assertEquals("diffie-hellman-group1-sha1," + JSch.getConfig("kex"), kex.getValue("kex")); } @Test void removeKexAlgorithm() throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse("KexAlgorithms -ecdh-sha2-nistp256"); ConfigRepository.Config kex = parse.getConfig(""); assertEquals(JSch.getConfig("kex").replaceAll(",ecdh-sha2-nistp256", ""), kex.getValue("kex")); } @Test void replaceKexAlgorithms() throws IOException { OpenSSHConfig parse = OpenSSHConfig.parse("KexAlgorithms diffie-hellman-group1-sha1"); ConfigRepository.Config kex = parse.getConfig(""); assertEquals("diffie-hellman-group1-sha1", kex.getValue("kex")); } @Test void parseFileWithNegations() throws IOException, URISyntaxException { final String configFile = Paths.get(ClassLoader.getSystemResource("config_with_negations").toURI()).toFile() .getAbsolutePath(); final OpenSSHConfig openSSHConfig = OpenSSHConfig.parseFile(configFile); assertUserEquals(openSSHConfig, "my.example.com", "u1"); assertUserEquals(openSSHConfig, "my-jump.example.com", "jump-u1"); assertUserEquals(openSSHConfig, "my-proxy.example.com", "proxy-u1"); assertUserEquals(openSSHConfig, "my.example.org", "u2"); } private void assertUserEquals(OpenSSHConfig openSSHConfig, String host, String expected) { final ConfigRepository.Config config = openSSHConfig.getConfig(host); assertNotNull(config); String actual = config.getUser(); assertEquals(expected, actual, String.format(Locale.ROOT, "Expected user for host %s to be %s, but was %s", host, expected, actual)); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/PktSize128IT.java000066400000000000000000000030431465436372100250760ustar00rootroot00000000000000package com.jcraft.jsch; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; public class PktSize128IT extends AbstractBufferMargin { public PktSize128IT() { super(128); } @ParameterizedTest @CsvSource(value = { // 16 byte tag (MAC doesn't matter) "aes128-gcm@openssh.com,hmac-sha1,none", "aes128-gcm@openssh.com,hmac-sha1,zlib@openssh.com", // 12 byte MAC "aes128-ctr,hmac-md5-96,none", "aes128-ctr,hmac-md5-96,zlib@openssh.com", // 16 byte MAC "aes128-ctr,hmac-md5,none", "aes128-ctr,hmac-md5,zlib@openssh.com", // 20 byte MAC "aes128-ctr,hmac-sha1,none", "aes128-ctr,hmac-sha1,zlib@openssh.com"}) public void testSftp(String cipher, String mac, String compression) throws Exception { doTestSftp(cipher, mac, compression); } @ParameterizedTest @CsvSource(value = { // 16 byte tag (MAC doesn't matter) "aes128-gcm@openssh.com,hmac-sha1,none", "aes128-gcm@openssh.com,hmac-sha1,zlib@openssh.com", // 12 byte MAC "aes128-ctr,hmac-md5-96,none", "aes128-ctr,hmac-md5-96,zlib@openssh.com", // 16 byte MAC "aes128-ctr,hmac-md5,none", "aes128-ctr,hmac-md5,zlib@openssh.com", // 20 byte MAC "aes128-ctr,hmac-sha1,none", "aes128-ctr,hmac-sha1,zlib@openssh.com", // 32 byte MAC "aes128-ctr,hmac-sha2-256,none", "aes128-ctr,hmac-sha2-256,zlib@openssh.com"}) public void testScp(String cipher, String mac, String compression) throws Exception { doTestScp(cipher, mac, compression); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/PktSize160IT.java000066400000000000000000000014461465436372100250770ustar00rootroot00000000000000package com.jcraft.jsch; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; public class PktSize160IT extends AbstractBufferMargin { public PktSize160IT() { super(160); } @ParameterizedTest @CsvSource(value = { // 32 byte MAC "aes128-ctr,hmac-sha2-256,none", "aes128-ctr,hmac-sha2-256,zlib@openssh.com"}) public void testSftp(String cipher, String mac, String compression) throws Exception { doTestSftp(cipher, mac, compression); } @ParameterizedTest @CsvSource(value = { // 64 byte MAC "aes128-ctr,hmac-sha2-512,none", "aes128-ctr,hmac-sha2-512,zlib@openssh.com"}) public void testScp(String cipher, String mac, String compression) throws Exception { doTestScp(cipher, mac, compression); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/PktSize192IT.java000066400000000000000000000010121465436372100250710ustar00rootroot00000000000000package com.jcraft.jsch; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; public class PktSize192IT extends AbstractBufferMargin { public PktSize192IT() { super(192); } @ParameterizedTest @CsvSource(value = { // 64 byte MAC "aes128-ctr,hmac-sha2-512,none", "aes128-ctr,hmac-sha2-512,zlib@openssh.com"}) public void testSftp(String cipher, String mac, String compression) throws Exception { doTestSftp(cipher, mac, compression); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/PktSize32768IT.java000066400000000000000000000035441465436372100252630ustar00rootroot00000000000000package com.jcraft.jsch; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; public class PktSize32768IT extends AbstractBufferMargin { public PktSize32768IT() { super(32768); } @ParameterizedTest @CsvSource(value = { // 16 byte tag (MAC doesn't matter) "aes128-gcm@openssh.com,hmac-sha1,none", "aes128-gcm@openssh.com,hmac-sha1,zlib@openssh.com", // 12 byte MAC "aes128-ctr,hmac-md5-96,none", "aes128-ctr,hmac-md5-96,zlib@openssh.com", // 16 byte MAC "aes128-ctr,hmac-md5,none", "aes128-ctr,hmac-md5,zlib@openssh.com", // 20 byte MAC "aes128-ctr,hmac-sha1,none", "aes128-ctr,hmac-sha1,zlib@openssh.com", // 32 byte MAC "aes128-ctr,hmac-sha2-256,none", "aes128-ctr,hmac-sha2-256,zlib@openssh.com", // 64 byte MAC "aes128-ctr,hmac-sha2-512,none", "aes128-ctr,hmac-sha2-512,zlib@openssh.com"}) public void testSftp(String cipher, String mac, String compression) throws Exception { doTestSftp(cipher, mac, compression); } @ParameterizedTest @CsvSource(value = { // 16 byte tag (MAC doesn't matter) "aes128-gcm@openssh.com,hmac-sha1,none", "aes128-gcm@openssh.com,hmac-sha1,zlib@openssh.com", // 12 byte MAC "aes128-ctr,hmac-md5-96,none", "aes128-ctr,hmac-md5-96,zlib@openssh.com", // 16 byte MAC "aes128-ctr,hmac-md5,none", "aes128-ctr,hmac-md5,zlib@openssh.com", // 20 byte MAC "aes128-ctr,hmac-sha1,none", "aes128-ctr,hmac-sha1,zlib@openssh.com", // 32 byte MAC "aes128-ctr,hmac-sha2-256,none", "aes128-ctr,hmac-sha2-256,zlib@openssh.com", // 64 byte MAC "aes128-ctr,hmac-sha2-512,none", "aes128-ctr,hmac-sha2-512,zlib@openssh.com"}) public void testScp(String cipher, String mac, String compression) throws Exception { doTestScp(cipher, mac, compression); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/ResourceUtil.java000066400000000000000000000007341465436372100254460ustar00rootroot00000000000000package com.jcraft.jsch; import java.io.File; public class ResourceUtil { public static String getResourceFile(Class clazz, String fileName) { String path = clazz.getClassLoader().getResource(fileName).getFile(); // Note: on Windows the returned path can be in the form: /C:/ // to strip the initial / in a platform independent way we need to // create a java.io.File and take it's absolute path return new File(path).getAbsolutePath(); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/SSHAgentIT.java000066400000000000000000000361751465436372100247020ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.JRE.JAVA_16; import static org.junit.jupiter.api.condition.OS.LINUX; import static org.testcontainers.containers.BindMode.READ_WRITE; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import com.sun.jna.platform.unix.LibC; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.EnabledOnOs; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @EnabledOnOs(LINUX) @Testcontainers public class SSHAgentIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(SSHAgentIT.class); private static final TestLogger sshAgentLogger = TestLoggerFactory.getTestLogger(AgentProxy.class); @TempDir public static Path tmpDir; private static String testuid; private static String testgid; private static Path sshAgentSock; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; private Slf4jLogConsumer sshAgentLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile")) .withExposedPorts(22); @Container public GenericContainer sshAgent = new GenericContainer<>( new ImageFromDockerfile().withBuildArg("testuid", testuid).withBuildArg("testgid", testgid) .withFileFromClasspath("Dockerfile", "docker/Dockerfile.sshagent")) .withFileSystemBind(sshAgentSock.getParent().toString(), "/testuser", READ_WRITE); @BeforeAll public static void beforeAll() throws IOException { JSch.setLogger(new Slf4jLogger()); LibC libc = LibC.INSTANCE; testuid = Integer.toString(libc.getuid()); testgid = Integer.toString(libc.getgid()); Path temp = Files.createTempDirectory(tmpDir, "sshagent"); sshAgentSock = temp.resolve("sock"); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } if (sshAgentLogConsumer == null) { sshAgentLogConsumer = new Slf4jLogConsumer(sshAgentLogger); sshAgent.followOutput(sshAgentLogConsumer); } Path temp = Files.createTempDirectory(tmpDir, "sshd"); in = temp.resolve("in"); out = temp.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); sshAgentLogger.clearAll(); } @AfterEach public void afterEach() { try { Files.deleteIfExists(sshAgentSock); } catch (IOException ignore) { } try { Files.deleteIfExists(out); } catch (IOException ignore) { } try { Files.deleteIfExists(in); } catch (IOException ignore) { } try { Files.deleteIfExists(in.getParent()); } catch (IOException ignore) { } } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); sshAgentLogger.clearAll(); try { Files.deleteIfExists(sshAgentSock.getParent()); } catch (IOException ignore) { } } @Test public void testEd25519JUnixSocketFactory() throws Exception { JSch ssh = createEd25519Identity(new JUnixSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed25519"); doSftp(session, true); } @Test public void testECDSA521JUnixSocketFactory() throws Exception { JSch ssh = createECDSA521Identity(new JUnixSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp521"); doSftp(session, true); } @Test public void testECDSA384JUnixSocketFactory() throws Exception { JSch ssh = createECDSA384Identity(new JUnixSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp384"); doSftp(session, true); } @Test public void testECDSA256JUnixSocketFactory() throws Exception { JSch ssh = createECDSA256Identity(new JUnixSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp256"); doSftp(session, true); } @ParameterizedTest @ValueSource(strings = {"rsa-sha2-512", "rsa-sha2-256", "ssh-rsa"}) public void testRSAJUnixSocketFactory(String keyType) throws Exception { JSch ssh = createRSAIdentity(new JUnixSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", keyType); doSftp(session, true); } @Test public void testDSAJUnixSocketFactory() throws Exception { JSch ssh = createDSAIdentity(new JUnixSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-dss"); doSftp(session, true); } @Test @EnabledForJreRange(min = JAVA_16) public void testEd25519UnixDomainSocketFactory() throws Exception { JSch ssh = createEd25519Identity(new UnixDomainSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-ed25519"); doSftp(session, true); } @Test @EnabledForJreRange(min = JAVA_16) public void testECDSA521UnixDomainSocketFactory() throws Exception { JSch ssh = createECDSA521Identity(new UnixDomainSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp521"); doSftp(session, true); } @Test @EnabledForJreRange(min = JAVA_16) public void testECDSA384UnixDomainSocketFactory() throws Exception { JSch ssh = createECDSA384Identity(new UnixDomainSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp384"); doSftp(session, true); } @Test @EnabledForJreRange(min = JAVA_16) public void testECDSA256UnixDomainSocketFactory() throws Exception { JSch ssh = createECDSA256Identity(new UnixDomainSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ecdsa-sha2-nistp256"); doSftp(session, true); } @ParameterizedTest @ValueSource(strings = {"rsa-sha2-512", "rsa-sha2-256", "ssh-rsa"}) @EnabledForJreRange(min = JAVA_16) public void testRSAUnixDomainSocketFactory(String keyType) throws Exception { JSch ssh = createRSAIdentity(new UnixDomainSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", keyType); doSftp(session, true); } @Test @EnabledForJreRange(min = JAVA_16) public void testDSAUnixDomainSocketFactory() throws Exception { JSch ssh = createDSAIdentity(new UnixDomainSocketFactory()); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", "ssh-dss"); doSftp(session, true); } private JSch createRSAIdentity(USocketFactory factory) throws Exception { IdentityRepository ir = new AgentIdentityRepository(new SSHAgentConnector(factory, sshAgentSock)); assertTrue(ir.getIdentities().isEmpty(), "ssh-agent empty"); HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.setIdentityRepository(ir); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); assertEquals(1, ir.getIdentities().size()); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createECDSA256Identity(USocketFactory factory) throws Exception { IdentityRepository ir = new AgentIdentityRepository(new SSHAgentConnector(factory, sshAgentSock)); assertTrue(ir.getIdentities().isEmpty(), "ssh-agent empty"); HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.setIdentityRepository(ir); ssh.addIdentity(getResourceFile("docker/id_ecdsa256"), getResourceFile("docker/id_ecdsa256.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createECDSA384Identity(USocketFactory factory) throws Exception { IdentityRepository ir = new AgentIdentityRepository(new SSHAgentConnector(factory, sshAgentSock)); assertTrue(ir.getIdentities().isEmpty(), "ssh-agent empty"); HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.setIdentityRepository(ir); ssh.addIdentity(getResourceFile("docker/id_ecdsa384"), getResourceFile("docker/id_ecdsa384.pub"), null); assertEquals(1, ir.getIdentities().size()); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createECDSA521Identity(USocketFactory factory) throws Exception { IdentityRepository ir = new AgentIdentityRepository(new SSHAgentConnector(factory, sshAgentSock)); assertTrue(ir.getIdentities().isEmpty(), "ssh-agent empty"); HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.setIdentityRepository(ir); ssh.addIdentity(getResourceFile("docker/id_ecdsa521"), getResourceFile("docker/id_ecdsa521.pub"), null); assertEquals(1, ir.getIdentities().size()); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createDSAIdentity(USocketFactory factory) throws Exception { IdentityRepository ir = new AgentIdentityRepository(new SSHAgentConnector(factory, sshAgentSock)); assertTrue(ir.getIdentities().isEmpty(), "ssh-agent empty"); HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.setIdentityRepository(ir); ssh.addIdentity(getResourceFile("docker/id_dsa"), getResourceFile("docker/id_dsa.pub"), null); assertEquals(1, ir.getIdentities().size()); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private JSch createEd25519Identity(USocketFactory factory) throws Exception { IdentityRepository ir = new AgentIdentityRepository(new SSHAgentConnector(factory, sshAgentSock)); assertTrue(ir.getIdentities().isEmpty(), "ssh-agent empty"); HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.setIdentityRepository(ir); ssh.addIdentity(getResourceFile("docker/id_ed25519"), getResourceFile("docker/id_ed25519.pub"), null); assertEquals(1, ir.getIdentities().size()); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshAgentLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/ServerSigAlgsIT.java000066400000000000000000000217641465436372100260040ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class ServerSigAlgsIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(ServerSigAlgsIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test public void testServerSigAlgs() throws Exception { String algos = "ssh-rsa-sha512@ssh.com,ssh-rsa-sha384@ssh.com,ssh-rsa-sha256@ssh.com,ssh-rsa-sha224@ssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa"; JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("PubkeyAcceptedAlgorithms", algos); session.setConfig("server_host_key", algos); doSftp(session, true); String expectedKex = "kex: host key algorithm: rsa-sha2-512"; String expectedExtInfo = "SSH_MSG_EXT_INFO received"; String expectedServerSigAlgs = "server-sig-algs="; String expectedPubkeysKnown = "PubkeyAcceptedAlgorithms in server-sig-algs = \\[rsa-sha2-512, rsa-sha2-256, ssh-rsa\\]"; String expectedPubkeysUnknown = "PubkeyAcceptedAlgorithms not in server-sig-algs = \\[ssh-rsa-sha512@ssh.com, ssh-rsa-sha384@ssh.com, ssh-rsa-sha256@ssh.com, ssh-rsa-sha224@ssh.com\\]"; String expectedPreauth = "rsa-sha2-512 preauth success"; String expectedAuth = "rsa-sha2-512 auth success"; checkLogs(expectedKex); checkLogs(expectedExtInfo); checkLogs(expectedServerSigAlgs); checkLogs(expectedPubkeysKnown); checkLogs(expectedPubkeysUnknown); checkLogs(expectedPreauth); checkLogs(expectedAuth); } @Test public void testNoServerSigAlgs() throws Exception { String algos = "ssh-rsa-sha512@ssh.com,ssh-rsa-sha384@ssh.com,ssh-rsa-sha256@ssh.com,ssh-rsa-sha224@ssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa"; JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_server_sig_algs", "no"); session.setConfig("PubkeyAcceptedAlgorithms", algos); session.setConfig("server_host_key", algos); doSftp(session, true); String expectedKex = "kex: host key algorithm: rsa-sha2-512"; // String expectedPubkeysNoServerSigs = String.format(Locale.ROOT, // "No server-sig-algs found, using PubkeyAcceptedAlgorithms = %s", algos); String expectedPreauthFail1 = "ssh-rsa-sha512@ssh.com preauth failure"; String expectedPreauthFail2 = "ssh-rsa-sha384@ssh.com preauth failure"; String expectedPreauthFail3 = "ssh-rsa-sha256@ssh.com preauth failure"; String expectedPreauthFail4 = "ssh-rsa-sha224@ssh.com preauth failure"; String expectedPreauth = "rsa-sha2-512 preauth success"; String expectedAuth = "rsa-sha2-512 auth success"; checkLogs(expectedKex); checkLogs(expectedPreauthFail1); checkLogs(expectedPreauthFail2); checkLogs(expectedPreauthFail3); checkLogs(expectedPreauthFail4); checkLogs(expectedPreauth); checkLogs(expectedAuth); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/SessionReconnectIT.java000066400000000000000000000130261465436372100265400ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class SessionReconnectIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(SessionReconnectIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>(new ImageFromDockerfile() .withFileFromClasspath("dropbear_rsa_host_key", "docker/dropbear_rsa_host_key") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.dropbear")).withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test public void testReconnectWithExtraAlgorithms() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); try { doSftp(session, false); fail("exception expected"); } catch (JSchAlgoNegoFailException e) { // Dropbear does not support rsa-sha2-512/rsa-sha2-256, so add ssh-rsa String serverHostKey = session.getConfig("server_host_key") + ",ssh-rsa"; String pubkeyAcceptedAlgorithms = session.getConfig("PubkeyAcceptedAlgorithms") + ",ssh-rsa"; session.setConfig("server_host_key", serverHostKey); session.setConfig("PubkeyAcceptedAlgorithms", pubkeyAcceptedAlgorithms); doSftp(session, true); } } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/SessionTest.java000066400000000000000000000071371465436372100253100ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; import com.jcraft.jsch.JSchTest.TestLogger; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; class SessionTest { static JSch jsch = new JSch(); @ParameterizedTest @MethodSource("sshConfigs") void parseForwarding(String sshConfig, String expectedBindAddress, String expectedHost, int expectedHostPort, String expectedSocket) throws JSchException { final Session session = new Session(jsch, null, null, 0); final Session.Forwarding forwarding = session.parseForwarding(sshConfig); assertEquals(expectedBindAddress, forwarding.bind_address); assertEquals(42, forwarding.port); assertEquals(expectedHost, forwarding.host); assertEquals(expectedHostPort, forwarding.hostport); assertEquals(expectedSocket, forwarding.socketPath); } private static Stream sshConfigs() { return Stream.of(Arguments.of("bind_address:42:host:99", "bind_address", "host", 99, null), // colon Arguments.of("bind_address:42 host:99", "bind_address", "host", 99, null), // blank Arguments.of("42:host:99", "127.0.0.1", "host", 99, null), // colon wo bind Arguments.of("42 host:99", "127.0.0.1", "host", 99, null), // blank wo bind Arguments.of("localhost:42 host:99", "127.0.0.1", "host", 99, null), // blank Arguments.of(":42 host:99", "0.0.0.0", "host", 99, null), // bind is empty Arguments.of("*:42 host:99", "0.0.0.0", "host", 99, null), // bind is asterisk Arguments.of("bind_adress:42 socket", "bind_adress", null, -1, "socket"), // socket Arguments.of("42 socket", "127.0.0.1", null, -1, "socket") // socket wo bind ); } @Test void getPubkeyAcceptedKeyTypes() throws JSchException { Session session = new Session(jsch, null, null, 0); session.setConfig("PubkeyAcceptedAlgorithms", "SessionTest111"); assertEquals("SessionTest111", session.getConfig("PubkeyAcceptedKeyTypes")); assertEquals("SessionTest111", session.getConfig("PubkeyAcceptedAlgorithms")); } @Test void setPubkeyAcceptedKeyTypes() throws JSchException { Session session = new Session(jsch, null, null, 0); session.setConfig("PubkeyAcceptedKeyTypes", "SessionTest222"); assertEquals("SessionTest222", session.getConfig("PubkeyAcceptedKeyTypes")); assertEquals("SessionTest222", session.getConfig("PubkeyAcceptedAlgorithms")); } @Test void checkLoggerFunctionality() throws Exception { Logger orgLogger = JSch.getLogger(); try { JSch.setLogger(null); TestLogger staticLogger = new TestLogger(); TestLogger jschInstanceLogger = new TestLogger(); TestLogger sessionLogger = new TestLogger(); Session session = new Session(jsch, null, null, 0); assertSame(JSch.DEVNULL, session.getLogger(), "DEVNULL logger expected after creation"); JSch.setLogger(staticLogger); assertSame(staticLogger, session.getLogger(), "static logger expected after setting static logger"); jsch.setInstanceLogger(jschInstanceLogger); assertSame(jschInstanceLogger, session.getLogger(), "static logger expected after setting instance logger"); session.setLogger(sessionLogger); assertSame(sessionLogger, session.getLogger(), "static logger expected after setting session logger"); } finally { JSch.setLogger(orgLogger); } } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/SftpATTRSTest.java000066400000000000000000000020261465436372100254070ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Date; import java.util.Random; import org.junit.jupiter.api.Test; public class SftpATTRSTest { private final Random random = new Random(); @Test public void testToDateString0() { String expected = new Date(0L).toString(); String actual = SftpATTRS.toDateString(0L); assertEquals(expected, actual); } @Test public void testToDateStringNow() { long now = System.currentTimeMillis() / 1000L; String expected = new Date(now * 1000L).toString(); String actual = SftpATTRS.toDateString(now); assertEquals(expected, actual); } @Test public void testToDateStringRandom() { for (int i = 0; i < 1000000; i++) { int j = random.ints(Integer.MIN_VALUE, Integer.MAX_VALUE).findFirst().getAsInt(); long l = Integer.toUnsignedLong(j); String expected = new Date(l * 1000L).toString(); String actual = SftpATTRS.toDateString(l); assertEquals(expected, actual); } } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/Slf4jLoggerTest.java000066400000000000000000000161251465436372100260040ustar00rootroot00000000000000package com.jcraft.jsch; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.event.Level; public class Slf4jLoggerTest { private static final TestLogger logger = TestLoggerFactory.getTestLogger(JSch.class); private final Set OFF_LEVELS = EnumSet.noneOf(Level.class); private final Set TRACE_LEVELS = EnumSet.of(Level.TRACE, Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR); private final Set DEBUG_LEVELS = EnumSet.of(Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR); private final Set INFO_LEVELS = EnumSet.of(Level.INFO, Level.WARN, Level.ERROR); private final Set WARN_LEVELS = EnumSet.of(Level.WARN, Level.ERROR); private final Set ERROR_LEVELS = EnumSet.of(Level.ERROR); private final Exception testException = new Exception("dummy exception"); @BeforeEach public void beforeEach() { logger.clearAll(); } @AfterAll public static void afterAll() { logger.clearAll(); } @Test public void testIsEnabled() { Slf4jLogger sl = new Slf4jLogger(); logger.setEnabledLevelsForAllThreads(DEBUG_LEVELS); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(sl.isEnabled(-1), "trace should not be enabled"); logger.setEnabledLevelsForAllThreads(ERROR_LEVELS); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(sl.isEnabled(-1), "trace should not be enabled"); logger.setEnabledLevelsForAllThreads(INFO_LEVELS); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(sl.isEnabled(-1), "trace should not be enabled"); logger.setEnabledLevelsForAllThreads(OFF_LEVELS); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should not be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should not be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should not be enabled"); assertFalse(sl.isEnabled(-1), "trace should not be enabled"); logger.setEnabledLevelsForAllThreads(TRACE_LEVELS); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertTrue(sl.isEnabled(-1), "trace should be enabled"); logger.setEnabledLevelsForAllThreads(WARN_LEVELS); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.DEBUG), "debug should not be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.ERROR), "error should be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.FATAL), "fatal should be enabled"); assertFalse(sl.isEnabled(com.jcraft.jsch.Logger.INFO), "info should not be enabled"); assertTrue(sl.isEnabled(com.jcraft.jsch.Logger.WARN), "warn should be enabled"); assertFalse(sl.isEnabled(-1), "trace should not be enabled"); } @Test public void testLogging() { Slf4jLogger sl = new Slf4jLogger(); List expectedMessages = Arrays.asList("debug message", "debug message with null cause", "debug message with cause"); List> expectedExceptions = Arrays.asList(Optional.empty(), Optional.ofNullable(null), Optional.of(testException)); logger.setEnabledLevelsForAllThreads(TRACE_LEVELS); sl.log(-1, "debug message"); sl.log(-1, "debug message with null cause", null); sl.log(-1, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); logger.setEnabledLevelsForAllThreads(TRACE_LEVELS); sl.log(com.jcraft.jsch.Logger.FATAL, "debug message"); sl.log(com.jcraft.jsch.Logger.FATAL, "debug message with null cause", null); sl.log(com.jcraft.jsch.Logger.FATAL, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); logger.setEnabledLevelsForAllThreads(ERROR_LEVELS); sl.log(-1, "debug message"); sl.log(-1, "debug message with null cause", null); sl.log(-1, "debug message with cause", testException); checkMessages(Collections.emptyList(), Collections.emptyList()); logger.setEnabledLevelsForAllThreads(ERROR_LEVELS); sl.log(com.jcraft.jsch.Logger.FATAL, "debug message"); sl.log(com.jcraft.jsch.Logger.FATAL, "debug message with null cause", null); sl.log(com.jcraft.jsch.Logger.FATAL, "debug message with cause", testException); checkMessages(expectedMessages, expectedExceptions); } private void checkMessages(List expectedMessages, List> expectedExceptions) { List events = logger.getAllLoggingEvents(); logger.clearAll(); List actualMessages = events.stream().map(LoggingEvent::getFormattedMessage).collect(Collectors.toList()); List> actualExceptions = events.stream().map(LoggingEvent::getThrowable).collect(Collectors.toList()); assertEquals(expectedMessages, actualMessages, "mismatch in logged messages"); assertEquals(expectedExceptions, actualExceptions, "mismatch in logged exceptions"); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/StrictKexIT.java000066400000000000000000000243751465436372100252050ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class StrictKexIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(ServerSigAlgsIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config.openssh96") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile.openssh96")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test public void testEnableStrictKexNoRequireStrictKex() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_strict_kex", "yes"); session.setConfig("require_strict_kex", "no"); doSftp(session, true); String expectedServerKex = "server proposal: KEX algorithms: .*,kex-strict-s-v00@openssh.com"; String expectedClientKex = "client proposal: KEX algorithms: .*,kex-strict-c-v00@openssh.com"; String expected1 = "Doing strict KEX"; String expected2 = "Reset outgoing sequence number after sending SSH_MSG_NEWKEYS for strict KEX"; String expected3 = "Reset incoming sequence number after receiving SSH_MSG_NEWKEYS for strict KEX"; checkLogs(expectedServerKex); checkLogs(expectedClientKex); checkLogs(expected1); checkLogs(expected2); checkLogs(expected3); } @Test public void testEnableStrictKexRequireStrictKex() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_strict_kex", "yes"); session.setConfig("require_strict_kex", "yes"); doSftp(session, true); String expectedServerKex = "server proposal: KEX algorithms: .*,kex-strict-s-v00@openssh.com"; String expectedClientKex = "client proposal: KEX algorithms: .*,kex-strict-c-v00@openssh.com"; String expected1 = "Doing strict KEX"; String expected2 = "Reset outgoing sequence number after sending SSH_MSG_NEWKEYS for strict KEX"; String expected3 = "Reset incoming sequence number after receiving SSH_MSG_NEWKEYS for strict KEX"; checkLogs(expectedServerKex); checkLogs(expectedClientKex); checkLogs(expected1); checkLogs(expected2); checkLogs(expected3); } @Test public void testNoEnableStrictKexRequireStrictKex() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_strict_kex", "no"); session.setConfig("require_strict_kex", "yes"); doSftp(session, true); String expectedServerKex = "server proposal: KEX algorithms: .*,kex-strict-s-v00@openssh.com"; String expectedClientKex = "client proposal: KEX algorithms: .*,kex-strict-c-v00@openssh.com"; String expected1 = "Doing strict KEX"; String expected2 = "Reset outgoing sequence number after sending SSH_MSG_NEWKEYS for strict KEX"; String expected3 = "Reset incoming sequence number after receiving SSH_MSG_NEWKEYS for strict KEX"; checkLogs(expectedServerKex); checkLogs(expectedClientKex); checkLogs(expected1); checkLogs(expected2); checkLogs(expected3); } @Test public void testNoEnableStrictKexNoRequireStrictKex() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_strict_kex", "no"); session.setConfig("require_strict_kex", "no"); doSftp(session, true); String expectedServerKex = "server proposal: KEX algorithms: .*,kex-strict-s-v00@openssh.com"; String expectedClientKex = "client proposal: KEX algorithms: .*,kex-strict-c-v00@openssh.com"; String expected1 = "Doing strict KEX"; String expected2 = "Reset outgoing sequence number after sending SSH_MSG_NEWKEYS for strict KEX"; String expected3 = "Reset incoming sequence number after receiving SSH_MSG_NEWKEYS for strict KEX"; checkLogs(expectedServerKex); checkNoLogs(expectedClientKex); checkNoLogs(expected1); checkNoLogs(expected2); checkNoLogs(expected3); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private void checkLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertTrue(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private void checkNoLogs(String expected) { Optional actualJsch = jschLogger.getAllLoggingEvents().stream() .map(LoggingEvent::getFormattedMessage).filter(msg -> msg.matches(expected)).findFirst(); try { assertFalse(actualJsch.isPresent(), () -> "JSch: " + expected); } catch (AssertionError e) { printInfo(); throw e; } } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/UserAuthIT.java000066400000000000000000000162051465436372100250160ustar00rootroot00000000000000package com.jcraft.jsch; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import com.github.valfirst.slf4jtest.LoggingEvent; import com.github.valfirst.slf4jtest.TestLogger; import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Locale; import java.util.Random; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @Testcontainers public class UserAuthIT { private static final int timeout = 2000; private static final DigestUtils sha256sum = new DigestUtils(DigestUtils.getSha256Digest()); private static final TestLogger jschLogger = TestLoggerFactory.getTestLogger(JSch.class); private static final TestLogger sshdLogger = TestLoggerFactory.getTestLogger(ServerSigAlgsIT.class); @TempDir public Path tmpDir; private Path in; private Path out; private String hash; private Slf4jLogConsumer sshdLogConsumer; @Container public GenericContainer sshd = new GenericContainer<>( new ImageFromDockerfile().withFileFromClasspath("ssh_host_rsa_key", "docker/ssh_host_rsa_key") .withFileFromClasspath("ssh_host_rsa_key.pub", "docker/ssh_host_rsa_key.pub") .withFileFromClasspath("ssh_host_ecdsa256_key", "docker/ssh_host_ecdsa256_key") .withFileFromClasspath("ssh_host_ecdsa256_key.pub", "docker/ssh_host_ecdsa256_key.pub") .withFileFromClasspath("ssh_host_ecdsa384_key", "docker/ssh_host_ecdsa384_key") .withFileFromClasspath("ssh_host_ecdsa384_key.pub", "docker/ssh_host_ecdsa384_key.pub") .withFileFromClasspath("ssh_host_ecdsa521_key", "docker/ssh_host_ecdsa521_key") .withFileFromClasspath("ssh_host_ecdsa521_key.pub", "docker/ssh_host_ecdsa521_key.pub") .withFileFromClasspath("ssh_host_ed25519_key", "docker/ssh_host_ed25519_key") .withFileFromClasspath("ssh_host_ed25519_key.pub", "docker/ssh_host_ed25519_key.pub") .withFileFromClasspath("ssh_host_dsa_key", "docker/ssh_host_dsa_key") .withFileFromClasspath("ssh_host_dsa_key.pub", "docker/ssh_host_dsa_key.pub") .withFileFromClasspath("sshd_config", "docker/sshd_config") .withFileFromClasspath("authorized_keys", "docker/authorized_keys") .withFileFromClasspath("Dockerfile", "docker/Dockerfile")) .withExposedPorts(22); @BeforeAll public static void beforeAll() { JSch.setLogger(new Slf4jLogger()); } @BeforeEach public void beforeEach() throws IOException { if (sshdLogConsumer == null) { sshdLogConsumer = new Slf4jLogConsumer(sshdLogger); sshd.followOutput(sshdLogConsumer); } in = tmpDir.resolve("in"); out = tmpDir.resolve("out"); Files.createFile(in); try (OutputStream os = Files.newOutputStream(in)) { byte[] data = new byte[1024]; for (int i = 0; i < 1024 * 100; i += 1024) { new Random().nextBytes(data); os.write(data); } } hash = sha256sum.digestAsHex(in); jschLogger.clearAll(); sshdLogger.clearAll(); } @AfterAll public static void afterAll() { JSch.setLogger(null); jschLogger.clearAll(); sshdLogger.clearAll(); } @Test public void testAuthNoneEnabledPubkeyAuthQueryEnabled() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_auth_none", "yes"); session.setConfig("enable_pubkey_auth_query", "yes"); doSftp(session, true); } @Test public void testAuthNoneEnabledPubkeyAuthQueryDisabled() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_auth_none", "yes"); session.setConfig("enable_pubkey_auth_query", "no"); doSftp(session, true); } @Test public void testAuthNoneDisabledPubkeyAuthQueryEnabled() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_auth_none", "no"); session.setConfig("enable_pubkey_auth_query", "yes"); doSftp(session, true); } @Test public void testAuthNoneDisabledPubkeyAuthQueryDisabled() throws Exception { JSch ssh = createRSAIdentity(); Session session = createSession(ssh); session.setConfig("enable_auth_none", "no"); session.setConfig("enable_pubkey_auth_query", "no"); doSftp(session, true); } private JSch createRSAIdentity() throws Exception { HostKey hostKey = readHostKey(getResourceFile("docker/ssh_host_rsa_key.pub")); JSch ssh = new JSch(); ssh.addIdentity(getResourceFile("docker/id_rsa"), getResourceFile("docker/id_rsa.pub"), null); ssh.getHostKeyRepository().add(hostKey, null); return ssh; } private HostKey readHostKey(String fileName) throws Exception { List lines = Files.readAllLines(Paths.get(fileName), UTF_8); String[] split = lines.get(0).split("\\s+"); String hostname = String.format(Locale.ROOT, "[%s]:%d", sshd.getHost(), sshd.getFirstMappedPort()); return new HostKey(hostname, Base64.getDecoder().decode(split[1])); } private Session createSession(JSch ssh) throws Exception { Session session = ssh.getSession("root", sshd.getHost(), sshd.getFirstMappedPort()); session.setConfig("StrictHostKeyChecking", "yes"); session.setConfig("PreferredAuthentications", "publickey"); return session; } private void doSftp(Session session, boolean debugException) throws Exception { assertDoesNotThrow(() -> { try { session.setTimeout(timeout); session.connect(); ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp"); sftp.connect(timeout); sftp.put(in.toString(), "/root/test"); sftp.get("/root/test", out.toString()); sftp.disconnect(); session.disconnect(); } catch (Exception e) { if (debugException) { printInfo(); } throw e; } }); assertEquals(1024L * 100L, Files.size(out)); assertEquals(hash, sha256sum.digestAsHex(out)); } private void printInfo() { jschLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); sshdLogger.getAllLoggingEvents().stream().map(LoggingEvent::getFormattedMessage) .forEach(System.out::println); System.out.println(""); System.out.println(""); System.out.println(""); } private String getResourceFile(String fileName) { return ResourceUtil.getResourceFile(getClass(), fileName); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jbcrypt/000077500000000000000000000000001465436372100236275ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jbcrypt/BCryptTest.java000066400000000000000000000322501465436372100265370ustar00rootroot00000000000000// Copyright (c) 2006 Damien Miller // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package com.jcraft.jsch.jbcrypt; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import org.junit.jupiter.api.Test; /** * JUnit unit tests for BCrypt routines * * @author Damien Miller * @version 0.2 */ public class BCryptTest { String test_vectors[][] = { {"", "$2a$06$DCq7YPn5Rq63x1Lad4cll.", "$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s."}, {"", "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.", "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye"}, {"", "$2a$10$k1wbIrmNyFAPwPVPSVa/ze", "$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW"}, {"", "$2a$12$k42ZFHFWqBp3vWli.nIn8u", "$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO"}, {"a", "$2a$06$m0CrhHm10qJ3lXRY.5zDGO", "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe"}, {"a", "$2a$08$cfcvVd2aQ8CMvoMpP2EBfe", "$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V."}, {"a", "$2a$10$k87L/MF28Q673VKh8/cPi.", "$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u"}, {"a", "$2a$12$8NJH3LsPrANStV6XtBakCe", "$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS"}, {"abc", "$2a$06$If6bvum7DFjUnE9p2uDeDu", "$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i"}, {"abc", "$2a$08$Ro0CUfOqk6cXEKf3dyaM7O", "$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm"}, {"abc", "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.", "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi"}, {"abc", "$2a$12$EXRkfkdmXn2gzds2SSitu.", "$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q"}, {"abcdefghijklmnopqrstuvwxyz", "$2a$06$.rCVZVOThsIa97pEDOxvGu", "$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC"}, {"abcdefghijklmnopqrstuvwxyz", "$2a$08$aTsUwsyowQuzRrDqFflhge", "$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz."}, {"abcdefghijklmnopqrstuvwxyz", "$2a$10$fVH8e28OQRj9tqiDXs1e1u", "$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq"}, {"abcdefghijklmnopqrstuvwxyz", "$2a$12$D4G5f18o7aMMfwasBL7Gpu", "$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG"}, {"~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$06$fPIsBO8qRqkjj273rfaOI.", "$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO"}, {"~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$08$Eq2r4G/76Wv39MzSX262hu", "$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW"}, {"~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$10$LgfYWkbzEvQ4JakH7rOvHe", "$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS"}, {"~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$12$WApznUOJfkEGSmYRfnkrPO", "$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC"},}; /** Test method for 'BCrypt.hashpw(String, String)' */ @Test public void testHashpw() { // System.out.print("BCrypt.hashpw(): "); for (int i = 0; i < test_vectors.length; i++) { String plain = test_vectors[i][0]; String salt = test_vectors[i][1]; String expected = test_vectors[i][2]; String hashed = BCrypt.hashpw(plain, salt); assertEquals(hashed, expected); // System.out.print("."); } // System.out.println(""); } /** Test method for 'BCrypt.gensalt(int)' */ @Test public void testGensaltInt() { // System.out.print("BCrypt.gensalt(log_rounds):"); for (int i = 4; i <= 12; i++) { // System.out.print(" " + Integer.toString(i) + ":"); for (int j = 0; j < test_vectors.length; j += 4) { String plain = test_vectors[j][0]; String salt = BCrypt.gensalt(i); String hashed1 = BCrypt.hashpw(plain, salt); String hashed2 = BCrypt.hashpw(plain, hashed1); assertEquals(hashed1, hashed2); // System.out.print("."); } } // System.out.println(""); } /** Test method for 'BCrypt.gensalt()' */ @Test public void testGensalt() { // System.out.print("BCrypt.gensalt(): "); for (int i = 0; i < test_vectors.length; i += 4) { String plain = test_vectors[i][0]; String salt = BCrypt.gensalt(); String hashed1 = BCrypt.hashpw(plain, salt); String hashed2 = BCrypt.hashpw(plain, hashed1); assertEquals(hashed1, hashed2); // System.out.print("."); } // System.out.println(""); } /** Test method for 'BCrypt.checkpw(String, String)' expecting success */ @Test public void testCheckpw_success() { // System.out.print("BCrypt.checkpw w/ good passwords: "); for (int i = 0; i < test_vectors.length; i++) { String plain = test_vectors[i][0]; String expected = test_vectors[i][2]; assertTrue(BCrypt.checkpw(plain, expected)); // System.out.print("."); } // System.out.println(""); } /** Test method for 'BCrypt.checkpw(String, String)' expecting failure */ @Test public void testCheckpw_failure() { // System.out.print("BCrypt.checkpw w/ bad passwords: "); for (int i = 0; i < test_vectors.length; i++) { int broken_index = (i + 4) % test_vectors.length; String plain = test_vectors[i][0]; String expected = test_vectors[broken_index][2]; assertFalse(BCrypt.checkpw(plain, expected)); // System.out.print("."); } // System.out.println(""); } /** Test for correct hashing of non-US-ASCII passwords */ @Test public void testInternationalChars() { // System.out.print("BCrypt.hashpw w/ international chars: "); String pw1 = "\u2605\u2605\u2605\u2605\u2605\u2605\u2605\u2605"; String pw2 = "????????"; String h1 = BCrypt.hashpw(pw1, BCrypt.gensalt()); assertFalse(BCrypt.checkpw(pw2, h1)); // System.out.print("."); String h2 = BCrypt.hashpw(pw2, BCrypt.gensalt()); assertFalse(BCrypt.checkpw(pw1, h2)); // System.out.print("."); // System.out.println(""); } private static class BCryptHashTV { private final byte[] pass; private final byte[] salt; private final byte[] out; public BCryptHashTV(byte[] pass, byte[] salt, byte[] out) { this.pass = pass; this.salt = salt; this.out = out; } } BCryptHashTV[] bcrypt_hash_test_vectors = new BCryptHashTV[] {new BCryptHashTV( new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, new byte[] {(byte) 0x46, (byte) 0x02, (byte) 0x86, (byte) 0xe9, (byte) 0x72, (byte) 0xfa, (byte) 0x83, (byte) 0x3f, (byte) 0x8b, (byte) 0x12, (byte) 0x83, (byte) 0xad, (byte) 0x8f, (byte) 0xa9, (byte) 0x19, (byte) 0xfa, (byte) 0x29, (byte) 0xbd, (byte) 0xe2, (byte) 0x0e, (byte) 0x23, (byte) 0x32, (byte) 0x9e, (byte) 0x77, (byte) 0x4d, (byte) 0x84, (byte) 0x22, (byte) 0xba, (byte) 0xc0, (byte) 0xa7, (byte) 0x92, (byte) 0x6c,}), new BCryptHashTV( new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,}, new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,}, new byte[] {(byte) 0xc6, (byte) 0xa9, (byte) 0x5f, (byte) 0xe6, (byte) 0x41, (byte) 0x31, (byte) 0x15, (byte) 0xfb, (byte) 0x57, (byte) 0xe9, (byte) 0x9f, (byte) 0x75, (byte) 0x74, (byte) 0x98, (byte) 0xe8, (byte) 0x5d, (byte) 0xa3, (byte) 0xc6, (byte) 0xe1, (byte) 0xdf, (byte) 0x0c, (byte) 0x3c, (byte) 0x93, (byte) 0xaa, (byte) 0x97, (byte) 0x5c, (byte) 0x54, (byte) 0x8a, (byte) 0x34, (byte) 0x43, (byte) 0x26, (byte) 0xf8,}),}; @Test public void testBCryptHashTestVectors() throws Exception { // System.out.print("BCrypt.hash w/ known vectors: "); for (BCryptHashTV tv : bcrypt_hash_test_vectors) { byte[] output = new byte[tv.out.length]; new BCrypt().hash(tv.pass, tv.salt, output); assertEquals(Arrays.toString(tv.out), Arrays.toString(output)); // System.out.print("."); } // System.out.println(""); } private static class BCryptPbkdfTV { private final byte[] pass; private final byte[] salt; private final int rounds; private final byte[] out; public BCryptPbkdfTV(byte[] pass, byte[] salt, int rounds, byte[] out) { this.pass = pass; this.salt = salt; this.rounds = rounds; this.out = out; } } BCryptPbkdfTV[] bcrypt_pbkdf_test_vectors = new BCryptPbkdfTV[] { new BCryptPbkdfTV("password".getBytes(UTF_8), "salt".getBytes(UTF_8), 4, new byte[] {(byte) 0x5b, (byte) 0xbf, (byte) 0x0c, (byte) 0xc2, (byte) 0x93, (byte) 0x58, (byte) 0x7f, (byte) 0x1c, (byte) 0x36, (byte) 0x35, (byte) 0x55, (byte) 0x5c, (byte) 0x27, (byte) 0x79, (byte) 0x65, (byte) 0x98, (byte) 0xd4, (byte) 0x7e, (byte) 0x57, (byte) 0x90, (byte) 0x71, (byte) 0xbf, (byte) 0x42, (byte) 0x7e, (byte) 0x9d, (byte) 0x8f, (byte) 0xbe, (byte) 0x84, (byte) 0x2a, (byte) 0xba, (byte) 0x34, (byte) 0xd9,}), new BCryptPbkdfTV("password".getBytes(UTF_8), "salt".getBytes(UTF_8), 8, new byte[] {(byte) 0xe1, (byte) 0x36, (byte) 0x7e, (byte) 0xc5, (byte) 0x15, (byte) 0x1a, (byte) 0x33, (byte) 0xfa, (byte) 0xac, (byte) 0x4c, (byte) 0xc1, (byte) 0xc1, (byte) 0x44, (byte) 0xcd, (byte) 0x23, (byte) 0xfa, (byte) 0x15, (byte) 0xd5, (byte) 0x54, (byte) 0x84, (byte) 0x93, (byte) 0xec, (byte) 0xc9, (byte) 0x9b, (byte) 0x9b, (byte) 0x5d, (byte) 0x9c, (byte) 0x0d, (byte) 0x3b, (byte) 0x27, (byte) 0xbe, (byte) 0xc7, (byte) 0x62, (byte) 0x27, (byte) 0xea, (byte) 0x66, (byte) 0x08, (byte) 0x8b, (byte) 0x84, (byte) 0x9b, (byte) 0x20, (byte) 0xab, (byte) 0x7a, (byte) 0xa4, (byte) 0x78, (byte) 0x01, (byte) 0x02, (byte) 0x46, (byte) 0xe7, (byte) 0x4b, (byte) 0xba, (byte) 0x51, (byte) 0x72, (byte) 0x3f, (byte) 0xef, (byte) 0xa9, (byte) 0xf9, (byte) 0x47, (byte) 0x4d, (byte) 0x65, (byte) 0x08, (byte) 0x84, (byte) 0x5e, (byte) 0x8d}), new BCryptPbkdfTV("password".getBytes(UTF_8), "salt".getBytes(UTF_8), 42, new byte[] {(byte) 0x83, (byte) 0x3c, (byte) 0xf0, (byte) 0xdc, (byte) 0xf5, (byte) 0x6d, (byte) 0xb6, (byte) 0x56, (byte) 0x08, (byte) 0xe8, (byte) 0xf0, (byte) 0xdc, (byte) 0x0c, (byte) 0xe8, (byte) 0x82, (byte) 0xbd}),}; @Test public void testBCryptPbkdfTestVectors() throws Exception { // System.out.print("BCrypt.pbkdf w/ known vectors: "); for (BCryptPbkdfTV tv : bcrypt_pbkdf_test_vectors) { byte[] output = new byte[tv.out.length]; new BCrypt().pbkdf(tv.pass, tv.salt, tv.rounds, output); assertEquals(Arrays.toString(tv.out), Arrays.toString(output)); // System.out.print("."); } // System.out.println(""); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/000077500000000000000000000000001465436372100232645ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/Adler32Test.java000066400000000000000000000034131465436372100261640ustar00rootroot00000000000000package com.jcraft.jsch.jzlib; import static com.jcraft.jsch.jzlib.Package.randombuf; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class Adler32Test { private Adler32 adler; @BeforeEach public void before() { adler = new Adler32(); } @AfterEach public void after() {} @Test public void testAdler32IsCompatibleWithJavaUtilZipAdler32() { byte[] buf1 = randombuf(1024); java.util.zip.Adler32 juza = new java.util.zip.Adler32(); juza.update(buf1, 0, buf1.length); long expected = juza.getValue(); long actual = getValue(Arrays.asList(buf1)); assertEquals(expected, actual); } @Test public void testAdler32CanCopyItself() { byte[] buf1 = randombuf(1024); byte[] buf2 = randombuf(1024); Adler32 adler1 = new Adler32(); adler1.update(buf1, 0, buf1.length); Adler32 adler2 = adler1.copy(); adler1.update(buf2, 0, buf1.length); adler2.update(buf2, 0, buf1.length); long expected = adler1.getValue(); long actual = adler2.getValue(); assertEquals(expected, actual); } @Test public void testAdler32CanCombineValues() { byte[] buf1 = randombuf(1024); byte[] buf2 = randombuf(1024); long adler1 = getValue(Arrays.asList(buf1)); long adler2 = getValue(Arrays.asList(buf2)); long expected = getValue(Arrays.asList(buf1, buf2)); long actual = Adler32.combine(adler1, adler2, buf2.length); assertEquals(expected, actual); } private synchronized long getValue(List buf) { adler.reset(); buf.forEach(b -> adler.update(b, 0, b.length)); return adler.getValue(); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/CRC32Test.java000066400000000000000000000033161465436372100255460ustar00rootroot00000000000000package com.jcraft.jsch.jzlib; import static com.jcraft.jsch.jzlib.Package.randombuf; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class CRC32Test { private CRC32 crc; @BeforeEach public void before() { crc = new CRC32(); } @AfterEach public void after() {} @Test public void testCRC32IsCompatibleWithJavaUtilZipCRC32() { byte[] buf1 = randombuf(1024); java.util.zip.CRC32 juza = new java.util.zip.CRC32(); juza.update(buf1, 0, buf1.length); long expected = juza.getValue(); long actual = getValue(Arrays.asList(buf1)); assertEquals(expected, actual); } @Test public void testCRC2CanCopyItself() { byte[] buf1 = randombuf(1024); byte[] buf2 = randombuf(1024); CRC32 crc1 = new CRC32(); crc1.update(buf1, 0, buf1.length); CRC32 crc2 = crc1.copy(); crc1.update(buf2, 0, buf1.length); crc2.update(buf2, 0, buf1.length); long expected = crc1.getValue(); long actual = crc2.getValue(); assertEquals(expected, actual); } @Test public void testCRC32CanCombineValues() { byte[] buf1 = randombuf(1024); byte[] buf2 = randombuf(1024); long crc1 = getValue(Arrays.asList(buf1)); long crc2 = getValue(Arrays.asList(buf2)); long expected = getValue(Arrays.asList(buf1, buf2)); long actual = CRC32.combine(crc1, crc2, buf2.length); assertEquals(expected, actual); } private synchronized long getValue(List buf) { crc.reset(); buf.forEach(b -> crc.update(b, 0, b.length)); return crc.getValue(); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/DeflateInflateTest.java000066400000000000000000000224071465436372100276430ustar00rootroot00000000000000package com.jcraft.jsch.jzlib; import static com.jcraft.jsch.jzlib.JZlib.Z_BEST_COMPRESSION; import static com.jcraft.jsch.jzlib.JZlib.Z_BEST_SPEED; import static com.jcraft.jsch.jzlib.JZlib.Z_DATA_ERROR; import static com.jcraft.jsch.jzlib.JZlib.Z_DEFAULT_COMPRESSION; import static com.jcraft.jsch.jzlib.JZlib.Z_DEFAULT_STRATEGY; import static com.jcraft.jsch.jzlib.JZlib.Z_FILTERED; import static com.jcraft.jsch.jzlib.JZlib.Z_FINISH; import static com.jcraft.jsch.jzlib.JZlib.Z_FULL_FLUSH; import static com.jcraft.jsch.jzlib.JZlib.Z_NEED_DICT; import static com.jcraft.jsch.jzlib.JZlib.Z_NO_COMPRESSION; import static com.jcraft.jsch.jzlib.JZlib.Z_NO_FLUSH; import static com.jcraft.jsch.jzlib.JZlib.Z_OK; import static com.jcraft.jsch.jzlib.JZlib.Z_STREAM_END; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class DeflateInflateTest { private final int comprLen = 40000; private final int uncomprLen = comprLen; private byte[] compr; private byte[] uncompr; private Deflater deflater; private Inflater inflater; private int err; @BeforeEach public void before() { compr = new byte[comprLen]; uncompr = new byte[uncomprLen]; deflater = new Deflater(); inflater = new Inflater(); err = Z_OK; } @AfterEach public void after() {} @Test public void testDeflaterAndInflaterCanDeflateAndInflateDataInLargeBuffer() { err = deflater.init(Z_BEST_SPEED); assertEquals(Z_OK, err); deflater.setInput(uncompr); deflater.setOutput(compr); err = deflater.deflate(Z_NO_FLUSH); assertEquals(Z_OK, err); assertEquals(0, deflater.avail_in); deflater.params(Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); deflater.setInput(compr); deflater.avail_in = comprLen / 2; err = deflater.deflate(Z_NO_FLUSH); assertEquals(Z_OK, err); deflater.params(Z_BEST_COMPRESSION, Z_FILTERED); deflater.setInput(uncompr); deflater.avail_in = uncomprLen; err = deflater.deflate(Z_NO_FLUSH); assertEquals(Z_OK, err); err = deflater.deflate(JZlib.Z_FINISH); assertEquals(Z_STREAM_END, err); err = deflater.end(); assertEquals(Z_OK, err); inflater.setInput(compr); err = inflater.init(); assertEquals(Z_OK, err); boolean loop = true; while (loop) { inflater.setOutput(uncompr); err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; assertEquals(2 * uncomprLen + comprLen / 2, total_out); } @Test public void testDeflaterAndInflaterCanDeflateAndInflateDataInSmallBuffer() { byte[] data = "hello, hello!".getBytes(UTF_8); err = deflater.init(Z_DEFAULT_COMPRESSION); assertEquals(Z_OK, err); deflater.setInput(data); deflater.setOutput(compr); while (deflater.total_in < data.length && deflater.total_out < comprLen) { deflater.avail_in = 1; deflater.avail_out = 1; err = deflater.deflate(Z_NO_FLUSH); assertEquals(Z_OK, err); } do { deflater.avail_out = 1; err = deflater.deflate(Z_FINISH); } while (err != Z_STREAM_END); err = deflater.end(); assertEquals(Z_OK, err); inflater.setInput(compr); inflater.setOutput(uncompr); err = inflater.init(); assertEquals(Z_OK, err); boolean loop = true; while (inflater.total_out < uncomprLen && inflater.total_in < comprLen && loop) { inflater.avail_in = 1; // force small buffers inflater.avail_out = 1; // force small buffers err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; byte[] actual = new byte[total_out]; System.arraycopy(uncompr, 0, actual, 0, total_out); assertArrayEquals(data, actual); } @Test public void testDeflaterAndInflaterSupportDictionary() { byte[] hello = "hello".getBytes(UTF_8); byte[] dictionary = "hello, hello!".getBytes(UTF_8); err = deflater.init(Z_DEFAULT_COMPRESSION); assertEquals(Z_OK, err); deflater.setDictionary(dictionary, dictionary.length); assertEquals(Z_OK, err); long dictID = deflater.getAdler(); deflater.setInput(hello); deflater.setOutput(compr); err = deflater.deflate(Z_FINISH); assertEquals(Z_STREAM_END, err); err = deflater.end(); assertEquals(Z_OK, err); err = inflater.init(); assertEquals(Z_OK, err); inflater.setInput(compr); inflater.setOutput(uncompr); boolean loop = true; do { err = inflater.inflate(JZlib.Z_NO_FLUSH); switch (err) { case Z_STREAM_END: loop = false; break; case Z_NEED_DICT: assertEquals(inflater.getAdler(), dictID); err = inflater.setDictionary(dictionary, dictionary.length); assertEquals(Z_OK, err); break; default: assertEquals(Z_OK, err); break; } } while (loop); err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; byte[] actual = new byte[total_out]; System.arraycopy(uncompr, 0, actual, 0, total_out); assertArrayEquals(hello, actual); } @Test public void testDeflaterAndInflaterSupportSync() { byte[] hello = "hello".getBytes(UTF_8); err = deflater.init(Z_DEFAULT_COMPRESSION); assertEquals(Z_OK, err); deflater.setInput(hello); deflater.avail_in = 3; deflater.setOutput(compr); err = deflater.deflate(Z_FULL_FLUSH); assertEquals(Z_OK, err); compr[3] = (byte) (compr[3] + 1); deflater.avail_in = hello.length - 3; err = deflater.deflate(Z_FINISH); assertEquals(Z_STREAM_END, err); int comprLen = (int) deflater.total_out; err = deflater.end(); assertEquals(Z_OK, err); err = inflater.init(); assertEquals(Z_OK, err); inflater.setInput(compr); inflater.avail_in = 2; inflater.setOutput(uncompr); err = inflater.inflate(JZlib.Z_NO_FLUSH); assertEquals(Z_OK, err); inflater.avail_in = comprLen - 2; err = inflater.sync(); err = inflater.inflate(Z_FINISH); assertEquals(Z_DATA_ERROR, err); err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; byte[] actual = new byte[total_out]; System.arraycopy(uncompr, 0, actual, 0, total_out); assertEquals(new String(hello, UTF_8), "hel" + new String(actual, UTF_8)); } @Test public void testInflaterCanInflateGzipData() { byte[] hello = "foo".getBytes(UTF_8); byte[] data = {(byte) 0x1f, (byte) 0x8b, (byte) 0x08, (byte) 0x18, (byte) 0x08, (byte) 0xeb, (byte) 0x7a, (byte) 0x0b, (byte) 0x00, (byte) 0x0b, (byte) 0x58, (byte) 0x00, (byte) 0x59, (byte) 0x00, (byte) 0x4b, (byte) 0xcb, (byte) 0xcf, (byte) 0x07, (byte) 0x00, (byte) 0x21, (byte) 0x65, (byte) 0x73, (byte) 0x8c, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00}; err = inflater.init(15 + 32); assertEquals(Z_OK, err); inflater.setInput(data); inflater.setOutput(uncompr); int comprLen = data.length; boolean loop = true; while (inflater.total_out < uncomprLen && inflater.total_in < comprLen && loop) { err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; byte[] actual = new byte[total_out]; System.arraycopy(uncompr, 0, actual, 0, total_out); assertArrayEquals(hello, actual); } @Test public void testInflaterAndDeflaterCanSupportGzipData() { byte[] data = "hello, hello!".getBytes(UTF_8); err = deflater.init(Z_DEFAULT_COMPRESSION, 15 + 16); assertEquals(Z_OK, err); deflater.setInput(data); deflater.setOutput(compr); while (deflater.total_in < data.length && deflater.total_out < comprLen) { deflater.avail_in = 1; deflater.avail_out = 1; err = deflater.deflate(Z_NO_FLUSH); assertEquals(Z_OK, err); } do { deflater.avail_out = 1; err = deflater.deflate(Z_FINISH); } while (err != Z_STREAM_END); err = deflater.end(); assertEquals(Z_OK, err); inflater.setInput(compr); inflater.setOutput(uncompr); err = inflater.init(15 + 32); assertEquals(Z_OK, err); boolean loop = true; while (inflater.total_out < uncomprLen && inflater.total_in < comprLen && loop) { inflater.avail_in = 1; // force small buffers inflater.avail_out = 1; // force small buffers err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; byte[] actual = new byte[total_out]; System.arraycopy(uncompr, 0, actual, 0, total_out); assertArrayEquals(data, actual); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/DeflaterInflaterStreamTest.java000066400000000000000000000100171465436372100313550ustar00rootroot00000000000000package com.jcraft.jsch.jzlib; import static com.jcraft.jsch.jzlib.Package.randombuf; import static com.jcraft.jsch.jzlib.Package.readArray; import static com.jcraft.jsch.jzlib.Package.readIS; import static com.jcraft.jsch.jzlib.Package.uncheckedConsumer; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class DeflaterInflaterStreamTest { @BeforeEach public void before() {} @AfterEach public void after() {} @Test public void testDeflaterAndInflaterCanDeflateAndInflateDataOneByOne() throws IOException { byte[] data1 = randombuf(1024); byte[] buf = new byte[1]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream gos = new DeflaterOutputStream(baos); readArray(data1, gos, buf); gos.close(); ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); readIS(new InflaterInputStream(new ByteArrayInputStream(baos.toByteArray())), baos2, buf); byte[] data2 = baos2.toByteArray(); assertEquals(data1.length, data2.length); assertArrayEquals(data1, data2); } @Test public void testDeflaterOutputStreamAndInflaterInputStreamCanDeflateAndInflate() throws IOException { for (int i = 1; i < 100; i += 3) { byte[] buf = new byte[i]; byte[] data1 = randombuf(10240); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream gos = new DeflaterOutputStream(baos); readArray(data1, gos, buf); gos.close(); ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); readIS(new InflaterInputStream(new ByteArrayInputStream(baos.toByteArray())), baos2, buf); byte[] data2 = baos2.toByteArray(); assertEquals(data1.length, data2.length); assertArrayEquals(data1, data2); } } @Test public void testDeflaterAndInflaterCanDeflateAndInflateNowrapData() throws IOException { for (int i = 1; i < 100; i += 3) { byte[] buf = new byte[i]; byte[] data1 = randombuf(10240); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Deflater deflater = new Deflater(JZlib.Z_DEFAULT_COMPRESSION, JZlib.DEF_WBITS, true); DeflaterOutputStream gos = new DeflaterOutputStream(baos, deflater); readArray(data1, gos, buf); gos.close(); ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); Inflater inflater = new Inflater(JZlib.DEF_WBITS, true); readIS(new InflaterInputStream(new ByteArrayInputStream(baos.toByteArray()), inflater), baos2, buf); byte[] data2 = baos2.toByteArray(); assertEquals(data1.length, data2.length); assertArrayEquals(data1, data2); } } @Test public void testDeflaterAndInflaterCanDeflateAndInflateNowrapDataWithMaxWbits() { byte[] buf = new byte[100]; Arrays.asList(randombuf(10240), "{\"color\":2,\"id\":\"EvLd4UG.CXjnk35o1e8LrYYQfHu0h.d*SqVJPoqmzXM::Ly::Snaps::Store::Commit\"}" .getBytes(UTF_8)) .forEach(uncheckedConsumer(data1 -> { Deflater deflater = new Deflater(JZlib.Z_DEFAULT_COMPRESSION, JZlib.MAX_WBITS, true); Inflater inflater = new Inflater(JZlib.MAX_WBITS, true); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream gos = new DeflaterOutputStream(baos, deflater); readArray(data1, gos, buf); gos.close(); ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); readIS(new InflaterInputStream(new ByteArrayInputStream(baos.toByteArray()), inflater), baos2, buf); byte[] data2 = baos2.toByteArray(); assertEquals(data1.length, data2.length); assertArrayEquals(data1, data2); })); } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/Package.java000066400000000000000000000027311465436372100254650ustar00rootroot00000000000000package com.jcraft.jsch.jzlib; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UncheckedIOException; import java.util.Random; import java.util.function.Consumer; import java.util.function.Function; public class Package { public static void readIS(InputStream is, OutputStream out, byte[] buf) throws IOException { int i; while ((i = is.read(buf)) != -1) { out.write(buf, 0, i); } is.close(); } public static void readArray(byte[] is, OutputStream out, byte[] buf) throws IOException { readIS(new ByteArrayInputStream(is), out, buf); } public static byte[] randombuf(int n) { Random random = new Random(); byte[] ret = new byte[n]; random.nextBytes(ret); return ret; } public static Consumer uncheckedConsumer(IOConsumer consumer) { return t -> { try { consumer.accept(t); } catch (IOException e) { throw new UncheckedIOException(e); } }; } public static Function uncheckedFunction(IOFunction function) { return t -> { try { return function.apply(t); } catch (IOException e) { throw new UncheckedIOException(e); } }; } @FunctionalInterface public interface IOConsumer { void accept(T t) throws IOException; } @FunctionalInterface public interface IOFunction { R apply(T t) throws IOException; } } mwiede-jsch-c8efa3f/src/test/java/com/jcraft/jsch/jzlib/WrapperTypeTest.java000066400000000000000000000173531465436372100272620ustar00rootroot00000000000000package com.jcraft.jsch.jzlib; import static com.jcraft.jsch.jzlib.JZlib.DEF_WBITS; import static com.jcraft.jsch.jzlib.JZlib.W_ANY; import static com.jcraft.jsch.jzlib.JZlib.W_GZIP; import static com.jcraft.jsch.jzlib.JZlib.W_NONE; import static com.jcraft.jsch.jzlib.JZlib.W_ZLIB; import static com.jcraft.jsch.jzlib.JZlib.Z_BEST_SPEED; import static com.jcraft.jsch.jzlib.JZlib.Z_DATA_ERROR; import static com.jcraft.jsch.jzlib.JZlib.Z_DEFAULT_COMPRESSION; import static com.jcraft.jsch.jzlib.JZlib.Z_NO_FLUSH; import static com.jcraft.jsch.jzlib.JZlib.Z_OK; import static com.jcraft.jsch.jzlib.JZlib.Z_STREAM_END; import static com.jcraft.jsch.jzlib.Package.readArray; import static com.jcraft.jsch.jzlib.Package.readIS; import static com.jcraft.jsch.jzlib.Package.uncheckedConsumer; import static com.jcraft.jsch.jzlib.Package.uncheckedFunction; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import com.jcraft.jsch.jzlib.JZlib.WrapperType; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Objects; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class WrapperTypeTest { private final byte[] data = "hello, hello!".getBytes(UTF_8); private final int comprLen = 40000; private final int uncomprLen = comprLen; private byte[] compr; private byte[] uncompr; private int err; private final List cases = Arrays.asList( /* success fail */ new Case(W_ZLIB, Arrays.asList(W_ZLIB, W_ANY), Arrays.asList(W_GZIP, W_NONE)), new Case(W_GZIP, Arrays.asList(W_GZIP, W_ANY), Arrays.asList(W_ZLIB, W_NONE)), new Case(W_NONE, Arrays.asList(W_NONE, W_ANY), Arrays.asList(W_ZLIB, W_GZIP))); @BeforeEach public void before() { compr = new byte[comprLen]; uncompr = new byte[uncomprLen]; err = Z_OK; } @AfterEach public void after() {} @Test public void testDeflaterCanDetectDataTypeOfInput() { byte[] buf = compr; cases.forEach(uncheckedConsumer(c -> { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Deflater deflater = new Deflater(Z_DEFAULT_COMPRESSION, DEF_WBITS, 9, c.iflag); DeflaterOutputStream gos = new DeflaterOutputStream(baos, deflater); readArray(data, gos, buf); gos.close(); byte[] deflated = baos.toByteArray(); c.good.stream().map(uncheckedFunction(w -> { ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); Inflater inflater = new Inflater(w); readIS(new InflaterInputStream(new ByteArrayInputStream(deflated), inflater), baos2, buf); byte[] data1 = baos2.toByteArray(); assertEquals(data.length, data1.length); assertArrayEquals(data, data1); return new Tuple(inflater.avail_in, inflater.avail_out, inflater.total_in, inflater.total_out); })).reduce((x, y) -> { assertEquals(y, x); return x; }); c.bad.forEach(uncheckedConsumer(w -> { ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); Inflater inflater = new Inflater(w); assertThrows(IOException.class, () -> readIS(new InflaterInputStream(new ByteArrayInputStream(deflated), inflater), baos2, buf)); })); })); } @Test public void testZStreamCanDetectDataTypeOfInput() { cases.forEach(c -> { ZStream deflater = new ZStream(); err = deflater.deflateInit(Z_BEST_SPEED, DEF_WBITS, 9, c.iflag); assertEquals(Z_OK, err); deflate(deflater, data, compr); c.good.forEach(w -> { ZStream inflater = inflate(compr, uncompr, w); int total_out = (int) inflater.total_out; assertEquals(new String(data, UTF_8), new String(uncompr, 0, total_out, UTF_8)); }); c.bad.forEach(w -> { inflate_fail(compr, uncompr, w); }); }); } @Test public void testDeflaterCanSupportWbitsPlus32() { Deflater deflater = new Deflater(); err = deflater.init(Z_BEST_SPEED, DEF_WBITS, 9); assertEquals(Z_OK, err); deflate(deflater, data, compr); Inflater inflater = new Inflater(); err = inflater.init(DEF_WBITS + 32); assertEquals(Z_OK, err); inflater.setInput(compr); boolean loop = true; while (loop) { inflater.setOutput(uncompr); err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); int total_out = (int) inflater.total_out; assertEquals(new String(data, UTF_8), new String(uncompr, 0, total_out, UTF_8)); deflater = new Deflater(); err = deflater.init(Z_BEST_SPEED, DEF_WBITS + 16, 9); assertEquals(Z_OK, err); deflate(deflater, data, compr); inflater = new Inflater(); err = inflater.init(DEF_WBITS + 32); assertEquals(Z_OK, err); inflater.setInput(compr); loop = true; while (loop) { inflater.setOutput(uncompr); err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); total_out = (int) inflater.total_out; assertEquals(new String(data, UTF_8), new String(uncompr, 0, total_out, UTF_8)); } private void deflate(ZStream deflater, byte[] data, byte[] compr) { deflater.setInput(data); deflater.setOutput(compr); err = deflater.deflate(JZlib.Z_FINISH); assertEquals(Z_STREAM_END, err); err = deflater.end(); assertEquals(Z_OK, err); } private ZStream inflate(byte[] compr, byte[] uncompr, WrapperType w) { ZStream inflater = new ZStream(); err = inflater.inflateInit(w); assertEquals(Z_OK, err); inflater.setInput(compr); boolean loop = true; while (loop) { inflater.setOutput(uncompr); err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else assertEquals(Z_OK, err); } err = inflater.end(); assertEquals(Z_OK, err); return inflater; } private void inflate_fail(byte[] compr, byte[] uncompr, WrapperType w) { ZStream inflater = new ZStream(); err = inflater.inflateInit(w); assertEquals(Z_OK, err); inflater.setInput(compr); boolean loop = true; while (loop) { inflater.setOutput(uncompr); err = inflater.inflate(Z_NO_FLUSH); if (err == Z_STREAM_END) loop = false; else { assertEquals(Z_DATA_ERROR, err); loop = false; } } } static class Case { final WrapperType iflag; final List good; final List bad; Case(WrapperType iflag, List good, List bad) { this.iflag = iflag; this.good = good; this.bad = bad; } } static class Tuple { private final int a; private final int b; private final long c; private final long d; Tuple(int a, int b, long c, long d) { this.a = a; this.b = b; this.c = c; this.d = d; } @Override public boolean equals(Object obj) { if (!(obj instanceof Tuple)) return false; else if (a != ((Tuple) obj).a) return false; else if (b != ((Tuple) obj).b) return false; else if (c != ((Tuple) obj).c) return false; else if (d != ((Tuple) obj).d) return false; else return true; } @Override public int hashCode() { return Objects.hash(a, b, c, d); } } } mwiede-jsch-c8efa3f/src/test/resources/000077500000000000000000000000001465436372100202655ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/resources/Log4j2LoggerTest.xml000066400000000000000000000007031465436372100240500ustar00rootroot00000000000000 mwiede-jsch-c8efa3f/src/test/resources/config000066400000000000000000000001651465436372100214570ustar00rootroot00000000000000# some comment Host host2 HostName host2.somewhere.edu User foobar IdentityFile ~/.ssh/old_keys/host2_keymwiede-jsch-c8efa3f/src/test/resources/config_with_negations000066400000000000000000000002761465436372100245640ustar00rootroot00000000000000Host *.example.com !*-jump.example.com !*-proxy.example.com User u1 Host *-jump.example.com User jump-u1 Host *-proxy.example.com User proxy-u1 Host *.example.org User u2 mwiede-jsch-c8efa3f/src/test/resources/docker/000077500000000000000000000000001465436372100215345ustar00rootroot00000000000000mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile000066400000000000000000000014251465436372100235300ustar00rootroot00000000000000FROM alpine:3.7 RUN apk update && \ apk upgrade && \ apk add openssh && \ rm /var/cache/apk/* && \ mkdir /root/.ssh && \ chmod 700 /root/.ssh COPY ssh_host_rsa_key /etc/ssh/ COPY ssh_host_rsa_key.pub /etc/ssh/ COPY ssh_host_ecdsa256_key /etc/ssh/ COPY ssh_host_ecdsa256_key.pub /etc/ssh/ COPY ssh_host_ecdsa384_key /etc/ssh/ COPY ssh_host_ecdsa384_key.pub /etc/ssh/ COPY ssh_host_ecdsa521_key /etc/ssh/ COPY ssh_host_ecdsa521_key.pub /etc/ssh/ COPY ssh_host_ed25519_key /etc/ssh/ COPY ssh_host_ed25519_key.pub /etc/ssh/ COPY ssh_host_dsa_key /etc/ssh/ COPY ssh_host_dsa_key.pub /etc/ssh/ COPY sshd_config /etc/ssh/ COPY authorized_keys /root/.ssh/ RUN chmod 600 /etc/ssh/ssh_*_key /root/.ssh/authorized_keys RUN passwd -u root ENTRYPOINT ["/usr/sbin/sshd", "-D", "-e"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.ExtInfoInAuthIT000066400000000000000000000024531465436372100264530ustar00rootroot00000000000000FROM alpine:3.19 RUN apk update && \ apk upgrade && \ apk add openssh && \ rm /var/cache/apk/* && \ addgroup -g 1000 rsa && \ adduser -Du 1000 -G rsa -Hh /rsa -s /bin/sh -g rsa rsa && \ mkdir -p /rsa/.ssh && \ chown -R rsa:rsa /rsa && \ chmod 700 /rsa /rsa/.ssh && \ passwd -u rsa && \ addgroup -g 1001 ecdsa && \ adduser -Du 1001 -G ecdsa -Hh /ecdsa -s /bin/sh -g ecdsa ecdsa && \ mkdir -p /ecdsa/.ssh && \ chown -R ecdsa:ecdsa /ecdsa && \ chmod 700 /ecdsa /ecdsa/.ssh && \ passwd -u ecdsa COPY ssh_host_rsa_key /etc/ssh/ COPY ssh_host_rsa_key.pub /etc/ssh/ COPY ssh_host_ecdsa256_key /etc/ssh/ COPY ssh_host_ecdsa256_key.pub /etc/ssh/ COPY ssh_host_ecdsa384_key /etc/ssh/ COPY ssh_host_ecdsa384_key.pub /etc/ssh/ COPY ssh_host_ecdsa521_key /etc/ssh/ COPY ssh_host_ecdsa521_key.pub /etc/ssh/ COPY ssh_host_ed25519_key /etc/ssh/ COPY ssh_host_ed25519_key.pub /etc/ssh/ COPY ssh_host_dsa_key /etc/ssh/ COPY ssh_host_dsa_key.pub /etc/ssh/ COPY sshd_config /etc/ssh/ COPY authorized_keys /rsa/.ssh/ COPY authorized_keys /ecdsa/.ssh/ RUN chown rsa:rsa /rsa/.ssh/authorized_keys && \ chown ecdsa:ecdsa /ecdsa/.ssh/authorized_keys && \ chmod 600 /etc/ssh/ssh_*_key /rsa/.ssh/authorized_keys /ecdsa/.ssh/authorized_keys ENTRYPOINT ["/usr/sbin/sshd", "-D", "-e"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.KeyPairIT000066400000000000000000000005701465436372100253300ustar00rootroot00000000000000FROM alpine:3.7 RUN apk update && \ apk upgrade && \ apk add openssh && \ rm /var/cache/apk/* && \ mkdir /root/.ssh && \ chmod 700 /root/.ssh && \ ssh-keygen -A COPY sshd_config /etc/ssh/ COPY authorized_keys /root/.ssh/ RUN chmod 600 /etc/ssh/ssh_*_key /root/.ssh/authorized_keys RUN passwd -u root EXPOSE 22 ENTRYPOINT ["/usr/sbin/sshd", "-D", "-e"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.asyncssh000066400000000000000000000015211465436372100253570ustar00rootroot00000000000000FROM python:3.9 ARG MAX_PKTSIZE=32768 RUN pip install 'asyncssh[bcrypt]' && \ mkdir /root/.ssh && \ chmod 700 /root/.ssh COPY asyncsshd.py / COPY ssh_host_rsa_key /etc/ssh/ COPY ssh_host_rsa_key.pub /etc/ssh/ COPY ssh_host_ecdsa256_key /etc/ssh/ COPY ssh_host_ecdsa256_key.pub /etc/ssh/ COPY ssh_host_ecdsa384_key /etc/ssh/ COPY ssh_host_ecdsa384_key.pub /etc/ssh/ COPY ssh_host_ecdsa521_key /etc/ssh/ COPY ssh_host_ecdsa521_key.pub /etc/ssh/ COPY ssh_host_ed25519_key /etc/ssh/ COPY ssh_host_ed25519_key.pub /etc/ssh/ COPY ssh_host_ed448_key /etc/ssh/ COPY ssh_host_ed448_key.pub /etc/ssh/ COPY ssh_host_dsa_key /etc/ssh/ COPY ssh_host_dsa_key.pub /etc/ssh/ COPY authorized_keys /root/.ssh/ RUN chmod 600 /etc/ssh/ssh_*_key /root/.ssh/authorized_keys RUN passwd -u root ENV MAX_PKTSIZE=${MAX_PKTSIZE} ENTRYPOINT ["python", "/asyncsshd.py"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.dropbear000066400000000000000000000006411465436372100253240ustar00rootroot00000000000000FROM alpine:3.12 RUN apk update && \ apk upgrade && \ apk add dropbear openssh && \ rm /var/cache/apk/* && \ mkdir /etc/dropbear && \ mkdir /root/.ssh && \ chmod 700 /root/.ssh COPY dropbear_rsa_host_key /etc/dropbear/ COPY authorized_keys /root/.ssh/ RUN chmod 600 /etc/dropbear/dropbear_*_key /root/.ssh/authorized_keys RUN passwd -u root ENTRYPOINT ["/usr/sbin/dropbear", "-F", "-s", "-E"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.openssh74000066400000000000000000000014021465436372100253540ustar00rootroot00000000000000FROM alpine:3.5 RUN apk update && \ apk upgrade && \ apk add openssh && \ rm /var/cache/apk/* && \ mkdir /root/.ssh && \ chmod 700 /root/.ssh COPY ssh_host_rsa_key /etc/ssh/ COPY ssh_host_rsa_key.pub /etc/ssh/ COPY ssh_host_ecdsa256_key /etc/ssh/ COPY ssh_host_ecdsa256_key.pub /etc/ssh/ COPY ssh_host_ecdsa384_key /etc/ssh/ COPY ssh_host_ecdsa384_key.pub /etc/ssh/ COPY ssh_host_ecdsa521_key /etc/ssh/ COPY ssh_host_ecdsa521_key.pub /etc/ssh/ COPY ssh_host_ed25519_key /etc/ssh/ COPY ssh_host_ed25519_key.pub /etc/ssh/ COPY ssh_host_dsa_key /etc/ssh/ COPY ssh_host_dsa_key.pub /etc/ssh/ COPY sshd_config /etc/ssh/ COPY authorized_keys /root/.ssh/ RUN chmod 600 /etc/ssh/ssh_*_key /root/.ssh/authorized_keys ENTRYPOINT ["/usr/sbin/sshd", "-D", "-e"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.openssh96000066400000000000000000000014031465436372100253610ustar00rootroot00000000000000FROM alpine:3.19 RUN apk update && \ apk upgrade && \ apk add openssh && \ rm /var/cache/apk/* && \ mkdir /root/.ssh && \ chmod 700 /root/.ssh COPY ssh_host_rsa_key /etc/ssh/ COPY ssh_host_rsa_key.pub /etc/ssh/ COPY ssh_host_ecdsa256_key /etc/ssh/ COPY ssh_host_ecdsa256_key.pub /etc/ssh/ COPY ssh_host_ecdsa384_key /etc/ssh/ COPY ssh_host_ecdsa384_key.pub /etc/ssh/ COPY ssh_host_ecdsa521_key /etc/ssh/ COPY ssh_host_ecdsa521_key.pub /etc/ssh/ COPY ssh_host_ed25519_key /etc/ssh/ COPY ssh_host_ed25519_key.pub /etc/ssh/ COPY ssh_host_dsa_key /etc/ssh/ COPY ssh_host_dsa_key.pub /etc/ssh/ COPY sshd_config /etc/ssh/ COPY authorized_keys /root/.ssh/ RUN chmod 600 /etc/ssh/ssh_*_key /root/.ssh/authorized_keys ENTRYPOINT ["/usr/sbin/sshd", "-D", "-e"] mwiede-jsch-c8efa3f/src/test/resources/docker/Dockerfile.sshagent000066400000000000000000000017321465436372100253440ustar00rootroot00000000000000FROM alpine:3.7 ARG testuid ARG testgid RUN apk update && \ apk upgrade && \ apk add openssh su-exec && \ rm /var/cache/apk/* && \ if [ "$testuid" -gt 0 ]; then if egrep "^[^:]+:x:$testuid:" /etc/passwd; then deluser "$(egrep "^[^:]+:x:$testuid:" /etc/passwd | cut -d: -f1)"; fi; fi && \ if [ "$testgid" -gt 0 ]; then if egrep "^[^:]+:x:[^:]+:$testgid:" /etc/passwd; then deluser "$(egrep "^[^:]+:x:[^:]+:$testgid:" /etc/passwd | cut -d: -f1)"; fi; fi && \ if [ "$testgid" -gt 0 ]; then if egrep "^[^:]+:x:$testgid:" /etc/group; then delgroup "$(egrep "^[^:]+:x:$testgid:" /etc/group | cut -d: -f1)"; fi; fi && \ addgroup -g $testgid testuser && \ adduser -Du $testuid -G testuser -Hh /testuser -s /bin/sh -g testuser testuser && \ mkdir /testuser && \ chown testuser:testuser /testuser && \ chmod 700 /testuser && \ passwd -u testuser ENTRYPOINT ["/sbin/su-exec", "testuser:testuser", "/usr/bin/ssh-agent", "-d", "-a", "/testuser/sock"] mwiede-jsch-c8efa3f/src/test/resources/docker/asyncsshd.py000077500000000000000000000076451465436372100241240ustar00rootroot00000000000000#!/usr/bin/env python import asyncio import asyncssh import os import sys class MySFTPServer(asyncssh.SFTPServer): def __init__(self, chan): root = '/' super().__init__(chan, chroot=root) async def start_server(max_pktsize: int): await asyncssh.listen('', 22, sftp_factory=MySFTPServer, allow_scp=True, max_pktsize=max_pktsize, authorized_client_keys='/root/.ssh/authorized_keys', server_host_keys=['/etc/ssh/ssh_host_ecdsa256_key', '/etc/ssh/ssh_host_ecdsa384_key', '/etc/ssh/ssh_host_ecdsa521_key', '/etc/ssh/ssh_host_ed448_key', '/etc/ssh/ssh_host_ed25519_key', '/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_dsa_key'], kex_algs=['curve448-sha512', 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp521', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp256', 'diffie-hellman-group18-sha512', 'diffie-hellman-group17-sha512', 'diffie-hellman-group16-sha512', 'diffie-hellman-group15-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1', 'diffie-hellman-group14-sha224@ssh.com', 'diffie-hellman-group14-sha256@ssh.com', 'diffie-hellman-group15-sha256@ssh.com', 'diffie-hellman-group15-sha384@ssh.com', 'diffie-hellman-group16-sha384@ssh.com', 'diffie-hellman-group16-sha512@ssh.com', 'diffie-hellman-group18-sha512@ssh.com', 'diffie-hellman-group-exchange-sha224@ssh.com', 'diffie-hellman-group-exchange-sha384@ssh.com', 'diffie-hellman-group-exchange-sha512@ssh.com'], signature_algs=['ecdsa-sha2-nistp521', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp256', 'ssh-ed448', 'ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa', 'ssh-dss', 'ssh-rsa-sha224@ssh.com', 'ssh-rsa-sha256@ssh.com', 'ssh-rsa-sha384@ssh.com', 'ssh-rsa-sha512@ssh.com'], encryption_algs=['chacha20-poly1305@openssh.com', 'aes256-gcm@openssh.com', 'aes128-gcm@openssh.com', 'aes256-ctr', 'aes192-ctr', 'aes128-ctr', 'aes256-cbc', 'aes192-cbc', 'aes128-cbc', '3des-cbc', 'blowfish-cbc', 'arcfour', 'arcfour256', 'arcfour128', 'cast128-cbc', 'seed-cbc@ssh.com'], mac_algs=['hmac-sha2-512-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'hmac-sha1-etm@openssh.com', 'hmac-sha2-512', 'hmac-sha2-256', 'hmac-sha1', 'hmac-sha1-96-etm@openssh.com', 'hmac-sha1-96', 'hmac-md5-etm@openssh.com', 'hmac-md5', 'hmac-md5-96-etm@openssh.com', 'hmac-md5-96', 'hmac-sha256-2@ssh.com', 'hmac-sha224@ssh.com', 'hmac-sha256@ssh.com', 'hmac-sha384@ssh.com', 'hmac-sha512@ssh.com'], compression_algs=['zlib@openssh.com', 'zlib', 'none']) loop = asyncio.get_event_loop() try: max_pktsize = int(os.getenv("MAX_PKTSIZE")) loop.run_until_complete(start_server(max_pktsize)) except (ValueError, OSError, asyncssh.Error) as exc: sys.exit('Error starting server: ' + str(exc)) loop.run_forever() mwiede-jsch-c8efa3f/src/test/resources/docker/authorized_keys000066400000000000000000000034301465436372100246700ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEE5LImdpZHwScWm81gWgQo2WqeMmKTNIGbWfhFwMgP2YSBt0HnuQ7/Fa88S5Url7ufOwJl8fC7s6m+yjHn1NYgCM88EtAklBAoiZzJaq4ulvuZsbi+r287wxCJ7/z0za099RkD5azXOCupD+PYlGtDONOxOaHTB38oQpi8kFOKdxguuJ3oWL/gsgUbkG9umejTtfpxRV8TLqXKYLzr0SZ1K+BXTG73Ye/U9LitPaOgpM1zUP8xu4n2WIa6Ahhnow3/7Rpaf7CW/4dPhzqINlBLet1bIlNlNVC1WFPNDV79AAf5FjiKhpcH7bUvojTc3SKUIyDzDlc140X7EebzN+J test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIErkTdmv0GQWOykbxhJdU8Dz8CqMRdCS6BZN7rVgb6Qe test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADl9cFNgeHKLh3cPhjr2QpnAYIN5w1jmm4AHIvz8r9XcLxl9+wrH0JCHGXNCdKQ4Sz/11wMc1eV6WQA= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBcLHSACx0yr1S902vlRRnXA12YpaXIOkZUXoNFb01+CxQBgGpVTEVMuakLpIW/XcD9ltu+c6Czk5WnBKEoHNuI= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPzeZvkHBTpjn1KGR0ZeW1mCEJhpL0TjvO3nei+16zUh6z3D6rs09rSbzwz9ovDzGd0SHN1vTeanm987Ebkpij4oIlypz3D6xSWXQZTQwKxB0JnOpccdeC7FxcLmHFFecg== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAG3XTlAFoQd4iIBt5KoTHJk46v1AdZSd+wfCSpc2/GCzHNGVqidrKCrypszpkQOW6vYG8riilyfF36rJa9ipjR+5gDApLIe/ix1Fknr8MU6nWoYv2+NBTsEcaS/VTeiUuMKftMtlO2wOaWFcbZBQUAlb3LDnpMyYKCqIXhhl4vqCxBukg== test ssh-dss AAAAB3NzaC1kc3MAAACBAKCQzxCEIM7yb5fbSmuJCz/+v40WEbULx4JKCXBb7zmRtDtweBqUJXDM1bMjQ4VwGB1EkfMZJQR7rPrOAxfdMdCpkqgPR0+xlljZLVarSJHwt1KR9EudUjUdD2ZrPlvPlG1sAyvMVTK5KCx2QaS2Bn/gukxrvT7DkaqCFHg2P7rLAAAAFQCF+m0B12XxhF1P+3hF3ktGmfYpywAAAIBX+azef1TX90FwS7vyngCrdJsOYqWtj1zQ8MlrwrWL0jdbjcIG/0vcq1x84LTgs+hAPylDBCGGJa/td88kJ6jIUeWiebRUG0zEH8LM+nehQA5O6TuEV3U0Dg73I0Mb04ZzN2GqYqW+KwHdiaU5M8XQv3V/PCmY8d7R5WcMKKDCcQAAAIEAmy0FgQoaWyHdD84b7zD0YjziMsVELAbGWwdxNuNe6wtACcctCdIQigQYaC2HwGjlDKVMjQfd4RWArshg7p0PlEw7//HSgoVhwcBbDpmWGCS6TxSSQpDmdDgiVegERMYjo2BZoZQTuJIx/BhQggVISkELwZfsi1BnPC5Aecq7ILI= test mwiede-jsch-c8efa3f/src/test/resources/docker/authorized_keys.KeyPairIT000066400000000000000000000754741465436372100265110ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEE5LImdpZHwScWm81gWgQo2WqeMmKTNIGbWfhFwMgP2YSBt0HnuQ7/Fa88S5Url7ufOwJl8fC7s6m+yjHn1NYgCM88EtAklBAoiZzJaq4ulvuZsbi+r287wxCJ7/z0za099RkD5azXOCupD+PYlGtDONOxOaHTB38oQpi8kFOKdxguuJ3oWL/gsgUbkG9umejTtfpxRV8TLqXKYLzr0SZ1K+BXTG73Ye/U9LitPaOgpM1zUP8xu4n2WIa6Ahhnow3/7Rpaf7CW/4dPhzqINlBLet1bIlNlNVC1WFPNDV79AAf5FjiKhpcH7bUvojTc3SKUIyDzDlc140X7EebzN+J test ssh-dss AAAAB3NzaC1kc3MAAACBAKCQzxCEIM7yb5fbSmuJCz/+v40WEbULx4JKCXBb7zmRtDtweBqUJXDM1bMjQ4VwGB1EkfMZJQR7rPrOAxfdMdCpkqgPR0+xlljZLVarSJHwt1KR9EudUjUdD2ZrPlvPlG1sAyvMVTK5KCx2QaS2Bn/gukxrvT7DkaqCFHg2P7rLAAAAFQCF+m0B12XxhF1P+3hF3ktGmfYpywAAAIBX+azef1TX90FwS7vyngCrdJsOYqWtj1zQ8MlrwrWL0jdbjcIG/0vcq1x84LTgs+hAPylDBCGGJa/td88kJ6jIUeWiebRUG0zEH8LM+nehQA5O6TuEV3U0Dg73I0Mb04ZzN2GqYqW+KwHdiaU5M8XQv3V/PCmY8d7R5WcMKKDCcQAAAIEAmy0FgQoaWyHdD84b7zD0YjziMsVELAbGWwdxNuNe6wtACcctCdIQigQYaC2HwGjlDKVMjQfd4RWArshg7p0PlEw7//HSgoVhwcBbDpmWGCS6TxSSQpDmdDgiVegERMYjo2BZoZQTuJIx/BhQggVISkELwZfsi1BnPC5Aecq7ILI= test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCmukZSkSImcmE/TQhe/pL/Bx3ZNwFIWFbdNy8tzjlN+TSxrVrb7kyH/4skSUleNAb8M69MTKTiospqq0E7bnZ21h8M0qQCTFcRnN5Jk6MLQzaWHG4dz3BSKWzf9wJhnGuFT0F3bhIG14LsewxcJyf2bVh4pAlt9rO0q77/HNSj4045XvUT2M/LwvNF68qXly90ZxsbTGmy6b3QT7wlJmdorThQRNTVp3MYq7X6oJb46QWxe35A3S3UfOKHBw9q2zjdG4UBE4UqkjTqWLyIu+BhG+K6y8/fbVGgX/L1sgxyzPhEIo++ZkXjzx8sTWH3DIE738jBS7o0/rz5zI/CRl8Z test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNVEfQu64p2GczvWj0AlncuNG+PzPd0jZ1/hfx/JDz1dRVEalcXMtIGRSAH49LzicAMPV8jvwNCa+aj/UF7laDNqjIXvvC+sTA8l8/YilLm6BJ2G8B4sMo7/F8WOAcxrs+j1QT5tAMV88yaefoaXjh9EWTOGesW1OiRfGYnzfhNrx8m8y0qVpYKpFbA5hswEL2VJC6YZxpg2XlMMJSSxBDhJLWBOBlxh1oN5cqv8cDPmwGYlvBYGGcuz6h3krARdXcyHciafoBKZNBimiJ5VNvhmsa7aSkZgH+k6w4Cbddnuo78WtrEGvyf7HN3gBJZHGVFeclkRkeR0RR05HDqyanhOE/fO2HOHW3/x9SSwrnk9I/lZAQlyROP+zOJ3LI4m+iHZUqMfgtN/JkK40l+rNbClGszEFLW+OSbajGoEh+deL+tdwownsuVORpAckoRJdLo03RGam8WMxx8UmkHw8WJBf91bshH1kgQSTIV/lBbFllkwM7+LAWy7Ow1ZGfzsM= test ssh-dss AAAAB3NzaC1kc3MAAACBAKCQzxCEIM7yb5fbSmuJCz/+v40WEbULx4JKCXBb7zmRtDtweBqUJXDM1bMjQ4VwGB1EkfMZJQR7rPrOAxfdMdCpkqgPR0+xlljZLVarSJHwt1KR9EudUjUdD2ZrPlvPlG1sAyvMVTK5KCx2QaS2Bn/gukxrvT7DkaqCFHg2P7rLAAAAFQCF+m0B12XxhF1P+3hF3ktGmfYpywAAAIBX+azef1TX90FwS7vyngCrdJsOYqWtj1zQ8MlrwrWL0jdbjcIG/0vcq1x84LTgs+hAPylDBCGGJa/td88kJ6jIUeWiebRUG0zEH8LM+nehQA5O6TuEV3U0Dg73I0Mb04ZzN2GqYqW+KwHdiaU5M8XQv3V/PCmY8d7R5WcMKKDCcQAAAIEAmy0FgQoaWyHdD84b7zD0YjziMsVELAbGWwdxNuNe6wtACcctCdIQigQYaC2HwGjlDKVMjQfd4RWArshg7p0PlEw7//HSgoVhwcBbDpmWGCS6TxSSQpDmdDgiVegERMYjo2BZoZQTuJIx/BhQggVISkELwZfsi1BnPC5Aecq7ILI= test ssh-dss AAAAB3NzaC1kc3MAAACBAMKmaZwslPWE83wv+Ofl9oaMeOR03Yk0cyDc5fSAgjepXZQR5sps0KFORRufI6dLQHY4XLoyPc/Hr0ra+vY/l+p20cJVjQ07oosPU/d2eLdZ66rdjXCyrJPjFjnNJtumnBnJZqWGObKspnWk73vPOflReyGpUFe51PF1usur3uDLAAAAFQC3dSlxZZVNbvqjJpg8/oSMuG27/QAAAIEApkd3miYVc/Cl1QwdqwInIjby1yGNCfFsZALGBYc67lkd5lGBdNlL+fgi+BwC6UXu5OAqWB/b9OtvJR8NRcM77V252IER4t95t2ZdG66M1T5q1aOVL/ehPZFHf0oPXHJLcsybzqKFAtQj5hEbnrwJYW0fWi87C9LApplzPTVYQikAAACAUEu5tFmImzyQsUBMN/j1GWCCSVznjfRHkeGwx5koC0D2iK3mMphnF9avsoX2PrboEbGqy69JPCekKQiPPWxcQRTRqFS/ySkECJ5lJ2zJrW1whjLQEJbOq7WmusSML9UXCpNSwCqhJxPYx5a8Pq7lrrBP21jT/Z/A4m4c4wMkLXo= test ssh-dss AAAAB3NzaC1kc3MAAACBAPmIBCP1AA8EiTL0VAdzau+1KuRmPkg+H2du4zt4ifhzEx4MscZ7cpBsUAM/EBC/ECWTHzDiWyFFuenvxDlfTi9XxySdOKM6XGLkY7oLsY1y5bShyLrycxDD7MRQ8HpUc9TPzE2PDH4Od6o98e+vdXP0+IDUZGbSuwEnaABX/1+ZAAAAFQDIB9KUd1/gnzM4s4FXCQb7zCnjVwAAAIBptrE9g/ooRnh4bOWiA3/StxbjMRmA9f9bJbM55CinL4yf/GdGmeBp6YjDBxDyk1oXmVJ2hLVXgW6kETbt+D01SouCTgLPlFwLFhqZQ+A4JQOKuLIBaM92hI7sAfTewkxbmAk/e1vyOeyfcQDhbncESzVBZrheXC1fTKv7O2PgbgAAAIBKhGEiNwKNA/pfYvkEbX90/jVoIEKZfqTk+PB2gbVMT98LWPaexrDwEGuCCK3KOtMncDai+0r1ujf1hzNJ4z43Z1n15tPvAIwQsObTL+eUQkVjHA8LXOq8n4yYyPidkjGzWcfBAm4Lm6vKkzFM3VRouQIHpWpjRl3wGTJZkOoH0Q== test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDY+326Z0bUOn8kYUc399P2mr7Eh0E7Nc9zPrv80B05ykfmsCM053SiGYQgwP5aBzZk83PdWdYIK12U9eO5WzTwT2po9PrZT0AvsBGnU7MkzSSlXX79e9ELbGYNWV4DafT/VHxVwCuoctG7XKUorGA3ZHxGbhNWyo/+6LNwyCMcxfpjpCelJWn4MTwFqs0DVme4R2Sy+LaVg3Nv5Vbbi27cIbA+6Orit2ajDUUCHJvcQlpGrM6x9w0zbt4pUI6yHPCHIIqZEPzj1285GCF6ZQzi0TMEf4wHtA8fN1Xgn1vBw+IEkrAAnQUeTWOR1nc6CDFEGTlyYlIuz634I4BwfhBl test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQD1ub4yJ8TCXgPaTtASEA034K+85zo2MDlRCB7tHgpmIpK7btPxizYEPEPywVnBRGMJnhIyKKHc7AHzCos3tkGVYNBlDGmnoaZTeZqhmsRSqqxHyfIRQ1T+aGIN4scliZ+iW8RI/djYyfPlcAR3Kku+Q3xsR5K2yzzxZiYB/rD9XjvRRtc7cYZlHaMe2NBtQhh3hamQVSEJMjfSCpq4okULk0UytXhdbPtP/tLDvqeK7op+q97hFS0wRY9xTaNM+qUhuhaKNbhuexgGQBk7We45LcR6O3XwjAB+X7owa4JtKx9oKY93+3qtM+5+6nRnFnkB/GL5fdKPmIswQ1vOSgGeEhg/M0yzX0PEMx4qfczpUp2rFtMTNg9O6Xz9qJCnZy/I1EmK6FEXerpEY0x41mY2NBBor9vataM9IxzJ1VIra8JYjnPqG48V9LFhSEpFfi1CquqJu1fmtxtH4YNWWNQECKp0s+WmxKAu2ZAAr1wl+tNkkiZOaDSluT14qMkSEjU= test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCze/5G1FPKvgcnLXqHV4jbUfO+gi75BUKUWKBowdg63kr9e3GdGVmwtBBWTJMyxEWVtJMrH8CARWoyViILQy9oFfbbcwuAnfhVjdPVNpK7RL1ZwCCrsg6UDpE+Vp4rTWzUcDXUyI2MZrePJCwU0+UWdvoEJXwE2Nitb+sS802IsdlwiRj9knzKJ5rVcpGpQ0Qkc0jbeNDfznRAE8ARawkDLcXEio9V6t4psAWf3BbHGYec9PZAYcdzCHcwmLmTT/DSOF+ut2fxvjBydWJzGHmKyozlFNjThgXt0i0fcedLG0oAHNNBL8UeEYQ7H0glbT9rsnMqOAtgBYD/nJGfMkMMjP7NRS0Y0jtkmY8PQ3l7RkHTFeKVkKpKtyD3+LsfuOZkh5A6rhOZgMP9+22AZhIXGho9kJZSSF7B9CWa+TCr5iZo9lLXbeMFRrk5Ltg7BNHkO5Rx8SGroGYGkLXt89+eL+Ht1I4jbq1fWF55YQYnTOovvnNVVCp4i0c8KlNAqSM= test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC96PvllVEOgtQdHnaoga3gi8md+/lUwBG0SOv4co9QaJ2kvJZDTiSLmJc4euEuciiplvzKpKSWSVqaZLboXiVVt8MnPmIwIlp8bhIqJ+0431FNWWq6RA/4EszHiARxMIwUqw+svN2GMm5fGr+PK3FR6mXGjiVlv4/5Vb0BCUjgB0vIqq123DmKpxrT6S3Ik5vYCCn0zKtuWxfxp3hpCqC2TdqD7/rFTX/AstmlhTO4FRDEK/7JNBSWY8+9/rQS/c/HSSW7qMGEoGFkELKSYFSdwLcyAMS1HySzNR1SuyBLDsOSaN5iWm5cBqKIK175Uc3Xe3fIn6+C5ld0m/nN75bw6QJiDH7I2jMYDTBpDqztBiqdjcSwvNTogGQg/oJLC7aAz+E5gfkTsg/Q6bPf6quyPIQ+KKH5v2YVFQIw2Te0X7/OZACsqUnCbGiDXCixPTTGoRypcR0MQDJxR497y7zvO4kiqQpsdBoELuhWSW8+9BcovL4/jSyqUEGvGYoh/QM= test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqGObM6DyGcra+/eBdm7mIvnLM9oUDUwpT3hRbF7S7V6bb64EuFlduGXJKK+i4/a/ls1Sm3GVwnWvwuRxrVXgv1497MYDzDcflfm+bQLUN38qNscVhn3jdtFuCTIc7VKmtEd9zn4HVzQhUYWq/oiqwOsDeP1QidWbNwgBthCxzhfdi9XUpdpT3Tm/mtLwEz8KZ2kP9VdfXBql6NI64COcI+B2nzE2YwxZsLGFj1orstRZ3WOLTJdLtQ1NhBQqTEwFD06Jhf50wo13xV84jWeZom+ylJQcj9njnfH8Kf7T+1eyBAqCPLvS6kM5Q9J6bGPj67Hkp96zPT/y3Gh1le80o3JrYjo20NqWzO+/OIXilrDoYdUKJbgoM7GXtMlxFNEnj7BIf6TLNZJY9bA6dw1yFs9wOl9LRhC1zUC6kESx8DIiqSpxrZTF0ScgvC/gKqX6K81ovJBklrAuTQpTqGKOW2eY5jqiRAVa7Gx8sPPtHkGqodD/sFOKurggVDf2Y1vs= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBcLHSACx0yr1S902vlRRnXA12YpaXIOkZUXoNFb01+CxQBgGpVTEVMuakLpIW/XcD9ltu+c6Czk5WnBKEoHNuI= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPKyvhX/3Q32EEhZKF6s+fEzfQwabsSpXgFJ2LwpGxKFxzE2jw4Nvwe9W3YbPyrZU6K2MMA7p7ZdJwdDP/tQ9dhttOGGSkea9Cq4dcdgC9cdBuQ4aGb8crmY3Z5wc1dPxQ== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAG3XTlAFoQd4iIBt5KoTHJk46v1AdZSd+wfCSpc2/GCzHNGVqidrKCrypszpkQOW6vYG8riilyfF36rJa9ipjR+5gDApLIe/ix1Fknr8MU6nWoYv2+NBTsEcaS/VTeiUuMKftMtlO2wOaWFcbZBQUAlb3LDnpMyYKCqIXhhl4vqCxBukg== test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEGMIJlen0L+Zbjr0UfhTGUs1NXKTWqxmLuHwjLXK5HD2ktbu/wWIqWD4fdfZ/bnH2s8FZu2Pw58PM0a7ZpvoGw= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPKyvhX/3Q32EEhZKF6s+fEzfQwabsSpXgFJ2LwpGxKFxzE2jw4Nvwe9W3YbPyrZU6K2MMA7p7ZdJwdDP/tQ9dhttOGGSkea9Cq4dcdgC9cdBuQ4aGb8crmY3Z5wc1dPxQ== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAEhmKgKa4VuG9k/oiIGUZMLKwIGJ1rwKhHHZ/m4ZGhaWbvBApeDPkSj8WG0uz4o+LnQHD/i9rzWiRr5sd27quHErAHFzzLbUUoRvKpVjGEKWt+5yWoK9kkj/shi4Rv5UOiwZRr7dcHX+5L9ff1KpkxsGUD9mq6dVSVttU4Bpygw5PP5tw== test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKHuAe5N1uLPUpY3t5kyYuISOxUobPZfK8H+CQaJTCALTMFrT63UDDYLyI2xroS67T2bWHkuhX1BHiTGP6JpwL8= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPzeZvkHBTpjn1KGR0ZeW1mCEJhpL0TjvO3nei+16zUh6z3D6rs09rSbzwz9ovDzGd0SHN1vTeanm987Ebkpij4oIlypz3D6xSWXQZTQwKxB0JnOpccdeC7FxcLmHFFecg== test ssh-dss AAAAB3NzaC1kc3MAAAEBAO8/3Ymo6sXoRb7gfTBqwAYPO+ck8aKsoBdQIn2oD9cX2EIjXaoUXv/gK8tVN4EN0C8XADEFXpE3AQU5WhVZ11bv0AXOqGOreoP381pN72aphh9o989Ee2PET+wEXZnZ4PmftMcuhtHWC8Pq0coht7CO6Xt56ItQuvj3nxMwYc0hvEFDOpHaFCyqiann9q3W5bLB9+ek2tJg5s1AVQKnlGCwn1fj+FXY1cRFDsp7AxGJZPDSNjq4awEZwECG/QLQYiWT0FVILFv68SxQeGk6OlOGip4dKkdXPIhMqHy0GT0diBUm//UweV44S9IXPF9Xsiidq1Dn0vDe9e5OYNmV8kcAAAAVAKpXVF5GLMgMtlhSvjICPOy/A+T7AAABAQDEFLE91TMvZkCGeAHHXHkjF02m3CafJ7qLej8RoTEeZxV8Op/XlRluKNn97XF5G3DHp/DWGqBgawbBwqEq7l3V97zRHESMlivPr0UuCvjSmFR/on5nFCbl3RtZJOHOUkamtv51zBfk124uw7+bpnm9aiDNUs+AHNC3SLSyvdBbz6+sgt3kqD+FZyk+7TC/sOm+zuNmducFDDQIjldI7gx78b8D4BBx33+P5qW12PSlKGrQ7E1Rnk+o9WMSJosq/D7lV56waSV6/AJE9lruQr3LGEwN28DrvbVWen8KtvivGlJUwl1OK/hMBS5u+QZTIzN5M6iGB2hfJjBbF+LUONDNAAABAHBA/s/1ShLjRiIfenBfnInfjl3a3DSF9M3/o1fuY6EFkNs8MR4P2aeOfk0zE4gmO3vlT7TFs960tdUdIHm4TFOo+PFp4pjvVSO3K93cAjzOTwMI4sPhB3rRJxrDmx1CWVdnBrWQKO78kLpLf63/QB71qEe7MirH4FXZRLFP39gRcWknBtHmez92CFlzKzqLQXAMfaSbZ95lPh/bwgQ8OCuYExuB3aw3QmoQQdzSJRfWfuCEsUMmJ3Aub/yUMkpfe+hmQwkG2v730MXp/uDXfDXhZKkoh+v7Mhm04wzpxtB/C1dYpmfSP/i5ews4+9Lo9me6l54xy3+k05PPBBhnYzw= test ssh-dss AAAAB3NzaC1kc3MAAAEBAKU4cgWySBcfMzYy9aSOQwvH5JM1/M4UMNIB5BOZocC2FvJbEok0gTTbLCzGI9A0pe2bnr6EWx78v+aIH6p1GOmbhxZVY4+vkEUMH9Ee8v7XMYqz+CCefWWiAH2bXNa1v7LC9mImiuKmcDdHiVLJwrj/TH3c2EUYlcyQSUGRyOmiw5/auITPrAlmwhyB2ZXLC0X1qNKn+nJiwWxe+SsTXV6F38jbZo+fepbnVEqZ3wTUVnW2gpk0z+LRiLM+1mhASykpmRCyggxW7H2NyNGW+9jVTXD8WCqB/z0o+7PVCPS85qpyfNi6PhH+etXiYnyG8iGI19BWZxDmMCG8Sgr+AnEAAAAVALkJetYWk3MacexWEA0Xa78/o9RfAAABAQCeNE28P6R13v2OUqUtBe6oYQPHOHzMFdEk+qJoXyzKmz7QuQiCGuJ90YUST3fhvsBCOY6lPc6zGfeaVb/r2loa6zm3/0DoOXc/dnU4sbB0auohPlwmjFXDwTQF5BRyxuRWtvPuNgKlgwFd/GcnIwlgW/jRIF3j5wopM3m12+yhZnW+gh575hjvf9edpra7Y1u1VR/jYEQRg+GuXFDvcGE3OTWpphAe0zfjwqIOMYYvx/JQ4HMnB+FxJ4svs5aUOPwBXhMCT9YPWEWVr+1GBVf/VlKTrbapNODYEp0tuL2z8FvakgquJ2XGY74+6M1wbhrrDZ+LPd0Iuwcr7N0ghtVYAAABAEU47Jcr0BB3XEcmy/LsL+hSKudgmczV6QD+fxelS4mY3//8INn+wMRyQzgix4B5yGL6OzQ2RBGlqho2TdfLo5UOjIoQzOpZsjZu2TLZezS5Lpx85ZVuLWwqezx1NZqGDXhtDz2tdUV8eNbePWb5788WXYXOW43ya6Z5RMoywkO7sZRziHH4I+WwlorUpDMgzzfGs2j91bpejsBYcSnqcUDcHJedbMmcUQ53OWocK+/MwoYi8+F/UBuwAoZ8wYauasMZ/ph2k8ygzWHCv7NNteyVAY3o5OvrML4sfu9kmgBIZKKfGZHeFptjQdQcOj7fTI3tuqocwiWVohYBF7laKvI= test ssh-dss AAAAB3NzaC1kc3MAAAEBAIRPWjGVTl5F+y9uOPu8PPtFyjFy+Qclpqww/vdKq7GVAYPU5zdDHPvmEBZKfklfcROB5Ody3Bf7miR3RoLmmK9SZLDqEint+FdbvSWEooFYexZmYukhS9FeGUwttMOz4K4JIAPMVBxbGMPOL2AzPhE45BT2PPUpXMNZTLft2YHYhSIg30nsx+gc7tK7dkdY38pJ3Qtazc3jpyHnxT9o5qA1OdrA09nYHs9osneC4O29uru4Qz+foNP8XbGbkl1XxfooweQiElA9kvoOX+IgtJGgX2fuexAl0VcRmeb8lYxC0KOo9QL/HRW84nC8ZvwhiOXwbvN6X+tmKqTpcYQXgOcAAAAVAKearN3tBfL6HPzkCHzgGrUbSK1zAAABABW+7UNnhWAvSwiHShVSWm+eHjY56rss8OoYCvVRxDTLYhnZs8GvjlHJTTvuPbNMiWYe/vqwKhBDkNJe2cw2on58GsJwLLmdhsZzGRuCZ5twFLusZsjjRImjBTY5ZNYhdbhM4/527a7bSRLT+QPsedmaEvJHeSMHwDYwEb/WMsYnL7XnQTaPRjetz1a64zWIYQU6PTHW+HRrQDT2Dh/knymQvcw3QC5/ZwNf9k1HS8FdE5HC9G9eQfPCGjiFGLfVfAKbq6HslLZO4Ea8WnFLm5CHz3+mFF+1fHXkahGxlOkPGMr/kSeIvcneiMAqUDINC7VcXShVAvATGyaVh324uwoAAAEBAIM8p/hq3+3N5V885fGyBuO6H9RFmmFsuA5c70CXm3A7CHLNh1+ql72WzaRs3DyTICexOtEy/m+2jFd2suKaSa4F74OMQv4KaeeXrGuC8+EGdWFMN0Tf5UkvR/3igCFdxUbhfEa7qbMJBi5fOkkY1/OCldoHHWwWmp7uJA9oY7AVaFcwVyzOOQtUxBL6rtAE8Bcff88H2TFT2vf0WX/fKMKss69uzbphIIxnqnk152lA/gVWcT/mhCWa6NBIGJqKTNppKExTcLBcLlglqmLFi616A7gm8Y1+gi3dnDVu/hWiyz8uOSE31LB4oJGX4fkhOcKgwMJbB00F2ZGPT7JM4JU= test ssh-dss AAAAB3NzaC1kc3MAAAEBAOex/Q9Z8ZKXJbCIQnLHKuJdhGNpdIIOsmFYpNGCClPz4ZTZmk0Dbw7sn2KrshVAbi2RXAIz4gJn+MfHRF7okwgAgN94mMP6VG+D4B2ZpgyyqWRYSSdV5AmbKc2VDX+DVK9qKmHlEX3Wjm4Yfw3s1kGN1/eWwI5MrHB7w5tA8Fw8iUfsRLnwTyGPBXbR1ATqT/obLAic6vogcpGojg1s61k8Rlz2bVMaYRu/RQsIdxvUVi27jn00ClTaMGWKH1ZMhnmjedvN7qI7GcAUgNXFjOGa786aPXzJDC0JdNcmDoei9G/ynTJOpMMo8oy4bJLnVqL/kS8v5k+P4JeIhwvgp+MAAAAVALGpbWxdf1geBNR9INuHLoevUHjvAAABAQDijQTRDHymwb7TO5Lxy2P5MBvxlhTlRN4C+KIo5rnZMX+oFeEX5/hG18grUn7FYdx5/4AHP5EhK4GIcoKYJqnEjXvfSuvBvD2OxES8y9QI5Y0DZSGyAsV0p0/9N6a/khkdJ5Zs9S8iFeeJkevIVsCskLRkz6rrBbsuiXB/N3ojtetEQfFuznFVgEJyBNrk7QuVvu43nWnzYaF98ah2o4C4HdjAds57XzyhDks5kJsi1mryl5jvbCSxcf4iZW9OsOHYcjifwfuM+hz2oYYf87obEIIMdOtsvHjMEfTmBqechUqqsRP6wzv0u6g8rReMBldaoG2HFGpwjvMM+PGU/zdWAAABAAhLKqKGhmXzW3ZugZftycNwrxXFeVXFBywlC1qtDH8N/0aW4AvhWXBk2gw+rDXQudpNlVbtV9sT/+9JBM5iQ9txRfDjVeEzdOuXR2ch51p9Ep7KTYoSaBrBqL5KCxsz12G1+KJazMmlbpxQbdWYrAJrlRjTcHnYCDuhyUV/yCnrR+7VMAx5FyIduuRtYrCgo/+Z/Z9UklPU2596/pp7uozkCBR+RkOm7+9ldU+U9YiaUWymVmXhohFJvy9O6tqj3kZYQll2h7NnGpKVeIqp8wNW5BoCyVwV+fIuyCVsWg5vOKTBu5GR2Kc3AMc18Uq+WEeC/jsXZS53ItONrdNsQNk= test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsUXXjApfYYCtRK2LrymKvcZpS4cf6agyOj1/VW48g1GVtJM4g5kOjHWRqqsQZJCb8R9CvChCsJp4LPOS3tC36dSS52loeMoti7Z3GtKORjPGKDO/byt7V68l02KZdaO6U91D73a7y9v0g+JsLtR4xkZMd1zXLK3NnT43rtLg116YBsLxAxbAC8eeC1xBF7MNzdLbmg8Gp9dA6iNnDlUhDsf2/FJ8a43WbU8inaNJh6eGd6NtL1fb9iDWho+JEhw7WbyoNrBAf4YlqO+3Y0oO1A4ezOspv3Vx8CkoZTrtyCzVCPEIV/3wSK40VQaMxt4ptbPwQK9mSUI2dG3kuzkxV test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCXX5GPy2zMByhViM5aW+lVH3oPVBVvsfXjb7Afy2ldttHHkDMhoQKMNUScBTdyLwHrje6c0C99aYNkSl5TLXePWx4nIkNFrEyhOfooY8CHPTuhCjfy+4A/psxeE5aoI5YGfffSr0uOVOUdhV3X3p1SmQsybzSiFz0THULrtirxoCbf5a1UGNafYoXPvtSS3/qGJnsnbxE/gL2mTEvOyLI7o3ffFIgbfOranbuow/HSboX/Uc9i2FsbJR4i6K5A6KB3NIL3gFJHxzjumJB4QXt7mUXzo0FWnOXLORFrzYd1Rf26AVcUc24wwStVAOtXO3EIr/AylwgsqWqoStOzoRFB test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdPnSRJDt/YuU5Oj1gq6JKYsJacWbgsdU+vpzAT7IiIVOoGB7oPi8EGcZSt1kIJBc9Lf70uRYCbCmq3v3EOLGpSdhV16oKQygSgSZawq2YwYHzHnonp6akLfQQXwE/nnubX3S6iYAaJSrJ50APhKfQXYsz4CH2alrzYb9Y2TDl4hKfxYABgMza3O02BFooK2tbxy2+0fbOKB/qjamGVE/CoMcv4ChB9FDGdUr0AVy7BYtfELAZ1dPrUh7lMCXa6JRRhFtdRWQGKmfM1nH/KpuzB+yZsl8kfHf47qiX/mwTQM87JMxm7HuV8pHHr7DNFs9g30CreF+hbY1Cx+IKh+eR test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCPJDCMNOM7Huv+NNeP626Slq54aPceMLEaoqlfvLJiQf11b8jXcKfFgLlp/f0Ltk10p+5hAGlzBw/nlYRU85i7Eq75kSb6LPcQ3SNY1/NkrNcZcFf4p/AKeC0s1qgbypvjWy7Zk8AUooPFrhIo/kKaPMouq4hcyENz2VKgpdJ21SzTxjDASj7zd9DZP8uc1Lsg3ftbr8Mi+MFFQRnFPLv/w2zIoLo6xwO0UplUIyAGAsRPDdRZQ50h9b5BFyFLnXUlwI/Jrpgs2J31Vg8J2j2Y3BFDgn/Mf/P9Rsvdo4fp/y+W195198VQ2gsH2+Az+3Id6ySsGhztBP5Pl2Z2K5Pt test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCo/5qxk4V6ZZGDFHDeVBr7ayBkc85+7SPuuY2OnBSrObqo06lw3nlH8dcloRzCt7qYvbmWTutlTujgSOJuvd3A= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJ3Mot6VLEkkG5HscBLY3geI20FnwrgQi2wzAKiktPDhF39ZavVlOMzvkIGgQDxmo8WoQllY52ed4e8+7KQ76M= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCDseBAbWBVvO3A6gqqd2+Qm9uSTBPEFvvj/huI35w7iYhMmIjWAYwi9av867hF9GsRJaPGSkoWUIcA6QBXarAM= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKIrHi0RIW1gbd9+rJLTPJ5qAyXzNjEHidpxBzRnN22jDcnvBjqnAtfWPBjazs2KHSn/RP+KtyejY1Q+mMikDDk= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBCTReLXxPo93rpl1xlrrx7yYZgD0DzRieTvFO9C3a8Z8blHuZHNy2iljsIYeCPOtK9lcivx+faOrp5FdE2VDroGPdDY2ZAuwF4/UxBiGNNEXWBhRFkupBcM6RbyjvCXaA== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBRylqfIuL/Bzq92j3g4UHd3TOlU2aG1U/2W76hrf1svwNPNe5d81xXA6j7Uh+AxOYfYrJRQr9KotRvd8WcxbikMZs5O/dKG+xx8WmTcgvu+jVW4lCbZrZk4S7/hqIlVjw== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPATBzcVXx8g+unFg+8RAEvjiY/ZSb98vuIQ6MAtFCkNU2zgUHI9m/Jn9FitFd/F7KlIh4G5/wMB2dGhks/FYSk+OxgAmhjif6lKLfD5veRCLhRnVbhTQm1fOmU0Sy+FSA== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGxZq9s9JfIvKluYcWj/f+OuiV0bJ9RLE8rT+8qF0syMvzZZVRqLmF+a9VxJ4uxxRVvmMQ1CXb5TGtLVdBv1SrviKWMoaBw/sosSMr8v3eoQ04f4bs32fx8/dN4JQbCZEg== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACuthNYwDJn4I/b0fdhJdD3ykWe5gMBS91H9qWt0NHh4QTYxVyu3npbLveRVr9AWoF36UYIVF0Z3WjFV4u4fOPapQFNlGDf1DNn8aipy/5iUKY02z+AxnWIIjToN0IPPizMw3LApwmy0UaBSw7sZyfxNHD0Nu8wXsP8A6HG+Y01zSMAqg== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAEUP4llO/qJcKrD5gZ6L+8+JzEU5RLICud1jgVh+QgtuuAZQUztdee3GEPmR+C9Mv5cAHg138OCNcyRI1eukjFNDgAq3xeh0V6BwjZZur+v5zyTnXQASBwuI+iofZZqS0z8lsM48eIluTZuo3siTlv6uvFLs4ovN/cg67QyGIpsKusESQ== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAGIVlZVYKq71fKe0Uxj73A5WPmvTuohTARpvnJ0VB5zIHFEtHRuI7Qkn6pRGv8rbKDRKygv1kZc6rFZ2fgfhLxXcQHG1LwWM8x+XXoWMJM0C0kpCEErKd/tCZstQqg4v2JO0iG5+wmoZ90Cru912t24fhFGfVeFIbLN/xqznIm0dZTN/Q== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACcIEokqqdXr1cB4vJksHNPuIb4HhwaRqaCi22yZa1slGr5+KQhWc6TaRP2yEsXaskuwThVy5hNjfONP/uB5IMj6QCxnR3bA/knuB2n7YRFlbIICLmCxr6QI5bz271MxCB+ccJO1L8sSfEsS6IcxH7O3rYv7hDadwcY9t5VmsJ3t7A67w== test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINknjInRhIeQB0yCD/N+ilxpTNwD2OGA776pYHI8bOdZ test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFYLKsn61Pg/YYmumVe7oXik0o+Ca/P3vvN0Om3KCHqo test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHh90f1nUVIpoKQoYxtD66cTGgLZ33D3hCxVqS/N5R3u test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILhbcrIlE43dp+IlosYszkS0c4zpwC60ec1MRwZuxwvr test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnTDrr21+87QbcPF+2Ayh61ot/Jtf0c9yTy126ki8Um/UUEW6uy87s/9gpS0OHyoH3GO3WgsUoe/AA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnwdqOa0pIeeorEzsEY7kskGeyZfhpkYZtbA/iR5Nyp0cbPZnl9UFsfKQIYKJwPWwnim8BXTkEq6YA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADk5uIOJgx7OfFkbkRV43yMP37dcnIVemLPjlaH/WRKjLTwueFIgN5Mc4UYcIZtlbAaUhiiEvW7aYQA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADkVNtCwBIBWO41k+QYmuMromfii6QbjVKRxjxbTYGPDaw8u+gSCHAnqgaxi9qkc7HU0U01BJI5tJgA= test ssh-dss AAAAB3NzaC1kc3MAAAEBAM6Xy9zencF2KDhq1r0gTXBdA4AL5Rtg5GYd4tx6qlSxk3ZX634ude5bV8Io2UrsgvIDQHSfj+1J4sDpWnhMtT12KucddwAzLhb+/5gYEr1UCZtPn1WlsvOXrJ9pmAt/MB1KppyG38UX3QK6Z04oWspqHWJBfO0oquUUGx5Ua9JSneJCrzk++Sd1GkhjZElR51Hm7MKV9KZejn/tUZQK2FRjpfP50GsIlAs1v31OkY1glhgs90/6v7PyV1ljp27Nw1aNL+CxOjA/wYnFo+jE5+EsW81oT8C06n4yrcFySWFR96wOfb2fAuCl4K9Ma4jN+7J0RLMY1++KzCsAtppi4KMAAAAVAMbFE/Q0VL6xGj975l/7AqEVxWH7AAABAQCbU609B2d7d5EipWyjlETAs64vaKBXOAREcQr8HQfAkWmSUBr//brBdNWeA4TVla4hyKL1CBiP1Hi6pDQ12lCB+J30ikRqdi45y2MvOR8OfEDy3sn94sLwswARnMwdfHWrPepfyVdqOnIlhsYWzLpc5EhfOThvL8YZ78tPTCqyui8COi3TznOFfW/do0ydEEmfQwJTlHi6dpFiokh+mpQVOlstehmgKzrolLEjccS/vnxSqsdWDwKErbtg0bYhhV3rztiMcMozoBblgCSDiVmvGBAO8GnIoyX5/J+UfuwWYQKYrtuZRfB4hRyRU4zKopPfQrZkc1Jummk959KgfeTIAAABAQCayyiO1dYHPHF6g21swekxrukaXix6sab4m+OLm0bNRa+7nI3A09wG+otKajznna/mdjcIaWuhdG5S4+l+aPypIUWTdM0krUu0A+9Pu9YpIgVgEFKVQX9PBcP5+WHanMaeYmLOCEP1WqFMJ5HiRCJmssOKwZJygH/KEMIGaDGhYnSmN6R+41j8sDAoY9/00WlSTKqpmVGTe7bJGWomnhT08RsATIyvM2i/J13qrh5UfGprj6GsaE9q+Zjg47oMdZIRSgyp4jw9coQoR68TemOmkODmXaoixfrGT1FC9LbqOmN/iDwv0QvLUen3RTbbB2lE3LwObBXJRpd44RjeMo7c test ssh-dss AAAAB3NzaC1kc3MAAAEBALvd0uyCDZFuKcpphdcnMEYVXnoy16rW5XIFhlxmvVSUDDz3DAGyXISyhyQ43BhI8R0OeOr6VpivujFu0srXrcxcgsAy6yv/6uAvaeLfekc/JErS7OqVqACFmt5ISkEBcvWKnUseFRwoy2KCeiEo2GyKwyV00caLnYb1Th2CUNRFZcH5p5XLj3gwFbPf7EdkKV0PHWV4E5ptFVVT/aRijCJRQn//FlSNlG6iOfUF4IRUpz05qivVGaHLWNOw1fSXK1Pc53qQqCAaEict3arhQCwSEKl1xktSNBDVmeapLPj7LNcZIGvAA52Tpg3qR1rp/8a+bdtteNkbRg4Gfx2uBuMAAAAVAKFdLforDVztYQzh7pFjN8qAjogVAAABACTsvZOw0aPNwdQFiaQik1F08HQrjlp298vgbjIZFrgABE4xeuWMydEcxAKKEhy7Y9Go4l9shUddkHgk3Y+OLvAsifowqfc8Fpsqxh1WKLxnw9NO5rjenO+kNeiwhX/oWa1VBMOa/O+iGTvCy1XcW3u0E1LqGVAx3DdkP6EHV91ma3d1LWih/RR8ClERNaovnETash8NQCHAmKejIObneLtNRqyaiNohYK0t5EAtP4JutVwrsnj3ZoSKrCZct2wVrMUkkqCsKcKygCsr29uk1xpVYBkv9zUn6V199ZB/uXanRLcL/vq0UYWGV9nXU0shVanMwHNQaMk8oWnd6hTPB6EAAAEADwMN1uDvQqkyKel83xNG4Er3LsSCx6iARNWpaV1ZLNrtf2h6MnYCKdSdyVgRjIL5coBQB5yZb/+CXm9QgysH+K5FHXgnh4hjz8W8/Magj+qm3/SKDTmbLAsNvvvenQvayTWUGNQlfQET/tHvGRy7gz4r95phWGmxS8Zu1NkT0RHl6xxcSqWmvvjG/m2MuNo+5lfKFa2+j+Is59HwN3ZK5umpPlJl4uM5SkyFD+iUbptOVCXdVV4xRhIzYy4wllADQQHkbNQtNGJT7JEHuot92J3FWOCEQVw4F06j8NsdghKWIwGSlcHLHAbA8zZDq11R6vnhOFDwmfekxCwLXaBlGQ== test ssh-dss AAAAB3NzaC1kc3MAAAEBAOGfXe0SXEr7JIMEZQo6rkTc6CfPIWsgqDYem72p84pn6KykGD6RonyqDEfDoS0XpwIY2sCZLmwauEhTQtBZpMyix4sD49w+SjaHUP1aoAT7iPFvsXXGNw9/jgK5a67NzWxmcl5XMQG/VDjtVLWzNfl9OXHMSNmGUKQmlPZKXRrm06SYVZMDsRbgSJgi6PNOatuVvfR+b2hK+ppMpQNKnHXe/vpgcblZ1ViPUTH4vG+04PkidIbwHIIl5Yv69lUYOcycxR3yzd8ZC3a7qzVkxet+tGWCD4/PzfWEP+/G2TWXbRuxV6YEaq9POmI0JuZa7CAZ8iA/OFtYua3TB4cUsSsAAAAVAJzJoUVy/fnPi6UuPLR8cCyhqB3HAAABAQDH61jRVXoAqKJRHgIWhBsrQMmAvOqVHyrALSlAchNT5cso4e7Rd9ajJFg+hVZGKu5PoQdhp/8ERk8mnABKue6r9qO/6qT8NvCRuI0Wb8Sxgw5q/4hzo4BVdx4UhLqTRl9rF7B5wLSjV75HIsqW61ZcbT9+VdYpRaNg8/Te1jfqwgrTndaD7jhkhU2P0Z7vHSRlzaeSksF6b+SRFu+bnQ6neBxZZTuMrSfKOSpp2ltLUvWrQ48GJ0I/uE1HbQehz9Tn0Q3VA2BjpfKgj8bLE5YFokveuqjFULF7EiL4CmAt6qhiQOl/f6zKR4gaLUjkVuvU/uyTr/da7/FfOJouETpFAAABAERldAO0JWHLr1nClDX+ZPN8XbbpjSaWO+fFLQO0A7QE/2gKJ8lt5qi39GOOhmUO10johHaOupqRqe4iCRnBxMJeLxXmS2KbcwDke+IBRaid81ccocpcPOrpov582DjJuwZ0394Akyrc7uMonjBy+JJaPwpXHQS4SXRe7NybuEE4S+DsV6DNx9WG5n5PFh4YELbzdP2oJZ3hyZ2MiZgo02ShziEDPI1vQ4BBAsknp6Ubzt40Gt1yjyNMbGpv8IIRZzu+H8CIRnzbCYKT8mRKe0HvTG48c6la0/wvvG62zfmbFYgkw0tQxgekpf3ojNpRJZ1vcQPgtvQ5IjkCYSF/ss4= test ssh-dss AAAAB3NzaC1kc3MAAAEBAIYJqKE0jtG+HpbHurIu+kVIuQLrMrgXhL7woINHOHGfb/0O85u+3DsSy+s7f/M9bWUIqRtt2+JV2J/V28mDgF7IEeiP3OjSYspmoxnCy8d6g313NcYYoCqG9f/yWrzSXQtK3hD8+KNqm68GQx2L6lceyyHn3CgUFTwHw0MNntOfAk94PCoM5wOZCfqx9sZfTVk+uQb++aG8xcAqPoPQdTgaqrFa9lrp2Ul8RhM/eDpCmByg8I5tIsbk17IVzS0gLp9slfInhwr2UjX2wIOlVOnNmS8UHLAwhDtdtHcWYdFbEMpO9hFMJCz39JqnJ7g8qjct/bfMxAEqhwlGpgbYrz0AAAAVAL66GQDORVX2on1ic6drzCN/9f4ZAAABAA8eU3kzUacUj50ggFzpTLuBBztILvjIpNGnXy7SUG5EWCZXLvBPTjJf9idxL/0P42AlJqKpaZSsdDLeaPbyUsQ0B9R+eTVDKQd5po5kBmWcxqMJh0f1XU1CYFZgN2cvzmtyx9euekEka/j1mqGLuXHRpX0vak/wsy3T8mEPlqLr09c6hPUDG5U8NXEy3aWS5gRRj7wPDLAi1sFGo4ReUfjn6LJglbCi71tSirnV0dJJvVGpXA17RzetDgZmIjdDur6XdGz+6B07puj/OUTTCFSFzJC0wNKGS/OjY9+59ziFj+M7LCA7HUAlYeL4n83EsZp4fHI09JyuLJppPo/4xxAAAAEAU2ThrVHZ3fT8JuXT4dgJVtgoBTQVf1vbzKA/o5yrOCKj+pPLFv+mXSJxLWvdSUeHkaRZF76hCwSpy6K+Wt9sRSuL6qTPog8TT7Yhk0YgfMd/wXwYlhhoH6HqRIIQRHd1bIOn+n1DUWQHS2w6Ksd6jnVDd5cte+sBRNFeNjRJPUg2dzFqYQUgf5bfDu6/mhISduez7BctGb0cWtVPyjzQivJRUVnLiUJJE3V0saEC2FYOalknyW2x99tolUn4YwOLjUuQm1oKZ+BEbXlgGe4pKe/JxB3nYHT78wP7ArnhImPGK8b0+/JD4nAA15GEkFLRV/u9qyZJe/iwbpqKz2vB/Q== test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCclEvT+gGh6exRwmgPhsN+PLMpcNltztLQ1x8iKOsxCCbXWXRxfvvG/ye8lp4kEOWIZ1224UoG1401aNBVTGNUT7SVyAFSdnHG7AGgFnLwJcxrsEHLX/f+gj/m4syNJfAg1PrS4O8IeaEnTdql9x4cYkzd+Jpa/OHZLgltc8SHezhmxrc5Ylm1IMHu6gxJb0WwQ1mIZ44IAIaYvNflal7dP8v//bY+6kvS5iARk6hDfiR/wH3926r7U0pB3siNDdz5yq7rjvTg6igtOhQDSnd9Drp0yHjBCyQoiDqP1P2jhyfz1iDdf6u71CFhZK20rfbsUUHCjWilB00onvjjIDYJ test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCMTxeJiE+rerxDpf3UhJRVvaWulraY8VZryHhSPnHCODQw3MsQ0X6ECmTs8c3YeNRBRhiaB6zOQorUFqFbAwO2XIFQgDGk9qSJF1kwsVXKnReFqUQ4MQGjRt5odjHc4+00KnmfdLUubvLGJmzHYJ4Ia1+EEyzkUik4nVTxdreXrvFEIEej/QHJlhVSqsL2oKXKVMLAJ6OvGt9K1pFSJRCyedHVmR/z3tfsiFqpw0R2P2WhhkK9jXG47tJcG9v5HPrGJqd3D+W982/YUFNFvLMVkq5qU4wEDFVh1u7Z95dABtZm2TwzhrYfxdAIcYbZLpbFozWX+f2mEQRAbWws2YE7 test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyu2eTD/3HRZnFhKMiy7YLGW7WUsT1uEgRCUufHFbjwZqSdUMXplB7wD5g/iombD36oZtFGpZWjiReT8hh2k2dR5pzF7Hg9yTZosuBu8YRSTjwicc/NHTcDfl5kQFSGz40azFXWn1xJqPRQesDGZ2rQVloCxW771AVS5hZvAybtM/qf6En7PxHJE4Eg7klvjH2bzhacDQch56u/ij+/ipwtqkWt40k6sMQ7xtRIQH4AUNlqQ+3qpZxKfAl+NCbJ/V8Mj9BM3WuyeD6DYPwBT1mHXug9KWi7aii2c/UvDv1xpF7u0mTRSW4Dkm7FTEbX8iPP1QF3ze87YEaF1qRkeMf test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCnTnSVyVw7nyqnxy/WWUUuFswXUsdwvNtojMVuqltV3CTDHfX6+uMu+XBC6Gqr/AzHvwzOPvzR+/k+m5fV5zLvjfe3zTU1gs5EmOtu3YbOnn6il/IvVvU9ILq/5Dg89aIbSYG9R28iu8KciZxHOOpjgFpmoCiMAg8x4OWRHc6irKj5VKTXMJC+5pmb4QZlSKal7KPqKyAsKII6IxMjpPNJejZm/Omw3QZ19YIN02ttbM8rwoLuPLi1DoZiAUvF7J3XTEUcDAn5y5upltk1Dx+bWhuth/sYZ26qksxPr+KmtHwJ5R8pWJ4CXtENlwxQiAWftVWW8MeQlyN17qPW+Z9x test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLoiF7se+l2KwZh9oxhfTASh5diPDNvYbVgS98Q4yPE9uExiDDMeX2Nu9XLtnevuTWrmcAF6u6/ozI3BIkeHiBQ= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGrSiZUMuXa3aTNDF/H+rTZb4wUBapMIf9QXzfoJI6hOYPcCtHGH8KChdeZ2U9W3ohzX/WZIX8IQ9fpxcGyvpbc= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDMTBUib+twute16i5Rs2zKlVDMam5/RMWuFcXs2dvIs0kLP5N06diHYHBqvMPT9N336KMChz0/O4S/dXR1pwHE= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMQNLejYwJxwVlAGIVi55Lb0zfkz18CEAwqDtrr6xs2sz+vqRU1xadOgEzHeWovBqCXdC9wVja202PyupH5QPsg= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBnR7wyGL+IOT7A7vKr4Do1OGlsMhBFN28GuKUohpkd5rvvZfe/9UNbdobFa38KmLWpxzAlL9Go3AK6+7OpWz6HE8JHdrJGyRYoS87XVv4oIIzmp8B8GThUYiDt8Qh8FmA== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGdfKrIhLUFtiMfBOFdF1LulPAF3OKNqlahGbA0bf/LXPf7tmbJUs+GvozsqYAbsMhed1vmwfBwpaQdIG97JRSK4MK4yIrCjDjGwqmakX/hg/WUQZPi17463t9zSzFZ8xA== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNShRribjCP+pkCkAMwdj2LjxNrZjIKHtylcTdohEgfHJTXzub4tbq6odNS3izPwgMEfX6M6Vl5NBIstk3c34+kDuJ/a+Cyn7lZ9HZPdDuaKE66PNp3zGK9linfzn3iFBA== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBKGDqZyyEHaKkg0ijDH9nRu86AiXmUNJcKWC05ksthEMheDRMyZtyqzIIwQI9Goum+Tktu3LeQS4fBh9aNHwMP2xN5uvj/uUYxN1dmQmLQ4NsQhpz+DY5TtxHJ/tUKvNpA== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADwW+/zw0OOBYVS2jEOym6OctYKqb1/uSTegImb7XOcklV6HZSnkGDrp89gzXL6AgoFWMQkySgR93l1j22kCwxGWQFQBLalq5ekPGpqBiE31QNot0QKPat2f4O8bw0DO5sUNPmH7ImKmyxAjHGiCPhi5egoIgrgzHoGnx1ynMr32Pntkg== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAGCln1Y+fp/uQTIVhjoNHuuRGVSzHc8shdMTGUQz0q+TpDSEf+SViws/gS0+V73QggV5TcUqOIOra4uD8mGSieuUwHea4ieXw+cbcts9lpYdjWkFmgSGwYfIVyosFZ+aE07We7fNRqSUpH5gyBpdSpFKAiBTwtv73FOIwz88I82E4HVQw== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAA37JVxrRSMTbtG8SUUuPzzwjsrumeJD+100IbXoAcXK0mPbGei04TdyMTpfy1SDWL3YND5CSzcuHMOjApNKrxJ6wB8A5LE178vFKb7kvYo5SJq+YAbv7utQqlMH4sdKdywGwvdSTSZXCu+mzx9ebdoyRsmPS7vBrJYKcQPHiBDa9iVMA== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAKniAtk8UOBIVa/348YbbZAyiLgJKpbH+2rEB0tHG7YYf+fAAGAZJsE7K7bl68XzunBT1HguytUpcjzNgOS2hx2AAVJT1ObdU0IK8+B0DTXrntG8BMKpDjpHZJr/RQLEDljHt6kc355TLoKZygF7vUujNjceWFjSmBlFeCbr5Fl4KoXw== test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFrJ3kAPWlhD8uR/Mo1dqhqtJIYACuH6vIh7/oP+r8UY test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINnWA1NU5+6rlguJ4vDwB7Ro3wTO+ntaSPfmWIXjp384 test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGGj5a3dN4+iyqsAXenA/CzejFmBNyZinnYHhXXcjbBV test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEy7J6rEkUafMJmtqE8SpWZg/uYx6EcME5FH3E3HB3rR test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADkhFs87N5abAoXAcsLiYTDOCujVJngP6C9j5dSttY/EBgCQBMK60a0vt1lF7b7Drby5kqg7+IvkGgA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADldNmjRx57BM40rrc4DabuF0L+RhEkOcDC8/jAhtbdTO0X+sqgITai5gSk1JGlIrCRIF83Kvs0TKIA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADkVoUhABT+RHfYEGAMKySSyUSoJFj6HHcz87U+io4Dpe4ye88DGUU2Lnxfux/WQq61DPHWxQHo4GoA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADkdO1HUptQ2ksEmblqqTM8loY2Q/Ep003qRxW753XVaz8eh9CejJvTO2FYtyHNib5syBD814By7C4A= test ssh-dss AAAAB3NzaC1kc3MAAACBAOGamTQ4i4AEWhMGssPosXwsaLBWIsldlycRQEfRCRlmi0hzdmYvuJJn+YQ2Jf1QJ49jTTxlCuFJLrDct+UxpittxRtDb+AdDpmhGp/zMeNdPBsfeLX9REfANyveQrfT9hqZ2gIbMOzJ0wRPgInmSRi22A0It7vxGaw47J5bAEf/AAAAFQD/Q9R8eCV6qL7aQr4E4aNOzZ5JdwAAAIAaUAApSPx+S6f+H49ml7sHdAQC4lVyKVQVh0RG55/rsIrd/dSYgo6LZ522vzNgxw2BmBeFJUpNZkQzIGmxN2FkTmlSgOxZkRH2oZA2j04vcskJgIiN8K1rhrpRUtJjcKXnF9YRn0eR4o1xph74ySPmIWX12GULB4R1j4nysqDmbwAAAIBL1zviIOohyjKKILovL9rPlTLHlcdXkyd5S3PZImq3CXDY5mQFlxH8r/hEnwMBBTAHmun7ptcdH/R5kZVB6v7xsAdJXDYiYOyoLI8yL4aWbjs3flriPXVmCb0hCh4n6pSKVR5IHLzsABABlJTULxSkvWcKwMms7arQm46WR6MPlQ== test ssh-dss AAAAB3NzaC1kc3MAAACBAMui93cyTI7R14Prqeet0joIvIWWGSw09hk6qDZvgKW2zzs5X1BTScrnLMnaKOgYtwDbFN4OQsBLNZu+PzcAqfwJBeTD4mGLRVk1k1zK6jXpdPr3V1sqQP7OEVa6MF6XsIf/Yu3zFvqpwkoNnrCcSrZxLMnnW83Ya6NG5d7WGBw/AAAAFQCHbVl3CZvAlhbRo/yMAY4do6Gg3QAAAIBb2u2D16qhuFq8B8UjBt1HSo7R/KPjRI0YzrCpJNoYjB743wARQMl5yDU67IuiIAzjxFZBiK5u+mTKpuO1v7MeTc9IFQ3ObR6N9PO1wUAZ1uv0KSesnxjgbZNIHwGwzJ88T43LEbugZleVEifbbIZl7puEgQdFko9zEgqGhOu3VQAAAIBKDmTnJZliffrAxCElJnnrM2SLo+Dl/cdtCDdI+3RBG7wTPWqMF8C9VNC5ssbi8QLDwl+OPrSIERPb3VXtjkVxQna36JK3od0aSx90VZkv7RPeL1Gt6Q/F+Td6D7p5ZCGjHaQkEk4kfPjTUnLxKn5FGxmY1HV7ceXo17AElmfmyg== test ssh-dss AAAAB3NzaC1kc3MAAACBALDWcFnpSWiwGbuyqVzo3ieAm2K9+BIUYjPlA69UCM1GulxzCj9ImbQDvMsuQ3tKpMH6925NoGU5G/atRnqXouJFNcOi43kqtHx8tE1vV9v8im3+gGsOF97pVgtBMHNQr8sjDN0FrtB5MvLMc9c5b/1lhrUj5PeupHIJzrhvAvsHAAAAFQCeztLdFSYoOE+Nq/XDQh0BuuuM+wAAAIEAh8p4L7O0vUW76jSJvE3v/yPG8bcBpZporUTvG2DqKP/rISyRblRoYlwmlaTzyrC0/HrUOqw/1fiyorr+KoxJVhOavlKVq/YSGpxmrgt4eS+VXr5BJyRGxDaPF4kTAu+2/FVMu4D1clK8BuR++phu9DWN32sWAzw2IYwOfhB0b+0AAACBAIUb/bDKE9DAGpG+zMyida0JTIIPHqWvkSa2dUXU9J+4iV+Bws+X3bEggZDeeDAKd9FmFTujek25ihIJD7tOu/CCFWEcUZ46aff/RQ5bfCKsJ2SyoSRvFGGal3541YvgK5A3DgzRjEGhlF5KfJ7HIcAdTq5CYA8uDBZngA8oeQfz test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCOSYk6+5VS4tJqK2Z095cPYHjlUT4Gqm2MM5xdzM2nK9bd4slUyz8fFYpWAIvu1G6Q5z9e/2Kfcme86lCjN/lidSNHQBpz6xW2WQTuTPfSPW2lBblRovlezhypdHTdMt1NB7B499py1BF1iLO5Y8URPCztTXawneMnUjvUp8g6dDKVDGNBssgwZ3TR8Fj/vrOkgafwtJAl/X4CJBXdt45dLre5eRXEoWDxTdW/GxUw/PtV/mW4Psheo3/RoIFequh2m7U8uSdXKvGqm0ZlpSTSoen7uELSd+9iY3E4ULdm03Pom/O3WO+DOCmRb5YUTNFKZUVop3DKizjEggy9mbb5W2iJp+6K31YWGWHCR/HhFr/61R6yQomXzHhbqAEGH1FsBmpRDa6c7a/b8Xl4w4kbBlOOs21G+tvL9l3hYqBfWpPE8A72WGdkzaOltvt9TEDroNI2yopNWTVXuUvJ2maFqiwf/4cYpGZqu3V4ccBpTJbhHQ3G3w5XVQ6Np42ez8= test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDIUGLfSbG/8i18Y53PL59UJ71RN4XTKJEvVljZM9K0HvFkc0wOlzTOXoOAEJiTIq6JXVWjq31BJoC/x20ySmaj6hSOs6NGrnyxXzSbM4E+PzJo74avh+NXZ6ojD3CKg7XuShgX5+PUqEiAffK3TdzRX4NlkIfiIaHi1O+Q5drSGwnoB1C5sNeimLDhO9IPo699OvQu1Obh06gygWh5pnu0NBuiv7rWwBx9S80fJvqhAQATxv2RWFDqcvn/T0WApJs5FCpyLxKozTpOenB9OGaEEz3mpg6H4KPL6UwhyC7YLr3rRKyjff08uELvdQzsO8q6tO8uOaQngLFhLe5lrlV test ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCszdi6vvJvN331KkQI2SVEtrwBHQunxWGfMP3HnSn4aH656Mcx/9a33V/W5KwKoSgVeRsHVnbjby10yP1PaU898hILUDFBazlJUyfxvMybiP6TC6LMomCFqoncaNJ+hR2BsEQmrIfmD+cvIFADz8zPtjDeOSAPQumP42C5uXJKNKYM8nmpCUrHo8qSvbVLTX/UC8mZweenxY21IxnKSZkkuLkRtqp7+p+xc6bYNfXcdb6LyrR/jmD2GsnEXSmWFPxvYGAErUZBSAMF2xYGG34l+lCB7Pzvpfv/mB0MK46YL+pdKC/B3JjDu2izt7cEBTlhd/TwzNah5OfsXtVJBNlYi9FU/Ee7A6+ylb5WnNasU165ngIVBBL5UNg8Hg/W6XJJmAVZg1PsRbikNNszKeaRrTC3X35PEr6uab5hlcORcAWV2FYoYWN8iIv0rFJyaE7InpxSHp/G3lE6XHddcJrq6BdmURez3jShrCYg7DdnE9Nx7dBX1rbJ46lLxKY5lQs= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGwG9ZwJjv29NIb0Cx1QsCboiidCStHoza+zQQMvs9nCBMRnABQL9ecKQeUGClj22ll8qRg6vWbHrQn8+ZUCgZg= test ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKjOhkR/tN6oSku7uJXEqDZh3HsYFeCi6F1rnDR1roSpLy2HQYGLPjalt+E+sQhayJBOLJd8j2idjIRNK9trrYA= test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDTDzvrOOKrQoRhWJCf5ZyYk2ugd2wAayLt13XYBPJHArsgwCKMktyW6+dmKmskqnVDEPqQ42RBO0kcJ78y+3l2i1iNXr5dDSkJ/2J28L4YxzEOU6HhVn8wBA0wPYNpsgw== test ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGYBJ8F7NOBihGiGXVBApYIXiLlNVW+SSYANC3okjqsax5eFcwyfQBRSWSJxAXKA1aV5vtYMN/nBwvg5kEgftHi3L3Pye4VA1PKyoa73E4T7AsAJ1eRrJp31ecSXi1f9HQ== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABdYMYEOU8AxcsHYPdHwtbndVLfJZsCFFQ8oMUt+xHi/MwISVkojGjk2FOtUeUnsc8SWXHEUC6GDSqy25+42GsxWQGL7/IyR2X0Iu9rUooKrKg4EsvQNEDfq9Joj7zuWOmAQBQK392fbXdYYILjSAaG5at9mhiw8Kr65ShK2IUv4n4dnA== test ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACWNfRwfrfQb+K8d5+VutrDWme+Pk6UyiDvbuS48bCg3e9ptaWHQVtQ6xm1yLYUeF/ZVWn20+s2DntLGKX8dFCaSwEHVmX4oj6hx2V5zprevf3GShfyz+HXt4qzoPzVMyOPY/po4d5oxM1RM7oWaqNwvuVhU9Zk5MbJSzKq3atWJv/+AQ== test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINKulAsCNhbGFNT4DlsMmQt57Y1/i40T2EWpeUWjiDL6 test ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2oQIAotMhMO8LyWecYBIXFlxSFRoxm8A0Hpbn1mEOJ test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlrhnFj5z0wgxD0IY7ECoZE3/8v9cUWP7VJnyp0YPY0aLKBLnagj5/GMDV71bYW56Tl7AFx3EQvxYA= test ssh-ed448 AAAACXNzaC1lZDQ0OAAAADn6JKamPkXumrMxQnui53u1e7U0WkROtrmraifd6LEDfbEW78xEmNPSVZARg0ydaeNYzc+iEGG/cYA= test mwiede-jsch-c8efa3f/src/test/resources/docker/dropbear_rsa_host_key000066400000000000000000000014461465436372100260340ustar00rootroot00000000000000ssh-rsaFR"&ra?M^7HXV7/-9M4ZL$II^43LLjA;nvv ҤLWI C6npR)lakOAwnׂ{ \''mXx mԣN9^Eʗ/tgLiO%&gh8PDէs{~@-|j8*4XamQ_ rD"fE,Ma ;K4̏F_JMi2ojx% IQ!k9(oS2D +UR#eMOG{ZKӍV[f}) $Xʍ)zEAka'XyώyKeJ#:Mk50[zɨجzb鄑Œ/jcS|p#FL#Wv0'68S1oˋ ÀN>z@'G ?UVXҁU;dWKqJSSh^- Ҹ;eC;Xr Rm6.Z;DH6O$G2xZZg-8.)B97^Q| DžnScc etQH,qREY@%I;'}-I&P@!`Ѧ x^%>Zk5M=25ZE5>@Z~"ZP\rRQl`wԒ_DA)cymwiede-jsch-c8efa3f/src/test/resources/docker/id_dsa000066400000000000000000000012341465436372100227020ustar00rootroot00000000000000-----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQCgkM8QhCDO8m+X20priQs//r+NFhG1C8eCSglwW+85kbQ7cHga lCVwzNWzI0OFcBgdRJHzGSUEe6z6zgMX3THQqZKoD0dPsZZY2S1Wq0iR8LdSkfRL nVI1HQ9maz5bz5RtbAMrzFUyuSgsdkGktgZ/4LpMa70+w5GqghR4Nj+6ywIVAIX6 bQHXZfGEXU/7eEXeS0aZ9inLAoGAV/ms3n9U1/dBcEu78p4Aq3SbDmKlrY9c0PDJ a8K1i9I3W43CBv9L3KtcfOC04LPoQD8pQwQhhiWv7XfPJCeoyFHlonm0VBtMxB/C zPp3oUAOTuk7hFd1NA4O9yNDG9OGczdhqmKlvisB3YmlOTPF0L91fzwpmPHe0eVn DCigwnECgYEAmy0FgQoaWyHdD84b7zD0YjziMsVELAbGWwdxNuNe6wtACcctCdIQ igQYaC2HwGjlDKVMjQfd4RWArshg7p0PlEw7//HSgoVhwcBbDpmWGCS6TxSSQpDm dDgiVegERMYjo2BZoZQTuJIx/BhQggVISkELwZfsi1BnPC5Aecq7ILICFE+sM/BQ 4c0QZhjod9UaZk7O2icH -----END DSA PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_dsa.pub000066400000000000000000000011221465436372100234630ustar00rootroot00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAKCQzxCEIM7yb5fbSmuJCz/+v40WEbULx4JKCXBb7zmRtDtweBqUJXDM1bMjQ4VwGB1EkfMZJQR7rPrOAxfdMdCpkqgPR0+xlljZLVarSJHwt1KR9EudUjUdD2ZrPlvPlG1sAyvMVTK5KCx2QaS2Bn/gukxrvT7DkaqCFHg2P7rLAAAAFQCF+m0B12XxhF1P+3hF3ktGmfYpywAAAIBX+azef1TX90FwS7vyngCrdJsOYqWtj1zQ8MlrwrWL0jdbjcIG/0vcq1x84LTgs+hAPylDBCGGJa/td88kJ6jIUeWiebRUG0zEH8LM+nehQA5O6TuEV3U0Dg73I0Mb04ZzN2GqYqW+KwHdiaU5M8XQv3V/PCmY8d7R5WcMKKDCcQAAAIEAmy0FgQoaWyHdD84b7zD0YjziMsVELAbGWwdxNuNe6wtACcctCdIQigQYaC2HwGjlDKVMjQfd4RWArshg7p0PlEw7//HSgoVhwcBbDpmWGCS6TxSSQpDmdDgiVegERMYjo2BZoZQTuJIx/BhQggVISkELwZfsi1BnPC5Aecq7ILI= test mwiede-jsch-c8efa3f/src/test/resources/docker/id_ecdsa256000066400000000000000000000003431465436372100234470ustar00rootroot00000000000000-----BEGIN EC PRIVATE KEY----- MHcCAQEEIGO2c0qkiVbPaFdw2b7jABHbSmnWp8K3LGq9UOTQ9HcdoAoGCCqGSM49 AwEHoUQDQgAEFwsdIALHTKvVL3Ta+VFGdcDXZilpcg6RlReg0VvTX4LFAGAalVMR Uy5qQukhb9dwP2W275zoLOTlacEoSgc24g== -----END EC PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_ecdsa256.pub000066400000000000000000000002461465436372100242360ustar00rootroot00000000000000ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBcLHSACx0yr1S902vlRRnXA12YpaXIOkZUXoNFb01+CxQBgGpVTEVMuakLpIW/XcD9ltu+c6Czk5WnBKEoHNuI= test mwiede-jsch-c8efa3f/src/test/resources/docker/id_ecdsa384000066400000000000000000000004401465436372100234470ustar00rootroot00000000000000-----BEGIN EC PRIVATE KEY----- MIGkAgEBBDAltVKtxP2QrTdQJa3REnwY3hMd8qT9iz5w4l0fmG534ktEcDI4lTVA rE+vgI/LN5ugBwYFK4EEACKhZANiAAT83mb5BwU6Y59ShkdGXltZghCYaS9E47zt 53ovtes1Ies9w+q7NPa0m88M/aLw8xndEhzdb03mp5vfOxG5KYo+KCJcqc9w+sUl l0GU0MCsQdCZzqXHHXguxcXC5hxRXnI= -----END EC PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_ecdsa384.pub000066400000000000000000000003221465436372100242330ustar00rootroot00000000000000ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPzeZvkHBTpjn1KGR0ZeW1mCEJhpL0TjvO3nei+16zUh6z3D6rs09rSbzwz9ovDzGd0SHN1vTeanm987Ebkpij4oIlypz3D6xSWXQZTQwKxB0JnOpccdeC7FxcLmHFFecg== test mwiede-jsch-c8efa3f/src/test/resources/docker/id_ecdsa521000066400000000000000000000005551465436372100234470ustar00rootroot00000000000000-----BEGIN EC PRIVATE KEY----- MIHcAgEBBEIBe/WgCLfCZlZnwZ04GQOkIW4i0az4cizRHXV0PvVyqUceJnMPNDXE nJeKsmYdfzAbB3llyY5f2SILMuEYRXzIdR+gBwYFK4EEACOhgYkDgYYABAG3XTlA FoQd4iIBt5KoTHJk46v1AdZSd+wfCSpc2/GCzHNGVqidrKCrypszpkQOW6vYG8ri ilyfF36rJa9ipjR+5gDApLIe/ix1Fknr8MU6nWoYv2+NBTsEcaS/VTeiUuMKftMt lO2wOaWFcbZBQUAlb3LDnpMyYKCqIXhhl4vqCxBukg== -----END EC PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_ecdsa521.pub000066400000000000000000000004021465436372100242230ustar00rootroot00000000000000ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAG3XTlAFoQd4iIBt5KoTHJk46v1AdZSd+wfCSpc2/GCzHNGVqidrKCrypszpkQOW6vYG8riilyfF36rJa9ipjR+5gDApLIe/ix1Fknr8MU6nWoYv2+NBTsEcaS/VTeiUuMKftMtlO2wOaWFcbZBQUAlb3LDnpMyYKCqIXhhl4vqCxBukg== test mwiede-jsch-c8efa3f/src/test/resources/docker/id_ed25519000066400000000000000000000006031465436372100231300ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACBK5E3Zr9BkFjspG8YSXVPA8/AqjEXQkugWTe61YG+kHgAAAIjbWs6021rO tAAAAAtzc2gtZWQyNTUxOQAAACBK5E3Zr9BkFjspG8YSXVPA8/AqjEXQkugWTe61YG+kHg AAAEBIs55uel1B0GufLAbr1fLpT5/trE3ONzFutHRmQgbTE0rkTdmv0GQWOykbxhJdU8Dz 8CqMRdCS6BZN7rVgb6QeAAAABHRlc3QB -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_ed25519.pub000066400000000000000000000001261465436372100237150ustar00rootroot00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIErkTdmv0GQWOykbxhJdU8Dz8CqMRdCS6BZN7rVgb6Qe test mwiede-jsch-c8efa3f/src/test/resources/docker/id_ed448000066400000000000000000000010051465436372100227570ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlzc2gtZW Q0NDgAAAA5fXBTYHhyi4d3D4Y69kKZwGCDecNY5puAByL8/K/V3C8ZffsKx9CQhxlzQnSk OEs/9dcDHNXlelkAAAAA0G1DR+ptQ0fqAAAACXNzaC1lZDQ0OAAAADl9cFNgeHKLh3cPhj r2QpnAYIN5w1jmm4AHIvz8r9XcLxl9+wrH0JCHGXNCdKQ4Sz/11wMc1eV6WQAAAAByxh+E aQEVBsa+DYaC8NvVcVQuch3GAITIqyweByuntdsKU/UYVIgFyWG+LIsMkKsRYHXpetH3Mt JhfXBTYHhyi4d3D4Y69kKZwGCDecNY5puAByL8/K/V3C8ZffsKx9CQhxlzQnSkOEs/9dcD HNXlelkAAAAABHRlc3Q= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_ed448.pub000066400000000000000000000001641465436372100235510ustar00rootroot00000000000000ssh-ed448 AAAACXNzaC1lZDQ0OAAAADl9cFNgeHKLh3cPhjr2QpnAYIN5w1jmm4AHIvz8r9XcLxl9+wrH0JCHGXNCdKQ4Sz/11wMc1eV6WQA= test mwiede-jsch-c8efa3f/src/test/resources/docker/id_rsa000066400000000000000000000032131465436372100227170ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAxBOSyJnaWR8EnFpvNYFoEKNlqnjJikzSBm1n4RcDID9mEgbd B57kO/xWvPEuVK5e7nzsCZfHwu7Opvsox59TWIAjPPBLQJJQQKImcyWquLpb7mbG 4vq9vO8MQie/89M2tPfUZA+Ws1zgrqQ/j2JRrQzjTsTmh0wd/KEKYvJBTincYLri d6Fi/4LIFG5Bvbpno07X6cUVfEy6lymC869EmdSvgV0xu92Hv1PS4rT2joKTNc1D /MbuJ9liGugIYZ6MN/+0aWn+wlv+HT4c6iDZQS3rdWyJTZTVQtVhTzQ1e/QAH+RY 4ioaXB+21L6I03N0ilCMg8w5XNeNF+xHm8zfiQIDAQABAoIBAFcia6SB2qqoQiBJ gApDC7/5HQD41HeFVABPNk6tL1JxWibArhDo53xQ0yr78x7mroFFOo+4x6k0/tjt 3F15zEwUBZTbJFX5r3hJltSs9IVLK/dx7QiJbTA8+zGbAI6WWkVprRUaaFok+CQk EarignFovMsQbXHKvbi6yCbYiXT2FUhzI9sk1y6wedAAW9Bgw7AHwI8bq5pSlnmH o58PprKi0tCeWCW+zuCSJeKoGwbYTMq5Glx7lqiLdi28xe/FctAfiQI4bLWtl8Aw vm0UWBK9IHP0K0U2iErNs1l80Kc6av1PVIZTVLaRJfrLMRO+k/HGSndUlGhpl1ds QB29axECgYEA9w+Fc3WeY5aBKZP8v4Mmn9+OIgfMYzxgoQuCpXGgLmi5r5of/COc 4+94XZ82o/s2InUKPLPwuox5dbRrbqp21dSpDtpFNKTEhHA+4Q8Vm7OMg7k+1NMj lckUiDp7jqAqSGSfDyPU0hPS7ztFsfu3dDpSXHFfLR+Putuub31a5aMCgYEAyyvL dWwMVG5jiQzIdgWWB622XkYj61T/v0nrT8obsZQ1SVuAx7gL2/fKPkQt3JZvCoQq G6nTd3buKClsSgDAG72S1Kh7QeMiskSIQ7coBr8yD4JVuVF3Ej+CxYoDfRaMahDC aAlvqSqtyAWdKSBgw4SJmFehFkBSaBQOqd2zwOMCgYEAjGXypZFyqA9waStjF4Y1 XecSA37BBKfcFcjPvqsapyT2WLdSc9vdHZ8JnNKMn5VzxxMR9TsgkzKfF2enIaWX kJ6gUAN0Dp2P299ZrFYBJpFbScPs088EyusRUvVBH+UfAjLEPTtUhumjFjZtvd5Y +6DlCwmWV7M2365Vq5/mFtcCgYBKJrbAKWoqmotrZqX3JTzHmqf3qmPLrR8WQrVG Tr5ixnPYTTQoMEzrwHko1ptiaeknDmuL4ySR8m8ja1Lhg3qZ5Uukn8U0m+B67bZJ +Jv8MmXj8S62TzxFBbcFv8RcMBGZWHqLm/4L4M7CNQJSE0Ydtc6+MiVRyLIK2F8t sgO7/wKBgEIXdAzaOBmw0Qk5BJTI5areYjQw7lFE7gi7EvjHmhZr/JjSg9fkVk4O lNskEfC6DZKcE3KV3mDIi0xzsz+D5nIj1n+b/6Hd5rFwxpWoassA0BIP+6U/AyYc TQxZKRN4RkFLYRMNegx71RRnyvNyU1dcam9J3wgVtlBz24QkEPZX -----END RSA PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/id_rsa.pub000066400000000000000000000006021465436372100235030ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEE5LImdpZHwScWm81gWgQo2WqeMmKTNIGbWfhFwMgP2YSBt0HnuQ7/Fa88S5Url7ufOwJl8fC7s6m+yjHn1NYgCM88EtAklBAoiZzJaq4ulvuZsbi+r287wxCJ7/z0za099RkD5azXOCupD+PYlGtDONOxOaHTB38oQpi8kFOKdxguuJ3oWL/gsgUbkG9umejTtfpxRV8TLqXKYLzr0SZ1K+BXTG73Ye/U9LitPaOgpM1zUP8xu4n2WIa6Ahhnow3/7Rpaf7CW/4dPhzqINlBLet1bIlNlNVC1WFPNDV79AAf5FjiKhpcH7bUvojTc3SKUIyDzDlc140X7EebzN+J test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_dsa_key000066400000000000000000000025351465436372100250150ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH NzAAAAgQDCpmmcLJT1hPN8L/jn5faGjHjkdN2JNHMg3OX0gII3qV2UEebKbNChTkUbnyOn S0B2OFy6Mj3Px69K2vr2P5fqdtHCVY0NO6KLD1P3dni3Weuq3Y1wsqyT4xY5zSbbppwZyW alhjmyrKZ1pO97zzn5UXshqVBXudTxdbrLq97gywAAABUAt3UpcWWVTW76oyaYPP6EjLht u/0AAACBAKZHd5omFXPwpdUMHasCJyI28tchjQnxbGQCxgWHOu5ZHeZRgXTZS/n4IvgcAu lF7uTgKlgf2/TrbyUfDUXDO+1dudiBEeLfebdmXRuujNU+atWjlS/3oT2RR39KD1xyS3LM m86ihQLUI+YRG568CWFtH1ovOwvSwKaZcz01WEIpAAAAgFBLubRZiJs8kLFATDf49Rlggk lc5430R5HhsMeZKAtA9oit5jKYZxfWr7KF9j626BGxqsuvSTwnpCkIjz1sXEEU0ahUv8kp BAieZSdsya1tcIYy0BCWzqu1prrEjC/VFwqTUsAqoScT2MeWvD6u5a6wT9tY0/2fwOJuHO MDJC16AAAB4Pd1QNz3dUDcAAAAB3NzaC1kc3MAAACBAMKmaZwslPWE83wv+Ofl9oaMeOR0 3Yk0cyDc5fSAgjepXZQR5sps0KFORRufI6dLQHY4XLoyPc/Hr0ra+vY/l+p20cJVjQ07oo sPU/d2eLdZ66rdjXCyrJPjFjnNJtumnBnJZqWGObKspnWk73vPOflReyGpUFe51PF1usur 3uDLAAAAFQC3dSlxZZVNbvqjJpg8/oSMuG27/QAAAIEApkd3miYVc/Cl1QwdqwInIjby1y GNCfFsZALGBYc67lkd5lGBdNlL+fgi+BwC6UXu5OAqWB/b9OtvJR8NRcM77V252IER4t95 t2ZdG66M1T5q1aOVL/ehPZFHf0oPXHJLcsybzqKFAtQj5hEbnrwJYW0fWi87C9LApplzPT VYQikAAACAUEu5tFmImzyQsUBMN/j1GWCCSVznjfRHkeGwx5koC0D2iK3mMphnF9avsoX2 PrboEbGqy69JPCekKQiPPWxcQRTRqFS/ySkECJ5lJ2zJrW1whjLQEJbOq7WmusSML9UXCp NSwCqhJxPYx5a8Pq7lrrBP21jT/Z/A4m4c4wMkLXoAAAAUSIVjC6KPZkvx3kYnCstVPm2t cIoAAAAEdGVzdAECAwQFBg== -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_dsa_key.pub000066400000000000000000000011221465436372100255710ustar00rootroot00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAMKmaZwslPWE83wv+Ofl9oaMeOR03Yk0cyDc5fSAgjepXZQR5sps0KFORRufI6dLQHY4XLoyPc/Hr0ra+vY/l+p20cJVjQ07oosPU/d2eLdZ66rdjXCyrJPjFjnNJtumnBnJZqWGObKspnWk73vPOflReyGpUFe51PF1usur3uDLAAAAFQC3dSlxZZVNbvqjJpg8/oSMuG27/QAAAIEApkd3miYVc/Cl1QwdqwInIjby1yGNCfFsZALGBYc67lkd5lGBdNlL+fgi+BwC6UXu5OAqWB/b9OtvJR8NRcM77V252IER4t95t2ZdG66M1T5q1aOVL/ehPZFHf0oPXHJLcsybzqKFAtQj5hEbnrwJYW0fWi87C9LApplzPTVYQikAAACAUEu5tFmImzyQsUBMN/j1GWCCSVznjfRHkeGwx5koC0D2iK3mMphnF9avsoX2PrboEbGqy69JPCekKQiPPWxcQRTRqFS/ySkECJ5lJ2zJrW1whjLQEJbOq7WmusSML9UXCpNSwCqhJxPYx5a8Pq7lrrBP21jT/Z/A4m4c4wMkLXo= test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ecdsa256_key000066400000000000000000000007541465436372100255630ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS 1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQRBjCCZXp9C/mW469FH4UxlLNTVyk1q sZi7h8Iy1yuRw9pLW7v8FiKlg+H3X2f25x9rPBWbtj8OfDzNGu2ab6BsAAAAoLQlxre0Jc a3AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEGMIJlen0L+Zbjr 0UfhTGUs1NXKTWqxmLuHwjLXK5HD2ktbu/wWIqWD4fdfZ/bnH2s8FZu2Pw58PM0a7ZpvoG wAAAAhALqL7wU3p+D026Wt1/hUKAL0xMloZFq6/hk4qm1LbCmgAAAABHRlc3QBAgM= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ecdsa256_key.pub000066400000000000000000000002461465436372100263440ustar00rootroot00000000000000ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEGMIJlen0L+Zbjr0UfhTGUs1NXKTWqxmLuHwjLXK5HD2ktbu/wWIqWD4fdfZ/bnH2s8FZu2Pw58PM0a7ZpvoGw= test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ecdsa384_key000066400000000000000000000011321465436372100255540ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS 1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQTysr4V/90N9hBIWSherPnxM30MGm7E qV4BSdi8KRsShccxNo8ODb8HvVt2Gz8q2VOitjDAO6e2XScHQz/7UPXYbbThhkpHmvQquH XHYAvXHQbkOGhm/HK5mN2ecHNXT8UAAADQ/hL8wv4S/MIAAAATZWNkc2Etc2hhMi1uaXN0 cDM4NAAAAAhuaXN0cDM4NAAAAGEE8rK+Ff/dDfYQSFkoXqz58TN9DBpuxKleAUnYvCkbEo XHMTaPDg2/B71bdhs/KtlTorYwwDuntl0nB0M/+1D12G204YZKR5r0Krh1x2AL1x0G5Dho ZvxyuZjdnnBzV0/FAAAAMQChI2+z1qVCRLNqJg9SPkA1YgSR3KrNTegm0FN+lRRTlj+bgl AAum+tBb9q85G8M1oAAAAEdGVzdAECAw== -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ecdsa384_key.pub000066400000000000000000000003221465436372100263410ustar00rootroot00000000000000ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPKyvhX/3Q32EEhZKF6s+fEzfQwabsSpXgFJ2LwpGxKFxzE2jw4Nvwe9W3YbPyrZU6K2MMA7p7ZdJwdDP/tQ9dhttOGGSkea9Cq4dcdgC9cdBuQ4aGb8crmY3Z5wc1dPxQ== test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ecdsa521_key000066400000000000000000000013241465436372100255500ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS 1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBIZioCmuFbhvZP6IiBlGTCysCBida 8CoRx2f5uGRoWlm7wQKXgz5Eo/FhtLs+KPi50Bw/4va81oka+bHdu6rhxKwBxc8y21FKEb yqVYxhClrfuclqCvZJI/7IYuEb+VDosGUa+3XB1/uS/X39SqZMbBlA/ZqunVUlbbVOAaco MOTz+bcAAAEIhI9q7oSPau4AAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ AAAIUEASGYqAprhW4b2T+iIgZRkwsrAgYnWvAqEcdn+bhkaFpZu8ECl4M+RKPxYbS7Pij4 udAcP+L2vNaJGvmx3buq4cSsAcXPMttRShG8qlWMYQpa37nJagr2SSP+yGLhG/lQ6LBlGv t1wdf7kv19/UqmTGwZQP2arp1VJW21TgGnKDDk8/m3AAAAQgF8ZZM2aCmx9w1sEKrJVR0f aoGPQYtuCFU3gHbBpbHDMzW7bmDZz/TVieEGY/Bv5JNpx6e9DjsNEr5LBCZYUlt87gAAAA R0ZXN0AQIDBAUG -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ecdsa521_key.pub000066400000000000000000000004021465436372100263310ustar00rootroot00000000000000ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAEhmKgKa4VuG9k/oiIGUZMLKwIGJ1rwKhHHZ/m4ZGhaWbvBApeDPkSj8WG0uz4o+LnQHD/i9rzWiRr5sd27quHErAHFzzLbUUoRvKpVjGEKWt+5yWoK9kkj/shi4Rv5UOiwZRr7dcHX+5L9ff1KpkxsGUD9mq6dVSVttU4Bpygw5PP5tw== test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ed25519_key000066400000000000000000000006031465436372100252360ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACBCPG6z5518A6IFxDrio2t6uZgQhgS2JHlkccUT7R204gAAAIgS2Q3NEtkN zQAAAAtzc2gtZWQyNTUxOQAAACBCPG6z5518A6IFxDrio2t6uZgQhgS2JHlkccUT7R204g AAAECdJnXoCSUoYHzHlcXkSeaH0GYzMhD88yjppCIIJZnd40I8brPnnXwDogXEOuKja3q5 mBCGBLYkeWRxxRPtHbTiAAAABHRlc3QB -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ed25519_key.pub000066400000000000000000000001261465436372100260230ustar00rootroot00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEI8brPnnXwDogXEOuKja3q5mBCGBLYkeWRxxRPtHbTi test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ed448_key000066400000000000000000000010051465436372100250650ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAAAlzc2gtZW Q0NDgAAAA57hSdc570vS9YNRSe4cSTdxaEcvWEnreS89JtkrkMhAzqeDVPVgkAJUvUWhQU 8Au9wO7pDscv++QAAAAA0Of4PPrn+Dz6AAAACXNzaC1lZDQ0OAAAADnuFJ1znvS9L1g1FJ 7hxJN3FoRy9YSet5Lz0m2SuQyEDOp4NU9WCQAlS9RaFBTwC73A7ukOxy/75AAAAABy9ryb m32A5PqfyePV4/Aml56Bj2P7cIu3PsKTXdpnDYTaMyaLhaoJ76GBfAaD6sEluVsl/oY2xM 8F7hSdc570vS9YNRSe4cSTdxaEcvWEnreS89JtkrkMhAzqeDVPVgkAJUvUWhQU8Au9wO7p Dscv++QAAAAABHRlc3Q= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_ed448_key.pub000066400000000000000000000001641465436372100256570ustar00rootroot00000000000000ssh-ed448 AAAACXNzaC1lZDQ0OAAAADnuFJ1znvS9L1g1FJ7hxJN3FoRy9YSet5Lz0m2SuQyEDOp4NU9WCQAlS9RaFBTwC73A7ukOxy/75AA= test mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_rsa_key000066400000000000000000000034231465436372100250300ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn NhAAAAAwEAAQAAAQEAprpGUpEiJnJhP00IXv6S/wcd2TcBSFhW3TcvLc45Tfk0sa1a2+5M h/+LJElJXjQG/DOvTEyk4qLKaqtBO252dtYfDNKkAkxXEZzeSZOjC0M2lhxuHc9wUils3/ cCYZxrhU9Bd24SBteC7HsMXCcn9m1YeKQJbfaztKu+/xzUo+NOOV71E9jPy8LzRevKl5cv dGcbG0xpsum90E+8JSZnaK04UETU1adzGKu1+qCW+OkFsXt+QN0t1HzihwcPats43RuFAR OFKpI06li8iLvgYRviusvP321RoF/y9bIMcsz4RCKPvmZF488fLE1h9wyBO9/IwUu6NP68 +cyPwkZfGQAAA8CLb3Z8i292fAAAAAdzc2gtcnNhAAABAQCmukZSkSImcmE/TQhe/pL/Bx 3ZNwFIWFbdNy8tzjlN+TSxrVrb7kyH/4skSUleNAb8M69MTKTiospqq0E7bnZ21h8M0qQC TFcRnN5Jk6MLQzaWHG4dz3BSKWzf9wJhnGuFT0F3bhIG14LsewxcJyf2bVh4pAlt9rO0q7 7/HNSj4045XvUT2M/LwvNF68qXly90ZxsbTGmy6b3QT7wlJmdorThQRNTVp3MYq7X6oJb4 6QWxe35A3S3UfOKHBw9q2zjdG4UBE4UqkjTqWLyIu+BhG+K6y8/fbVGgX/L1sgxyzPhEIo ++ZkXjzx8sTWH3DIE738jBS7o0/rz5zI/CRl8ZAAAAAwEAAQAAAQEAoUqCzU1p5BeyzDIR bxSHz/9qeMAllX8gSVEhawadmTkEKP6zbx/RGZ+1U50yRNfACitV4lIjELy7ZQXXTU9Hex 8ZWqZL041Wjctbn4IbsMGNBRrrzBrpZhJ9KQ0kWJmhyo0poAfzmHrURUGka2HV3ydY9xx5 os+OebHMS6/wZbnoD4CAtMwWzAhKI8wWOk1rNbcAMFt6yajYrOG6egBiv+mEkcWS/BS2jd vXL2pjU758/gJw3xqcI87Y77dG/oXF90wjmbtXdjAZJxg2OFMxvM1vy4sMucOAqJSkTreR PtoVeqjKQCeVR6wMlKP1t730wvScovMWP1VWhliftrHSgQAAAIA0FlTE7isLTUuAaoSWhR ilWfv9ta4R4Q/jbrhUuKIesHzIeVlB1YG0D1tncp6ZDPnlA+yF1IROEcbyxhK3aHAd/5DZ 7B8Csdj9wzo+D55hPt5E1y9wZnf/E9KtYIb8OHT0B+e1z7W3+rRecc3MIKCQVM2j0MlJwj 9dkvzuCDSO5gAAAIEA0+6HmMGF/+xVO2RXsOXiS+fAuX9x8tkOwQjQSqGIU+W+U2hesC3x ytEgFtK4xh+OpDtl2hdD5aMG2jtYBwCHcgxSbbjLNi5an4A7nKhE1Eg2TyRHBDJ4Wpyn/V pnvR0tOC7F9/4pQjmxm4Y39F5RfBUNw8eFbrKAU2NjCoeJBvUAAACBAMlldN5RsLvxAUj4 EYYscVJFWUAlSYI7r6CpJ999gC1JtSag/FDnQCEEYMzRpo2R3AqUrXgYXgaHJf/GA4KPrr DkzgWGPlq8vmsZ3jWdTT0ylLQ1ulpF8TU+4EDsWtEZ8n4iWrtQAshcCLGtclJRbGB31JKw pF9E8UH4Kf0TY3kVAAAABHRlc3QBAgMEBQY= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/docker/ssh_host_rsa_key.pub000066400000000000000000000006021465436372100256110ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCmukZSkSImcmE/TQhe/pL/Bx3ZNwFIWFbdNy8tzjlN+TSxrVrb7kyH/4skSUleNAb8M69MTKTiospqq0E7bnZ21h8M0qQCTFcRnN5Jk6MLQzaWHG4dz3BSKWzf9wJhnGuFT0F3bhIG14LsewxcJyf2bVh4pAlt9rO0q77/HNSj4045XvUT2M/LwvNF68qXly90ZxsbTGmy6b3QT7wlJmdorThQRNTVp3MYq7X6oJb46QWxe35A3S3UfOKHBw9q2zjdG4UBE4UqkjTqWLyIu+BhG+K6y8/fbVGgX/L1sgxyzPhEIo++ZkXjzx8sTWH3DIE738jBS7o0/rz5zI/CRl8Z test mwiede-jsch-c8efa3f/src/test/resources/docker/sshd_config000066400000000000000000000031241465436372100237450ustar00rootroot00000000000000ChallengeResponseAuthentication no HostbasedAuthentication no PasswordAuthentication no PubkeyAuthentication yes AuthenticationMethods publickey PubkeyAcceptedKeyTypes ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss UseDNS no PrintMotd no PermitRootLogin yes Subsystem sftp internal-sftp HostKey /etc/ssh/ssh_host_ecdsa256_key HostKey /etc/ssh/ssh_host_ecdsa384_key HostKey /etc/ssh/ssh_host_ecdsa521_key HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 HostKeyAlgorithms ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-cbc,blowfish-cbc,arcfour,arcfour256,arcfour128,rijndael-cbc@lysator.liu.se,cast128-cbc MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1,hmac-sha1-96-etm@openssh.com,hmac-sha1-96,hmac-md5-etm@openssh.com,hmac-md5,hmac-md5-96-etm@openssh.com,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-ripemd160-etm@openssh.com LogLevel DEBUG3 mwiede-jsch-c8efa3f/src/test/resources/docker/sshd_config.ExtInfoInAuthIT000066400000000000000000000030421465436372100266650ustar00rootroot00000000000000ChallengeResponseAuthentication no HostbasedAuthentication no PasswordAuthentication no PubkeyAuthentication yes AuthenticationMethods publickey PubkeyAcceptedAlgorithms ssh-ed25519 UseDNS no PrintMotd no PermitRootLogin yes Subsystem sftp internal-sftp HostKey /etc/ssh/ssh_host_ecdsa256_key HostKey /etc/ssh/ssh_host_ecdsa384_key HostKey /etc/ssh/ssh_host_ecdsa521_key HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 HostKeyAlgorithms ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1,hmac-sha1-96-etm@openssh.com,hmac-sha1-96,hmac-md5-etm@openssh.com,hmac-md5,hmac-md5-96-etm@openssh.com,hmac-md5-96 LogLevel DEBUG3 Match User rsa PubkeyAcceptedAlgorithms rsa-sha2-512,rsa-sha2-256,ssh-rsa Match User ecdsa PubkeyAcceptedAlgorithms ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256 mwiede-jsch-c8efa3f/src/test/resources/docker/sshd_config.openssh96000066400000000000000000000027241465436372100256070ustar00rootroot00000000000000ChallengeResponseAuthentication no HostbasedAuthentication no PasswordAuthentication no PubkeyAuthentication yes AuthenticationMethods publickey PubkeyAcceptedAlgorithms ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss UseDNS no PrintMotd no PermitRootLogin yes Subsystem sftp internal-sftp HostKey /etc/ssh/ssh_host_ecdsa256_key HostKey /etc/ssh/ssh_host_ecdsa384_key HostKey /etc/ssh/ssh_host_ecdsa521_key HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 HostKeyAlgorithms ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-sha1,hmac-sha1-96-etm@openssh.com,hmac-sha1-96,hmac-md5-etm@openssh.com,hmac-md5,hmac-md5-96-etm@openssh.com,hmac-md5-96 LogLevel DEBUG3 mwiede-jsch-c8efa3f/src/test/resources/encrypted_issue_369_rsa_opensshv1000066400000000000000000000052061465436372100266740ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCd+5LZfU vM8no5y5XUnD99AAAAEAAAAAEAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQC96PvllVEO gtQdHnaoga3gi8md+/lUwBG0SOv4co9QaJ2kvJZDTiSLmJc4euEuciiplvzKpKSWSVqaZL boXiVVt8MnPmIwIlp8bhIqJ+0431FNWWq6RA/4EszHiARxMIwUqw+svN2GMm5fGr+PK3FR 6mXGjiVlv4/5Vb0BCUjgB0vIqq123DmKpxrT6S3Ik5vYCCn0zKtuWxfxp3hpCqC2TdqD7/ rFTX/AstmlhTO4FRDEK/7JNBSWY8+9/rQS/c/HSSW7qMGEoGFkELKSYFSdwLcyAMS1HySz NR1SuyBLDsOSaN5iWm5cBqKIK175Uc3Xe3fIn6+C5ld0m/nN75bw6QJiDH7I2jMYDTBpDq ztBiqdjcSwvNTogGQg/oJLC7aAz+E5gfkTsg/Q6bPf6quyPIQ+KKH5v2YVFQIw2Te0X7/O ZACsqUnCbGiDXCixPTTGoRypcR0MQDJxR497y7zvO4kiqQpsdBoELuhWSW8+9BcovL4/jS yqUEGvGYoh/QMAAAWQCCm+hXX3/lj0BTGT+TRll0G/c21MVlKHmh4pSbWuWcVsNYf0Xk9T AzQL2Aw2iIlCR0nZAb6fbeWkO7FcZwdUWgEH+qhUE5jnzsrGs8dVbuMQcCo//PRK5wPqGu z1Na6IUSvuvVUk+t+spmVLOjbgKVmXD8NMz3yRrlb92bP/u10OWvHS2lQf8L4qyG0SCbsR +mfKuuhquOvL+0hqeMwaMjcIeIDqF7XM3lYStliF8atc0KiyX3jNh3xzHZof791WmXgz6f kHa0vpY/Ds84hkT0CKa7q7v08V2RXisdwfqs36sMMJDTSJbF8f72mSrX3ZiTDCRVzxxa7K JOt6eKJMBlobsJvDq9cE1paypIiThIwdrcVKTtdk9QjWiVzalF5xrvYAO5rM9jt1RMvEHi 8uAuAz4rOqGlnNU3ruxTtyynAIk+Ao+TFxRwUfX053oJGCvvUgpQvIhK1PPTAJQxKL299C Hsid01jDXujRCKURcFcBkjczHMV/Y35tBhRm31E5oQofONaejPLyna5RoKlfmw7feOqh1U GhJPl0kX0RcOG4WafyXjDP8a4mlkukka2HxoVnI4DTo5rvNNifa1VN27jDcVJG9EoC4KdQ Jn9jwrQtGgpYUC2Mw1yz8IImIjhzaOwuofuEa8XpSCDWN9EIF1+QNRFb8e8s8PkYG2qB3T abxXFrZlXjG5xOpv2Nx5FfjLpzRXWNzyjy3boxJ2DMamcKoHsWV0FZe0dyoSWz0pVQc55Z LcVH3pFM/mfyv5S3bEsoQsDHIoJJ1yAOHoAAKzKj8J6xqvXa6j71JIce68cIYx3Qrs3W92 xrOAjVlE6M476C4lPJdNBxTdkClvgdnulzv56BYNAoBWtbuymZiwB1TZetSGDsDSdtD2rX wNGHHdUceau+OEh+rsZpmFzBfN0ezyogzy+5FFVrlKFrcUnIlPm+1cgEncLES9AZttwkjx HzUxdBgm7rq1sCB22Kld6dN5akRXGFC2DpU3t91XPw1lavTqudGC3ovMFfoFrfJPy95eVt yAA73aHS93t0xZTxCkXff6sP0E2C/ztq38LP2SpvT7SZa250DLD+v3pdRgz5wYUNlnTlH/ wvRdqHkEnQWwcOyoO33E/iZS/u88EjfMDMu3JbS/LR+0S7iZS5MSh8O3KUtNR51/qhP/Em Q6v4R/2+odWi7yr0PrCsuyURaq44o12unHE2pzHmas5mN48+agF6thTUmiMR0csoMs/yEW TeAbdPTEjxNc3cxvrMmnWhVCLFDNYRScq+O/PEWsPN7ofoYagUUM+TbgGGs7kWOOcyo/oN gxMowxWX3sraUevHEpl8Fgbapl18W/ppNd1eIT965SiI2cHPzUW6aTPYW6y6BKOBHhX3np EPf7ApjnUhuHF8Brvikgtu2eHoAA9gKFs/X7sOD8KWIhsV5tIr6psCqalOA4QGdMsmZuaW GCIfeaCsMM/HcTJZzj8OBBpLAOC0/lSs8Y9qRqDK8Aid12Tp9FrtJKlvt5DsnsR8an4zsJ e4k9sN7Z+bxVxKyhQulc16hSSUBJTQdCJ3fbdlyklTgx45maL8Q/bQhYlQ2y/EBIASwOwq Gq5gJw1RNm2CaLBP/tjD+qCjIZ4DsPuHsdv1a51BGiTjt9YqV/eqXdZ+Npz89jFQw7WGc8 AStzRvxNE7fIAZgK3LtlNNDpgEX0+g6VCPfiPrl8cvz003x1SMtSMYftPjbvuKosJaMu4K g3t7vdQjTObNpuJMOcuTKiY3pJDBbNAcF1OKbzGpTF25zspvzHou60BKt1mQD4ktuSkh9k IfwiPacrs5zA3S680z93Pt17M11tfMXgYpN7z34DCzdj5COdwo7Ei9Et3dxdv/Nzj83kxh KmpEq3lxqRzHG2mb2h1zHQW3RR0= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/encrypted_issue_369_rsa_opensshv1.pub000066400000000000000000000010571465436372100274610ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC96PvllVEOgtQdHnaoga3gi8md+/lUwBG0SOv4co9QaJ2kvJZDTiSLmJc4euEuciiplvzKpKSWSVqaZLboXiVVt8MnPmIwIlp8bhIqJ+0431FNWWq6RA/4EszHiARxMIwUqw+svN2GMm5fGr+PK3FR6mXGjiVlv4/5Vb0BCUjgB0vIqq123DmKpxrT6S3Ik5vYCCn0zKtuWxfxp3hpCqC2TdqD7/rFTX/AstmlhTO4FRDEK/7JNBSWY8+9/rQS/c/HSSW7qMGEoGFkELKSYFSdwLcyAMS1HySzNR1SuyBLDsOSaN5iWm5cBqKIK175Uc3Xe3fIn6+C5ld0m/nN75bw6QJiDH7I2jMYDTBpDqztBiqdjcSwvNTogGQg/oJLC7aAz+E5gfkTsg/Q6bPf6quyPIQ+KKH5v2YVFQIw2Te0X7/OZACsqUnCbGiDXCixPTTGoRypcR0MQDJxR497y7zvO4kiqQpsdBoELuhWSW8+9BcovL4/jSyqUEGvGYoh/QM= test mwiede-jsch-c8efa3f/src/test/resources/encrypted_issue_369_rsa_pem000066400000000000000000000050341465436372100255260ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,D5AFEF41BADEB0A6ADDCC294C4C34402 BgIiIqe5ABrapndv+KDz2EoUj/QWtEJ81cCVLBJT05GTA93ZPYmwFOOHzwDtZN2n 36qqSkiytcPcF4onogR50qziz/k3cN38Eiiqyrm1kOrIkxaCUogy0I2vQvDSYr8v CuW7btHpHpv8TlbWWNO2OGawH3ZYplNZoU8lPkHrGd8s0SdwHWjGm5pvKtbNRMjP G8UYgBO4259oCRKpXbJJK2J7cH44itedZeiHPhh2gukqyFIaiu5m8ZG8X+sCnxw3 DYYdm9C24uaC55Pfh7DTaGdvKXlprR816FUnqqF30Len+JegHbT3EG68PYsakIwr O2h/jJo7Io61/w5lzoFoGrh2MJ73sHpsLk+ytQIghfUEHc1pBZnI9YcHhiHqEhUb GZH/knfhR/V+OjFL8eXD+Mv6RHilxe22Dma0kk45B9rtAHa7wCtkRpQPBerUQ/Rz uD39LPc5hS9tdvMVVZHJRCx10B+yvRo+CutuTpyZo27Hr5EtamGCgKU8BIr5EYaH FkRAMy7Q+27kiXgD0H+DViyZZQ1gM09gxItQuw/E4tjjaAqsy/xnZtGdmKARqqZe 3oPXIv/bmLWrO9c2Hq8xFB5iJYRrzgmmt03RPMyrQLPw8gfbGVrehn1F9F5TLfdc J2Ao2K+Bv7bTTh7OunwGXF/UmAphvREcH2yhB4VOr04R54z8Vo81x8kRJtTlbP1g fsYHRK/BSG3R8pTge7MJwWLYW4lyGyNQ1G3NWbhsafbC2sBxm43uP1sO32SR7moe t4Um+DzxNeVx1zaSuw0XSc/W87F5GuXKpYRmeaKo/EkC3LLKI2UFK/5iv9m3//Jn 6XPMA1jfiavN/hZwKTHImCdHP7uqEn0VwfmoNnSovZUcVikuPjToRPoxOYblPed4 RDmsT1DrEO3zRiZ4wY/al1/Qs5ivojoAzwpuJDbG9C9H4B82gDvXcqAr8LeJS2gZ 9w3hD+8XJJMf3wA112RaoDJn7xzJC/fTmyq5tiS0pMkGP0bH9RVAVTVPoKLjs70m oW81L/3Z6FK7t+6vDonQITZqal79jU7HNwb0Jelv95kT4jUtkzeLjLGgsBGRGBqg ACAwFqMKqAZAmqCI2aai8ky054aNSi0CCEN+kQEs29BRzs7/+RdlPUZCQKeY9siT 5htrC1g8xn+F/HudIzcue6Vg0KmONCn/PjJbSjK5lyQc3PN8W6Fa6POJRZgHpkR/ vfN+IJlh9vmU7CqZcT08SZDp/2x/eIq58yoBCBDwu46vr477+Vc25rSpl1Wt+9sj PZ5WKLqHmPy8vBmG5nOv1p3OKHv/AL7LvhvBk/B33oK7mDI0HhGaHDmMyPrikI1n DcStuKhNgtZxV6V5YLVfbGI92Q6bggyN9eslb2AMcPg3Jusw1wQHKtGBYTveQC3I zakD00bl6eyR8L8GM7NQFlBWO6QAQRAjwbrop9uixrXFqJ+kcsJ2EXikhHOKpW8B 3uhmGkIokzbCy2SLy8ErzBPNea58vc4kI+CJEFANsrhOhrkIw+9+MVz6XnOUafb7 mk4k9Vu+EdAT8zwFpdo4oDH3gO6Y7E6fzFvCWblXmy34xf2C2G7uxl2jHJFbqPxY 3sCcKfFMOZACsdiq4SqtgilzLvnyxf6QY704hIS4Tl6QpLVxshIDHVNW6TUJ7qwg I1fDyFWFponmtV0pS28yYAEM7Eb4aoUvXWEeQh6PE+CPB/s/6UQ++IgM0INAt4kn LIljwtHAcWtKvoWup4CHelnBpdEqzWjWbiopW1/166m6/BFNJKarUNZtuuj3vorU rAi/pwNxQ9a32pNW9ox0ir/C04Aqb2Jj58BD+X/dw2PbfilHPNraOJqdiMn8802S 2Vlj8R3VpbeETBc8J4zRibV0ZL2TsNRlBPXAaCVJhBgqUdYGAeaLqioK3hdQqHA0 y/c+DsjFwODP+jtfVYHTgKIeAS4BnUt/3TwfzdSC7CgdZztk9aPc9bhQrFM1rdZN olV2k2nTHLtflLPvQWckL5W0vBYqELjwBCJ4fUG3aNRwoml00uYWWtliOA7qABW7 dkX4Xx0iUwql00tEiugxHHOgC2S5cDmSeC2+emGFb8ca55nrxIkCJWG0wOm+/gtH UDBHmgxD01dk4QFG5wF77AAIBXWuFcYVLp9wzgAIhnEqGbYy5+hzoCxYTjjIpUv5 MA5A1z2Yc9n0Qvu08swzO9YvrRpQPy/3Ys2nVhLF8MSI6qn20o/sDYy8DAum4GIr RaVuIIo7cnqkDGXjnVTtganrRfdS0YzUh7jkoxN0us9YBMKyJnNNIDMEJW5SOU2i t2qluYBIdfEdvB/LWOgJt0YDQUtk0ed7RCQqauBKDPWLvZ+Q8j4DOdZgW8makCS1 -----END RSA PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/encrypted_issue_369_rsa_pem.pub000066400000000000000000000010571465436372100263140ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqGObM6DyGcra+/eBdm7mIvnLM9oUDUwpT3hRbF7S7V6bb64EuFlduGXJKK+i4/a/ls1Sm3GVwnWvwuRxrVXgv1497MYDzDcflfm+bQLUN38qNscVhn3jdtFuCTIc7VKmtEd9zn4HVzQhUYWq/oiqwOsDeP1QidWbNwgBthCxzhfdi9XUpdpT3Tm/mtLwEz8KZ2kP9VdfXBql6NI64COcI+B2nzE2YwxZsLGFj1orstRZ3WOLTJdLtQ1NhBQqTEwFD06Jhf50wo13xV84jWeZom+ylJQcj9njnfH8Kf7T+1eyBAqCPLvS6kM5Q9J6bGPj67Hkp96zPT/y3Gh1le80o3JrYjo20NqWzO+/OIXilrDoYdUKJbgoM7GXtMlxFNEnj7BIf6TLNZJY9bA6dw1yFs9wOl9LRhC1zUC6kESx8DIiqSpxrZTF0ScgvC/gKqX6K81ovJBklrAuTQpTqGKOW2eY5jqiRAVa7Gx8sPPtHkGqodD/sFOKurggVDf2Y1vs= test mwiede-jsch-c8efa3f/src/test/resources/encrypted_openssh_private_key_dsa000066400000000000000000000026321465436372100272000ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBtwRvhD+ SsnQUTeW/8JbaXAAAAEAAAAAEAAAGxAAAAB3NzaC1kc3MAAACBAPmIBCP1AA8EiTL0VAdz au+1KuRmPkg+H2du4zt4ifhzEx4MscZ7cpBsUAM/EBC/ECWTHzDiWyFFuenvxDlfTi9Xxy SdOKM6XGLkY7oLsY1y5bShyLrycxDD7MRQ8HpUc9TPzE2PDH4Od6o98e+vdXP0+IDUZGbS uwEnaABX/1+ZAAAAFQDIB9KUd1/gnzM4s4FXCQb7zCnjVwAAAIBptrE9g/ooRnh4bOWiA3 /StxbjMRmA9f9bJbM55CinL4yf/GdGmeBp6YjDBxDyk1oXmVJ2hLVXgW6kETbt+D01SouC TgLPlFwLFhqZQ+A4JQOKuLIBaM92hI7sAfTewkxbmAk/e1vyOeyfcQDhbncESzVBZrheXC 1fTKv7O2PgbgAAAIBKhGEiNwKNA/pfYvkEbX90/jVoIEKZfqTk+PB2gbVMT98LWPaexrDw EGuCCK3KOtMncDai+0r1ujf1hzNJ4z43Z1n15tPvAIwQsObTL+eUQkVjHA8LXOq8n4yYyP idkjGzWcfBAm4Lm6vKkzFM3VRouQIHpWpjRl3wGTJZkOoH0QAAAfCw91NlezuvRtiR06mE iiEUUjSLamkTQuC5zezJRYrdfYLE5nXGJG5I9Z0AN6bknf1AqZrSUtemnAxgArXm1f8CU5 3b20z9lRKM/W3CJpmIV5YAnx2cmZe/Ls4hpauwTktY+47QMG1Egi14fJvLAI7vGmCkSI2R JuuHpaQFZ1k57tfvIPllauOuvUZ8cEfXx3LvSabSfuUDpMlHuzlKJ76sq7WqPfP0mo1baX lF4019kJHKoUar/G4CHgz+uuhpOvFD7vqP3CuEGa9E+hQhrzmHv9/+gO3se4qetPtuu825 /7p3bzDaNZ0p0cnk4Ol2G0+1lDIRJslPlfqmmzIn19j9WYZbMd1/UJ7vWJ29gYIE7lX5VJ SFlGG1AaW+3V+eviBVB09Tio60q7pUWz9xJE+Tp0cGBJYCZWV8c7vC4c5nCmYAWKeXlcgA az2jUXyosqguSPxbWETzXaD7jgKmfrpNLRbBkws9LXHikv7Zd3JtjAYFTqK5h3Xh4OFRCG X8XHiLOlQ0or2LgD4kWQp437xz5oKywbTabqeBCdlbYKuq91fM9DwILLBtphOcEKoIs+OD 3nmf1MoisQs1Oir9Nau8Kk4MRsqjx7JSF9q+q4vN97BGjrpERFlKm1XGDrcVYNq0miINBP pJTZbcmjD3oMtF -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/encrypted_openssh_private_key_dsa.pub000066400000000000000000000011221465436372100277560ustar00rootroot00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAPmIBCP1AA8EiTL0VAdzau+1KuRmPkg+H2du4zt4ifhzEx4MscZ7cpBsUAM/EBC/ECWTHzDiWyFFuenvxDlfTi9XxySdOKM6XGLkY7oLsY1y5bShyLrycxDD7MRQ8HpUc9TPzE2PDH4Od6o98e+vdXP0+IDUZGbSuwEnaABX/1+ZAAAAFQDIB9KUd1/gnzM4s4FXCQb7zCnjVwAAAIBptrE9g/ooRnh4bOWiA3/StxbjMRmA9f9bJbM55CinL4yf/GdGmeBp6YjDBxDyk1oXmVJ2hLVXgW6kETbt+D01SouCTgLPlFwLFhqZQ+A4JQOKuLIBaM92hI7sAfTewkxbmAk/e1vyOeyfcQDhbncESzVBZrheXC1fTKv7O2PgbgAAAIBKhGEiNwKNA/pfYvkEbX90/jVoIEKZfqTk+PB2gbVMT98LWPaexrDwEGuCCK3KOtMncDai+0r1ujf1hzNJ4z43Z1n15tPvAIwQsObTL+eUQkVjHA8LXOq8n4yYyPidkjGzWcfBAm4Lm6vKkzFM3VRouQIHpWpjRl3wGTJZkOoH0Q== test mwiede-jsch-c8efa3f/src/test/resources/encrypted_openssh_private_key_ecdsa000066400000000000000000000010551465436372100275060ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCnz7UO3z wPva3ZeqAv3Fb3AAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz dHAyNTYAAABBBKHuAe5N1uLPUpY3t5kyYuISOxUobPZfK8H+CQaJTCALTMFrT63UDDYLyI 2xroS67T2bWHkuhX1BHiTGP6JpwL8AAACwwZ1jHlWJTZUwle+U8cXZx2Od0s4Y71qL9onX /+g+UVxaBeAZq88S8fbIPc1netiue9VVo7Qiw4e4WEPUCWKykQ+mwBX9798q/QUbrK3UZl 509ZLFe/DN41mVGO6rU6NHy+1mVstStgEEle7Dc+JaZwa/iZRVeRNq58MXQ5HBAO8fi4Y5 yhe050OWLkNylLtLOmRffRWo6eFg/DwCK64G5+qsSeTYVrt0nq/ffcvyovc= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/encrypted_openssh_private_key_ecdsa.pub000066400000000000000000000002461465436372100302740ustar00rootroot00000000000000ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKHuAe5N1uLPUpY3t5kyYuISOxUobPZfK8H+CQaJTCALTMFrT63UDDYLyI2xroS67T2bWHkuhX1BHiTGP6JpwL8= test mwiede-jsch-c8efa3f/src/test/resources/encrypted_openssh_private_key_rsa000066400000000000000000000051371465436372100272210ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCg12tR7n gz+3k/7bLxtc8TAAAAEAAAAAEAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQDNVEfQu64p 2GczvWj0AlncuNG+PzPd0jZ1/hfx/JDz1dRVEalcXMtIGRSAH49LzicAMPV8jvwNCa+aj/ UF7laDNqjIXvvC+sTA8l8/YilLm6BJ2G8B4sMo7/F8WOAcxrs+j1QT5tAMV88yaefoaXjh 9EWTOGesW1OiRfGYnzfhNrx8m8y0qVpYKpFbA5hswEL2VJC6YZxpg2XlMMJSSxBDhJLWBO Blxh1oN5cqv8cDPmwGYlvBYGGcuz6h3krARdXcyHciafoBKZNBimiJ5VNvhmsa7aSkZgH+ k6w4Cbddnuo78WtrEGvyf7HN3gBJZHGVFeclkRkeR0RR05HDqyanhOE/fO2HOHW3/x9SSw rnk9I/lZAQlyROP+zOJ3LI4m+iHZUqMfgtN/JkK40l+rNbClGszEFLW+OSbajGoEh+deL+ tdwownsuVORpAckoRJdLo03RGam8WMxx8UmkHw8WJBf91bshH1kgQSTIV/lBbFllkwM7+L AWy7Ow1ZGfzsMAAAWQbzIlDprGTE9bLjJZr45mf6CCPHGX6uZxlQnFmfL0zKLwfZm0hEJm 7SZuaZZbCqD/dOknidKyvumtX1NPK8HIWELLLv9L/0jg5NdJPUZKeDJXAm5DHrNWFxCMMs TxfM0R3E8NMC/qR+q0ECjBO9yZzJFTtx1V1uQF6Xw718vP9iHztSbpRQHOejASzDk2VWG3 KTgF2fadRINabcH7/ecniETT5PvrYFasCNKtOdSA2flFkEjT97RAQi9C7ZdSxvqLUKjAah gUv/YLTZFc6fW3iGky1rBSEP7XLf3qeh7GZF0TZ09CdcNl6I/hFR4AndlozFFCx+GISFB2 Qw7zB8EsGjjD0CPbiwIJiJsWBo6/ck+QHpiydJFaetB9otpF6Q6wgCjofJh2VjZkJdU9W0 Af22TurAj6OjSBEZeSsMPbmP4qO2jGWVYzBMTwprap09jgVfm0sVgTcD9yuchU/XDlI0l6 qno/T74o58lOm8B5ZAKc2SCAzbOTrVQnY35j8A87rrUSMM6NyGc4GIvQiOBmgPqJOdxhI2 JR63IZAq4mdqCMfqIr+itNxVCs3kZxzMXqIKVJO1w9sQaOEySqOQHVHpBJqqsb8SXQMWXd rNpNQ31Jgpavz12BsQ09+AV4K0oSfHJ0IlEFeXAUCUYiCR5JF0ZD6yBBnQ/JUVGMfmf9Ms 73on47cRlGyNzI2vGXslktvApp77s0A/n3pXmKK7aPHeLCeGUy5jGjGWgPP6R9DNSy2bUU FvKySiw2xGCsZsGBOATIBcJAYUj31NK/bpXDdmoX3033gWH8bCVmU+zglSExrzSKJSvOZI p2fWue/dNj4Jin79YwW26ukxyguo8Kd1NkKrSPMGnnUK3DB9EJjjB5Mgwv1xyngAybIFZp SdUvIDtLwNU6ZXxoMgA6FUlbn5WO9Ay5R5xVUB8d6HI/upgQyFch3Tuoj+jM1LSDRstQId Ox4w7vpijNN9b/Opq6af+sDcbiejDQ0Z4ubSayBt4AjjzmMgAf1OPd5csyfclB8xwSIH0e 2wz5zZ1rj8inGgZM2D/2cY4HuLOxIiHpkwn515sEi6cIAThg9bAZ8VseQI7fwW+nBuc+qb RkSaHW5YMVuCCoyq2z+HdMX6IPbIgy7Vm+AzeJfsF8TnKE9Etgse0EopqNgAgz8gwxbvvL hYpRPJEHbkTntZsIPZG7oQesDiXev+2A+u/YD0oYokHn3UXKXpbIdjkgWBRnEh13d+94qt cCHuZ81gFYz4mofYavLIBk7ESHGCx5/oGHlTHThgKTT5gDATcA3dxGPoegq4mEAGTHxolp J947DPh32J6jSSRe46u8cL2LS3It8Tt8Lc2roAvTr9kyCcDMj3hXHQ7RcaXPynIdZqPHP8 gOvcrtftAp2f2J1XHCe8Tn5VG80lJdpeiWVHi4sBYSnbJe8/e+P+uU0oerrOF5uI/R3L9h 5PVogMl2YF3l3xsvezLtWPo32/BkeswVdJa2RsClGQUAUsOuHJRudMlMVCmX9teqDEvJES QZrY/XaS0X6nPwanzOU7UC0usIDy+Jdhp0doO4YGUtiX0XA1nF+kJlKB4Ad9bClcDDvUXy kFOOV28ogmIMDAvk9i2eq06YNMHdN+jgeIrKadOX6giTJBns3coavrlVRUv+NCir0tAKLv dpPE053uuKAzC6akQONfqRdJoVzQrURTaccpvxQ+0Scfedsl2RknNOx203oVGAz6/Xkrpx T7g2k1Hmy4G3vFm1V2ecpOfmxEleexOra5nLEWSCHReh8uBi37reaSriQaLskjr2JZw34K NyZewMEm6cLva2vYab7DWVXE2QMg2BIubmS0+SWJ9PHH5jUGvfHfKf9hIT3/kcF2bOb3yt BWQjyzG8068U9T52Kp1ZANHh9yo= -----END OPENSSH PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/encrypted_openssh_private_key_rsa.pub000066400000000000000000000010561465436372100300020ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNVEfQu64p2GczvWj0AlncuNG+PzPd0jZ1/hfx/JDz1dRVEalcXMtIGRSAH49LzicAMPV8jvwNCa+aj/UF7laDNqjIXvvC+sTA8l8/YilLm6BJ2G8B4sMo7/F8WOAcxrs+j1QT5tAMV88yaefoaXjh9EWTOGesW1OiRfGYnzfhNrx8m8y0qVpYKpFbA5hswEL2VJC6YZxpg2XlMMJSSxBDhJLWBOBlxh1oN5cqv8cDPmwGYlvBYGGcuz6h3krARdXcyHciafoBKZNBimiJ5VNvhmsa7aSkZgH+k6w4Cbddnuo78WtrEGvyf7HN3gBJZHGVFeclkRkeR0RR05HDqyanhOE/fO2HOHW3/x9SSwrnk9I/lZAQlyROP+zOJ3LI4m+iHZUqMfgtN/JkK40l+rNbClGszEFLW+OSbajGoEh+deL+tdwownsuVORpAckoRJdLo03RGam8WMxx8UmkHw8WJBf91bshH1kgQSTIV/lBbFllkwM7+LAWy7Ow1ZGfzsM= test mwiede-jsch-c8efa3f/src/test/resources/issue362_rsa000066400000000000000000000031661465436372100224460ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA2Pt9umdG1Dp/JGFHN/fT9pq+xIdBOzXPcz67/NAdOcpH5rAjNOd0ohmEIMD+Wgc2ZPNz3VnWCCtdlPXjuVs08E9qaPT62U9AL7ARp1OzJM0kpV1+/XvRC2xmDVleA2n0/1R8VcArqHLRu1ylKKxgN2R8Rm4TVsqP/uizcMgjHMX6Y6QnpSVp+DE8BarNA1ZnuEdksvi2lYNzb+VW24tu3CGwPujq4rdmow1FAhyb3EJaRqzOsfcNM27eKVCOshzwhyCKmRD849dvORghemUM4tEzBH+MB7QPHzdV4J9bwcPiBJKwAJ0FHk1jkdZ3OggxRBk5cmJSLs+t+COAcH4QZQIDAQABAoIBAGcA5AuEEWyYJFkZ0Nwxyq6LgTn8VywLfGJiCo2WIfmYHA/X1666nXSCFmYSF+yW9exwYbVXezI/m9ol7CfGs1fM61/Nw/M7GuZId+jt4+H5fIb/3lPo3jDFEaEOpoGKYCKBcdCnPFJnx0ZhUYoAYmCJVDF++bE+0aKZxu0oJPr35Lda1hBeCfrb8fDReAAU71jIoOGyuSyOXlCVyT+OmBhVme0u2xDpdY8cd5t9YueTK7BFNjNt3sJOI4L+2wRskNwxqHCrECtuOXmzEyza7vqo8cjRGSx1HZfqhoKgiRpRkRmSi8p+X1+DZOVZuCxc3BTZ7WrPgVZhu7u9hsISKyECgYEA+C9ajUNsx7Hx9gOg6Zvr+zV461PjKI/0n9g0DTZ5RHdcAfeNs3ugmsiDK6b9SayUW08EVyveJ1OJjT/NPvdP0/KhCAjUt+kN0j9f9CPdHKEWoboDca8u67dayOAhC10mNhoAp3tFQryfgpb678GIzqnXkVjGgyWC/8Z81AN7uAkCgYEA39CcJAUVMc6FigTwoMOkdOgNK6qCxAxkNBTdfB/cBBtG3h8g49n0u/fAMjkfL6awdl53j3jVCP4pUZgSSqArLb0aGo84G2vP92iN3d3j/kPiox22w8KG2XR7tHLWcc+CFfk8mdiKdPFxaWVQaYJ6htGq9LGqY3sw5lVzmk0wlH0CgYEAuWim/WGhoo4NdPzA+cTCRqlr7GJ/EY558fBS8ov/jGafFdkawztYgEnLtJDMKH4FVzFwzK65CCggWqWPb7rSqERaiOYQBFTXPnqZ9InWZczyW1/bstJs+yu/ZtIJ3bN5GHHUi0pMM882Wxjv3q12xu2bXbo0k0Uy2GIwXzM6+gECgYBDByur0eXeC7aMdhxGWTEoXdKL8D3HTtq3ikQmhzgR9sVLglEMS9rybCkgIWFImQgh+vqdehd64Pso130q4jrsMMTfjWLFO42Fz8ck2e4M2PHH3f89M0XFXBAsI3Q7k2SnBgRzIpmcmi5X3SKu5oehVqt3KroXnu4vHQpI/LL+1QKBgD3zxf795zFXw53iZXtKkzYNQhEMVRzbx6dQE+tguB0YCb2vPvYaxfejg/02hCQ4twIMuMK18v0Y9W7E34C0m++lP8UbnHdR0Dsg9ryH7OlUMp4662060HWDnDy79swB/Nnk9dxf+BoPIXGny84bEpk6cLoiHuL6TRpQhuJ292DW -----END RSA PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/issue362_rsa.pub000066400000000000000000000006031465436372100232240ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDY+326Z0bUOn8kYUc399P2mr7Eh0E7Nc9zPrv80B05ykfmsCM053SiGYQgwP5aBzZk83PdWdYIK12U9eO5WzTwT2po9PrZT0AvsBGnU7MkzSSlXX79e9ELbGYNWV4DafT/VHxVwCuoctG7XKUorGA3ZHxGbhNWyo/+6LNwyCMcxfpjpCelJWn4MTwFqs0DVme4R2Sy+LaVg3Nv5Vbbi27cIbA+6Orit2ajDUUCHJvcQlpGrM6x9w0zbt4pUI6yHPCHIIqZEPzj1285GCF6ZQzi0TMEf4wHtA8fN1Xgn1vBw+IEkrAAnQUeTWOR1nc6CDFEGTlyYlIuz634I4BwfhBl test mwiede-jsch-c8efa3f/src/test/resources/issue_369_rsa_opensshv1000066400000000000000000000046761465436372100246310ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIG4gIBAAKCAYEA9bm+MifEwl4D2k7QEhANN+CvvOc6NjA5UQge7R4KZiKSu27T 8Ys2BDxD8sFZwURjCZ4SMiih3OwB8wqLN7ZBlWDQZQxpp6GmU3maoZrEUqqsR8ny EUNU/mhiDeLHJYmfolvESP3Y2Mnz5XAEdypLvkN8bEeStss88WYmAf6w/V470UbX O3GGZR2jHtjQbUIYd4WpkFUhCTI30gqauKJFC5NFMrV4XWz7T/7Sw76niu6Kfqve 4RUtMEWPcU2jTPqlIboWijW4bnsYBkAZO1nuOS3Eejt18IwAfl+6MGuCbSsfaCmP d/t6rTPufup0ZxZ5Afxi+X3Sj5iLMENbzkoBnhIYPzNMs19DxDMeKn3M6VKdqxbT EzYPTul8/aiQp2cvyNRJiuhRF3q6RGNMeNZmNjQQaK/b2rWjPSMcydVSK2vCWI5z 6huPFfSxYUhKRX4tQqrqibtX5rcbR+GDVljUBAiqdLPlpsSgLtmQAK9cJfrTZJIm Tmg0pbk9eKjJEhI1AgMBAAECggGAEOhyf2YAInWwoy1oIM4M8srZnNB2T3M7Bmne Iue9xHBdk1sZZ1XyZhE1hbcrM2K+w9MmImBsXtS4f546nR9D3QD35fQYMwoq9TR5 YORS3PNUfm4VY320E/tfv9/aXylcnCHfXDxnVudyileOXxrAcnuXTKYSINTUQTIL rHh3ej+pMwnCVptFqaCD8GPv14zEPTkrxTwuVUEo2SGUqt6zjIvaJ5aYDSmqE0OQ AhsU0Tj/u56c6/T2kos+xweWFH5siuTKHnC4GOxeFMlHOKohTVPUgkzzN9MbzuSA YjZAknZeHTHcaWFtFFeSFBbmzVJZKfoDCC5ESpLYZLRgV9AqU0dsoDJUP5ET8lHx uh4SNcCXR8acN3qkGSJRijAff2jdVQiLe0hqkMurhuJzArGHVpjphXWvDwxe8mLe nrjheykKn6CuWkrJWoFUIrDUaCcY26p9dNFdxPrEZfgUpnzCiDCGDIgj1lJvt1U0 ifx7ttUI45UC6URU/yR9EP2TvmRBAoHBAPwYRRjVacqINmAJFnU9+4eD22uOI1ed bfMUqqwt4ivWWmKs0ZI+GJmXiYSWettuN+Rtv1KOK8SAZSz3OdSWcwLuz8dlh4O7 cjjInaXTz9Tf4sqMaiC/IdZlmt6ngZ7ZG+r8zR9HhxUwy7Cs9GpYF5m3BJmZn1LZ bP9TH3dqvZH5G+Wn8ltNl1pVKM6rC0ARKGBMa7Bo0rsv1rUvmEetaZu5iiah5r6h XTmb5jPLEaMxklxkqfkOIHgairYegEip1QKBwQD5iDbu0QxiA3Uu7DeZx+6GHUY8 ffKkYXcnKdXFNIbeBGFcHkWlmZeuA6IqcOBbFTHpSpKcRmVuzvmd3TtP4FcIQxuH RqJ6TRMeXm+Y+GzBLeVKiOCrABsKapUy3TLTDtguAbFlTduuM1HOYmq5vCe3o2MK tgpOKJEHaOWHzrznMRgehjoWTeq3WuuMZmbYfjDsDo7IleZslWkIokWD0U7SERBo D05/x9x5fSNqyyjM8NZ/ik2ujPUR+WdCHtXqluECgcA/k59Zc/kKKvALqD8RsmAM /SQJK/+dyQZBl6SzZ57yj0ycNhlkWGS714vG9GxnipRt93+YwmInXHonrPHYu1im FLQyBVj3z/4uc+nOOGzhstTvYBojyBAwkc9M99GozfhMexUAHnnizjuQgw3hA/Zv vchbNHMJ4eurOLtm0nScq8ZtVL26aQcSsQdpl5luvuT/5EYEZ2s96gKsDyTIbuOD cnd05r/as7dfIAIebcg07/uJcZmsRfPKVmdFJswTh0ECgcBr8FU61ujRWQeOpZWj is2N7Anezuhv3M1K/pi+9mrEjQaEb3/XE2p+VooGa89Q9wkhDiX/PaBQ320wsWsf sT5Uj5rP2GkeGEsF3vnNJOD+a1j89dqhfak0x0gEuZRrocc3l3niBVzarM5dRUs/ TrmrgRytnHM2veuGVgS7y10BcMYrJgrobQn0CHtNv1oLmgKVifKPp/AF1leZ6X/C dn7u9XywVraxJYYkc1IntvvOMvvGLdBOiiDUhpr5Cheko2ECgcAEFU2CTCaTzV/s xTySE3AK6flhNaxdwL0wjK0I8DUZhfpqrBJVnlfV35Y5dXWl09qR/f1r6ZQOg2Ew HiUnsFq8XxAwvQ7SrrLvGY7OAxp4mSeUufP/uP9hNIZQoXof6gxosLxeTfDq4ddA dWQCygbX8PQRrrg7BMqC1pRIGljwt7ijKy2H4RS8WteGlM+nTrps9iEImAqxoOAz ky2V56s1enP1E+5C/1Hr6yyVSxBF46482Bpl2WvJG6BBQRV146E= -----END RSA PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/issue_369_rsa_opensshv1.pub000066400000000000000000000010571465436372100254040ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQD1ub4yJ8TCXgPaTtASEA034K+85zo2MDlRCB7tHgpmIpK7btPxizYEPEPywVnBRGMJnhIyKKHc7AHzCos3tkGVYNBlDGmnoaZTeZqhmsRSqqxHyfIRQ1T+aGIN4scliZ+iW8RI/djYyfPlcAR3Kku+Q3xsR5K2yzzxZiYB/rD9XjvRRtc7cYZlHaMe2NBtQhh3hamQVSEJMjfSCpq4okULk0UytXhdbPtP/tLDvqeK7op+q97hFS0wRY9xTaNM+qUhuhaKNbhuexgGQBk7We45LcR6O3XwjAB+X7owa4JtKx9oKY93+3qtM+5+6nRnFnkB/GL5fdKPmIswQ1vOSgGeEhg/M0yzX0PEMx4qfczpUp2rFtMTNg9O6Xz9qJCnZy/I1EmK6FEXerpEY0x41mY2NBBor9vataM9IxzJ1VIra8JYjnPqG48V9LFhSEpFfi1CquqJu1fmtxtH4YNWWNQECKp0s+WmxKAu2ZAAr1wl+tNkkiZOaDSluT14qMkSEjU= test mwiede-jsch-c8efa3f/src/test/resources/issue_369_rsa_pem000066400000000000000000000047021465436372100234520ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIG5AIBAAKCAYEAs3v+RtRTyr4HJy16h1eI21HzvoIu+QVClFigaMHYOt5K/Xtx nRlZsLQQVkyTMsRFlbSTKx/AgEVqMlYiC0MvaBX223MLgJ34VY3T1TaSu0S9WcAg q7IOlA6RPlaeK01s1HA11MiNjGa3jyQsFNPlFnb6BCV8BNjYrW/rEvNNiLHZcIkY /ZJ8yiea1XKRqUNEJHNI23jQ3850QBPAEWsJAy3FxIqPVereKbAFn9wWxxmHnPT2 QGHHcwh3MJi5k0/w0jhfrrdn8b4wcnVicxh5isqM5RTY04YF7dItH3HnSxtKABzT QS/FHhGEOx9IJW0/a7JzKjgLYAWA/5yRnzJDDIz+zUUtGNI7ZJmPD0N5e0ZB0xXi lZCqSrcg9/i7H7jmZIeQOq4TmYDD/fttgGYSFxoaPZCWUkhewfQlmvkwq+YmaPZS 123jBUa5OS7YOwTR5DuUcfEhq6BmBpC17fPfni/h7dSOI26tX1heeWEGJ0zqL75z VVQqeItHPCpTQKkjAgMBAAECggGAHHtwvoyzP1koiW8OIqwha6x1oaXHDn1nM2Nd EUKxraXZAKC2RtffA8uPTCKauVOsNzWQpSdExRY+4/4HKQJgY4QYyHpZOO/YmLsJ AqzGXDFsWvHCPXzkE1q8ccgNEZIX0x57bGjnDYC/YFe9JxD5Kbd3tXC9XYeL2voH s9ooU6jleJZJAPReGTZvu6+SremexqoExc9GVj3M9N4tfJYfuAFrgOT8GgZLexIT 0mp6st26R44YBd9+ZyLQx0V1LYthx+Z3uMA4BYyTc0P3TcgRiazIBjhFC7gcbFwR kma/MFv9P4jvUeNYJuQIueF5Bb24/FvRYp5o6HGTiE2pGUv1DAGK1PvI711D1aDd TAcLhwkzPog1C9KPyz3mAn6p6x8S8+Lk35AjGGBE7i3s6ZGJF17SJW7BwzKJ1vSe XX9U3XLq3DErPx9AnQhCAiPihohx3Cm8Hy68NGSHjRdu5CeWJiczX0TKHUNSx6TM Jo5Ew5Lplr01x5UsjDbwgEOPToEBAoHBAN5UGGcXgkQ2jn/pH/BOQ7FnHNtS0/lo feBnUHLEGRnFylka3sRak0fF6bMj48NrGyiI9QFNv/NeHqwhjGYGVeK75HGJENPC 6Wlewifo6Nw/GxmBo0sewEZ8XEyqClIkpj1oOhIbkGyeT/dXZjbyvx+kdz0FTAyU /fUB20Ai3rgS600r6GSQKloOs2iAnELugpkTYeB7Fiwe2613i4l7myVLowhwYhu3 BBW5kg+ApasSTwloJlC454TO1RylJ/GwjwKBwQDOqslErBZfb2Lvm8DkequQ9kzp dIw8pZoPLXkRsU+X2kifxCY9W6SWlgzMQptX/wWwI6QB7fMIwLB1Umtzuu7vwlzB +NBgeflLdWlWT76/mc2GfbW9QsKvnAR2ar3z9GV+zmHp09NPddFn2bZdLlXl736p 4C8MfLTZlmSwwJm2MYyoGQB/NfMMrJ/yaAPJV+AdlE0hV3A+5a1cRim2n8rUVEHj OJ4x7AqxA+xt88picKIAXEtTGyjsj6DQQdUBYC0CgcEAv00u/i3NSfKDpO4sLDK7 rn8h5lobyQQvI5LiNw4i5vk4xnkHa37gMabLEvhzt6eGY9eMsYV7/+VhkQ0A6JzU 89Zml4av8vZIrwD5ISwYicLHB6hzoGSiX0QMi27YmJuuazIunXwYRk3mUtZiPi+b Ype6fcf8Cut8pX/mbwZSC6ND0lBQk4800e7KUsYvLqxZtWtnEaf3iRk4PseZSkAQ XAP8EXvZ/yz4F9VoJ2yzoEKNvXNfXJ/tnmn2F8LIXv9jAoHAccENwa/bLLKZyXt4 xApFbygzE3kkS6l3UA1ei3+GaPYsbUxBJBrSUFTNPI0ZBmmHzvj/KFS6JkIxnpI8 NNpa9DuOZPI4eDILJx68WVbRjpLwzqtZIpChqpl811VPsvz99LtSp6sBr8YQ+lGa kFWV0Fdv579PBleKEA445BVPRjqlykzguiSO4JYQABSCqQumf4GGpuiDDwvKzXSN N0ljElZCYfhjEuVyyRZ4x9iduGt4sCwdBeR4NSWlhZwGy5gNAoHBAMmDur+qZ5sL bb+AVsIPOhS1Nk64QyXru6Bz0M6doY3pgZJRGmXPwqfpHFsVGrjFoYU0Xxz4zWJb fY0UBJZfb2vgLcHGVYCUL6C6d+f0m6DFDB7iqY06hU7EirYzA6iAcKiIHgAbELB2 7ux+jieXxWKaMsJWYgR7XQn/UbC5xuOPSazZ5ws3Hz8toUK1tsYjXe+RoZioij2f Xm+9NXEFFGhLtOvepf9qw1fHlIIetCOJ/yrCJKVzFmzhUReGPAnmoA== -----END RSA PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/issue_369_rsa_pem.pub000066400000000000000000000010571465436372100242370ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCze/5G1FPKvgcnLXqHV4jbUfO+gi75BUKUWKBowdg63kr9e3GdGVmwtBBWTJMyxEWVtJMrH8CARWoyViILQy9oFfbbcwuAnfhVjdPVNpK7RL1ZwCCrsg6UDpE+Vp4rTWzUcDXUyI2MZrePJCwU0+UWdvoEJXwE2Nitb+sS802IsdlwiRj9knzKJ5rVcpGpQ0Qkc0jbeNDfznRAE8ARawkDLcXEio9V6t4psAWf3BbHGYec9PZAYcdzCHcwmLmTT/DSOF+ut2fxvjBydWJzGHmKyozlFNjThgXt0i0fcedLG0oAHNNBL8UeEYQ7H0glbT9rsnMqOAtgBYD/nJGfMkMMjP7NRS0Y0jtkmY8PQ3l7RkHTFeKVkKpKtyD3+LsfuOZkh5A6rhOZgMP9+22AZhIXGho9kJZSSF7B9CWa+TCr5iZo9lLXbeMFRrk5Ltg7BNHkO5Rx8SGroGYGkLXt89+eL+Ht1I4jbq1fWF55YQYnTOovvnNVVCp4i0c8KlNAqSM= test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_dsa000066400000000000000000000007751465436372100221000ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOGamTQ4i4AEWhMGssPosXwsaLBW IsldlycRQEfRCRlmi0hzdmYvuJJn+YQ2Jf1QJ49jTTxlCuFJLrDct+UxpittxRtD b+AdDpmhGp/zMeNdPBsfeLX9REfANyveQrfT9hqZ2gIbMOzJ0wRPgInmSRi22A0I t7vxGaw47J5bAEf/AhUA/0PUfHgleqi+2kK+BOGjTs2eSXcCgYAaUAApSPx+S6f+ H49ml7sHdAQC4lVyKVQVh0RG55/rsIrd/dSYgo6LZ522vzNgxw2BmBeFJUpNZkQz IGmxN2FkTmlSgOxZkRH2oZA2j04vcskJgIiN8K1rhrpRUtJjcKXnF9YRn0eR4o1x ph74ySPmIWX12GULB4R1j4nysqDmbwQWAhRf04nB8DdbuA1JAbbkaSwORY/Mdw== -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_dsa.pub000066400000000000000000000011221465436372100226500ustar00rootroot00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAOGamTQ4i4AEWhMGssPosXwsaLBWIsldlycRQEfRCRlmi0hzdmYvuJJn+YQ2Jf1QJ49jTTxlCuFJLrDct+UxpittxRtDb+AdDpmhGp/zMeNdPBsfeLX9REfANyveQrfT9hqZ2gIbMOzJ0wRPgInmSRi22A0It7vxGaw47J5bAEf/AAAAFQD/Q9R8eCV6qL7aQr4E4aNOzZ5JdwAAAIAaUAApSPx+S6f+H49ml7sHdAQC4lVyKVQVh0RG55/rsIrd/dSYgo6LZ522vzNgxw2BmBeFJUpNZkQzIGmxN2FkTmlSgOxZkRH2oZA2j04vcskJgIiN8K1rhrpRUtJjcKXnF9YRn0eR4o1xph74ySPmIWX12GULB4R1j4nysqDmbwAAAIBL1zviIOohyjKKILovL9rPlTLHlcdXkyd5S3PZImq3CXDY5mQFlxH8r/hEnwMBBTAHmun7ptcdH/R5kZVB6v7xsAdJXDYiYOyoLI8yL4aWbjs3flriPXVmCb0hCh4n6pSKVR5IHLzsABABlJTULxSkvWcKwMms7arQm46WR6MPlQ== test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_dsa_encrypted_hmacsha1000066400000000000000000000012031465436372100257050ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIBnzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIILw8uFzY0qcCAggA MB0GCWCGSAFlAwQBKgQQw6RQtTSUAB05u3PwE4Qt9wSCAVCIpjeuXs1WOfohxzCa AZYsQQ0hvJFa1DN5UTu0YwL8No71FAb86zoOcjKcrx96Vu+D7VnCCiJuYVpFalL3 OoYpOpHY3m2ri24C31bR+2BY60GfCncK2LqlQcJbgQck4JGKJL1laN+9+6x1qXnQ 72D0gEWDWSLHdgnB8lAwcuh/B6ZBwwqJYh4njOtjAwOWb7ynG1pKm8C4Vk55UwMi JT5gTpRMVONuj7w4NtROJmIe1eLAzZn9nZWo2y2dVzafCH0RcOZaEBJ4nBEYi0hf 5eU0irwWXdoVzegPYR3j/xFSjVLSb14rR6XBjgF+kaH9KPIDTqKzCqXplrNK70+v H/IZbIgAKZh3YMU7GrBOArEBD9N4qdxJqO3OvgQ+WJbXXE5gauxgVFMYdXpUJXCV q+FdjhzDJAZzNlj4OsZx4YQqHroeixFV7sdg/T2/elypkCE= -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_dsa_encrypted_hmacsha1.pub000066400000000000000000000011221465436372100264720ustar00rootroot00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAMui93cyTI7R14Prqeet0joIvIWWGSw09hk6qDZvgKW2zzs5X1BTScrnLMnaKOgYtwDbFN4OQsBLNZu+PzcAqfwJBeTD4mGLRVk1k1zK6jXpdPr3V1sqQP7OEVa6MF6XsIf/Yu3zFvqpwkoNnrCcSrZxLMnnW83Ya6NG5d7WGBw/AAAAFQCHbVl3CZvAlhbRo/yMAY4do6Gg3QAAAIBb2u2D16qhuFq8B8UjBt1HSo7R/KPjRI0YzrCpJNoYjB743wARQMl5yDU67IuiIAzjxFZBiK5u+mTKpuO1v7MeTc9IFQ3ObR6N9PO1wUAZ1uv0KSesnxjgbZNIHwGwzJ88T43LEbugZleVEifbbIZl7puEgQdFko9zEgqGhOu3VQAAAIBKDmTnJZliffrAxCElJnnrM2SLo+Dl/cdtCDdI+3RBG7wTPWqMF8C9VNC5ssbi8QLDwl+OPrSIERPb3VXtjkVxQna36JK3od0aSx90VZkv7RPeL1Gt6Q/F+Td6D7p5ZCGjHaQkEk4kfPjTUnLxKn5FGxmY1HV7ceXo17AElmfmyg== test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_dsa_encrypted_hmacsha256000066400000000000000000000012301465436372100260610ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIBrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIf91MBHTU55UCAggA MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBCKkOxM17NPpYz8mDja3yvOBIIB ULDh7/2bZa2i5p529GCVrTjLYFWT9wLkkN6TSAGbVHeyjHm5hasrDlfK7Gni93Qt Hmaii/0PBvWkcf2mQPKujl0gwnPel+li28duaysYOCNwMgadlN9cTs2y/+yAXzoa q7UrQLxckpuDB3/hxn6WWDO7GRhthW3QmR6yzh2E0CzKhB2YU0tTGK7KHzGp+cS7 Z0bwYlRlDE3YnDgi3Rpt3O5BT+uA0WOeSw1xd07jm/+okfhB3xHmM+vfO97476um 2POcDsth0a66j3p1bZkNb4NHQEp8Ud+ST+4j90lb9Eu76bXGIOHubWRN+ytyITBn 2O014+oOIdn00b38/yA/ej17fZPumEYh1fQHOlmOGi3fV9kEiTZYtiRYYET4keY4 nduV4MVBjAFvtRWArEnkdeUqAqyEFbIzWADFxRZtfPCv6Pxr1So5DQatpe/UJiQC qA== -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_dsa_encrypted_hmacsha256.pub000066400000000000000000000011221465436372100266460ustar00rootroot00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBALDWcFnpSWiwGbuyqVzo3ieAm2K9+BIUYjPlA69UCM1GulxzCj9ImbQDvMsuQ3tKpMH6925NoGU5G/atRnqXouJFNcOi43kqtHx8tE1vV9v8im3+gGsOF97pVgtBMHNQr8sjDN0FrtB5MvLMc9c5b/1lhrUj5PeupHIJzrhvAvsHAAAAFQCeztLdFSYoOE+Nq/XDQh0BuuuM+wAAAIEAh8p4L7O0vUW76jSJvE3v/yPG8bcBpZporUTvG2DqKP/rISyRblRoYlwmlaTzyrC0/HrUOqw/1fiyorr+KoxJVhOavlKVq/YSGpxmrgt4eS+VXr5BJyRGxDaPF4kTAu+2/FVMu4D1clK8BuR++phu9DWN32sWAzw2IYwOfhB0b+0AAACBAIUb/bDKE9DAGpG+zMyida0JTIIPHqWvkSa2dUXU9J+4iV+Bws+X3bEggZDeeDAKd9FmFTujek25ihIJD7tOu/CCFWEcUZ46aff/RQ5bfCKsJ2SyoSRvFGGal3541YvgK5A3DgzRjEGhlF5KfJ7HIcAdTq5CYA8uDBZngA8oeQfz test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa256000066400000000000000000000003611465436372100226340ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgFQCSuRDPQE9G+4NK nZDeTFNJ0lJUy0aqUr3/hToG8yyhRANCAARsBvWcCY79vTSG9AsdULAm6IonQkrR 6M2vs0EDL7PZwgTEZwAUC/XnCkHlBgpY9tpZfKkYOr1mx60J/PmVAoGY -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa256.pub000066400000000000000000000002461465436372100234230ustar00rootroot00000000000000ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGwG9ZwJjv29NIb0Cx1QsCboiidCStHoza+zQQMvs9nCBMRnABQL9ecKQeUGClj22ll8qRg6vWbHrQn8+ZUCgZg= test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa256_encrypted_scrypt000066400000000000000000000006031465436372100263140ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIHkME8GCSqGSIb3DQEFDTBCMCEGCSsGAQQB2kcECzAUBAhlStjRMGQ7hwICQAAC AQgCAQEwHQYJYIZIAWUDBAECBBAdI6Cy/NhVCMbKL+x3uaw9BIGQgUJxrLtS+ygm BYp4b24PS568lpErhJy38FXl82atJimDxQhEECU8ZsMj5mdnGocGEyR9WvwFQ45Q MAuuPQO24WgvWcDLQXBF2c1ZtyJwrFLNEZ1eW2XxZqr3UEqyRgIPtUcjpOftTeH2 BKksRQ1tixUBL4TuFX1ph1uuhO57pf4QDD/3cUeg829dg85qG9U1 -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa256_encrypted_scrypt.pub000066400000000000000000000002461465436372100271040ustar00rootroot00000000000000ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKjOhkR/tN6oSku7uJXEqDZh3HsYFeCi6F1rnDR1roSpLy2HQYGLPjalt+E+sQhayJBOLJd8j2idjIRNK9trrYA= test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa384000066400000000000000000000004621465436372100226400ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDArsAu86PviKZkcTLOV i7Xch/I8gwEH+RPFb5VTH+N5USzfRqDzFbjSBQDyl8+uteOhZANiAAQ0w876zjiq 0KEYViQn+WcmJNroHdsAGsi7dd12ATyRwK7IMAijJLcluvnZiprJKp1QxD6kONkQ TtJHCe/Mvt5dotYjV6+XQ0pCf9idvC+GMcxDlOh4VZ/MAQNMD2DabIM= -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa384.pub000066400000000000000000000003221465436372100234200ustar00rootroot00000000000000ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDTDzvrOOKrQoRhWJCf5ZyYk2ugd2wAayLt13XYBPJHArsgwCKMktyW6+dmKmskqnVDEPqQ42RBO0kcJ78y+3l2i1iNXr5dDSkJ/2J28L4YxzEOU6HhVn8wBA0wPYNpsgw== test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa384_encrypted_scrypt000066400000000000000000000007101465436372100263150ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIBFDBPBgkqhkiG9w0BBQ0wQjAhBgkrBgEEAdpHBAswFAQIAICpko7c3GsCAkAA AgEIAgEBMB0GCWCGSAFlAwQBFgQQYR9mSZAzK41nexevamz0sQSBwG37I4qWSkb7 wpldjYIYd3YMX0h+E+9uGgxZeBW74bQ/yM2F2GoWjDnw38YEJZceNh+RA/COh6b4 MqD+cIjmi5aXhtDKnnqyuYeEAZtRRpWEKO8xCwIkY0kG5dNBb4r9mJRbDGJU68zt bJGT2j5YXebwgszCt3UUhTXqF1bObYDdwx1SMOOMpkjn5PfGS9//EAF+xXBEXMLJ h802rFX81ZRe2d6WhW5ypZ6ZAmusbgdtlY00R/iKLvzznx/zkHeH3w== -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa384_encrypted_scrypt.pub000066400000000000000000000003221465436372100271010ustar00rootroot00000000000000ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGYBJ8F7NOBihGiGXVBApYIXiLlNVW+SSYANC3okjqsax5eFcwyfQBRSWSJxAXKA1aV5vtYMN/nBwvg5kEgftHi3L3Pye4VA1PKyoa73E4T7AsAJ1eRrJp31ecSXi1f9HQ== test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa521000066400000000000000000000006001465436372100226230ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAu4Fi4AfgUdlwwYC3 9ciPeVaUz8vZzqC1bXVtpPsRO5hCbtFrAQBdIQGyJ3chfDt3mi6UHToPXPEMGvSL weiJ+0KhgYkDgYYABABdYMYEOU8AxcsHYPdHwtbndVLfJZsCFFQ8oMUt+xHi/MwI SVkojGjk2FOtUeUnsc8SWXHEUC6GDSqy25+42GsxWQGL7/IyR2X0Iu9rUooKrKg4 EsvQNEDfq9Joj7zuWOmAQBQK392fbXdYYILjSAaG5at9mhiw8Kr65ShK2IUv4n4d nA== -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa521.pub000066400000000000000000000004021465436372100234100ustar00rootroot00000000000000ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABdYMYEOU8AxcsHYPdHwtbndVLfJZsCFFQ8oMUt+xHi/MwISVkojGjk2FOtUeUnsc8SWXHEUC6GDSqy25+42GsxWQGL7/IyR2X0Iu9rUooKrKg4EsvQNEDfq9Joj7zuWOmAQBQK392fbXdYYILjSAaG5at9mhiw8Kr65ShK2IUv4n4dnA== test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa521_encrypted_scrypt000066400000000000000000000010361465436372100263100ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIBVTBPBgkqhkiG9w0BBQ0wQjAhBgkrBgEEAdpHBAswFAQIf54qi5gx2/wCAkAA AgEIAgEBMB0GCWCGSAFlAwQBKgQQKNwzbVYlv85zx1qRSDIuNwSCAQA6KsoUMRQS BHjCTbclDicOr16QQ5G0weLTjfy2xxaefnWlU0Kb8bZ795Z69+UfBcIPKeTi16EK QdamyrEqxioimHtLrSGY5wFXGD3SNXWOULKA7HIMwbvpD4w4ccuD2vv2uYmoMXeL s1l8eOC2gPb5Tip10bn9ZuHK5xEVMAAzFjO5ycT8d2j6ZUAE7EgJXdjCv6l+59iU texwnhXfX9Zla5K+wrMclWV4TIokjNfckPP4ZwBIrYsYG2SXtpszGWWBviZrb6Fz 1DI/aApGZzw0MiZoYQ0HuzIE39TCdH/nvjMtWK1LZy/fNxipBtfVHOIB9LxpNyYO ijzcUbrY0bU2 -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ecdsa521_encrypted_scrypt.pub000066400000000000000000000004021465436372100270710ustar00rootroot00000000000000ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACWNfRwfrfQb+K8d5+VutrDWme+Pk6UyiDvbuS48bCg3e9ptaWHQVtQ6xm1yLYUeF/ZVWn20+s2DntLGKX8dFCaSwEHVmX4oj6hx2V5zprevf3GShfyz+HXt4qzoPzVMyOPY/po4d5oxM1RM7oWaqNwvuVhU9Zk5MbJSzKq3atWJv/+AQ== test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed25519000066400000000000000000000001671465436372100223220ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MC4CAQAwBQYDK2VwBCIEIBdzIGiV1WyXNDyPVUcXZrG3jBYaXHG7TBZK6rrRYRUX -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed25519.pub000066400000000000000000000001261465436372100231020ustar00rootroot00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINKulAsCNhbGFNT4DlsMmQt57Y1/i40T2EWpeUWjiDL6 test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed25519_encrypted_scrypt000066400000000000000000000004261465436372100260010ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIGTME8GCSqGSIb3DQEFDTBCMCEGCSsGAQQB2kcECzAUBAhFrC34mnc2UgICQAAC AQgCAQEwHQYJYIZIAWUDBAECBBC4Yl2xDb6OxiknqsqFrNJSBECqIsjJq1c947Wj AVEwaAqDUkDPywSKR5R4b9lDAEclbUHfZAHDkDX9kk2+zwT1toPOuECGq3FN55BO wOUhPR0o -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed25519_encrypted_scrypt.pub000066400000000000000000000001261465436372100265630ustar00rootroot00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2oQIAotMhMO8LyWecYBIXFlxSFRoxm8A0Hpbn1mEOJ test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed448000066400000000000000000000002341465436372100221470ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MEcCAQAwBQYDK2VxBDsEOei82miP3EX0EZ0HhIhYRIP5r4+MqIPN/x+Qz/9LbyPb arD2I/6g3IU94gr6yne5fp3/coL8xBX+QA== -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed448.pub000066400000000000000000000001641465436372100227360ustar00rootroot00000000000000ssh-ed448 AAAACXNzaC1lZDQ0OAAAADlrhnFj5z0wgxD0IY7ECoZE3/8v9cUWP7VJnyp0YPY0aLKBLnagj5/GMDV71bYW56Tl7AFx3EQvxYA= test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed448_encrypted_scrypt000066400000000000000000000004561465436372100256360ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIGjME8GCSqGSIb3DQEFDTBCMCEGCSsGAQQB2kcECzAUBAhr6TolSPij1wICQAAC AQgCAQEwHQYJYIZIAWUDBAEqBBB73QBoaoKyPGPrWSkWZauEBFDiTfYOM29sHJFC psVERa9DH3Ir1vvCqAL/IldUx+UcdzjQxQkYqZeFiNZrFuNlDPua8fLlvuH2JNCK E7qNRbNDX/S/wk9ADpIrrkYFbmhTEg== -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_ed448_encrypted_scrypt.pub000066400000000000000000000001641465436372100264170ustar00rootroot00000000000000ssh-ed448 AAAACXNzaC1lZDQ0OAAAADn6JKamPkXumrMxQnui53u1e7U0WkROtrmraifd6LEDfbEW78xEmNPSVZARg0ydaeNYzc+iEGG/cYA= test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_rsa000066400000000000000000000046641465436372100221170ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIIG/AIBADANBgkqhkiG9w0BAQEFAASCBuYwggbiAgEAAoIBgQDCOSYk6+5VS4tJ qK2Z095cPYHjlUT4Gqm2MM5xdzM2nK9bd4slUyz8fFYpWAIvu1G6Q5z9e/2Kfcme 86lCjN/lidSNHQBpz6xW2WQTuTPfSPW2lBblRovlezhypdHTdMt1NB7B499py1BF 1iLO5Y8URPCztTXawneMnUjvUp8g6dDKVDGNBssgwZ3TR8Fj/vrOkgafwtJAl/X4 CJBXdt45dLre5eRXEoWDxTdW/GxUw/PtV/mW4Psheo3/RoIFequh2m7U8uSdXKvG qm0ZlpSTSoen7uELSd+9iY3E4ULdm03Pom/O3WO+DOCmRb5YUTNFKZUVop3DKizj Eggy9mbb5W2iJp+6K31YWGWHCR/HhFr/61R6yQomXzHhbqAEGH1FsBmpRDa6c7a/ b8Xl4w4kbBlOOs21G+tvL9l3hYqBfWpPE8A72WGdkzaOltvt9TEDroNI2yopNWTV XuUvJ2maFqiwf/4cYpGZqu3V4ccBpTJbhHQ3G3w5XVQ6Np42ez8CAwEAAQKCAYA0 Ssi/VhpkMqO84EJlUUrkENdg2/amyh75Y6ihmhNa19LK0KPRF9Tb4eoc1Yo5Kbj2 am/hO7nmyLk5J6dhuKYrmfF1UOKkmnpvI7azLMEPlAg78SE898KAta1cCNM2mJKS 6saBM4YaaNgjBWV3yQy9y1X3PInUbVlcrZhOfzNC3FEPuJ1it/qGxjplAUPLVYJX ja9k4kJTi9Z4wm2Cbwmj9I6/pqvU2bLC6J1euTW9mMibFX2opshWmjWTDnvBV+ZX jT0i+D2p0sRHO2oo0O5WKvII6UI2csEM5VVCR7wReNxvIjCFgQP6+P+msIl7YSvm 0Pz0RWbFVsbP+EqyAl8DDxLfq209Fq99V17T1lVu/4y9HEaI+4+hsO6JBCNNezK2 nn9bq4GYlZ0xrxQuvEUG3BjaIJe0B7XIC2XUBA+530bImN8D70sO+3Q1gydB2+Sw uf1sYXMSfJwyy6qOsw+mJUNxYowDcCo44MRcB23XFQDLEb2MAFC3/lIvNKlQSEkC gcEA8P8UqV9J+ItSDjDtsA/un5T9DCy3zOJ8p9TMszJjuteCJw3huKFPG3oJIBiR uex2kwLiS6bNnZiiyW6eFy8e+w/xOVed3XKjculIhoT1ZL0IiBCsaDa/+L9hBqG1 257k9yfgTl5j1ZppRzy0JMEE1Y/hQ5CZxxZjw+Am3XgRFzqpLqhd5vi0oGXgL1PX zHeiRp+oSnqr+JWw3DBhLbQ1SwbDXco0vyQj5nR1+EV7A/DeptPBeCn5Ox/p3g0R PcxjAoHBAM5QnQHYVeNFIC4zK4WC42wnSLaqzQS0YCx20NSs79xmeqiOhkkqbnEk 2E/l4LKb0j2xtNEAIs389QfKoqwXlZB01Q8oOHMd6HKd7eelh+bkV7mig6rV1O64 7TC1jTVlCKXL/jADVHd/DKCZ74C9AOubU8ONjSH0na6Stq/nYQrAj7aHKKJ2wBP2 WRI3lj6Ma7Ebl3OtyXIay+gBegEMoAt/eJaJbcI4LirVl6vDTBXOGHtNSuJf9BEZ plgsvCdGdQKBwADi3z+UMyBv2rhko6sfE+CQWrHdxDtDpfO0C6CpEcbRHhBos6jL JxBRzZDJpleJsBHwU8a1cVIgCpE1D+3D5ZhEwb1VPiZfUoyMoRClkoVxUIO3k/q6 INCYW5H7rECHgA4Mnn2LSVCyxapWZc8wyoTCh7CI6pfZ1DoXK+1qkJ2GQLMEOXws 8/UXCtEBvOxqkDU0RxknBFTgsArPPrw9SmjhOHyyzqjZSCyDxx9HmiE0lI0GgFKh zOHTxzdi0upoQwKBwF0VAcFTWWywQ1SUwY36/6BMGQJRDS6SMtHcyVsqqw1FLxHd O7jG7A0gEnf5vubWZoRvKKUi6pEFD4f0ZHBAM7p4+6da/hzx4W3U0wEwLaB+ZRXb vIvW7brGtDzFrG/qpXwoDQacef9v0sKisOvkWgXyjlgsBQDM3Fdm2gWC3sV7G1u+ nxatfPuEqasOaTrPH8dIK4yFW92fOV/zSpgumgaV/FHurxZxQmMQ+t0Dv9AWq/T1 alO39uXALMybYkhWAQKBwCKNkCzsGc3yMzi32go5v9ysg1Pfj7qqIUzdxXWXFd71 5e/1I4nfRi/6cZjmYQn6Br9oN/GkzMZXiPE3DUjwCvHPK3L9EqPPDGnxrFc05GnD 2JsTzYT1XqlYraCgKLljlULjAdQgAm3YaXEoBY3o46yvG7/7N19OBF1j5SkcRHyk Pi7fBAKkIgBoPDCA9SO4Z/9aBmzImXmbkSQpawHOEYTk2xTebjYLl1oQiuy72b6s F1BlgpW6GHpeDNVV+j8vTw== -----END PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_rsa.pub000066400000000000000000000010561465436372100226740ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCOSYk6+5VS4tJqK2Z095cPYHjlUT4Gqm2MM5xdzM2nK9bd4slUyz8fFYpWAIvu1G6Q5z9e/2Kfcme86lCjN/lidSNHQBpz6xW2WQTuTPfSPW2lBblRovlezhypdHTdMt1NB7B499py1BF1iLO5Y8URPCztTXawneMnUjvUp8g6dDKVDGNBssgwZ3TR8Fj/vrOkgafwtJAl/X4CJBXdt45dLre5eRXEoWDxTdW/GxUw/PtV/mW4Psheo3/RoIFequh2m7U8uSdXKvGqm0ZlpSTSoen7uELSd+9iY3E4ULdm03Pom/O3WO+DOCmRb5YUTNFKZUVop3DKizjEggy9mbb5W2iJp+6K31YWGWHCR/HhFr/61R6yQomXzHhbqAEGH1FsBmpRDa6c7a/b8Xl4w4kbBlOOs21G+tvL9l3hYqBfWpPE8A72WGdkzaOltvt9TEDroNI2yopNWTVXuUvJ2maFqiwf/4cYpGZqu3V4ccBpTJbhHQ3G3w5XVQ6Np42ez8= test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_rsa_encrypted_hmacsha1000066400000000000000000000035021465436372100257270ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIj8U2DOUAM48CAggA MB0GCWCGSAFlAwQBKgQQgkPCvl5Jsbu0bwVn+H4d1QSCBNCXNIf7CZi2cVPX3lbs r2D0aka8fzyVyazOWK1BTTyrr0lA3EIUDHDwp1tXoGXmTfyD4cto+pCwqCGLJOWr wwC4d0Av/Atdo+N4iePxrt2HBhDSWQsX7YyhntjBJD1Lk2LVt5qmlcxU+maizcLP afTdCOHIhRIbxf2dhrxOD4Vk6ccq4cvzDLRZ2r97H/saB5xQDyZkQn29jRFBMWuU nCbcVqgpfGV7shz1oecn8KyT6+B4Yxzv3SuxkUchZMX4FMj91Unr6B2XQ72X6ab8 Ura6xaWuxIjkqTxKgwu4dVyujp3xTFA2DzIxdKogRurMLOvWBpAezOXr6whVrziT 5gF0JfFyDevdNWAB0YM0MGgoCncI4lsR8hwaxXOTqh2Z8o/L3+ec9u7vckNOQinT fF0t7Gpup98Iu7uo3k2dqNtmUiHfX1PLhqtqdGhDjQTtjiUzHaOX82o3M3oGb5u4 79c+R3snNtG8PlJDnR90YHns2YbRkJrFCqJ1qtxbN8qeWwUv5/Dc2Tmv2MwP9tUW 34/0gmz9ylZAXK53mRBCdqPVboDKJd6rWK512Z41Yqire0T37qO0GrauEJMtVuCV dvO86jEc75sJcs/mGM0EGYWL9PlOphq/IHyFD1DHdA2WoieIyIg8o/DBsgw5xKW4 wpu1Yaas3qG/X6XIMIGGlFl+H3g7gmSgmh1SjMsSnMFgVTMRmLgn1hnOaXNLrBDv nZlhrfVMKk4dCE9JfTnlC2J2OdoGE9bmW3c4IKLtlCTyoyZn9hlzfW6zprjV/Cz+ ZtnCv40nO4GozXBlixXd+OPPRF7cLLBwPYzMs19zbqZcnF1ZYVZuEoarSG+yKMOi ZA9KPOwu8BVGoLW7WKG9XvTPpYeEUG1dNBnJyUGxg+m7CVM8f/2q4YBaJoZdmDBa 3AxCAFckhJIk1SUGt3+C5+QBwPU2g905umZIZ8cH2X3w6T4M+bjYdDYj2+CfYV9R x1dSNwxMM4fVF4Q6/H1efyFjLeIpweSzqU9ZayxiDsVE+3LqPeJrcDOSDi4Qoaxz Lub/4KJDkrFw9FtDDkM4VS9FVy0BzbHayla3gWqmSBnjc/7TEuWEfKl2oULAklME aUAsKzw3pTXi63nFtS2nJyWDr/Te6peHmpXoTtXbUi5rIt2tcRqPEOowxjrSflnb Xv+1CWbTqGkmf/gXpapbcNgqKQQiR5lsBboXApwOutGy8rw5lhUc/88rI4oS44el vWhFdvBoQSuZLOXku8OoJvsv0HVLYa0apsDdCaI0bcO/0KZZKAy3VTaMZq5isgyT oAs4DHU7LY2SVFCWFt9Abv10Zzsjl2Ai5br6wfhP04tV9/VdC29MFN8Mv8PfA0H0 cMgm8UdWwRFdDSYyqh+/sdfMXRsoXUU4aDWcisn7CAIOqfFj3dkUkfYZZaFeTQEs 5k5pDn4xeyXX8wSyqjTiei7iK/rOmRPD4RyuOCG4KMmO8fJDNNuOQX2IhiKJSHGu BeMrXUDZ4zGmjy1Rk8gxK96HYZRV7uEmaV5deVYh3w1CejpK3nwN+uVCM2sAdLV5 +853Qp7/GzrCujzGbOUAp+h9nQy7YpdTRDeoffE2TKBc5jVXnvKRUS0JyVVnEtTG H8gn/MacxmPzp72vKecGoelMMg== -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_rsa_encrypted_hmacsha1.pub000066400000000000000000000006021465436372100265120ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDIUGLfSbG/8i18Y53PL59UJ71RN4XTKJEvVljZM9K0HvFkc0wOlzTOXoOAEJiTIq6JXVWjq31BJoC/x20ySmaj6hSOs6NGrnyxXzSbM4E+PzJo74avh+NXZ6ojD3CKg7XuShgX5+PUqEiAffK3TdzRX4NlkIfiIaHi1O+Q5drSGwnoB1C5sNeimLDhO9IPo699OvQu1Obh06gygWh5pnu0NBuiv7rWwBx9S80fJvqhAQATxv2RWFDqcvn/T0WApJs5FCpyLxKozTpOenB9OGaEEz3mpg6H4KPL6UwhyC7YLr3rRKyjff08uELvdQzsO8q6tO8uOaQngLFhLe5lrlV test mwiede-jsch-c8efa3f/src/test/resources/pkcs8_rsa_encrypted_hmacsha256000066400000000000000000000051361465436372100261100ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIHbTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQINQ6pBY4N8X4CAggA MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBCj+GNhaK8p2R+feHgNRcWVBIIH EE01wtlgC5EVkPa/OgdN7MA26FSIDHTNqj+0rDhzvpgrw8R3IFsb7WZf6klE5Qns Ct/mZWt6ddMJwiI3xjPOQX6E4aJqgK5NanwftcuUjKICrOPseXEi8l+P0vwInn1t zaDxFgIqo+N7L/0MXiFbubk2eoUfpj/xPaGz2DxQqilQabJfWGy6S3VSw1yvQqKP q6IFJ9N+bRXbrrIRD3RgAkMfJr5MhFdwQPrWoUUr5U4s2JHY6r9hEaVn2UqCnopF FUj3aX2JQtLuJaTsRw4MmnDcPysob83w+njx9+1dldXXNW3hfWZ3y0RhFH7CfbAl h59yzS26rKweI0ir5Va+SVfdjHQWx8ICYr90rTt1tL79DHnmrwK48RJe0/mJ+ITc eQdA9X8VcI0mRQRdACHt84N+fzNG0/w7iiCK9jpS5hePO6cUlgkpC9/WoNrTSV7R NFTEmSp6LfTdMcWS0mt/8VdpwOcOlxe/UuXb8JSMk45ByutkYjrrvmDjx6hQLLhd urPeSYiC28k3zBHQB+PVdbrX5waHIQQkEykYjwQZR+ICh0fwveDPn8Xhl/ZslkTm xGmez+ZPssAtMLvlY+oDm43QjLaUBkwP8BH+vbhZ4Tmv2+Fv34+Dors4L4IvwXlf nun4UilFHoMbnZKWDTAQ2DvPU8DPnEVVCuE65nhOLuHhxdjMBc+Bl3+RdMuNGKb4 fvW965RrDUNMkqQK0mqHVMtvv4eJiZAR4FQa2SzQ+9bHBv14L2uwxI/d8nNUFbgh imG4mnOJ7LacUDX3ewI/G2EgdJDVV7e1CJbTPu/EftX4uIkPite3JIcwF0ajr9+d tm3yYAr8jLp1ZR7vh89eBFj7NPAjG8FmxjEVMU11lovND7ioL/f+FITl5blUqZok 4OCoOppa7BoPGULwB+fV5xiPa5V9KB4OqsJpIoCoMrxVMGsEkCgu358vdmbrMckg B9yMPFfU8dF+SI6Galfz3/iR3x6FKW4TiqgqkrZbpb7zs1HhnzHPPdvniSatgOEa QUSb2yZdO46++/2j+kfmhb7cx78ZaBQFMk1onv8sDBUY67LLD8ma3QkTJb3aKhpV gwK6NIv9D+F3kNrpnscfp7OsvZBxIXmMBsmH86TI3k/x0/tjTD3Q1VYSL3OAetvc uXz/WTide/T1EVSTdrv8H91QGypvxX9RIrf33KRZzCAdeGa7LABD2aNmhgif0gzi 0yzilnfBjNZIZ18Zb0cbJYPr4Dvx3A8iqhCjJczN5yxe5sjQB+sxE6O1bQWOIG1r R1crXRjRTK3oauBiAfKTHmlmNUl805QBgjnMmeQLNGUOyVC0IdV3d/Q/dc4WEM9z QoAN6OPWNhZJLVNCLYl7kDtj3GcjHde/QzGJjkrB/ycP989MXk8B646m3uEYgVFP 0HZseOF30gTvnLHNV99nDL16di6rr0St92hXtwOWR3NrGSWnzxSewP/d+adL2DEp TIF+WAFmbXr/iaAMPuiI2TegGiMf1YuWuth9vNN3E57l3vKpPXizh0q0617nCS1l yOkN/9ekjD4Cb8NjVdAxWlI9ibpO+ZNH7p+FzkxyiWbc5HcxGQnVcPpoZGiPpCMh TEwlaj0YAuqb6wWksEpOeb7FAKslGkQR2Azw3JH5hhpRKsVdJcVXVEKlzizazC0N wwe7Fm/CUdOiM5pW0/ZkvX13lRxxwWYRczpZ4hcu76DF8SMfO0Sks+BF1qNU87Ay Ic23Nc4Dr9YiTlf2/MQmmQBBZ6l+9Ju/NbZYSaPC69Mfkt+ENn8EYcX108Plaioc /rO1gkqE8g96ABvmddCRvqk0O9aV6odMCBBzeaV1X+teH2gkGTnhsE1QQhjScVxz LXU3kgtfeTZG0hwHI0ZZm4KKPn7gb+vNQ8oOz1Dm1lGaatUuiwuOMu88M/hqWwh7 V2l61LEe/ugCGZuCJFOyDHZpDeaTtX90pl7ijDuUfVZnTBfGkoyoIQScz8mJkKnr yOV9oONevpF5Lf7uFihRpgWDBc1UsjV+lWeZo+IEra+W4hx5ADwqsThXKV9slhdq /xJlbmD1hvFRHhdSBbiZ6UUCmfP8XxIKDi4Ghfgd0ysrrVWDOZPuws0lg1WsgUOn kwHwfN0KXYfbdl+VQ3S51inRJUWAWDDQklAwBvWA+S5grhFNHRONk5OOBLvX8Atw 86nFW63a0PR3X0AFzLAJZrqF+EZbeloQgX2EX8gx8XFIPTy7XoS1T8/Ezq8AIfXk JjF6aeBy8YAnRJn+4sPGAqX5QqktWcvIkD+kv2dZIADOhSRXxQq5ZA0WZchC6l18 1lnAq+XXHq8NxupJ32rrZ1IRf1VIYCsJRMNguXKTWKZUHPAQxWhLuKW0ZBQJM3AE t0Q+gYvgja/p8WiC3l6WnioqJdWD5/FEsRGLy2GnWsvI -----END ENCRYPTED PRIVATE KEY----- mwiede-jsch-c8efa3f/src/test/resources/pkcs8_rsa_encrypted_hmacsha256.pub000066400000000000000000000010561465436372100266720ustar00rootroot00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCszdi6vvJvN331KkQI2SVEtrwBHQunxWGfMP3HnSn4aH656Mcx/9a33V/W5KwKoSgVeRsHVnbjby10yP1PaU898hILUDFBazlJUyfxvMybiP6TC6LMomCFqoncaNJ+hR2BsEQmrIfmD+cvIFADz8zPtjDeOSAPQumP42C5uXJKNKYM8nmpCUrHo8qSvbVLTX/UC8mZweenxY21IxnKSZkkuLkRtqp7+p+xc6bYNfXcdb6LyrR/jmD2GsnEXSmWFPxvYGAErUZBSAMF2xYGG34l+lCB7Pzvpfv/mB0MK46YL+pdKC/B3JjDu2izt7cEBTlhd/TwzNah5OfsXtVJBNlYi9FU/Ee7A6+ylb5WnNasU165ngIVBBL5UNg8Hg/W6XJJmAVZg1PsRbikNNszKeaRrTC3X35PEr6uab5hlcORcAWV2FYoYWN8iIv0rFJyaE7InpxSHp/G3lE6XHddcJrq6BdmURez3jShrCYg7DdnE9Nx7dBX1rbJ46lLxKY5lQs= test mwiede-jsch-c8efa3f/src/test/resources/ppkv2_dsa_unix.ppk000066400000000000000000000024151465436372100237370ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-dss Encryption: none Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAO8/3Ymo6sXoRb7gfTBqwAYPO+ck8aKsoBdQIn2oD9cX 2EIjXaoUXv/gK8tVN4EN0C8XADEFXpE3AQU5WhVZ11bv0AXOqGOreoP381pN72ap hh9o989Ee2PET+wEXZnZ4PmftMcuhtHWC8Pq0coht7CO6Xt56ItQuvj3nxMwYc0h vEFDOpHaFCyqiann9q3W5bLB9+ek2tJg5s1AVQKnlGCwn1fj+FXY1cRFDsp7AxGJ ZPDSNjq4awEZwECG/QLQYiWT0FVILFv68SxQeGk6OlOGip4dKkdXPIhMqHy0GT0d iBUm//UweV44S9IXPF9Xsiidq1Dn0vDe9e5OYNmV8kcAAAAVAKpXVF5GLMgMtlhS vjICPOy/A+T7AAABAQDEFLE91TMvZkCGeAHHXHkjF02m3CafJ7qLej8RoTEeZxV8 Op/XlRluKNn97XF5G3DHp/DWGqBgawbBwqEq7l3V97zRHESMlivPr0UuCvjSmFR/ on5nFCbl3RtZJOHOUkamtv51zBfk124uw7+bpnm9aiDNUs+AHNC3SLSyvdBbz6+s gt3kqD+FZyk+7TC/sOm+zuNmducFDDQIjldI7gx78b8D4BBx33+P5qW12PSlKGrQ 7E1Rnk+o9WMSJosq/D7lV56waSV6/AJE9lruQr3LGEwN28DrvbVWen8KtvivGlJU wl1OK/hMBS5u+QZTIzN5M6iGB2hfJjBbF+LUONDNAAABAHBA/s/1ShLjRiIfenBf nInfjl3a3DSF9M3/o1fuY6EFkNs8MR4P2aeOfk0zE4gmO3vlT7TFs960tdUdIHm4 TFOo+PFp4pjvVSO3K93cAjzOTwMI4sPhB3rRJxrDmx1CWVdnBrWQKO78kLpLf63/ QB71qEe7MirH4FXZRLFP39gRcWknBtHmez92CFlzKzqLQXAMfaSbZ95lPh/bwgQ8 OCuYExuB3aw3QmoQQdzSJRfWfuCEsUMmJ3Aub/yUMkpfe+hmQwkG2v730MXp/uDX fDXhZKkoh+v7Mhm04wzpxtB/C1dYpmfSP/i5ews4+9Lo9me6l54xy3+k05PPBBhn Yzw= Private-Lines: 1 AAAAFBtGbtke8qQ6YY4xizrBFRlokJMi Private-MAC: 10e180bb416d61cf0196c6b1c9b75382f092c20c mwiede-jsch-c8efa3f/src/test/resources/ppkv2_dsa_unix_encrypted.ppk000066400000000000000000000024371465436372100260200ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-dss Encryption: aes256-cbc Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAKU4cgWySBcfMzYy9aSOQwvH5JM1/M4UMNIB5BOZocC2 FvJbEok0gTTbLCzGI9A0pe2bnr6EWx78v+aIH6p1GOmbhxZVY4+vkEUMH9Ee8v7X MYqz+CCefWWiAH2bXNa1v7LC9mImiuKmcDdHiVLJwrj/TH3c2EUYlcyQSUGRyOmi w5/auITPrAlmwhyB2ZXLC0X1qNKn+nJiwWxe+SsTXV6F38jbZo+fepbnVEqZ3wTU VnW2gpk0z+LRiLM+1mhASykpmRCyggxW7H2NyNGW+9jVTXD8WCqB/z0o+7PVCPS8 5qpyfNi6PhH+etXiYnyG8iGI19BWZxDmMCG8Sgr+AnEAAAAVALkJetYWk3MacexW EA0Xa78/o9RfAAABAQCeNE28P6R13v2OUqUtBe6oYQPHOHzMFdEk+qJoXyzKmz7Q uQiCGuJ90YUST3fhvsBCOY6lPc6zGfeaVb/r2loa6zm3/0DoOXc/dnU4sbB0auoh PlwmjFXDwTQF5BRyxuRWtvPuNgKlgwFd/GcnIwlgW/jRIF3j5wopM3m12+yhZnW+ gh575hjvf9edpra7Y1u1VR/jYEQRg+GuXFDvcGE3OTWpphAe0zfjwqIOMYYvx/JQ 4HMnB+FxJ4svs5aUOPwBXhMCT9YPWEWVr+1GBVf/VlKTrbapNODYEp0tuL2z8Fva kgquJ2XGY74+6M1wbhrrDZ+LPd0Iuwcr7N0ghtVYAAABAEU47Jcr0BB3XEcmy/Ls L+hSKudgmczV6QD+fxelS4mY3//8INn+wMRyQzgix4B5yGL6OzQ2RBGlqho2TdfL o5UOjIoQzOpZsjZu2TLZezS5Lpx85ZVuLWwqezx1NZqGDXhtDz2tdUV8eNbePWb5 788WXYXOW43ya6Z5RMoywkO7sZRziHH4I+WwlorUpDMgzzfGs2j91bpejsBYcSnq cUDcHJedbMmcUQ53OWocK+/MwoYi8+F/UBuwAoZ8wYauasMZ/ph2k8ygzWHCv7NN teyVAY3o5OvrML4sfu9kmgBIZKKfGZHeFptjQdQcOj7fTI3tuqocwiWVohYBF7la KvI= Private-Lines: 1 WJAxySL5c2ikIb8JusI0EABRvX2f8O3tBbAuCx4o/i0= Private-MAC: 3384ce7d2ed81d15d76e9f80c3196813800d241c mwiede-jsch-c8efa3f/src/test/resources/ppkv2_dsa_windows.ppk000066400000000000000000000024521465436372100244470ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-dss Encryption: none Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAIRPWjGVTl5F+y9uOPu8PPtFyjFy+Qclpqww/vdKq7GV AYPU5zdDHPvmEBZKfklfcROB5Ody3Bf7miR3RoLmmK9SZLDqEint+FdbvSWEooFY exZmYukhS9FeGUwttMOz4K4JIAPMVBxbGMPOL2AzPhE45BT2PPUpXMNZTLft2YHY hSIg30nsx+gc7tK7dkdY38pJ3Qtazc3jpyHnxT9o5qA1OdrA09nYHs9osneC4O29 uru4Qz+foNP8XbGbkl1XxfooweQiElA9kvoOX+IgtJGgX2fuexAl0VcRmeb8lYxC 0KOo9QL/HRW84nC8ZvwhiOXwbvN6X+tmKqTpcYQXgOcAAAAVAKearN3tBfL6HPzk CHzgGrUbSK1zAAABABW+7UNnhWAvSwiHShVSWm+eHjY56rss8OoYCvVRxDTLYhnZ s8GvjlHJTTvuPbNMiWYe/vqwKhBDkNJe2cw2on58GsJwLLmdhsZzGRuCZ5twFLus ZsjjRImjBTY5ZNYhdbhM4/527a7bSRLT+QPsedmaEvJHeSMHwDYwEb/WMsYnL7Xn QTaPRjetz1a64zWIYQU6PTHW+HRrQDT2Dh/knymQvcw3QC5/ZwNf9k1HS8FdE5HC 9G9eQfPCGjiFGLfVfAKbq6HslLZO4Ea8WnFLm5CHz3+mFF+1fHXkahGxlOkPGMr/ kSeIvcneiMAqUDINC7VcXShVAvATGyaVh324uwoAAAEBAIM8p/hq3+3N5V885fGy BuO6H9RFmmFsuA5c70CXm3A7CHLNh1+ql72WzaRs3DyTICexOtEy/m+2jFd2suKa Sa4F74OMQv4KaeeXrGuC8+EGdWFMN0Tf5UkvR/3igCFdxUbhfEa7qbMJBi5fOkkY 1/OCldoHHWwWmp7uJA9oY7AVaFcwVyzOOQtUxBL6rtAE8Bcff88H2TFT2vf0WX/f KMKss69uzbphIIxnqnk152lA/gVWcT/mhCWa6NBIGJqKTNppKExTcLBcLlglqmLF i616A7gm8Y1+gi3dnDVu/hWiyz8uOSE31LB4oJGX4fkhOcKgwMJbB00F2ZGPT7JM 4JU= Private-Lines: 1 AAAAFQCNWViCVJUIHWjoUKL46EXL0dwMeg== Private-MAC: 93e11b58c7d05304857d602a2b0db8b8047414f3 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_dsa_windows_encrypted.ppk000066400000000000000000000024701465436372100265240ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-dss Encryption: aes256-cbc Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAOex/Q9Z8ZKXJbCIQnLHKuJdhGNpdIIOsmFYpNGCClPz 4ZTZmk0Dbw7sn2KrshVAbi2RXAIz4gJn+MfHRF7okwgAgN94mMP6VG+D4B2Zpgyy qWRYSSdV5AmbKc2VDX+DVK9qKmHlEX3Wjm4Yfw3s1kGN1/eWwI5MrHB7w5tA8Fw8 iUfsRLnwTyGPBXbR1ATqT/obLAic6vogcpGojg1s61k8Rlz2bVMaYRu/RQsIdxvU Vi27jn00ClTaMGWKH1ZMhnmjedvN7qI7GcAUgNXFjOGa786aPXzJDC0JdNcmDoei 9G/ynTJOpMMo8oy4bJLnVqL/kS8v5k+P4JeIhwvgp+MAAAAVALGpbWxdf1geBNR9 INuHLoevUHjvAAABAQDijQTRDHymwb7TO5Lxy2P5MBvxlhTlRN4C+KIo5rnZMX+o FeEX5/hG18grUn7FYdx5/4AHP5EhK4GIcoKYJqnEjXvfSuvBvD2OxES8y9QI5Y0D ZSGyAsV0p0/9N6a/khkdJ5Zs9S8iFeeJkevIVsCskLRkz6rrBbsuiXB/N3ojtetE QfFuznFVgEJyBNrk7QuVvu43nWnzYaF98ah2o4C4HdjAds57XzyhDks5kJsi1mry l5jvbCSxcf4iZW9OsOHYcjifwfuM+hz2oYYf87obEIIMdOtsvHjMEfTmBqechUqq sRP6wzv0u6g8rReMBldaoG2HFGpwjvMM+PGU/zdWAAABAAhLKqKGhmXzW3ZugZft ycNwrxXFeVXFBywlC1qtDH8N/0aW4AvhWXBk2gw+rDXQudpNlVbtV9sT/+9JBM5i Q9txRfDjVeEzdOuXR2ch51p9Ep7KTYoSaBrBqL5KCxsz12G1+KJazMmlbpxQbdWY rAJrlRjTcHnYCDuhyUV/yCnrR+7VMAx5FyIduuRtYrCgo/+Z/Z9UklPU2596/pp7 uozkCBR+RkOm7+9ldU+U9YiaUWymVmXhohFJvy9O6tqj3kZYQll2h7NnGpKVeIqp 8wNW5BoCyVwV+fIuyCVsWg5vOKTBu5GR2Kc3AMc18Uq+WEeC/jsXZS53ItONrdNs QNk= Private-Lines: 1 zn+CjCYuUbnPlsKh8Ge/gwCgzNkTwlBn4oeqV6/G3oY= Private-MAC: e0dc648a379bcbf2087192cb32fd1ab061ddba04 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa256_unix.ppk000066400000000000000000000005411465436372100245020ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp256 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCo/5qxk4V6Z ZGDFHDeVBr7ayBkc85+7SPuuY2OnBSrObqo06lw3nlH8dcloRzCt7qYvbmWTutlT ujgSOJuvd3A= Private-Lines: 1 AAAAIEfIpXqum0vHuX3aJmumOiRTGEcPs8cB6B5cmKV7j8Pq Private-MAC: c2c907c13abcd1e429a8a53c162fb27fa32bf88d mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa256_unix_encrypted.ppk000066400000000000000000000005671465436372100265670ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp256 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJ3Mot6VLEk kG5HscBLY3geI20FnwrgQi2wzAKiktPDhF39ZavVlOMzvkIGgQDxmo8WoQllY52e d4e8+7KQ76M= Private-Lines: 1 Giq4fU1ffVMQzpRS7vPtl4eViHxNmagS8TmYqnvb4KsMip0XwtRkRd1tqV9UGS2F Private-MAC: 9a55718d397e4bbbc0c00003bdcf5b8648da7f2c mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa256_windows.ppk000066400000000000000000000005571465436372100252200ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp256 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCDseBAbWBVv O3A6gqqd2+Qm9uSTBPEFvvj/huI35w7iYhMmIjWAYwi9av867hF9GsRJaPGSkoWU IcA6QBXarAM= Private-Lines: 1 AAAAIQCY9fEH+jqw1o/AtlCcSjksNFSuUILNENI6mcLywmdQLA== Private-MAC: 9ed0ea63718ce130ee11733dec5f91abfc076d30 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa256_windows_encrypted.ppk000066400000000000000000000006011465436372100272630ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp256 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKIrHi0RIW1g bd9+rJLTPJ5qAyXzNjEHidpxBzRnN22jDcnvBjqnAtfWPBjazs2KHSn/RP+Ktyej Y1Q+mMikDDk= Private-Lines: 1 dYVv2mbM2lr/QhQ4Sro7ev9ztR0YAFD0ECI76rjyGRBTsbSH28KXEF4Vjq/eatWu Private-MAC: 7034973c6f35c7da66e86c2bed7d8e8367bfd8ba mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa384_unix.ppk000066400000000000000000000006461465436372100245120ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp384 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBCTReLXxPo9 3rpl1xlrrx7yYZgD0DzRieTvFO9C3a8Z8blHuZHNy2iljsIYeCPOtK9lcivx+faO rp5FdE2VDroGPdDY2ZAuwF4/UxBiGNNEXWBhRFkupBcM6RbyjvCXaA== Private-Lines: 2 AAAAMH0T4NXp6wOqp8DWnEmXGlmAD+I5ytsSdlhznBdprZ2+wPZWcoa5XME85BUY p3HhlA== Private-MAC: df1b26fba219f717cf75002855565ce1b3c065b3 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa384_unix_encrypted.ppk000066400000000000000000000006741465436372100265700ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp384 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBRylqfIuL/B zq92j3g4UHd3TOlU2aG1U/2W76hrf1svwNPNe5d81xXA6j7Uh+AxOYfYrJRQr9Ko tRvd8WcxbikMZs5O/dKG+xx8WmTcgvu+jVW4lCbZrZk4S7/hqIlVjw== Private-Lines: 2 mKo1enxDPaVSSEiOYuEL76/0NHTZLDCZuwy/KVXskXb2gwUu4cdbr7Vwj1IHnkBN GIBLGOWIDva5Spqj0XdDLA== Private-MAC: 4666bb8eeacc4a0b137edf9e7a32632298f83910 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa384_windows.ppk000066400000000000000000000006611465436372100252160ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp384 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPATBzcVXx8g +unFg+8RAEvjiY/ZSb98vuIQ6MAtFCkNU2zgUHI9m/Jn9FitFd/F7KlIh4G5/wMB 2dGhks/FYSk+OxgAmhjif6lKLfD5veRCLhRnVbhTQm1fOmU0Sy+FSA== Private-Lines: 2 AAAAMQDHKqb0OEYb1K4KBaXYiXqkC+ybUGbleKdkx4V4VPfkDavMdGsOoFsyquuv CRh3/b8= Private-MAC: 8ef4699bc3c514b09b56ff672f30237da3d0956b mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa384_windows_encrypted.ppk000066400000000000000000000007071465436372100272740ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp384 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGxZq9s9JfIv KluYcWj/f+OuiV0bJ9RLE8rT+8qF0syMvzZZVRqLmF+a9VxJ4uxxRVvmMQ1CXb5T GtLVdBv1SrviKWMoaBw/sosSMr8v3eoQ04f4bs32fx8/dN4JQbCZEg== Private-Lines: 2 aTUgs7URruvHriTmaMe12Y4Ow5smlllupJ1BnErif5PwHd6MrXFCzYq0grADQKpS 0QaIGRrtXq4Hb7vvq+c6Mg== Private-MAC: 79f4ff32f403112ce42a5206d0da4b9e53edf33a mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa521_unix.ppk000066400000000000000000000007531465436372100245020ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp521 Encryption: none Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACuthNYwDJn 4I/b0fdhJdD3ykWe5gMBS91H9qWt0NHh4QTYxVyu3npbLveRVr9AWoF36UYIVF0Z 3WjFV4u4fOPapQFNlGDf1DNn8aipy/5iUKY02z+AxnWIIjToN0IPPizMw3LApwmy 0UaBSw7sZyfxNHD0Nu8wXsP8A6HG+Y01zSMAqg== Private-Lines: 2 AAAAQXaGiZwhRZG+dlWCB8h9+wc0Qer7IjpJ3kiRyYXLTku+FloU3F0MXJiIOnFV 31joL2SC2QEHHLEmvBXMT48R8AYy Private-MAC: 187e49c327364d784c54b3221adf18ad544339c3 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa521_unix_encrypted.ppk000066400000000000000000000010011465436372100265420ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp521 Encryption: aes256-cbc Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAEUP4llO/qJ cKrD5gZ6L+8+JzEU5RLICud1jgVh+QgtuuAZQUztdee3GEPmR+C9Mv5cAHg138OC NcyRI1eukjFNDgAq3xeh0V6BwjZZur+v5zyTnXQASBwuI+iofZZqS0z8lsM48eIl uTZuo3siTlv6uvFLs4ovN/cg67QyGIpsKusESQ== Private-Lines: 2 4OKuO5v+JHd96qUoo18Tb440u71nbpZNpXqSgBPr2VK5OAxVy+lqeccRtpAcUyXu TU8TTrQGHTxGMNMMUxun9HDcV02oZ8It2MsywvtfTRM= Private-MAC: e5aeb1290b219010b58cde9376db795b17dc1755 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa521_windows.ppk000066400000000000000000000007671465436372100252160ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp521 Encryption: none Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAGIVlZVYKq7 1fKe0Uxj73A5WPmvTuohTARpvnJ0VB5zIHFEtHRuI7Qkn6pRGv8rbKDRKygv1kZc 6rFZ2fgfhLxXcQHG1LwWM8x+XXoWMJM0C0kpCEErKd/tCZstQqg4v2JO0iG5+wmo Z90Cru912t24fhFGfVeFIbLN/xqznIm0dZTN/Q== Private-Lines: 2 AAAAQQn76HAtrPDaRmvvO6XRFvuSRNt/onJPOFRF9pOFDZzBWbllnPf0vR5h7uOo xn0UoPNYc1rQAd9s0a6LvEpMRUCJ Private-MAC: d1deafe89f187d0f75d3d6eee2d292c5ee5f9dc1 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ecdsa521_windows_encrypted.ppk000066400000000000000000000010151465436372100272560ustar00rootroot00000000000000PuTTY-User-Key-File-2: ecdsa-sha2-nistp521 Encryption: aes256-cbc Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACcIEokqqdX r1cB4vJksHNPuIb4HhwaRqaCi22yZa1slGr5+KQhWc6TaRP2yEsXaskuwThVy5hN jfONP/uB5IMj6QCxnR3bA/knuB2n7YRFlbIICLmCxr6QI5bz271MxCB+ccJO1L8s SfEsS6IcxH7O3rYv7hDadwcY9t5VmsJ3t7A67w== Private-Lines: 2 plCduQfYJ2kW2Gbi2B6Rb0I0PXb+YgMTClhaOFJwpqV+z3GY9YK0VEwYj05cZya1 HjGOtG69IWuPjrI523dcNYOeegI2BAYhFJLq05T4R/M= Private-MAC: 3e73192522ebf55488bfefe8d5033294dc39a972 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed25519_unix.ppk000066400000000000000000000004201465436372100241600ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed25519 Encryption: none Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAINknjInRhIeQB0yCD/N+ilxpTNwD2OGA776pYHI8 bOdZ Private-Lines: 1 AAAAIKg8xC9HSZbf6mY5WU6F7OWr9VGuDnJWLayXM3omacpf Private-MAC: ce1310f32622d44cb5d90198d482772bdd6bab72 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed25519_unix_encrypted.ppk000066400000000000000000000004461465436372100262450ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed25519 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAIFYLKsn61Pg/YYmumVe7oXik0o+Ca/P3vvN0Om3K CHqo Private-Lines: 1 QGanXsZXxLK4SWcL9Y1JnGZxcbfBlZD4h2wi4YsyefXbhaTKCnX/+7SaRdXmFRB9 Private-MAC: 30b7b90fe3c142891eebd05cbdb9c5e06c6ba448 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed25519_windows.ppk000066400000000000000000000004311465436372100246710ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed25519 Encryption: none Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAIHh90f1nUVIpoKQoYxtD66cTGgLZ33D3hCxVqS/N 5R3u Private-Lines: 1 AAAAIH3OoVCpAhXZns3AaYJE7WXYQVUsY8RB7lwdJ9FXFS1u Private-MAC: 5942475d67b84bc1c89ad2fdb502dd8537835e7b mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed25519_windows_encrypted.ppk000066400000000000000000000004571465436372100267560ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed25519 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAILhbcrIlE43dp+IlosYszkS0c4zpwC60ec1MRwZu xwvr Private-Lines: 1 ARj/EPcb2v9tt/miQAJGKAf3Iz8HkzMHl6Egc5M5VCu+mkRRnB1DIN6wNYtp7ncY Private-MAC: 39813a46a634fd277b5a8bf379c804223df99027 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed448_unix.ppk000066400000000000000000000005231465436372100240160ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed448 Encryption: none Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADnTDrr21+87QbcPF+2Ayh61ot/Jtf0c9yTy126ki8Um /UUEW6uy87s/9gpS0OHyoH3GO3WgsUoe/AA= Private-Lines: 2 AAAAObILm/ALMj5npvYMwKLrb2gJu3ZK1pSO78zy6XPjSJ2SxwAFNcVi1ig9elS/ T8ZoChnKOv3P0qarAA== Private-MAC: 55827a80d4951757730ab061c617901d2c3dcb7b mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed448_unix_encrypted.ppk000066400000000000000000000005351465436372100260760ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed448 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADnwdqOa0pIeeorEzsEY7kskGeyZfhpkYZtbA/iR5Nyp 0cbPZnl9UFsfKQIYKJwPWwnim8BXTkEq6YA= Private-Lines: 2 /A3mDpDv6Qz0Ou4TR1tZEKsJDYbC5lIotFETja/Q0ZGpRTBjUWZ1xlVZAQwZhDqe bIXTpngJcoMuU9ca+FlhAw== Private-MAC: 8c73debd89d60515a535a88c0e05cbd828592cd4 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed448_windows.ppk000066400000000000000000000005351465436372100245300ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed448 Encryption: none Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADk5uIOJgx7OfFkbkRV43yMP37dcnIVemLPjlaH/WRKj LTwueFIgN5Mc4UYcIZtlbAaUhiiEvW7aYQA= Private-Lines: 2 AAAAOSPpYS2oZf4SDKYbuFSxf+CZzYA5LC7mVwEObSg/NcsadJM3l7chtEgC+dPI OnzXuIwAaMzPSs+KAA== Private-MAC: 14cf577bd1d0851fb5bd13c5a92695e0a04ccecb mwiede-jsch-c8efa3f/src/test/resources/ppkv2_ed448_windows_encrypted.ppk000066400000000000000000000005471465436372100266100ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-ed448 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADkVNtCwBIBWO41k+QYmuMromfii6QbjVKRxjxbTYGPD aw8u+gSCHAnqgaxi9qkc7HU0U01BJI5tJgA= Private-Lines: 2 eUusIDlLKMS0TWcSwgfEx+SSDzlYX7QNXkkCZeOv/oc2Tx6/Jtsv7CnwDrVybF3f jbKnojgYqJ6OEV1uC0D8gg== Private-MAC: 216027b1e8ec6ff47ee2ac9f69e6f743206f8076 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_rsa_unix.ppk000066400000000000000000000026161465436372100237600ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-rsa Encryption: none Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQDsUXXjApfYYCtRK2LrymKvcZpS4cf6agyO j1/VW48g1GVtJM4g5kOjHWRqqsQZJCb8R9CvChCsJp4LPOS3tC36dSS52loeMoti 7Z3GtKORjPGKDO/byt7V68l02KZdaO6U91D73a7y9v0g+JsLtR4xkZMd1zXLK3Nn T43rtLg116YBsLxAxbAC8eeC1xBF7MNzdLbmg8Gp9dA6iNnDlUhDsf2/FJ8a43Wb U8inaNJh6eGd6NtL1fb9iDWho+JEhw7WbyoNrBAf4YlqO+3Y0oO1A4ezOspv3Vx8 CkoZTrtyCzVCPEIV/3wSK40VQaMxt4ptbPwQK9mSUI2dG3kuzkxV Private-Lines: 14 AAABAQCKb84XhlVdtDir/Dae2pilHm/BTfLQh3+DpAoH+vMF0Gb6YS0/qKTG0Vka A5+M+ti7wXZGlCbgMl8zRiDWXP7yUd2J4pgYSJPPCFP9K6UGhwKYVKvOnjGcL9x8 Ts5muinJqngOk/cA7h+rSPfLC/b8IsOEH6artnCMfNYu1ldzchjmwt8u57xw0Yc1 JqIqAnQD0ZFv50JsZzdHy719IgMFiqYnulAgK+mwGG6Fcbcz0Mi29dcqPkpDzFNz +5Dm0oV+oipg4oSMHBpF4EaEBXPshSoPCMvid2IBYqZk/0P1VeHeTfD12Tz6J2ag 8bMxYh+BzBh9Lk23qLgbiy+zMOKhAAAAgQD3mVM5gnJvON4be5GoQHPsoZCLapFm ykfGxbtexc/96T7k9iISHMzzFFss3+kf+wTiM+M/eWMCGMNfeDVqCLQKXvijhnGJ zFsaEd2BAem7r0yBT35o0jcSNskHOFP9ZLmv1cx+QS3AMvW1d/Wgrdzg/n/N3oSy 6xG0lwYAP18CqwAAAIEA9FYmUBuUGP2fIev5INsIS6ffOiTiSGRjz2yRRc0SDVSL PLknhdPrPDFJKvhOshkr+A3n2t/oqGI+ktbOuUxI7uhlPDL3D6Te/1ysObT0rXGR 9cV/SE8NKWe83J6wG21u0AZIgiOYKAgmUFSju93Pj22s8ECmmSTh0QwJV3If7P8A AACBAPZa+3GZW7AwkHCPy2zjnCC49nnjVc/ZqodJiQ+95T4QQK8MzqlrQ+bTsoAS +nN4WA9eOdvF6WQVrt5D/oLleA0I+c7iYd7JAOyiAVV75rHbBxpEUNgzP+VKymk4 nR8N5IcbZJ/XXeUzQX7HaiRZansWPb+PvhbuYvKNsLD8pjr7 Private-MAC: 456c364af11080a5032d3f01cf0adb5c425a13f6 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_rsa_unix_encrypted.ppk000066400000000000000000000026441465436372100260360ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-rsa Encryption: aes256-cbc Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCXX5GPy2zMByhViM5aW+lVH3oPVBVvsfXj b7Afy2ldttHHkDMhoQKMNUScBTdyLwHrje6c0C99aYNkSl5TLXePWx4nIkNFrEyh OfooY8CHPTuhCjfy+4A/psxeE5aoI5YGfffSr0uOVOUdhV3X3p1SmQsybzSiFz0T HULrtirxoCbf5a1UGNafYoXPvtSS3/qGJnsnbxE/gL2mTEvOyLI7o3ffFIgbfOra nbuow/HSboX/Uc9i2FsbJR4i6K5A6KB3NIL3gFJHxzjumJB4QXt7mUXzo0FWnOXL ORFrzYd1Rf26AVcUc24wwStVAOtXO3EIr/AylwgsqWqoStOzoRFB Private-Lines: 14 8ObwsQzQGN/DN+sRAL8BwisB6emytEjK0EMer4XyScCaZWg0rKrGwM8HnLaenAVk kyNcE6/Pe7/jPLJjqG2qpDo7eFSWML1JZdrByEbzsJL0lSKEIgJQEWw3ozl7eLD0 Mmhm5WC3qivygw8OGXM6IZyT8WnjsUZGFUlqt7o2cZ7hPlrVFoIumn4mWlFA96EY wjyWEsQiYPVtwuKIudwXrLWD/BcFOpKajNJ2xiZHDe15zPvJPTXCUiLP0/1OqEFC 5MhUWbQ26igKx2rMjtx0fN2I+U9eVBIFuNnqAh/nQ0gMet55H5fBkSwWUVSA8Wt1 SQBTlbtWx828EAeycBdLnUxJzhNWmBMz4ljda8cBecKTKHzAhRkxA7KgBiml3omE jUR4ZpxFoaL/y3tdMI4EyNnOOgpaHARamAqIrMB5JUEXNuYw+aOOkQlXmi+2JwuI 2nggRicIV1+Tlo2Zi9lb723J43xlvcdSpULo8acFw60ybn9/Z+lkQjHRN1W/AR0d xzB/ytvIAFO9pHiRJrBkJ8K7GBGOR5XIrE1mn64zh+lgxhGdPyw73f6uBeeDKl+N QtPI9xAtX+2ENsJCXzbdVF6GSYCNQ/PomZz04LiyzvGPLe2xyt5EgGw5eR7ii7cA YdJsFgOSyqZm12NnuDFGlJdIHiB+nK5g0ZG3Q5KvI9xhJvYFaeJfGplP8ky3B9SI BP1xRUAzbmdxs81LUJMQtNZGZFC491iId4LAGy2SPGkiJ9OsxZ7UM3mtX8LBd+Ju R2OQZwMLJgGXkAd3bEphQwTFUnIAYHql6KTVbzxoZU+rjFrgFaphWCoD8HqOYx0W ELK8ereV7vQVFngbQIiazZaD/RyYbYkLJdBO+PE9Sv9LMqr4H8tiTrRCDg2EwYk1 Private-MAC: e00e7d3fc277d5fe759477456f348ae71c78fbfe mwiede-jsch-c8efa3f/src/test/resources/ppkv2_rsa_windows.ppk000066400000000000000000000026501465436372100244650ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-rsa Encryption: none Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCdPnSRJDt/YuU5Oj1gq6JKYsJacWbgsdU+ vpzAT7IiIVOoGB7oPi8EGcZSt1kIJBc9Lf70uRYCbCmq3v3EOLGpSdhV16oKQygS gSZawq2YwYHzHnonp6akLfQQXwE/nnubX3S6iYAaJSrJ50APhKfQXYsz4CH2alrz Yb9Y2TDl4hKfxYABgMza3O02BFooK2tbxy2+0fbOKB/qjamGVE/CoMcv4ChB9FDG dUr0AVy7BYtfELAZ1dPrUh7lMCXa6JRRhFtdRWQGKmfM1nH/KpuzB+yZsl8kfHf4 7qiX/mwTQM87JMxm7HuV8pHHr7DNFs9g30CreF+hbY1Cx+IKh+eR Private-Lines: 14 AAABAQCG7sc8nWjpAUZOe2mcAOx9BI5e6h0sB65D73G3nSvxGcQd5MTw6huSW0PS Sz99OusuNsAn5IO8hHClDkGZFkVuTc30q+JgeAx1BJqTG6e4A6WtqKOOT9Ex5bUg L0Z0/1x2kc0rHT7uMKKtK2HPbzhKF1uSomzCdbWiUGjQp1/Mg38Hvy1KETfjAb4l 4skIgqvCp/iIqd/2o+qonID3VYGRohHuf1BfGcFuwAXjwy1UQztPopHn6eclSLKd J/YpZHkw5t4UNN6NZ/vpTlU0H4DJPmXFsW9lPT6qTRjrT91vumumwlV5vaEFOZdZ a/b4KSh0QRs8Ae/X+g+nIRfT5t75AAAAgQDdovwknLlpl70yMktt2fvFZ1z/Tx22 lc2Gs7wgrRlj76R7Y0RhrpRVCt/Y+Z6trocw6maHrtYzpF5IUFSteSoYvKqIT5kq HDCsxnD6wlH9jmKoVovGRLpDNzSlNtLlUVdmkyTQmbJGX/YjWb4/B93e3kzkFe5e PqGuI3YjR8Y0NwAAAIEAtZ+mZsJUuJOImvE37AbBljd6LlxRyVXqaTuXx5hetJ7U VK6tbLmMUXSL5F0f2Ftg6+i093Qc2HsaE3+Dt+LkkmiPEM+o9FIK8xwgey/S8RQk uGdaP84Q+cqIC0MMxOUuk3MWK1yKRDOZFYgjkfZPvhywY7d7scCPgzzZjoW6bncA AACAVZHXu+Xc6VTaLjAwlLj4aV6vgcFBlJVP1GSBnMdnRqHrqYWMpmodsh6xjT+K DkX0wkheNiqcxFs4FCIsGePGDdo4kofnYo6aH1a7jjAcZMQWgS9DxRgJQstYvGfr qnaDGse0dmD/w6tyqEmeBP6AGZJBWx9SvzJ441NtAv3+r2c= Private-MAC: 5c60a7b96b51ae767b879915d64328bfbe2867a6 mwiede-jsch-c8efa3f/src/test/resources/ppkv2_rsa_windows_encrypted.ppk000066400000000000000000000026761465436372100265520ustar00rootroot00000000000000PuTTY-User-Key-File-2: ssh-rsa Encryption: aes256-cbc Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCPJDCMNOM7Huv+NNeP626Slq54aPceMLEa oqlfvLJiQf11b8jXcKfFgLlp/f0Ltk10p+5hAGlzBw/nlYRU85i7Eq75kSb6LPcQ 3SNY1/NkrNcZcFf4p/AKeC0s1qgbypvjWy7Zk8AUooPFrhIo/kKaPMouq4hcyENz 2VKgpdJ21SzTxjDASj7zd9DZP8uc1Lsg3ftbr8Mi+MFFQRnFPLv/w2zIoLo6xwO0 UplUIyAGAsRPDdRZQ50h9b5BFyFLnXUlwI/Jrpgs2J31Vg8J2j2Y3BFDgn/Mf/P9 Rsvdo4fp/y+W195198VQ2gsH2+Az+3Id6ySsGhztBP5Pl2Z2K5Pt Private-Lines: 14 RU1YnbiIpjM2kSpm91PPq6ZEsvAJiM1ZBle98bdLIOI1KhrXzcP5GlDz0khoUHMF 8uFn3zS9pAV3t6UC38KYBH5/sRni1wDf6nfnJ12VrOxeSE4q+5lC8e5MipOyOx1b RfwDb6o7tzUl8RHm+xmzihCHilUQB/05sDHy4JwMcN6QgA9hm23drSiCO8itd9tw fhidYahW0JkGrQf5rNkgYgCssMfAqcecurng+RWTU/J8M0BMbp8AYEUVtPvOK95J 0kWz/lFG1d6oC1d5bcRL0LL4Oz6PWaVNf7+cjBRkJGfqJYtNi0zEN4R5MW8QTKye C29Dqy2/+JLjaa2xVYbdFqwIgePENEJIu0/g+k6tAhMN0G8kLaApsclKEtYCdd83 wlNdpFvPr31Xna1y5mfpXDgfEYYUf+t3vcD0+IluYMRzkDwv/BN6QGB1q00NmWZ7 iWZv0NZzf2pVo7hFJC83pKXfnkhqaLlLywfyu8RYEmA3LwdFe45Dt0oS7xP6DnAq bzgC3L+tMGoHrrKUhefqV8ma4m3rnBzobS8OCzwIRK8Jio1BgQuYX4EU4eu2DEmU eVJENZDT03uNzvh6G5ews809qz3T04Gyj7gQLgh560BwZ+Q8CVm9LVyynht+DMgH 1CEGi7I8pW8aPZDcgY8EyS02NAf+kHUtHF9Y3nO2T0VyiBrHwyF13B6kuQATuWPu SRJpQlcMytjdwAx/iPzQBg2Gdbc1hmPVzFi9N4LWpTLncSVdwMWBAEKF+qZBkXx+ BjBal45UoAD8JiNa/jfRVU/BHclLEr0DU0gGeUcP+u1WGv1srHjrrDbpujj7qQfu kIyq2p6IPkaCjz+6wHoZzlyY1fHGXS8c9qpMw7f/VohWDUkLP26hCErF+eiAtq1K Private-MAC: f5e53c305287fa9b6b02422ee5de0dfee3ad1a5c mwiede-jsch-c8efa3f/src/test/resources/ppkv3_dsa_unix.ppk000066400000000000000000000024451465436372100237430ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-dss Encryption: none Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAM6Xy9zencF2KDhq1r0gTXBdA4AL5Rtg5GYd4tx6qlSx k3ZX634ude5bV8Io2UrsgvIDQHSfj+1J4sDpWnhMtT12KucddwAzLhb+/5gYEr1U CZtPn1WlsvOXrJ9pmAt/MB1KppyG38UX3QK6Z04oWspqHWJBfO0oquUUGx5Ua9JS neJCrzk++Sd1GkhjZElR51Hm7MKV9KZejn/tUZQK2FRjpfP50GsIlAs1v31OkY1g lhgs90/6v7PyV1ljp27Nw1aNL+CxOjA/wYnFo+jE5+EsW81oT8C06n4yrcFySWFR 96wOfb2fAuCl4K9Ma4jN+7J0RLMY1++KzCsAtppi4KMAAAAVAMbFE/Q0VL6xGj97 5l/7AqEVxWH7AAABAQCbU609B2d7d5EipWyjlETAs64vaKBXOAREcQr8HQfAkWmS UBr//brBdNWeA4TVla4hyKL1CBiP1Hi6pDQ12lCB+J30ikRqdi45y2MvOR8OfEDy 3sn94sLwswARnMwdfHWrPepfyVdqOnIlhsYWzLpc5EhfOThvL8YZ78tPTCqyui8C Oi3TznOFfW/do0ydEEmfQwJTlHi6dpFiokh+mpQVOlstehmgKzrolLEjccS/vnxS qsdWDwKErbtg0bYhhV3rztiMcMozoBblgCSDiVmvGBAO8GnIoyX5/J+UfuwWYQKY rtuZRfB4hRyRU4zKopPfQrZkc1Jummk959KgfeTIAAABAQCayyiO1dYHPHF6g21s wekxrukaXix6sab4m+OLm0bNRa+7nI3A09wG+otKajznna/mdjcIaWuhdG5S4+l+ aPypIUWTdM0krUu0A+9Pu9YpIgVgEFKVQX9PBcP5+WHanMaeYmLOCEP1WqFMJ5Hi RCJmssOKwZJygH/KEMIGaDGhYnSmN6R+41j8sDAoY9/00WlSTKqpmVGTe7bJGWom nhT08RsATIyvM2i/J13qrh5UfGprj6GsaE9q+Zjg47oMdZIRSgyp4jw9coQoR68T emOmkODmXaoixfrGT1FC9LbqOmN/iDwv0QvLUen3RTbbB2lE3LwObBXJRpd44Rje Mo7c Private-Lines: 1 AAAAFE1NvhJa+HevZ3y1nFhhtzEh3Yi3 Private-MAC: de384c789bdafb1acfb4ad240ede6a24ba92b4c45d22906b0ae348f5caeb4302 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_dsa_unix_encrypted.ppk000066400000000000000000000026721465436372100260220ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-dss Encryption: aes256-cbc Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBALvd0uyCDZFuKcpphdcnMEYVXnoy16rW5XIFhlxmvVSU DDz3DAGyXISyhyQ43BhI8R0OeOr6VpivujFu0srXrcxcgsAy6yv/6uAvaeLfekc/ JErS7OqVqACFmt5ISkEBcvWKnUseFRwoy2KCeiEo2GyKwyV00caLnYb1Th2CUNRF ZcH5p5XLj3gwFbPf7EdkKV0PHWV4E5ptFVVT/aRijCJRQn//FlSNlG6iOfUF4IRU pz05qivVGaHLWNOw1fSXK1Pc53qQqCAaEict3arhQCwSEKl1xktSNBDVmeapLPj7 LNcZIGvAA52Tpg3qR1rp/8a+bdtteNkbRg4Gfx2uBuMAAAAVAKFdLforDVztYQzh 7pFjN8qAjogVAAABACTsvZOw0aPNwdQFiaQik1F08HQrjlp298vgbjIZFrgABE4x euWMydEcxAKKEhy7Y9Go4l9shUddkHgk3Y+OLvAsifowqfc8Fpsqxh1WKLxnw9NO 5rjenO+kNeiwhX/oWa1VBMOa/O+iGTvCy1XcW3u0E1LqGVAx3DdkP6EHV91ma3d1 LWih/RR8ClERNaovnETash8NQCHAmKejIObneLtNRqyaiNohYK0t5EAtP4JutVwr snj3ZoSKrCZct2wVrMUkkqCsKcKygCsr29uk1xpVYBkv9zUn6V199ZB/uXanRLcL /vq0UYWGV9nXU0shVanMwHNQaMk8oWnd6hTPB6EAAAEADwMN1uDvQqkyKel83xNG 4Er3LsSCx6iARNWpaV1ZLNrtf2h6MnYCKdSdyVgRjIL5coBQB5yZb/+CXm9QgysH +K5FHXgnh4hjz8W8/Magj+qm3/SKDTmbLAsNvvvenQvayTWUGNQlfQET/tHvGRy7 gz4r95phWGmxS8Zu1NkT0RHl6xxcSqWmvvjG/m2MuNo+5lfKFa2+j+Is59HwN3ZK 5umpPlJl4uM5SkyFD+iUbptOVCXdVV4xRhIzYy4wllADQQHkbNQtNGJT7JEHuot9 2J3FWOCEQVw4F06j8NsdghKWIwGSlcHLHAbA8zZDq11R6vnhOFDwmfekxCwLXaBl GQ== Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: e10608eedddc7992eff0f91aeac654b4 Private-Lines: 1 0+i6uWp69WUFuFgBYYmfzrEw7wjMgKINMsfXSRh+JL8= Private-MAC: f962cf010508ca8b62f2562881179e2d70afe18bbea3d48939d98b695710cb93 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_dsa_windows.ppk000066400000000000000000000024761465436372100244560ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-dss Encryption: none Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAOGfXe0SXEr7JIMEZQo6rkTc6CfPIWsgqDYem72p84pn 6KykGD6RonyqDEfDoS0XpwIY2sCZLmwauEhTQtBZpMyix4sD49w+SjaHUP1aoAT7 iPFvsXXGNw9/jgK5a67NzWxmcl5XMQG/VDjtVLWzNfl9OXHMSNmGUKQmlPZKXRrm 06SYVZMDsRbgSJgi6PNOatuVvfR+b2hK+ppMpQNKnHXe/vpgcblZ1ViPUTH4vG+0 4PkidIbwHIIl5Yv69lUYOcycxR3yzd8ZC3a7qzVkxet+tGWCD4/PzfWEP+/G2TWX bRuxV6YEaq9POmI0JuZa7CAZ8iA/OFtYua3TB4cUsSsAAAAVAJzJoUVy/fnPi6Uu PLR8cCyhqB3HAAABAQDH61jRVXoAqKJRHgIWhBsrQMmAvOqVHyrALSlAchNT5cso 4e7Rd9ajJFg+hVZGKu5PoQdhp/8ERk8mnABKue6r9qO/6qT8NvCRuI0Wb8Sxgw5q /4hzo4BVdx4UhLqTRl9rF7B5wLSjV75HIsqW61ZcbT9+VdYpRaNg8/Te1jfqwgrT ndaD7jhkhU2P0Z7vHSRlzaeSksF6b+SRFu+bnQ6neBxZZTuMrSfKOSpp2ltLUvWr Q48GJ0I/uE1HbQehz9Tn0Q3VA2BjpfKgj8bLE5YFokveuqjFULF7EiL4CmAt6qhi QOl/f6zKR4gaLUjkVuvU/uyTr/da7/FfOJouETpFAAABAERldAO0JWHLr1nClDX+ ZPN8XbbpjSaWO+fFLQO0A7QE/2gKJ8lt5qi39GOOhmUO10johHaOupqRqe4iCRnB xMJeLxXmS2KbcwDke+IBRaid81ccocpcPOrpov582DjJuwZ0394Akyrc7uMonjBy +JJaPwpXHQS4SXRe7NybuEE4S+DsV6DNx9WG5n5PFh4YELbzdP2oJZ3hyZ2MiZgo 02ShziEDPI1vQ4BBAsknp6Ubzt40Gt1yjyNMbGpv8IIRZzu+H8CIRnzbCYKT8mRK e0HvTG48c6la0/wvvG62zfmbFYgkw0tQxgekpf3ojNpRJZ1vcQPgtvQ5IjkCYSF/ ss4= Private-Lines: 1 AAAAFB8185dI+D57PqqRGfFcBGxjParZ Private-MAC: bdd028dd46f482f8aad5a4ba4a40db927350d41f129f6fb80c3907cb51a22d20 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_dsa_windows_encrypted.ppk000066400000000000000000000027301465436372100265240ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-dss Encryption: aes256-cbc Comment: test Public-Lines: 18 AAAAB3NzaC1kc3MAAAEBAIYJqKE0jtG+HpbHurIu+kVIuQLrMrgXhL7woINHOHGf b/0O85u+3DsSy+s7f/M9bWUIqRtt2+JV2J/V28mDgF7IEeiP3OjSYspmoxnCy8d6 g313NcYYoCqG9f/yWrzSXQtK3hD8+KNqm68GQx2L6lceyyHn3CgUFTwHw0MNntOf Ak94PCoM5wOZCfqx9sZfTVk+uQb++aG8xcAqPoPQdTgaqrFa9lrp2Ul8RhM/eDpC mByg8I5tIsbk17IVzS0gLp9slfInhwr2UjX2wIOlVOnNmS8UHLAwhDtdtHcWYdFb EMpO9hFMJCz39JqnJ7g8qjct/bfMxAEqhwlGpgbYrz0AAAAVAL66GQDORVX2on1i c6drzCN/9f4ZAAABAA8eU3kzUacUj50ggFzpTLuBBztILvjIpNGnXy7SUG5EWCZX LvBPTjJf9idxL/0P42AlJqKpaZSsdDLeaPbyUsQ0B9R+eTVDKQd5po5kBmWcxqMJ h0f1XU1CYFZgN2cvzmtyx9euekEka/j1mqGLuXHRpX0vak/wsy3T8mEPlqLr09c6 hPUDG5U8NXEy3aWS5gRRj7wPDLAi1sFGo4ReUfjn6LJglbCi71tSirnV0dJJvVGp XA17RzetDgZmIjdDur6XdGz+6B07puj/OUTTCFSFzJC0wNKGS/OjY9+59ziFj+M7 LCA7HUAlYeL4n83EsZp4fHI09JyuLJppPo/4xxAAAAEAU2ThrVHZ3fT8JuXT4dgJ VtgoBTQVf1vbzKA/o5yrOCKj+pPLFv+mXSJxLWvdSUeHkaRZF76hCwSpy6K+Wt9s RSuL6qTPog8TT7Yhk0YgfMd/wXwYlhhoH6HqRIIQRHd1bIOn+n1DUWQHS2w6Ksd6 jnVDd5cte+sBRNFeNjRJPUg2dzFqYQUgf5bfDu6/mhISduez7BctGb0cWtVPyjzQ ivJRUVnLiUJJE3V0saEC2FYOalknyW2x99tolUn4YwOLjUuQm1oKZ+BEbXlgGe4p Ke/JxB3nYHT78wP7ArnhImPGK8b0+/JD4nAA15GEkFLRV/u9qyZJe/iwbpqKz2vB /Q== Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: b2f8dee868310abc40ef9d96abcd67cf Private-Lines: 1 HUZSXpBSW1DZJtQ9dCmjGPKRfqwKXlOFleqL2zzeK7Q= Private-MAC: a7217ec852a154487b30da65849d2f25a78d822881b739471164df5fa24c08ef mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa256_unix.ppk000066400000000000000000000005711465436372100245060ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp256 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLoiF7se+l2K wZh9oxhfTASh5diPDNvYbVgS98Q4yPE9uExiDDMeX2Nu9XLtnevuTWrmcAF6u6/o zI3BIkeHiBQ= Private-Lines: 1 AAAAIE+1J+zx/1g2rtov3b16NoLXn/cW+jdeTQrXgllPzlC/ Private-MAC: 9549460921fa6dc12d723f3985618f1c8fb719fca05f388a3405f4c3eee7f7f8 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa256_unix_encrypted.ppk000066400000000000000000000010221465436372100265530ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp256 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGrSiZUMuXa3 aTNDF/H+rTZb4wUBapMIf9QXzfoJI6hOYPcCtHGH8KChdeZ2U9W3ohzX/WZIX8IQ 9fpxcGyvpbc= Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 712b0ba1fdfd732b3dbdf061acadeb51 Private-Lines: 1 +RPUh/TDOJB+zgkGpLmCpmoaiQpD69WlNiES+pPbUQ1SF+fxZMhvme6k57zH6iem Private-MAC: 58dd68fa08d7fdb217db1a69cc970320bd3fa45706b8a5b2a1feaa03efb25cb9 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa256_windows.ppk000066400000000000000000000006031465436372100252110ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp256 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDMTBUib+twu te16i5Rs2zKlVDMam5/RMWuFcXs2dvIs0kLP5N06diHYHBqvMPT9N336KMChz0/O 4S/dXR1pwHE= Private-Lines: 1 AAAAICNn2sFEDQ05pZvx8Wjcd+m/fHnlumgo7Rr7nE7XZd/0 Private-MAC: a49e1637cc50016094abd341f817036d512f54f6a024947725e3ce9a2eacf67a mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa256_windows_encrypted.ppk000066400000000000000000000010411465436372100272630ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp256 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMQNLejYwJxw VlAGIVi55Lb0zfkz18CEAwqDtrr6xs2sz+vqRU1xadOgEzHeWovBqCXdC9wVja20 2PyupH5QPsg= Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 43ab4dfef809a010f8b46898613e7791 Private-Lines: 1 kChNCwDStowc8bfgLq8ZvT5PWqIe6tDfu4Cs6gwPAv5V9LOYJZhD0VzCLE4NsJg6 Private-MAC: d1bca120202371a62af6c718c51d15cef782baa2d5bf87beb99585eef66569d3 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa384_unix.ppk000066400000000000000000000006761465436372100245160ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp384 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBnR7wyGL+IO T7A7vKr4Do1OGlsMhBFN28GuKUohpkd5rvvZfe/9UNbdobFa38KmLWpxzAlL9Go3 AK6+7OpWz6HE8JHdrJGyRYoS87XVv4oIIzmp8B8GThUYiDt8Qh8FmA== Private-Lines: 2 AAAAMQDFnuMXVDcejvYI0FcivZkI2cZ750s1tLgc9U/zQUFIYyybb8oHM4UsPeko qZKs9xM= Private-MAC: 3c36b58ea113af96aac49762d118793c374fcb399f293a3a79d9241e37bb4ab8 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa384_unix_encrypted.ppk000066400000000000000000000011271465436372100265630ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp384 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBGdfKrIhLUFt iMfBOFdF1LulPAF3OKNqlahGbA0bf/LXPf7tmbJUs+GvozsqYAbsMhed1vmwfBwp aQdIG97JRSK4MK4yIrCjDjGwqmakX/hg/WUQZPi17463t9zSzFZ8xA== Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 72bcd381a51296c255fb63a40cc2113e Private-Lines: 2 ROTdHYRD0zldAv4hvurg1k/BV7QnFgj7IdvsC5OA/kDSJmiXs0yJqyYKzdydS1xW DrZV8KwWZO4GmvXUH0byDg== Private-MAC: 4139eedb961ba84cb1375927930738cbe9ecf7feff471ae44a567b4264b5bf5c mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa384_windows.ppk000066400000000000000000000007111465436372100252130ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp384 Encryption: none Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBNShRribjCP+ pkCkAMwdj2LjxNrZjIKHtylcTdohEgfHJTXzub4tbq6odNS3izPwgMEfX6M6Vl5N BIstk3c34+kDuJ/a+Cyn7lZ9HZPdDuaKE66PNp3zGK9linfzn3iFBA== Private-Lines: 2 AAAAMEWKgeXFZVyRT28hwsvRRB7H/ZhnII8d9uP0uhPPU4742NGWdsDIYtlEAW+N 54PC1A== Private-MAC: cdca5f9ec10f19900830e393483c95a2f96056545ce560334f37e75c35169ccd mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa384_windows_encrypted.ppk000066400000000000000000000011471465436372100272740ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp384 Encryption: aes256-cbc Comment: test Public-Lines: 3 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBKGDqZyyEHaK kg0ijDH9nRu86AiXmUNJcKWC05ksthEMheDRMyZtyqzIIwQI9Goum+Tktu3LeQS4 fBh9aNHwMP2xN5uvj/uUYxN1dmQmLQ4NsQhpz+DY5TtxHJ/tUKvNpA== Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 8de0354d6f5f58738c3756f7691e9b0d Private-Lines: 2 JuLWiPoGeL31caJQj5mk+sUE8BK4JsOqEZt24rIjNMcFU/zVrVD/GxnACvjwRAH7 mlL0AuHbi/5L0pFOLaz4/w== Private-MAC: 477fcc9f7ae260b3ba4715476a56c04871808e9e5353802dfa7b5caa3914c424 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa521_unix.ppk000066400000000000000000000010071465436372100244740ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp521 Encryption: none Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADwW+/zw0OO BYVS2jEOym6OctYKqb1/uSTegImb7XOcklV6HZSnkGDrp89gzXL6AgoFWMQkySgR 93l1j22kCwxGWQFQBLalq5ekPGpqBiE31QNot0QKPat2f4O8bw0DO5sUNPmH7ImK myxAjHGiCPhi5egoIgrgzHoGnx1ynMr32Pntkg== Private-Lines: 2 AAAAQgDp0Jv8HmHaLVbfLM9oSHMOjGKJ3/uZY9gC8IDuBovmnapY10H8f1Uo9GD9 Fpo7ZBTXNqAaHAh+KWvFYmUq5TVLWg== Private-MAC: de2f0fc2577ac8c553ab52b838f127f3426c8ca9de22cfcbd11cbf5dfe8ff6f6 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa521_unix_encrypted.ppk000066400000000000000000000012341465436372100265530ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp521 Encryption: aes256-cbc Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAGCln1Y+fp/ uQTIVhjoNHuuRGVSzHc8shdMTGUQz0q+TpDSEf+SViws/gS0+V73QggV5TcUqOIO ra4uD8mGSieuUwHea4ieXw+cbcts9lpYdjWkFmgSGwYfIVyosFZ+aE07We7fNRqS UpH5gyBpdSpFKAiBTwtv73FOIwz88I82E4HVQw== Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 2eb44562d24a9caf29194f4b74ad0af9 Private-Lines: 2 yJ0r68xbDPwIcsHmNsDMTQaWCPbEPF043Sm1oJJ48fVS3/Mid6iBTMffqbM4QdHs uVTyA5l4/Rh9GKgb1NZr+NMNthCmbDF34gEAbgc332k= Private-MAC: 3234726c3bd4ced9ad412585c8fd287fdf011c655e0d51e441be33180e571bc3 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa521_windows.ppk000066400000000000000000000010231465436372100252010ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp521 Encryption: none Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAA37JVxrRSM TbtG8SUUuPzzwjsrumeJD+100IbXoAcXK0mPbGei04TdyMTpfy1SDWL3YND5CSzc uHMOjApNKrxJ6wB8A5LE178vFKb7kvYo5SJq+YAbv7utQqlMH4sdKdywGwvdSTSZ XCu+mzx9ebdoyRsmPS7vBrJYKcQPHiBDa9iVMA== Private-Lines: 2 AAAAQgFaFuLM1IvKBh6hChBTqbN2px8shq+rd1YV59GcnV6zVlaEgbZ9Lpdz3SZc nKVT9/BjJ8Q0IRoko/jl5+fGsVp5Eg== Private-MAC: 517745eb8ed80dad2395e80999921c3abcb4690fb01b2bb73e4e232f177fdaed mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ecdsa521_windows_encrypted.ppk000066400000000000000000000012551465436372100272650ustar00rootroot00000000000000PuTTY-User-Key-File-3: ecdsa-sha2-nistp521 Encryption: aes256-cbc Comment: test Public-Lines: 4 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAKniAtk8UO BIVa/348YbbZAyiLgJKpbH+2rEB0tHG7YYf+fAAGAZJsE7K7bl68XzunBT1Hguyt UpcjzNgOS2hx2AAVJT1ObdU0IK8+B0DTXrntG8BMKpDjpHZJr/RQLEDljHt6kc35 5TLoKZygF7vUujNjceWFjSmBlFeCbr5Fl4KoXw== Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 9c4e53a5c080d688ac149f396ba7872e Private-Lines: 2 mpMJCAaqeTZ13LGQo68IepcXDAd0iq9nYG2pp9V+6dOVtXMHZVDVFsCYhD/vCeaj lb247g8fSDyxQGvwk/CwVtq6uZXO/d+0W5K3ZgFOnVI= Private-MAC: ec2a55039d54f981a8dc3126e820eac4c358800abdae76d00b91dd7226ec3374 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed25519_unix.ppk000066400000000000000000000004501465436372100241640ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed25519 Encryption: none Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAIFrJ3kAPWlhD8uR/Mo1dqhqtJIYACuH6vIh7/oP+ r8UY Private-Lines: 1 AAAAIMTyr4DIkFlwt9d07Iw2GX2KJ9F90y/GciEu20RwqF0o Private-MAC: 37c84944792d7dc96a40c3d92e6a1d3d32a5a238568503d48580bc032a23a678 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed25519_unix_encrypted.ppk000066400000000000000000000007011465436372100262400ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed25519 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAINnWA1NU5+6rlguJ4vDwB7Ro3wTO+ntaSPfmWIXj p384 Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: aa1e739cbaa9d86e771fdf499ad93a59 Private-Lines: 1 oFIxq7q4Xb3LfYANl6QhPbx/3poc5/tvVG5Fj0BHer9iHh5GrofY3D2P7JcS/j6P Private-MAC: c819ba8f6fc792f60400ad71bf577cc9baba13ffa696c610dca162564a405f6b mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed25519_windows.ppk000066400000000000000000000004611465436372100246750ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed25519 Encryption: none Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAIGGj5a3dN4+iyqsAXenA/CzejFmBNyZinnYHhXXc jbBV Private-Lines: 1 AAAAIDWvlS89N/MQ+7GMxk5N09vo7X6W8szaJ1mu6C4s9WsE Private-MAC: 4eb0763c03faad6289f10d2dfdfeaed6b024b959cad06e1e042000b97e176745 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed25519_windows_encrypted.ppk000066400000000000000000000007171465436372100267560ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed25519 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAAC3NzaC1lZDI1NTE5AAAAIEy7J6rEkUafMJmtqE8SpWZg/uYx6EcME5FH3E3H B3rR Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: b26d22df894298dac8ce32d3189e35d8 Private-Lines: 1 mDG3fado6OIW/+xkwWRYgi2/bU29GW1KQvM0otOqWKcJPpoySjtPuuja43FNyh1Z Private-MAC: f61593c72cbad92ea1443a8c3b844b8fe52f4feb43f0c03e6f73b84401dbd2a6 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed448_unix.ppk000066400000000000000000000005531465436372100240220ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed448 Encryption: none Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADkhFs87N5abAoXAcsLiYTDOCujVJngP6C9j5dSttY/E BgCQBMK60a0vt1lF7b7Drby5kqg7+IvkGgA= Private-Lines: 2 AAAAOaA4VTeL/Vg12PIVqPhDcT9qfUT0dIZolnGVRBbU71tD9DyyLbykR5LADjMG YVuHR3tKi1qkRyxoAA== Private-MAC: c2623760d10dbe581b7dc8dad41d3a40f437fb9ac2787e4a877c654776dfbae5 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed448_unix_encrypted.ppk000066400000000000000000000007701465436372100261000ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed448 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADldNmjRx57BM40rrc4DabuF0L+RhEkOcDC8/jAhtbdT O0X+sqgITai5gSk1JGlIrCRIF83Kvs0TKIA= Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 42327c0d92de84745042deb048cb888b Private-Lines: 2 MD0ereDMhZNnTbZvgK5h0GlTlXZbdVNJfzaKrHth4q+ZMuZK3ONfTHbMgRKtsuFj vRCgMJAJdq1qNCflJavE/w== Private-MAC: 9bc62748d045aef6be0de10ecba4b626e41504636a7faf284f6ebac39a66d249 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed448_windows.ppk000066400000000000000000000005651465436372100245340ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed448 Encryption: none Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADkVoUhABT+RHfYEGAMKySSyUSoJFj6HHcz87U+io4Dp e4ye88DGUU2Lnxfux/WQq61DPHWxQHo4GoA= Private-Lines: 2 AAAAObCkYvIfcF/UyhGmrFg1BIzY+m/1BjSOl/G7BXbjb/afcugNYfD8Mx6c3kLa 05UFTkTX858guX/lAA== Private-MAC: 6f19bb57b0ef41d6abdd1c555a6247507db32e5d022032c9744f3f735bceefe5 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_ed448_windows_encrypted.ppk000066400000000000000000000010071465436372100266010ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-ed448 Encryption: aes256-cbc Comment: test Public-Lines: 2 AAAACXNzaC1lZDQ0OAAAADkdO1HUptQ2ksEmblqqTM8loY2Q/Ep003qRxW753XVa z8eh9CejJvTO2FYtyHNib5syBD814By7C4A= Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: adfd1dcbca4e55bb379eee8123a41943 Private-Lines: 2 7v3Io0Ub3fTnNaE9qHuJ3Ua8KCPBQvDoznZ+ppbJdVV/gDrczoa2teEIQ6qonpYA pIjHDQ/56tyVpt/yvkJGAg== Private-MAC: 538f86533f231dce675843a305cf28bfe29f73434cb589bd08e6b9410f209a45 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_rsa_unix.ppk000066400000000000000000000026461465436372100237640ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-rsa Encryption: none Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCclEvT+gGh6exRwmgPhsN+PLMpcNltztLQ 1x8iKOsxCCbXWXRxfvvG/ye8lp4kEOWIZ1224UoG1401aNBVTGNUT7SVyAFSdnHG 7AGgFnLwJcxrsEHLX/f+gj/m4syNJfAg1PrS4O8IeaEnTdql9x4cYkzd+Jpa/OHZ Lgltc8SHezhmxrc5Ylm1IMHu6gxJb0WwQ1mIZ44IAIaYvNflal7dP8v//bY+6kvS 5iARk6hDfiR/wH3926r7U0pB3siNDdz5yq7rjvTg6igtOhQDSnd9Drp0yHjBCyQo iDqP1P2jhyfz1iDdf6u71CFhZK20rfbsUUHCjWilB00onvjjIDYJ Private-Lines: 14 AAABAHB5omK58xRA+e3dLW0BzEpRBg3dr4JOkGdOMGIUbKYDCguliZzBr9DJltzE gQK9VHSAc/Qbr1Zs3lWgXg732V5GBx2U10ZKKP7Qp3Y8ygGx1T8CFLEn1ffvzkFn Z7J4rx6WfzqeM3auEFIwfcC8W9fd0QOeQhrcDsw4YrNJ9sGuYIa/bo3VDNr4sbmc odnbHSmxQFam9BV7bfxFcC3CPusvh4BdrT3vkQjlFR+RQOU6nDPpQ3Z3SXp12k3k EoHClZuNKP1YCci8+uRWeobOo6rsJKJsmzFYnjNdPDH9ytQm2N7Pg93gB7Sqp27S 56XLoRSGzCeZqrW1Uc38wj/qX2UAAACBAO/PhzZFQOSOKydp+4d2U0ZM8YumRYYN OBCd3XtypcThMjwj09smbZI2bMm7xGySwEW5VIRmry8swvy3bNFtybhlEV3/+SDl spCCTKWUZykSCPJvWrt21LMe+DYvZRJhPyhjQvfStIjlDgyuJQVaPghx3KBaglvU e6OGaBLbu9+nAAAAgQCnJldXgo0q9RXeSOJtiXKg8Y5ykLGALpkWudU6VdYGurbU Q5Bu3gO3MyFeRV/GhHEZ3av0i63tfNBeOcWafm3OW1xaLaJDioHQ/KKlCfs5nXMC Z6Qp+56mhk48unpdvOWSe3qorazrgo4XefKa/9nn8O6Im4DDOLPzAWxu8jJyzwAA AIEAoX8jMlUD2McXRGBbRu3UoXRir0amRYONcYJN+kCeiptJl3WNETgni2Vt5Cgw 45mrIDQ3I+HkqhU+0cw6p8n9m4JkBQ7naWpyA32ofxdRPa9h0he5fZj+tDs3IQRY OLh5cZMOxHsymrnHRCgLkddr+P976niOWEFc73MFvpxM3qE= Private-MAC: 61abe803ffbf8f7ebd9c899ba3ef9279f08b433e9095eb248a28a38b45e6367e mwiede-jsch-c8efa3f/src/test/resources/ppkv3_rsa_unix_encrypted.ppk000066400000000000000000000030771465436372100260400ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-rsa Encryption: aes256-cbc Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCMTxeJiE+rerxDpf3UhJRVvaWulraY8VZr yHhSPnHCODQw3MsQ0X6ECmTs8c3YeNRBRhiaB6zOQorUFqFbAwO2XIFQgDGk9qSJ F1kwsVXKnReFqUQ4MQGjRt5odjHc4+00KnmfdLUubvLGJmzHYJ4Ia1+EEyzkUik4 nVTxdreXrvFEIEej/QHJlhVSqsL2oKXKVMLAJ6OvGt9K1pFSJRCyedHVmR/z3tfs iFqpw0R2P2WhhkK9jXG47tJcG9v5HPrGJqd3D+W982/YUFNFvLMVkq5qU4wEDFVh 1u7Z95dABtZm2TwzhrYfxdAIcYbZLpbFozWX+f2mEQRAbWws2YE7 Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 331886f5ea02ebe8d0aac746a408ede7 Private-Lines: 14 EpXqXpaS5gbssePDuppbh72EaQb4J17ReVx664sVo479mR07xjj1R24hP20H3FUr zYif4C0NuWWqyUCZ4ULyjW5+08m3SgQ5WOva9bPLryWpI6CTDTZ8wVQqkmCgweKt JtPVOtcrdCKze7udLa/Ah0PxNkFzsHNfu1aQfG6MnQ9p9orwzfy5A8pm36sxigwj i6hHKMdcJY4+eA7Df5CkccVBiZlKr4nTChoSsSmBnLMKNSwR2EftW2H1uk9UzjxU 5VozBBeTkOqU9p6ph7pez5tDIZPN3krzQETIz1dXhTRrueard5l4slHV7N6W/k7t JynUfkhiGfhwKEjD9GutdJ4oTTe1SNz/3ndVzRS/10uSCPEcn2SdL7QzxYG/lY3W dAyS6hL8bR3V6NoxdTx/RWUqVrTfI0/dZpUN+h1iSsApB3M8Nth0nFhgsmveSPvT K//weuOgfB7AtO0Jn+KG81sW0cBK4AlSr80BzfOhKpkgG5OciSw+P1VRE5eq3bzp iRgbn8yKmvVXbY4NSX2Nued4C2z8MLMv1jHPyg7UOPhb52LyBGqWdT5iOURqWF/6 Az37Tag7iDe8K/tFNBQUcazHNKFPnQpXPYJDo3ucRE2tV8txrhQws3WRvAh6n/Ag Sb6Rz9OymLeSh/VAqcrWHb7PanGZGIo9XeWXRKKhU9SF0+vqqdPFCbVsleyVdoa4 rIB7zOG15Rr81FaIVh2axTsKsMCIMiMNTOO6p55JT7ViVJr566LxgNA2FBZMEdhV lXIfxz9JlLaP7a4/rTt4sp00PVorVjx/CeptKCRyptHYA2nM6In/tMHkkxd88l8d 6JESwNXAZz9JTWplWdMa0e0GjZ7hcazms0gWzd/5pMPAOjnixqqpEulGzmEX8EmK Private-MAC: 1120af9034ed0384d24f636c7dcf926fdca1de80490322bc616b7f6bee225098 mwiede-jsch-c8efa3f/src/test/resources/ppkv3_rsa_windows.ppk000066400000000000000000000027001465436372100244620ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-rsa Encryption: none Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCyu2eTD/3HRZnFhKMiy7YLGW7WUsT1uEgR CUufHFbjwZqSdUMXplB7wD5g/iombD36oZtFGpZWjiReT8hh2k2dR5pzF7Hg9yTZ osuBu8YRSTjwicc/NHTcDfl5kQFSGz40azFXWn1xJqPRQesDGZ2rQVloCxW771AV S5hZvAybtM/qf6En7PxHJE4Eg7klvjH2bzhacDQch56u/ij+/ipwtqkWt40k6sMQ 7xtRIQH4AUNlqQ+3qpZxKfAl+NCbJ/V8Mj9BM3WuyeD6DYPwBT1mHXug9KWi7aii 2c/UvDv1xpF7u0mTRSW4Dkm7FTEbX8iPP1QF3ze87YEaF1qRkeMf Private-Lines: 14 AAABABoV6fb3xYU47kl6o0inzKjwDFIxgFeQjswVvDi7rR7Omd24SZOBDYwSMch8 L/CtqZoTzhKW38xAMKSnJkrJzrwewDb+BVMdHv64mNUVb8IEGtBYe4EJCek4DOom NLgkC78gyfHC3j4OcqhO45rvOSjOf9sEiyaDtf91qgWmwXxT9yfLeSXn+tbEBpez 1sUHw0Pk+Io2bG+jwrCEeA/sf0zBfoLAREAe9CcdZmhKpoXRadaN3falLpwH5fOk wCnnjdxRCFgLpDZXsc3iA34hhM/mO7h2bnghe6h2KSrqgWJRdGL/+OpclJOx+l8s L+n9n1/SMJtfLZ8mn6iZd74GAlEAAACBAPtVtmpNFNxw4S+arkhJGo5qplFQ6RNj bbaCQWv7g7sYfZQuzRyq+ar4hn4Y71x8mLJKqlBNebtfctq0SzCSvFc/jOLqX+LH /haOrM7WKh8QFVQ8UwtZZdzXImViEw4W1HGJvoLe/MksakTl6afYabLBsDUI04Fd RekXhcy7sC5ZAAAAgQC2DLMio0Bgvz+hPotfHuSrBb49Gyqc/Nzt3jvFzvqFywU0 lpXPjy/nCN7fEVuCusLaEM5KY0giQaLna/xDfcoFmpdfQR79E2NFu88nRf1nr4e/ y/2etw0Pl1Eh/roWDjBi5bFpDBU3eDjF01ylcIbDTb6klJ4PON3gdHJx4WWeNwAA AIBFMs9P/P9EIFebF91b4wvJTG1xS3b6aLE0jIHNv4inD/6u/4R8U3meGMlvzeZQ xI56n6Hk8IaCEXehAj+VAfp9z2YHtPoAfUD8mbCKdBzgpW1P1AeOTIzvsi3+bHbm ZM+e6cTsQGaZ9OJSRYCmGT7LiTRm6PQwyq+4FEP1t9VF3w== Private-MAC: 20cf1acc614037e76bbc47942988e0aa3bc5582df1a173be2c468149139a406a mwiede-jsch-c8efa3f/src/test/resources/ppkv3_rsa_windows_encrypted.ppk000066400000000000000000000031361465436372100265430ustar00rootroot00000000000000PuTTY-User-Key-File-3: ssh-rsa Encryption: aes256-cbc Comment: test Public-Lines: 6 AAAAB3NzaC1yc2EAAAADAQABAAABAQCnTnSVyVw7nyqnxy/WWUUuFswXUsdwvNto jMVuqltV3CTDHfX6+uMu+XBC6Gqr/AzHvwzOPvzR+/k+m5fV5zLvjfe3zTU1gs5E mOtu3YbOnn6il/IvVvU9ILq/5Dg89aIbSYG9R28iu8KciZxHOOpjgFpmoCiMAg8x 4OWRHc6irKj5VKTXMJC+5pmb4QZlSKal7KPqKyAsKII6IxMjpPNJejZm/Omw3QZ1 9YIN02ttbM8rwoLuPLi1DoZiAUvF7J3XTEUcDAn5y5upltk1Dx+bWhuth/sYZ26q ksxPr+KmtHwJ5R8pWJ4CXtENlwxQiAWftVWW8MeQlyN17qPW+Z9x Key-Derivation: Argon2id Argon2-Memory: 8192 Argon2-Passes: 21 Argon2-Parallelism: 1 Argon2-Salt: 8bfc7fec5e9a97b5c271a2ff59bbd42a Private-Lines: 14 BdVaIWyb2IRejqogeZj7d55V+oiRVB87REDIRT+2nsqmRpv8d9wkEZxa2hZD4JJI yPJoLHyl6LwKrGWwwCDXf0DHTePNAAASAcp5G60XY/rAz/DMtYUfjFKYfOB3SjUr G1hjswV+RHm1OT9g5lz7tkeeF5jd3JkZ+6vdqeTxKrosUdqkLkN9SDbVtyLnEnfK up5RVoMN6jd8UZG90HIsuwR8/G4UwYPwKpj/5RwjKUx26yKPyOCl7tZcrZbA8+fw UNsODwlFSNdU4roo1SrmVKaDQ5LtV+HXunIOTuxt0p/YfvFcLupgaWgMysXzmhja sAQyZt5RB7rJOlWXKVOXdd0UWwYOhYTgTItY7tljns8SffOQMt0j+DoLZdMJq1Ej qWIy53yqCUs1Nyjqv9J9ptUCUiDP0xM50Qeob2YpFK1gpOpPTBOD1GrhF9P33uYT lhlsz8Wvh4U6txuO3DaPkfmNn4t/0lVdBh6x2Tv1x7OWsebmUQy1Pj5ffJJ6N4wt UbGdAeiJ2IsGzHHRThmBrjCTxI14QTjIrNpl4Ntbj7x2vPXHVoDfgUJrkeFD8NxW NaTn+WdYRtod3wLcdM6YAf+rBtGs4gGWK+eKPlepJhia9onRc7Esue/svHYTVgm4 jdPhQyHPvunLfN+ryD1yZkCRfir0c4HP7sniolfhVYM2UBvzBj+HiauEEWXetFeM 96Cdian5ouUtwvKmoIR0K5KT7g7iDtH94WreGK0Le13EGV9gwEk33HEenbcpn7Db 0ScHiwhHp4sXsiXh75b1kEWAJZVe8B6xbwLegIZesXvDztCMYq1RToBJ7rrMdEoN uRkinI6LFI5JzxhLDRpsmfSEJQM1SqxRmyoBVn6Jrd02giL1CxuadULsNc4LV4B9 Private-MAC: 7531943a8f9d37c31a318dbacb9de07b14346541d5b100bd665b36a195daf60f mwiede-jsch-c8efa3f/tools/000077500000000000000000000000001465436372100156455ustar00rootroot00000000000000mwiede-jsch-c8efa3f/tools/bin/000077500000000000000000000000001465436372100164155ustar00rootroot00000000000000mwiede-jsch-c8efa3f/tools/bin/gen-ed448-keys.py000077500000000000000000000005331465436372100213430ustar00rootroot00000000000000#!/usr/bin/env python import asyncssh user_key = asyncssh.generate_private_key('ssh-ed448', 'test') user_key.write_private_key('id_ed448') user_key.write_public_key('id_ed448.pub') host_key = asyncssh.generate_private_key('ssh-ed448', 'test') host_key.write_private_key('ssh_host_ed448_key') host_key.write_public_key('ssh_host_ed448_key.pub')