Compare commits

..

1 Commits

Author SHA1 Message Date
Andreas Schneider
8daf03c564 session: Check the session timeout and use it if set
This checks if a timeout has been set using ssh_options_set(). If it has
been set it will use that parameter by default for blocking reads.

This is at least what users are expecting.

Fixes T33

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2018-12-07 18:09:27 +01:00
215 changed files with 8874 additions and 32984 deletions

2
.gitignore vendored
View File

@@ -4,8 +4,6 @@
*.swp
*~$
cscope.*
compile_commands.json
/.clangd
tags
/build
/obj*

View File

@@ -4,8 +4,9 @@ variables:
CENTOS7_BUILD: buildenv-centos7
TUMBLEWEED_BUILD: buildenv-tumbleweed
MINGW_BUILD: buildenv-mingw
DEBIAN_CROSS_BUILD: buildenv-debian-cross
# pkd tests fail on CentOS7 docker images, so we don't use -DSERVER_TESTING=ON
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
centos7/openssl_1.0.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
script:
@@ -13,7 +14,7 @@ centos7/openssl_1.0.x/x86_64:
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON .. &&
-DUNIT_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -31,10 +32,7 @@ fedora/openssl_1.1.x/x86_64:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_BLOWFISH_CIPHER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DWITH_DEBUG_CRYPTO=ON
-DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
@@ -47,48 +45,6 @@ fedora/openssl_1.1.x/x86_64:
paths:
- obj/
fedora/openssl_1.1.x/x86_64/fips:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- echo 1 > /etc/system-fips
- update-crypto-policies --set FIPS
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_BLOWFISH_CIPHER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DWITH_DEBUG_CRYPTO=ON -DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
fedora/openssl_1.1.x/x86_64/minimal:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_ZLIB=OFF -DWITH_PCAP=OFF
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DWITH_GEX=OFF .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
# so, this is only enabled for unit tests right now.
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
@@ -111,34 +67,11 @@ fedora/address-sanitizer:
paths:
- obj/
# This is disabled as it report OpenSSL issues
# It also has ethe same issues with cwrap as AddressSanitizer
.fedora/memory-sanitizer:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=MemorySanitizer
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON ..
&& make -j$(nproc) && ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
fedora/undefined-sanitizer:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- mkdir -p obj && cd obj && cmake
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
-DPICKY_DEVELOPER=ON
-DCMAKE_C_FLAGS="-fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
&& make -j$(nproc) && ctest --output-on-failure
@@ -153,8 +86,6 @@ fedora/undefined-sanitizer:
- obj/
fedora/csbuild:
variables:
GIT_DEPTH: "100"
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- |
@@ -170,7 +101,8 @@ fedora/csbuild:
- csbuild
--build-dir=obj-csbuild
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON @SRCDIR@ && make clean && make -j$(nproc)"
--prep-cmd="cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON @SRCDIR@"
--build-cmd "make clean && make -j$(nproc)"
--git-commit-range $CI_COMMIT_RANGE
--color
--print-current --print-fixed
@@ -216,7 +148,7 @@ fedora/libgcrypt/x86_64:
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DWITH_GCRYPT=ON -DWITH_DEBUG_CRYPTO=ON .. &&
-DWITH_GCRYPT=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -236,7 +168,7 @@ fedora/mbedtls/x86_64:
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON .. &&
-DWITH_MBEDTLS=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -296,6 +228,33 @@ fedora/mingw32:
paths:
- obj/
.Debian.cross.template: &Debian_cross_template
stage: test
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_CROSS_BUILD
script:
- build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE)
- host="${CI_JOB_NAME#*.cross.}"
- mkdir -p obj && cd obj && cmake
-DCMAKE_C_COMPILER="$(which $host-gcc)"
-DCMAKE_CXX_COMPILER="$(which $host-g++)"
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
-DWITH_PCAP=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
Debian.cross.mips-linux-gnu:
<<: *Debian_cross_template
tumbleweed/openssl_1.1.x/x86_64/gcc:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
script:
@@ -304,7 +263,7 @@ tumbleweed/openssl_1.1.x/x86_64/gcc:
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -345,7 +304,7 @@ tumbleweed/openssl_1.1.x/x86_64/gcc7:
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -387,8 +346,7 @@ tumbleweed/openssl_1.1.x/x86_64/clang:
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config
-DUNIT_TESTING=ON
-DSERVER_TESTING=ON .. &&
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -421,7 +379,7 @@ tumbleweed/undefined-sanitizer:
-DCMAKE_BUILD_TYPE=UndefinedSanitizer
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
make -j$(nproc) && ctest --output-on-failure
tags:
- shared
@@ -443,7 +401,7 @@ tumbleweed/static-analysis:
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON -DSERVER_TESTING=ON .. &&
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON .. &&
scan-build --status-bugs -o scan make -j$(nproc)
tags:
- shared
@@ -456,11 +414,9 @@ tumbleweed/static-analysis:
- obj/scan
visualstudio/x86_64:
variables:
ErrorActionPreference: STOP
script:
- $env:VCPKG_DEFAULT_TRIPLET="x64-windows"
- mkdir -p obj; if ($?) {cd obj}; if (! $?) {exit 1}
- cd obj
- cmake
-A x64
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
@@ -478,7 +434,6 @@ visualstudio/x86_64:
- branches@libssh/libssh-mirror
- branches@ansasaki/libssh-mirror
- branches@cryptomilk/libssh-mirror
- branches@jjelen/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
@@ -486,11 +441,9 @@ visualstudio/x86_64:
- obj/
visualstudio/x86:
variables:
ErrorActionPreference: STOP
script:
- $env:VCPKG_DEFAULT_TRIPLET="x86-windows"
- mkdir -p obj; if ($?) {cd obj}; if (! $?) {exit 1}
- cd obj
- cmake
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
-DPICKY_DEVELOPER=ON
@@ -507,7 +460,6 @@ visualstudio/x86:
- branches@libssh/libssh-mirror
- branches@ansasaki/libssh-mirror
- branches@cryptomilk/libssh-mirror
- branches@jjelen/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure

View File

@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.9.4 LANGUAGES C)
project(libssh VERSION 0.8.90 LANGUAGES C)
# global needed variable
set(APPLICATION_NAME ${PROJECT_NAME})
@@ -22,16 +22,16 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.8.5")
set(LIBRARY_VERSION "4.7.2")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
# add definitions
include(DefinePlatformDefaults)
include(DefineInstallationPaths)
include(DefineOptions.cmake)
include(CPackConfig.cmake)
include(GNUInstallDirs)
include(CompilerChecks.cmake)
@@ -117,7 +117,7 @@ install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
DESTINATION
${CMAKE_INSTALL_LIBDIR}/pkgconfig
${LIB_INSTALL_DIR}/pkgconfig
COMPONENT
pkgconfig
)
@@ -133,13 +133,21 @@ write_basic_package_version_file(libssh-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
# libssh-config.cmake
configure_package_config_file(${PROJECT_NAME}-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
COMPONENT
devel)
devel
)
if (WITH_EXAMPLES)
add_subdirectory(examples)
@@ -205,11 +213,6 @@ endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET})
# Link compile database for clangd
execute_process(COMMAND cmake -E create_symlink
"${CMAKE_BINARY_DIR}/compile_commands.json"
"${CMAKE_SOURCE_DIR}/compile_commands.json")
message(STATUS "********************************************")
message(STATUS "********** ${PROJECT_NAME} build options : **********")
@@ -220,12 +223,10 @@ message(STATUS "libnacl support: ${WITH_NACL}")
message(STATUS "SFTP support: ${WITH_SFTP}")
message(STATUS "Server support : ${WITH_SERVER}")
message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
message(STATUS "GEX support : ${WITH_GEX}")
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
message(STATUS "Build shared library: ${BUILD_SHARED_LIBS}")
message(STATUS "With static library: ${WITH_STATIC_LIB}")
message(STATUS "Unit testing: ${UNIT_TESTING}")
message(STATUS "Client code testing: ${CLIENT_TESTING}")
message(STATUS "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
set(_SERVER_TESTING OFF)
if (WITH_SERVER)
set(_SERVER_TESTING ${SERVER_TESTING})
@@ -240,9 +241,5 @@ message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
message(STATUS "Release is final: ${WITH_FINAL}")
message(STATUS "Global client config: ${GLOBAL_CLIENT_CONFIG}")
if (WITH_SERVER)
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
endif()
message(STATUS "********************************************")

View File

@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
# SOURCE GENERATOR
set(CPACK_SOURCE_GENERATOR "TXZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;/[.]clangd/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
### NSIS INSTALLER
@@ -23,7 +23,7 @@ if (WIN32)
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
set(CPACK_NSIS_MENU_LINKS "https://www.libssh.org/" "libssh homepage")
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
endif (NSIS_MAKE)
endif (WIN32)

120
ChangeLog
View File

@@ -1,126 +1,6 @@
ChangeLog
==========
version 0.9.4 (released 2020-04-09)
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
AES-CTR keys with OpenSSL
* Added diffie-hellman-group14-sha256
* Fixed serveral possible memory leaks
version 0.9.3 (released 2019-12-10)
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
* SSH-01-003 Client: Missing NULL check leads to crash in erroneous state
* SSH-01-006 General: Various unchecked Null-derefs cause DOS
* SSH-01-007 PKI Gcrypt: Potential UAF/double free with RSA pubkeys
* SSH-01-010 SSH: Deprecated hash function in fingerprinting
* SSH-01-013 Conf-Parsing: Recursive wildcards in hostnames lead to DOS
* SSH-01-014 Conf-Parsing: Integer underflow leads to OOB array access
* SSH-01-001 State Machine: Initial machine states should be set explicitly
* SSH-01-002 Kex: Differently bound macros used to iterate same array
* SSH-01-005 Code-Quality: Integer sign confusion during assignments
* SSH-01-008 SCP: Protocol Injection via unescaped File Names
* SSH-01-009 SSH: Update documentation which RFCs are implemented
* SSH-01-012 PKI: Information leak via uninitialized stack buffer
version 0.9.2 (released 2019-11-07)
* Fixed libssh-config.cmake
* Fixed issues with rsa algorithm negotiation (T191)
* Fixed detection of OpenSSL ed25519 support (T197)
version 0.9.1 (released 2019-10-25)
* Added support for Ed25519 via OpenSSL
* Added support for X25519 via OpenSSL
* Added support for localuser in Match keyword
* Fixed Match keyword to be case sensitive
* Fixed compilation with LibreSSL
* Fixed error report of channel open (T75)
* Fixed sftp documentation (T137)
* Fixed known_hosts parsing (T156)
* Fixed build issue with MinGW (T157)
* Fixed build with gcc 9 (T164)
* Fixed deprecation issues (T165)
* Fixed known_hosts directory creation (T166)
version 0.9.0 (released 2019-06-28)
* Added support for AES-GCM
* Added improved rekeying support
* Added performance improvements
* Disabled blowfish support by default
* Fixed several ssh config parsing issues
* Added support for DH Group Exchange KEX
* Added support for Encrypt-then-MAC mode
* Added support for parsing server side configuration file
* Added support for ECDSA/Ed25519 certificates
* Added FIPS 140-2 compatibility
* Improved known_hosts parsing
* Improved documentation
* Improved OpenSSL API usage for KEX, DH, and signatures
version 0.8.7 (released 2019-02-25)
* Fixed handling extension flags in the server implementation
* Fixed exporting ed25519 private keys
* Fixed corner cases for rsa-sha2 signatures
* Fixed some issues with connector
version 0.8.6 (released 2018-12-24)
* Fixed compilation issues with different OpenSSL versions
* Fixed StrictHostKeyChecking in new knownhosts API
* Fixed ssh_send_keepalive() with packet filter
* Fixed possible crash with knownhosts options
* Fixed issus with rekeying
* Fixed strong ECDSA keys
* Fixed some issues with rsa-sha2 extentions
* Fixed access violation in ssh_init() (static linking)
* Fixed ssh_channel_close() handling
version 0.8.5 (released 2018-10-29)
* Added support to get known_hosts locations with ssh_options_get()
* Fixed preferred algorithm for known hosts negotiations
* Fixed KEX with some server implementations (e.g. Cisco)
* Fixed issues with MSVC
* Fixed keyboard-interactive auth in server mode
(regression from CVE-2018-10933)
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
* Fixed socket fd handling with proxy command
* Fixed a memory leak with OpenSSL
version 0.8.4 (released 2018-10-16)
* Fixed CVE-2018-10933
* Fixed building without globbing support
* Fixed possible memory leaks
* Avoid SIGPIPE on sockets
version 0.8.3 (released 2018-09-21)
* Added support for rsa-sha2
* Added support to parse private keys in openssh container format
(other than ed25519)
* Added support for diffie-hellman-group18-sha512 and
diffie-hellman-group16-sha512
* Added ssh_get_fingerprint_hash()
* Added ssh_pki_export_privkey_base64()
* Added support for Match keyword in config file
* Improved performance and reduced memory footprint for sftp
* Fixed ecdsa publickey auth
* Fixed reading a closed channel
* Added support to announce posix-rename@openssh.com and
hardlink@openssh.com in the sftp server
version 0.8.2 (released 2018-08-30)
* Added sha256 fingerprints for pubkeys
* Improved compiler flag detection
* Fixed race condition in reading sftp messages
* Fixed doxygen generation and added modern style
* Fixed library initialization on Windows
* Fixed __bounded__ attribute detection
* Fixed a bug in the options parser
* Fixed documentation for new knwon_hosts API
version 0.8.1 (released 2018-08-13)
* Fixed version number in the header
* Fixed version number in pkg-config and cmake config
* Fixed library initialization
* Fixed attribute detection
version 0.8.0 (released 2018-08-10)
* Removed support for deprecated SSHv1 protocol
* Added new connector API for clients

View File

@@ -41,8 +41,6 @@ if (UNIX)
add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wmissing-field-initializers" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wsign-compare" SUPPORTED_COMPILER_FLAGS)
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
if (REQUIRED_FLAGS_WFORMAT)

View File

@@ -9,7 +9,10 @@ include(TestBigEndian)
set(PACKAGE ${PROJECT_NAME})
set(VERSION ${PROJECT_VERSION})
set(SYSCONFDIR ${CMAKE_INSTALL_SYSCONFDIR})
set(DATADIR ${DATA_INSTALL_DIR})
set(LIBDIR ${LIB_INSTALL_DIR})
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
set(BINARYDIR ${CMAKE_BINARY_DIR})
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
@@ -86,10 +89,8 @@ if (OPENSSL_FOUND)
message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()
if (WITH_BLOWFISH_CIPHER)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
@@ -124,41 +125,12 @@ if (OPENSSL_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_DigestSign HAVE_OPENSSL_EVP_DIGESTSIGN)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_DigestVerify HAVE_OPENSSL_EVP_DIGESTVERIFY)
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_symbol_exists(EVP_PKEY_ED25519 "openssl/evp.h" FOUND_OPENSSL_ED25519)
if (HAVE_OPENSSL_EVP_DIGESTSIGN AND HAVE_OPENSSL_EVP_DIGESTVERIFY AND
FOUND_OPENSSL_ED25519)
set(HAVE_OPENSSL_ED25519 1)
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_symbol_exists(EVP_PKEY_X25519 "openssl/evp.h" HAVE_OPENSSL_X25519)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)
endif()
@@ -405,6 +377,18 @@ int main(void)
return 0;
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
check_c_source_compiles("
#include <stdio.h>
#define __VA_NARG__(...) (__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
#define __VA_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,N,...) N
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define myprintf(format, ...) printf((format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__)
int main(void) {
myprintf(\"%d %d %d %d\",1,2,3);
return 0;
}" HAVE_GCC_NARG_MACRO)
check_c_source_compiles("
#include <stdio.h>
int main(void) {

View File

@@ -2,15 +2,14 @@ option(WITH_GSSAPI "Build with GSSAPI support" ON)
option(WITH_ZLIB "Build with ZLIB support" ON)
option(WITH_SFTP "Build with SFTP support" ON)
option(WITH_SERVER "Build with SSH server support" ON)
option(WITH_STATIC_LIB "Build with a static library" OFF)
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
option(WITH_DEBUG_PACKET "Build with packet debug output" OFF)
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
option(WITH_MBEDTLS "Compile against libmbedtls" OFF)
option(WITH_BLOWFISH_CIPHER "Compile with blowfish support" OFF)
option(WITH_PCAP "Compile with Pcap generation support" ON)
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(UNIT_TESTING "Build with unit tests" OFF)
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF)
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
@@ -19,7 +18,6 @@ option(WITH_EXAMPLES "Build examples" ON)
option(WITH_NACL "Build with libnacl (curve25519)" ON)
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
option(WITH_ABI_BREAK "Allow ABI break" OFF)
option(WITH_GEX "Enable DH Group exchange mechanisms" ON)
option(FUZZ_TESTING "Build with fuzzer for the server" OFF)
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
@@ -34,9 +32,13 @@ if (WITH_BENCHMARKS)
set(CLIENT_TESTING ON)
endif()
if (UNIT_TESTING OR CLIENT_TESTING OR SERVER_TESTING)
if (WITH_STATIC_LIB)
set(BUILD_STATIC_LIB ON)
endif (WITH_STATIC_LIB)
if (UNIT_TESTING)
set(BUILD_STATIC_LIB ON)
endif()
endif (UNIT_TESTING)
if (WITH_NACL)
set(WITH_NACL ON)
@@ -45,11 +47,3 @@ endif (WITH_NACL)
if (WITH_ABI_BREAK)
set(WITH_SYMBOL_VERSIONING ON)
endif (WITH_ABI_BREAK)
if (NOT GLOBAL_BIND_CONFIG)
set(GLOBAL_BIND_CONFIG "/etc/ssh/libssh_server_config")
endif (NOT GLOBAL_BIND_CONFIG)
if (NOT GLOBAL_CLIENT_CONFIG)
set(GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config")
endif (NOT GLOBAL_CLIENT_CONFIG)

13
INSTALL
View File

@@ -7,14 +7,13 @@
In order to build libssh, you need to install several components:
- A C compiler
- [CMake](https://www.cmake.org) >= 2.6.0.
- [openssl](https://www.openssl.org) >= 0.9.8
- [CMake](http://www.cmake.org) >= 2.6.0.
- [openssl](http://www.openssl.org) >= 0.9.8
or
- [gcrypt](https://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
- [libz](https://www.zlib.net) >= 1.2
- [gcrypt](http://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
optional:
- [cmocka](https://cmocka.org/) >= 1.1.0
- [libz](http://www.zlib.net) >= 1.2
- [socket_wrapper](https://cwrap.org/) >= 1.1.5
- [nss_wrapper](https://cwrap.org/) >= 1.1.2
- [uid_wrapper](https://cwrap.org/) >= 1.2.0
@@ -27,7 +26,7 @@ For Windows use vcpkg:
https://github.com/Microsoft/vcpkg
which you can use to install openssl and zlib. libssh itself is also part of
which you can use to install openssl and zilib. libssh itself is also part of
vcpkg!
## Building
@@ -117,4 +116,4 @@ This document is written using [Markdown][] syntax, making it possible to
provide usable information in both plain text and HTML format. Whenever
modifying this document please use [Markdown][] syntax.
[markdown]: https://www.daringfireball.net/projects/markdown
[markdown]: http://www.daringfireball.net/projects/markdown

2
README
View File

@@ -31,7 +31,7 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
3* Where ?
-_-_-_-_-_-_
https://www.libssh.org
http://www.libssh.org
4* Contributing
-_-_-_-_-_-_-_-_-_

View File

@@ -60,7 +60,7 @@ following to $HOME/.vimrc:
You can use the Vim gitmodline plugin to store this in the git config:
https://git.cryptomilk.org/projects/vim-gitmodeline.git/
http://git.cryptomilk.org/projects/vim-gitmodeline.git/
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:

View File

@@ -23,7 +23,7 @@ much easier to work with individuals who have ownership than corporate
legal departments if we ever need to make reasonable compromises with
people using and working with libssh.
We track the ownership of every part of libssh via https://git.libssh.org,
We track the ownership of every part of libssh via http://git.libssh.org,
our source code control system, so we know the provenance of every piece
of code that is committed to libssh.
@@ -85,7 +85,7 @@ By making a contribution to this project, I certify that:
Free Software Foundation; either version 2.1 of
the License, or (at the option of the project) any later version.
https://www.gnu.org/licenses/lgpl-2.1.html
http://www.gnu.org/licenses/lgpl-2.1.html
We will maintain a copy of that email as a record that you have the

View File

@@ -23,18 +23,6 @@ if (UNIX AND NOT WIN32)
set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address"
CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.")
# Activate with: -DCMAKE_BUILD_TYPE=MemorySanitizer
set(CMAKE_C_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
CACHE STRING "Flags used by the C compiler during MEMORYSANITIZER builds.")
set(CMAKE_CXX_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
CACHE STRING "Flags used by the CXX compiler during MEMORYSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
set(CMAKE_MODULE_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory"
CACHE STRING "Flags used by the linker during MEMORYSANITIZER builds.")
# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.")

View File

@@ -0,0 +1,109 @@
if (UNIX OR OS2)
IF (NOT APPLICATION_NAME)
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
SET(APPLICATION_NAME ${PROJECT_NAME})
ENDIF (NOT APPLICATION_NAME)
# Suffix for Linux
SET(LIB_SUFFIX
CACHE STRING "Define suffix of directory name (32/64)"
)
SET(EXEC_INSTALL_PREFIX
"${CMAKE_INSTALL_PREFIX}"
CACHE PATH "Base directory for executables and libraries"
)
SET(SHARE_INSTALL_PREFIX
"${CMAKE_INSTALL_PREFIX}/share"
CACHE PATH "Base directory for files which go to share/"
)
SET(DATA_INSTALL_PREFIX
"${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}"
CACHE PATH "The parent directory where applications can install their data")
# The following are directories where stuff will be installed to
SET(BIN_INSTALL_DIR
"${EXEC_INSTALL_PREFIX}/bin"
CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)"
)
SET(SBIN_INSTALL_DIR
"${EXEC_INSTALL_PREFIX}/sbin"
CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)"
)
SET(LIB_INSTALL_DIR
"${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}"
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)"
)
SET(LIBEXEC_INSTALL_DIR
"${EXEC_INSTALL_PREFIX}/libexec"
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
)
SET(PLUGIN_INSTALL_DIR
"${LIB_INSTALL_DIR}/${APPLICATION_NAME}"
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})"
)
SET(INCLUDE_INSTALL_DIR
"${CMAKE_INSTALL_PREFIX}/include"
CACHE PATH "The subdirectory to the header prefix (default prefix/include)"
)
set(CMAKE_INSTALL_DIR
"${LIB_INSTALL_DIR}/cmake"
CACHE PATH "The subdirectory to install cmake config files")
SET(DATA_INSTALL_DIR
"${DATA_INSTALL_PREFIX}"
CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})"
)
SET(HTML_INSTALL_DIR
"${DATA_INSTALL_PREFIX}/doc/HTML"
CACHE PATH "The HTML install dir for documentation (default data/doc/html)"
)
SET(ICON_INSTALL_DIR
"${DATA_INSTALL_PREFIX}/icons"
CACHE PATH "The icon install dir (default data/icons/)"
)
SET(SOUND_INSTALL_DIR
"${DATA_INSTALL_PREFIX}/sounds"
CACHE PATH "The install dir for sound files (default data/sounds)"
)
SET(LOCALE_INSTALL_DIR
"${SHARE_INSTALL_PREFIX}/locale"
CACHE PATH "The install dir for translations (default prefix/share/locale)"
)
SET(XDG_APPS_DIR
"${SHARE_INSTALL_PREFIX}/applications/"
CACHE PATH "The XDG apps dir"
)
SET(XDG_DIRECTORY_DIR
"${SHARE_INSTALL_PREFIX}/desktop-directories"
CACHE PATH "The XDG directory"
)
SET(SYSCONF_INSTALL_DIR
"${EXEC_INSTALL_PREFIX}/etc"
CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)"
)
SET(MAN_INSTALL_DIR
"${SHARE_INSTALL_PREFIX}/man"
CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)"
)
SET(INFO_INSTALL_DIR
"${SHARE_INSTALL_PREFIX}/info"
CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)"
)
else()
# Same same
set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
set(SBIN_INSTALL_DIR "sbin" CACHE PATH "-")
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "-")
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
set(CMAKE_INSTALL_DIR "CMake" CACHE PATH "-")
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
set(ICON_INSTALL_DIR "icons" CACHE PATH "-")
set(SOUND_INSTALL_DIR "soudns" CACHE PATH "-")
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
endif ()

View File

@@ -4,16 +4,14 @@
/* Version number of package */
#cmakedefine VERSION "${PROJECT_VERSION}"
#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}"
#cmakedefine DATADIR "${DATADIR}"
#cmakedefine LIBDIR "${LIBDIR}"
#cmakedefine PLUGINDIR "${PLUGINDIR}"
#cmakedefine SYSCONFDIR "${SYSCONFDIR}"
#cmakedefine BINARYDIR "${BINARYDIR}"
#cmakedefine SOURCEDIR "${SOURCEDIR}"
/* Global bind configuration file path */
#cmakedefine GLOBAL_BIND_CONFIG "${GLOBAL_BIND_CONFIG}"
/* Global client configuration file path */
#cmakedefine GLOBAL_CLIENT_CONFIG "${GLOBAL_CLIENT_CONFIG}"
/************************** HEADER FILES *************************/
/* Define to 1 if you have the <argp.h> header file. */
@@ -97,12 +95,6 @@
/* Define to 1 if you have gl_flags as a glob_t sturct member */
#cmakedefine HAVE_GLOB_GL_FLAGS_MEMBER 1
/* Define to 1 if you have OpenSSL with Ed25519 support */
#cmakedefine HAVE_OPENSSL_ED25519 1
/* Define to 1 if you have OpenSSL with X25519 support */
#cmakedefine HAVE_OPENSSL_X25519 1
/*************************** FUNCTIONS ***************************/
/* Define to 1 if you have the `EVP_aes128_ctr' function. */
@@ -123,18 +115,6 @@
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
#cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' function. */
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID 1
/* Define to 1 if you have the `FIPS_mode' function. */
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
/* Define to 1 if you have the `EVP_DigestSign' function. */
#cmakedefine HAVE_OPENSSL_EVP_DIGESTSIGN 1
/* Define to 1 if you have the `EVP_DigestVerify' function. */
#cmakedefine HAVE_OPENSSL_EVP_DIGESTVERIFY 1
/* Define to 1 if you have the `OPENSSL_ia32cap_loc' function. */
#cmakedefine HAVE_OPENSSL_IA32CAP_LOC 1
@@ -239,6 +219,7 @@
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
#cmakedefine HAVE_GCC_NARG_MACRO 1
#cmakedefine HAVE_COMPILER__FUNC__ 1
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
@@ -257,12 +238,6 @@
/* Define to 1 if you want to enable server support */
#cmakedefine WITH_SERVER 1
/* Define to 1 if you want to enable DH group exchange algorithms */
#cmakedefine WITH_GEX 1
/* Define to 1 if you want to enable blowfish cipher support */
#cmakedefine WITH_BLOWFISH_CIPHER 1
/* Define to 1 if you want to enable debug output for crypto functions */
#cmakedefine DEBUG_CRYPTO 1

View File

@@ -15,8 +15,6 @@ if (DOXYGEN_FOUND)
set(DOXYGEN_MARKDOWN_SUPPORT YES)
set(DOXYGEN_PREDEFINED DOXYGEN
WITH_SERVER
WITH_SFTP
PRINTF_ATTRIBUTE(x,y))
set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style)

View File

@@ -63,7 +63,7 @@ int authenticate_pubkey(ssh_session session)
{
int rc;
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
rc = ssh_userauth_publickey_auto(session, NULL);
if (rc == SSH_AUTH_ERROR)
{
@@ -281,7 +281,7 @@ pass, ssh_userauth_none() might answer SSH_AUTH_SUCCESS.
The following example shows how to perform "none" authentication:
@code
int authenticate_none(ssh_session session)
int authenticate_kbdint(ssh_session session)
{
int rc;

View File

@@ -112,8 +112,8 @@ This number is calculated using the following procedure:
This conversion follows the network byte order. This step differs from
RFC5656.
[RFC5656] https://tools.ietf.org/html/rfc5656
[RFC5656] http://tools.ietf.org/html/rfc5656
[SCHNEIER] https://www.schneier.com/blog/archives/2013/09/the_nsa_is_brea.html#c1675929
[DJB] https://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
[DJB] http://cr.yp.to/talks/2013.05.31/slides-dan+tanja-20130531-4x3.pdf
[Curve25519] "Curve25519: new Diffie-Hellman speed records."
https://cr.yp.to/ecdh/curve25519-20060209.pdf
http://cr.yp.to/ecdh/curve25519-20060209.pdf

View File

@@ -431,9 +431,6 @@ int show_remote_processes(ssh_session session)
}
@endcode
Each ssh_channel_request_exec() needs to be run on freshly created
and connected (with ssh_channel_open_session()) channel.
@see @ref opening_shell
@see @ref remote_command
@see @ref sftp_subsystem

View File

@@ -27,7 +27,4 @@ the dllimport attribute.
#include <libssh/libssh.h>
@endcode
If you're are statically linking with OpenSSL, read the "Linking your
application" section in the NOTES.[OS] in the OpenSSL source tree!
*/

View File

@@ -23,7 +23,7 @@ The libssh library provides:
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256,ssh-dss
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5, none
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512, hmac-md5, none
- <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
@@ -39,8 +39,8 @@ The libssh library provides:
- Client <b>and</b> server support
- SSHv2 and SSHv1 protocol support
- Supports <a href="https://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
- Automated test cases with nightly <a href="https://test.libssh.org/" target="_blank">tests</a>
- Supports <a href="http://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
- Automated test cases with nightly <a href="http://test.libssh.org/" target="_blank">tests</a>
- Event model based on poll(2), or a poll(2)-emulation.
@section main-copyright Copyright Policy
@@ -111,7 +111,7 @@ By making a contribution to this project, I certify that:
Free Software Foundation; either version 2.1 of
the License, or (at the option of the project) any later version.
https://www.gnu.org/licenses/lgpl-2.1.html
http://www.gnu.org/licenses/lgpl-2.1.html
@endverbatim
We will maintain a copy of that email as a record that you have the rights to
@@ -151,79 +151,47 @@ The libssh Team
The following RFC documents described SSH-2 protcol as an Internet standard.
- <a href="https://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
- <a href="http://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
The Secure Shell (SSH) Protocol Assigned Numbers
- <a href="https://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
- <a href="http://tools.ietf.org/html/rfc4251" target="_blank">RFC 4251</a>,
The Secure Shell (SSH) Protocol Architecture
- <a href="https://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
- <a href="http://tools.ietf.org/html/rfc4252" target="_blank">RFC 4252</a>,
The Secure Shell (SSH) Authentication Protocol
- <a href="https://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
- <a href="http://tools.ietf.org/html/rfc4253" target="_blank">RFC 4253</a>,
The Secure Shell (SSH) Transport Layer Protocol
- <a href="https://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
- <a href="http://tools.ietf.org/html/rfc4254" target="_blank">RFC 4254</a>,
The Secure Shell (SSH) Connection Protocol
- <a href="https://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
- <a href="http://tools.ietf.org/html/rfc4255" target="_blank">RFC 4255</a>,
Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
(not implemented in libssh)
- <a href="https://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
- <a href="http://tools.ietf.org/html/rfc4256" target="_blank">RFC 4256</a>,
Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
- <a href="https://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
- <a href="http://tools.ietf.org/html/rfc4335" target="_blank">RFC 4335</a>,
The Secure Shell (SSH) Session Channel Break Extension
- <a href="https://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
- <a href="http://tools.ietf.org/html/rfc4344" target="_blank">RFC 4344</a>,
The Secure Shell (SSH) Transport Layer Encryption Modes
- <a href="https://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
- <a href="http://tools.ietf.org/html/rfc4345" target="_blank">RFC 4345</a>,
Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
It was later modified and expanded by the following RFCs.
- <a href="https://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
- <a href="http://tools.ietf.org/html/rfc4419" target="_blank">RFC 4419</a>,
Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer
Protocol
- <a href="https://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
- <a href="http://tools.ietf.org/html/rfc4432" target="_blank">RFC 4432</a>,
RSA Key Exchange for the Secure Shell (SSH) Transport Layer Protocol
(not implemented in libssh)
- <a href="https://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
- <a href="http://tools.ietf.org/html/rfc4462" target="_blank">RFC 4462</a>,
Generic Security Service Application Program Interface (GSS-API)
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
(only the authentication implemented in libssh)
- <a href="https://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
The Secure Shell (SSH) Public Key File Format
(not implemented in libssh)
- <a href="https://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
- <a href="http://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
(the algorithm negotiation implemented according to openssh.com)
- <a href="https://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
- <a href="https://tools.ietf.org/html/rfc6594" target="_blank">RFC 6594</a>,
Use of the SHA-256 Algorithm with RSA, DSA, and ECDSA in SSHFP Resource Records
(not implemented in libssh)
- <a href="https://tools.ietf.org/html/rfc6668" target="_blank">RFC 6668</a>,
SHA-2 Data Integrity Verification for the Secure Shell (SSH) Transport Layer Protocol
- <a href="https://tools.ietf.org/html/rfc7479" target="_blank">RFC 7479</a>,
Using Ed25519 in SSHFP Resource Records
(not implemented in libssh)
- <a href="https://tools.ietf.org/html/rfc8160" target="_blank">RFC 8160</a>,
IUTF8 Terminal Mode in Secure Shell (SSH)
(not handled in libssh)
- <a href="https://tools.ietf.org/html/rfc8270" target="_blank">RFC 8270</a>,
Increase the Secure Shell Minimum Recommended Diffie-Hellman Modulus Size to 2048 Bits
- <a href="https://tools.ietf.org/html/rfc8308" target="_blank">RFC 8308</a>,
Extension Negotiation in the Secure Shell (SSH) Protocol
(only the "server-sig-algs" extension implemented)
- <a href="https://tools.ietf.org/html/rfc8332" target="_blank">RFC 8332</a>,
Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol
There are also drafts that are being currently developed and followed.
- <a href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-kex-sha2-10" target="_blank">draft-ietf-curdle-ssh-kex-sha2-10</a>
Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)
- <a href="https://tools.ietf.org/html/draft-miller-ssh-agent-03" target="_blank">draft-miller-ssh-agent-03</a>
SSH Agent Protocol
- <a href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-12" target="_blank">draft-ietf-curdle-ssh-curves-12</a>
Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448
Interesting cryptography documents:
- <a href="https://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
- <a href="http://www.cryptsoft.com/pkcs11doc/" target="_blank">PKCS #11</a>, PKCS #11 reference documents, describing interface with smartcards.
@subsection main-rfc-sftp Secure Shell File Transfer Protocol (SFTP)
@@ -231,22 +199,26 @@ The protocol is not an Internet standard but it is still widely implemented.
OpenSSH and most other implementation implement Version 3 of the protocol. We
do the same in libssh.
- <a href="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
- <a href="http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02" target="_blank">
draft-ietf-secsh-filexfer-02.txt</a>,
SSH File Transfer Protocol
@subsection main-rfc-extensions Secure Shell Extensions
The libssh project has an extension to support Curve25519 which is also supported by
the OpenSSH project.
- <a href="http://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt" target="_blank">curve25519-sha256@libssh.org</a>,
Curve25519-SHA256 for ECDH KEX
The OpenSSH project has defined some extensions to the protocol. We support some of
them like the statvfs calls in SFTP or the ssh-agent.
- <a href="https://api.libssh.org/rfc/PROTOCOL" target="_blank">
- <a href="http://api.libssh.org/rfc/PROTOCOL" target="_blank">
OpenSSH's deviations and extensions</a>
- <a href="https://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
- <a href="http://api.libssh.org/rfc/PROTOCOL.agent" target="_blank">
OpenSSH's ssh-agent</a>
- <a href="http://api.libssh.org/rfc/PROTOCOL.certkeys" target="_blank">
OpenSSH's pubkey certificate authentication</a>
- <a href="https://api.libssh.org/rfc/PROTOCOL.chacha20poly1305" target="_blank">
chacha20-poly1305@openssh.com authenticated encryption mode</a>
- <a href="https://api.libssh.org/rfc/PROTOCOL.key" target="_blank">
OpenSSH private key format (openssh-key-v1)</a>
*/

View File

@@ -61,7 +61,7 @@ int sftp_helloworld(ssh_session session)
rc = sftp_init(sftp);
if (rc != SSH_OK)
{
fprintf(stderr, "Error initializing SFTP session: code %d.\n",
fprintf(stderr, "Error initializing SFTP session: %s.\n",
sftp_get_error(sftp));
sftp_free(sftp);
return rc;

View File

@@ -6,7 +6,10 @@ set(examples_SRCS
connect_ssh.c
)
include_directories(${libssh_BINARY_DIR})
include_directories(
${LIBSSH_PUBLIC_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}
)
if (ARGP_INCLUDE_DIR)
include_directories(${ARGP_INCLUDE_DIR})
@@ -15,68 +18,60 @@ endif()
if (UNIX AND NOT WIN32)
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
target_compile_options(libssh_scp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(libssh_scp ssh::ssh)
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
add_executable(scp_download scp_download.c ${examples_SRCS})
target_compile_options(scp_download PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(scp_download ssh::ssh)
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
target_compile_options(sshnetcat PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(sshnetcat ssh::ssh)
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
if (WITH_SFTP)
add_executable(samplesftp samplesftp.c ${examples_SRCS})
target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesftp ssh::ssh)
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
endif (WITH_SFTP)
add_executable(ssh-client ssh_client.c ${examples_SRCS})
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh-client ssh::ssh)
target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY})
if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H))
if (HAVE_LIBUTIL)
add_executable(ssh_server_fork ssh_server_fork.c)
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh_server_fork ssh::ssh ${ARGP_LIBRARY} util)
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util)
endif (HAVE_LIBUTIL)
if (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-cb samplesshd-cb.c)
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-cb ssh::ssh ${ARGP_LIBRARY})
target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
add_executable(proxy proxy.c)
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(proxy ssh::ssh ${ARGP_LIBRARY})
add_executable(sshd_direct-tcpip sshd_direct-tcpip.c)
target_compile_options(sshd_direct-tcpip PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(sshd_direct-tcpip ssh::ssh ${ARGP_LIBRARY})
target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
endif (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-kbdint samplesshd-kbdint.c)
target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-kbdint ssh::ssh ${ARGP_LIBRARY})
target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY})
endif()
endif (UNIX AND NOT WIN32)
add_executable(exec exec.c ${examples_SRCS})
target_compile_options(exec PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(exec ssh::ssh)
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
add_executable(senddata senddata.c ${examples_SRCS})
target_compile_options(senddata PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(senddata ssh::ssh)
add_executable(keygen keygen.c)
target_compile_options(keygen PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(keygen ssh::ssh)
target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY})
add_executable(libsshpp libsshpp.cpp)
target_link_libraries(libsshpp ssh::ssh)
target_link_libraries(libsshpp ${LIBSSH_SHARED_LIBRARY})
add_executable(libsshpp_noexcept libsshpp_noexcept.cpp)
target_link_libraries(libsshpp_noexcept ssh::ssh)
target_link_libraries(libsshpp_noexcept ${LIBSSH_SHARED_LIBRARY})

View File

@@ -100,39 +100,6 @@ int authenticate_kbdint(ssh_session session, const char *password)
return err;
}
static int auth_keyfile(ssh_session session, char* keyfile)
{
ssh_key key = NULL;
char pubkey[132] = {0}; // +".pub"
int rc;
snprintf(pubkey, sizeof(pubkey), "%s.pub", keyfile);
rc = ssh_pki_import_pubkey_file( pubkey, &key);
if (rc != SSH_OK)
return SSH_AUTH_DENIED;
rc = ssh_userauth_try_publickey(session, NULL, key);
ssh_key_free(key);
if (rc!=SSH_AUTH_SUCCESS)
return SSH_AUTH_DENIED;
rc = ssh_pki_import_privkey_file(keyfile, NULL, NULL, NULL, &key);
if (rc != SSH_OK)
return SSH_AUTH_DENIED;
rc = ssh_userauth_publickey(session, NULL, key);
ssh_key_free(key);
return rc;
}
static void error(ssh_session session)
{
fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
@@ -173,35 +140,6 @@ int authenticate_console(ssh_session session)
break;
}
}
{
char buffer[128] = {0};
char *p = NULL;
printf("Automatic pubkey failed. "
"Do you want to try a specific key? (y/n)\n");
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
break;
}
if ((buffer[0]=='Y') || (buffer[0]=='y')) {
printf("private key filename: ");
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
return SSH_AUTH_ERROR;
}
buffer[sizeof(buffer) - 1] = '\0';
if ((p = strchr(buffer, '\n'))) {
*p = '\0';
}
rc = auth_keyfile(session, buffer);
if(rc == SSH_AUTH_SUCCESS) {
break;
}
fprintf(stderr, "failed with key\n");
}
}
// Try to authenticate with keyboard interactive";
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
@@ -234,7 +172,7 @@ int authenticate_console(ssh_session session)
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n",banner);
SSH_STRING_FREE_CHAR(banner);
ssh_string_free_char(banner);
}
return rc;

View File

@@ -1,41 +0,0 @@
/* keygen.c
* Sample implementation of ssh-keygen using libssh
*/
/*
Copyright 2019 Red Hat, Inc.
Author: Jakub Jelen <jjelen@redhat.com>
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
*/
#include <libssh/libssh.h>
#include <stdio.h>
int main(void)
{
ssh_key key = NULL;
int rv;
/* Generate a new ED25519 private key file */
rv = ssh_pki_generate(SSH_KEYTYPE_ED25519, 0, &key);
if (rv != SSH_OK) {
fprintf(stderr, "Failed to generate private key");
return -1;
}
/* Write it to a file testkey in the current dirrectory */
rv = ssh_pki_export_privkey_file(key, NULL, NULL, NULL, "testkey");
if (rv != SSH_OK) {
fprintf(stderr, "Failed to write private key file");
return -1;
}
return 0;
}

View File

@@ -257,15 +257,14 @@ static int open_location(struct location *loc, int flag) {
* @param recursive Copy also directories
*/
static int do_copy(struct location *src, struct location *dest, int recursive) {
size_t size;
int size;
socket_t fd;
struct stat s;
int w, r;
char buffer[16384];
size_t total = 0;
mode_t mode;
int total = 0;
int mode;
char *filename = NULL;
/* recursive mode doesn't work yet */
(void)recursive;
/* Get the file name and size*/
@@ -303,7 +302,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
fprintf(stderr,
"Error: %s\n",
ssh_get_error(src->session));
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
return -1;
}
} while(r != SSH_SCP_REQUEST_NEWFILE);
@@ -316,7 +315,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
fprintf(stderr,
"error: %s\n",
ssh_get_error(dest->session));
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
ssh_scp_free(dest->scp);
dest->scp = NULL;
return -1;
@@ -331,7 +330,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
if (src->is_ssh) {
ssh_scp_deny_request(src->scp, "Cannot open local file");
}
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
return -1;
}
}
@@ -347,7 +346,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
fprintf(stderr,
"Error reading scp: %s\n",
ssh_get_error(src->session));
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
return -1;
}
@@ -364,7 +363,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
fprintf(stderr,
"Error reading file: %s\n",
strerror(errno));
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
return -1;
}
}
@@ -377,7 +376,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp = NULL;
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
return -1;
}
} else {
@@ -386,7 +385,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
fprintf(stderr,
"Error writing in local file: %s\n",
strerror(errno));
SSH_STRING_FREE_CHAR(filename);
ssh_string_free_char(filename);
return -1;
}
}
@@ -394,8 +393,8 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
} while(total < size);
SSH_STRING_FREE_CHAR(filename);
printf("wrote %zu bytes\n", total);
ssh_string_free_char(filename);
printf("wrote %d bytes\n", total);
return 0;
}

View File

@@ -1,17 +1,16 @@
/* ssh_client.c */
/* client.c */
/*
* Copyright 2003-2015 Aris Adamantiadis
*
* This file is part of the SSH Library
*
* You are free to copy this file, modify it in any way, consider it being public
* domain. This does not apply to the rest of the library though, but it is
* allowed to cut-and-paste working code from this file to any license of
* program.
* The goal is to show the API in action. It's not a reference on how terminal
* clients must be made or how a client should react.
*/
Copyright 2003-2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
#include "config.h"
#include <stdio.h>
@@ -198,20 +197,19 @@ static void sizechanged(void)
static void select_loop(ssh_session session,ssh_channel channel)
{
ssh_connector connector_in, connector_out, connector_err;
int rc;
ssh_event event = ssh_event_new();
/* stdin */
connector_in = ssh_connector_new(session);
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDINOUT);
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDOUT);
ssh_connector_set_in_fd(connector_in, 0);
ssh_event_add_connector(event, connector_in);
/* stdout */
connector_out = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_out, 1);
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT);
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDOUT);
ssh_event_add_connector(event, connector_out);
/* stderr */
@@ -224,11 +222,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
if (signal_delayed) {
sizechanged();
}
rc = ssh_event_dopoll(event, 60000);
if (rc == SSH_ERROR) {
fprintf(stderr, "Error in ssh_event_dopoll()\n");
break;
}
ssh_event_dopoll(event, 60000);
}
ssh_event_remove_connector(event, connector_in);
ssh_event_remove_connector(event, connector_out);
@@ -239,6 +233,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
ssh_connector_free(connector_err);
ssh_event_free(event);
ssh_channel_free(channel);
}
static void shell(ssh_session session)
@@ -246,11 +241,7 @@ static void shell(ssh_session session)
ssh_channel channel;
struct termios terminal_local;
int interactive=isatty(0);
channel = ssh_channel_new(session);
if (channel == NULL) {
return;
}
if (interactive) {
tcgetattr(0, &terminal_local);
@@ -259,7 +250,6 @@ static void shell(ssh_session session)
if (ssh_channel_open_session(channel)) {
printf("Error opening channel : %s\n", ssh_get_error(session));
ssh_channel_free(channel);
return;
}
chan = channel;
@@ -270,7 +260,6 @@ static void shell(ssh_session session)
if (ssh_channel_request_shell(channel)) {
printf("Requesting shell : %s\n", ssh_get_error(session));
ssh_channel_free(channel);
return;
}
@@ -284,7 +273,6 @@ static void shell(ssh_session session)
if (interactive) {
do_cleanup(0);
}
ssh_channel_free(channel);
}
static void batch_shell(ssh_session session)
@@ -301,18 +289,12 @@ static void batch_shell(ssh_session session)
}
channel = ssh_channel_new(session);
if (channel == NULL) {
return;
}
ssh_channel_open_session(channel);
if (ssh_channel_request_exec(channel, buffer)) {
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
ssh_channel_free(channel);
return;
}
select_loop(session, channel);
ssh_channel_free(channel);
}
static int client(ssh_session session)

View File

@@ -37,7 +37,6 @@ The goal is to show the API in action.
#endif
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdio.h>
#ifndef KEYS_FOLDER
@@ -70,11 +69,8 @@ static void set_default_keys(ssh_bind sshbind,
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
KEYS_FOLDER "ssh_host_ecdsa_key");
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
KEYS_FOLDER "ssh_host_ed25519_key");
}
#define DEF_STR_SIZE 1024
char authorizedkeys[DEF_STR_SIZE] = {0};
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
@@ -129,14 +125,6 @@ static struct argp_option options[] = {
.doc = "Set the ecdsa key.",
.group = 0
},
{
.name = "authorizedkeys",
.key = 'a',
.arg = "FILE",
.flags = 0,
.doc = "Set the authorized keys file.",
.group = 0
},
{
.name = "no-default-keys",
.key = 'n',
@@ -190,9 +178,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
ecdsa_already_set = 1;
break;
case 'a':
strncpy(authorizedkeys, arg, DEF_STR_SIZE-1);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
"3");
@@ -449,53 +434,6 @@ static int auth_password(ssh_session session, const char *user,
return SSH_AUTH_DENIED;
}
static int auth_publickey(ssh_session session,
const char *user,
struct ssh_key_struct *pubkey,
char signature_state,
void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
(void) user;
(void) session;
if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
return SSH_AUTH_SUCCESS;
}
if (signature_state != SSH_PUBLICKEY_STATE_VALID) {
return SSH_AUTH_DENIED;
}
// valid so far. Now look through authorized keys for a match
if (authorizedkeys[0]) {
ssh_key key = NULL;
int result;
struct stat buf;
if (stat(authorizedkeys, &buf) == 0) {
result = ssh_pki_import_pubkey_file( authorizedkeys, &key );
if ((result != SSH_OK) || (key==NULL)) {
fprintf(stderr,
"Unable to import public key file %s\n",
authorizedkeys);
} else {
result = ssh_key_cmp( key, pubkey, SSH_KEY_CMP_PUBLIC );
ssh_key_free(key);
if (result == 0) {
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
}
}
}
// no matches
sdata->authenticated = 0;
return SSH_AUTH_DENIED;
}
static ssh_channel channel_open(ssh_session session, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
@@ -580,12 +518,6 @@ static void handle_session(ssh_event event, ssh_session session) {
.channel_open_request_session_function = channel_open,
};
if (authorizedkeys[0]) {
server_cb.auth_pubkey_function = auth_publickey;
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY);
} else
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
ssh_callbacks_init(&server_cb);
ssh_callbacks_init(&channel_cb);
@@ -596,6 +528,7 @@ static void handle_session(ssh_event event, ssh_session session) {
return;
}
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
ssh_event_add_session(event, session);
n = 0;

View File

@@ -1,681 +0,0 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2003-2009 Aris Adamantiadis
Copyright 2018 T. Wimmer
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action. It's not a reference on how terminal
clients must be made or how a client should react.
*/
/*
Example:
./sshd_direct-tcpip -v -p 2022 -d serverkey.dsa -r serverkey.rsa 127.0.0.1
*/
#include "config.h"
#include <libssh/libssh.h>
#include <libssh/server.h>
#include <libssh/callbacks.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <poll.h>
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
#ifndef __unused__
# ifdef HAVE_UNUSED_ATTRIBUTE
# define __unused__ __attribute__((unused))
# else /* HAVE_UNUSED_ATTRIBUTE */
# define __unused__
# endif /* HAVE_UNUSED_ATTRIBUTE */
#endif /* __unused__ */
#ifndef UNUSED_PARAM
#define UNUSED_PARAM(param) param __unused__
#endif /* UNUSED_PARAM */
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#define USER "user"
#define PASSWORD "pwd"
struct event_fd_data_struct {
int *p_fd;
ssh_channel channel;
struct ssh_channel_callbacks_struct *cb_chan;
int stacked;
};
struct cleanup_node_struct {
struct event_fd_data_struct *data;
struct cleanup_node_struct *next;
};
static bool authenticated = false;
static int tries = 0;
static bool error_set = false;
static int sockets_cnt = 0;
static ssh_event mainloop = NULL;
static struct cleanup_node_struct *cleanup_stack = NULL;
static void _close_socket(struct event_fd_data_struct event_fd_data);
static void cleanup_push(struct cleanup_node_struct** head_ref, struct event_fd_data_struct *new_data) {
// Allocate memory for node
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
new_node->next = (*head_ref);
// Copy new_data
new_node->data = new_data;
// Change head pointer as new node is added at the beginning
(*head_ref) = new_node;
}
static void do_cleanup(struct cleanup_node_struct **head_ref) {
struct cleanup_node_struct *current = (*head_ref);
struct cleanup_node_struct *previous = NULL, *gone = NULL;
while (current != NULL) {
if (ssh_channel_is_closed(current->data->channel)) {
if (current == (*head_ref)) {
(*head_ref) = current->next;
}
if (previous != NULL) {
previous->next = current->next;
}
gone = current;
current = current->next;
if (gone->data->channel) {
_close_socket(*gone->data);
ssh_remove_channel_callbacks(gone->data->channel, gone->data->cb_chan);
ssh_channel_free(gone->data->channel);
gone->data->channel = NULL;
SAFE_FREE(gone->data->p_fd);
SAFE_FREE(gone->data->cb_chan);
SAFE_FREE(gone->data);
SAFE_FREE(gone);
}
else {
fprintf(stderr, "channel already freed!\n");
}
_ssh_log(SSH_LOG_FUNCTIONS, "=== do_cleanup", "Freed.");
}
else {
ssh_channel_close(current->data->channel);
previous = current;
current = current->next;
}
}
}
static int auth_password(ssh_session session, const char *user,
const char *password, void *userdata) {
(void)userdata;
_ssh_log(SSH_LOG_PROTOCOL, "=== auth_password", "Authenticating user %s pwd %s",user, password);
if (strcmp(user,USER) == 0 && strcmp(password, PASSWORD) == 0){
authenticated = true;
printf("Authenticated\n");
return SSH_AUTH_SUCCESS;
}
if (tries >= 3){
printf("Too many authentication tries\n");
ssh_disconnect(session);
error_set = true;
return SSH_AUTH_DENIED;
}
tries++;
return SSH_AUTH_DENIED;
}
static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata) {
ssh_gssapi_creds creds = ssh_gssapi_get_creds(session);
(void)userdata;
printf("Authenticating user %s with gssapi principal %s\n", user, principal);
if (creds != NULL)
printf("Received some gssapi credentials\n");
else
printf("Not received any forwardable creds\n");
printf("authenticated\n");
authenticated = true;
return SSH_AUTH_SUCCESS;
}
static int subsystem_request(ssh_session session, ssh_channel channel, const char *subsystem, void *userdata) {
(void)session;
(void)channel;
//(void)subsystem;
(void)userdata;
_ssh_log(SSH_LOG_PROTOCOL, "=== subsystem_request", "Channel subsystem reqeuest: %s", subsystem);
return 0;
}
struct ssh_channel_callbacks_struct channel_cb = {
.channel_subsystem_request_function = subsystem_request
};
static ssh_channel new_session_channel(ssh_session session, void *userdata) {
(void)session;
(void)userdata;
_ssh_log(SSH_LOG_PROTOCOL, "=== subsystem_request", "Session channel request");
/* For TCP forward only there seems to be no need for a session channel */
/*if(chan != NULL)
return NULL;
printf("Session channel request\n");
chan = ssh_channel_new(session);
ssh_callbacks_init(&channel_cb);
ssh_set_channel_callbacks(chan, &channel_cb);
return chan;*/
return NULL;
}
static void stack_socket_close(UNUSED_PARAM(ssh_session session),
struct event_fd_data_struct *event_fd_data)
{
if (event_fd_data->stacked != 1) {
_ssh_log(SSH_LOG_FUNCTIONS, "=== stack_socket_close", "Closing fd = %d sockets_cnt = %d", *event_fd_data->p_fd, sockets_cnt);
event_fd_data->stacked = 1;
cleanup_push(&cleanup_stack, event_fd_data);
}
}
static void _close_socket(struct event_fd_data_struct event_fd_data) {
_ssh_log(SSH_LOG_FUNCTIONS, "=== close_socket", "Closing fd = %d sockets_cnt = %d", *event_fd_data.p_fd, sockets_cnt);
ssh_event_remove_fd(mainloop, *event_fd_data.p_fd);
sockets_cnt--;
#ifdef _WIN32
closesocket(*event_fd_data.p_fd);
#else
close(*event_fd_data.p_fd);
#endif // _WIN32
(*event_fd_data.p_fd) = SSH_INVALID_SOCKET;
}
static int service_request(ssh_session session, const char *service, void *userdata) {
(void)session;
//(void)service;
(void)userdata;
_ssh_log(SSH_LOG_PROTOCOL, "=== service_request", "Service request: %s", service);
return 0;
}
static void global_request(ssh_session session, ssh_message message, void *userdata) {
(void)session;
(void)userdata;
_ssh_log(SSH_LOG_PROTOCOL, "=== global_request", "Global request, message type: %d", ssh_message_type(message));
}
static void my_channel_close_function(ssh_session session, ssh_channel channel, void *userdata) {
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
(void)session;
_ssh_log(SSH_LOG_PROTOCOL,
"=== my_channel_close_function",
"Channel closed by remote.");
stack_socket_close(session, event_fd_data);
}
static void my_channel_eof_function(ssh_session session, ssh_channel channel, void *userdata) {
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
(void)session;
_ssh_log(SSH_LOG_PROTOCOL,
"=== my_channel_eof_function",
"Got EOF on channel. Shuting down write on socket (fd = %d).",
*event_fd_data->p_fd);
stack_socket_close(session, event_fd_data);
}
static void my_channel_exit_status_function(ssh_session session, ssh_channel channel, int exit_status, void *userdata) {
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
(void)session;
_ssh_log(SSH_LOG_PROTOCOL,
"=== my_channel_exit_status_function",
"Got exit status %d on channel fd = %d.",
exit_status, *event_fd_data->p_fd);
}
static int my_channel_data_function(ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
UNUSED_PARAM(int is_stderr),
void *userdata)
{
int i = 0;
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
if (event_fd_data->channel == NULL) {
fprintf(stderr, "Why we're here? Stacked = %d\n", event_fd_data->stacked);
}
_ssh_log(SSH_LOG_PROTOCOL,
"=== my_channel_data_function",
"%d bytes waiting on channel for reading. Fd = %d",
len,
*event_fd_data->p_fd);
if (len > 0) {
i = send(*event_fd_data->p_fd, data, len, 0);
}
if (i < 0) {
_ssh_log(SSH_LOG_WARNING, "=== my_channel_data_function", "Writing to tcp socket %d: %s", *event_fd_data->p_fd, strerror(errno));
stack_socket_close(session, event_fd_data);
}
else {
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_channel_data_function", "Sent %d bytes", i);
}
return i;
}
static int my_fd_data_function(UNUSED_PARAM(socket_t fd),
int revents,
void *userdata)
{
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
ssh_channel channel = event_fd_data->channel;
ssh_session session;
int len, i, wr;
char buf[16384];
int blocking;
if (channel == NULL) {
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel == NULL!");
return 0;
}
session = ssh_channel_get_session(channel);
if (ssh_channel_is_closed(channel)) {
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel is closed!");
stack_socket_close(session, event_fd_data);
return 0;
}
if (!(revents & POLLIN)) {
if (revents & POLLPRI) {
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLPRI");
}
if (revents & POLLOUT) {
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLOUT");
}
if (revents & POLLHUP) {
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLHUP");
}
if (revents & POLLNVAL) {
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLNVAL");
}
if (revents & POLLERR) {
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLERR");
}
return 0;
}
blocking = ssh_is_blocking(session);
ssh_set_blocking(session, 0);
_ssh_log(SSH_LOG_FUNCTIONS,
"=== my_fd_data_function",
"Trying to read from tcp socket fd = %d",
*event_fd_data->p_fd);
#ifdef _WIN32
struct sockaddr from;
int fromlen = sizeof(from);
len = recvfrom(*event_fd_data->p_fd, buf, sizeof(buf), 0, &from, &fromlen);
#else
len = recv(*event_fd_data->p_fd, buf, sizeof(buf), 0);
#endif // _WIN32
if (len < 0) {
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Reading from tcp socket: %s", strerror(errno));
ssh_channel_send_eof(channel);
}
else if (len > 0) {
if (ssh_channel_is_open(channel)) {
wr = 0;
do {
i = ssh_channel_write(channel, buf, len);
if (i < 0) {
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Error writing on the direct-tcpip channel: %d", i);
len = wr;
break;
}
wr += i;
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel_write (%d from %d)", wr, len);
} while (i > 0 && wr < len);
}
else {
_ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Can't write on closed channel!");
}
}
else {
_ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "The destination host has disconnected!");
ssh_channel_close(channel);
#ifdef _WIN32
shutdown(*event_fd_data->p_fd, SD_RECEIVE);
#else
shutdown(*event_fd_data->p_fd, SHUT_RD);
#endif // _WIN32
}
ssh_set_blocking(session, blocking);
return len;
}
static int open_tcp_socket(ssh_message msg) {
struct sockaddr_in sin;
int forwardsock = -1;
struct hostent *host;
const char *dest_hostname;
int dest_port;
forwardsock = socket(AF_INET, SOCK_STREAM, 0);
if (forwardsock < 0) {
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR opening socket: %s", strerror(errno));
return -1;
}
dest_hostname = ssh_message_channel_request_open_destination(msg);
dest_port = ssh_message_channel_request_open_destination_port(msg);
_ssh_log(SSH_LOG_PROTOCOL, "=== open_tcp_socket", "Connecting to %s on port %d", dest_hostname, dest_port);
host = gethostbyname(dest_hostname);
if (host == NULL) {
close(forwardsock);
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR, no such host: %s", dest_hostname);
return -1;
}
memset((char *)&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
memcpy((char *)&sin.sin_addr.s_addr, (char *)host->h_addr, host->h_length);
sin.sin_port = htons(dest_port);
if (connect(forwardsock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
close(forwardsock);
_ssh_log(SSH_LOG_WARNING, "=== open_tcp_socket", "ERROR connecting: %s", strerror(errno));
return -1;
}
sockets_cnt++;
_ssh_log(SSH_LOG_FUNCTIONS, "=== open_tcp_socket", "Connected. sockets_cnt = %d", sockets_cnt);
return forwardsock;
}
static int message_callback(ssh_session session, ssh_message message, void *userdata) {
ssh_channel channel;
int socket_fd, *pFd;
struct ssh_channel_callbacks_struct *cb_chan;
struct event_fd_data_struct *event_fd_data;
(void)session;
(void)message;
(void)userdata;
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d", ssh_message_type(message));
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message Subtype: %d", ssh_message_subtype(message));
if (ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN) {
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "channel_request_open");
if (ssh_message_subtype(message) == SSH_CHANNEL_DIRECT_TCPIP) {
channel = ssh_message_channel_request_open_reply_accept(message);
if (channel == NULL) {
_ssh_log(SSH_LOG_WARNING, "=== message_callback", "Accepting direct-tcpip channel failed!");
return 1;
}
else {
_ssh_log(SSH_LOG_PROTOCOL, "=== message_callback", "Connected to channel!");
socket_fd = open_tcp_socket(message);
if (-1 == socket_fd) {
return 1;
}
pFd = malloc(sizeof *pFd);
cb_chan = malloc(sizeof *cb_chan);
event_fd_data = malloc(sizeof *event_fd_data);
(*pFd) = socket_fd;
event_fd_data->channel = channel;
event_fd_data->p_fd = pFd;
event_fd_data->stacked = 0;
event_fd_data->cb_chan = cb_chan;
cb_chan->userdata = event_fd_data;
cb_chan->channel_eof_function = my_channel_eof_function;
cb_chan->channel_close_function = my_channel_close_function;
cb_chan->channel_data_function = my_channel_data_function;
cb_chan->channel_exit_status_function = my_channel_exit_status_function;
ssh_callbacks_init(cb_chan);
ssh_set_channel_callbacks(channel, cb_chan);
ssh_event_add_fd(mainloop, (socket_t)*pFd, POLLIN, my_fd_data_function, event_fd_data);
return 0;
}
}
}
return 1;
}
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{
.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0
},
{
.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0
},
{
.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0
},
{NULL, 0, NULL, 0, NULL, 0}
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure.
*/
ssh_bind sshbind = state->input;
switch (key) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "1");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
struct ssh_server_callbacks_struct cb = {
.userdata = NULL,
.auth_password_function = auth_password,
.auth_gssapi_mic_function = auth_gssapi_mic,
.channel_open_request_session_function = new_session_channel,
.service_request_function = service_request
};
struct ssh_callbacks_struct cb_gen = {
.userdata = NULL,
.global_request_function = global_request
};
int ret = 1;
sshbind = ssh_bind_new();
session = ssh_new();
mainloop = ssh_event_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
* Parse our arguments; every option seen by parse_opt will
* be reflected in arguments.
*/
argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
(void)argc;
(void)argv;
#endif
if (ssh_bind_listen(sshbind) < 0) {
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
return 1;
}
if (ssh_bind_accept(sshbind, session) == SSH_ERROR) {
printf("error accepting a connection : %s\n", ssh_get_error(sshbind));
ret = 1;
goto shutdown;
}
ssh_callbacks_init(&cb);
ssh_callbacks_init(&cb_gen);
ssh_set_server_callbacks(session, &cb);
ssh_set_callbacks(session, &cb_gen);
ssh_set_message_callback(session, message_callback, (void *)NULL);
if (ssh_handle_key_exchange(session)) {
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
ret = 1;
goto shutdown;
}
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC);
ssh_event_add_session(mainloop, session);
while (!authenticated) {
if (error_set) {
break;
}
if (ssh_event_dopoll(mainloop, -1) == SSH_ERROR) {
printf("Error : %s\n", ssh_get_error(session));
ret = 1;
goto shutdown;
}
}
if (error_set) {
printf("Error, exiting loop\n");
} else {
printf("Authenticated and got a channel\n");
while (!error_set) {
if (ssh_event_dopoll(mainloop, 100) == SSH_ERROR) {
printf("Error : %s\n", ssh_get_error(session));
ret = 1;
goto shutdown;
}
do_cleanup(&cleanup_stack);
}
}
shutdown:
ssh_disconnect(session);
ssh_bind_free(sshbind);
ssh_finalize();
return ret;
}

View File

@@ -26,7 +26,7 @@ install(
FILES
${libssh_HDRS}
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/${APPLICATION_NAME}
${INCLUDE_INSTALL_DIR}/${APPLICATION_NAME}
COMPONENT
headers
)

View File

@@ -104,7 +104,7 @@ void ssh_agent_free(struct ssh_agent_struct *agent);
*/
int ssh_agent_is_running(struct ssh_session_struct *session);
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session);
int ssh_agent_get_ident_count(struct ssh_session_struct *session);
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
char **comment);

View File

@@ -26,8 +26,9 @@
#include "libssh/libmbedcrypto.h"
bignum ssh_make_string_bn(ssh_string string);
void ssh_make_string_bn_inplace(ssh_string string, bignum bnout);
ssh_string ssh_make_bignum_string(bignum num);
void ssh_print_bignum(const char *which, const_bignum num);
void ssh_print_bignum(const char *which, const bignum num);
#endif /* BIGNUM_H_ */

View File

@@ -22,7 +22,6 @@
#define BIND_H_
#include "libssh/priv.h"
#include "libssh/kex.h"
#include "libssh/session.h"
struct ssh_bind_struct {
@@ -32,7 +31,7 @@ struct ssh_bind_struct {
struct ssh_poll_handle_struct *poll;
/* options */
char *wanted_methods[SSH_KEX_METHODS];
char *wanted_methods[10];
char *banner;
char *ecdsakey;
char *dsakey;
@@ -47,9 +46,6 @@ struct ssh_bind_struct {
unsigned int bindport;
int blocking;
int toaccept;
bool config_processed;
char *config_dir;
char *pubkey_accepted_key_types;
};
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct

View File

@@ -1,64 +0,0 @@
/*
* bind_config.h - Parse the SSH server configuration file
*
* This file is part of the SSH Library
*
* Copyright (c) 2019 by Red Hat, Inc.
*
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef BIND_CONFIG_H_
#define BIND_CONFIG_H_
#include "libssh/server.h"
enum ssh_bind_config_opcode_e {
/* Known but not allowed in Match block */
BIND_CFG_NOT_ALLOWED_IN_MATCH = -4,
/* Unknown opcode */
BIND_CFG_UNKNOWN = -3,
/* Known and not applicable to libssh */
BIND_CFG_NA = -2,
/* Known but not supported by current libssh version */
BIND_CFG_UNSUPPORTED = -1,
BIND_CFG_INCLUDE,
BIND_CFG_HOSTKEY,
BIND_CFG_LISTENADDRESS,
BIND_CFG_PORT,
BIND_CFG_LOGLEVEL,
BIND_CFG_CIPHERS,
BIND_CFG_MACS,
BIND_CFG_KEXALGORITHMS,
BIND_CFG_MATCH,
BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES,
BIND_CFG_HOSTKEY_ALGORITHMS,
BIND_CFG_MAX /* Keep this one last in the list */
};
/* @brief Parse configuration file and set the options to the given ssh_bind
*
* @params[in] sshbind The ssh_bind context to be configured
* @params[in] filename The path to the configuration file
*
* @returns 0 on successful parsing the configuration file, -1 on error
*/
int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename);
#endif /* BIND_CONFIG_H_ */

View File

@@ -50,11 +50,11 @@ int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
_ssh_buffer_pack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
const char *format, size_t argc,
const char *format, int argc,
va_list ap);
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
int argc,
...);
#define ssh_buffer_unpack(buffer, format, ...) \
_ssh_buffer_unpack((buffer), (format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__, SSH_BUFFER_PACK_END)

View File

@@ -854,7 +854,7 @@ typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
* @code
* struct ssh_channel_callbacks_struct cb = {
* .userdata = data,
* .channel_data_function = my_channel_data_function
* .channel_data = my_channel_data_function
* };
* ssh_callbacks_init(&cb);
* ssh_set_channel_callbacks(channel, &cb);
@@ -944,20 +944,9 @@ LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
*cb);
/**
* @brief Returns a pointer to the appropriate callbacks structure for the
* environment, to be used with ssh_threads_set_callbacks.
*
* @returns A pointer to a ssh_threads_callbacks_struct to be used with
* @brief returns a pointer on the pthread threads callbacks, to be used with
* ssh_threads_set_callbacks.
*
* @see ssh_threads_set_callbacks
*/
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_default(void);
/**
* @brief Returns a pointer on the pthread threads callbacks, to be used with
* ssh_threads_set_callbacks.
*
* @warning you have to link with the library ssh_threads.
* @see ssh_threads_set_callbacks
*/
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);

View File

@@ -48,16 +48,11 @@ enum ssh_channel_state_e {
};
/* The channel has been closed by the remote side */
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x0001
/* The channel has been closed locally */
#define SSH_CHANNEL_FLAG_CLOSED_LOCAL 0x0002
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x1
/* The channel has been freed by the calling program */
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x0004
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x2
/* the channel has not yet been bound to a remote one */
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x0008
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x4
struct ssh_channel_struct {
ssh_session session; /* SSH_SESSION pointer */
@@ -97,9 +92,8 @@ SSH_PACKET_CALLBACK(channel_rcv_close);
SSH_PACKET_CALLBACK(channel_rcv_request);
SSH_PACKET_CALLBACK(channel_rcv_data);
int channel_default_bufferize(ssh_channel channel,
void *data, size_t len,
bool is_stderr);
int channel_default_bufferize(ssh_channel channel, void *data, int len,
int is_stderr);
int ssh_channel_flush(ssh_channel channel);
uint32_t ssh_channel_new_id(ssh_session session);
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);

View File

@@ -46,7 +46,6 @@ enum ssh_config_opcode_e {
SOC_STRICTHOSTKEYCHECK,
SOC_KNOWNHOSTS,
SOC_PROXYCOMMAND,
SOC_PROXYJUMP,
SOC_GSSAPISERVERIDENTITY,
SOC_GSSAPICLIENTIDENTITY,
SOC_GSSAPIDELEGATECREDENTIALS,
@@ -61,7 +60,6 @@ enum ssh_config_opcode_e {
SOC_PASSWORDAUTHENTICATION,
SOC_PUBKEYAUTHENTICATION,
SOC_PUBKEYACCEPTEDTYPES,
SOC_REKEYLIMIT,
SOC_MAX /* Keep this one last in the list */
};

View File

@@ -1,57 +0,0 @@
/*
* config_parser.h - Common configuration file parser functions
*
* This file is part of the SSH Library
*
* Copyright (c) 2019 by Red Hat, Inc.
*
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef CONFIG_PARSER_H_
#define CONFIG_PARSER_H_
char *ssh_config_get_cmd(char **str);
char *ssh_config_get_token(char **str);
long ssh_config_get_long(char **str, long notfound);
const char *ssh_config_get_str_tok(char **str, const char *def);
int ssh_config_get_yesno(char **str, int notfound);
/* @brief Parse SSH URI in format [user@]host[:port] from the given string
*
* @param[in] tok String to parse
* @param[out] username Pointer to the location, where the new username will
* be stored or NULL if we do not care about the result.
* @param[out] hostname Pointer to the location, where the new hostname will
* be stored or NULL if we do not care about the result.
* @param[out] port Pointer to the location, where the new port will
* be stored or NULL if we do not care about the result.
*
* @returns SSH_OK if the provided string is in format of SSH URI,
* SSH_ERROR on failure
*/
int ssh_config_parse_uri(const char *tok,
char **username,
char **hostname,
char **port);
#endif /* LIBSSH_CONFIG_H_ */

View File

@@ -25,7 +25,6 @@
#ifndef _CRYPTO_H_
#define _CRYPTO_H_
#include <stdbool.h>
#include "config.h"
#ifdef HAVE_LIBGCRYPT
@@ -45,7 +44,6 @@
#ifdef HAVE_OPENSSL_ECDH_H
#include <openssl/ecdh.h>
#endif
#include "libssh/dh.h"
#include "libssh/ecdh.h"
#include "libssh/kex.h"
#include "libssh/curve25519.h"
@@ -60,12 +58,6 @@ enum ssh_key_exchange_e {
SSH_KEX_DH_GROUP1_SHA1=1,
/* diffie-hellman-group14-sha1 */
SSH_KEX_DH_GROUP14_SHA1,
#ifdef WITH_GEX
/* diffie-hellman-group-exchange-sha1 */
SSH_KEX_DH_GEX_SHA1,
/* diffie-hellman-group-exchange-sha256 */
SSH_KEX_DH_GEX_SHA256,
#endif /* WITH_GEX */
/* ecdh-sha2-nistp256 */
SSH_KEX_ECDH_SHA2_NISTP256,
/* ecdh-sha2-nistp384 */
@@ -80,15 +72,11 @@ enum ssh_key_exchange_e {
SSH_KEX_DH_GROUP16_SHA512,
/* diffie-hellman-group18-sha512 */
SSH_KEX_DH_GROUP18_SHA512,
/* diffie-hellman-group14-sha256 */
SSH_KEX_DH_GROUP14_SHA256,
};
enum ssh_cipher_e {
SSH_NO_CIPHER=0,
#ifdef WITH_BLOWFISH_CIPHER
SSH_BLOWFISH_CBC,
#endif /* WITH_BLOWFISH_CIPHER */
SSH_3DES_CBC,
SSH_AES128_CBC,
SSH_AES192_CBC,
@@ -101,14 +89,8 @@ enum ssh_cipher_e {
SSH_AEAD_CHACHA20_POLY1305
};
struct dh_ctx;
struct ssh_crypto_struct {
bignum shared_secret;
struct dh_ctx *dh_ctx;
#ifdef WITH_GEX
size_t dh_pmin; size_t dh_pn; size_t dh_pmax; /* preferred group parameters */
#endif /* WITH_GEX */
bignum e,f,x,k,y;
#ifdef HAVE_ECDH
#ifdef HAVE_OPENSSL_ECC
EC_KEY *ecdh_privkey;
@@ -126,7 +108,7 @@ struct ssh_crypto_struct {
ssh_curve25519_pubkey curve25519_server_pubkey;
#endif
ssh_string dh_server_signature; /* information used by dh_handshake. */
size_t digest_len; /* len of the two fields below */
size_t digest_len; /* len of all the fields below */
unsigned char *session_id;
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
unsigned char *encryptIV;
@@ -138,7 +120,6 @@ struct ssh_crypto_struct {
unsigned char hmacbuf[DIGEST_MAX_LEN];
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */
bool in_hmac_etm, out_hmac_etm; /* Whether EtM mode is used or not */
ssh_key server_pubkey;
int do_compress_out; /* idem */
@@ -152,8 +133,7 @@ struct ssh_crypto_struct {
struct ssh_kex_struct client_kex;
char *kex_methods[SSH_KEX_METHODS];
enum ssh_key_exchange_e kex_type;
enum ssh_kdf_digest digest_type; /* Digest type for session keys derivation */
enum ssh_crypto_direction_e used; /* Is this crypto still used for either of directions? */
enum ssh_mac_e mac_type; /* Mac operations to use for key gen */
};
struct ssh_cipher_struct {
@@ -182,11 +162,6 @@ struct ssh_cipher_struct {
struct chacha20_poly1305_keysched *chacha20_schedule;
unsigned int keysize; /* bytes of key used. != keylen */
size_t tag_size; /* overhead required for tag */
/* Counters for rekeying initialization */
uint32_t packets;
uint64_t blocks;
/* Rekeying limit for the cipher or manually enforced */
uint64_t max_blocks;
/* sets the new key for immediate use */
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
@@ -208,9 +183,5 @@ struct ssh_cipher_struct {
};
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void);
int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
unsigned char *key, size_t key_len,
int key_type, unsigned char *output,
size_t requested_len);
#endif /* _CRYPTO_H_ */

View File

@@ -48,9 +48,10 @@ typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
int ssh_client_curve25519_init(ssh_session session);
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet);
#ifdef WITH_SERVER
void ssh_server_curve25519_init(ssh_session session);
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet);
#endif /* WITH_SERVER */
#endif /* CURVE25519_H_ */

View File

@@ -1,32 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.be>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef SRC_DH_GEX_H_
#define SRC_DH_GEX_H_
int ssh_client_dhgex_init(ssh_session session);
#ifdef WITH_SERVER
void ssh_server_dhgex_init(ssh_session session);
#endif /* WITH_SERVER */
#endif /* SRC_DH_GEX_H_ */

View File

@@ -25,37 +25,25 @@
#include "libssh/crypto.h"
struct dh_ctx;
int ssh_dh_generate_e(ssh_session session);
int ssh_dh_generate_f(ssh_session session);
int ssh_dh_generate_x(ssh_session session);
int ssh_dh_generate_y(ssh_session session);
#define DH_CLIENT_KEYPAIR 0
#define DH_SERVER_KEYPAIR 1
/* functions implemented by crypto backends */
int ssh_dh_init_common(struct ssh_crypto_struct *crypto);
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto);
int ssh_dh_get_parameters(struct dh_ctx *ctx,
const_bignum *modulus, const_bignum *generator);
int ssh_dh_set_parameters(struct dh_ctx *ctx,
const bignum modulus, const bignum generator);
int ssh_dh_keypair_gen_keys(struct dh_ctx *ctx, int peer);
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
const_bignum *priv, const_bignum *pub);
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
const bignum priv, const bignum pub);
int ssh_dh_compute_shared_secret(struct dh_ctx *ctx, int local, int remote,
bignum *dest);
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c);
/* common functions */
int ssh_dh_init(void);
void ssh_dh_finalize(void);
int ssh_dh_import_next_pubkey_blob(ssh_session session,
ssh_string pubkey_blob);
ssh_string ssh_dh_get_e(ssh_session session);
ssh_string ssh_dh_get_f(ssh_session session);
int ssh_dh_import_f(ssh_session session,ssh_string f_string);
int ssh_dh_import_e(ssh_session session, ssh_string e_string);
int ssh_dh_import_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
int ssh_dh_build_k(ssh_session session);
int ssh_client_dh_init(ssh_session session);
int ssh_client_dh_reply(ssh_session session, ssh_buffer packet);
ssh_key ssh_dh_get_current_server_publickey(ssh_session session);
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
@@ -64,12 +52,10 @@ ssh_key ssh_dh_get_next_server_publickey(ssh_session session);
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
ssh_string *pubkey_blob);
int ssh_client_dh_init(ssh_session session);
#ifdef WITH_SERVER
void ssh_server_dh_init(ssh_session session);
#endif /* WITH_SERVER */
int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet);
int ssh_fallback_group(uint32_t pmax, bignum *p, bignum *g);
bool ssh_dh_is_known_group(bignum modulus, bignum generator);
int ssh_make_sessionid(ssh_session session);
/* add data for the final cookie */
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int ssh_hashbufout_add_cookie(ssh_session session);
int ssh_generate_session_keys(ssh_session session);
#endif /* DH_H_ */

View File

@@ -22,7 +22,6 @@
#define ECDH_H_
#include "config.h"
#include "libssh/callbacks.h"
#ifdef HAVE_LIBCRYPTO
#ifdef HAVE_OPENSSL_ECDH_H
@@ -42,15 +41,15 @@
#define HAVE_ECDH 1
#endif
extern struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks;
/* Common functions. */
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
/* Backend-specific functions. */
int ssh_client_ecdh_init(ssh_session session);
int ecdh_build_k(ssh_session session);
#ifdef WITH_SERVER
extern struct ssh_packet_callbacks_struct ssh_ecdh_server_callbacks;
void ssh_server_ecdh_init(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init);
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet);
#endif /* WITH_SERVER */
#endif /* ECDH_H_ */

View File

@@ -56,8 +56,8 @@ int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
* @return 0 on success.
*/
int crypto_sign_ed25519(
unsigned char *sm, uint64_t *smlen,
const unsigned char *m, uint64_t mlen,
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
const ed25519_privkey sk);
/** @internal
@@ -71,8 +71,8 @@ int crypto_sign_ed25519(
* @returns 0 on success (supposedly).
*/
int crypto_sign_ed25519_open(
unsigned char *m, uint64_t *mlen,
const unsigned char *sm, uint64_t smlen,
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
const ed25519_pubkey pk);
/** @} */

View File

@@ -39,7 +39,7 @@ void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
void fe25519_pack(unsigned char r[32], const fe25519 *x);
uint32_t fe25519_iszero(const fe25519 *x);
int fe25519_iszero(const fe25519 *x);
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);

View File

@@ -39,21 +39,12 @@ int ssh_set_client_kex(ssh_session session);
int ssh_kex_select_methods(ssh_session session);
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list);
char **ssh_space_tokenize(const char *chain);
int ssh_get_kex1(ssh_session session);
char *ssh_find_matching(const char *in_d, const char *what_d);
const char *ssh_kex_get_supported_method(uint32_t algo);
const char *ssh_kex_get_default_methods(uint32_t algo);
const char *ssh_kex_get_fips_methods(uint32_t algo);
const char *ssh_kex_get_description(uint32_t algo);
char *ssh_client_select_hostkeys(ssh_session session);
int ssh_send_rekex(ssh_session session);
int server_set_kex(ssh_session session);
int ssh_make_sessionid(ssh_session session);
/* add data for the final cookie */
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int ssh_hashbufout_add_cookie(ssh_session session);
int ssh_generate_session_keys(ssh_session session);
#endif /* KEX_H_ */

View File

@@ -28,13 +28,13 @@
struct ssh_public_key_struct {
int type;
const char *type_c; /* Don't free it ! it is static */
#if defined(HAVE_LIBGCRYPT)
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa_pub;
gcry_sexp_t rsa_pub;
#elif defined(HAVE_LIBCRYPTO)
#elif HAVE_LIBCRYPTO
DSA *dsa_pub;
RSA *rsa_pub;
#elif defined(HAVE_LIBMBEDCRYPTO)
#elif HAVE_LIBMBEDCRYPTO
mbedtls_pk_context *rsa_pub;
void *dsa_pub;
#endif
@@ -42,13 +42,13 @@ struct ssh_public_key_struct {
struct ssh_private_key_struct {
int type;
#if defined(HAVE_LIBGCRYPT)
#ifdef HAVE_LIBGCRYPT
gcry_sexp_t dsa_priv;
gcry_sexp_t rsa_priv;
#elif defined(HAVE_LIBCRYPTO)
#elif defined HAVE_LIBCRYPTO
DSA *dsa_priv;
RSA *rsa_priv;
#elif defined(HAVE_LIBMBEDCRYPTO)
#elif HAVE_LIBMBEDCRYPTO
mbedtls_pk_context *rsa_priv;
void *dsa_priv;
#endif

View File

@@ -23,7 +23,6 @@
#define SSH_KNOWNHOSTS_H_
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
char *ssh_known_hosts_get_algorithms_names(ssh_session session);
enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry_file(ssh_session session,
const char *filename,

View File

@@ -31,7 +31,6 @@
#include <openssl/md5.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
typedef EVP_MD_CTX* SHACTX;
typedef EVP_MD_CTX* SHA256CTX;
@@ -65,7 +64,6 @@ typedef void *EVPCTX;
#define BROKEN_AES_CTR
#endif
typedef BIGNUM* bignum;
typedef const BIGNUM* const_bignum;
typedef BN_CTX* bignum_CTX;
#define bignum_new() BN_new()
@@ -76,47 +74,19 @@ typedef BN_CTX* bignum_CTX;
} \
} while(0)
#define bignum_set_word(bn,n) BN_set_word(bn,n)
#define bignum_bin2bn(data, datalen, dest) \
do { \
(*dest) = BN_new(); \
if ((*dest) != NULL) { \
BN_bin2bn(data,datalen,(*dest)); \
} \
} while(0)
#define bignum_bin2bn(bn,datalen,data) BN_bin2bn(bn,datalen,data)
#define bignum_bn2dec(num) BN_bn2dec(num)
#define bignum_dec2bn(data, bn) BN_dec2bn(bn, data)
#define bignum_hex2bn(data, bn) BN_hex2bn(bn, data)
#define bignum_bn2hex(num, dest) (*dest)=(unsigned char *)BN_bn2hex(num)
#define bignum_dec2bn(bn,data) BN_dec2bn(data,bn)
#define bignum_bn2hex(num) BN_bn2hex(num)
#define bignum_rand(rnd, bits) BN_rand(rnd, bits, 0, 1)
#define bignum_rand_range(rnd, max) BN_rand_range(rnd, max)
#define bignum_ctx_new() BN_CTX_new()
#define bignum_ctx_free(num) BN_CTX_free(num)
#define bignum_ctx_invalid(ctx) ((ctx) == NULL)
#define bignum_mod_exp(dest,generator,exp,modulo,ctx) BN_mod_exp(dest,generator,exp,modulo,ctx)
#define bignum_add(dest, a, b) BN_add(dest, a, b)
#define bignum_sub(dest, a, b) BN_sub(dest, a, b)
#define bignum_mod(dest, a, b, ctx) BN_mod(dest, a, b, ctx)
#define bignum_num_bytes(num) (size_t)BN_num_bytes(num)
#define bignum_num_bits(num) (size_t)BN_num_bits(num)
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num, (int)bit)
#define bignum_bn2bin(num,len, ptr) BN_bn2bin(num, ptr)
#define bignum_num_bytes(num) BN_num_bytes(num)
#define bignum_num_bits(num) BN_num_bits(num)
#define bignum_is_bit_set(num,bit) BN_is_bit_set(num,bit)
#define bignum_bn2bin(num,ptr) BN_bn2bin(num,ptr)
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
#define bignum_rshift1(dest, src) BN_rshift1(dest, src)
#define bignum_dup(orig, dest) do { \
if (*(dest) == NULL) { \
*(dest) = BN_dup(orig); \
} else { \
BN_copy(*(dest), orig); \
} \
} while(0)
/* Returns true if the OpenSSL is operating in FIPS mode */
#ifdef HAVE_OPENSSL_FIPS_MODE
#define ssh_fips_mode() (FIPS_mode() != 0)
#else
#define ssh_fips_mode() false
#endif
#endif /* HAVE_LIBCRYPTO */

View File

@@ -50,8 +50,6 @@ typedef gcry_md_hd_t EVPCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
typedef gcry_mpi_t bignum;
typedef const struct gcry_mpi *const_bignum;
typedef void* bignum_CTX;
/* Constants for curves. */
#define NID_gcrypt_nistp256 0
@@ -61,7 +59,6 @@ typedef void* bignum_CTX;
/* missing gcrypt functions */
int ssh_gcry_dec2bn(bignum *bn, const char *data);
char *ssh_gcry_bn2dec(bignum bn);
int ssh_gcry_rand_range(bignum rnd, bignum max);
#define bignum_new() gcry_mpi_new(0)
#define bignum_safe_free(num) do { \
@@ -70,38 +67,20 @@ int ssh_gcry_rand_range(bignum rnd, bignum max);
(num)=NULL; \
} \
} while (0)
#define bignum_free(num) gcry_mpi_release(num)
#define bignum_ctx_new() NULL
#define bignum_ctx_free(ctx) do {(ctx) = NULL;} while(0)
#define bignum_ctx_invalid(ctx) (ctx != NULL)
#define bignum_set_word(bn,n) (gcry_mpi_set_ui(bn,n)!=NULL ? 1 : 0)
#define bignum_bin2bn(data,datalen,dest) gcry_mpi_scan(dest,GCRYMPI_FMT_USG,data,datalen,NULL)
#define bignum_set_word(bn,n) gcry_mpi_set_ui(bn,n)
#define bignum_bin2bn(bn,datalen,data) gcry_mpi_scan(data,GCRYMPI_FMT_USG,bn,datalen,NULL)
#define bignum_bn2dec(num) ssh_gcry_bn2dec(num)
#define bignum_dec2bn(num, data) ssh_gcry_dec2bn(data, num)
#define bignum_bn2hex(num, data) \
gcry_mpi_aprint(GCRYMPI_FMT_HEX, data, NULL, (const gcry_mpi_t)num)
#define bignum_hex2bn(data, num) (gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,0,NULL)==0?1:0)
#define bignum_rand(num,bits) 1,gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
#define bignum_mod_exp(dest,generator,exp,modulo, ctx) 1,gcry_mpi_powm(dest,generator,exp,modulo)
#define bignum_bn2hex(num,data) gcry_mpi_aprint(GCRYMPI_FMT_HEX,data,NULL,num)
#define bignum_hex2bn(num,datalen,data) gcry_mpi_scan(num,GCRYMPI_FMT_HEX,data,datalen,NULL)
#define bignum_rand(num,bits) gcry_mpi_randomize(num,bits,GCRY_STRONG_RANDOM),gcry_mpi_set_bit(num,bits-1),gcry_mpi_set_bit(num,0)
#define bignum_mod_exp(dest,generator,exp,modulo) gcry_mpi_powm(dest,generator,exp,modulo)
#define bignum_num_bits(num) gcry_mpi_get_nbits(num)
#define bignum_num_bytes(num) ((gcry_mpi_get_nbits(num)+7)/8)
#define bignum_is_bit_set(num,bit) gcry_mpi_test_bit(num,bit)
#define bignum_bn2bin(num,datalen,data) gcry_mpi_print(GCRYMPI_FMT_USG,data,datalen,NULL,num)
#define bignum_cmp(num1,num2) gcry_mpi_cmp(num1,num2)
#define bignum_rshift1(dest, src) gcry_mpi_rshift (dest, src, 1)
#define bignum_add(dst, a, b) gcry_mpi_add(dst, a, b)
#define bignum_sub(dst, a, b) gcry_mpi_sub(dst, a, b)
#define bignum_mod(dst, a, b, ctx) 1,gcry_mpi_mod(dst, a, b)
#define bignum_rand_range(rnd, max) ssh_gcry_rand_range(rnd, max);
#define bignum_dup(orig, dest) do { \
if (*(dest) == NULL) { \
*(dest) = gcry_mpi_copy(orig); \
} else { \
gcry_mpi_set(*(dest), orig); \
} \
} while(0)
/* Helper functions for data conversions. */
/* Extract an MPI from the given s-expression SEXP named NAME which is
@@ -112,8 +91,6 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
enum gcry_mpi_format informat,
enum gcry_mpi_format outformat);
#define ssh_fips_mode() false
#endif /* HAVE_LIBGCRYPT */
#endif /* LIBGCRYPT_H_ */

View File

@@ -60,8 +60,6 @@ typedef mbedtls_md_context_t *EVPCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
typedef mbedtls_mpi *bignum;
typedef const mbedtls_mpi *const_bignum;
typedef void* bignum_CTX;
/* Constants for curves */
#define NID_mbedtls_nistp256 0
@@ -75,11 +73,9 @@ struct mbedtls_ecdsa_sig {
bignum ssh_mbedcry_bn_new(void);
void ssh_mbedcry_bn_free(bignum num);
unsigned char *ssh_mbedcry_bn2num(const_bignum num, int radix);
char *ssh_mbedcry_bn2num(bignum num, int radix);
int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom);
int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
int ssh_mbedcry_rand_range(bignum dest, bignum max);
int ssh_mbedcry_hex2bn(bignum *dest, char *data);
#define bignum_new() ssh_mbedcry_bn_new()
#define bignum_safe_free(num) do { \
@@ -88,44 +84,22 @@ int ssh_mbedcry_hex2bn(bignum *dest, char *data);
(num)=NULL; \
} \
} while(0)
#define bignum_ctx_new() NULL
#define bignum_ctx_free(num) do {(num) = NULL;} while(0)
#define bignum_ctx_invalid(ctx) (ctx == NULL?0:1)
#define bignum_set_word(bn, n) (mbedtls_mpi_lset(bn, n)==0?1:0) /* TODO fix
#define bignum_set_word(bn, n) mbedtls_mpi_lset(bn, n) /* TODO fix
overflow/underflow */
#define bignum_bin2bn(data, datalen, bn) do { \
*(bn) = bignum_new(); \
if (*(bn) != NULL) { \
mbedtls_mpi_read_binary(*(bn), data, datalen); \
} \
} while(0)
#define bignum_bin2bn(data, datalen, bn) mbedtls_mpi_read_binary(bn, data, \
datalen)
#define bignum_bn2dec(num) ssh_mbedcry_bn2num(num, 10)
#define bignum_dec2bn(data, bn) mbedtls_mpi_read_string(bn, 10, data)
#define bignum_bn2hex(num, dest) (*dest)=ssh_mbedcry_bn2num(num, 16)
#define bignum_hex2bn(data, dest) ssh_mbedcry_hex2bn(dest, data)
#define bignum_bn2hex(num) ssh_mbedcry_bn2num(num, 16)
#define bignum_rand(rnd, bits) ssh_mbedcry_rand((rnd), (bits), 0, 1)
#define bignum_rand_range(rnd, max) ssh_mbedcry_rand_range(rnd, max)
#define bignum_mod_exp(dest, generator, exp, modulo, ctx) \
(mbedtls_mpi_exp_mod(dest, generator, exp, modulo, NULL)==0?1:0)
#define bignum_add(dest, a, b) mbedtls_mpi_add_mpi(dest, a, b)
#define bignum_sub(dest, a, b) mbedtls_mpi_sub_mpi(dest, a, b)
#define bignum_mod(dest, a, b, ctx) \
(mbedtls_mpi_mod_mpi(dest, a, b) == 0 ? 1 : 0)
mbedtls_mpi_exp_mod(dest, generator, exp, modulo, NULL)
#define bignum_num_bytes(num) mbedtls_mpi_size(num)
#define bignum_num_bits(num) mbedtls_mpi_bitlen(num)
#define bignum_is_bit_set(num, bit) ssh_mbedcry_is_bit_set(num, bit)
#define bignum_bn2bin(num, len, ptr) mbedtls_mpi_write_binary(num, ptr, \
#define bignum_bn2bin(num, ptr) mbedtls_mpi_write_binary(num, ptr, \
mbedtls_mpi_size(num))
#define bignum_cmp(num1, num2) mbedtls_mpi_cmp_mpi(num1, num2)
#define bignum_rshift1(dest, src) mbedtls_mpi_copy(dest, src), mbedtls_mpi_shift_r(dest, 1)
#define bignum_dup(orig, dest) do { \
if (*(dest) == NULL) { \
*(dest) = bignum_new(); \
} \
if (*(dest) != NULL) { \
mbedtls_mpi_copy(orig, *(dest)); \
} \
} while(0)
mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void);
@@ -134,7 +108,5 @@ int ssh_mbedtls_random(void *where, int len, int strong);
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
mbedtls_ecp_point *p);
#define ssh_fips_mode() false
#endif /* HAVE_LIBMBEDCRYPTO */
#endif /* LIBMBEDCRYPTO_H_ */

View File

@@ -78,8 +78,8 @@
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 9
#define LIBSSH_VERSION_MICRO 3
#define LIBSSH_VERSION_MINOR 8
#define LIBSSH_VERSION_MICRO 90
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \
@@ -168,13 +168,13 @@ enum ssh_auth_e {
};
/* auth flags */
#define SSH_AUTH_METHOD_UNKNOWN 0x0000u
#define SSH_AUTH_METHOD_NONE 0x0001u
#define SSH_AUTH_METHOD_PASSWORD 0x0002u
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004u
#define SSH_AUTH_METHOD_HOSTBASED 0x0008u
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010u
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020u
#define SSH_AUTH_METHOD_UNKNOWN 0
#define SSH_AUTH_METHOD_NONE 0x0001
#define SSH_AUTH_METHOD_PASSWORD 0x0002
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004
#define SSH_AUTH_METHOD_HOSTBASED 0x0008
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020
/* messages */
enum ssh_requests_e {
@@ -293,17 +293,10 @@ enum ssh_keytypes_e{
SSH_KEYTYPE_DSS=1,
SSH_KEYTYPE_RSA,
SSH_KEYTYPE_RSA1,
SSH_KEYTYPE_ECDSA, /* deprecated */
SSH_KEYTYPE_ECDSA,
SSH_KEYTYPE_ED25519,
SSH_KEYTYPE_DSS_CERT01,
SSH_KEYTYPE_RSA_CERT01,
SSH_KEYTYPE_ECDSA_P256,
SSH_KEYTYPE_ECDSA_P384,
SSH_KEYTYPE_ECDSA_P521,
SSH_KEYTYPE_ECDSA_P256_CERT01,
SSH_KEYTYPE_ECDSA_P384_CERT01,
SSH_KEYTYPE_ECDSA_P521_CERT01,
SSH_KEYTYPE_ED25519_CERT01,
SSH_KEYTYPE_RSA_CERT01
};
enum ssh_keycmp_e {
@@ -413,8 +406,6 @@ enum ssh_options_e {
SSH_OPTIONS_NODELAY,
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
SSH_OPTIONS_PROCESS_CONFIG,
SSH_OPTIONS_REKEY_DATA,
SSH_OPTIONS_REKEY_TIME,
};
enum {
@@ -441,7 +432,6 @@ enum ssh_scp_request_types {
enum ssh_connector_flags_e {
/** Only the standard stream of the channel */
SSH_CONNECTOR_STDOUT = 1,
SSH_CONNECTOR_STDINOUT = 1,
/** Only the exception stream of the channel */
SSH_CONNECTOR_STDERR = 2,
/** Merge both standard and exception streams */
@@ -462,8 +452,6 @@ LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
LIBSSH_API int ssh_channel_open_forward_unix(ssh_channel channel, const char *remotepath,
const char *sourcehost, int localport);
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
@@ -559,7 +547,6 @@ SSH_DEPRECATED LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *ke
SSH_DEPRECATED LIBSSH_API int ssh_write_knownhost(ssh_session session);
SSH_DEPRECATED LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
SSH_DEPRECATED LIBSSH_API int ssh_is_server_known(ssh_session session);
SSH_DEPRECATED LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
@@ -589,8 +576,9 @@ LIBSSH_API int ssh_session_export_known_hosts_entry(ssh_session session,
char **pentry_string);
LIBSSH_API int ssh_session_update_known_hosts(ssh_session session);
LIBSSH_API enum ssh_known_hosts_e ssh_session_get_known_hosts_entry(ssh_session session,
struct ssh_knownhosts_entry **pentry);
LIBSSH_API enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry(ssh_session session,
struct ssh_knownhosts_entry **pentry);
LIBSSH_API enum ssh_known_hosts_e ssh_session_is_known_server(ssh_session session);
/* LOGGING */
@@ -608,7 +596,6 @@ SSH_DEPRECATED LIBSSH_API void ssh_log(ssh_session session,
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
LIBSSH_API ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg);
LIBSSH_API int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);
LIBSSH_API int ssh_message_channel_request_reply_success(ssh_message msg);
#define SSH_MESSAGE_FREE(x) \
do { if ((x) != NULL) { ssh_message_free(x); (x) = NULL; } } while(0)
@@ -633,13 +620,7 @@ LIBSSH_API ssh_pcap_file ssh_pcap_file_new(void);
LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
/**
* @addtogroup libssh_auth
*
* @{
*/
/**
* @brief SSH authentication callback for password and publickey auth.
* @brief SSH authentication callback.
*
* @param prompt Prompt to be displayed.
* @param buf Buffer to save the password. You should null-terminate it.
@@ -654,8 +635,6 @@ LIBSSH_API int ssh_pcap_file_open(ssh_pcap_file pcap, const char *filename);
typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata);
/** @} */
LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
@@ -720,6 +699,7 @@ LIBSSH_API char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
unsigned char *hash,
size_t len);
LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char *hash, size_t len);
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);

View File

@@ -28,7 +28,7 @@ struct ssh_auth_request {
int method;
char *password;
struct ssh_key_struct *pubkey;
enum ssh_publickey_state_e signature_state;
char signature_state;
char kbdint_response;
};
@@ -102,5 +102,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request);
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
const char *request, uint8_t want_reply);
ssh_message ssh_message_pop_head(ssh_session session);
int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan);
#endif /* MESSAGES_H_ */

View File

@@ -26,7 +26,6 @@
char *ssh_get_user_home_dir(void);
char *ssh_get_local_username(void);
int ssh_file_readaccess_ok(const char *file);
int ssh_dir_writeable(const char *path);
char *ssh_path_expand_tilde(const char *d);
char *ssh_path_expand_escape(ssh_session session, const char *s);
@@ -51,12 +50,6 @@ struct ssh_timestamp {
long useconds;
};
enum ssh_quote_state_e {
NO_QUOTE,
SINGLE_QUOTE,
DOUBLE_QUOTE
};
struct ssh_list *ssh_list_new(void);
void ssh_list_free(struct ssh_list *list);
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
@@ -90,11 +83,4 @@ int ssh_match_group(const char *group, const char *object);
void uint64_inc(unsigned char *counter);
void ssh_log_hexdump(const char *descr, const unsigned char *what, size_t len);
int ssh_mkdirs(const char *pathname, mode_t mode);
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
int ssh_newline_vis(const char *string, char *buf, size_t buf_len);
#endif /* MISC_H_ */

View File

@@ -81,11 +81,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
unsigned char *ssh_packet_encrypt(ssh_session session,
void *packet,
unsigned int len);
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
int ssh_packet_hmac_verify(ssh_session session,ssh_buffer buffer,
unsigned char *mac, enum ssh_hmac_e type);
int ssh_packet_set_newkeys(ssh_session session,
enum ssh_crypto_direction_e direction);
struct ssh_crypto_struct *ssh_packet_get_current_crypto(ssh_session session,
enum ssh_crypto_direction_e direction);
#endif /* PACKET_H_ */

View File

@@ -30,15 +30,7 @@
#endif
#include "libssh/crypto.h"
#ifdef HAVE_OPENSSL_ED25519
/* If using OpenSSL implementation, define the signature lenght which would be
* defined in libssh/ed25519.h otherwise */
#define ED25519_SIG_LEN 64
#else
#include "libssh/ed25519.h"
#endif
/* This definition is used for both OpenSSL and internal implementations */
#define ED25519_KEY_LEN 32
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
@@ -69,13 +61,8 @@ struct ssh_key_struct {
void *ecdsa;
# endif /* HAVE_OPENSSL_EC_H */
#endif /* HAVE_LIBGCRYPT */
#ifdef HAVE_OPENSSL_ED25519
uint8_t *ed25519_pubkey;
uint8_t *ed25519_privkey;
#else
ed25519_pubkey *ed25519_pubkey;
ed25519_privkey *ed25519_privkey;
#endif
void *cert;
enum ssh_keytypes_e cert_type;
};
@@ -88,14 +75,19 @@ struct ssh_signature_struct {
gcry_sexp_t dsa_sig;
gcry_sexp_t rsa_sig;
gcry_sexp_t ecdsa_sig;
#elif defined(HAVE_LIBCRYPTO)
DSA_SIG *dsa_sig;
ssh_string rsa_sig;
# ifdef HAVE_OPENSSL_ECC
ECDSA_SIG *ecdsa_sig;
# else
void *ecdsa_sig;
# endif
#elif defined(HAVE_LIBMBEDCRYPTO)
ssh_string rsa_sig;
struct mbedtls_ecdsa_sig ecdsa_sig;
#endif /* HAVE_LIBGCRYPT */
#ifndef HAVE_OPENSSL_ED25519
ed25519_signature *ed25519_sig;
#endif
ssh_string raw_sig;
};
typedef struct ssh_signature_struct *ssh_signature;
@@ -108,19 +100,6 @@ const char *
ssh_key_get_signature_algorithm(ssh_session session,
enum ssh_keytypes_e type);
enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name);
enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type);
enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
enum ssh_keytypes_e type);
enum ssh_digest_e ssh_key_hash_from_name(const char *name);
#define is_ecdsa_key_type(t) \
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
#define is_cert_type(kt)\
((kt) == SSH_KEYTYPE_DSS_CERT01 ||\
(kt) == SSH_KEYTYPE_RSA_CERT01 ||\
((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
(kt) <= SSH_KEYTYPE_ED25519_CERT01))
/* SSH Signature Functions */
ssh_signature ssh_signature_new(void);
@@ -134,7 +113,7 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
int ssh_pki_signature_verify(ssh_session session,
ssh_signature sig,
const ssh_key key,
const unsigned char *digest,
unsigned char *digest,
size_t dlen);
/* SSH Public Key Functions */
@@ -149,13 +128,12 @@ int ssh_pki_import_cert_blob(const ssh_string cert_blob,
/* SSH Signing Functions */
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
const ssh_key privatekey, enum ssh_digest_e hash_type);
const ssh_key privatekey);
ssh_string ssh_pki_do_sign_agent(ssh_session session,
struct ssh_buffer_struct *buf,
const ssh_key pubkey);
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
const ssh_key privkey,
const enum ssh_digest_e digest);
const ssh_key privkey);
/* Temporary functions, to be removed after migration to ssh_key */
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);

View File

@@ -61,8 +61,6 @@ int pki_key_compare(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
int pki_key_check_hash_compatible(ssh_key key,
enum ssh_digest_e hash_type);
/* SSH Private Key Functions */
enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey);
ssh_key pki_private_key_from_base64(const char *b64_key,
@@ -111,29 +109,30 @@ int pki_privkey_build_ecdsa(ssh_key key,
ssh_string pki_publickey_to_blob(const ssh_key key);
/* SSH Signature Functions */
ssh_signature pki_sign_data(const ssh_key privkey,
enum ssh_digest_e hash_type,
const unsigned char *input,
size_t input_len);
int pki_verify_data_signature(ssh_signature signature,
const ssh_key pubkey,
const unsigned char *input,
size_t input_len);
ssh_string pki_signature_to_blob(const ssh_signature sign);
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
const ssh_string sig_blob,
enum ssh_keytypes_e type,
enum ssh_digest_e hash_type);
int pki_signature_verify(ssh_session session,
const ssh_signature sig,
const ssh_key key,
const unsigned char *hash,
size_t hlen);
/* SSH Signing Functions */
ssh_signature pki_do_sign(const ssh_key privkey,
const unsigned char *input,
size_t input_len,
enum ssh_digest_e hash_type);
#define pki_do_sign(key, hash, hlen) \
pki_do_sign_hash(key, hash, hlen, SSH_DIGEST_AUTO)
ssh_signature pki_do_sign_hash(const ssh_key privkey,
const unsigned char *hash,
size_t hlen,
enum ssh_digest_e hash_type);
#define pki_do_sign_sessionid(key, hash, hlen) \
pki_do_sign_sessionid_hash(key, hash, hlen, SSH_DIGEST_AUTO)
ssh_signature pki_do_sign_sessionid_hash(const ssh_key key,
const unsigned char *hash,
size_t hlen,
enum ssh_digest_e hash_type);
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
@@ -143,8 +142,8 @@ int pki_ed25519_key_cmp(const ssh_key k1,
enum ssh_keycmp_e what);
int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig);
int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob);
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
int pki_privkey_build_ed25519(ssh_key key,
ssh_string pubkey,
ssh_string privkey);

View File

@@ -78,22 +78,6 @@ char *strndup(const char *s, size_t n);
# endif /* __WORDSIZE */
# endif /* PRIu64 */
# ifndef PRIu32
# define PRIu32 "u"
# endif /* PRIu32 */
# ifndef PRIx64
# if __WORDSIZE == 64
# define PRIx64 "lx"
# else
# define PRIx64 "llx"
# endif /* __WORDSIZE */
# endif /* PRIx64 */
# ifndef PRIx32
# define PRIx32 "x"
# endif /* PRIx32 */
# ifdef _MSC_VER
# include <stdio.h>
# include <stdarg.h> /* va_copy define check */
@@ -221,17 +205,7 @@ int gettimeofday(struct timeval *__p, void *__t);
struct ssh_common_struct;
struct ssh_kex_struct;
enum ssh_digest_e {
SSH_DIGEST_AUTO=0,
SSH_DIGEST_SHA1=1,
SSH_DIGEST_SHA256,
SSH_DIGEST_SHA384,
SSH_DIGEST_SHA512,
};
int ssh_get_key_params(ssh_session session,
ssh_key *privkey,
enum ssh_digest_e *digest);
int ssh_get_key_params(ssh_session session, ssh_key *privkey);
/* LOGGING */
void ssh_log_function(int verbosity,
@@ -282,12 +256,14 @@ int ssh_auth_reply_success(ssh_session session, int partial);
int ssh_send_banner(ssh_session session, int is_server);
/* connect.c */
socket_t ssh_connect_host(ssh_session session, const char *host,const char
*bind_addr, int port, long timeout, long usec);
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
const char *bind_addr, int port);
/* in base64.c */
ssh_buffer base64_to_bin(const char *source);
uint8_t *bin_to_base64(const uint8_t *source, size_t len);
unsigned char *bin_to_base64(const unsigned char *source, int len);
/* gzip.c */
int compress_buffer(ssh_session session,ssh_buffer buf);
@@ -348,6 +324,7 @@ void explicit_bzero(void *s, size_t n);
/**
* Get the argument cound of variadic arguments
*/
#ifdef HAVE_GCC_NARG_MACRO
/*
* Since MSVC 2010 there is a bug in passing __VA_ARGS__ to subsequent
* macros as a single token, which results in:
@@ -357,7 +334,7 @@ void explicit_bzero(void *s, size_t n);
#define VA_APPLY_VARIADIC_MACRO(macro, tuple) macro tuple
#define __VA_NARG__(...) \
(__VA_NARG_(__VA_ARGS__, __RSEQ_N()))
(__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) \
VA_APPLY_VARIADIC_MACRO(__VA_ARG_N, (__VA_ARGS__))
#define __VA_ARG_N( \
@@ -376,6 +353,10 @@ void explicit_bzero(void *s, size_t n);
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#else
/* clang does not support the above construction */
#define __VA_NARG__(...) (-1)
#endif
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
@@ -405,20 +386,20 @@ void explicit_bzero(void *s, size_t n);
# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
#endif /* FALL_THROUGH */
#ifndef __attr_unused__
#ifndef __unused__
# ifdef HAVE_UNUSED_ATTRIBUTE
# define __attr_unused__ __attribute__((unused))
# define __unused__ __attribute__((unused))
# else /* HAVE_UNUSED_ATTRIBUTE */
# define __attr_unused__
# define __unused__
# endif /* HAVE_UNUSED_ATTRIBUTE */
#endif /* __attr_unused__ */
#endif /* __unused__ */
#ifndef UNUSED_PARAM
#define UNUSED_PARAM(param) param __attr_unused__
#define UNUSED_PARAM(param) param __unused__
#endif /* UNUSED_PARAM */
#ifndef UNUSED_VAR
#define UNUSED_VAR(var) __attr_unused__ var
#define UNUSED_VAR(var) __unused__ var
#endif /* UNUSED_VAR */
void ssh_agent_state_free(void *data);

View File

@@ -46,16 +46,7 @@ enum ssh_bind_options_e {
SSH_BIND_OPTIONS_LOG_VERBOSITY,
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
SSH_BIND_OPTIONS_ECDSAKEY,
SSH_BIND_OPTIONS_IMPORT_KEY,
SSH_BIND_OPTIONS_KEY_EXCHANGE,
SSH_BIND_OPTIONS_CIPHERS_C_S,
SSH_BIND_OPTIONS_CIPHERS_S_C,
SSH_BIND_OPTIONS_HMAC_C_S,
SSH_BIND_OPTIONS_HMAC_S_C,
SSH_BIND_OPTIONS_CONFIG_DIR,
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES,
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS,
SSH_BIND_OPTIONS_PROCESS_CONFIG,
SSH_BIND_OPTIONS_IMPORT_KEY
};
typedef struct ssh_bind_struct* ssh_bind;
@@ -94,9 +85,6 @@ LIBSSH_API ssh_bind ssh_bind_new(void);
LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind,
enum ssh_bind_options_e type, const void *value);
LIBSSH_API int ssh_bind_options_parse_config(ssh_bind sshbind,
const char *filename);
/**
* @brief Start listening to the socket.
*

View File

@@ -30,7 +30,6 @@
#include "libssh/channels.h"
#include "libssh/poll.h"
#include "libssh/config.h"
#include "libssh/misc.h"
/* These are the different states a SSH session can be into its life */
enum ssh_session_state_e {
@@ -49,8 +48,6 @@ enum ssh_session_state_e {
enum ssh_dh_state_e {
DH_STATE_INIT=0,
DH_STATE_GROUP_SENT,
DH_STATE_REQUEST_SENT,
DH_STATE_INIT_SENT,
DH_STATE_NEWKEYS_SENT,
DH_STATE_FINISHED
@@ -93,11 +90,10 @@ enum ssh_pending_call_e {
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
/* extensions flags */
/* negotiation enabled */
#define SSH_EXT_NEGOTIATION 0x01
/* server-sig-algs extension */
#define SSH_EXT_SIG_RSA_SHA256 0x02
#define SSH_EXT_SIG_RSA_SHA512 0x04
#define SSH_EXT_SIG_RSA_SHA256 0x01
#define SSH_EXT_SIG_RSA_SHA512 0x02
#define SSH_EXT_ALL SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512
/* members that are common to ssh_session and ssh_bind */
struct ssh_common_struct {
@@ -117,7 +113,6 @@ struct ssh_session_struct {
int openssh;
uint32_t send_seq;
uint32_t recv_seq;
struct ssh_timestamp last_rekey_time;
int connected;
/* !=0 when the user got a session handle */
@@ -138,14 +133,12 @@ struct ssh_session_struct {
ssh_buffer in_buffer;
PACKET in_packet;
ssh_buffer out_buffer;
struct ssh_list *out_queue; /* This list is used for delaying packets
when rekeying is required */
/* the states are used by the nonblocking stuff to remember */
/* where it was before being interrupted */
enum ssh_pending_call_e pending_call_state;
enum ssh_session_state_e session_state;
enum ssh_packet_state_e packet_state;
int packet_state;
enum ssh_dh_state_e dh_handshake_state;
enum ssh_channel_request_state_e global_req_state;
struct ssh_agent_state_struct *agent_state;
@@ -188,7 +181,6 @@ struct ssh_session_struct {
ssh_key ed25519_key;
/* The type of host key wanted by client */
enum ssh_keytypes_e hostkey;
enum ssh_digest_e hostkey_digest;
} srv;
/* auths accepted by server */
@@ -213,7 +205,7 @@ struct ssh_session_struct {
char *sshdir;
char *knownhosts;
char *global_knownhosts;
char *wanted_methods[SSH_KEX_METHODS];
char *wanted_methods[10];
char *pubkey_accepted_types;
char *ProxyCommand;
char *custombanner;
@@ -230,8 +222,6 @@ struct ssh_session_struct {
int nodelay;
bool config_processed;
uint8_t options_seen[SOC_MAX];
uint64_t rekey_data;
uint32_t rekey_time;
} opts;
/* counters */
ssh_counter socket_counter;

View File

@@ -201,18 +201,13 @@ struct sftp_statvfs_struct {
};
/**
* @brief Creates a new sftp session.
*
* This function creates a new sftp session and allocates a new sftp channel
* with the server inside of the provided ssh session. This function call is
* usually followed by the sftp_init(), which initializes SFTP protocol itself.
* @brief Start a new sftp session.
*
* @param session The ssh session to use.
*
* @return A new sftp session or NULL on error.
*
* @see sftp_free()
* @see sftp_init()
*/
LIBSSH_API sftp_session sftp_new(ssh_session session);
@@ -237,10 +232,7 @@ LIBSSH_API sftp_session sftp_new_channel(ssh_session session, ssh_channel channe
LIBSSH_API void sftp_free(sftp_session sftp);
/**
* @brief Initialize the sftp protocol with the server.
*
* This function involves the SFTP protocol initialization (as described
* in the SFTP specification), including the version and extensions negotiation.
* @brief Initialize the sftp session with the server.
*
* @param sftp The sftp session to initialize.
*
@@ -826,9 +818,7 @@ LIBSSH_API int sftp_fsync(sftp_file file);
*
* @param path The path to be canonicalized.
*
* @return A pointer to the newly allocated canonicalized path,
* NULL on error. The caller needs to free the memory
* using ssh_string_free_char().
* @return The canonicalize path, NULL on error.
*/
LIBSSH_API char *sftp_canonicalize_path(sftp_session sftp, const char *path);
@@ -861,15 +851,15 @@ LIBSSH_API sftp_session sftp_server_new(ssh_session session, ssh_channel chan);
* @return 0 on success, < 0 on error.
*/
LIBSSH_API int sftp_server_init(sftp_session sftp);
/**
* @brief Close and deallocate a sftp server session.
*
* @param sftp The sftp session handle to free.
*/
LIBSSH_API void sftp_server_free(sftp_session sftp);
#endif /* WITH_SERVER */
/* this is not a public interface */
#define SFTP_HANDLES 256
sftp_packet sftp_packet_read(sftp_session sftp);
int sftp_packet_write(sftp_session sftp,uint8_t type, ssh_buffer payload);
void sftp_packet_free(sftp_packet packet);
int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr);
sftp_attributes sftp_parse_attr(sftp_session session, ssh_buffer buf,int expectname);
/* sftpserver.c */
LIBSSH_API sftp_client_message sftp_get_client_message(sftp_session sftp);

View File

@@ -1,32 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2003-2008 by Aris Adamantiadis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SFTP_PRIV_H
#define SFTP_PRIV_H
sftp_packet sftp_packet_read(sftp_session sftp);
ssize_t sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload);
void sftp_packet_free(sftp_packet packet);
int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr);
sftp_attributes sftp_parse_attr(sftp_session session,
ssh_buffer buf,
int expectname);
#endif /* SFTP_PRIV_H */

View File

@@ -63,9 +63,6 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle(ssh_socket s);
int ssh_socket_connect(ssh_socket s,
const char *host,
uint16_t port,
const char *bind_addr);
int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr);
#endif /* SOCKET_H_ */

View File

@@ -1,48 +0,0 @@
/*
* token.h - Tokens list handling
*
* This file is part of the SSH Library
*
* Copyright (c) 2019 by Red Hat, Inc.
*
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef TOKEN_H_
#define TOKEN_H_
struct ssh_tokens_st {
char *buffer;
char **tokens;
};
struct ssh_tokens_st *ssh_tokenize(const char *chain, char separator);
void ssh_tokens_free(struct ssh_tokens_st *tokens);
char *ssh_find_matching(const char *available_d,
const char *preferred_d);
char *ssh_find_all_matching(const char *available_d,
const char *preferred_d);
char *ssh_remove_duplicates(const char *list);
char *ssh_append_without_duplicates(const char *list,
const char *appended_list);
#endif /* TOKEN_H_ */

View File

@@ -21,24 +21,30 @@
#ifndef WRAPPER_H_
#define WRAPPER_H_
#include <stdbool.h>
#include "config.h"
#include "libssh/libssh.h"
#include "libssh/libcrypto.h"
#include "libssh/libgcrypt.h"
#include "libssh/libmbedcrypto.h"
enum ssh_kdf_digest {
SSH_KDF_SHA1=1,
SSH_KDF_SHA256,
SSH_KDF_SHA384,
SSH_KDF_SHA512
enum ssh_digest_e {
SSH_DIGEST_AUTO=0,
SSH_DIGEST_SHA1=1,
SSH_DIGEST_SHA256,
SSH_DIGEST_SHA512
};
enum ssh_mac_e {
SSH_MAC_SHA1=1,
SSH_MAC_SHA256,
SSH_MAC_SHA384,
SSH_MAC_SHA512
};
enum ssh_hmac_e {
SSH_HMAC_SHA1 = 1,
SSH_HMAC_SHA256,
SSH_HMAC_SHA384,
SSH_HMAC_SHA512,
SSH_HMAC_MD5,
SSH_HMAC_AEAD_POLY1305,
@@ -53,17 +59,9 @@ enum ssh_des_e {
struct ssh_hmac_struct {
const char* name;
enum ssh_hmac_e hmac_type;
bool etm;
};
enum ssh_crypto_direction_e {
SSH_DIRECTION_IN = 1,
SSH_DIRECTION_OUT = 2,
SSH_DIRECTION_BOTH = 3,
};
struct ssh_cipher_struct;
struct ssh_crypto_struct;
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void);
@@ -73,38 +71,37 @@ void md5_final(unsigned char *md,MD5CTX c);
SHACTX sha1_init(void);
void sha1_update(SHACTX c, const void *data, unsigned long len);
void sha1_final(unsigned char *md,SHACTX c);
void sha1(const unsigned char *digest,int len,unsigned char *hash);
void sha1(unsigned char *digest,int len,unsigned char *hash);
SHA256CTX sha256_init(void);
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
void sha256_final(unsigned char *md,SHA256CTX c);
void sha256(const unsigned char *digest, int len, unsigned char *hash);
void sha256(unsigned char *digest, int len, unsigned char *hash);
SHA384CTX sha384_init(void);
void sha384_update(SHA384CTX c, const void *data, unsigned long len);
void sha384_final(unsigned char *md,SHA384CTX c);
void sha384(const unsigned char *digest, int len, unsigned char *hash);
void sha384(unsigned char *digest, int len, unsigned char *hash);
SHA512CTX sha512_init(void);
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
void sha512_final(unsigned char *md,SHA512CTX c);
void sha512(const unsigned char *digest, int len, unsigned char *hash);
void sha512(unsigned char *digest, int len, unsigned char *hash);
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
EVPCTX evp_init(int nid);
void evp_update(EVPCTX ctx, const void *data, unsigned long len);
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type);
void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len);
void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx);
HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
void hmac_update(HMACCTX c, const void *data, unsigned long len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
size_t hmac_digest_len(enum ssh_hmac_e type);
int ssh_kdf(struct ssh_crypto_struct *crypto,
unsigned char *key, size_t key_len,
int key_type, unsigned char *output,
size_t requested_len);
int crypt_set_algorithms_client(ssh_session session);
int crypt_set_algorithms_server(ssh_session session);
struct ssh_crypto_struct *crypto_new(void);
@@ -117,6 +114,6 @@ void ssh_crypto_finalize(void);
void ssh_cipher_clear(struct ssh_cipher_struct *cipher);
struct ssh_hmac_struct *ssh_get_hmactab(void);
struct ssh_cipher_struct *ssh_get_ciphertab(void);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type, bool etm);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type);
#endif /* WRAPPER_H_ */

15
libssh-config.cmake.in Normal file
View File

@@ -0,0 +1,15 @@
@PACKAGE_INIT@
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/CMakeCache.txt")
# In tree build
set_and_check(LIBSSH_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
set_and_check(LIBSSH_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/@LIBSSH_LIBRARY_NAME@")
else()
set_and_check(LIBSSH_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(LIBSSH_LIBRARIES "@PACKAGE_LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@")
endif()
# For backward compatibility
set(LIBSSH_LIBRARY ${LIBSSH_LIBRARIES})
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_LIBRARY LIBSSH_INCLUDE_DIR)

View File

@@ -1,6 +1,6 @@
Name: ${PROJECT_NAME}
Description: The SSH Library
Version: ${PROJECT_VERSION}
Libs: -L${CMAKE_INSTALL_FULL_LIBDIR} -lssh
Cflags: -I${CMAKE_INSTALL_FULL_INCLUDEDIR}
Libs: -L${LIB_INSTALL_DIR} -lssh
Cflags: -I${INCLUDE_INSTALL_DIR}

200
obj/build_make.sh Executable file
View File

@@ -0,0 +1,200 @@
#!/bin/bash
#
# Last Change: 2008-06-18 14:13:46
#
# Script to build libssh on UNIX.
#
# Copyright (c) 2006-2007 Andreas Schneider <asn@cryptomilk.org>
#
SOURCE_DIR=".."
LANG=C
export LANG
SCRIPT="$0"
COUNT=0
while [ -L "${SCRIPT}" ]
do
SCRIPT=$(readlink ${SCRIPT})
COUNT=$(expr ${COUNT} + 1)
if [ ${COUNT} -gt 100 ]; then
echo "Too many symbolic links"
exit 1
fi
done
BUILDDIR=$(dirname ${SCRIPT})
cleanup_and_exit () {
if test "$1" = 0 -o -z "$1" ; then
exit 0
else
exit $1
fi
}
function configure() {
if [ -n "${CMAKEDIR}" ]; then
${CMAKEDIR}/bin/cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
else
cmake "$@" ${SOURCE_DIR} || cleanup_and_exit $?
fi
}
function compile() {
if [ -f /proc/cpuinfo ]; then
CPUCOUNT=$(grep -c processor /proc/cpuinfo)
elif test `uname` = "SunOS" ; then
CPUCOUNT=$(psrinfo -p)
else
CPUCOUNT="1"
fi
if [ "${CPUCOUNT}" -gt "1" ]; then
${MAKE} -j${CPUCOUNT} $1 || cleanup_and_exit $?
else
${MAKE} $1 || exit $?
fi
}
function clean_build_dir() {
find ! -path "*.svn*" ! -name "*.bat" ! -name "*.sh" ! -name "." -print0 | xargs -0 rm -rf
}
function usage () {
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make
(gmake|make)|--ccompiler(gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withserver|--withoutsymbolversioning]"
cleanup_and_exit
}
cd ${BUILDDIR}
# the default CMake options:
OPTIONS="--graphviz=${BUILDDIR}/libssh.dot"
# the default 'make' utility:
MAKE="make"
while test -n "$1"; do
PARAM="$1"
ARG="$2"
shift
case ${PARAM} in
*-*=*)
ARG=${PARAM#*=}
PARAM=${PARAM%%=*}
set -- "----noarg=${PARAM}" "$@"
esac
case ${PARAM} in
*-help|-h)
#echo_help
usage
cleanup_and_exit
;;
*-build)
DOMAKE="1"
BUILD_TYPE="${ARG}"
test -n "${BUILD_TYPE}" && shift
;;
*-clean)
clean_build_dir
cleanup_and_exit
;;
*-clang)
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
;;
*-verbose)
DOVERBOSE="1"
;;
*-memtest)
OPTIONS="${OPTIONS} -DMEM_NULL_TESTS=ON"
;;
*-libsuffix)
OPTIONS="${OPTIONS} -DLIB_SUFFIX=${ARG}"
shift
;;
*-prefix)
OPTIONS="${OPTIONS} -DCMAKE_INSTALL_PREFIX=${ARG}"
shift
;;
*-sysconfdir)
OPTIONS="${OPTIONS} -DSYSCONF_INSTALL_DIR=${ARG}"
shift
;;
*-cmakedir)
CMAKEDIR="${ARG}"
shift
;;
*-make)
MAKE="${ARG}"
shift
;;
*-ccompiler)
OPTIONS="${OPTIONS} -DCMAKE_C_COMPILER=${ARG}"
shift
;;
*-withstaticlib)
OPTIONS="${OPTIONS} -DWITH_STATIC_LIB=ON"
;;
*-unittesting)
OPTIONS="${OPTIONS} -DUNIT_TESTING=ON"
;;
*-clientunittesting)
OPTIONS="${OPTIONS} -DCLIENT_TESTING=ON"
;;
*-withserver)
OPTIONS="${OPTIONS} -DWITH_SERVER=ON"
;;
*-withoutsymbolversioning)
OPTIONS="${OPTIONS} -DWITH_SYMBOL_VERSIONING=OFF"
;;
*-finalrelease)
OPTIONS="${OPTIONS} -DWITH_FINAL=ON"
;;
----noarg)
echo "$ARG does not take an argument"
cleanup_and_exit
;;
-*)
echo Unknown Option "$PARAM". Exit.
cleanup_and_exit 1
;;
*)
usage
;;
esac
done
if [ "${DOMAKE}" == "1" ]; then
OPTIONS="${OPTIONS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE}"
fi
if [ -n "${DOVERBOSE}" ]; then
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=1"
else
OPTIONS="${OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=0"
fi
test -f "${BUILDDIR}/.build.log" && rm -f ${BUILDDIR}/.build.log
touch ${BUILDDIR}/.build.log
# log everything from here to .build.log
exec 1> >(exec -a 'build logging tee' tee -a ${BUILDDIR}/.build.log) 2>&1
echo "${HOST} started build at $(date)."
echo
configure ${OPTIONS} "$@"
if [ -n "${DOMAKE}" ]; then
test -n "${DOVERBOSE}" && compile VERBOSE=1 || compile
fi
DOT=$(which dot 2>/dev/null)
if [ -n "${DOT}" ]; then
${DOT} -Tpng -o${BUILDDIR}/libssh.png ${BUILDDIR}/libssh.dot
${DOT} -Tsvg -o${BUILDDIR}/libssh.svg ${BUILDDIR}/libssh.dot
fi
exec >&0 2>&0 # so that the logging tee finishes
sleep 1 # wait till tee terminates
cleanup_and_exit 0

View File

@@ -1 +1 @@
4.8.5
4.7.2

View File

@@ -1,415 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,415 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,419 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,421 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,421 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,421 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,421 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,421 +0,0 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -1,4 +1,7 @@
set(LIBSSH_PUBLIC_INCLUDE_DIRS ${libssh_SOURCE_DIR}/include)
set(LIBSSH_PUBLIC_INCLUDE_DIRS
${libssh_SOURCE_DIR}/include
CACHE INTERNAL "libssh public include directories"
)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${libssh_BINARY_DIR}
@@ -15,6 +18,13 @@ if (WIN32)
)
endif (WIN32)
if (HAVE_LIBSOCKET)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
socket
)
endif (HAVE_LIBSOCKET)
if (OPENSSL_CRYPTO_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
@@ -85,12 +95,15 @@ if (WITH_NACL AND NACL_FOUND)
)
endif (WITH_NACL AND NACL_FOUND)
if (MINGW AND Threads_FOUND)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
Threads::Threads
)
endif()
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
CACHE INTERNAL "libssh link libraries"
)
set(LIBSSH_SHARED_LIBRARY
ssh_shared
CACHE INTERNAL "libssh shared library"
)
if (BUILD_STATIC_LIB)
set(LIBSSH_STATIC_LIBRARY
@@ -117,7 +130,6 @@ set(libssh_SRCS
error.c
getpass.c
init.c
kdf.c
kex.c
known_hosts.c
knownhosts.c
@@ -133,6 +145,7 @@ set(libssh_SRCS
pcap.c
pki.c
pki_container_openssh.c
pki_ed25519.c
poll.c
session.c
scp.c
@@ -143,11 +156,12 @@ set(libssh_SRCS
external/bcrypt_pbkdf.c
external/blowfish.c
external/chacha.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
external/poly1305.c
external/sc25519.c
chachapoly.c
config_parser.c
token.c
pki_ed25519_common.c
)
if (DEFAULT_C_NO_DEPRECATION_FLAGS)
@@ -183,12 +197,6 @@ if (WITH_GCRYPT)
gcrypt_missing.c
pki_gcrypt.c
ecdh_gcrypt.c
dh_key.c
pki_ed25519.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
external/sc25519.c
)
elseif (WITH_MBEDTLS)
set(libssh_SRCS
@@ -198,12 +206,6 @@ elseif (WITH_MBEDTLS)
mbedcrypto_missing.c
pki_mbedcrypto.c
ecdh_mbedcrypto.c
dh_key.c
pki_ed25519.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
external/sc25519.c
)
else (WITH_GCRYPT)
set(libssh_SRCS
@@ -212,18 +214,7 @@ else (WITH_GCRYPT)
pki_crypto.c
ecdh_crypto.c
libcrypto.c
dh_crypto.c
)
if (NOT HAVE_OPENSSL_ED25519)
set(libssh_SRCS
${libssh_SRCS}
pki_ed25519.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
external/sc25519.c
)
endif (NOT HAVE_OPENSSL_ED25519)
if(OPENSSL_VERSION VERSION_LESS "1.1.0")
set(libssh_SRCS ${libssh_SRCS} libcrypto-compat.c)
endif()
@@ -248,17 +239,9 @@ if (WITH_SERVER)
${libssh_SRCS}
server.c
bind.c
bind_config.c
)
endif (WITH_SERVER)
if (WITH_GEX)
set(libssh_SRCS
${libssh_SRCS}
dh-gex.c
)
endif (WITH_GEX)
if (WITH_ZLIB)
set(libssh_SRCS
${libssh_SRCS}
@@ -274,14 +257,17 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
endif (WITH_GSSAPI AND GSSAPI_FOUND)
if (NOT WITH_NACL)
if (NOT HAVE_OPENSSL_ED25519)
set(libssh_SRCS
${libssh_SRCS}
external/curve25519_ref.c
)
endif (NOT HAVE_OPENSSL_ED25519)
set(libssh_SRCS
${libssh_SRCS}
external/curve25519_ref.c
)
endif (NOT WITH_NACL)
include_directories(
${LIBSSH_PUBLIC_INCLUDE_DIRS}
${LIBSSH_PRIVATE_INCLUDE_DIRS}
)
# Set the path to the default map file
set(MAP_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.map")
@@ -313,27 +299,10 @@ if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
)
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT AND ABIMAP_FOUND)
# This gets built as a static library, if -DBUILD_SHARED_LIBS=OFF is passed to
# cmake.
add_library(ssh ${libssh_SRCS})
target_compile_options(ssh
PRIVATE
${DEFAULT_C_COMPILE_FLAGS}
-D_GNU_SOURCE)
target_include_directories(ssh
PUBLIC
$<BUILD_INTERFACE:${libssh_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${LIBSSH_PRIVATE_INCLUDE_DIRS})
add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS})
target_compile_options(${LIBSSH_SHARED_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh
PRIVATE ${LIBSSH_LINK_LIBRARIES})
if (WIN32 AND NOT BUILD_SHARED_LIBS)
set_target_properties(ssh PROPERTIES COMPILE_FLAGS "-DLIBSSH_STATIC")
endif ()
add_library(ssh::ssh ALIAS ssh)
target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES})
if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
if (ABIMAP_FOUND)
@@ -341,55 +310,45 @@ if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
set(MAP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_dev.map")
endif (ABIMAP_FOUND)
set_target_properties(ssh
set_target_properties(${LIBSSH_SHARED_LIBRARY}
PROPERTIES LINK_FLAGS
"-Wl,--version-script,\"${MAP_PATH}\"")
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
set_target_properties(ssh
set_target_properties(
${LIBSSH_SHARED_LIBRARY}
PROPERTIES
VERSION
${LIBRARY_VERSION}
SOVERSION
${LIBRARY_SOVERSION}
OUTPUT_NAME
ssh
DEFINE_SYMBOL
LIBSSH_EXPORTS
)
if (WITH_VISIBILITY_HIDDEN)
set_target_properties(ssh PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
endif (WITH_VISIBILITY_HIDDEN)
if (MINGW)
set_target_properties(ssh PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
set_target_properties(${LIBSSH_SHARED_LIBRARY} PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
endif ()
install(TARGETS ssh
EXPORT libssh-config
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT libraries)
install(EXPORT libssh-config
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
install(
TARGETS
${LIBSSH_SHARED_LIBRARY}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
COMPONENT libraries
)
if (BUILD_STATIC_LIB)
add_library(ssh-static STATIC ${libssh_SRCS})
target_compile_options(ssh-static
PRIVATE
${DEFAULT_C_COMPILE_FLAGS}
-D_GNU_SOURCE)
target_include_directories(ssh-static
PUBLIC
$<BUILD_INTERFACE:${libssh_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${LIBSSH_PRIVATE_INCLUDE_DIRS})
target_link_libraries(ssh-static
PUBLIC ${LIBSSH_LINK_LIBRARIES})
add_library(ssh::static ALIAS ssh-static)
add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS})
target_compile_options(${LIBSSH_STATIC_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
if (MSVC)
set(OUTPUT_SUFFIX static)
@@ -397,7 +356,7 @@ if (BUILD_STATIC_LIB)
set(OUTPUT_SUFFIX )
endif (MSVC)
set_target_properties(
ssh-static
${LIBSSH_STATIC_LIBRARY}
PROPERTIES
VERSION
${LIBRARY_VERSION}
@@ -411,12 +370,21 @@ if (BUILD_STATIC_LIB)
if (WIN32)
set_target_properties(
ssh-static
${LIBSSH_STATIC_LIBRARY}
PROPERTIES
COMPILE_FLAGS
"-DLIBSSH_STATIC"
)
endif (WIN32)
if (WITH_STATIC_LIB)
install(TARGETS
${LIBSSH_STATIC_LIBRARY}
DESTINATION
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
COMPONENT
libraries)
endif (WITH_STATIC_LIB)
endif (BUILD_STATIC_LIB)
message(STATUS "Threads_FOUND=${Threads_FOUND}")

View File

@@ -196,7 +196,7 @@ void ssh_agent_close(struct ssh_agent_struct *agent) {
void ssh_agent_free(ssh_agent agent) {
if (agent) {
if (agent->ident) {
SSH_BUFFER_FREE(agent->ident);
ssh_buffer_free(agent->ident);
}
if (agent->sock) {
ssh_agent_close(agent);
@@ -307,91 +307,90 @@ static int agent_talk(struct ssh_session_struct *session,
return 0;
}
uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
{
ssh_buffer request = NULL;
ssh_buffer reply = NULL;
unsigned int type = 0;
uint32_t count = 0;
int rc;
int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
ssh_buffer request = NULL;
ssh_buffer reply = NULL;
unsigned int type = 0;
uint32_t count = 0;
int rc;
/* send message to the agent requesting the list of identities */
request = ssh_buffer_new();
if (request == NULL) {
ssh_set_error_oom(session);
return 0;
}
if (ssh_buffer_add_u8(request, SSH2_AGENTC_REQUEST_IDENTITIES) < 0) {
ssh_set_error_oom(session);
SSH_BUFFER_FREE(request);
return 0;
}
/* send message to the agent requesting the list of identities */
request = ssh_buffer_new();
if (request == NULL) {
ssh_set_error_oom(session);
return -1;
}
if (ssh_buffer_add_u8(request, SSH2_AGENTC_REQUEST_IDENTITIES) < 0) {
ssh_set_error_oom(session);
ssh_buffer_free(request);
return -1;
}
reply = ssh_buffer_new();
if (reply == NULL) {
SSH_BUFFER_FREE(request);
ssh_set_error(session, SSH_FATAL, "Not enough space");
return 0;
}
reply = ssh_buffer_new();
if (reply == NULL) {
ssh_buffer_free(request);
ssh_set_error(session, SSH_FATAL, "Not enough space");
return -1;
}
if (agent_talk(session, request, reply) < 0) {
SSH_BUFFER_FREE(request);
SSH_BUFFER_FREE(reply);
return 0;
}
SSH_BUFFER_FREE(request);
if (agent_talk(session, request, reply) < 0) {
ssh_buffer_free(request);
ssh_buffer_free(reply);
return 0;
}
ssh_buffer_free(request);
/* get message type and verify the answer */
rc = ssh_buffer_get_u8(reply, (uint8_t *) &type);
if (rc != sizeof(uint8_t)) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply size: %d", rc);
SSH_BUFFER_FREE(reply);
return 0;
}
/* get message type and verify the answer */
rc = ssh_buffer_get_u8(reply, (uint8_t *) &type);
if (rc != sizeof(uint8_t)) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply size: %d", rc);
ssh_buffer_free(reply);
return -1;
}
#ifdef WORDS_BIGENDIAN
type = bswap_32(type);
type = bswap_32(type);
#endif
SSH_LOG(SSH_LOG_WARN,
"Answer type: %d, expected answer: %d",
type, SSH2_AGENT_IDENTITIES_ANSWER);
SSH_LOG(SSH_LOG_WARN,
"Answer type: %d, expected answer: %d",
type, SSH2_AGENT_IDENTITIES_ANSWER);
if (agent_failed(type)) {
SSH_BUFFER_FREE(reply);
return 0;
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %u", type);
SSH_BUFFER_FREE(reply);
return 0;
}
if (agent_failed(type)) {
ssh_buffer_free(reply);
return 0;
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %u", type);
ssh_buffer_free(reply);
return -1;
}
rc = ssh_buffer_get_u32(reply, &count);
if (rc != 4) {
ssh_set_error(session,
SSH_FATAL,
"Failed to read count");
SSH_BUFFER_FREE(reply);
return 0;
}
session->agent->count = ntohl(count);
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
session->agent->count);
if (session->agent->count > 1024) {
ssh_set_error(session, SSH_FATAL,
"Too many identities in authentication reply: %d",
session->agent->count);
SSH_BUFFER_FREE(reply);
return 0;
}
rc = ssh_buffer_get_u32(reply, &count);
if (rc != 4) {
ssh_set_error(session,
SSH_FATAL,
"Failed to read count");
ssh_buffer_free(reply);
return -1;
}
session->agent->count = ntohl(count);
SSH_LOG(SSH_LOG_DEBUG, "Agent count: %d",
session->agent->count);
if (session->agent->count > 1024) {
ssh_set_error(session, SSH_FATAL,
"Too many identities in authentication reply: %d",
session->agent->count);
ssh_buffer_free(reply);
return -1;
}
if (session->agent->ident) {
ssh_buffer_reinit(session->agent->ident);
}
session->agent->ident = reply;
if (session->agent->ident) {
ssh_buffer_reinit(session->agent->ident);
}
session->agent->ident = reply;
return session->agent->count;
return session->agent->count;
}
/* caller has to free commment */
@@ -425,7 +424,7 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
/* get the comment */
tmp = ssh_buffer_get_ssh_string(session->agent->ident);
if (tmp == NULL) {
SSH_STRING_FREE(blob);
ssh_string_free(blob);
return NULL;
}
@@ -433,12 +432,12 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
if (comment) {
*comment = ssh_string_to_char(tmp);
} else {
SSH_STRING_FREE(blob);
SSH_STRING_FREE(tmp);
ssh_string_free(blob);
ssh_string_free(tmp);
return NULL;
}
SSH_STRING_FREE(tmp);
ssh_string_free(tmp);
/* get key from blob */
rc = ssh_pki_import_pubkey_blob(blob, &key);
@@ -446,7 +445,7 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
/* Try again as a cert. */
rc = ssh_pki_import_cert_blob(blob, &key);
}
SSH_STRING_FREE(blob);
ssh_string_free(blob);
if (rc == SSH_ERROR) {
return NULL;
}
@@ -492,13 +491,13 @@ ssh_string ssh_agent_sign_data(ssh_session session,
/* create request */
if (ssh_buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
rc = ssh_pki_export_pubkey_blob(pubkey, &key_blob);
if (rc < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
@@ -513,31 +512,31 @@ ssh_string ssh_agent_sign_data(ssh_session session,
sizeof(uint32_t) * 2 +
ssh_string_len(key_blob));
if (rc < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
/* adds len + blob */
rc = ssh_buffer_add_ssh_string(request, key_blob);
SSH_STRING_FREE(key_blob);
ssh_string_free(key_blob);
if (rc < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
/* Add data */
dlen = ssh_buffer_get_len(data);
if (ssh_buffer_add_u32(request, htonl(dlen)) < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
if (ssh_buffer_add_data(request, ssh_buffer_get(data), dlen) < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
/* Add Flags: SHA2 extension (RFC 8332) if negotiated */
if (ssh_key_type_plain(pubkey->type) == SSH_KEYTYPE_RSA) {
if (pubkey->type == SSH_KEYTYPE_RSA) {
if (session->extensions & SSH_EXT_SIG_RSA_SHA512) {
flags |= SSH_AGENT_RSA_SHA2_512;
} else if (session->extensions & SSH_EXT_SIG_RSA_SHA256) {
@@ -545,27 +544,27 @@ ssh_string ssh_agent_sign_data(ssh_session session,
}
}
if (ssh_buffer_add_u32(request, htonl(flags)) < 0) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
reply = ssh_buffer_new();
if (reply == NULL) {
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
return NULL;
}
/* send the request */
if (agent_talk(session, request, reply) < 0) {
SSH_BUFFER_FREE(request);
SSH_BUFFER_FREE(reply);
ssh_buffer_free(request);
ssh_buffer_free(reply);
return NULL;
}
SSH_BUFFER_FREE(request);
ssh_buffer_free(request);
/* check if reply is valid */
if (ssh_buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) {
SSH_BUFFER_FREE(reply);
ssh_buffer_free(reply);
return NULL;
}
#ifdef WORDS_BIGENDIAN
@@ -574,19 +573,19 @@ ssh_string ssh_agent_sign_data(ssh_session session,
if (agent_failed(type)) {
SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key");
SSH_BUFFER_FREE(reply);
ssh_buffer_free(reply);
return NULL;
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
ssh_set_error(session,
SSH_FATAL,
"Bad authentication response: %u",
type);
SSH_BUFFER_FREE(reply);
ssh_buffer_free(reply);
return NULL;
}
sig_blob = ssh_buffer_get_ssh_string(reply);
SSH_BUFFER_FREE(reply);
ssh_buffer_free(reply);
return sig_blob;
}

View File

@@ -25,7 +25,6 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#ifndef _WIN32
#include <netinet/in.h>
@@ -70,7 +69,7 @@ static int ssh_userauth_request_service(ssh_session session) {
int rc;
rc = ssh_service_request(session, "ssh-userauth");
if ((rc != SSH_OK) && (rc != SSH_AGAIN)) {
if (rc != SSH_OK) {
SSH_LOG(SSH_LOG_WARN,
"Failed to request \"ssh-userauth\" service");
}
@@ -205,7 +204,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_banner) {
SSH_LOG(SSH_LOG_DEBUG,
"Received SSH_USERAUTH_BANNER packet");
if (session->banner != NULL)
SSH_STRING_FREE(session->banner);
ssh_string_free(session->banner);
session->banner = banner;
}
@@ -283,10 +282,7 @@ end:
*
* It is also used to communicate the new to the upper levels.
*/
SSH_PACKET_CALLBACK(ssh_packet_userauth_success)
{
struct ssh_crypto_struct *crypto = NULL;
SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
(void)packet;
(void)type;
(void)user;
@@ -298,16 +294,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success)
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
if (crypto != NULL && crypto->delayed_compress_out) {
if (session->current_crypto && session->current_crypto->delayed_compress_out) {
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression OUT");
crypto->do_compress_out = 1;
session->current_crypto->do_compress_out = 1;
}
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
if (crypto != NULL && crypto->delayed_compress_in) {
if (session->current_crypto && session->current_crypto->delayed_compress_in) {
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression IN");
crypto->do_compress_in = 1;
session->current_crypto->do_compress_in = 1;
}
/* Reset errors by previous authentication methods. */
@@ -516,13 +509,26 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_ERROR;
}
/* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) {
ssh_set_error(session, SSH_REQUEST_DENIED,
switch (pubkey->type) {
case SSH_KEYTYPE_UNKNOWN:
ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)");
return SSH_AUTH_DENIED;
case SSH_KEYTYPE_ECDSA:
sig_type_c = ssh_pki_key_ecdsa_name(pubkey);
break;
case SSH_KEYTYPE_DSS:
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_DSS_CERT01:
case SSH_KEYTYPE_RSA_CERT01:
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
break;
}
/* Check if the given public key algorithm is allowed */
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by"
@@ -558,7 +564,7 @@ int ssh_userauth_try_publickey(ssh_session session,
goto fail;
}
SSH_STRING_FREE(pubkey_s);
ssh_string_free(pubkey_s);
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT;
@@ -576,7 +582,7 @@ pending:
return rc;
fail:
SSH_STRING_FREE(pubkey_s);
ssh_string_free(pubkey_s);
ssh_set_error_oom(session);
ssh_buffer_reinit(session->out_buffer);
@@ -614,7 +620,6 @@ int ssh_userauth_publickey(ssh_session session,
int rc;
const char *sig_type_c = NULL;
enum ssh_keytypes_e key_type;
enum ssh_digest_e hash_type;
if (session == NULL) {
return SSH_AUTH_ERROR;
@@ -640,13 +645,26 @@ int ssh_userauth_publickey(ssh_session session,
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
/* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, key_type);
if (sig_type_c == NULL) {
ssh_set_error(session, SSH_REQUEST_DENIED,
switch (key_type) {
case SSH_KEYTYPE_UNKNOWN:
ssh_set_error(session,
SSH_REQUEST_DENIED,
"Invalid key type (unknown)");
return SSH_AUTH_DENIED;
case SSH_KEYTYPE_ECDSA:
sig_type_c = ssh_pki_key_ecdsa_name(privkey);
break;
case SSH_KEYTYPE_DSS:
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_DSS_CERT01:
case SSH_KEYTYPE_RSA_CERT01:
sig_type_c = ssh_key_get_signature_algorithm(session, key_type);
break;
}
/* Check if the given public key algorithm is allowed */
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by"
@@ -681,19 +699,16 @@ int ssh_userauth_publickey(ssh_session session,
if (rc < 0) {
goto fail;
}
SSH_STRING_FREE(str);
/* Get the hash type to be used in the signature based on the key type */
hash_type = ssh_key_type_to_hash(session, privkey->type);
ssh_string_free(str);
/* sign the buffer with the private key */
str = ssh_pki_do_sign(session, session->out_buffer, privkey, hash_type);
str = ssh_pki_do_sign(session, session->out_buffer, privkey);
if (str == NULL) {
goto fail;
}
rc = ssh_buffer_add_ssh_string(session->out_buffer, str);
SSH_STRING_FREE(str);
ssh_string_free(str);
str = NULL;
if (rc < 0) {
goto fail;
@@ -715,7 +730,7 @@ pending:
return rc;
fail:
SSH_STRING_FREE(str);
ssh_string_free(str);
ssh_set_error_oom(session);
ssh_buffer_reinit(session->out_buffer);
@@ -756,15 +771,9 @@ static int ssh_userauth_agent_publickey(ssh_session session,
if (rc < 0) {
goto fail;
}
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
/* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"Invalid key type (unknown)");
SSH_STRING_FREE(pubkey_s);
return SSH_AUTH_DENIED;
}
if (!ssh_key_algorithm_allowed(session, sig_type_c)) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"The key algorithm '%s' is not allowed to be used by"
@@ -841,7 +850,7 @@ void ssh_agent_state_free(void *data) {
struct ssh_agent_state_struct *state = data;
if (state) {
SSH_STRING_FREE_CHAR(state->comment);
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
free (state);
}
@@ -919,7 +928,7 @@ int ssh_userauth_agent(ssh_session session,
} else if (rc != SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_DEBUG,
"Public key of %s refused by server", state->comment);
SSH_STRING_FREE_CHAR(state->comment);
ssh_string_free_char(state->comment);
state->comment = NULL;
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
@@ -935,7 +944,7 @@ int ssh_userauth_agent(ssh_session session,
rc = ssh_userauth_agent_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_AGAIN)
return rc;
SSH_STRING_FREE_CHAR(state->comment);
ssh_string_free_char(state->comment);
state->comment = NULL;
if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_PARTIAL) {
ssh_agent_state_free (session->agent_state);
@@ -1031,9 +1040,6 @@ int ssh_userauth_publickey_auto(ssh_session session,
ssh_set_error_oom(session);
return SSH_AUTH_ERROR;
}
/* Set state explicitly */
session->auth.auto_state->state = SSH_AUTH_AUTO_STATE_NONE;
}
state = session->auth.auto_state;
if (state->state == SSH_AUTH_AUTO_STATE_NONE) {
@@ -1116,9 +1122,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
"Public key authentication error for %s",
privkey_file);
ssh_key_free(state->privkey);
state->privkey = NULL;
ssh_key_free(state->pubkey);
state->pubkey = NULL;
SAFE_FREE(session->auth.auto_state);
return rc;
} else if (rc == SSH_AUTH_AGAIN) {
@@ -1184,9 +1188,6 @@ int ssh_userauth_publickey_auto(ssh_session session,
return rc;
}
ssh_key_free(state->privkey);
ssh_key_free(state->pubkey);
SSH_LOG(SSH_LOG_WARN,
"The server accepted the public key but refused the signature");
state->it = state->it->next;
@@ -1270,9 +1271,6 @@ int ssh_userauth_password(ssh_session session,
goto fail;
}
/* Set the buffer as secure to be explicitly zeroed when freed */
ssh_buffer_set_secure(session->out_buffer);
session->auth.current_method = SSH_AUTH_METHOD_PASSWORD;
session->auth.state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
@@ -1338,7 +1336,7 @@ ssh_kbdint ssh_kbdint_new(void) {
void ssh_kbdint_free(ssh_kbdint kbd) {
size_t i, n;
int i, n;
if (kbd == NULL) {
return;
@@ -1374,7 +1372,7 @@ void ssh_kbdint_free(ssh_kbdint kbd) {
}
void ssh_kbdint_clean(ssh_kbdint kbd) {
size_t i, n;
int i, n;
if (kbd == NULL) {
return;
@@ -1563,7 +1561,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
);
/* We don't care about tmp */
SSH_STRING_FREE(tmp);
ssh_string_free(tmp);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
@@ -1787,7 +1785,7 @@ const char *ssh_userauth_kbdint_getprompt(ssh_session session, unsigned int i,
}
if (echo) {
*echo = (char)session->kbdint->echo[i];
*echo = session->kbdint->echo[i];
}
return session->kbdint->prompts[i];

View File

@@ -29,8 +29,7 @@
#include "libssh/priv.h"
#include "libssh/buffer.h"
static
const uint8_t alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
@@ -168,19 +167,19 @@ ssh_buffer base64_to_bin(const char *source) {
error:
SAFE_FREE(base64);
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return NULL;
}
#define BLOCK(letter, n) do {ptr = strchr((const char *)alphabet, source[n]); \
#define BLOCK(letter, n) do {ptr = strchr(alphabet, source[n]); \
if(!ptr) return -1; \
i = ptr - (const char *)alphabet; \
i = ptr - alphabet; \
SET_##letter(*block, i); \
} while(0)
/* Returns 0 if ok, -1 if not (ie invalid char into the stuff) */
static int to_block4(unsigned long *block, const char *source, int num) {
const char *ptr = NULL;
char *ptr;
unsigned int i;
*block = 0;
@@ -235,32 +234,29 @@ static int get_equals(char *string) {
}
/* thanks sysk for debugging my mess :) */
static void _bin_to_base64(uint8_t *dest,
const uint8_t source[3],
size_t len)
{
#define BITS(n) ((1 << (n)) - 1)
switch (len) {
case 1:
dest[0] = alphabet[(source[0] >> 2)];
dest[1] = alphabet[((source[0] & BITS(2)) << 4)];
dest[2] = '=';
dest[3] = '=';
break;
case 2:
dest[0] = alphabet[source[0] >> 2];
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
dest[2] = alphabet[(source[1] & BITS(4)) << 2];
dest[3] = '=';
break;
case 3:
dest[0] = alphabet[(source[0] >> 2)];
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
dest[2] = alphabet[(source[2] >> 6) | (source[1] & BITS(4)) << 2];
dest[3] = alphabet[source[2] & BITS(6)];
break;
}
#undef BITS
static void _bin_to_base64(unsigned char *dest, const unsigned char source[3],
int len) {
switch (len) {
case 1:
dest[0] = alphabet[(source[0] >> 2)];
dest[1] = alphabet[((source[0] & BITS(2)) << 4)];
dest[2] = '=';
dest[3] = '=';
break;
case 2:
dest[0] = alphabet[source[0] >> 2];
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
dest[2] = alphabet[(source[1] & BITS(4)) << 2];
dest[3] = '=';
break;
case 3:
dest[0] = alphabet[(source[0] >> 2)];
dest[1] = alphabet[(source[1] >> 4) | ((source[0] & BITS(2)) << 4)];
dest[2] = alphabet[ (source[2] >> 6) | (source[1] & BITS(4)) << 2];
dest[3] = alphabet[source[2] & BITS(6)];
break;
}
}
/**
@@ -270,29 +266,25 @@ static void _bin_to_base64(uint8_t *dest,
*
* @returns the converted string
*/
uint8_t *bin_to_base64(const uint8_t *source, size_t len)
{
uint8_t *base64 = NULL;
uint8_t *ptr = NULL;
size_t flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
flen = (4 * flen) / 3 + 1;
unsigned char *bin_to_base64(const unsigned char *source, int len) {
unsigned char *base64;
unsigned char *ptr;
int flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
flen = (4 * flen) / 3 + 1;
base64 = malloc(flen);
if (base64 == NULL) {
return NULL;
}
ptr = base64;
base64 = malloc(flen);
if (base64 == NULL) {
return NULL;
}
ptr = base64;
while(len > 0){
_bin_to_base64(ptr, source, len > 3 ? 3 : len);
ptr += 4;
if (len < 3) {
break;
}
source += 3;
len -= 3;
}
ptr[0] = '\0';
while(len > 0){
_bin_to_base64(ptr, source, len > 3 ? 3 : len);
ptr += 4;
source += 3;
len -= 3;
}
ptr[0] = '\0';
return base64;
return base64;
}

View File

@@ -29,9 +29,9 @@
ssh_string ssh_make_bignum_string(bignum num) {
ssh_string ptr = NULL;
size_t pad = 0;
size_t len = bignum_num_bytes(num);
size_t bits = bignum_num_bits(num);
int pad = 0;
unsigned int len = bignum_num_bytes(num);
unsigned int bits = bignum_num_bits(num);
if (len == 0) {
return NULL;
@@ -43,9 +43,7 @@ ssh_string ssh_make_bignum_string(bignum num) {
}
#ifdef DEBUG_CRYPTO
SSH_LOG(SSH_LOG_TRACE,
"%zu bits, %zu bytes, %zu padding\n",
bits, len, pad);
fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
#endif /* DEBUG_CRYPTO */
ptr = ssh_string_new(len + pad);
@@ -58,40 +56,70 @@ ssh_string ssh_make_bignum_string(bignum num) {
ptr->data[0] = 0;
}
#ifdef HAVE_LIBGCRYPT
bignum_bn2bin(num, len, ptr->data + pad);
#elif HAVE_LIBCRYPTO
bignum_bn2bin(num, ptr->data + pad);
#elif HAVE_LIBMBEDCRYPTO
bignum_bn2bin(num, ptr->data + pad);
#endif
return ptr;
}
bignum ssh_make_string_bn(ssh_string string)
{
bignum bn = NULL;
size_t len = ssh_string_len(string);
bignum ssh_make_string_bn(ssh_string string){
bignum bn = NULL;
size_t len = ssh_string_len(string);
#ifdef DEBUG_CRYPTO
SSH_LOG(SSH_LOG_TRACE,
"Importing a %zu bits, %zu bytes object ...\n",
len * 8, len);
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
len * 8, len);
#endif /* DEBUG_CRYPTO */
bignum_bin2bn(string->data, len, &bn);
#ifdef HAVE_LIBGCRYPT
bignum_bin2bn(string->data, len, &bn);
#elif defined HAVE_LIBCRYPTO
bn = bignum_bin2bn(string->data, len, NULL);
#elif defined HAVE_LIBMBEDCRYPTO
bn = bignum_new();
bignum_bin2bn(string->data, len, bn);
#endif
return bn;
return bn;
}
void ssh_make_string_bn_inplace(ssh_string string,
UNUSED_PARAM(bignum bnout))
{
UNUSED_VAR(size_t len) = ssh_string_len(string);
#ifdef HAVE_LIBGCRYPT
/* XXX: FIXME as needed for LIBGCRYPT ECDSA codepaths. */
#elif defined HAVE_LIBCRYPTO
bignum_bin2bn(string->data, len, bnout);
#elif defined HAVE_LIBMBEDCRYPTO
bignum_bin2bn(string->data, len, bnout);
#endif
}
/* prints the bignum on stderr */
void ssh_print_bignum(const char *name, const_bignum num)
{
unsigned char *hex = NULL;
if (num != NULL) {
bignum_bn2hex(num, &hex);
}
fprintf(stderr, "%s value: %s\n", name, (hex == NULL) ? "(null)" : (char *) hex);
void ssh_print_bignum(const char *which, const bignum num) {
#ifdef HAVE_LIBGCRYPT
SAFE_FREE(hex);
unsigned char *hex = NULL;
bignum_bn2hex(num, &hex);
#elif defined HAVE_LIBCRYPTO
OPENSSL_free(hex);
char *hex = NULL;
hex = bignum_bn2hex(num);
#elif defined HAVE_LIBMBEDCRYPTO
SAFE_FREE(hex);
char *hex = NULL;
hex = bignum_bn2hex(num);
#endif
fprintf(stderr, "%s value: ", which);
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
#ifdef HAVE_LIBGCRYPT
SAFE_FREE(hex);
#elif defined HAVE_LIBCRYPTO
OPENSSL_free(hex);
#elif defined HAVE_LIBMBEDCRYPTO
SAFE_FREE(hex);
#endif
}

View File

@@ -38,7 +38,6 @@
#include "libssh/buffer.h"
#include "libssh/socket.h"
#include "libssh/session.h"
#include "libssh/token.h"
/**
* @addtogroup libssh_server
@@ -131,17 +130,18 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
}
ssh_bind ssh_bind_new(void) {
ssh_bind ptr;
ssh_bind ptr;
ptr = calloc(1, sizeof(struct ssh_bind_struct));
if (ptr == NULL) {
return NULL;
}
ptr->bindfd = SSH_INVALID_SOCKET;
ptr->bindport = 22;
ptr->common.log_verbosity = 0;
ptr = malloc(sizeof(struct ssh_bind_struct));
if (ptr == NULL) {
return NULL;
}
ZERO_STRUCTP(ptr);
ptr->bindfd = SSH_INVALID_SOCKET;
ptr->bindport= 22;
ptr->common.log_verbosity = 0;
return ptr;
return ptr;
}
static int ssh_bind_import_keys(ssh_bind sshbind) {
@@ -169,7 +169,7 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
return SSH_ERROR;
}
if (!is_ecdsa_key_type(ssh_key_type(sshbind->ecdsa))) {
if (ssh_key_type(sshbind->ecdsa) != SSH_KEYTYPE_ECDSA) {
ssh_set_error(sshbind, SSH_FATAL,
"The ECDSA host key has the wrong type");
ssh_key_free(sshbind->ecdsa);
@@ -343,24 +343,12 @@ static int ssh_bind_poll_callback(ssh_poll_handle sshpoll,
* @param sshbind the ssh_bind object
* @returns a ssh_poll handle suitable for operation
*/
ssh_poll_handle ssh_bind_get_poll(ssh_bind sshbind)
{
short events = POLLIN;
if (sshbind->poll) {
return sshbind->poll;
}
#ifdef POLLRDHUP
events |= POLLRDHUP;
#endif /* POLLRDHUP */
sshbind->poll = ssh_poll_new(sshbind->bindfd,
events,
ssh_bind_poll_callback,
sshbind);
ssh_poll_handle ssh_bind_get_poll(ssh_bind sshbind){
if(sshbind->poll)
return sshbind->poll;
sshbind->poll=ssh_poll_new(sshbind->bindfd,POLLIN,
ssh_bind_poll_callback,sshbind);
return sshbind->poll;
}
void ssh_bind_set_blocking(ssh_bind sshbind, int blocking) {
@@ -394,8 +382,6 @@ void ssh_bind_free(ssh_bind sshbind){
/* options */
SAFE_FREE(sshbind->banner);
SAFE_FREE(sshbind->bindaddr);
SAFE_FREE(sshbind->config_dir);
SAFE_FREE(sshbind->pubkey_accepted_key_types);
SAFE_FREE(sshbind->dsakey);
SAFE_FREE(sshbind->rsakey);
@@ -411,7 +397,7 @@ void ssh_bind_free(ssh_bind sshbind){
ssh_key_free(sshbind->ed25519);
sshbind->ed25519 = NULL;
for (i = 0; i < SSH_KEX_METHODS; i++) {
for (i = 0; i < 10; i++) {
if (sshbind->wanted_methods[i]) {
SAFE_FREE(sshbind->wanted_methods[i]);
}
@@ -423,26 +409,15 @@ void ssh_bind_free(ssh_bind sshbind){
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
int i, rc;
if (sshbind == NULL) {
return SSH_ERROR;
}
if (session == NULL){
ssh_set_error(sshbind, SSH_FATAL,"session is null");
return SSH_ERROR;
}
/* Apply global bind configurations, if it hasn't been applied before */
rc = ssh_bind_options_parse_config(sshbind, NULL);
if (rc != 0) {
ssh_set_error(sshbind, SSH_FATAL,"Could not parse global config");
return SSH_ERROR;
}
session->server = 1;
/* Copy options from bind to session */
for (i = 0; i < SSH_KEX_METHODS; i++) {
/* copy options */
for (i = 0; i < 10; i++) {
if (sshbind->wanted_methods[i]) {
session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
if (session->opts.wanted_methods[i] == NULL) {
@@ -461,29 +436,6 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
}
}
if (sshbind->pubkey_accepted_key_types != NULL) {
if (session->opts.pubkey_accepted_types == NULL) {
session->opts.pubkey_accepted_types = strdup(sshbind->pubkey_accepted_key_types);
if (session->opts.pubkey_accepted_types == NULL) {
ssh_set_error_oom(sshbind);
return SSH_ERROR;
}
} else {
char *p;
/* If something was set to the session prior to calling this
* function, keep only what is allowed by the options set in
* sshbind */
p = ssh_find_all_matching(sshbind->pubkey_accepted_key_types,
session->opts.pubkey_accepted_types);
if (p == NULL) {
return SSH_ERROR;
}
SAFE_FREE(session->opts.pubkey_accepted_types);
session->opts.pubkey_accepted_types = p;
}
}
session->common.log_verbosity = sshbind->common.log_verbosity;
if(sshbind->banner != NULL)
session->opts.custombanner = strdup(sshbind->banner);

View File

@@ -1,638 +0,0 @@
/*
* bind_config.c - Parse the SSH server configuration file
*
* This file is part of the SSH Library
*
* Copyright (c) 2019 by Red Hat, Inc.
*
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef HAVE_GLOB_H
# include <glob.h>
#endif
#include "libssh/bind.h"
#include "libssh/bind_config.h"
#include "libssh/config_parser.h"
#include "libssh/priv.h"
#include "libssh/server.h"
#include "libssh/options.h"
#define MAX_LINE_SIZE 1024
/* Flags used for the parser state */
#define PARSING 1
#define IN_MATCH (1<<1)
struct ssh_bind_config_keyword_table_s {
const char *name;
enum ssh_bind_config_opcode_e opcode;
bool allowed_in_match;
};
static struct ssh_bind_config_keyword_table_s
ssh_bind_config_keyword_table[] = {
{
.name = "include",
.opcode = BIND_CFG_INCLUDE
},
{
.name = "hostkey",
.opcode = BIND_CFG_HOSTKEY
},
{
.name = "listenaddress",
.opcode = BIND_CFG_LISTENADDRESS
},
{
.name = "port",
.opcode = BIND_CFG_PORT
},
{
.name = "loglevel",
.opcode = BIND_CFG_LOGLEVEL,
.allowed_in_match = true,
},
{
.name = "ciphers",
.opcode = BIND_CFG_CIPHERS
},
{
.name = "macs",
.opcode = BIND_CFG_MACS
},
{
.name = "kexalgorithms",
.opcode = BIND_CFG_KEXALGORITHMS
},
{
.name = "match",
.opcode = BIND_CFG_MATCH,
.allowed_in_match = true
},
{
.name = "pubkeyacceptedkeytypes",
.opcode = BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES,
.allowed_in_match = true
},
{
.name = "hostkeyalgorithms",
.opcode = BIND_CFG_HOSTKEY_ALGORITHMS,
.allowed_in_match = true
},
{
.opcode = BIND_CFG_UNKNOWN,
}
};
enum ssh_bind_config_match_e {
BIND_MATCH_UNKNOWN = -1,
BIND_MATCH_ALL,
BIND_MATCH_USER,
BIND_MATCH_GROUP,
BIND_MATCH_HOST,
BIND_MATCH_LOCALADDRESS,
BIND_MATCH_LOCALPORT,
BIND_MATCH_RDOMAIN,
BIND_MATCH_ADDRESS,
};
struct ssh_bind_config_match_keyword_table_s {
const char *name;
enum ssh_bind_config_match_e opcode;
};
static struct ssh_bind_config_match_keyword_table_s
ssh_bind_config_match_keyword_table[] = {
{
.name = "all",
.opcode = BIND_MATCH_ALL
},
{
.name = "user",
.opcode = BIND_MATCH_USER
},
{
.name = "group",
.opcode = BIND_MATCH_GROUP
},
{
.name = "host",
.opcode = BIND_MATCH_HOST
},
{
.name = "localaddress",
.opcode = BIND_MATCH_LOCALADDRESS
},
{
.name = "localport",
.opcode = BIND_MATCH_LOCALPORT
},
{
.name = "rdomain",
.opcode = BIND_MATCH_RDOMAIN
},
{
.name = "address",
.opcode = BIND_MATCH_ADDRESS
},
{
.opcode = BIND_MATCH_UNKNOWN
},
};
static enum ssh_bind_config_opcode_e
ssh_bind_config_get_opcode(char *keyword, uint32_t *parser_flags)
{
int i;
for (i = 0; ssh_bind_config_keyword_table[i].name != NULL; i++) {
if (strcasecmp(keyword, ssh_bind_config_keyword_table[i].name) == 0) {
if ((*parser_flags & IN_MATCH) &&
!(ssh_bind_config_keyword_table[i].allowed_in_match))
{
return BIND_CFG_NOT_ALLOWED_IN_MATCH;
}
return ssh_bind_config_keyword_table[i].opcode;
}
}
return BIND_CFG_UNKNOWN;
}
static int
ssh_bind_config_parse_line(ssh_bind bind,
const char *line,
unsigned int count,
uint32_t *parser_flags,
uint8_t *seen);
static void local_parse_file(ssh_bind bind,
const char *filename,
uint32_t *parser_flags,
uint8_t *seen)
{
FILE *f;
char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0;
int rv;
f = fopen(filename, "r");
if (f == NULL) {
SSH_LOG(SSH_LOG_RARE, "Cannot find file %s to load",
filename);
return;
}
SSH_LOG(SSH_LOG_PACKET, "Reading additional configuration data from %s",
filename);
while (fgets(line, sizeof(line), f)) {
count++;
rv = ssh_bind_config_parse_line(bind, line, count, parser_flags, seen);
if (rv < 0) {
fclose(f);
return;
}
}
fclose(f);
return;
}
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
static void local_parse_glob(ssh_bind bind,
const char *fileglob,
uint32_t *parser_flags,
uint8_t *seen)
{
glob_t globbuf = {
.gl_flags = 0,
};
int rt;
u_int i;
rt = glob(fileglob, GLOB_TILDE, NULL, &globbuf);
if (rt == GLOB_NOMATCH) {
globfree(&globbuf);
return;
} else if (rt != 0) {
SSH_LOG(SSH_LOG_RARE, "Glob error: %s",
fileglob);
globfree(&globbuf);
return;
}
for (i = 0; i < globbuf.gl_pathc; i++) {
local_parse_file(bind, globbuf.gl_pathv[i], parser_flags, seen);
}
globfree(&globbuf);
}
#endif /* HAVE_GLOB HAVE_GLOB_GL_FLAGS_MEMBER */
static enum ssh_bind_config_match_e
ssh_bind_config_get_match_opcode(const char *keyword)
{
size_t i;
for (i = 0; ssh_bind_config_match_keyword_table[i].name != NULL; i++) {
if (strcasecmp(keyword, ssh_bind_config_match_keyword_table[i].name) == 0) {
return ssh_bind_config_match_keyword_table[i].opcode;
}
}
return BIND_MATCH_UNKNOWN;
}
static int
ssh_bind_config_parse_line(ssh_bind bind,
const char *line,
unsigned int count,
uint32_t *parser_flags,
uint8_t *seen)
{
enum ssh_bind_config_opcode_e opcode;
const char *p = NULL;
char *s = NULL, *x = NULL;
char *keyword = NULL;
size_t len;
int rc = 0;
if (bind == NULL) {
return -1;
}
if ((line == NULL) || (parser_flags == NULL)) {
ssh_set_error_invalid(bind);
return -1;
}
x = s = strdup(line);
if (s == NULL) {
ssh_set_error_oom(bind);
return -1;
}
/* Remove trailing spaces */
for (len = strlen(s) - 1; len > 0; len--) {
if (! isspace(s[len])) {
break;
}
s[len] = '\0';
}
keyword = ssh_config_get_token(&s);
if (keyword == NULL || *keyword == '#' ||
*keyword == '\0' || *keyword == '\n') {
SAFE_FREE(x);
return 0;
}
opcode = ssh_bind_config_get_opcode(keyword, parser_flags);
if ((*parser_flags & PARSING) &&
opcode != BIND_CFG_HOSTKEY &&
opcode != BIND_CFG_INCLUDE &&
opcode != BIND_CFG_MATCH &&
opcode > BIND_CFG_UNSUPPORTED) { /* Ignore all unknown types here */
/* Skip all the options that were already applied */
if (seen[opcode] != 0) {
SAFE_FREE(x);
return 0;
}
seen[opcode] = 1;
}
switch (opcode) {
case BIND_CFG_INCLUDE:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
local_parse_glob(bind, p, parser_flags, seen);
#else
local_parse_file(bind, p, parser_flags, seen);
#endif /* HAVE_GLOB */
}
break;
case BIND_CFG_HOSTKEY:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HOSTKEY, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set Hostkey value '%s'",
count, p);
}
}
break;
case BIND_CFG_LISTENADDRESS:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDADDR, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set ListenAddress value '%s'",
count, p);
}
}
break;
case BIND_CFG_PORT:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDPORT_STR, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set Port value '%s'",
count, p);
}
}
break;
case BIND_CFG_CIPHERS:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_C_S, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set C->S Ciphers value '%s'",
count, p);
break;
}
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_S_C, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set S->C Ciphers value '%s'",
count, p);
}
}
break;
case BIND_CFG_MACS:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_C_S, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set C->S MAC value '%s'",
count, p);
break;
}
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_S_C, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set S->C MAC value '%s'",
count, p);
}
}
break;
case BIND_CFG_LOGLEVEL:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
int value = -1;
if (strcasecmp(p, "quiet") == 0) {
value = SSH_LOG_NONE;
} else if (strcasecmp(p, "fatal") == 0 ||
strcasecmp(p, "error")== 0 ||
strcasecmp(p, "info") == 0) {
value = SSH_LOG_WARN;
} else if (strcasecmp(p, "verbose") == 0) {
value = SSH_LOG_INFO;
} else if (strcasecmp(p, "DEBUG") == 0 ||
strcasecmp(p, "DEBUG1") == 0) {
value = SSH_LOG_DEBUG;
} else if (strcasecmp(p, "DEBUG2") == 0 ||
strcasecmp(p, "DEBUG3") == 0) {
value = SSH_LOG_TRACE;
}
if (value != -1) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY,
&value);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set LogLevel value '%s'",
count, p);
}
}
}
break;
case BIND_CFG_KEXALGORITHMS:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_KEY_EXCHANGE, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set KexAlgorithms value '%s'",
count, p);
}
}
break;
case BIND_CFG_MATCH: {
bool negate;
int result = PARSING;
size_t args = 0;
enum ssh_bind_config_match_e opt;
const char *p2 = NULL;
/* The options set in Match blocks should be applied when a connection
* is accepted, and not right away when parsing the file (as it is
* currently done). This means the configuration files should be parsed
* again or the options set in the Match blocks should be stored and
* applied as necessary. */
/* If this is the first Match block, erase the seen table to allow
* options to be overridden. Erasing the seen table was the easiest way
* to allow overriding an option, but only for the first occurrence of
* an option in a Match block. This is sufficient for the current
* implementation which supports only the 'All' criterion, meaning the
* options can be applied right away. */
if (!(*parser_flags & IN_MATCH)) {
memset(seen, 0x00, BIND_CFG_MAX * sizeof(uint8_t));
}
/* In this line the PARSING bit is cleared from the flags */
*parser_flags = IN_MATCH;
do {
p = p2 = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') {
break;
}
args++;
SSH_LOG(SSH_LOG_TRACE, "line %d: Processing Match keyword '%s'",
count, p);
/* If the option is prefixed with ! the result should be negated */
negate = false;
if (p[0] == '!') {
negate = true;
p++;
}
opt = ssh_bind_config_get_match_opcode(p);
switch (opt) {
case BIND_MATCH_ALL:
p = ssh_config_get_str_tok(&s, NULL);
if ((args == 1) && (p == NULL || p[0] == '\0')) {
/* The "all" keyword does not accept arguments or modifiers
*/
if (negate == true) {
result = 0;
}
break;
}
ssh_set_error(bind, SSH_FATAL,
"line %d: ERROR - Match all cannot be combined with "
"other Match attributes", count);
SAFE_FREE(x);
return -1;
case BIND_MATCH_USER:
case BIND_MATCH_GROUP:
case BIND_MATCH_HOST:
case BIND_MATCH_LOCALADDRESS:
case BIND_MATCH_LOCALPORT:
case BIND_MATCH_RDOMAIN:
case BIND_MATCH_ADDRESS:
/* Only "All" is supported for now */
/* Skip one argument */
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') {
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
"'%s' requires argument\n", count, p2);
SAFE_FREE(x);
return -1;
}
args++;
SSH_LOG(SSH_LOG_WARN,
"line %d: Unsupported Match keyword '%s', ignoring\n",
count,
p2);
result = 0;
break;
case BIND_MATCH_UNKNOWN:
default:
ssh_set_error(bind, SSH_FATAL,
"ERROR - Unknown argument '%s' for Match keyword", p);
SAFE_FREE(x);
return -1;
}
} while (p != NULL && p[0] != '\0');
if (args == 0) {
ssh_set_error(bind, SSH_FATAL,
"ERROR - Match keyword requires an argument");
SAFE_FREE(x);
return -1;
}
/* This line only sets the PARSING flag if all checks passed */
*parser_flags |= result;
break;
}
case BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind,
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set PubKeyAcceptedKeyTypes value '%s'",
count, p);
}
}
break;
case BIND_CFG_HOSTKEY_ALGORITHMS:
p = ssh_config_get_str_tok(&s, NULL);
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind,
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set HostkeyAlgorithms value '%s'",
count, p);
}
}
break;
case BIND_CFG_NOT_ALLOWED_IN_MATCH:
SSH_LOG(SSH_LOG_WARN, "Option not allowed in Match block: %s, line: %d",
keyword, count);
break;
case BIND_CFG_UNKNOWN:
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d",
keyword, count);
break;
case BIND_CFG_UNSUPPORTED:
SSH_LOG(SSH_LOG_WARN, "Unsupported option: %s, line: %d",
keyword, count);
break;
case BIND_CFG_NA:
SSH_LOG(SSH_LOG_WARN, "Option not applicable: %s, line: %d",
keyword, count);
break;
default:
ssh_set_error(bind, SSH_FATAL, "ERROR - unimplemented opcode: %d",
opcode);
SAFE_FREE(x);
return -1;
break;
}
SAFE_FREE(x);
return rc;
}
int ssh_bind_config_parse_file(ssh_bind bind, const char *filename)
{
char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0;
FILE *f;
uint32_t parser_flags;
int rv;
/* This local table is used during the parsing of the current file (and
* files included recursively in this file) to prevent an option to be
* redefined, i.e. the first value set is kept. But this DO NOT prevent the
* option to be redefined later by another file. */
uint8_t seen[BIND_CFG_MAX] = {0};
f = fopen(filename, "r");
if (f == NULL) {
return 0;
}
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
parser_flags = PARSING;
while (fgets(line, sizeof(line), f)) {
count++;
rv = ssh_bind_config_parse_line(bind, line, count, &parser_flags, seen);
if (rv) {
fclose(f);
return -1;
}
}
fclose(f);
return 0;
}

View File

@@ -1015,7 +1015,7 @@ int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
}
if (rc != SSH_ERROR){
/* Check if our canary is intact, if not something really bad happened */
/* Check if our canary is intact, if not somthing really bad happened */
uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END) {
abort();
@@ -1082,11 +1082,11 @@ int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
*/
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
int argc,
va_list ap)
{
int rc = SSH_ERROR;
const char *p = format, *last;
const char *p, *last;
union {
uint8_t *byte;
uint16_t *word;
@@ -1094,32 +1094,24 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
uint64_t *qword;
ssh_string *string;
char **cstring;
bignum *bignum;
void **data;
} o;
size_t len, rlen, max_len;
ssh_string tmp_string = NULL;
va_list ap_copy;
size_t count;
int count; /* int for size comparison with argc */
max_len = ssh_buffer_get_len(buffer);
/* copy the argument list in case a rollback is needed */
va_copy(ap_copy, ap);
if (argc > 256) {
rc = SSH_ERROR;
goto cleanup;
}
for (count = 0; *p != '\0'; p++, count++) {
for (p = format, count = 0; *p != '\0'; p++, count++) {
/* Invalid number of arguments passed */
if (count > argc) {
if (argc != -1 && count > argc) {
rc = SSH_ERROR;
goto cleanup;
}
rc = SSH_ERROR;
switch (*p) {
case 'b':
o.byte = va_arg(ap, uint8_t *);
@@ -1129,38 +1121,20 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
case 'w':
o.word = va_arg(ap, uint16_t *);
rlen = ssh_buffer_get_data(buffer, o.word, sizeof(uint16_t));
if (rlen == 2) {
*o.word = ntohs(*o.word);
rc = SSH_OK;
}
*o.word = ntohs(*o.word);
rc = rlen==2 ? SSH_OK : SSH_ERROR;
break;
case 'd':
o.dword = va_arg(ap, uint32_t *);
rlen = ssh_buffer_get_u32(buffer, o.dword);
if (rlen == 4) {
*o.dword = ntohl(*o.dword);
rc = SSH_OK;
}
*o.dword = ntohl(*o.dword);
rc = rlen==4 ? SSH_OK : SSH_ERROR;
break;
case 'q':
o.qword = va_arg(ap, uint64_t*);
rlen = ssh_buffer_get_u64(buffer, o.qword);
if (rlen == 8) {
*o.qword = ntohll(*o.qword);
rc = SSH_OK;
}
break;
case 'B':
o.bignum = va_arg(ap, bignum *);
*o.bignum = NULL;
tmp_string = ssh_buffer_get_ssh_string(buffer);
if (tmp_string == NULL) {
break;
}
*o.bignum = ssh_make_string_bn(tmp_string);
ssh_string_burn(tmp_string);
SSH_STRING_FREE(tmp_string);
rc = (*o.bignum != NULL) ? SSH_OK : SSH_ERROR;
*o.qword = ntohll(*o.qword);
rc = rlen==8 ? SSH_OK : SSH_ERROR;
break;
case 'S':
o.string = va_arg(ap, ssh_string *);
@@ -1173,12 +1147,14 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
o.cstring = va_arg(ap, char **);
*o.cstring = NULL;
rlen = ssh_buffer_get_u32(buffer, &u32len);
if (rlen != 4){
rc = ssh_buffer_get_u32(buffer, &u32len);
if (rc != 4){
rc = SSH_ERROR;
break;
}
len = ntohl(u32len);
if (len > max_len - 1) {
rc = SSH_ERROR;
break;
}
@@ -1234,13 +1210,14 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
break;
default:
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
rc = SSH_ERROR;
}
if (rc != SSH_OK) {
break;
}
}
if (argc != count) {
if (argc != -1 && argc != count) {
rc = SSH_ERROR;
}
@@ -1249,7 +1226,11 @@ cleanup:
/* Check if our canary is intact, if not something really bad happened */
uint32_t canary = va_arg(ap, uint32_t);
if (canary != SSH_BUFFER_PACK_END){
abort();
if (argc == -1){
rc = SSH_ERROR;
} else {
abort();
}
}
}
@@ -1286,10 +1267,6 @@ cleanup:
break;
}
break;
case 'B':
o.bignum = va_arg(ap_copy, bignum *);
bignum_safe_free(*o.bignum);
break;
case 'S':
o.string = va_arg(ap_copy, ssh_string *);
if (buffer->secure) {
@@ -1336,7 +1313,6 @@ cleanup:
* 's': char ** (C string, pulled as SSH string)
* 'P': size_t, void ** (len of data, pointer to data)
* only pulls data.
* 'B': bignum * (pulled as SSH string)
* @returns SSH_OK on success
* SSH_ERROR on error
* @warning when using 'P' with a constant size (e.g. 8), do not
@@ -1344,7 +1320,7 @@ cleanup:
*/
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
int argc,
...)
{
va_list ap;

View File

@@ -109,11 +109,11 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
out_packet->payload,
len - sizeof(uint32_t));
/* ssh_log_hexdump("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
/* ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
/* step 4, compute the MAC */
poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx);
/* ssh_log_hexdump("poly1305 src", (uint8_t *)out_packet, len);
ssh_log_hexdump("poly1305 tag", tag, POLY1305_TAGLEN); */
/* ssh_print_hexa("poly1305 src", (uint8_t *)out_packet, len);
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN); */
}
static int chacha20_poly1305_aead_decrypt_length(
@@ -159,17 +159,17 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
poly1305_ctx,
POLY1305_KEYLEN);
#if 0
ssh_log_hexdump("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
#endif
poly1305_auth(tag, (uint8_t *)complete_packet, encrypted_size +
sizeof(uint32_t), poly1305_ctx);
#if 0
ssh_log_hexdump("poly1305 src",
ssh_print_hexa("poly1305 src",
(uint8_t*)complete_packet,
encrypted_size + 4);
ssh_log_hexdump("poly1305 tag", tag, POLY1305_TAGLEN);
ssh_log_hexdump("received tag", mac, POLY1305_TAGLEN);
ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN);
ssh_print_hexa("received tag", mac, POLY1305_TAGLEN);
#endif
cmp = memcmp(tag, mac, POLY1305_TAGLEN);

View File

@@ -28,7 +28,6 @@
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <stdbool.h>
#ifndef _WIN32
#include <netinet/in.h>
@@ -85,11 +84,6 @@ ssh_channel ssh_channel_new(ssh_session session)
return NULL;
}
/* Check if we have an authenticated session */
if (!(session->flags & SSH_SESSION_FLAG_AUTHENTICATED)) {
return NULL;
}
channel = calloc(1, sizeof(struct ssh_channel_struct));
if (channel == NULL) {
ssh_set_error_oom(session);
@@ -106,7 +100,7 @@ ssh_channel ssh_channel_new(ssh_session session)
channel->stderr_buffer = ssh_buffer_new();
if (channel->stderr_buffer == NULL) {
ssh_set_error_oom(session);
SSH_BUFFER_FREE(channel->stdout_buffer);
ssh_buffer_free(channel->stdout_buffer);
SAFE_FREE(channel);
return NULL;
}
@@ -121,10 +115,6 @@ ssh_channel ssh_channel_new(ssh_session session)
ssh_list_prepend(session->channels, channel);
/* Set states explicitly */
channel->state = SSH_CHANNEL_STATE_NOT_OPEN;
channel->request_state = SSH_CHANNEL_REQ_STATE_NONE;
return channel;
}
@@ -163,8 +153,8 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
channel=ssh_channel_from_local(session,channelid);
if(channel==NULL){
ssh_set_error(session, SSH_FATAL,
"Unknown channel id %"PRIu32,
(uint32_t) channelid);
"Unknown channel id %lu",
(long unsigned int) channelid);
/* TODO: Set error marking in channel object */
return SSH_PACKET_USED;
@@ -191,9 +181,9 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
}
SSH_LOG(SSH_LOG_PROTOCOL,
"Remote window : %"PRIu32", maxpacket : %"PRIu32,
(uint32_t) channel->remote_window,
(uint32_t) channel->remote_maxpacket);
"Remote window : %lu, maxpacket : %lu",
(long unsigned int) channel->remote_window,
(long unsigned int) channel->remote_maxpacket);
channel->state = SSH_CHANNEL_STATE_OPEN;
channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND;
@@ -239,9 +229,9 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
}
ssh_set_error(session, SSH_REQUEST_DENIED,
"Channel opening failure: channel %u error (%"PRIu32") %s",
"Channel opening failure: channel %u error (%lu) %s",
channel->local_channel,
(uint32_t) code,
(long unsigned int) code,
error);
SAFE_FREE(error);
channel->state=SSH_CHANNEL_STATE_OPEN_DENIED;
@@ -278,92 +268,75 @@ static int ssh_channel_open_termination(void *c){
* @param[in] maxpacket The maximum packet size allowed (like MTU).
*
* @param[in] payload The buffer containing additional payload for the query.
*
* @return SSH_OK if successful; SSH_ERROR otherwise.
*/
static int
channel_open(ssh_channel channel,
const char *type,
uint32_t window,
uint32_t maxpacket,
ssh_buffer payload)
{
ssh_session session = channel->session;
int err = SSH_ERROR;
int rc;
static int channel_open(ssh_channel channel, const char *type, int window,
int maxpacket, ssh_buffer payload) {
ssh_session session = channel->session;
int err=SSH_ERROR;
int rc;
switch (channel->state) {
case SSH_CHANNEL_STATE_NOT_OPEN:
break;
case SSH_CHANNEL_STATE_OPENING:
goto pending;
case SSH_CHANNEL_STATE_OPEN:
case SSH_CHANNEL_STATE_CLOSED:
case SSH_CHANNEL_STATE_OPEN_DENIED:
goto end;
default:
ssh_set_error(session, SSH_FATAL, "Bad state in channel_open: %d",
channel->state);
}
channel->local_channel = ssh_channel_new_id(session);
channel->local_maxpacket = maxpacket;
channel->local_window = window;
SSH_LOG(SSH_LOG_PROTOCOL,
"Creating a channel %d with %d window and %d max packet",
channel->local_channel, window, maxpacket);
rc = ssh_buffer_pack(session->out_buffer,
"bsddd",
SSH2_MSG_CHANNEL_OPEN,
type,
channel->local_channel,
channel->local_window,
channel->local_maxpacket);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
return err;
}
if (payload != NULL) {
if (ssh_buffer_add_buffer(session->out_buffer, payload) < 0) {
ssh_set_error_oom(session);
return err;
}
}
channel->state = SSH_CHANNEL_STATE_OPENING;
if (ssh_packet_send(session) == SSH_ERROR) {
return err;
}
SSH_LOG(SSH_LOG_PACKET,
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
type, channel->local_channel);
pending:
/* wait until channel is opened by server */
err = ssh_handle_packets_termination(session,
SSH_TIMEOUT_DEFAULT,
ssh_channel_open_termination,
channel);
if (session->session_state == SSH_SESSION_STATE_ERROR) {
err = SSH_ERROR;
}
end:
/* This needs to pass the SSH_AGAIN from the above,
* but needs to catch failed channel states */
if (channel->state == SSH_CHANNEL_STATE_OPEN) {
err = SSH_OK;
} else if (err != SSH_AGAIN) {
/* Messages were handled correctly, but he channel state is invalid */
err = SSH_ERROR;
switch(channel->state){
case SSH_CHANNEL_STATE_NOT_OPEN:
break;
case SSH_CHANNEL_STATE_OPENING:
goto pending;
case SSH_CHANNEL_STATE_OPEN:
case SSH_CHANNEL_STATE_CLOSED:
case SSH_CHANNEL_STATE_OPEN_DENIED:
goto end;
default:
ssh_set_error(session,SSH_FATAL,"Bad state in channel_open: %d",channel->state);
}
channel->local_channel = ssh_channel_new_id(session);
channel->local_maxpacket = maxpacket;
channel->local_window = window;
SSH_LOG(SSH_LOG_PROTOCOL,
"Creating a channel %d with %d window and %d max packet",
channel->local_channel, window, maxpacket);
rc = ssh_buffer_pack(session->out_buffer,
"bsddd",
SSH2_MSG_CHANNEL_OPEN,
type,
channel->local_channel,
channel->local_window,
channel->local_maxpacket);
if (rc != SSH_OK){
ssh_set_error_oom(session);
return err;
}
if (payload != NULL) {
if (ssh_buffer_add_buffer(session->out_buffer, payload) < 0) {
ssh_set_error_oom(session);
return err;
}
}
channel->state = SSH_CHANNEL_STATE_OPENING;
if (ssh_packet_send(session) == SSH_ERROR) {
return err;
}
SSH_LOG(SSH_LOG_PACKET,
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
type, channel->local_channel);
pending:
/* wait until channel is opened by server */
err = ssh_handle_packets_termination(session,
SSH_TIMEOUT_DEFAULT,
ssh_channel_open_termination,
channel);
if (session->session_state == SSH_SESSION_STATE_ERROR)
err = SSH_ERROR;
end:
if(channel->state == SSH_CHANNEL_STATE_OPEN)
err=SSH_OK;
return err;
}
/* return channel with corresponding local id, or NULL if not found */
@@ -390,12 +363,8 @@ ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) {
* @param session SSH session
* @param channel SSH channel
* @param minimumsize The minimum acceptable size for the new window.
* @return SSH_OK if successful; SSH_ERROR otherwise.
*/
static int grow_window(ssh_session session,
ssh_channel channel,
uint32_t minimumsize)
{
static int grow_window(ssh_session session, ssh_channel channel, int minimumsize) {
uint32_t new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE;
int rc;
@@ -449,7 +418,7 @@ error:
* @param[in] packet The buffer to parse packet from. The read pointer will
* be moved after the call.
*
* @return The related ssh_channel, or NULL if the channel is
* @returns The related ssh_channel, or NULL if the channel is
* unknown or the packet is invalid.
*/
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
@@ -467,8 +436,8 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
channel = ssh_channel_from_local(session, chan);
if (channel == NULL) {
ssh_set_error(session, SSH_FATAL,
"Server specified invalid channel %"PRIu32,
(uint32_t) chan);
"Server specified invalid channel %lu",
(long unsigned int) chan);
}
return channel;
@@ -560,7 +529,7 @@ SSH_PACKET_CALLBACK(channel_rcv_data){
if (channel_default_bufferize(channel, ssh_string_data(str), len,
is_stderr) < 0) {
SSH_STRING_FREE(str);
ssh_string_free(str);
return SSH_PACKET_USED;
}
@@ -576,7 +545,7 @@ SSH_PACKET_CALLBACK(channel_rcv_data){
channel->local_window,
channel->remote_window);
SSH_STRING_FREE(str);
ssh_string_free(str);
if (is_stderr) {
buf = channel->stderr_buffer;
@@ -844,10 +813,8 @@ SSH_PACKET_CALLBACK(channel_rcv_request) {
*
* FIXME is the window changed?
*/
int channel_default_bufferize(ssh_channel channel,
void *data, size_t len,
bool is_stderr)
{
int channel_default_bufferize(ssh_channel channel, void *data, int len,
int is_stderr) {
ssh_session session;
if(channel == NULL) {
@@ -862,10 +829,8 @@ int channel_default_bufferize(ssh_channel channel,
}
SSH_LOG(SSH_LOG_PACKET,
"placing %zu bytes into channel buffer (%s)",
len,
is_stderr ? "stderr" : "stdout");
if (!is_stderr) {
"placing %d bytes into channel buffer (stderr=%d)", len, is_stderr);
if (is_stderr == 0) {
/* stdout */
if (channel->stdout_buffer == NULL) {
channel->stdout_buffer = ssh_buffer_new();
@@ -877,7 +842,7 @@ int channel_default_bufferize(ssh_channel channel,
if (ssh_buffer_add_data(channel->stdout_buffer, data, len) < 0) {
ssh_set_error_oom(session);
SSH_BUFFER_FREE(channel->stdout_buffer);
ssh_buffer_free(channel->stdout_buffer);
channel->stdout_buffer = NULL;
return -1;
}
@@ -893,7 +858,7 @@ int channel_default_bufferize(ssh_channel channel,
if (ssh_buffer_add_data(channel->stderr_buffer, data, len) < 0) {
ssh_set_error_oom(session);
SSH_BUFFER_FREE(channel->stderr_buffer);
ssh_buffer_free(channel->stderr_buffer);
channel->stderr_buffer = NULL;
return -1;
}
@@ -1024,94 +989,12 @@ int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
payload);
error:
SSH_BUFFER_FREE(payload);
SSH_STRING_FREE(str);
ssh_buffer_free(payload);
ssh_string_free(str);
return rc;
}
/**
* @brief Open a TCP/IP - UNIX domain socket forwarding channel.
*
* @param[in] channel An allocated channel.
*
* @param[in] remotepath The UNIX socket path on the remote machine
*
* @param[in] sourcehost The numeric IP address of the machine from where the
* connection request originates. This is mostly for
* logging purposes.
*
* @param[in] localport The port on the host from where the connection
* originated. This is mostly for logging purposes.
*
* @return SSH_OK on success,
* SSH_ERROR if an error occurred,
* SSH_AGAIN if in nonblocking mode and call has
* to be done again.
*
* @warning This function does not bind the local port and does not
* automatically forward the content of a socket to the channel.
* You still have to use channel_read and channel_write for this.
* @warning Requires support of OpenSSH for UNIX domain socket forwarding.
*/
int ssh_channel_open_forward_unix(ssh_channel channel,
const char *remotepath,
const char *sourcehost,
int localport)
{
ssh_session session = NULL;
ssh_buffer payload = NULL;
ssh_string str = NULL;
int rc = SSH_ERROR;
int version;
if (channel == NULL) {
return rc;
}
session = channel->session;
version = ssh_get_openssh_version(session);
if (version == 0) {
ssh_set_error(session,
SSH_REQUEST_DENIED,
"We're not connected to an OpenSSH server!");
return SSH_ERROR;
}
if (remotepath == NULL || sourcehost == NULL) {
ssh_set_error_invalid(session);
return rc;
}
payload = ssh_buffer_new();
if (payload == NULL) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_buffer_pack(payload,
"ssd",
remotepath,
sourcehost,
localport);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
}
rc = channel_open(channel,
"direct-streamlocal@openssh.com",
CHANNEL_INITIAL_WINDOW,
CHANNEL_MAX_PACKET,
payload);
error:
SSH_BUFFER_FREE(payload);
SSH_STRING_FREE(str);
return rc;
}
/**
* @brief Close and free a channel.
@@ -1120,50 +1003,28 @@ error:
*
* @warning Any data unread on this channel will be lost.
*/
void ssh_channel_free(ssh_channel channel)
{
ssh_session session;
void ssh_channel_free(ssh_channel channel) {
ssh_session session;
if (channel == NULL) {
return;
}
if (channel == NULL) {
return;
}
session = channel->session;
if (session->alive) {
bool send_close = false;
session = channel->session;
if (session->alive && channel->state == SSH_CHANNEL_STATE_OPEN) {
ssh_channel_close(channel);
}
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
switch (channel->state) {
case SSH_CHANNEL_STATE_OPEN:
send_close = true;
break;
case SSH_CHANNEL_STATE_CLOSED:
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) {
send_close = true;
}
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
send_close = false;
}
break;
default:
send_close = false;
break;
}
if (send_close) {
ssh_channel_close(channel);
}
}
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
/* The idea behind the flags is the following : it is well possible
* that a client closes a channel that stills exists on the server side.
* We definitively close the channel when we receive a close message *and*
* the user closed it.
*/
if ((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) ||
(channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)) {
ssh_channel_do_free(channel);
}
/* The idea behind the flags is the following : it is well possible
* that a client closes a channel that stills exists on the server side.
* We definitively close the channel when we receive a close message *and*
* the user closed it.
*/
if((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE)
|| (channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)){
ssh_channel_do_free(channel);
}
}
/**
@@ -1181,15 +1042,13 @@ void ssh_channel_do_free(ssh_channel channel)
ssh_list_remove(session->channels, it);
}
SSH_BUFFER_FREE(channel->stdout_buffer);
SSH_BUFFER_FREE(channel->stderr_buffer);
ssh_buffer_free(channel->stdout_buffer);
ssh_buffer_free(channel->stderr_buffer);
if (channel->callbacks != NULL) {
ssh_list_free(channel->callbacks);
channel->callbacks = NULL;
}
channel->session = NULL;
SAFE_FREE(channel);
}
@@ -1227,15 +1086,10 @@ int ssh_channel_send_eof(ssh_channel channel)
int rc = SSH_ERROR;
int err;
if (channel == NULL || channel->session == NULL) {
if(channel == NULL) {
return rc;
}
/* If the EOF has already been sent we're done here. */
if (channel->local_eof != 0) {
return SSH_OK;
}
session = channel->session;
err = ssh_buffer_pack(session->out_buffer,
@@ -1282,57 +1136,52 @@ error:
* @see ssh_channel_free()
* @see ssh_channel_is_eof()
*/
int ssh_channel_close(ssh_channel channel)
{
ssh_session session;
int rc = 0;
int ssh_channel_close(ssh_channel channel){
ssh_session session;
int rc = 0;
if(channel == NULL) {
return SSH_ERROR;
}
if(channel == NULL) {
return SSH_ERROR;
}
/* If the channel close has already been sent we're done here. */
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
return SSH_OK;
}
session = channel->session;
session = channel->session;
if (channel->local_eof == 0) {
rc = ssh_channel_send_eof(channel);
if (rc != SSH_OK) {
return rc;
}
rc = ssh_buffer_pack(session->out_buffer,
"bd",
SSH2_MSG_CHANNEL_CLOSE,
channel->remote_channel);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET,
"Sent a close on client channel (%d:%d)",
channel->local_channel,
channel->remote_channel);
if (rc == SSH_OK) {
channel->state = SSH_CHANNEL_STATE_CLOSED;
channel->flags |= SSH_CHANNEL_FLAG_CLOSED_LOCAL;
}
rc = ssh_channel_flush(channel);
if(rc == SSH_ERROR) {
goto error;
}
}
if (rc != SSH_OK) {
return rc;
}
rc = ssh_buffer_pack(session->out_buffer,
"bd",
SSH2_MSG_CHANNEL_CLOSE,
channel->remote_channel);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET,
"Sent a close on client channel (%d:%d)",
channel->local_channel,
channel->remote_channel);
if(rc == SSH_OK) {
channel->state=SSH_CHANNEL_STATE_CLOSED;
}
rc = ssh_channel_flush(channel);
if(rc == SSH_ERROR)
goto error;
return rc;
error:
ssh_buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return rc;
return rc;
}
/* this termination function waits for a window growing condition */
@@ -1365,9 +1214,9 @@ static int ssh_waitsession_unblocked(void *s){
* @brief Flushes a channel (and its session) until the output buffer
* is empty, or timeout elapsed.
* @param channel SSH channel
* @return SSH_OK On success,
* SSH_ERROR On error.
* SSH_AGAIN Timeout elapsed (or in nonblocking mode).
* @returns SSH_OK On success,
* SSH_ERROR on error
* SSH_AGAIN Timeout elapsed (or in nonblocking mode)
*/
int ssh_channel_flush(ssh_channel channel){
return ssh_blocking_flush(channel->session, SSH_TIMEOUT_DEFAULT);
@@ -1841,7 +1690,7 @@ int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal,
pending:
rc = channel_request(channel, "pty-req", buffer, 1);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -1901,7 +1750,7 @@ int ssh_channel_change_pty_size(ssh_channel channel, int cols, int rows) {
rc = channel_request(channel, "window-change", buffer, 0);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -1970,23 +1819,11 @@ int ssh_channel_request_subsystem(ssh_channel channel, const char *subsys) {
pending:
rc = channel_request(channel, "subsystem", buffer, 1);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
/**
* @brief Request sftp subsystem on the channel
*
* @param[in] channel The channel to request the sftp subsystem.
*
* @return SSH_OK on success,
* SSH_ERROR if an error occurred,
* SSH_AGAIN if in nonblocking mode and call has
* to be done again.
*
* @note You should use sftp_new() which does this for you.
*/
int ssh_channel_request_sftp( ssh_channel channel){
if(channel == NULL) {
return SSH_ERROR;
@@ -2086,7 +1923,7 @@ pending:
rc = channel_request(channel, "x11-req", buffer, 1);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2399,7 +2236,7 @@ pending:
}
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2471,7 +2308,7 @@ pending:
rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2529,7 +2366,7 @@ int ssh_channel_request_env(ssh_channel channel, const char *name, const char *v
pending:
rc = channel_request(channel, "env", buffer,1);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2551,12 +2388,12 @@ error:
*
* Example:
@code
rc = ssh_channel_request_exec(channel, "ps aux");
rc = channel_request_exec(channel, "ps aux");
if (rc > 0) {
return -1;
}
while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
while ((rc = channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
if (fwrite(buffer, 1, rc, stdout) != (unsigned int) rc) {
return -1;
}
@@ -2598,7 +2435,7 @@ int ssh_channel_request_exec(ssh_channel channel, const char *cmd) {
pending:
rc = channel_request(channel, "exec", buffer, 1);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2661,7 +2498,7 @@ int ssh_channel_request_send_signal(ssh_channel channel, const char *sig) {
rc = channel_request(channel, "signal", buffer, 0);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2704,7 +2541,7 @@ int ssh_channel_request_send_break(ssh_channel channel, uint32_t length) {
rc = channel_request(channel, "break", buffer, 0);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -2980,45 +2817,42 @@ int ssh_channel_read_timeout(ssh_channel channel,
*
* @see ssh_channel_is_eof()
*/
int ssh_channel_read_nonblocking(ssh_channel channel,
void *dest,
uint32_t count,
int is_stderr)
{
ssh_session session;
ssize_t to_read;
int rc;
int blocking;
int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
int is_stderr) {
ssh_session session;
int to_read;
int rc;
int blocking;
if(channel == NULL) {
return SSH_ERROR;
}
if(dest == NULL) {
ssh_set_error_invalid(channel->session);
return SSH_ERROR;
}
if(channel == NULL) {
return SSH_ERROR;
}
if(dest == NULL) {
ssh_set_error_invalid(channel->session);
return SSH_ERROR;
}
session = channel->session;
session = channel->session;
to_read = ssh_channel_poll(channel, is_stderr);
to_read = ssh_channel_poll(channel, is_stderr);
if (to_read <= 0) {
if (session->session_state == SSH_SESSION_STATE_ERROR){
return SSH_ERROR;
}
if (to_read <= 0) {
if (session->session_state == SSH_SESSION_STATE_ERROR){
return SSH_ERROR;
}
return to_read; /* may be an error code */
}
return to_read; /* may be an error code */
}
if ((size_t)to_read > count) {
to_read = (ssize_t)count;
}
blocking = ssh_is_blocking(session);
ssh_set_blocking(session, 0);
rc = ssh_channel_read(channel, dest, (uint32_t)to_read, is_stderr);
ssh_set_blocking(session,blocking);
if (to_read > (int)count) {
to_read = (int)count;
}
blocking = ssh_is_blocking(session);
ssh_set_blocking(session, 0);
rc = ssh_channel_read(channel, dest, to_read, is_stderr);
ssh_set_blocking(session,blocking);
return rc;
return rc;
}
/**
@@ -3087,51 +2921,38 @@ int ssh_channel_poll(ssh_channel channel, int is_stderr){
*
* @see ssh_channel_is_eof()
*/
int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr)
{
ssh_session session;
ssh_buffer stdbuf;
struct ssh_channel_read_termination_struct ctx;
size_t len;
int rc;
int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr){
ssh_session session;
ssh_buffer stdbuf;
struct ssh_channel_read_termination_struct ctx;
int rc;
if(channel == NULL) {
return SSH_ERROR;
}
if(channel == NULL) {
return SSH_ERROR;
}
session = channel->session;
stdbuf = channel->stdout_buffer;
session = channel->session;
stdbuf = channel->stdout_buffer;
if (is_stderr) {
stdbuf = channel->stderr_buffer;
}
ctx.buffer = stdbuf;
ctx.channel = channel;
ctx.count = 1;
rc = ssh_handle_packets_termination(channel->session,
timeout,
ssh_channel_read_termination,
&ctx);
if (rc == SSH_ERROR ||
session->session_state == SSH_SESSION_STATE_ERROR) {
rc = SSH_ERROR;
goto out;
}
len = ssh_buffer_get_len(stdbuf);
if (len > 0) {
if (len > INT_MAX) {
rc = SSH_ERROR;
} else {
rc = (int)len;
}
goto out;
}
if (channel->remote_eof) {
rc = SSH_EOF;
}
out:
return rc;
if (is_stderr) {
stdbuf = channel->stderr_buffer;
}
ctx.buffer = stdbuf;
ctx.channel = channel;
ctx.count = 1;
rc = ssh_handle_packets_termination(channel->session, timeout,
ssh_channel_read_termination, &ctx);
if(rc ==SSH_ERROR || session->session_state == SSH_SESSION_STATE_ERROR){
rc = SSH_ERROR;
goto end;
}
rc = ssh_buffer_get_len(stdbuf);
if(rc > 0)
goto end;
if (channel->remote_eof)
rc = SSH_EOF;
end:
return rc;
}
/**
@@ -3167,8 +2988,8 @@ static int ssh_channel_exit_status_termination(void *c){
*
* @param[in] channel The channel to get the status from.
*
* @return The exit status, -1 if no exit status has been returned
* (yet), or SSH_ERROR on error.
* @returns The exit status, -1 if no exit status has been returned
* (yet).
* @warning This function may block until a timeout (or never)
* if the other side is not willing to close the channel.
*
@@ -3250,9 +3071,8 @@ static int channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
}
/* Just count number of pointers in the array */
static size_t count_ptrs(ssh_channel *ptrs)
{
size_t c;
static int count_ptrs(ssh_channel *ptrs) {
int c;
for (c = 0; ptrs[c] != NULL; c++)
;
@@ -3279,7 +3099,7 @@ static size_t count_ptrs(ssh_channel *ptrs)
*
* @return SSH_OK on a successful operation, SSH_EINTR if the
* select(2) syscall was interrupted, then relaunch the
* function, or SSH_ERROR on error.
* function.
*/
int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
ssh_channel *exceptchans, struct timeval * timeout) {
@@ -3506,7 +3326,7 @@ pending:
payload);
error:
SSH_BUFFER_FREE(payload);
ssh_buffer_free(payload);
return rc;
}
@@ -3568,7 +3388,7 @@ pending:
payload);
error:
SSH_BUFFER_FREE(payload);
ssh_buffer_free(payload);
return rc;
}
@@ -3609,7 +3429,7 @@ int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) {
rc = channel_request(channel, "exit-status", buffer, 0);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}
@@ -3664,7 +3484,7 @@ int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
rc = channel_request(channel, "exit-signal", buffer, 0);
error:
SSH_BUFFER_FREE(buffer);
ssh_buffer_free(buffer);
return rc;
}

View File

@@ -38,9 +38,6 @@
#include "libssh/socket.h"
#include "libssh/session.h"
#include "libssh/dh.h"
#ifdef WITH_GEX
#include "libssh/dh-gex.h"
#endif /* WITH_GEX */
#include "libssh/ecdh.h"
#include "libssh/threads.h"
#include "libssh/misc.h"
@@ -252,17 +249,10 @@ static int dh_handshake(ssh_session session) {
switch(session->next_crypto->kex_type){
case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1:
case SSH_KEX_DH_GROUP14_SHA256:
case SSH_KEX_DH_GROUP16_SHA512:
case SSH_KEX_DH_GROUP18_SHA512:
rc = ssh_client_dh_init(session);
break;
#ifdef WITH_GEX
case SSH_KEX_DH_GEX_SHA1:
case SSH_KEX_DH_GEX_SHA256:
rc = ssh_client_dhgex_init(session);
break;
#endif /* WITH_GEX */
#ifdef HAVE_ECDH
case SSH_KEX_ECDH_SHA2_NISTP256:
case SSH_KEX_ECDH_SHA2_NISTP384:
@@ -280,7 +270,11 @@ static int dh_handshake(ssh_session session) {
rc = SSH_ERROR;
}
break;
if (rc == SSH_ERROR) {
return SSH_ERROR;
}
session->dh_handshake_state = DH_STATE_INIT_SENT;
case DH_STATE_INIT_SENT:
/* wait until ssh_packet_dh_reply is called */
break;
@@ -400,7 +394,7 @@ static void ssh_client_connection_callback(ssh_session session)
goto error;
}
set_status(session, 0.4f);
SSH_LOG(SSH_LOG_PROTOCOL,
SSH_LOG(SSH_LOG_RARE,
"SSH server banner: %s", session->serverbanner);
/* Here we analyze the different protocols the server allows. */
@@ -751,7 +745,7 @@ error:
}
const char *ssh_copyright(void) {
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2019 "
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2018 "
"Aris Adamantiadis, Andreas Schneider "
"and libssh contributors. "
"Distributed under the LGPL, please refer to COPYING "

View File

@@ -31,9 +31,7 @@
# include <glob.h>
#endif
#include <stdbool.h>
#include <limits.h>
#include "libssh/config_parser.h"
#include "libssh/config.h"
#include "libssh/priv.h"
#include "libssh/session.h"
@@ -108,10 +106,10 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = {
{ "numberofpasswordprompts", SOC_UNSUPPORTED},
{ "pkcs11provider", SOC_UNSUPPORTED},
{ "preferredauthentications", SOC_UNSUPPORTED},
{ "proxyjump", SOC_PROXYJUMP},
{ "proxyjump", SOC_UNSUPPORTED},
{ "proxyusefdpass", SOC_UNSUPPORTED},
{ "pubkeyacceptedtypes", SOC_PUBKEYACCEPTEDTYPES},
{ "rekeylimit", SOC_REKEYLIMIT},
{ "rekeylimit", SOC_UNSUPPORTED},
{ "remotecommand", SOC_UNSUPPORTED},
{ "revokedhostkeys", SOC_UNSUPPORTED},
{ "rhostsrsaauthentication", SOC_UNSUPPORTED},
@@ -147,14 +145,12 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = {
{ "tunnel", SOC_NA},
{ "tunneldevice", SOC_NA},
{ "xauthlocation", SOC_NA},
{ "pubkeyacceptedkeytypes", SOC_PUBKEYACCEPTEDTYPES},
{ NULL, SOC_UNKNOWN }
};
enum ssh_config_match_e {
MATCH_UNKNOWN = -1,
MATCH_ALL,
MATCH_FINAL,
MATCH_CANONICAL,
MATCH_EXEC,
MATCH_HOST,
@@ -171,13 +167,11 @@ struct ssh_config_match_keyword_table_s {
static struct ssh_config_match_keyword_table_s ssh_config_match_keyword_table[] = {
{ "all", MATCH_ALL },
{ "canonical", MATCH_CANONICAL },
{ "final", MATCH_FINAL },
{ "exec", MATCH_EXEC },
{ "host", MATCH_HOST },
{ "originalhost", MATCH_ORIGINALHOST },
{ "user", MATCH_USER },
{ "localuser", MATCH_LOCALUSER },
{ NULL, MATCH_UNKNOWN },
};
static int ssh_config_parse_line(ssh_session session, const char *line,
@@ -195,6 +189,102 @@ static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
return SOC_UNKNOWN;
}
static char *ssh_config_get_cmd(char **str) {
register char *c;
char *r;
/* Ignore leading spaces */
for (c = *str; *c; c++) {
if (! isblank(*c)) {
break;
}
}
if (*c == '\"') {
for (r = ++c; *c; c++) {
if (*c == '\"') {
*c = '\0';
goto out;
}
}
}
for (r = c; *c; c++) {
if (*c == '\n') {
*c = '\0';
goto out;
}
}
out:
*str = c + 1;
return r;
}
static char *ssh_config_get_token(char **str) {
register char *c;
char *r;
c = ssh_config_get_cmd(str);
for (r = c; *c; c++) {
if (isblank(*c) || *c == '=') {
*c = '\0';
goto out;
}
}
out:
*str = c + 1;
return r;
}
static long ssh_config_get_long(char **str, long notfound) {
char *p, *endp;
long i;
p = ssh_config_get_token(str);
if (p && *p) {
i = strtol(p, &endp, 10);
if (p == endp) {
return notfound;
}
return i;
}
return notfound;
}
static const char *ssh_config_get_str_tok(char **str, const char *def) {
char *p;
p = ssh_config_get_token(str);
if (p && *p) {
return p;
}
return def;
}
static int ssh_config_get_yesno(char **str, int notfound) {
const char *p;
p = ssh_config_get_str_tok(str, NULL);
if (p == NULL) {
return notfound;
}
if (strncasecmp(p, "yes", 3) == 0) {
return 1;
} else if (strncasecmp(p, "no", 2) == 0) {
return 0;
}
return notfound;
}
static void
local_parse_file(ssh_session session,
const char *filename,
@@ -235,7 +325,7 @@ static void local_parse_glob(ssh_session session,
.gl_flags = 0,
};
int rt;
size_t i;
u_int i;
rt = glob(fileglob, GLOB_TILDE, NULL, &globbuf);
if (rt == GLOB_NOMATCH) {
@@ -274,8 +364,10 @@ static int
ssh_config_match(char *value, const char *pattern, bool negate)
{
int ok, result = 0;
char *lowervalue;
ok = match_pattern_list(value, pattern, strlen(pattern), 0);
lowervalue = (value) ? ssh_lowercase(value) : NULL;
ok = match_pattern_list(lowervalue, pattern, strlen(pattern), 0);
if (ok <= 0 && negate == true) {
result = 1;
} else if (ok > 0 && negate == false) {
@@ -284,99 +376,10 @@ ssh_config_match(char *value, const char *pattern, bool negate)
SSH_LOG(SSH_LOG_TRACE, "%s '%s' against pattern '%s'%s (ok=%d)",
result == 1 ? "Matched" : "Not matched", value, pattern,
negate == true ? " (negated)" : "", ok);
SAFE_FREE(lowervalue);
return result;
}
/* @brief: Parse the ProxyJump configuration line and if parsing,
* stores the result in the configuration option
*/
static int
ssh_config_parse_proxy_jump(ssh_session session, const char *s, bool do_parsing)
{
char *c = NULL, *cp = NULL, *endp = NULL;
char *username = NULL;
char *hostname = NULL;
char *port = NULL;
char *next = NULL;
int cmp, rv = SSH_ERROR;
bool parse_entry = do_parsing;
/* Special value none disables the proxy */
cmp = strcasecmp(s, "none");
if (cmp == 0 && do_parsing) {
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, s);
return SSH_OK;
}
/* This is comma-separated list of [user@]host[:port] entries */
c = strdup(s);
if (c == NULL) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
cp = c;
do {
endp = strchr(cp, ',');
if (endp != NULL) {
/* Split out the token */
*endp = '\0';
}
if (parse_entry) {
/* We actually care only about the first item */
rv = ssh_config_parse_uri(cp, &username, &hostname, &port);
/* The rest of the list needs to be passed on */
if (endp != NULL) {
next = strdup(endp + 1);
if (next == NULL) {
ssh_set_error_oom(session);
rv = SSH_ERROR;
}
}
} else {
/* The rest is just sanity-checked to avoid failures later */
rv = ssh_config_parse_uri(cp, NULL, NULL, NULL);
}
if (rv != SSH_OK) {
goto out;
}
parse_entry = 0;
if (endp != NULL) {
cp = endp + 1;
} else {
cp = NULL; /* end */
}
} while (cp != NULL);
if (hostname != NULL && do_parsing) {
char com[512] = {0};
rv = snprintf(com, sizeof(com), "ssh%s%s%s%s%s%s -W [%%h]:%%p %s",
username ? " -l " : "",
username ? username : "",
port ? " -p " : "",
port ? port : "",
next ? " -J " : "",
next ? next : "",
hostname);
if (rv < 0 || rv >= (int)sizeof(com)) {
SSH_LOG(SSH_LOG_WARN, "Too long ProxyJump configuration line");
rv = SSH_ERROR;
goto out;
}
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, com);
}
rv = SSH_OK;
out:
SAFE_FREE(username);
SAFE_FREE(hostname);
SAFE_FREE(port);
SAFE_FREE(next);
SAFE_FREE(c);
return rv;
}
static int
ssh_config_parse_line(ssh_session session,
const char *line,
@@ -384,20 +387,14 @@ ssh_config_parse_line(ssh_session session,
int *parsing)
{
enum ssh_config_opcode_e opcode;
const char *p = NULL, *p2 = NULL;
char *s = NULL, *x = NULL;
char *keyword = NULL;
char *lowerhost = NULL;
const char *p;
char *s, *x;
char *keyword;
char *lowerhost;
size_t len;
int i, rv;
int i;
uint8_t *seen = session->opts.options_seen;
long l;
int64_t ll;
/* Ignore empty lines */
if (line == NULL || *line == '\0') {
return 0;
}
x = s = strdup(line);
if (s == NULL) {
@@ -452,11 +449,10 @@ ssh_config_parse_line(ssh_session session,
int result = 1;
size_t args = 0;
enum ssh_config_match_e opt;
char *localuser = NULL;
*parsing = 0;
do {
p = p2 = ssh_config_get_str_tok(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') {
break;
}
@@ -475,10 +471,8 @@ ssh_config_parse_line(ssh_session session,
switch (opt) {
case MATCH_ALL:
p = ssh_config_get_str_tok(&s, NULL);
if (args <= 2 && (p == NULL || p[0] == '\0')) {
/* The first or second, but last argument. The "all" keyword
* can be prefixed with either "final" or "canonical"
* keywords which do not have any effect here. */
if (args == 1 && (p == NULL || p[0] == '\0')) {
/* The first argument and end of line */
if (negate == true) {
result = 0;
}
@@ -491,69 +485,16 @@ ssh_config_parse_line(ssh_session session,
SAFE_FREE(x);
return -1;
case MATCH_FINAL:
case MATCH_CANONICAL:
SSH_LOG(SSH_LOG_WARN,
"line %d: Unsupported Match keyword '%s', skipping",
count,
p);
/* Not set any result here -- the result is dependent on the
* following matches after this keyword */
break;
case MATCH_EXEC:
/* Skip to the end of line as unsupported */
p = ssh_config_get_cmd(&s);
if (p == NULL || p[0] == '\0') {
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
"'%s' requires argument", count, p2);
SAFE_FREE(x);
return -1;
}
args++;
SSH_LOG(SSH_LOG_WARN,
"line %d: Unsupported Match keyword '%s', ignoring",
count,
p2);
result = 0;
break;
case MATCH_LOCALUSER:
/* Here we match only one argument */
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') {
ssh_set_error(session, SSH_FATAL,
"line %d: ERROR - Match user keyword "
"requires argument", count);
SAFE_FREE(x);
return -1;
}
localuser = ssh_get_local_username();
if (localuser == NULL) {
SSH_LOG(SSH_LOG_WARN, "line %d: Can not get local username "
"for conditional matching.", count);
SAFE_FREE(x);
return -1;
}
result &= ssh_config_match(localuser, p, negate);
SAFE_FREE(localuser);
args++;
break;
case MATCH_ORIGINALHOST:
case MATCH_LOCALUSER:
/* Skip one argument */
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') {
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
"'%s' requires argument", count, p2);
SAFE_FREE(x);
return -1;
}
args++;
SSH_LOG(SSH_LOG_WARN,
"line %d: Unsupported Match keyword '%s', ignoring",
count,
p2);
FALL_THROUGH;
case MATCH_CANONICAL:
SSH_LOG(SSH_LOG_WARN, "line: %d: Unsupported Match keyword "
"'%s', Ignoring\n", count, p);
result = 0;
break;
@@ -728,25 +669,10 @@ ssh_config_parse_line(ssh_session session,
break;
case SOC_PROXYCOMMAND:
p = ssh_config_get_cmd(&s);
/* We share the seen value with the ProxyJump */
if (p && *parsing && !seen[SOC_PROXYJUMP]) {
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, p);
}
break;
case SOC_PROXYJUMP:
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL) {
SAFE_FREE(x);
return -1;
}
/* We share the seen value with the ProxyCommand */
rv = ssh_config_parse_proxy_jump(session, p,
(*parsing && !seen[SOC_PROXYCOMMAND]));
if (rv != SSH_OK) {
SAFE_FREE(x);
return -1;
}
break;
case SOC_GSSAPISERVERIDENTITY:
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
@@ -820,141 +746,6 @@ ssh_config_parse_line(ssh_session session,
ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, p);
}
break;
case SOC_REKEYLIMIT:
/* Parse the data limit */
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL) {
break;
} else if (strcmp(p, "default") == 0) {
/* Default rekey limits enforced automaticaly */
ll = 0;
} else {
char *endp = NULL;
ll = strtoll(p, &endp, 10);
if (p == endp || ll < 0) {
/* No number or negative */
SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit");
break;
}
switch (*endp) {
case 'G':
if (ll > LLONG_MAX / 1024) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 1024;
FALL_THROUGH;
case 'M':
if (ll > LLONG_MAX / 1024) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 1024;
FALL_THROUGH;
case 'K':
if (ll > LLONG_MAX / 1024) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 1024;
endp++;
FALL_THROUGH;
case '\0':
/* just the number */
break;
default:
/* Invalid suffix */
ll = -1;
break;
}
if (*endp != ' ' && *endp != '\0') {
SSH_LOG(SSH_LOG_WARN,
"Invalid trailing characters after the rekey limit: %s",
endp);
break;
}
}
if (ll > -1 && *parsing) {
uint64_t v = (uint64_t)ll;
ssh_options_set(session, SSH_OPTIONS_REKEY_DATA, &v);
}
/* Parse the time limit */
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL) {
break;
} else if (strcmp(p, "none") == 0) {
ll = 0;
} else {
char *endp = NULL;
ll = strtoll(p, &endp, 10);
if (p == endp || ll < 0) {
/* No number or negative */
SSH_LOG(SSH_LOG_WARN, "Invalid argument to rekey limit");
break;
}
switch (*endp) {
case 'w':
case 'W':
if (ll > LLONG_MAX / 7) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 7;
FALL_THROUGH;
case 'd':
case 'D':
if (ll > LLONG_MAX / 24) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 24;
FALL_THROUGH;
case 'h':
case 'H':
if (ll > LLONG_MAX / 60) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 60;
FALL_THROUGH;
case 'm':
case 'M':
if (ll > LLONG_MAX / 60) {
SSH_LOG(SSH_LOG_WARN, "Possible overflow of rekey limit");
ll = -1;
break;
}
ll = ll * 60;
FALL_THROUGH;
case 's':
case 'S':
endp++;
FALL_THROUGH;
case '\0':
/* just the number */
break;
default:
/* Invalid suffix */
ll = -1;
break;
}
if (*endp != '\0') {
SSH_LOG(SSH_LOG_WARN, "Invalid trailing characters after the"
" rekey limit: %s", endp);
break;
}
}
if (ll > -1 && *parsing) {
uint32_t v = (uint32_t)ll;
ssh_options_set(session, SSH_OPTIONS_REKEY_TIME, &v);
}
break;
case SOC_GSSAPIAUTHENTICATION:
case SOC_KBDINTERACTIVEAUTHENTICATION:
case SOC_PASSWORDAUTHENTICATION:

View File

@@ -1,238 +0,0 @@
/*
* config_parser.c - Common configuration file parser functions
*
* This file is part of the SSH Library
*
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "libssh/config_parser.h"
#include "libssh/priv.h"
char *ssh_config_get_cmd(char **str)
{
register char *c;
char *r;
/* Ignore leading spaces */
for (c = *str; *c; c++) {
if (! isblank(*c)) {
break;
}
}
if (*c == '\"') {
for (r = ++c; *c; c++) {
if (*c == '\"') {
*c = '\0';
goto out;
}
}
}
for (r = c; *c; c++) {
if (*c == '\n') {
*c = '\0';
goto out;
}
}
out:
*str = c + 1;
return r;
}
char *ssh_config_get_token(char **str)
{
register char *c;
char *r;
c = ssh_config_get_cmd(str);
for (r = c; *c; c++) {
if (isblank(*c) || *c == '=') {
*c = '\0';
goto out;
}
}
out:
*str = c + 1;
return r;
}
long ssh_config_get_long(char **str, long notfound)
{
char *p, *endp;
long i;
p = ssh_config_get_token(str);
if (p && *p) {
i = strtol(p, &endp, 10);
if (p == endp) {
return notfound;
}
return i;
}
return notfound;
}
const char *ssh_config_get_str_tok(char **str, const char *def)
{
char *p;
p = ssh_config_get_token(str);
if (p && *p) {
return p;
}
return def;
}
int ssh_config_get_yesno(char **str, int notfound)
{
const char *p;
p = ssh_config_get_str_tok(str, NULL);
if (p == NULL) {
return notfound;
}
if (strncasecmp(p, "yes", 3) == 0) {
return 1;
} else if (strncasecmp(p, "no", 2) == 0) {
return 0;
}
return notfound;
}
int ssh_config_parse_uri(const char *tok,
char **username,
char **hostname,
char **port)
{
char *endp = NULL;
long port_n;
/* Sanitize inputs */
if (username != NULL) {
*username = NULL;
}
if (hostname != NULL) {
*hostname = NULL;
}
if (port != NULL) {
*port = NULL;
}
/* Username part (optional) */
endp = strchr(tok, '@');
if (endp != NULL) {
/* Zero-length username is not valid */
if (tok == endp) {
goto error;
}
if (username != NULL) {
*username = strndup(tok, endp - tok);
if (*username == NULL) {
goto error;
}
}
tok = endp + 1;
/* If there is second @ character, this does not look like our URI */
endp = strchr(tok, '@');
if (endp != NULL) {
goto error;
}
}
/* Hostname */
if (*tok == '[') {
/* IPv6 address is enclosed with square brackets */
tok++;
endp = strchr(tok, ']');
if (endp == NULL) {
goto error;
}
} else {
/* Hostnames or aliases expand to the last colon or to the end */
endp = strrchr(tok, ':');
if (endp == NULL) {
endp = strchr(tok, '\0');
}
}
if (tok == endp) {
/* Zero-length hostnames are not valid */
goto error;
}
if (hostname != NULL) {
*hostname = strndup(tok, endp - tok);
if (*hostname == NULL) {
goto error;
}
}
/* Skip also the closing bracket */
if (*endp == ']') {
endp++;
}
/* Port (optional) */
if (*endp != '\0') {
char *port_end = NULL;
/* Verify the port is valid positive number */
port_n = strtol(endp + 1, &port_end, 10);
if (port_n < 1 || *port_end != '\0') {
SSH_LOG(SSH_LOG_WARN, "Failed to parse port number."
" The value '%ld' is invalid or there are some"
" trailing characters: '%s'", port_n, port_end);
goto error;
}
if (port != NULL) {
*port = strdup(endp + 1);
if (*port == NULL) {
goto error;
}
}
}
return SSH_OK;
error:
if (username != NULL) {
SAFE_FREE(*username);
}
if (hostname != NULL) {
SAFE_FREE(*hostname);
}
if (port != NULL) {
SAFE_FREE(*port);
}
return SSH_ERROR;
}

View File

@@ -25,7 +25,6 @@
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -91,55 +90,131 @@
#ifdef _WIN32
#ifndef gai_strerror
char WSAAPI *gai_strerrorA(int code)
{
static char buf[256];
char WSAAPI *gai_strerrorA(int code) {
static char buf[256];
snprintf(buf, sizeof(buf), "Undetermined error code (%d)", code);
snprintf(buf, sizeof(buf), "Undetermined error code (%d)", code);
return buf;
return buf;
}
#endif /* gai_strerror */
#endif /* _WIN32 */
static int ssh_connect_socket_close(socket_t s)
{
static int ssh_connect_socket_close(socket_t s){
#ifdef _WIN32
return closesocket(s);
return closesocket(s);
#else
return close(s);
return close(s);
#endif
}
static int getai(const char *host, int port, struct addrinfo **ai)
{
const char *service = NULL;
struct addrinfo hints;
char s_port[10];
ZERO_STRUCT(hints);
static int getai(const char *host, int port, struct addrinfo **ai) {
const char *service = NULL;
struct addrinfo hints;
char s_port[10];
hints.ai_protocol = IPPROTO_TCP;
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
ZERO_STRUCT(hints);
if (port == 0) {
hints.ai_flags = AI_PASSIVE;
} else {
snprintf(s_port, sizeof(s_port), "%hu", (unsigned short)port);
service = s_port;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (port == 0) {
hints.ai_flags = AI_PASSIVE;
} else {
snprintf(s_port, sizeof(s_port), "%hu", (unsigned short)port);
service = s_port;
#ifdef AI_NUMERICSERV
hints.ai_flags = AI_NUMERICSERV;
hints.ai_flags=AI_NUMERICSERV;
#endif
}
}
if (ssh_is_ipaddr(host)) {
/* this is an IP address */
SSH_LOG(SSH_LOG_PACKET, "host %s matches an IP address", host);
hints.ai_flags |= AI_NUMERICHOST;
}
if (ssh_is_ipaddr(host)) {
/* this is an IP address */
SSH_LOG(SSH_LOG_PACKET,"host %s matches an IP address",host);
hints.ai_flags |= AI_NUMERICHOST;
}
return getaddrinfo(host, service, &hints, ai);
return getaddrinfo(host, service, &hints, ai);
}
static int ssh_connect_ai_timeout(ssh_session session, const char *host,
int port, struct addrinfo *ai, long timeout, long usec, socket_t s) {
int timeout_ms;
ssh_pollfd_t fds;
int rc = 0;
int ret;
socklen_t len = sizeof(rc);
/* I know we're losing some precision. But it's not like poll-like family
* type of mechanisms are precise up to the microsecond.
*/
timeout_ms=timeout * 1000 + usec / 1000;
rc = ssh_socket_set_nonblocking(s);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket non-blocking for %s:%d", host, port);
ssh_connect_socket_close(s);
return -1;
}
SSH_LOG(SSH_LOG_RARE, "Trying to connect to host: %s:%d with "
"timeout %d ms", host, port, timeout_ms);
/* The return value is checked later */
connect(s, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(ai);
fds.fd=s;
fds.revents=0;
fds.events=POLLOUT;
#ifdef _WIN32
fds.events |= POLLWRNORM;
#endif
rc = ssh_poll(&fds,1,timeout_ms);
if (rc == 0) {
/* timeout */
ssh_set_error(session, SSH_FATAL,
"Timeout while connecting to %s:%d", host, port);
ssh_connect_socket_close(s);
return -1;
}
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"poll error: %s", strerror(errno));
ssh_connect_socket_close(s);
return -1;
}
rc = -1;
/* Get connect(2) return code. Zero means no error */
ret = getsockopt(s, SOL_SOCKET, SO_ERROR,(char *) &rc, &len);
if (ret < 0 || rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Connect to %s:%d failed: %s", host, port, strerror(rc));
ssh_connect_socket_close(s);
return -1;
}
/* s is connected ? */
SSH_LOG(SSH_LOG_PACKET, "Socket connected with timeout");
ret = ssh_socket_set_blocking(s);
if (ret < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket as blocking connecting to %s:%d failed: %s",
host, port, strerror(errno));
ssh_connect_socket_close(s);
return -1;
}
return s;
}
static int set_tcp_nodelay(socket_t socket)
@@ -153,6 +228,99 @@ static int set_tcp_nodelay(socket_t socket)
sizeof(opt));
}
/**
* @internal
*
* @brief Connect to an IPv4 or IPv6 host specified by its IP address or
* hostname.
*
* @returns A file descriptor, < 0 on error.
*/
socket_t ssh_connect_host(ssh_session session, const char *host,
const char *bind_addr, int port, long timeout, long usec) {
socket_t s = -1;
int rc;
struct addrinfo *ai;
struct addrinfo *itr;
rc = getai(host, port, &ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
return -1;
}
for (itr = ai; itr != NULL; itr = itr->ai_next){
/* create socket */
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
if (s < 0) {
ssh_set_error(session, SSH_FATAL,
"Socket create failed: %s", strerror(errno));
continue;
}
if (bind_addr) {
struct addrinfo *bind_ai;
struct addrinfo *bind_itr;
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
rc = getai(bind_addr, 0, &bind_ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve bind address %s (%s)",
bind_addr,
gai_strerror(rc));
freeaddrinfo(ai);
close(s);
return -1;
}
for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
ssh_set_error(session, SSH_FATAL,
"Binding local address: %s", strerror(errno));
continue;
} else {
break;
}
}
freeaddrinfo(bind_ai);
/* Cannot bind to any local addresses */
if (bind_itr == NULL) {
ssh_connect_socket_close(s);
s = -1;
continue;
}
}
if (timeout || usec) {
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
timeout, usec, s);
freeaddrinfo(ai);
return ret;
}
if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) {
ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno));
ssh_connect_socket_close(s);
s = -1;
continue;
} else {
/* We are connected */
break;
}
}
freeaddrinfo(ai);
return s;
}
/**
* @internal
*
@@ -163,109 +331,102 @@ static int set_tcp_nodelay(socket_t socket)
* @warning very ugly !!!
*/
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
const char *bind_addr, int port)
{
socket_t s = -1;
int rc;
struct addrinfo *ai = NULL;
struct addrinfo *itr = NULL;
const char *bind_addr, int port) {
socket_t s = -1;
int rc;
struct addrinfo *ai;
struct addrinfo *itr;
rc = getai(host, port, &ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve hostname %s (%s)",
host, gai_strerror(rc));
rc = getai(host, port, &ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
return -1;
return -1;
}
for (itr = ai; itr != NULL; itr = itr->ai_next){
/* create socket */
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
if (s < 0) {
ssh_set_error(session, SSH_FATAL,
"Socket create failed: %s", strerror(errno));
continue;
}
for (itr = ai; itr != NULL; itr = itr->ai_next) {
/* create socket */
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
if (s < 0) {
ssh_set_error(session, SSH_FATAL,
"Socket create failed: %s", strerror(errno));
continue;
if (bind_addr) {
struct addrinfo *bind_ai;
struct addrinfo *bind_itr;
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
rc = getai(bind_addr, 0, &bind_ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve bind address %s (%s)",
bind_addr,
gai_strerror(rc));
ssh_connect_socket_close(s);
s=-1;
break;
}
for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
ssh_set_error(session, SSH_FATAL,
"Binding local address: %s", strerror(errno));
continue;
} else {
break;
}
}
freeaddrinfo(bind_ai);
if (bind_addr) {
struct addrinfo *bind_ai;
struct addrinfo *bind_itr;
/* Cannot bind to any local addresses */
if (bind_itr == NULL) {
ssh_connect_socket_close(s);
s = -1;
continue;
}
}
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);
rc = ssh_socket_set_nonblocking(s);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket non-blocking for %s:%d", host, port);
ssh_connect_socket_close(s);
s = -1;
continue;
}
rc = getai(bind_addr, 0, &bind_ai);
if (rc != 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to resolve bind address %s (%s)",
bind_addr,
gai_strerror(rc));
ssh_connect_socket_close(s);
s = -1;
break;
}
for (bind_itr = bind_ai;
bind_itr != NULL;
bind_itr = bind_itr->ai_next)
{
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
ssh_set_error(session, SSH_FATAL,
"Binding local address: %s", strerror(errno));
continue;
} else {
break;
}
}
freeaddrinfo(bind_ai);
/* Cannot bind to any local addresses */
if (bind_itr == NULL) {
ssh_connect_socket_close(s);
s = -1;
continue;
}
}
rc = ssh_socket_set_nonblocking(s);
if (session->opts.nodelay) {
/* For winsock, socket options are only effective before connect */
rc = set_tcp_nodelay(s);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set socket non-blocking for %s:%d",
host, port);
"Failed to set TCP_NODELAY on socket: %s", strerror(errno));
ssh_connect_socket_close(s);
s = -1;
continue;
}
if (session->opts.nodelay) {
/* For winsock, socket options are only effective before connect */
rc = set_tcp_nodelay(s);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL,
"Failed to set TCP_NODELAY on socket: %s",
strerror(errno));
ssh_connect_socket_close(s);
s = -1;
continue;
}
}
errno = 0;
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
ssh_set_error(session, SSH_FATAL,
"Failed to connect: %s", strerror(errno));
ssh_connect_socket_close(s);
s = -1;
continue;
}
break;
}
freeaddrinfo(ai);
errno = 0;
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
ssh_set_error(session, SSH_FATAL,
"Failed to connect: %s", strerror(errno));
ssh_connect_socket_close(s);
s = -1;
continue;
}
return s;
break;
}
freeaddrinfo(ai);
return s;
}
/**
@@ -274,13 +435,11 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
* @{
*/
static int ssh_select_cb (socket_t fd, int revents, void *userdata)
{
fd_set *set = (fd_set *)userdata;
if (revents & POLLIN) {
FD_SET(fd, set);
}
return 0;
static int ssh_select_cb (socket_t fd, int revents, void *userdata){
fd_set *set = (fd_set *)userdata;
if(revents & POLLIN)
FD_SET(fd, set);
return 0;
}
/**
@@ -314,84 +473,73 @@ static int ssh_select_cb (socket_t fd, int revents, void *userdata)
* @see select(2)
*/
int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout)
{
fd_set origfds;
socket_t fd;
size_t i, j;
int rc;
int base_tm, tm;
struct ssh_timestamp ts;
ssh_event event = ssh_event_new();
int firstround = 1;
fd_set *readfds, struct timeval *timeout) {
fd_set origfds;
socket_t fd;
size_t i, j;
int rc;
int base_tm, tm;
struct ssh_timestamp ts;
ssh_event event = ssh_event_new();
int firstround=1;
base_tm = tm = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
for (i = 0 ; channels[i] != NULL; ++i) {
ssh_event_add_session(event, channels[i]->session);
base_tm = tm=timeout->tv_sec * 1000 + timeout->tv_usec/1000;
for (i=0 ; channels[i] != NULL; ++i){
ssh_event_add_session(event, channels[i]->session);
}
ZERO_STRUCT(origfds);
FD_ZERO(&origfds);
for (fd = 0; fd < maxfd ; fd++) {
if (FD_ISSET(fd, readfds)) {
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
FD_SET(fd, &origfds);
}
}
outchannels[0] = NULL;
FD_ZERO(readfds);
ssh_timestamp_init(&ts);
do {
/* Poll every channel */
j = 0;
for (i = 0; channels[i]; i++) {
if(ssh_channel_poll(channels[i], 0) != 0) {
outchannels[j] = channels[i];
j++;
} else if(ssh_channel_poll(channels[i], 1) != 0) {
outchannels[j] = channels[i];
j++;
}
}
ZERO_STRUCT(origfds);
FD_ZERO(&origfds);
for (fd = 0; fd < maxfd ; fd++) {
if (FD_ISSET(fd, readfds)) {
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
FD_SET(fd, &origfds);
}
}
outchannels[0] = NULL;
FD_ZERO(readfds);
ssh_timestamp_init(&ts);
do {
/* Poll every channel */
j = 0;
for (i = 0; channels[i]; i++) {
rc = ssh_channel_poll(channels[i], 0);
if (rc != 0) {
outchannels[j] = channels[i];
j++;
} else {
rc = ssh_channel_poll(channels[i], 1);
if (rc != 0) {
outchannels[j] = channels[i];
j++;
}
}
}
outchannels[j] = NULL;
if (j != 0) {
break;
}
/* watch if a user socket was triggered */
for (fd = 0; fd < maxfd; fd++) {
if (FD_ISSET(fd, readfds)) {
goto out;
}
}
/* If the timeout is elapsed, we should go out */
if (!firstround && ssh_timeout_elapsed(&ts, base_tm)) {
goto out;
}
/* since there's nothing, let's fire the polling */
rc = ssh_event_dopoll(event,tm);
if (rc == SSH_ERROR) {
goto out;
}
tm = ssh_timeout_update(&ts, base_tm);
firstround = 0;
} while (1);
out:
outchannels[j] = NULL;
if(j != 0)
break;
/* watch if a user socket was triggered */
for (fd = 0; fd < maxfd; fd++) {
if (FD_ISSET(fd, &origfds)) {
ssh_event_remove_fd(event, fd);
if (FD_ISSET(fd, readfds)) {
goto out;
}
}
ssh_event_free(event);
return SSH_OK;
/* If the timeout is elapsed, we should go out */
if(!firstround && ssh_timeout_elapsed(&ts, base_tm))
goto out;
/* since there's nothing, let's fire the polling */
rc = ssh_event_dopoll(event,tm);
if (rc == SSH_ERROR){
goto out;
}
tm = ssh_timeout_update(&ts, base_tm);
firstround=0;
} while (1);
out:
for (fd = 0; fd < maxfd; fd++) {
if (FD_ISSET(fd, &origfds)) {
ssh_event_remove_fd(event, fd);
}
}
ssh_event_free(event);
return SSH_OK;
}
/** @} */

View File

@@ -267,13 +267,8 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
if (connector->out_channel != NULL) {
if (r == 0) {
SSH_LOG(SSH_LOG_TRACE, "input fd %d is EOF", connector->in_fd);
if (connector->out_channel->local_eof == 0) {
rc = ssh_channel_send_eof(connector->out_channel);
(void)rc; /* TODO Handle rc? */
}
connector->in_available = 1; /* Don't poll on it */
return;
rc = ssh_channel_send_eof(connector->out_channel);
(void)rc; /* TODO Handle rc? */
} else if (r> 0) {
/* loop around ssh_channel_write in case our window reduced due to a race */
while (total != r){
@@ -294,7 +289,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
}
} else if (connector->out_fd != SSH_INVALID_SOCKET) {
if (r == 0){
close(connector->out_fd);
close (connector->out_fd);
connector->out_fd = SSH_INVALID_SOCKET;
} else {
/*
@@ -646,12 +641,14 @@ int ssh_connector_remove_event(ssh_connector connector) {
session = ssh_channel_get_session(connector->in_channel);
ssh_event_remove_session(connector->event, session);
connector->in_channel = NULL;
}
if (connector->out_channel != NULL) {
session = ssh_channel_get_session(connector->out_channel);
ssh_event_remove_session(connector->event, session);
connector->out_channel = NULL;
}
connector->event = NULL;

View File

@@ -39,235 +39,75 @@
#include "libssh/pki.h"
#include "libssh/bignum.h"
#ifdef HAVE_OPENSSL_X25519
#include <openssl/err.h>
#endif
static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply);
static ssh_packet_callback dh_client_callbacks[] = {
ssh_packet_client_curve25519_reply
};
static struct ssh_packet_callbacks_struct ssh_curve25519_client_callbacks = {
.start = SSH2_MSG_KEX_ECDH_REPLY,
.n_callbacks = 1,
.callbacks = dh_client_callbacks,
.user = NULL
};
static int ssh_curve25519_init(ssh_session session)
{
int rc;
#ifdef HAVE_OPENSSL_X25519
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL;
size_t pubkey_len = CURVE25519_PUBKEY_SIZE;
size_t pkey_len = CURVE25519_PRIVKEY_SIZE;
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
if (pctx == NULL) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to initialize X25519 context: %s",
ERR_error_string(ERR_get_error(), NULL));
return SSH_ERROR;
}
rc = EVP_PKEY_keygen_init(pctx);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to initialize X25519 keygen: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_CTX_free(pctx);
return SSH_ERROR;
}
rc = EVP_PKEY_keygen(pctx, &pkey);
EVP_PKEY_CTX_free(pctx);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to generate X25519 keys: %s",
ERR_error_string(ERR_get_error(), NULL));
return SSH_ERROR;
}
if (session->server) {
rc = EVP_PKEY_get_raw_public_key(pkey,
session->next_crypto->curve25519_server_pubkey,
&pubkey_len);
} else {
rc = EVP_PKEY_get_raw_public_key(pkey,
session->next_crypto->curve25519_client_pubkey,
&pubkey_len);
}
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to get X25519 raw public key: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_free(pkey);
return SSH_ERROR;
}
rc = EVP_PKEY_get_raw_private_key(pkey,
session->next_crypto->curve25519_privkey,
&pkey_len);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to get X25519 raw private key: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_PKEY_free(pkey);
return SSH_ERROR;
}
EVP_PKEY_free(pkey);
#else
rc = ssh_get_random(session->next_crypto->curve25519_privkey,
CURVE25519_PRIVKEY_SIZE, 1);
if (rc != 1) {
ssh_set_error(session, SSH_FATAL, "PRNG error");
return SSH_ERROR;
}
if (session->server) {
crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
session->next_crypto->curve25519_privkey);
} else {
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
session->next_crypto->curve25519_privkey);
}
#endif /* HAVE_OPENSSL_X25519 */
return SSH_OK;
}
/** @internal
* @brief Starts curve25519-sha256@libssh.org / curve25519-sha256 key exchange
*/
int ssh_client_curve25519_init(ssh_session session)
{
int rc;
int ssh_client_curve25519_init(ssh_session session){
int rc;
int ok;
rc = ssh_curve25519_init(session);
if (rc != SSH_OK) {
return rc;
}
ok = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
if (!ok) {
ssh_set_error(session, SSH_FATAL, "PRNG error");
return SSH_ERROR;
}
rc = ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_KEX_ECDH_INIT,
CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE,
session->next_crypto->curve25519_client_pubkey);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
session->next_crypto->curve25519_privkey);
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_curve25519_client_callbacks);
session->dh_handshake_state = DH_STATE_INIT_SENT;
rc = ssh_packet_send(session);
rc = ssh_buffer_pack(session->out_buffer,
"bdP",
SSH2_MSG_KEX_ECDH_INIT,
CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
return SSH_ERROR;
}
return rc;
rc = ssh_packet_send(session);
return rc;
}
static int ssh_curve25519_build_k(ssh_session session)
{
ssh_curve25519_pubkey k;
static int ssh_curve25519_build_k(ssh_session session) {
ssh_curve25519_pubkey k;
#ifdef HAVE_OPENSSL_X25519
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL, *pubkey = NULL;
size_t shared_key_len = sizeof(k);
int rc, ret = SSH_ERROR;
#ifdef HAVE_LIBCRYPTO
session->next_crypto->k = bignum_new();
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL,
session->next_crypto->curve25519_privkey,
CURVE25519_PRIVKEY_SIZE);
if (pkey == NULL) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to create X25519 EVP_PKEY: %s",
ERR_error_string(ERR_get_error(), NULL));
return SSH_ERROR;
}
if (session->next_crypto->k == NULL) {
return SSH_ERROR;
}
#elif defined HAVE_LIBMBEDCRYPTO
session->next_crypto->k = bignum_new();
pctx = EVP_PKEY_CTX_new(pkey, NULL);
if (pctx == NULL) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to initialize X25519 context: %s",
ERR_error_string(ERR_get_error(), NULL));
goto out;
}
if (session->next_crypto->k == NULL) {
return SSH_ERROR;
}
#endif
rc = EVP_PKEY_derive_init(pctx);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to initialize X25519 key derivation: %s",
ERR_error_string(ERR_get_error(), NULL));
goto out;
}
if (session->server)
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
session->next_crypto->curve25519_client_pubkey);
else
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
session->next_crypto->curve25519_server_pubkey);
if (session->server) {
pubkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL,
session->next_crypto->curve25519_client_pubkey,
CURVE25519_PUBKEY_SIZE);
} else {
pubkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL,
session->next_crypto->curve25519_server_pubkey,
CURVE25519_PUBKEY_SIZE);
}
if (pubkey == NULL) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to create X25519 public key EVP_PKEY: %s",
ERR_error_string(ERR_get_error(), NULL));
goto out;
}
rc = EVP_PKEY_derive_set_peer(pctx, pubkey);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to set peer X25519 public key: %s",
ERR_error_string(ERR_get_error(), NULL));
goto out;
}
rc = EVP_PKEY_derive(pctx, k, &shared_key_len);
if (rc != 1) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to derive X25519 shared secret: %s",
ERR_error_string(ERR_get_error(), NULL));
goto out;
}
ret = SSH_OK;
out:
EVP_PKEY_free(pkey);
EVP_PKEY_free(pubkey);
EVP_PKEY_CTX_free(pctx);
if (ret == SSH_ERROR) {
return ret;
}
#else
if (session->server) {
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
session->next_crypto->curve25519_client_pubkey);
} else {
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
session->next_crypto->curve25519_server_pubkey);
}
#endif /* HAVE_OPENSSL_X25519 */
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->shared_secret);
if (session->next_crypto->shared_secret == NULL) {
return SSH_ERROR;
}
#ifdef HAVE_LIBGCRYPT
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->k);
#elif defined HAVE_LIBCRYPTO
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
#elif defined HAVE_LIBMBEDCRYPTO
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
#endif
#ifdef DEBUG_CRYPTO
ssh_log_hexdump("Session server cookie",
ssh_print_hexa("Session server cookie",
session->next_crypto->server_kex.cookie, 16);
ssh_log_hexdump("Session client cookie",
ssh_print_hexa("Session client cookie",
session->next_crypto->client_kex.cookie, 16);
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
ssh_print_bignum("Shared secret key", session->next_crypto->k);
#endif
return 0;
@@ -277,15 +117,11 @@ out:
* @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
* a SSH_MSG_NEWKEYS
*/
static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){
ssh_string q_s_string = NULL;
ssh_string pubkey_blob = NULL;
ssh_string signature = NULL;
int rc;
(void)type;
(void)user;
ssh_packet_remove_callbacks(session, &ssh_curve25519_client_callbacks);
pubkey_blob = ssh_buffer_get_ssh_string(packet);
if (pubkey_blob == NULL) {
@@ -294,7 +130,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
}
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
SSH_STRING_FREE(pubkey_blob);
ssh_string_free(pubkey_blob);
if (rc != 0) {
ssh_set_error(session,
SSH_FATAL,
@@ -310,11 +146,11 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
(int)ssh_string_len(q_s_string));
SSH_STRING_FREE(q_s_string);
ssh_string_free(q_s_string);
goto error;
}
memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE);
SSH_STRING_FREE(q_s_string);
ssh_string_free(q_s_string);
signature = ssh_buffer_get_ssh_string(packet);
if (signature == NULL) {
@@ -335,47 +171,18 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){
}
rc=ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
return SSH_PACKET_USED;
return rc;
error:
session->session_state=SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
return SSH_ERROR;
}
#ifdef WITH_SERVER
static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init);
static ssh_packet_callback dh_server_callbacks[]= {
ssh_packet_server_curve25519_init
};
static struct ssh_packet_callbacks_struct ssh_curve25519_server_callbacks = {
.start = SSH2_MSG_KEX_ECDH_INIT,
.n_callbacks = 1,
.callbacks = dh_server_callbacks,
.user = NULL
};
/** @internal
* @brief sets up the curve25519-sha256@libssh.org kex callbacks
*/
void ssh_server_curve25519_init(ssh_session session){
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_curve25519_server_callbacks);
}
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
* SSH_MSG_KEXDH_REPLY
*/
static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
/* ECDH keys */
ssh_string q_c_string;
ssh_string q_s_string;
@@ -383,40 +190,37 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
/* SSH host keys (rsa,dsa,ecdsa) */
ssh_key privkey;
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
ssh_string sig_blob = NULL;
int ok;
int rc;
(void)type;
(void)user;
ssh_packet_remove_callbacks(session, &ssh_curve25519_server_callbacks);
/* Extract the client pubkey from the init packet */
q_c_string = ssh_buffer_get_ssh_string(packet);
if (q_c_string == NULL) {
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
goto error;
return SSH_ERROR;
}
if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){
ssh_set_error(session,
SSH_FATAL,
"Incorrect size for server Curve25519 public key: %zu",
ssh_string_len(q_c_string));
SSH_STRING_FREE(q_c_string);
goto error;
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
(int)ssh_string_len(q_c_string));
ssh_string_free(q_c_string);
return SSH_ERROR;
}
memcpy(session->next_crypto->curve25519_client_pubkey,
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
SSH_STRING_FREE(q_c_string);
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
ssh_string_free(q_c_string);
/* Build server's keypair */
rc = ssh_curve25519_init(session);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Failed to generate curve25519 keys");
goto error;
ok = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
if (!ok) {
ssh_set_error(session, SSH_FATAL, "PRNG error");
return SSH_ERROR;
}
crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
session->next_crypto->curve25519_privkey);
rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY);
if (rc < 0) {
ssh_set_error_oom(session);
@@ -431,7 +235,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
}
/* privkey is not allocated */
rc = ssh_get_key_params(session, &privkey, &digest);
rc = ssh_get_key_params(session, &privkey);
if (rc == SSH_ERROR) {
goto error;
}
@@ -451,7 +255,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
/* add host's public key */
rc = ssh_buffer_add_ssh_string(session->out_buffer,
server_pubkey_blob);
SSH_STRING_FREE(server_pubkey_blob);
ssh_string_free(server_pubkey_blob);
if (rc < 0) {
ssh_set_error_oom(session);
goto error;
@@ -468,20 +272,20 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
CURVE25519_PUBKEY_SIZE);
rc = ssh_buffer_add_ssh_string(session->out_buffer, q_s_string);
SSH_STRING_FREE(q_s_string);
ssh_string_free(q_s_string);
if (rc < 0) {
ssh_set_error_oom(session);
goto error;
}
/* add signature blob */
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
if (sig_blob == NULL) {
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
goto error;
}
rc = ssh_buffer_add_ssh_string(session->out_buffer, sig_blob);
SSH_STRING_FREE(sig_blob);
ssh_string_free(sig_blob);
if (rc < 0) {
ssh_set_error_oom(session);
goto error;
@@ -501,16 +305,12 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
return SSH_PACKET_USED;
return rc;
error:
ssh_buffer_reinit(session->out_buffer);
session->session_state=SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
return SSH_ERROR;
}
#endif /* WITH_SERVER */

View File

@@ -1,689 +0,0 @@
/*
* dh-gex.c - diffie-hellman group exchange
*
* This file is part of the SSH Library
*
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.be>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "config.h"
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include "libssh/priv.h"
#include "libssh/dh-gex.h"
#include "libssh/libssh.h"
#include "libssh/ssh2.h"
#include "libssh/callbacks.h"
#include "libssh/dh.h"
#include "libssh/buffer.h"
#include "libssh/session.h"
/* Minimum, recommanded and maximum size of DH group */
#define DH_PMIN 2048
#define DH_PREQ 2048
#define DH_PMAX 8192
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group);
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply);
static ssh_packet_callback dhgex_client_callbacks[] = {
ssh_packet_client_dhgex_group, /* SSH_MSG_KEX_DH_GEX_GROUP */
NULL, /* SSH_MSG_KEX_DH_GEX_INIT */
ssh_packet_client_dhgex_reply /* SSH_MSG_KEX_DH_GEX_REPLY */
};
static struct ssh_packet_callbacks_struct ssh_dhgex_client_callbacks = {
.start = SSH2_MSG_KEX_DH_GEX_GROUP,
.n_callbacks = 3,
.callbacks = dhgex_client_callbacks,
.user = NULL
};
/** @internal
* @brief initiates a diffie-hellman-group-exchange kex
*/
int ssh_client_dhgex_init(ssh_session session)
{
int rc;
rc = ssh_dh_init_common(session->next_crypto);
if (rc != SSH_OK){
goto error;
}
session->next_crypto->dh_pmin = DH_PMIN;
session->next_crypto->dh_pn = DH_PREQ;
session->next_crypto->dh_pmax = DH_PMAX;
/* Minimum group size, preferred group size, maximum group size */
rc = ssh_buffer_pack(session->out_buffer,
"bddd",
SSH2_MSG_KEX_DH_GEX_REQUEST,
session->next_crypto->dh_pmin,
session->next_crypto->dh_pn,
session->next_crypto->dh_pmax);
if (rc != SSH_OK) {
goto error;
}
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_dhgex_client_callbacks);
session->dh_handshake_state = DH_STATE_REQUEST_SENT;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
return rc;
error:
ssh_dh_cleanup(session->next_crypto);
return SSH_ERROR;
}
/** @internal
* @brief handle a DH_GEX_GROUP packet, client side. This packet contains
* the group parameters.
*/
SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
{
int rc;
int blen;
bignum pmin1 = NULL, one = NULL;
bignum_CTX ctx = bignum_ctx_new();
bignum modulus = NULL, generator = NULL;
const_bignum pubkey;
(void) type;
(void) user;
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_GROUP received");
if (bignum_ctx_invalid(ctx)) {
goto error;
}
if (session->dh_handshake_state != DH_STATE_REQUEST_SENT) {
ssh_set_error(session,
SSH_FATAL,
"Received DH_GEX_GROUP in invalid state");
goto error;
}
one = bignum_new();
pmin1 = bignum_new();
if (one == NULL || pmin1 == NULL) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_buffer_unpack(packet,
"BB",
&modulus,
&generator);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_GROUP packet");
goto error;
}
/* basic checks */
if (ssh_fips_mode() &&
!ssh_dh_is_known_group(modulus, generator)) {
ssh_set_error(session,
SSH_FATAL,
"The received DH group is not FIPS approved");
goto error;
}
rc = bignum_set_word(one, 1);
if (rc != 1) {
goto error;
}
blen = bignum_num_bits(modulus);
if (blen < DH_PMIN || blen > DH_PMAX) {
ssh_set_error(session,
SSH_FATAL,
"Invalid dh group parameter p: %d not in [%d:%d]",
blen,
DH_PMIN,
DH_PMAX);
goto error;
}
if (bignum_cmp(modulus, one) <= 0) {
/* p must be positive and preferably bigger than one */
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
}
if (!bignum_is_bit_set(modulus, 0)) {
/* p must be a prime and therefore not divisible by 2 */
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
goto error;
}
bignum_sub(pmin1, modulus, one);
if (bignum_cmp(generator, one) <= 0 ||
bignum_cmp(generator, pmin1) > 0) {
/* generator must be at least 2 and smaller than p-1*/
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter g");
goto error;
}
bignum_ctx_free(ctx);
ctx = NULL;
/* all checks passed, set parameters (the BNs are copied in openssl backend) */
rc = ssh_dh_set_parameters(session->next_crypto->dh_ctx,
modulus, generator);
if (rc != SSH_OK) {
goto error;
}
#ifdef HAVE_LIBCRYPTO
bignum_safe_free(modulus);
bignum_safe_free(generator);
#endif
modulus = NULL;
generator = NULL;
/* compute and send DH public parameter */
rc = ssh_dh_keypair_gen_keys(session->next_crypto->dh_ctx,
DH_CLIENT_KEYPAIR);
if (rc == SSH_ERROR) {
goto error;
}
rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
DH_CLIENT_KEYPAIR, NULL, &pubkey);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_buffer_pack(session->out_buffer,
"bB",
SSH2_MSG_KEX_DH_GEX_INIT,
pubkey);
if (rc != SSH_OK) {
goto error;
}
session->dh_handshake_state = DH_STATE_INIT_SENT;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
bignum_safe_free(one);
bignum_safe_free(pmin1);
return SSH_PACKET_USED;
error:
bignum_safe_free(modulus);
bignum_safe_free(generator);
bignum_safe_free(one);
bignum_safe_free(pmin1);
if(!bignum_ctx_invalid(ctx)) {
bignum_ctx_free(ctx);
}
ssh_dh_cleanup(session->next_crypto);
session->session_state = SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
}
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
{
struct ssh_crypto_struct *crypto=session->next_crypto;
int rc;
ssh_string pubkey_blob = NULL;
bignum server_pubkey = NULL;
(void)type;
(void)user;
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_REPLY received");
ssh_packet_remove_callbacks(session, &ssh_dhgex_client_callbacks);
rc = ssh_buffer_unpack(packet,
"SBS",
&pubkey_blob, &server_pubkey,
&crypto->dh_server_signature);
if (rc == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_REPLY packet");
goto error;
}
rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
NULL, server_pubkey);
if (rc != SSH_OK) {
bignum_safe_free(server_pubkey);
goto error;
}
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
SSH_STRING_FREE(pubkey_blob);
if (rc != 0) {
goto error;
}
rc = ssh_dh_compute_shared_secret(session->next_crypto->dh_ctx,
DH_CLIENT_KEYPAIR, DH_SERVER_KEYPAIR,
&session->next_crypto->shared_secret);
ssh_dh_debug_crypto(session->next_crypto);
if (rc == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
goto error;
}
/* Send the MSG_NEWKEYS */
if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
goto error;
}
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
return SSH_PACKET_USED;
error:
ssh_dh_cleanup(session->next_crypto);
session->session_state = SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
}
#ifdef WITH_SERVER
#define MODULI_FILE "/etc/ssh/moduli"
/* 2 "Safe" prime; (p-1)/2 is also prime. */
#define SAFE_PRIME 2
/* 0x04 Probabilistic Miller-Rabin primality tests. */
#define PRIM_TEST_REQUIRED 0x04
/**
* @internal
*
* @brief Determines if the proposed modulus size is more appropriate than the
* current one.
*
* @returns 1 if it's more appropriate. Returns 0 if same or less appropriate
*/
static bool dhgroup_better_size(uint32_t pmin,
uint32_t pn,
uint32_t pmax,
size_t current_size,
size_t proposed_size)
{
if (current_size == proposed_size) {
return false;
}
if (current_size == pn) {
/* can't do better */
return false;
}
if (current_size == 0 && proposed_size >= pmin && proposed_size <= pmax) {
return true;
}
if (proposed_size < pmin || proposed_size > pmax) {
/* out of bounds */
return false;
}
if (current_size == 0) {
/* not in the allowed window */
return false;
}
if (proposed_size >= pn && proposed_size < current_size) {
return true;
}
if (proposed_size <= pn && proposed_size > current_size) {
return true;
}
if (proposed_size >= pn && current_size < pn) {
return true;
}
/* We're in the allowed window but a better match already exists. */
return false;
}
/** @internal
* @brief returns 1 with 1/n probability
* @returns 1 on with P(1/n), 0 with P(n-1/n).
*/
static bool invn_chance(int n)
{
uint32_t nounce = 0;
int ok;
ok = ssh_get_random(&nounce, sizeof(nounce), 0);
if (!ok) {
return false;
}
return (nounce % n) == 0;
}
/** @internal
* @brief retrieves a DH group from an open moduli file.
*/
static int ssh_retrieve_dhgroup_file(FILE *moduli,
uint32_t pmin,
uint32_t pn,
uint32_t pmax,
size_t *best_size,
char **best_generator,
char **best_modulus)
{
char timestamp[32] = {0};
char generator[32] = {0};
char modulus[4096] = {0};
size_t type, tests, tries, size, proposed_size;
int firstbyte;
int rc;
size_t line = 0;
size_t best_nlines = 0;
for(;;) {
line++;
firstbyte = getc(moduli);
if (firstbyte == '#'){
do {
firstbyte = getc(moduli);
} while(firstbyte != '\n' && firstbyte != EOF);
continue;
}
if (firstbyte == EOF) {
break;
}
ungetc(firstbyte, moduli);
rc = fscanf(moduli,
"%31s %zu %zu %zu %zu %31s %4095s\n",
timestamp,
&type,
&tests,
&tries,
&size,
generator,
modulus);
if (rc != 7){
if (rc == EOF) {
break;
}
SSH_LOG(SSH_LOG_INFO, "Invalid moduli entry line %zu", line);
do {
firstbyte = getc(moduli);
} while(firstbyte != '\n' && firstbyte != EOF);
continue;
}
/* we only want safe primes that were tested */
if (type != SAFE_PRIME || !(tests & PRIM_TEST_REQUIRED)) {
continue;
}
proposed_size = size + 1;
if (proposed_size != *best_size &&
dhgroup_better_size(pmin, pn, pmax, *best_size, proposed_size)) {
best_nlines = 0;
*best_size = proposed_size;
}
if (proposed_size == *best_size) {
best_nlines++;
}
/* Use reservoir sampling algorithm */
if (proposed_size == *best_size && invn_chance(best_nlines)) {
SAFE_FREE(*best_generator);
SAFE_FREE(*best_modulus);
*best_generator = strdup(generator);
if (*best_generator == NULL) {
return SSH_ERROR;
}
*best_modulus = strdup(modulus);
if (*best_modulus == NULL) {
SAFE_FREE(*best_generator);
return SSH_ERROR;
}
}
}
if (*best_size != 0) {
SSH_LOG(SSH_LOG_INFO,
"Selected %zu bits modulus out of %zu candidates in %zu lines",
*best_size,
best_nlines - 1,
line);
} else {
SSH_LOG(SSH_LOG_WARNING,
"No moduli found for [%u:%u:%u]",
pmin,
pn,
pmax);
}
return SSH_OK;
}
/** @internal
* @brief retrieves a DH group from the moduli file based on bits len parameters
* @param[in] pmin minimum group size in bits
* @param[in] pn preferred group size
* @param[in] pmax maximum group size
* @param[out] size size of the chosen modulus
* @param[out] p modulus
* @param[out] g generator
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
static int ssh_retrieve_dhgroup(uint32_t pmin,
uint32_t pn,
uint32_t pmax,
size_t *size,
bignum *p,
bignum *g)
{
FILE *moduli = NULL;
char *generator = NULL;
char *modulus = NULL;
int rc;
/* In FIPS mode, we can not negotiate arbitrary primes,
* but just the approved ones */
if (ssh_fips_mode()) {
SSH_LOG(SSH_LOG_TRACE, "In FIPS mode, using built-in primes");
return ssh_fallback_group(pmax, p, g);
}
moduli = fopen(MODULI_FILE, "r");
if (moduli == NULL) {
SSH_LOG(SSH_LOG_WARNING,
"Unable to open moduli file: %s",
strerror(errno));
return ssh_fallback_group(pmax, p, g);
}
*size = 0;
*p = NULL;
*g = NULL;
rc = ssh_retrieve_dhgroup_file(moduli,
pmin,
pn,
pmax,
size,
&generator,
&modulus);
fclose(moduli);
if (rc == SSH_ERROR || *size == 0) {
goto error;
}
rc = bignum_hex2bn(generator, g);
if (rc == 0) {
goto error;
}
rc = bignum_hex2bn(modulus, p);
if (rc == 0) {
goto error;
}
SAFE_FREE(generator);
SAFE_FREE(modulus);
return SSH_OK;
error:
bignum_safe_free(*g);
bignum_safe_free(*p);
SAFE_FREE(generator);
SAFE_FREE(modulus);
return SSH_ERROR;
}
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request);
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_init);
static ssh_packet_callback dhgex_server_callbacks[]= {
NULL, /* SSH_MSG_KEX_DH_GEX_REQUEST_OLD */
NULL, /* SSH_MSG_KEX_DH_GEX_GROUP */
ssh_packet_server_dhgex_init, /* SSH_MSG_KEX_DH_GEX_INIT */
NULL, /* SSH_MSG_KEX_DH_GEX_REPLY */
ssh_packet_server_dhgex_request /* SSH_MSG_GEX_DH_GEX_REQUEST */
};
static struct ssh_packet_callbacks_struct ssh_dhgex_server_callbacks = {
.start = SSH2_MSG_KEX_DH_GEX_REQUEST_OLD,
.n_callbacks = 5,
.callbacks = dhgex_server_callbacks,
.user = NULL
};
/** @internal
* @brief sets up the diffie-hellman-groupx kex callbacks
*/
void ssh_server_dhgex_init(ssh_session session){
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_dhgex_server_callbacks);
ssh_dh_init_common(session->next_crypto);
session->dh_handshake_state = DH_STATE_INIT;
}
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
{
bignum modulus = NULL, generator = NULL;
uint32_t pmin, pn, pmax;
size_t size = 0;
int rc;
(void) type;
(void) user;
if (session->dh_handshake_state != DH_STATE_INIT) {
ssh_set_error(session,
SSH_FATAL,
"Received DH_GEX_REQUEST in invalid state");
goto error;
}
/* Minimum group size, preferred group size, maximum group size */
rc = ssh_buffer_unpack(packet, "ddd", &pmin, &pn, &pmax);
if (rc != SSH_OK){
ssh_set_error_invalid(session);
goto error;
}
SSH_LOG(SSH_LOG_INFO, "dh-gex: DHGEX_REQUEST[%u:%u:%u]", pmin, pn, pmax);
if (pmin > pn || pn > pmax || pn > DH_PMAX || pmax < DH_PMIN) {
ssh_set_error(session,
SSH_FATAL,
"Invalid dh-gex arguments [%u:%u:%u]",
pmin,
pn,
pmax);
goto error;
}
session->next_crypto->dh_pmin = pmin;
session->next_crypto->dh_pn = pn;
session->next_crypto->dh_pmax = pmax;
/* ensure safe parameters */
if (pmin < DH_PMIN) {
pmin = DH_PMIN;
if (pn < pmin) {
pn = pmin;
}
}
rc = ssh_retrieve_dhgroup(pmin,
pn,
pmax,
&size,
&modulus,
&generator);
if (rc == SSH_ERROR) {
ssh_set_error(session,
SSH_FATAL,
"Couldn't find DH group for [%u:%u:%u]",
pmin,
pn,
pmax);
goto error;
}
rc = ssh_dh_set_parameters(session->next_crypto->dh_ctx,
modulus, generator);
if (rc != SSH_OK) {
bignum_safe_free(generator);
bignum_safe_free(modulus);
goto error;
}
rc = ssh_buffer_pack(session->out_buffer,
"bBB",
SSH2_MSG_KEX_DH_GEX_GROUP,
modulus,
generator);
#ifdef HAVE_LIBCRYPTO
bignum_safe_free(generator);
bignum_safe_free(modulus);
#endif
if (rc != SSH_OK) {
ssh_set_error_invalid(session);
goto error;
}
session->dh_handshake_state = DH_STATE_GROUP_SENT;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
error:
return SSH_PACKET_USED;
}
/** @internal
* @brief parse an incoming SSH_MSG_KEX_DH_GEX_INIT packet and complete
* Diffie-Hellman key exchange
**/
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_init){
(void) type;
(void) user;
SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_KEX_DHGEX_INIT");
ssh_packet_remove_callbacks(session, &ssh_dhgex_server_callbacks);
ssh_server_dh_process_init(session, packet);
return SSH_PACKET_USED;
}
#endif /* WITH_SERVER */

1501
src/dh.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,287 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2019 by Simo Sorce - Red Hat, Inc.
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "config.h"
#include "libssh/session.h"
#include "libssh/dh.h"
#include "libssh/buffer.h"
#include "libssh/ssh2.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
#include "openssl/crypto.h"
#include "openssl/dh.h"
#include "libcrypto-compat.h"
extern bignum ssh_dh_generator;
extern bignum ssh_dh_group1;
extern bignum ssh_dh_group14;
extern bignum ssh_dh_group16;
extern bignum ssh_dh_group18;
struct dh_ctx {
DH *keypair[2];
};
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c)
{
#ifdef DEBUG_CRYPTO
const_bignum x = NULL, y = NULL, e = NULL, f = NULL;
ssh_dh_keypair_get_keys(c->dh_ctx, DH_CLIENT_KEYPAIR, &x, &e);
ssh_dh_keypair_get_keys(c->dh_ctx, DH_SERVER_KEYPAIR, &y, &f);
ssh_print_bignum("x", x);
ssh_print_bignum("y", y);
ssh_print_bignum("e", e);
ssh_print_bignum("f", f);
ssh_log_hexdump("Session server cookie", c->server_kex.cookie, 16);
ssh_log_hexdump("Session client cookie", c->client_kex.cookie, 16);
ssh_print_bignum("k", c->shared_secret);
#else
(void)c; /* UNUSED_PARAM */
#endif
}
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
const_bignum *priv, const_bignum *pub)
{
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
((priv == NULL) && (pub == NULL)) || (ctx == NULL) ||
(ctx->keypair[peer] == NULL)) {
return SSH_ERROR;
}
DH_get0_key(ctx->keypair[peer], pub, priv);
if (priv && (*priv == NULL || bignum_num_bits(*priv) == 0)) {
return SSH_ERROR;
}
if (pub && (*pub == NULL || bignum_num_bits(*pub) == 0)) {
return SSH_ERROR;
}
return SSH_OK;
}
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
const bignum priv, const bignum pub)
{
bignum priv_key = NULL;
bignum pub_key = NULL;
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
((priv == NULL) && (pub == NULL)) || (ctx == NULL) ||
(ctx->keypair[peer] == NULL)) {
return SSH_ERROR;
}
if (priv) {
priv_key = priv;
}
if (pub) {
pub_key = pub;
}
(void)DH_set0_key(ctx->keypair[peer], pub_key, priv_key);
return SSH_OK;
}
int ssh_dh_get_parameters(struct dh_ctx *ctx,
const_bignum *modulus, const_bignum *generator)
{
if (ctx == NULL || ctx->keypair[0] == NULL) {
return SSH_ERROR;
}
DH_get0_pqg(ctx->keypair[0], modulus, NULL, generator);
return SSH_OK;
}
int ssh_dh_set_parameters(struct dh_ctx *ctx,
const bignum modulus, const bignum generator)
{
size_t i;
int rc;
if ((ctx == NULL) || (modulus == NULL) || (generator == NULL)) {
return SSH_ERROR;
}
for (i = 0; i < 2; i++) {
bignum p = NULL;
bignum g = NULL;
/* when setting modulus or generator,
* make sure to invalidate existing keys */
DH_free(ctx->keypair[i]);
ctx->keypair[i] = DH_new();
if (ctx->keypair[i] == NULL) {
rc = SSH_ERROR;
goto done;
}
p = BN_dup(modulus);
g = BN_dup(generator);
rc = DH_set0_pqg(ctx->keypair[i], p, NULL, g);
if (rc != 1) {
BN_free(p);
BN_free(g);
rc = SSH_ERROR;
goto done;
}
}
rc = SSH_OK;
done:
if (rc != SSH_OK) {
DH_free(ctx->keypair[0]);
DH_free(ctx->keypair[1]);
ctx->keypair[0] = NULL;
ctx->keypair[1] = NULL;
}
return rc;
}
/**
* @internal
* @brief allocate and initialize ephemeral values used in dh kex
*/
int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
{
struct dh_ctx *ctx;
int rc;
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return SSH_ERROR;
}
crypto->dh_ctx = ctx;
switch (crypto->kex_type) {
case SSH_KEX_DH_GROUP1_SHA1:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group1, ssh_dh_generator);
break;
case SSH_KEX_DH_GROUP14_SHA1:
case SSH_KEX_DH_GROUP14_SHA256:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group14, ssh_dh_generator);
break;
case SSH_KEX_DH_GROUP16_SHA512:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group16, ssh_dh_generator);
break;
case SSH_KEX_DH_GROUP18_SHA512:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group18, ssh_dh_generator);
break;
default:
rc = SSH_OK;
break;
}
if (rc != SSH_OK) {
ssh_dh_cleanup(crypto);
}
return rc;
}
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto)
{
if (crypto->dh_ctx != NULL) {
DH_free(crypto->dh_ctx->keypair[0]);
DH_free(crypto->dh_ctx->keypair[1]);
free(crypto->dh_ctx);
crypto->dh_ctx = NULL;
}
}
/** @internal
* @brief generates a secret DH parameter of at least DH_SECURITY_BITS
* security as well as the corresponding public key.
* @param[out] parms a dh_ctx that will hold the new keys.
* @param peer Select either client or server key storage. Valid values are:
* DH_CLIENT_KEYPAIR or DH_SERVER_KEYPAIR
*
* @return SSH_OK on success, SSH_ERROR on error
*/
int ssh_dh_keypair_gen_keys(struct dh_ctx *dh_ctx, int peer)
{
int rc;
if ((dh_ctx == NULL) || (dh_ctx->keypair[peer] == NULL)) {
return SSH_ERROR;
}
rc = DH_generate_key(dh_ctx->keypair[peer]);
if (rc != 1) {
return SSH_ERROR;
}
return SSH_OK;
}
/** @internal
* @brief generates a shared secret between the local peer and the remote
* peer. The local peer must have been initialized using either the
* ssh_dh_keypair_gen_keys() function or by seetting manually both
* the private and public keys. The remote peer only needs to have
* the remote's peer public key set.
* @param[in] local peer identifier (DH_CLIENT_KEYPAIR or DH_SERVER_KEYPAIR)
* @param[in] remote peer identifier (DH_CLIENT_KEYPAIR or DH_SERVER_KEYPAIR)
* @param[out] dest a new bignum with the shared secret value is returned.
* @return SSH_OK on success, SSH_ERROR on error
*/
int ssh_dh_compute_shared_secret(struct dh_ctx *dh_ctx, int local, int remote,
bignum *dest)
{
unsigned char *kstring = NULL;
const_bignum pub_key = NULL;
int klen, rc;
if ((dh_ctx == NULL) ||
(dh_ctx->keypair[local] == NULL) ||
(dh_ctx->keypair[remote] == NULL)) {
return SSH_ERROR;
}
kstring = malloc(DH_size(dh_ctx->keypair[local]));
if (kstring == NULL) {
rc = SSH_ERROR;
goto done;
}
rc = ssh_dh_keypair_get_keys(dh_ctx, remote, NULL, &pub_key);
if (rc != SSH_OK) {
rc = SSH_ERROR;
goto done;
}
klen = DH_compute_key(kstring, pub_key, dh_ctx->keypair[local]);
if (klen == -1) {
rc = SSH_ERROR;
goto done;
}
*dest = BN_bin2bn(kstring, klen, NULL);
if (*dest == NULL) {
rc = SSH_ERROR;
goto done;
}
rc = SSH_OK;
done:
free(kstring);
return rc;
}

View File

@@ -1,376 +0,0 @@
/*
* dh-int.c - Diffie-Helman algorithm code against SSH 2
*
* This file is part of the SSH Library
*
* Copyright (c) 2003-2018 by Aris Adamantiadis
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2012 by Dmitriy Kuznetsov <dk@yandex.ru>
* Copyright (c) 2019 by Simo Sorce <simo@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "config.h"
#include "libssh/priv.h"
#include "libssh/crypto.h"
#include "libssh/buffer.h"
#include "libssh/session.h"
#include "libssh/misc.h"
#include "libssh/dh.h"
#include "libssh/ssh2.h"
#include "libssh/pki.h"
#include "libssh/bignum.h"
extern bignum ssh_dh_generator;
extern bignum ssh_dh_group1;
extern bignum ssh_dh_group14;
extern bignum ssh_dh_group16;
extern bignum ssh_dh_group18;
/*
* How many bits of security we want for fast DH. DH private key size must be
* twice that size.
*/
#define DH_SECURITY_BITS 512
struct dh_keypair {
bignum priv_key;
bignum pub_key;
};
struct dh_ctx {
/* 0 is client, 1 is server */
struct dh_keypair keypair[2];
bignum generator;
bignum modulus;
};
void ssh_dh_debug_crypto(struct ssh_crypto_struct *c)
{
#ifdef DEBUG_CRYPTO
const_bignum x = NULL, y = NULL, e = NULL, f = NULL;
ssh_dh_keypair_get_keys(c->dh_ctx, DH_CLIENT_KEYPAIR, &x, &e);
ssh_dh_keypair_get_keys(c->dh_ctx, DH_SERVER_KEYPAIR, &y, &f);
ssh_print_bignum("p", c->dh_ctx->modulus);
ssh_print_bignum("g", c->dh_ctx->generator);
ssh_print_bignum("x", x);
ssh_print_bignum("y", y);
ssh_print_bignum("e", e);
ssh_print_bignum("f", f);
ssh_log_hexdump("Session server cookie", c->server_kex.cookie, 16);
ssh_log_hexdump("Session client cookie", c->client_kex.cookie, 16);
ssh_print_bignum("k", c->shared_secret);
#else
(void)c; /* UNUSED_PARAM */
#endif
}
static void ssh_dh_free_modulus(struct dh_ctx *ctx)
{
if ((ctx->modulus != ssh_dh_group1) &&
(ctx->modulus != ssh_dh_group14) &&
(ctx->modulus != ssh_dh_group16) &&
(ctx->modulus != ssh_dh_group18)) {
bignum_safe_free(ctx->modulus);
}
ctx->modulus = NULL;
}
static void ssh_dh_free_generator(struct dh_ctx *ctx)
{
if (ctx->generator != ssh_dh_generator) {
bignum_safe_free(ctx->generator);
}
}
static void ssh_dh_free_dh_keypair(struct dh_keypair *keypair)
{
bignum_safe_free(keypair->priv_key);
bignum_safe_free(keypair->pub_key);
}
static int ssh_dh_init_dh_keypair(struct dh_keypair *keypair)
{
int rc;
keypair->priv_key = bignum_new();
if (keypair->priv_key == NULL) {
rc = SSH_ERROR;
goto done;
}
keypair->pub_key = bignum_new();
if (keypair->pub_key == NULL) {
rc = SSH_ERROR;
goto done;
}
rc = SSH_OK;
done:
if (rc != SSH_OK) {
ssh_dh_free_dh_keypair(keypair);
}
return rc;
}
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
const_bignum *priv, const_bignum *pub)
{
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
((priv == NULL) && (pub == NULL)) || (ctx == NULL)) {
return SSH_ERROR;
}
if (priv) {
/* check that we have something in it */
if (bignum_num_bits(ctx->keypair[peer].priv_key)) {
*priv = ctx->keypair[peer].priv_key;
} else {
return SSH_ERROR;
}
}
if (pub) {
/* check that we have something in it */
if (bignum_num_bits(ctx->keypair[peer].pub_key)) {
*pub = ctx->keypair[peer].pub_key;
} else {
return SSH_ERROR;
}
}
return SSH_OK;
}
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
bignum priv, bignum pub)
{
if (((peer != DH_CLIENT_KEYPAIR) && (peer != DH_SERVER_KEYPAIR)) ||
((priv == NULL) && (pub == NULL)) || (ctx == NULL)) {
return SSH_ERROR;
}
if (priv) {
bignum_safe_free(ctx->keypair[peer].priv_key);
ctx->keypair[peer].priv_key = priv;
}
if (pub) {
bignum_safe_free(ctx->keypair[peer].pub_key);
ctx->keypair[peer].pub_key = pub;
}
return SSH_OK;
}
int ssh_dh_get_parameters(struct dh_ctx *ctx,
const_bignum *modulus, const_bignum *generator)
{
if (ctx == NULL) {
return SSH_ERROR;
}
if (modulus) {
*modulus = ctx->modulus;
}
if (generator) {
*generator = ctx->generator;
}
return SSH_OK;
}
int ssh_dh_set_parameters(struct dh_ctx *ctx,
bignum modulus, bignum generator)
{
int rc;
if ((ctx == NULL) || ((modulus == NULL) && (generator == NULL))) {
return SSH_ERROR;
}
/* when setting modulus or generator,
* make sure to invalidate existing keys */
ssh_dh_free_dh_keypair(&ctx->keypair[DH_CLIENT_KEYPAIR]);
ssh_dh_free_dh_keypair(&ctx->keypair[DH_SERVER_KEYPAIR]);
rc = ssh_dh_init_dh_keypair(&ctx->keypair[DH_CLIENT_KEYPAIR]);
if (rc != SSH_OK) {
goto done;
}
rc = ssh_dh_init_dh_keypair(&ctx->keypair[DH_SERVER_KEYPAIR]);
if (rc != SSH_OK) {
goto done;
}
if (modulus) {
ssh_dh_free_modulus(ctx);
ctx->modulus = modulus;
}
if (generator) {
ssh_dh_free_generator(ctx);
ctx->generator = generator;
}
done:
return rc;
}
/**
* @internal
* @brief allocate and initialize ephemeral values used in dh kex
*/
int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
{
struct dh_ctx *ctx = NULL;
int rc;
ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return SSH_ERROR;
}
switch (crypto->kex_type) {
case SSH_KEX_DH_GROUP1_SHA1:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group1, ssh_dh_generator);
break;
case SSH_KEX_DH_GROUP14_SHA1:
case SSH_KEX_DH_GROUP14_SHA256:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group14, ssh_dh_generator);
break;
case SSH_KEX_DH_GROUP16_SHA512:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group16, ssh_dh_generator);
break;
case SSH_KEX_DH_GROUP18_SHA512:
rc = ssh_dh_set_parameters(ctx, ssh_dh_group18, ssh_dh_generator);
break;
default:
rc = SSH_OK;
break;
}
crypto->dh_ctx = ctx;
if (rc != SSH_OK) {
ssh_dh_cleanup(crypto);
}
return rc;
}
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto)
{
struct dh_ctx *ctx = crypto->dh_ctx;
if (ctx == NULL) {
return;
}
ssh_dh_free_dh_keypair(&ctx->keypair[DH_CLIENT_KEYPAIR]);
ssh_dh_free_dh_keypair(&ctx->keypair[DH_SERVER_KEYPAIR]);
ssh_dh_free_modulus(ctx);
ssh_dh_free_generator(ctx);
free(ctx);
crypto->dh_ctx = NULL;
}
/** @internal
* @brief generates a secret DH parameter of at least DH_SECURITY_BITS
* security as well as the corresponding public key.
* @param[out] parms a dh_kex paramters structure with preallocated bignum
* where to store the parameters
* @return SSH_OK on success, SSH_ERROR on error
*/
int ssh_dh_keypair_gen_keys(struct dh_ctx *dh_ctx, int peer)
{
bignum tmp = NULL;
bignum_CTX ctx = NULL;
int rc = 0;
int bits = 0;
int p_bits = 0;
ctx = bignum_ctx_new();
if (bignum_ctx_invalid(ctx)){
goto error;
}
tmp = bignum_new();
if (tmp == NULL) {
goto error;
}
p_bits = bignum_num_bits(dh_ctx->modulus);
/* we need at most DH_SECURITY_BITS */
bits = MIN(DH_SECURITY_BITS * 2, p_bits);
/* ensure we're not too close of p so rnd()%p stays uniform */
if (bits <= p_bits && bits + 64 > p_bits) {
bits += 64;
}
rc = bignum_rand(tmp, bits);
if (rc != 1) {
goto error;
}
rc = bignum_mod(dh_ctx->keypair[peer].priv_key, tmp, dh_ctx->modulus, ctx);
if (rc != 1) {
goto error;
}
/* Now compute the corresponding public key */
rc = bignum_mod_exp(dh_ctx->keypair[peer].pub_key, dh_ctx->generator,
dh_ctx->keypair[peer].priv_key, dh_ctx->modulus, ctx);
if (rc != 1) {
goto error;
}
bignum_safe_free(tmp);
bignum_ctx_free(ctx);
return SSH_OK;
error:
bignum_safe_free(tmp);
bignum_ctx_free(ctx);
return SSH_ERROR;
}
/** @internal
* @brief generates a shared secret between the local peer and the remote peer
* @param[in] local peer identifier
* @param[in] remote peer identifier
* @param[out] dest a preallocated bignum where to store parameter
* @return SSH_OK on success, SSH_ERROR on error
*/
int ssh_dh_compute_shared_secret(struct dh_ctx *dh_ctx, int local, int remote,
bignum *dest)
{
int rc;
bignum_CTX ctx = bignum_ctx_new();
if (bignum_ctx_invalid(ctx)) {
return -1;
}
if (*dest == NULL) {
*dest = bignum_new();
if (*dest == NULL) {
rc = 0;
goto done;
}
}
rc = bignum_mod_exp(*dest, dh_ctx->keypair[remote].pub_key,
dh_ctx->keypair[local].priv_key,
dh_ctx->modulus, ctx);
done:
bignum_ctx_free(ctx);
if (rc != 1) {
return SSH_ERROR;
}
return SSH_OK;
}

View File

@@ -30,32 +30,16 @@
#ifdef HAVE_ECDH
static SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply);
static ssh_packet_callback ecdh_client_callbacks[]= {
ssh_packet_client_ecdh_reply
};
struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks = {
.start = SSH2_MSG_KEX_ECDH_REPLY,
.n_callbacks = 1,
.callbacks = ecdh_client_callbacks,
.user = NULL
};
/** @internal
* @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
* a SSH_MSG_NEWKEYS
*/
SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){
int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet){
ssh_string q_s_string = NULL;
ssh_string pubkey_blob = NULL;
ssh_string signature = NULL;
int rc;
(void)type;
(void)user;
ssh_packet_remove_callbacks(session, &ssh_ecdh_client_callbacks);
pubkey_blob = ssh_buffer_get_ssh_string(packet);
if (pubkey_blob == NULL) {
ssh_set_error(session,SSH_FATAL, "No public key in packet");
@@ -63,7 +47,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){
}
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
SSH_STRING_FREE(pubkey_blob);
ssh_string_free(pubkey_blob);
if (rc != 0) {
goto error;
}
@@ -93,39 +77,10 @@ SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){
}
rc=ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
return SSH_PACKET_USED;
return rc;
error:
session->session_state=SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
return SSH_ERROR;
}
#ifdef WITH_SERVER
static ssh_packet_callback ecdh_server_callbacks[] = {
ssh_packet_server_ecdh_init
};
struct ssh_packet_callbacks_struct ssh_ecdh_server_callbacks = {
.start = SSH2_MSG_KEX_ECDH_INIT,
.n_callbacks = 1,
.callbacks = ecdh_server_callbacks,
.user = NULL
};
/** @internal
* @brief sets up the ecdh kex callbacks
*/
void ssh_server_ecdh_init(ssh_session session){
ssh_packet_set_callbacks(session, &ssh_ecdh_server_callbacks);
}
#endif /* WITH_SERVER */
#endif /* HAVE_ECDH */

View File

@@ -101,17 +101,13 @@ int ssh_client_ecdh_init(ssh_session session){
rc = ssh_buffer_add_ssh_string(session->out_buffer,client_pubkey);
if (rc < 0) {
EC_KEY_free(key);
SSH_STRING_FREE(client_pubkey);
ssh_string_free(client_pubkey);
return SSH_ERROR;
}
session->next_crypto->ecdh_privkey = key;
session->next_crypto->ecdh_client_pubkey = client_pubkey;
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
session->dh_handshake_state = DH_STATE_INIT_SENT;
rc = ssh_packet_send(session);
return rc;
@@ -128,6 +124,12 @@ int ecdh_build_k(ssh_session session) {
return -1;
}
session->next_crypto->k = bignum_new();
if (session->next_crypto->k == NULL) {
bignum_ctx_free(ctx);
return -1;
}
pubkey = EC_POINT_new(group);
if (pubkey == NULL) {
bignum_ctx_free(ctx);
@@ -170,22 +172,18 @@ int ecdh_build_k(ssh_session session) {
return -1;
}
bignum_bin2bn(buffer, len, &session->next_crypto->shared_secret);
bignum_bin2bn(buffer, len, session->next_crypto->k);
free(buffer);
if (session->next_crypto->shared_secret == NULL) {
EC_KEY_free(session->next_crypto->ecdh_privkey);
session->next_crypto->ecdh_privkey = NULL;
return -1;
}
EC_KEY_free(session->next_crypto->ecdh_privkey);
session->next_crypto->ecdh_privkey = NULL;
#ifdef DEBUG_CRYPTO
ssh_log_hexdump("Session server cookie",
ssh_print_hexa("Session server cookie",
session->next_crypto->server_kex.cookie, 16);
ssh_log_hexdump("Session client cookie",
ssh_print_hexa("Session client cookie",
session->next_crypto->client_kex.cookie, 16);
ssh_print_bignum("Shared secret key", session->next_crypto->shared_secret);
ssh_print_bignum("Shared secret key", session->next_crypto->k);
#endif
return 0;
@@ -193,10 +191,11 @@ int ecdh_build_k(ssh_session session) {
#ifdef WITH_SERVER
/** @brief Handle a SSH_MSG_KEXDH_INIT packet (server) and send a
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
* SSH_MSG_KEXDH_REPLY
*/
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
/* ECDH keys */
ssh_string q_c_string;
ssh_string q_s_string;
@@ -206,21 +205,17 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
bignum_CTX ctx;
/* SSH host keys (rsa,dsa,ecdsa) */
ssh_key privkey;
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
ssh_string sig_blob = NULL;
ssh_string pubkey_blob = NULL;
int curve;
int len;
int rc;
(void)type;
(void)user;
ssh_packet_remove_callbacks(session, &ssh_ecdh_server_callbacks);
/* Extract the client pubkey from the init packet */
q_c_string = ssh_buffer_get_ssh_string(packet);
if (q_c_string == NULL) {
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
goto error;
return SSH_ERROR;
}
session->next_crypto->ecdh_client_pubkey = q_c_string;
@@ -238,7 +233,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
if (ecdh_key == NULL) {
ssh_set_error_oom(session);
BN_CTX_free(ctx);
goto error;
return SSH_ERROR;
}
group = EC_KEY_get0_group(ecdh_key);
@@ -256,7 +251,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
if (q_s_string == NULL) {
EC_KEY_free(ecdh_key);
BN_CTX_free(ctx);
goto error;
return SSH_ERROR;
}
EC_POINT_point2oct(group,
@@ -274,31 +269,31 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
rc = ecdh_build_k(session);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
goto error;
return SSH_ERROR;
}
/* privkey is not allocated */
rc = ssh_get_key_params(session, &privkey, &digest);
rc = ssh_get_key_params(session, &privkey);
if (rc == SSH_ERROR) {
goto error;
return SSH_ERROR;
}
rc = ssh_make_sessionid(session);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
goto error;
return SSH_ERROR;
}
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
if (sig_blob == NULL) {
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
goto error;
return SSH_ERROR;
}
rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Could not export server public key");
SSH_STRING_FREE(sig_blob);
ssh_string_free(sig_blob);
return SSH_ERROR;
}
@@ -309,38 +304,31 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
q_s_string, /* ecdh public key */
sig_blob); /* signature blob */
SSH_STRING_FREE(sig_blob);
SSH_STRING_FREE(pubkey_blob);
ssh_string_free(sig_blob);
ssh_string_free(pubkey_blob);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
return SSH_ERROR;
}
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent");
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
return SSH_ERROR;
}
/* Send the MSG_NEWKEYS */
rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
if (rc < 0) {
goto error;
return SSH_ERROR;;
}
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR){
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
return SSH_PACKET_USED;
error:
ssh_buffer_reinit(session->out_buffer);
session->session_state = SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
return rc;
}
#endif /* WITH_SERVER */

Some files were not shown because too many files have changed in this diff Show More