Compare commits
63 Commits
libssh2-1.
...
libssh2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cbd5f72339 | ||
![]() |
858930cae5 | ||
![]() |
08fa27b628 | ||
![]() |
4383a39d83 | ||
![]() |
09c5e59933 | ||
![]() |
5a88a86fef | ||
![]() |
0340d4586e | ||
![]() |
2d2744efdd | ||
![]() |
e113202098 | ||
![]() |
983ceafe58 | ||
![]() |
e160ba448e | ||
![]() |
b8289b625e | ||
![]() |
5f4c249e42 | ||
![]() |
6f95c2efd3 | ||
![]() |
31a5986c6d | ||
![]() |
22bd8d81d8 | ||
![]() |
3d3347c062 | ||
![]() |
2d59b41daa | ||
![]() |
1e7988cb0d | ||
![]() |
b99204f289 | ||
![]() |
7ca44fbd94 | ||
![]() |
41b1cb6751 | ||
![]() |
84590bc78f | ||
![]() |
864950cf16 | ||
![]() |
09a559433e | ||
![]() |
57dea4df6d | ||
![]() |
77020c7961 | ||
![]() |
e52f35d9f4 | ||
![]() |
a8d14c5dcf | ||
![]() |
0c90b8bd9b | ||
![]() |
3fc17cd69f | ||
![]() |
aa4e649d94 | ||
![]() |
49ea2be885 | ||
![]() |
247dfce5fb | ||
![]() |
71d45d3df1 | ||
![]() |
daa2dfa2db | ||
![]() |
1429ad749d | ||
![]() |
4078da8d81 | ||
![]() |
0930928810 | ||
![]() |
55d030089b | ||
![]() |
260410edf3 | ||
![]() |
1de36eb5b4 | ||
![]() |
aa7f9a85f7 | ||
![]() |
41d22ccf26 | ||
![]() |
56f7c0e2a4 | ||
![]() |
1329dc5155 | ||
![]() |
a1e744bb5e | ||
![]() |
14d9ee01bc | ||
![]() |
fed47c34e4 | ||
![]() |
18cfec8336 | ||
![]() |
74624c8ddf | ||
![]() |
bbbdf946a7 | ||
![]() |
042993b8eb | ||
![]() |
41ed2b71a2 | ||
![]() |
6bf8983368 | ||
![]() |
523a552258 | ||
![]() |
d73e0ec260 | ||
![]() |
1fa5fe6059 | ||
![]() |
8f00a7471d | ||
![]() |
fe3e23022b | ||
![]() |
33e1013d7b | ||
![]() |
20eb836f4e | ||
![]() |
6ada234c62 |
75
.travis.yml
Normal file
75
.travis.yml
Normal file
@@ -0,0 +1,75 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON
|
||||
- ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository --yes ppa:kalakris/cmake
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y install cmake
|
||||
- if [ $ADDRESS_SIZE = '64' ]; then sudo apt-get install -y libgcrypt11-dev libssl-dev zlib1g-dev; fi
|
||||
- if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get install -y linux-libc-dev linux-libc-dev:i386; fi
|
||||
- if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get install -y gcc-multilib libgcrypt11-dev:i386 libssl-dev:i386 zlib1g-dev:i386; fi
|
||||
- if [ $ADDRESS_SIZE = '32' ]; then export TOOLCHAIN_OPTION="-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-Linux-32.cmake"; fi
|
||||
|
||||
install:
|
||||
- mkdir bin
|
||||
- cd bin
|
||||
|
||||
script:
|
||||
- cmake $TOOLCHAIN_OPTION -DCRYPTO_BACKEND=$CRYPTO_BACKEND -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS -DENABLE_ZLIB_COMPRESSION=$ENABLE_ZLIB_COMPRESSION .. && cmake --build . && CTEST_OUTPUT_ON_FAILURE=1 cmake --build . --target test && cmake --build . --target package
|
101
CMakeLists.txt
Normal file
101
CMakeLists.txt
Normal file
@@ -0,0 +1,101 @@
|
||||
# Copyright (c) 2014, 2015 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
project(libssh2 C)
|
||||
set(PROJECT_URL "http://www.libssh2.org/")
|
||||
set(PROJECT_DESCRIPTION "The SSH library")
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
||||
|
||||
# Parse version
|
||||
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/include/libssh2.h _HEADER_CONTENTS)
|
||||
string(
|
||||
REGEX REPLACE ".*#define LIBSSH2_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
|
||||
LIBSSH2_VERSION "${_HEADER_CONTENTS}")
|
||||
string(
|
||||
REGEX REPLACE ".*#define LIBSSH2_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1"
|
||||
LIBSSH2_VERSION_MAJOR "${_HEADER_CONTENTS}")
|
||||
string(
|
||||
REGEX REPLACE ".*#define LIBSSH2_VERSION_MINOR[ \t]+([0-9]+).*" "\\1"
|
||||
LIBSSH2_VERSION_MINOR "${_HEADER_CONTENTS}")
|
||||
string(
|
||||
REGEX REPLACE ".*#define LIBSSH2_VERSION_PATCH[ \t]+([0-9]+).*" "\\1"
|
||||
LIBSSH2_VERSION_PATCH "${_HEADER_CONTENTS}")
|
||||
|
||||
if(NOT LIBSSH2_VERSION OR
|
||||
NOT LIBSSH2_VERSION_MAJOR MATCHES "^[0-9]+$" OR
|
||||
NOT LIBSSH2_VERSION_MINOR MATCHES "^[0-9]+$" OR
|
||||
NOT LIBSSH2_VERSION_PATCH MATCHES "^[0-9]+$")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Unable to parse version from"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/libssh2.h")
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(
|
||||
FILES docs/AUTHORS COPYING docs/HACKING README RELEASE-NOTES NEWS
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
|
||||
include(max_warnings)
|
||||
include(FeatureSummary)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
option(BUILD_EXAMPLES "Build libssh2 examples" ON)
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory(example)
|
||||
endif()
|
||||
|
||||
option(BUILD_TESTING "Build libssh2 test suite" ON)
|
||||
if(BUILD_TESTING)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
add_subdirectory(docs)
|
||||
|
||||
feature_summary(WHAT ALL)
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${LIBSSH2_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${LIBSSH2_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${LIBSSH2_VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_VERSION ${LIBSSH2_VERSION})
|
||||
include(CPack)
|
8
README
8
README
@@ -10,8 +10,10 @@ Mailing list: http://cool.haxx.se/mailman/listinfo/libssh2-devel
|
||||
|
||||
License: see COPYING
|
||||
|
||||
Source code: https://github.com/bagder/libssh2
|
||||
Source code: https://github.com/libssh2/libssh2
|
||||
|
||||
Web site source code: https://github.com/bagder/libssh2-www
|
||||
Web site source code: https://github.com/libssh2/www
|
||||
|
||||
Installation instructions are in docs/INSTALL
|
||||
Installation instructions are in:
|
||||
- docs/INSTALL_CMAKE for CMake
|
||||
- docs/INSTALL_AUTOTOOLS for Autotools
|
||||
|
106
RELEASE-NOTES
106
RELEASE-NOTES
@@ -1,83 +1,45 @@
|
||||
libssh2 1.5.0
|
||||
libssh2 1.6.0
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added Windows Cryptography API: Next Generation based backend
|
||||
o Added CMake build system
|
||||
o Added libssh2_userauth_publickey_frommemory()
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o Security Advisory for CVE-2015-1782, using SSH_MSG_KEXINIT data unbounded
|
||||
o missing _libssh2_error in _libssh2_channel_write
|
||||
o knownhost: Fix DSS keys being detected as unknown.
|
||||
o knownhost: Restore behaviour of `libssh2_knownhost_writeline` with short buffer.
|
||||
o libssh2.h: on Windows, a socket is of type SOCKET, not int
|
||||
o libssh2_priv.h: a 1 bit bit-field should be unsigned
|
||||
o windows build: do not export externals from static library
|
||||
o Fixed two potential use-after-frees of the payload buffer
|
||||
o Fixed a few memory leaks in error paths
|
||||
o userauth: Fixed an attempt to free from stack on error
|
||||
o agent_list_identities: Fixed memory leak on OOM
|
||||
o knownhosts: Abort if the hosts buffer is too small
|
||||
o sftp_close_handle: ensure the handle is always closed
|
||||
o channel_close: Close the channel even in the case of errors
|
||||
o docs: added missing libssh2_session_handshake.3 file
|
||||
o docs: fixed a bunch of typos
|
||||
o userauth_password: pass on the underlying error code
|
||||
o _libssh2_channel_forward_cancel: accessed struct after free
|
||||
o _libssh2_packet_add: avoid using uninitialized memory
|
||||
o _libssh2_channel_forward_cancel: avoid memory leaks on error
|
||||
o _libssh2_channel_write: client spins on write when window full
|
||||
o windows build: fix build errors
|
||||
o publickey_packet_receive: avoid junk in returned pointers
|
||||
o channel_receive_window_adjust: store windows size always
|
||||
o userauth_hostbased_fromfile: zero assign to avoid uninitialized use
|
||||
o configure: change LIBS not LDFLAGS when checking for libs
|
||||
o agent_connect_unix: make sure there's a trailing zero
|
||||
o MinGW build: Fixed redefine warnings.
|
||||
o sftpdir.c: added authentication method detection.
|
||||
o Watcom build: added support for WinCNG build.
|
||||
o configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS
|
||||
o sftp_statvfs: fix for servers not supporting statfvs extension
|
||||
o knownhost.c: use LIBSSH2_FREE macro instead of free
|
||||
o Fixed compilation using mingw-w64
|
||||
o knownhost.c: fixed that 'key_type_len' may be used uninitialized
|
||||
o configure: Display individual crypto backends on separate lines
|
||||
o examples on Windows: check for WSAStartup return code
|
||||
o examples on Windows: check for socket return code
|
||||
o agent.c: check return code of MapViewOfFile
|
||||
o kex.c: fix possible NULL pointer de-reference with session->kex
|
||||
o packet.c: fix possible NULL pointer de-reference within listen_state
|
||||
o tests on Windows: check for WSAStartup return code
|
||||
o userauth.c: improve readability and clarity of for-loops
|
||||
o examples on Windows: use native SOCKET-type instead of int
|
||||
o packet.c: i < 256 was always true and i would overflow to 0
|
||||
o kex.c: make sure mlist is not set to NULL
|
||||
o session.c: check return value of session_nonblock in debug mode
|
||||
o session.c: check return value of session_nonblock during startup
|
||||
o userauth.c: make sure that sp_len is positive and avoid overflows
|
||||
o knownhost.c: fix use of uninitialized argument variable wrote
|
||||
o openssl: initialise the digest context before calling EVP_DigestInit()
|
||||
o libssh2_agent_init: init ->fd to LIBSSH2_INVALID_SOCKET
|
||||
o configure.ac: Add zlib to Requires.private in libssh2.pc if using zlib
|
||||
o configure.ac: Rework crypto library detection
|
||||
o configure.ac: Reorder --with-* options in --help output
|
||||
o configure.ac: Call zlib zlib and not libz in text but keep option names
|
||||
o Fix non-autotools builds: Always define the LIBSSH2_OPENSSL CPP macro
|
||||
o sftp: seek: Don't flush buffers on same offset
|
||||
o sftp: statvfs: Along error path, reset the correct 'state' variable.
|
||||
o sftp: Add support for fsync (OpenSSH extension).
|
||||
o _libssh2_channel_read: fix data drop when out of window
|
||||
o comp_method_zlib_decomp: Improve buffer growing algorithm
|
||||
o _libssh2_channel_read: Honour window_size_initial
|
||||
o window_size: redid window handling for flow control reasons
|
||||
o knownhosts: handle unknown key types
|
||||
|
||||
o wait_socket: wrong use of difftime() [1]
|
||||
o userauth: Fixed prompt text no longer being copied to the prompts struct
|
||||
o mingw build: allow to pass custom CFLAGS
|
||||
o Let mansyntax.sh work regardless of where it is called from
|
||||
o Init HMAC_CTX before using it
|
||||
o direct_tcpip: Fixed channel write
|
||||
o WinCNG: fixed backend breakage
|
||||
o OpenSSL: caused by introducing libssh2_hmac_ctx_init
|
||||
o userauth.c: fix possible dereferences of a null pointer
|
||||
o wincng: Added explicit clear memory feature to WinCNG backend
|
||||
o openssl.c: fix possible segfault in case EVP_DigestInit fails
|
||||
o wincng: fix return code of libssh2_md5_init()
|
||||
o kex: do not ignore failure of libssh2_sha1_init()
|
||||
o scp: fix that scp_send may transmit not initialised memory [3]
|
||||
o scp.c: improved command length calculation
|
||||
o nonblocking examples: fix warning about unused tvdiff on Mac OS X
|
||||
o configure: make clear-memory default but WARN if backend unsupported
|
||||
o OpenSSL: Enable use of OpenSSL that doesn't have DSA
|
||||
o OpenSSL: Use correct no-blowfish #define
|
||||
o kex: fix libgcrypt memory leaks of bignum [2]
|
||||
o libssh2_channel_open: more detailed error message
|
||||
o wincng: fixed memleak in (block) cipher destructor
|
||||
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Alexander Lamaison, Bob Kast, Dan Fandrich, Daniel Stenberg, Guenter Knauf,
|
||||
Kamil Dudka, Leif Salomonsson, Marc Hörsken, Mark McPherson,
|
||||
Matthias Kerestesch, Mikhail Gusarov, Peter Stuge, Richard W.M. Jones,
|
||||
Salvador Fandino, Seth Willits, Mariusz Ziulek
|
||||
Alexander Lamaison, Daniel Stenberg, David Calavera, Hannes Domani,
|
||||
Jakob Egger, Joe Turpin, Marc Hoersken, Viktor Szakáts, Will Cosgrove,
|
||||
(9 contributors)
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
[1] = https://github.com/bagder/libssh2/issues/1
|
||||
[2] = https://trac.libssh2.org/ticket/168
|
||||
[3] = https://trac.libssh2.org/ticket/244
|
||||
|
59
appveyor.yml
Normal file
59
appveyor.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
# Copyright (c) 2014, Ruslan Baratov
|
||||
# Copyright (c) 2014, Alexander Lamaison
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- GENERATOR: "Visual Studio 12"
|
||||
BUILD_SHARED_LIBS: ON
|
||||
|
||||
- GENERATOR: "Visual Studio 12"
|
||||
BUILD_SHARED_LIBS: OFF
|
||||
|
||||
- GENERATOR: "Visual Studio 11"
|
||||
BUILD_SHARED_LIBS: ON
|
||||
|
||||
- GENERATOR: "Visual Studio 11"
|
||||
BUILD_SHARED_LIBS: OFF
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
# configuration:
|
||||
# - Debug
|
||||
# - Release
|
||||
|
||||
build_script:
|
||||
- ps: if($env:PLATFORM -eq "x64") { $env:CMAKE_GEN_SUFFIX=" Win64" }
|
||||
- cmake "-G%GENERATOR%%CMAKE_GEN_SUFFIX%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% -H. -B_builds
|
||||
- cmake --build _builds --config "%CONFIGURATION%"
|
||||
|
||||
test_script:
|
||||
- ps: cd _builds
|
||||
- ctest -VV -C "%CONFIGURATION%" --output-on-failure
|
||||
|
||||
on_failure:
|
||||
- ps: cat _builds/CMakeFiles/CMakeOutput.log
|
||||
- ps: cat _builds/CMakeFiles/CMakeError.log
|
81
cmake/CheckFunctionExistsMayNeedLibrary.cmake
Normal file
81
cmake/CheckFunctionExistsMayNeedLibrary.cmake
Normal file
@@ -0,0 +1,81 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
|
||||
# - check_function_exists_maybe_need_library(<function> <var> [lib1 ... libn])
|
||||
#
|
||||
# Check if function is available for linking, first without extra libraries, and
|
||||
# then, if not found that way, linking in each optional library as well. This
|
||||
# function is similar to autotools AC_SEARCH_LIBS.
|
||||
#
|
||||
# If the function if found, this will define <var>.
|
||||
#
|
||||
# If the function was only found by linking in an additional library, this
|
||||
# will define NEED_LIB_LIBX, where LIBX is the one of lib1 to libn that
|
||||
# makes the function available, in uppercase.
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
#
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckLibraryExists)
|
||||
|
||||
function(check_function_exists_may_need_library function variable)
|
||||
|
||||
check_function_exists(${function} ${variable})
|
||||
|
||||
if(NOT ${variable})
|
||||
foreach(lib ${ARGN})
|
||||
string(TOUPPER ${lib} UP_LIB)
|
||||
# Use new variable to prevent cache from previous step shortcircuiting
|
||||
# new test
|
||||
check_library_exists(${lib} ${function} "" HAVE_${function}_IN_${lib})
|
||||
if(HAVE_${function}_IN_${lib})
|
||||
set(${variable} 1 CACHE INTERNAL
|
||||
"Function ${function} found in library ${lib}")
|
||||
set(NEED_LIB_${UP_LIB} 1 CACHE INTERNAL
|
||||
"Need to link ${lib}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
endfunction()
|
119
cmake/CheckNonblockingSocketSupport.cmake
Normal file
119
cmake/CheckNonblockingSocketSupport.cmake
Normal file
@@ -0,0 +1,119 @@
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
# - check_nonblocking_socket_support()
|
||||
#
|
||||
# Check for how to set a socket to non-blocking state. There seems to exist
|
||||
# four known different ways, with the one used almost everywhere being POSIX
|
||||
# and XPG3, while the other different ways for different systems (old BSD,
|
||||
# Windows and Amiga).
|
||||
#
|
||||
# One of the following variables will be set indicating the supported
|
||||
# method (if any):
|
||||
# HAVE_O_NONBLOCK
|
||||
# HAVE_FIONBIO
|
||||
# HAVE_IOCTLSOCKET
|
||||
# HAVE_IOCTLSOCKET_CASE
|
||||
# HAVE_SO_NONBLOCK
|
||||
# HAVE_DISABLED_NONBLOCKING
|
||||
#
|
||||
# The following variables may be set before calling this macro to
|
||||
# modify the way the check is run:
|
||||
#
|
||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
||||
#
|
||||
macro(check_nonblocking_socket_support)
|
||||
# There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
|
||||
# O_NONBLOCK define is found but does not work.
|
||||
check_c_source_compiles("
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
# define PLATFORM_SUNOS4
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
|
||||
# define PLATFORM_AIX_V3
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
|
||||
#error \"O_NONBLOCK does not work on this platform\"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
int socket;
|
||||
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
|
||||
}"
|
||||
HAVE_O_NONBLOCK)
|
||||
|
||||
if(NOT HAVE_O_NONBLOCK)
|
||||
check_c_source_compiles("/* FIONBIO test (old-style unix) */
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int socket;
|
||||
int flags = ioctl(socket, FIONBIO, &flags);
|
||||
}"
|
||||
HAVE_FIONBIO)
|
||||
|
||||
if(NOT HAVE_FIONBIO)
|
||||
check_c_source_compiles("/* ioctlsocket test (Windows) */
|
||||
#undef inline
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
SOCKET sd;
|
||||
unsigned long flags = 0;
|
||||
sd = socket(0, 0, 0);
|
||||
ioctlsocket(sd, FIONBIO, &flags);
|
||||
}"
|
||||
HAVE_IOCTLSOCKET)
|
||||
|
||||
if(NOT HAVE_IOCTLSOCKET)
|
||||
check_c_source_compiles("/* IoctlSocket test (Amiga?) */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int socket;
|
||||
int flags = IoctlSocket(socket, FIONBIO, (long)1);
|
||||
}"
|
||||
HAVE_IOCTLSOCKET_CASE)
|
||||
|
||||
if(NOT HAVE_IOCTLSOCKET_CASE)
|
||||
check_c_source_compiles("/* SO_NONBLOCK test (BeOS) */
|
||||
#include <socket.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
long b = 1;
|
||||
int socket;
|
||||
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
|
||||
}"
|
||||
HAVE_SO_NONBLOCK)
|
||||
|
||||
if(NOT HAVE_SO_NONBLOCK)
|
||||
# No non-blocking socket method found
|
||||
set(HAVE_DISABLED_NONBLOCKING 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
72
cmake/CopyRuntimeDependencies.cmake
Normal file
72
cmake/CopyRuntimeDependencies.cmake
Normal file
@@ -0,0 +1,72 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
function(ADD_TARGET_TO_COPY_DEPENDENCIES)
|
||||
set(options)
|
||||
set(oneValueArgs TARGET)
|
||||
set(multiValueArgs DEPENDENCIES BEFORE_TARGETS)
|
||||
cmake_parse_arguments(COPY
|
||||
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT COPY_DEPENDENCIES)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Using a custom target to drive custom commands stops multiple
|
||||
# parallel builds trying to kick off the commands at the same time
|
||||
add_custom_target(${COPY_TARGET})
|
||||
|
||||
foreach(target ${COPY_BEFORE_TARGETS})
|
||||
add_dependencies(${target} ${COPY_TARGET})
|
||||
endforeach()
|
||||
|
||||
foreach(dependency ${COPY_DEPENDENCIES})
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${COPY_TARGET}
|
||||
DEPENDS ${dependency}
|
||||
# Make directory first otherwise file is copied in place of
|
||||
# directory instead of into it
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E copy ${dependency} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
|
||||
VERBATIM)
|
||||
|
||||
endforeach()
|
||||
|
||||
endfunction()
|
53
cmake/FindLibgcrypt.cmake
Normal file
53
cmake/FindLibgcrypt.cmake
Normal file
@@ -0,0 +1,53 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
# - Try to find Libgcrypt
|
||||
# This will define all or none of:
|
||||
# LIBGCRYPT_FOUND - if Libgcrypt headers and library was found
|
||||
# LIBGCRYPT_INCLUDE_DIRS - The Libgcrypt include directories
|
||||
# LIBGCRYPT_LIBRARIES - The libraries needed to use Libgcrypt
|
||||
|
||||
find_path(LIBGCRYPT_INCLUDE_DIR gcrypt.h)
|
||||
|
||||
find_library(LIBGCRYPT_LIBRARY NAMES gcrypt libgcrypt)
|
||||
|
||||
set(LIBGCRYPT_LIBRARIES ${LIBGCRYPT_LIBRARY})
|
||||
set(LIBGCRYPT_INCLUDE_DIRS ${LIBGCRYPT_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libgcrypt DEFAULT_MSG
|
||||
LIBGCRYPT_LIBRARY LIBGCRYPT_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(LIBGCRYPT_INCLUDE_DIR LIBGCRYPT_LIBRARY)
|
64
cmake/SocketLibraries.cmake
Normal file
64
cmake/SocketLibraries.cmake
Normal file
@@ -0,0 +1,64 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
# Some systems have their socket functions in a library.
|
||||
# (Solaris -lsocket/-lnsl, Windows -lws2_32). This macro appends those
|
||||
# libraries to the given list
|
||||
macro(append_needed_socket_libraries LIBRARIES_LIST)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
# x86 Windows uses STDCALL for these functions, so their names are mangled,
|
||||
# meaning the platform checks don't work. Hardcoding these until we get
|
||||
# a better solution.
|
||||
set(HAVE_SOCKET 1)
|
||||
set(HAVE_SELECT 1)
|
||||
set(HAVE_INET_ADDR 1)
|
||||
set(NEED_LIB_WS2_32 1)
|
||||
else()
|
||||
check_function_exists_may_need_library(socket HAVE_SOCKET socket ws2_32)
|
||||
check_function_exists_may_need_library(select HAVE_SELECT ws2_32)
|
||||
check_function_exists_may_need_library(inet_addr HAVE_INET_ADDR nsl ws2_32)
|
||||
endif()
|
||||
|
||||
if(NEED_LIB_SOCKET)
|
||||
list(APPEND ${LIBRARIES_LIST} socket)
|
||||
endif()
|
||||
if(NEED_LIB_NSL)
|
||||
list(APPEND ${LIBRARIES_LIST} nsl)
|
||||
endif()
|
||||
if(NEED_LIB_WS2_32)
|
||||
list(APPEND ${LIBRARIES_LIST} ws2_32)
|
||||
endif()
|
||||
|
||||
endmacro()
|
42
cmake/Toolchain-Linux-32.cmake
Normal file
42
cmake/Toolchain-Linux-32.cmake
Normal file
@@ -0,0 +1,42 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
# Cross-compile 32-bit binary on 64-bit linux host
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
set(CMAKE_SYSTEM_PROCESSOR "i386")
|
||||
|
||||
set(CMAKE_CXX_COMPILER_ARG1 "-m32")
|
||||
set(CMAKE_C_COMPILER_ARG1 "-m32")
|
23
cmake/max_warnings.cmake
Normal file
23
cmake/max_warnings.cmake
Normal file
@@ -0,0 +1,23 @@
|
||||
if(MSVC)
|
||||
# Use the highest warning level for visual studio.
|
||||
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
endif()
|
||||
if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
|
||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
|
||||
endif()
|
||||
|
||||
# Disable broken warnings
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
endif()
|
||||
if(NOT CMAKE_C_FLAGS MATCHES "-Wall")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
endif()
|
||||
endif()
|
32
configure.ac
32
configure.ac
@@ -97,6 +97,7 @@ AC_ARG_WITH(libz,
|
||||
use_libz=$withval,use_libz=auto)
|
||||
|
||||
found_crypto=none
|
||||
support_clear_memory=no
|
||||
|
||||
# Look for OpenSSL
|
||||
if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then
|
||||
@@ -141,6 +142,9 @@ if test "$found_crypto" = "none" && test "$use_wincng" != "no"; then
|
||||
AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [
|
||||
#include <windows.h>
|
||||
])
|
||||
AC_CHECK_DECLS([SecureZeroMemory], [], [], [
|
||||
#include <windows.h>
|
||||
])
|
||||
fi
|
||||
if test "$ac_cv_libbcrypt" = "yes"; then
|
||||
AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG])
|
||||
@@ -150,6 +154,9 @@ if test "$ac_cv_libbcrypt" = "yes"; then
|
||||
LIBS="$LIBS -lcrypt32"
|
||||
fi
|
||||
found_crypto="Windows Cryptography API: Next Generation"
|
||||
if test "$ac_cv_have_decl_SecureZeroMemory" = "yes"; then
|
||||
support_clear_memory=yes
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes")
|
||||
|
||||
@@ -197,6 +204,30 @@ if test "$GEX_NEW" != "no"; then
|
||||
AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(clear-memory,
|
||||
AC_HELP_STRING([--disable-clear-memory],[Disable clearing of memory before being freed]),
|
||||
[CLEAR_MEMORY=$enableval])
|
||||
if test "$CLEAR_MEMORY" != "no"; then
|
||||
if test "$support_clear_memory" = "yes"; then
|
||||
AC_DEFINE(LIBSSH2_CLEAR_MEMORY, 1, [Enable clearing of memory before being freed])
|
||||
enable_clear_memory=yes
|
||||
else
|
||||
if test "$CLEAR_MEMORY" = "yes"; then
|
||||
AC_MSG_ERROR([secure clearing/zeroing of memory is not supported by the selected crypto backend])
|
||||
else
|
||||
AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend])
|
||||
fi
|
||||
enable_clear_memory=unsupported
|
||||
fi
|
||||
else
|
||||
if test "$support_clear_memory" = "yes"; then
|
||||
enable_clear_memory=no
|
||||
else
|
||||
AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend])
|
||||
enable_clear_memory=unsupported
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ************************************************************
|
||||
dnl option to switch on compiler debug options
|
||||
dnl
|
||||
@@ -362,6 +393,7 @@ AC_MSG_NOTICE([summary of build options:
|
||||
Compiler flags: ${CFLAGS}
|
||||
Library types: Shared=${enable_shared}, Static=${enable_static}
|
||||
Crypto library: ${found_crypto}
|
||||
Clear memory: $enable_clear_memory
|
||||
Debug build: $enable_debug
|
||||
Build examples: $build_examples
|
||||
Path to sshd: $ac_cv_path_SSHD (only for self-tests)
|
||||
|
204
docs/CMakeLists.txt
Normal file
204
docs/CMakeLists.txt
Normal file
@@ -0,0 +1,204 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
set(MAN_PAGES
|
||||
libssh2_agent_connect.3
|
||||
libssh2_agent_disconnect.3
|
||||
libssh2_agent_free.3
|
||||
libssh2_agent_get_identity.3
|
||||
libssh2_agent_init.3
|
||||
libssh2_agent_list_identities.3
|
||||
libssh2_agent_userauth.3
|
||||
libssh2_banner_set.3
|
||||
libssh2_base64_decode.3
|
||||
libssh2_channel_close.3
|
||||
libssh2_channel_direct_tcpip.3
|
||||
libssh2_channel_direct_tcpip_ex.3
|
||||
libssh2_channel_eof.3
|
||||
libssh2_channel_exec.3
|
||||
libssh2_channel_flush.3
|
||||
libssh2_channel_flush_ex.3
|
||||
libssh2_channel_flush_stderr.3
|
||||
libssh2_channel_forward_accept.3
|
||||
libssh2_channel_forward_cancel.3
|
||||
libssh2_channel_forward_listen.3
|
||||
libssh2_channel_forward_listen_ex.3
|
||||
libssh2_channel_free.3
|
||||
libssh2_channel_get_exit_signal.3
|
||||
libssh2_channel_get_exit_status.3
|
||||
libssh2_channel_handle_extended_data.3
|
||||
libssh2_channel_handle_extended_data2.3
|
||||
libssh2_channel_ignore_extended_data.3
|
||||
libssh2_channel_open_ex.3
|
||||
libssh2_channel_open_session.3
|
||||
libssh2_channel_process_startup.3
|
||||
libssh2_channel_read.3
|
||||
libssh2_channel_read_ex.3
|
||||
libssh2_channel_read_stderr.3
|
||||
libssh2_channel_receive_window_adjust.3
|
||||
libssh2_channel_receive_window_adjust2.3
|
||||
libssh2_channel_request_pty.3
|
||||
libssh2_channel_request_pty_ex.3
|
||||
libssh2_channel_request_pty_size.3
|
||||
libssh2_channel_request_pty_size_ex.3
|
||||
libssh2_channel_send_eof.3
|
||||
libssh2_channel_set_blocking.3
|
||||
libssh2_channel_setenv.3
|
||||
libssh2_channel_setenv_ex.3
|
||||
libssh2_channel_shell.3
|
||||
libssh2_channel_subsystem.3
|
||||
libssh2_channel_wait_closed.3
|
||||
libssh2_channel_wait_eof.3
|
||||
libssh2_channel_window_read.3
|
||||
libssh2_channel_window_read_ex.3
|
||||
libssh2_channel_window_write.3
|
||||
libssh2_channel_window_write_ex.3
|
||||
libssh2_channel_write.3
|
||||
libssh2_channel_write_ex.3
|
||||
libssh2_channel_write_stderr.3
|
||||
libssh2_channel_x11_req.3
|
||||
libssh2_channel_x11_req_ex.3
|
||||
libssh2_exit.3
|
||||
libssh2_free.3
|
||||
libssh2_hostkey_hash.3
|
||||
libssh2_init.3
|
||||
libssh2_keepalive_config.3
|
||||
libssh2_keepalive_send.3
|
||||
libssh2_knownhost_add.3
|
||||
libssh2_knownhost_addc.3
|
||||
libssh2_knownhost_check.3
|
||||
libssh2_knownhost_checkp.3
|
||||
libssh2_knownhost_del.3
|
||||
libssh2_knownhost_free.3
|
||||
libssh2_knownhost_get.3
|
||||
libssh2_knownhost_init.3
|
||||
libssh2_knownhost_readfile.3
|
||||
libssh2_knownhost_readline.3
|
||||
libssh2_knownhost_writefile.3
|
||||
libssh2_knownhost_writeline.3
|
||||
libssh2_poll.3
|
||||
libssh2_poll_channel_read.3
|
||||
libssh2_publickey_add.3
|
||||
libssh2_publickey_add_ex.3
|
||||
libssh2_publickey_init.3
|
||||
libssh2_publickey_list_fetch.3
|
||||
libssh2_publickey_list_free.3
|
||||
libssh2_publickey_remove.3
|
||||
libssh2_publickey_remove_ex.3
|
||||
libssh2_publickey_shutdown.3
|
||||
libssh2_scp_recv.3
|
||||
libssh2_scp_send.3
|
||||
libssh2_scp_send64.3
|
||||
libssh2_scp_send_ex.3
|
||||
libssh2_session_abstract.3
|
||||
libssh2_session_banner_get.3
|
||||
libssh2_session_banner_set.3
|
||||
libssh2_session_block_directions.3
|
||||
libssh2_session_callback_set.3
|
||||
libssh2_session_disconnect.3
|
||||
libssh2_session_disconnect_ex.3
|
||||
libssh2_session_flag.3
|
||||
libssh2_session_free.3
|
||||
libssh2_session_get_blocking.3
|
||||
libssh2_session_get_timeout.3
|
||||
libssh2_session_hostkey.3
|
||||
libssh2_session_init.3
|
||||
libssh2_session_init_ex.3
|
||||
libssh2_session_last_errno.3
|
||||
libssh2_session_last_error.3
|
||||
libssh2_session_method_pref.3
|
||||
libssh2_session_methods.3
|
||||
libssh2_session_set_blocking.3
|
||||
libssh2_session_set_timeout.3
|
||||
libssh2_session_startup.3
|
||||
libssh2_session_supported_algs.3
|
||||
libssh2_sftp_close.3
|
||||
libssh2_sftp_close_handle.3
|
||||
libssh2_sftp_closedir.3
|
||||
libssh2_sftp_fsetstat.3
|
||||
libssh2_sftp_fstat.3
|
||||
libssh2_sftp_fstat_ex.3
|
||||
libssh2_sftp_fstatvfs.3
|
||||
libssh2_sftp_fsync.3
|
||||
libssh2_sftp_get_channel.3
|
||||
libssh2_sftp_init.3
|
||||
libssh2_sftp_last_error.3
|
||||
libssh2_sftp_lstat.3
|
||||
libssh2_sftp_mkdir.3
|
||||
libssh2_sftp_mkdir_ex.3
|
||||
libssh2_sftp_open.3
|
||||
libssh2_sftp_open_ex.3
|
||||
libssh2_sftp_opendir.3
|
||||
libssh2_sftp_read.3
|
||||
libssh2_sftp_readdir.3
|
||||
libssh2_sftp_readdir_ex.3
|
||||
libssh2_sftp_readlink.3
|
||||
libssh2_sftp_realpath.3
|
||||
libssh2_sftp_rename.3
|
||||
libssh2_sftp_rename_ex.3
|
||||
libssh2_sftp_rewind.3
|
||||
libssh2_sftp_rmdir.3
|
||||
libssh2_sftp_rmdir_ex.3
|
||||
libssh2_sftp_seek.3
|
||||
libssh2_sftp_seek64.3
|
||||
libssh2_sftp_setstat.3
|
||||
libssh2_sftp_shutdown.3
|
||||
libssh2_sftp_stat.3
|
||||
libssh2_sftp_stat_ex.3
|
||||
libssh2_sftp_statvfs.3
|
||||
libssh2_sftp_symlink.3
|
||||
libssh2_sftp_symlink_ex.3
|
||||
libssh2_sftp_tell.3
|
||||
libssh2_sftp_tell64.3
|
||||
libssh2_sftp_unlink.3
|
||||
libssh2_sftp_unlink_ex.3
|
||||
libssh2_sftp_write.3
|
||||
libssh2_trace.3
|
||||
libssh2_trace_sethandler.3
|
||||
libssh2_userauth_authenticated.3
|
||||
libssh2_userauth_hostbased_fromfile.3
|
||||
libssh2_userauth_hostbased_fromfile_ex.3
|
||||
libssh2_userauth_keyboard_interactive.3
|
||||
libssh2_userauth_keyboard_interactive_ex.3
|
||||
libssh2_userauth_list.3
|
||||
libssh2_userauth_password.3
|
||||
libssh2_userauth_password_ex.3
|
||||
libssh2_userauth_publickey.3
|
||||
libssh2_userauth_publickey_fromfile.3
|
||||
libssh2_userauth_publickey_fromfile_ex.3
|
||||
libssh2_version.3)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(FILES ${MAN_PAGES} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
|
174
docs/INSTALL_CMAKE
Normal file
174
docs/INSTALL_CMAKE
Normal file
@@ -0,0 +1,174 @@
|
||||
License: see COPYING
|
||||
|
||||
Source code: https://github.com/libssh2/libssh2
|
||||
|
||||
Web site source code: https://github.com/libssh2/www
|
||||
|
||||
Installation instructions are in docs/INSTALL
|
||||
=======
|
||||
To build libssh2 you will need CMake v2.8 or later [1] and one of the
|
||||
following cryptography libraries:
|
||||
|
||||
* OpenSSL
|
||||
* Libgcrypt
|
||||
* WinCNG
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
If you are happy with the default options, make a new build directory,
|
||||
change to it, configure the build environment and build the project:
|
||||
|
||||
mkdir bin
|
||||
cd bin
|
||||
cmake ..
|
||||
cmake --build .
|
||||
|
||||
libssh2 will be built as a static library and will use any
|
||||
cryptography library available. The library binary will be put in
|
||||
`bin/src`, with the examples in `bin/example` and the tests in
|
||||
`bin/tests`.
|
||||
|
||||
Customising the build
|
||||
---------------------
|
||||
|
||||
Of course, you might want to customise the build options. You can
|
||||
pass the options to CMake on the command line:
|
||||
|
||||
cmake -D<option>=<value> ..
|
||||
|
||||
The following options are available:
|
||||
|
||||
* `BUILD_SHARED_LIBS=OFF`
|
||||
|
||||
Determines whether libssh2 is built as a static library or as a
|
||||
shared library (.dll/.so). Can be `ON` or `OFF`.
|
||||
|
||||
* `CRYPTO_BACKEND=`
|
||||
|
||||
Chooses a specific cryptography library to use for cryptographic
|
||||
operations. Can be `OpenSSL` (http://www.openssl.org),
|
||||
`Libgcrypt` (http://www.gnupg.org/), `WinCNG` (Windows Vista+) or
|
||||
blank to use any library available.
|
||||
|
||||
CMake will attempt to locate the libraries automatically. See [2]
|
||||
for more information.
|
||||
|
||||
* `ENABLE_ZLIB_COMPRESSION=OFF`
|
||||
|
||||
Will use zlib (http://www.zlib.org) for payload compression. Can
|
||||
be `ON` or `OFF`.
|
||||
|
||||
* `ENABLE_CRYPT_NONE=OFF`
|
||||
|
||||
The SSH2 Transport allows for unencrypted data transmission using
|
||||
the "none" cipher. Because this is such a huge security hole, it
|
||||
is typically disabled on SSH2 implementations and is disabled in
|
||||
libssh2 by default as well.
|
||||
|
||||
Enabling this option will allow for "none" as a negotiable method,
|
||||
however it still requires that the method be advertized by the
|
||||
remote end and that no more-preferable methods are available.
|
||||
|
||||
* `ENABLE_MAC_NONE=OFF`
|
||||
|
||||
The SSH2 Transport also allows implementations to forego a message
|
||||
authentication code. While this is less of a security risk than
|
||||
using a "none" cipher, it is still not recommended as disabling
|
||||
MAC hashes removes a layer of security.
|
||||
|
||||
Enabling this option will allow for "none" as a negotiable method,
|
||||
however it still requires that the method be advertized by the
|
||||
remote end and that no more-preferable methods are available.
|
||||
|
||||
* `ENABLE_GEX_NEW=ON`
|
||||
|
||||
The diffie-hellman-group-exchange-sha1 (dh-gex) key exchange
|
||||
method originally defined an exchange negotiation using packet
|
||||
type 30 to request a generation pair based on a single target
|
||||
value. Later refinement of dh-gex provided for range and target
|
||||
values. By default libssh2 will use the newer range method.
|
||||
|
||||
If you experience trouble connecting to an old SSH server using
|
||||
dh-gex, try this option to fallback on the older more reliable
|
||||
method.
|
||||
|
||||
* `ENABLE_DEBUG_LOGGING=ON` in Debug, `=OFF` in Release
|
||||
|
||||
Will enable the libssh2_trace() function for showing debug traces.
|
||||
|
||||
Build tools
|
||||
-----------
|
||||
|
||||
The previous examples used CMake to start the build using:
|
||||
|
||||
cmake --build .
|
||||
|
||||
Alternatively, once CMake has configured your project, you can just
|
||||
use your own build tool, e.g GNU make, Visual Studio, etc., from that
|
||||
point onwards.
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
To test the build, run the appropriate test target for your build
|
||||
system. For example:
|
||||
|
||||
cmake --build . --target test
|
||||
or
|
||||
cmake --build . --target RUN_TESTS
|
||||
|
||||
How do I use libssh2 in my project if my project doesn't use CMake?
|
||||
-------------------------------------------------------------------
|
||||
|
||||
If you are not using CMake for your own project, install libssh2
|
||||
|
||||
cmake <libssh2 source location>
|
||||
cmake --build .
|
||||
cmake --build . --target install
|
||||
or
|
||||
cmake --build . --target INSTALL
|
||||
|
||||
and then specify the install location to your project in the normal
|
||||
way for your build environment. If you don't like the default install
|
||||
location, add `-DCMAKE_INSTALL_PREFIX=<chosen prefix>` when initially
|
||||
configuring the project.
|
||||
|
||||
How can I use libssh2 in my project if it also uses CMake?
|
||||
----------------------------------------------------------
|
||||
|
||||
If your own project also uses CMake, you don't need to worry about
|
||||
setting it up with libssh2's location. Just add just the following
|
||||
lines and CMake will find libssh2 on your system, set up the necessary
|
||||
paths and link the library with your binary.
|
||||
|
||||
find_package(Libssh2 REQUIRED CONFIG)
|
||||
target_link_libraries(my_project_target Libssh2::libssh2)
|
||||
|
||||
Of course, you still have to make libssh2 available on your system
|
||||
first. You can install it in the traditional way shown above, but you
|
||||
don't have to. Instead you can just build it, which will export its
|
||||
location to the user package registry [3] where `find_package` will
|
||||
find it.
|
||||
|
||||
You can even combine the two steps using a so-called 'superbuild'
|
||||
project [4] that downloads, builds and exports libssh2, and then
|
||||
builds your project:
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(
|
||||
Libssh2
|
||||
URL <libssh2 download location>
|
||||
URL_HASH SHA1=<libssh2 archive SHA1>
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
ExternalProject_Add(
|
||||
MyProject DEPENDS Libssh2
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
[1] http://www.cmake.org/cmake/resources/software.html
|
||||
[2] http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html
|
||||
[3] http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#package-registry
|
||||
[4] http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html
|
@@ -1,6 +1,7 @@
|
||||
# $Id: Makefile.am,v 1.37 2009/03/26 15:41:15 bagder Exp $
|
||||
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL HACKING TODO AUTHORS
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL_AUTOTOOLS INSTALL_CMAKE HACKING TODO \
|
||||
AUTHORS
|
||||
|
||||
dist_man_MANS = \
|
||||
libssh2_agent_connect.3 \
|
||||
@@ -168,4 +169,5 @@ dist_man_MANS = \
|
||||
libssh2_userauth_publickey.3 \
|
||||
libssh2_userauth_publickey_fromfile.3 \
|
||||
libssh2_userauth_publickey_fromfile_ex.3 \
|
||||
libssh2_userauth_publickey_frommemory.3 \
|
||||
libssh2_version.3
|
||||
|
56
docs/libssh2_userauth_publickey_frommemory.3
Normal file
56
docs/libssh2_userauth_publickey_frommemory.3
Normal file
@@ -0,0 +1,56 @@
|
||||
.TH libssh2_userauth_publickey_frommemory 3 "1 Sep 2014" "libssh2 1.5" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_userauth_publickey_frommemory - authenticate a session with a public key, read from memory
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
.nf
|
||||
int libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
size_t username_len,
|
||||
const char *publickeydata,
|
||||
size_t publickeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
.SH DESCRIPTION
|
||||
This function allows to authenticate a session with a public key read from memory.
|
||||
It's only supported when libssh2 is backed by OpenSSL.
|
||||
\fIsession\fP - Session instance as returned by
|
||||
.BR libssh2_session_init_ex(3)
|
||||
|
||||
\fIusername\fP - Remote user name to authenticate as.
|
||||
|
||||
\fIusername_len\fP - Length of username.
|
||||
|
||||
\fIpublickeydata\fP - Buffer containing the contents of a public key file.
|
||||
|
||||
\fIpublickeydata_len\fP - Length of public key data.
|
||||
|
||||
\fIprivatekeydata\fP - Buffer containing the contents of a private key file.
|
||||
|
||||
\fIprivatekeydata_len\fP - Length of private key data.
|
||||
|
||||
\fIpassphrase\fP - Passphrase to use when decoding private key file.
|
||||
|
||||
Attempt public key authentication using a PEM encoded private key file stored in memory.
|
||||
.SH RETURN VALUE
|
||||
Return 0 on success or negative on failure. It returns
|
||||
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||
.SH ERRORS
|
||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||
|
||||
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||
|
||||
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
|
||||
|
||||
\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
|
||||
combination was invalid.
|
||||
|
||||
\fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the supplied
|
||||
public key was not accepted.
|
||||
.SH AVAILABILITY
|
||||
libssh2_userauth_publickey_frommemory was added in libssh2 1.6.0
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_session_init_ex(3)
|
101
example/CMakeLists.txt
Normal file
101
example/CMakeLists.txt
Normal file
@@ -0,0 +1,101 @@
|
||||
# Copyright (c) 2014, 2015 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckSymbolExists)
|
||||
include(CopyRuntimeDependencies)
|
||||
include(SocketLibraries)
|
||||
|
||||
set(EXAMPLES
|
||||
direct_tcpip
|
||||
ssh2
|
||||
scp
|
||||
scp_nonblock
|
||||
scp_write
|
||||
scp_write_nonblock
|
||||
sftp
|
||||
sftp_nonblock
|
||||
sftp_write
|
||||
sftp_write_nonblock
|
||||
sftp_mkdir
|
||||
sftp_mkdir_nonblock
|
||||
sftp_RW_nonblock
|
||||
sftp_write_sliding
|
||||
sftpdir
|
||||
sftpdir_nonblock
|
||||
ssh2_exec
|
||||
ssh2_agent
|
||||
ssh2_echo
|
||||
sftp_append
|
||||
subsystem_netconf
|
||||
tcpip-forward)
|
||||
|
||||
append_needed_socket_libraries(LIBRARIES)
|
||||
|
||||
foreach(example ${EXAMPLES})
|
||||
add_executable(example-${example} ${example}.c)
|
||||
list(APPEND EXAMPLE_TARGETS example-${example})
|
||||
# to find generated header
|
||||
target_include_directories(example-${example} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_link_libraries(example-${example} libssh2 ${LIBRARIES})
|
||||
endforeach()
|
||||
add_target_to_copy_dependencies(
|
||||
TARGET copy_example_dependencies
|
||||
DEPENDENCIES ${RUNTIME_DEPENDENCIES}
|
||||
BEFORE_TARGETS ${EXAMPLE_TARGETS})
|
||||
|
||||
## Platform checks
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(stdlib.h HAVE_STDLIB_H)
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_files(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
check_include_files(netinet/in.h HAVE_NETINET_IN_H)
|
||||
check_include_files(winsock2.h HAVE_WINSOCK2_H)
|
||||
|
||||
check_function_exists(strcasecmp HAVE_STRCASECMP)
|
||||
check_function_exists(_stricmp HAVE__STRICMP)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
check_function_exists(_snprintf HAVE__SNPRINTF)
|
||||
|
||||
check_symbol_exists(__func__ "" HAVE___FUNC__)
|
||||
check_symbol_exists(__FUNCTION__ "" HAVE___FUNCTION__)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libssh2_config_cmake.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh2_config.h)
|
@@ -15,10 +15,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
@@ -272,14 +275,17 @@ int main(int argc, char *argv[])
|
||||
goto shutdown;
|
||||
}
|
||||
wr = 0;
|
||||
do {
|
||||
i = libssh2_channel_write(channel, buf, len);
|
||||
while(wr < len) {
|
||||
i = libssh2_channel_write(channel, buf + wr, len - wr);
|
||||
if (LIBSSH2_ERROR_EAGAIN == i) {
|
||||
continue;
|
||||
}
|
||||
if (i < 0) {
|
||||
fprintf(stderr, "libssh2_channel_write: %d\n", i);
|
||||
goto shutdown;
|
||||
}
|
||||
wr += i;
|
||||
} while(i > 0 && wr < len);
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
len = libssh2_channel_read(channel, buf, sizeof(buf));
|
||||
|
72
example/libssh2_config_cmake.h.in
Normal file
72
example/libssh2_config_cmake.h.in
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Headers */
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
#cmakedefine HAVE_INTTYPES_H
|
||||
#cmakedefine HAVE_STDLIB_H
|
||||
#cmakedefine HAVE_SYS_SELECT_H
|
||||
#cmakedefine HAVE_SYS_SOCKET_H
|
||||
#cmakedefine HAVE_SYS_TIME_H
|
||||
#cmakedefine HAVE_ARPA_INET_H
|
||||
#cmakedefine HAVE_NETINET_IN_H
|
||||
#cmakedefine HAVE_WINSOCK2_H
|
||||
|
||||
/* Functions */
|
||||
#cmakedefine HAVE_STRCASECMP
|
||||
#cmakedefine HAVE__STRICMP
|
||||
#cmakedefine HAVE_SNPRINTF
|
||||
#cmakedefine HAVE__SNPRINTF
|
||||
|
||||
/* Workaround for platforms without POSIX strcasecmp (e.g. Windows) */
|
||||
#ifndef HAVE_STRCASECMP
|
||||
# ifdef HAVE__STRICMP
|
||||
# define strcasecmp _stricmp
|
||||
# define HAVE_STRCASECMP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Symbols */
|
||||
#cmakedefine HAVE___FUNC__
|
||||
#cmakedefine HAVE___FUNCTION__
|
||||
|
||||
/* Workaround for platforms without C90 __func__ */
|
||||
#ifndef HAVE___FUNC__
|
||||
# ifdef HAVE___FUNCTION__
|
||||
# define __func__ __FUNCTION__
|
||||
# define HAVE___FUNC__
|
||||
# endif
|
||||
#endif
|
@@ -38,12 +38,14 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
/* diff in ms */
|
||||
static long tvdiff(struct timeval newer, struct timeval older)
|
||||
{
|
||||
return (newer.tv_sec-older.tv_sec)*1000+
|
||||
(newer.tv_usec-older.tv_usec)/1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
@@ -87,11 +89,13 @@ int main(int argc, char *argv[])
|
||||
const char *password="password";
|
||||
const char *scppath="/tmp/TEST";
|
||||
struct stat fileinfo;
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval start;
|
||||
struct timeval end;
|
||||
long time_ms;
|
||||
#endif
|
||||
int rc;
|
||||
int total = 0;
|
||||
long time_ms;
|
||||
int spin = 0;
|
||||
off_t got=0;
|
||||
|
||||
@@ -149,7 +153,9 @@ int main(int argc, char *argv[])
|
||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&start, NULL);
|
||||
#endif
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
@@ -252,11 +258,15 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&end, NULL);
|
||||
|
||||
time_ms = tvdiff(end, start);
|
||||
fprintf(stderr, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
|
||||
time_ms, total/(time_ms/1000.0), spin );
|
||||
#else
|
||||
fprintf(stderr, "Got %d bytes spin: %d\n", total, spin);
|
||||
#endif
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
@@ -39,12 +39,14 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
/* diff in ms */
|
||||
static long tvdiff(struct timeval newer, struct timeval older)
|
||||
{
|
||||
return (newer.tv_sec-older.tv_sec)*1000+
|
||||
(newer.tv_usec-older.tv_usec)/1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
@@ -86,11 +88,13 @@ int main(int argc, char *argv[])
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval start;
|
||||
struct timeval end;
|
||||
long time_ms;
|
||||
#endif
|
||||
int rc;
|
||||
int total = 0;
|
||||
long time_ms;
|
||||
int spin = 0;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
@@ -151,7 +155,9 @@ int main(int argc, char *argv[])
|
||||
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&start, NULL);
|
||||
#endif
|
||||
|
||||
/* ... start it up. This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
@@ -254,10 +260,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
} while (1);
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
gettimeofday(&end, NULL);
|
||||
time_ms = tvdiff(end, start);
|
||||
fprintf(stderr, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
|
||||
time_ms, total/(time_ms/1000.0), spin );
|
||||
#else
|
||||
fprintf(stderr, "Got %d bytes spin: %d\n", total, spin);
|
||||
#endif
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
libssh2_sftp_shutdown(sftp_session);
|
||||
|
@@ -29,10 +29,13 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
@@ -31,10 +31,13 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
@@ -16,10 +16,13 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
@@ -28,6 +31,12 @@
|
||||
#define INADDR_NONE (in_addr_t)~0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# ifdef HAVE__SNPRINTF
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
const char *keyfile1 = "/home/username/.ssh/id_rsa.pub";
|
||||
const char *keyfile2 = "/home/username/.ssh/id_rsa";
|
||||
const char *username = "username";
|
||||
|
@@ -15,10 +15,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2012 Daniel Stenberg
|
||||
* Copyright (c) 2009-2015 Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -40,19 +40,19 @@
|
||||
#ifndef LIBSSH2_H
|
||||
#define LIBSSH2_H 1
|
||||
|
||||
#define LIBSSH2_COPYRIGHT "2004-2014 The libssh2 project and its contributors."
|
||||
#define LIBSSH2_COPYRIGHT "2004-2015 The libssh2 project and its contributors."
|
||||
|
||||
/* We use underscore instead of dash when appending DEV in dev versions just
|
||||
to make the BANNER define (used by src/session.c) be a valid SSH
|
||||
banner. Release versions have no appended strings and may of course not
|
||||
have dashes either. */
|
||||
#define LIBSSH2_VERSION "1.4.4_DEV"
|
||||
#define LIBSSH2_VERSION "1.6.0_DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBSSH2_VERSION_MAJOR 1
|
||||
#define LIBSSH2_VERSION_MINOR 4
|
||||
#define LIBSSH2_VERSION_PATCH 4
|
||||
#define LIBSSH2_VERSION_MINOR 6
|
||||
#define LIBSSH2_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
|
||||
@@ -69,7 +69,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBSSH2_VERSION_NUM 0x010404
|
||||
#define LIBSSH2_VERSION_NUM 0x010600
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@@ -114,7 +114,7 @@ extern "C" {
|
||||
# endif /* LIBSSH2_WIN32 */
|
||||
#endif /* LIBSSH2_API */
|
||||
|
||||
#if defined(LIBSSH2_DARWIN)
|
||||
#ifdef HAVE_SYS_UIO_H
|
||||
# include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
@@ -576,6 +576,16 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
(username), \
|
||||
(unsigned int)strlen(username))
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
size_t username_len,
|
||||
const char *publickeyfiledata,
|
||||
size_t publickeyfiledata_len,
|
||||
const char *privatekeyfiledata,
|
||||
size_t privatekeyfiledata_len,
|
||||
const char *passphrase);
|
||||
|
||||
/*
|
||||
* response_callback is provided with filled by library prompts array,
|
||||
* but client must allocate and fill individual responses. Responses
|
||||
|
384
src/CMakeLists.txt
Normal file
384
src/CMakeLists.txt
Normal file
@@ -0,0 +1,384 @@
|
||||
# Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckFunctionExistsMayNeedLibrary)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckTypeSize)
|
||||
include(CheckNonblockingSocketSupport)
|
||||
include(SocketLibraries)
|
||||
|
||||
## Cryptography backend choice
|
||||
|
||||
set(CRYPTO_BACKEND
|
||||
""
|
||||
CACHE
|
||||
STRING
|
||||
"The backend to use for cryptography: OpenSSL, Libgcrypt or WinCNG,
|
||||
or empty to try any available")
|
||||
|
||||
# If the crypto backend was given, rather than searching for the first
|
||||
# we are able to find, the find_package commands must abort configuration
|
||||
# and report to the user.
|
||||
if(CRYPTO_BACKEND)
|
||||
set(SPECIFIC_CRYPTO_REQUIREMENT REQUIRED)
|
||||
endif()
|
||||
|
||||
if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND)
|
||||
|
||||
find_package(OpenSSL ${SPECIFIC_CRYPTO_REQUIREMENT})
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
set(CRYPTO_BACKEND "OpenSSL")
|
||||
set(CRYPTO_SOURCES openssl.c openssl.h)
|
||||
list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_OPENSSL)
|
||||
list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
|
||||
list(APPEND LIBRARIES ${OPENSSL_LIBRARIES})
|
||||
list(APPEND PC_REQUIRES_PRIVATE libssl libcrypto)
|
||||
|
||||
if (WIN32)
|
||||
find_file(DLL_LIBEAY32
|
||||
NAMES libeay32.dll crypto.dll
|
||||
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin)
|
||||
if (NOT DLL_LIBEAY32)
|
||||
message(WARNING
|
||||
"Unable to find OpenSSL libeay32 DLL, executables may not run")
|
||||
endif()
|
||||
|
||||
find_file(DLL_SSLEAY32
|
||||
NAMES ssleay32.dll ssl.dll
|
||||
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin)
|
||||
if (NOT DLL_SSLEAY32)
|
||||
message(WARNING
|
||||
"Unable to find OpenSSL ssleay32 DLL, executables may not run")
|
||||
endif()
|
||||
|
||||
if(DLL_LIBEAY32 AND DLL_SSLEAY32)
|
||||
list(APPEND _RUNTIME_DEPENDENCIES ${DLL_LIBEAY32} ${DLL_SSLEAY32})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Not all OpenSSL have AES-CTR functions.
|
||||
set(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
|
||||
check_function_exists(EVP_aes_128_ctr HAVE_EVP_AES_128_CTR)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CRYPTO_BACKEND STREQUAL "Libgcrypt" OR NOT CRYPTO_BACKEND)
|
||||
|
||||
find_package(Libgcrypt ${SPECIFIC_CRYPTO_REQUIREMENT})
|
||||
|
||||
if(LIBGCRYPT_FOUND)
|
||||
set(CRYPTO_BACKEND "Libgcrypt")
|
||||
set(CRYPTO_SOURCES libgcrypt.c libgcrypt.h)
|
||||
list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_LIBGCRYPT)
|
||||
list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${LIBGCRYPT_INCLUDE_DIRS})
|
||||
list(APPEND LIBRARIES ${LIBGCRYPT_LIBRARIES})
|
||||
list(APPEND PC_LIBS -lgcrypt)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CRYPTO_BACKEND STREQUAL "WinCNG" OR NOT CRYPTO_BACKEND)
|
||||
|
||||
# The check actually compiles the header. This requires windows.h.
|
||||
check_include_files("windows.h;bcrypt.h" HAVE_BCRYPT_H)
|
||||
|
||||
if(HAVE_BCRYPT_H)
|
||||
set(CRYPTO_BACKEND "WinCNG")
|
||||
set(CRYPTO_SOURCES wincng.c wincng.h)
|
||||
list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_WINCNG)
|
||||
|
||||
set(HAVE_LIBCRYPT32 TRUE)
|
||||
list(APPEND LIBRARIES bcrypt)
|
||||
list(APPEND PC_LIBS -lbcrypt)
|
||||
|
||||
check_include_files(ntdef.h HAVE_NTDEF_H)
|
||||
check_include_files(ntstatus.h HAVE_NTSTATUS_H)
|
||||
|
||||
# Reading keys from files is optional and depends on Wincrypt
|
||||
check_include_files("windows.h;wincrypt.h" HAVE_WINCRYPT_H)
|
||||
|
||||
if(HAVE_WINCRYPT_H)
|
||||
list(APPEND LIBRARIES crypt32)
|
||||
list(APPEND PC_LIBS -lcrypt32)
|
||||
endif()
|
||||
|
||||
elseif(${SPECIFIC_CRYPTO_REQUIREMENT} STREQUAL ${REQUIRED})
|
||||
message(FATAL_ERROR "WinCNG not available")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CRYPTO_BACKEND)
|
||||
message(FATAL_ERROR "No suitable cryptography backend found.")
|
||||
endif()
|
||||
|
||||
## Library definition
|
||||
|
||||
include(GNUInstallDirs)
|
||||
set(SOURCES
|
||||
${CRYPTO_SOURCES}
|
||||
agent.c
|
||||
channel.c
|
||||
channel.h
|
||||
comp.c
|
||||
comp.h
|
||||
crypt.c
|
||||
crypto.h
|
||||
global.c
|
||||
hostkey.c
|
||||
keepalive.c
|
||||
kex.c
|
||||
knownhost.c
|
||||
libssh2_priv.h
|
||||
mac.c
|
||||
mac.h
|
||||
misc.c
|
||||
misc.h
|
||||
packet.c
|
||||
packet.h
|
||||
pem.c
|
||||
publickey.c
|
||||
scp.c
|
||||
session.c
|
||||
session.h
|
||||
sftp.c
|
||||
sftp.h
|
||||
transport.c
|
||||
transport.h
|
||||
userauth.c
|
||||
userauth.h
|
||||
version.c)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/win32/libssh2.rc)
|
||||
endif()
|
||||
|
||||
add_library(libssh2 ${SOURCES})
|
||||
# we want it to be called libssh2 on all platforms
|
||||
set_target_properties(libssh2 PROPERTIES PREFIX "")
|
||||
|
||||
target_compile_definitions(libssh2 PRIVATE ${PRIVATE_COMPILE_DEFINITIONS})
|
||||
target_include_directories(libssh2
|
||||
PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
## Options
|
||||
|
||||
add_feature_info("Shared library" BUILD_SHARED_LIBS
|
||||
"creating libssh2 as a shared library (.so/.dll)")
|
||||
|
||||
option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression")
|
||||
add_feature_info(Compression ENABLE_ZLIB_COMPRESSION
|
||||
"using zlib for compression")
|
||||
if(ENABLE_ZLIB_COMPRESSION)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
target_include_directories(libssh2 PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||
list(APPEND LIBRARIES ${ZLIB_LIBRARIES})
|
||||
list(APPEND PC_REQUIRES_PRIVATE zlib)
|
||||
if(ZLIB_FOUND)
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_HAVE_ZLIB=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(ENABLE_CRYPT_NONE "Permit \"none\" cipher -- NOT RECOMMENDED")
|
||||
add_feature_info("\"none\" cipher" ENABLE_CRYPT_NONE "")
|
||||
if(ENABLE_CRYPT_NONE)
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_CRYPT_NONE=1)
|
||||
endif()
|
||||
|
||||
option(ENABLE_MAC_NONE "Permit \"none\" MAC -- NOT RECOMMMENDED")
|
||||
add_feature_info("\"none\" MAC" ENABLE_MAC_NONE "")
|
||||
if(ENABLE_MAC_NONE)
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_MAC_NONE=1)
|
||||
endif()
|
||||
|
||||
option(ENABLE_GEX_NEW
|
||||
"Enable diffie-hellman-group-exchange-sha1 method" ON)
|
||||
add_feature_info("diffie-hellman-group-exchange-sha1" ENABLE_GEX_NEW
|
||||
"\"new\" diffie-hellman-group-exchange-sha1 method")
|
||||
if(ENABLE_GEX_NEW)
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_DH_GEX_NEW=1)
|
||||
endif()
|
||||
|
||||
# Enable debugging logging by default if the user configured a debug build
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(DEBUG_LOGGING_DEFAULT ON)
|
||||
else()
|
||||
set(DEBUG_LOGGING_DEFAULT OFF)
|
||||
endif()
|
||||
option(ENABLE_DEBUG_LOGGING "log execution with debug trace"
|
||||
${DEBUG_LOGGING_DEFAULT})
|
||||
add_feature_info(Logging ENABLE_DEBUG_LOGGING
|
||||
"Logging of execution with debug trace")
|
||||
if(ENABLE_DEBUG_LOGGING)
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2DEBUG)
|
||||
endif()
|
||||
|
||||
## Platform checks
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files(stdlib.h HAVE_STDLIB_H)
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
|
||||
check_include_files(sys/uio.h HAVE_SYS_UIO_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(sys/ioctl.h HAVE_SYS_IOCTL_H)
|
||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_files(sys/un.h HAVE_SYS_UN_H)
|
||||
check_include_files(windows.h HAVE_WINDOWS_H)
|
||||
check_include_files(ws2tcpip.h HAVE_WS2TCPIP_H)
|
||||
check_include_files(winsock2.h HAVE_WINSOCK2_H)
|
||||
|
||||
check_type_size("long long" LONGLONG)
|
||||
|
||||
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
check_function_exists(strtoll HAVE_STRTOLL)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
|
||||
${CMAKE_SYSTEM_NAME} STREQUAL "Interix")
|
||||
# poll() does not work on these platforms
|
||||
#
|
||||
# Interix: "does provide poll(), but the implementing developer must
|
||||
# have been in a bad mood, because poll() only works on the /proc
|
||||
# filesystem here"
|
||||
#
|
||||
# Mac OS X's poll has funny behaviors, like:
|
||||
# not being able to do poll on no fildescriptors (10.3?)
|
||||
# not being able to poll on some files (like anything in /dev)
|
||||
# not having reliable timeout support
|
||||
# inconsistent return of POLLHUP where other implementations give POLLIN
|
||||
message("poll use is disabled on this platform")
|
||||
else()
|
||||
check_function_exists(poll HAVE_POLL)
|
||||
endif()
|
||||
|
||||
append_needed_socket_libraries(LIBRARIES)
|
||||
|
||||
# Non-blocking socket support tests. Must be after after library tests to
|
||||
# link correctly
|
||||
set(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES})
|
||||
check_nonblocking_socket_support()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libssh2_config_cmake.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh2_config.h)
|
||||
# to find generated header
|
||||
target_include_directories(libssh2 PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Check for the OS.
|
||||
# Daniel's note: this should not be necessary and we need to work to
|
||||
# get this removed.
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_WIN32)
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_DARWIN)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS "2.8.12")
|
||||
# Fall back to over-linking dependencies
|
||||
target_link_libraries(libssh2 ${LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(libssh2 PRIVATE ${LIBRARIES})
|
||||
endif()
|
||||
|
||||
## Installation
|
||||
|
||||
install(FILES
|
||||
${CMAKE_SOURCE_DIR}/include/libssh2.h
|
||||
${CMAKE_SOURCE_DIR}/include/libssh2_publickey.h
|
||||
${CMAKE_SOURCE_DIR}/include/libssh2_sftp.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
install(TARGETS libssh2
|
||||
EXPORT Libssh2Config
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
list(APPEND _RUNTIME_DEPENDENCIES $<TARGET_FILE:libssh2>)
|
||||
endif()
|
||||
|
||||
set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL
|
||||
"Files that must be in the same directory as the executables at runtime.")
|
||||
|
||||
# Package config
|
||||
|
||||
## During package installation, install Libssh2Config.cmake
|
||||
install(EXPORT Libssh2Config
|
||||
NAMESPACE Libssh2::
|
||||
DESTINATION lib/cmake/libssh2)
|
||||
|
||||
## During build, register directly from build tree
|
||||
# create Libssh2Config.cmake
|
||||
export(TARGETS libssh2 NAMESPACE Libssh2:: FILE Libssh2Config.cmake)
|
||||
export(PACKAGE Libssh2) # register it
|
||||
|
||||
## Export a .pc file for client projects not using CMaek
|
||||
if(PC_REQUIRES_PRIVATE)
|
||||
string(REPLACE ";" "," PC_REQUIRES_PRIVATE "${PC_REQUIRES_PRIVATE}")
|
||||
endif()
|
||||
if(PC_LIBS)
|
||||
string(REPLACE ";" " " PC_LIBS "${PC_LIBS}")
|
||||
endif()
|
||||
configure_file(libssh2.pc.in libssh2.pc @ONLY)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
## Versioning
|
||||
|
||||
set_target_properties(libssh2 PROPERTIES
|
||||
SOVERSION 1
|
||||
VERSION 1.0.1)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake
|
||||
VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}"
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake
|
||||
DESTINATION lib/cmake/libssh2)
|
@@ -266,8 +266,28 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
}
|
||||
|
||||
if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||
"Channel open failure");
|
||||
unsigned int reason_code = _libssh2_ntohu32(session->open_data + 5);
|
||||
switch (reason_code) {
|
||||
case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED:
|
||||
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||
"Channel open failure (admininstratively prohibited)");
|
||||
break;
|
||||
case SSH_OPEN_CONNECT_FAILED:
|
||||
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||
"Channel open failure (connect failed)");
|
||||
break;
|
||||
case SSH_OPEN_UNKNOWN_CHANNELTYPE:
|
||||
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||
"Channel open failure (unknown channel type)");
|
||||
break;
|
||||
case SSH_OPEN_RESOURCE_SHORTAGE:
|
||||
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||
"Channel open failure (resource shortage)");
|
||||
break;
|
||||
default:
|
||||
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||
"Channel open failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
16
src/crypto.h
16
src/crypto.h
@@ -80,6 +80,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
size_t hash_len,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
||||
@@ -102,6 +106,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
#endif
|
||||
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
@@ -120,6 +128,14 @@ int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
|
||||
void _libssh2_init_aes_ctr(void);
|
||||
|
||||
|
@@ -130,6 +130,38 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* hostkey_method_ssh_rsa_initPEMFromMemory
|
||||
*
|
||||
* Load a Private Key from a memory
|
||||
*/
|
||||
static int
|
||||
hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
|
||||
const char *privkeyfiledata,
|
||||
size_t privkeyfiledata_len,
|
||||
unsigned const char *passphrase,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx;
|
||||
int ret;
|
||||
|
||||
if (*abstract) {
|
||||
hostkey_method_ssh_rsa_dtor(session, abstract);
|
||||
*abstract = NULL;
|
||||
}
|
||||
|
||||
ret = _libssh2_rsa_new_private_frommemory(&rsactx, session,
|
||||
privkeyfiledata,
|
||||
privkeyfiledata_len, passphrase);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*abstract = rsactx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* hostkey_method_ssh_rsa_sign
|
||||
*
|
||||
@@ -208,6 +240,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
|
||||
MD5_DIGEST_LENGTH,
|
||||
hostkey_method_ssh_rsa_init,
|
||||
hostkey_method_ssh_rsa_initPEM,
|
||||
hostkey_method_ssh_rsa_initPEMFromMemory,
|
||||
hostkey_method_ssh_rsa_sig_verify,
|
||||
hostkey_method_ssh_rsa_signv,
|
||||
NULL, /* encrypt */
|
||||
@@ -305,6 +338,38 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* hostkey_method_ssh_dss_initPEMFromMemory
|
||||
*
|
||||
* Load a Private Key from memory
|
||||
*/
|
||||
static int
|
||||
hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
|
||||
const char *privkeyfiledata,
|
||||
size_t privkeyfiledata_len,
|
||||
unsigned const char *passphrase,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx;
|
||||
int ret;
|
||||
|
||||
if (*abstract) {
|
||||
hostkey_method_ssh_dss_dtor(session, abstract);
|
||||
*abstract = NULL;
|
||||
}
|
||||
|
||||
ret = _libssh2_dsa_new_private_frommemory(&dsactx, session,
|
||||
privkeyfiledata,
|
||||
privkeyfiledata_len, passphrase);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*abstract = dsactx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_hostkey_method_ssh_dss_sign
|
||||
*
|
||||
@@ -391,6 +456,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = {
|
||||
MD5_DIGEST_LENGTH,
|
||||
hostkey_method_ssh_dss_init,
|
||||
hostkey_method_ssh_dss_initPEM,
|
||||
hostkey_method_ssh_dss_initPEMFromMemory,
|
||||
hostkey_method_ssh_dss_sig_verify,
|
||||
hostkey_method_ssh_dss_signv,
|
||||
NULL, /* encrypt */
|
||||
@@ -434,7 +500,9 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
|
||||
break;
|
||||
#endif /* LIBSSH2_MD5 */
|
||||
case LIBSSH2_HOSTKEY_HASH_SHA1:
|
||||
return (char *) session->server_hostkey_sha1;
|
||||
return (session->server_hostkey_sha1_valid)
|
||||
? (char *) session->server_hostkey_sha1
|
||||
: NULL;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
|
27
src/kex.c
27
src/kex.c
@@ -96,7 +96,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
exchange_state->ctx = _libssh2_bn_ctx_new();
|
||||
exchange_state->x = _libssh2_bn_init(); /* Random from client */
|
||||
exchange_state->e = _libssh2_bn_init(); /* g^x mod p */
|
||||
exchange_state->f = _libssh2_bn_init(); /* g^(Random from server) mod p */
|
||||
exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from server) mod p */
|
||||
exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */
|
||||
|
||||
/* Zero the whole thing out */
|
||||
@@ -221,7 +221,8 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
if (libssh2_md5_init(&fingerprint_ctx)) {
|
||||
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
|
||||
session->server_hostkey_len);
|
||||
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
|
||||
libssh2_md5_final(fingerprint_ctx,
|
||||
session->server_hostkey_md5);
|
||||
session->server_hostkey_md5_valid = TRUE;
|
||||
}
|
||||
else {
|
||||
@@ -245,10 +246,16 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
{
|
||||
libssh2_sha1_ctx fingerprint_ctx;
|
||||
|
||||
libssh2_sha1_init(&fingerprint_ctx);
|
||||
libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
|
||||
session->server_hostkey_len);
|
||||
libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1);
|
||||
if (libssh2_sha1_init(&fingerprint_ctx)) {
|
||||
libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
|
||||
session->server_hostkey_len);
|
||||
libssh2_sha1_final(fingerprint_ctx,
|
||||
session->server_hostkey_sha1);
|
||||
session->server_hostkey_sha1_valid = TRUE;
|
||||
}
|
||||
else {
|
||||
session->server_hostkey_sha1_valid = FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIBSSH2DEBUG
|
||||
{
|
||||
@@ -708,7 +715,7 @@ kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
|
||||
|
||||
if (key_state->state == libssh2_NB_state_idle) {
|
||||
/* g == 2 */
|
||||
key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */
|
||||
key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */
|
||||
key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
|
||||
|
||||
/* Initialize P and G */
|
||||
@@ -783,7 +790,7 @@ kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
|
||||
int ret;
|
||||
|
||||
if (key_state->state == libssh2_NB_state_idle) {
|
||||
key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */
|
||||
key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */
|
||||
key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
|
||||
|
||||
/* g == 2 */
|
||||
@@ -827,8 +834,8 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
|
||||
int rc;
|
||||
|
||||
if (key_state->state == libssh2_NB_state_idle) {
|
||||
key_state->p = _libssh2_bn_init();
|
||||
key_state->g = _libssh2_bn_init();
|
||||
key_state->p = _libssh2_bn_init_from_bin();
|
||||
key_state->g = _libssh2_bn_init_from_bin();
|
||||
/* Ask for a P and G pair */
|
||||
#ifdef LIBSSH2_DH_GEX_NEW
|
||||
key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
|
||||
|
@@ -417,8 +417,9 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
plain input to produce a hash to compare with the
|
||||
stored hash.
|
||||
*/
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
libssh2_hmac_ctx ctx;
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
|
||||
if(SHA_DIGEST_LENGTH != node->name_len) {
|
||||
/* the name hash length must be the sha1 size or
|
||||
|
@@ -149,6 +149,17 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unable to extract private key from memory: "
|
||||
"Method unimplemented in libgcrypt backend");
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
@@ -251,6 +262,17 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unable to extract private key from memory: "
|
||||
"Method unimplemented in libgcrypt backend");
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
@@ -566,6 +588,21 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase)
|
||||
{
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unable to extract public key from private key in memory: "
|
||||
"Method unimplemented in libgcrypt backend");
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
|
@@ -60,7 +60,10 @@
|
||||
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
|
||||
|
||||
#define libssh2_sha1_ctx gcry_md_hd_t
|
||||
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
#define libssh2_sha1_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA1, 0))
|
||||
#define libssh2_sha1_update(ctx, data, len) \
|
||||
gcry_md_write (ctx, (unsigned char *) data, len)
|
||||
#define libssh2_sha1_final(ctx, out) \
|
||||
@@ -82,6 +85,7 @@
|
||||
gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len)
|
||||
|
||||
#define libssh2_hmac_ctx gcry_md_hd_t
|
||||
#define libssh2_hmac_ctx_init(ctx)
|
||||
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||
gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey (*ctx, key, keylen)
|
||||
@@ -145,6 +149,7 @@
|
||||
#define _libssh2_bn_ctx_new() 0
|
||||
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
|
||||
#define _libssh2_bn_init() gcry_mpi_new(0)
|
||||
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a new bignum */
|
||||
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
|
||||
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
|
||||
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
|
||||
|
17
src/libssh2.pc.in
Normal file
17
src/libssh2.pc.in
Normal file
@@ -0,0 +1,17 @@
|
||||
###########################################################################
|
||||
# libssh2 installation details
|
||||
###########################################################################
|
||||
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
URL: @PROJECT_URL@
|
||||
Description: @PROJECT_DESCRIPTION@
|
||||
Version: @LIBSSH2_VERSION@
|
||||
Requires.private: @PC_REQUIRES_PRIVATE@
|
||||
Libs: -L${libdir} -lssh2 @PC_LIBS@
|
||||
Libs.private: @PC_LIBS@
|
||||
Cflags: -I${includedir}
|
104
src/libssh2_config_cmake.h.in
Normal file
104
src/libssh2_config_cmake.h.in
Normal file
@@ -0,0 +1,104 @@
|
||||
/* Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
* Copyright (c) 1999-2011 Douglas Gilbert. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Headers */
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
#cmakedefine HAVE_INTTYPES_H
|
||||
#cmakedefine HAVE_STDLIB_H
|
||||
#cmakedefine HAVE_SYS_SELECT_H
|
||||
#cmakedefine HAVE_SYS_UIO_H
|
||||
#cmakedefine HAVE_SYS_SOCKET_H
|
||||
#cmakedefine HAVE_SYS_IOCTL_H
|
||||
#cmakedefine HAVE_SYS_TIME_H
|
||||
#cmakedefine HAVE_SYS_UN_H
|
||||
#cmakedefine HAVE_WINDOWS_H
|
||||
#cmakedefine HAVE_WS2TCPIP_H
|
||||
#cmakedefine HAVE_WINSOCK2_H
|
||||
#cmakedefine HAVE_NTDEF_H
|
||||
#cmakedefine HAVE_NTSTATUS_H
|
||||
|
||||
/* Libraries */
|
||||
#cmakedefine HAVE_LIBCRYPT32
|
||||
|
||||
/* Types */
|
||||
#cmakedefine HAVE_LONGLONG
|
||||
|
||||
/* Functions */
|
||||
#cmakedefine HAVE_GETTIMEOFDAY
|
||||
#cmakedefine HAVE_INET_ADDR
|
||||
#cmakedefine HAVE_POLL
|
||||
#cmakedefine HAVE_SELECT
|
||||
#cmakedefine HAVE_SOCKET
|
||||
#cmakedefine HAVE_STRTOLL
|
||||
#cmakedefine HAVE_SNPRINTF
|
||||
|
||||
/* OpenSSL functions */
|
||||
#cmakedefine HAVE_EVP_AES_128_CTR
|
||||
|
||||
/* Socket non-blocking support */
|
||||
#cmakedefine HAVE_O_NONBLOCK
|
||||
#cmakedefine HAVE_FIONBIO
|
||||
#cmakedefine HAVE_IOCTLSOCKET
|
||||
#cmakedefine HAVE_IOCTLSOCKET_CASE
|
||||
#cmakedefine HAVE_SO_NONBLOCK
|
||||
#cmakedefine HAVE_DISABLED_NONBLOCKING
|
||||
|
||||
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
|
||||
We provide a safe wrapper if snprintf not found */
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
|
||||
* then assume cp is pointing to a null char and do nothing. Returns number
|
||||
* number of chars placed in cp excluding the trailing null char. So for
|
||||
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
|
||||
* <= 0 the return value is 0 (and no chars are written to cp). */
|
||||
static int snprintf(char * cp, int cp_max_len, const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int n;
|
||||
|
||||
if (cp_max_len < 2)
|
||||
return 0;
|
||||
va_start(args, fmt);
|
||||
n = vsnprintf(cp, cp_max_len, fmt, args);
|
||||
va_end(args);
|
||||
return (n < cp_max_len) ? n : (cp_max_len - 1);
|
||||
}
|
||||
|
||||
#define HAVE_SNPRINTF
|
||||
#endif
|
@@ -600,6 +600,7 @@ struct _LIBSSH2_SESSION
|
||||
int server_hostkey_md5_valid;
|
||||
#endif /* ! LIBSSH2_MD5 */
|
||||
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
|
||||
int server_hostkey_sha1_valid;
|
||||
|
||||
/* (remote as source of data -- packet_read ) */
|
||||
libssh2_endpoint_data remote;
|
||||
@@ -854,6 +855,9 @@ struct _LIBSSH2_HOSTKEY_METHOD
|
||||
size_t hostkey_data_len, void **abstract);
|
||||
int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
|
||||
unsigned const char *passphrase, void **abstract);
|
||||
int (*initPEMFromMemory) (LIBSSH2_SESSION * session,
|
||||
const char *privkeyfiledata, size_t privkeyfiledata_len,
|
||||
unsigned const char *passphrase, void **abstract);
|
||||
int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
|
||||
size_t sig_len, const unsigned char *m,
|
||||
size_t m_len, void **abstract);
|
||||
@@ -1023,6 +1027,11 @@ int _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
FILE * fp, unsigned char **data, unsigned int *datalen);
|
||||
int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned char **data, unsigned int *datalen);
|
||||
int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
|
||||
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||
unsigned char **i, unsigned int *ilen);
|
||||
|
@@ -113,6 +113,7 @@ mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_sha1_init(&ctx, *abstract, 20);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
@@ -185,6 +186,7 @@ mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_md5_init(&ctx, *abstract, 16);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
@@ -257,6 +259,7 @@ mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
|
141
src/openssl.c
141
src/openssl.c
@@ -387,6 +387,28 @@ passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
|
||||
typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *,
|
||||
void * u);
|
||||
|
||||
static int
|
||||
read_private_key_from_memory(void ** key_ctx,
|
||||
pem_read_bio_func read_private_key,
|
||||
const char * filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
BIO * bp;
|
||||
|
||||
*key_ctx = NULL;
|
||||
|
||||
bp = BIO_new_mem_buf((char *)filedata, filedata_len);
|
||||
if (!bp) {
|
||||
return -1;
|
||||
}
|
||||
*key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
|
||||
(void *) passphrase);
|
||||
|
||||
BIO_free(bp);
|
||||
return (*key_ctx) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
read_private_key_from_file(void ** key_ctx,
|
||||
pem_read_bio_func read_private_key,
|
||||
@@ -409,6 +431,22 @@ read_private_key_from_file(void ** key_ctx,
|
||||
return (*key_ctx) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
pem_read_bio_func read_rsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
return read_private_key_from_memory((void **) rsa, read_rsa,
|
||||
filedata, filedata_len, passphrase);
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
@@ -425,6 +463,22 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
}
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
int
|
||||
_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
pem_read_bio_func read_dsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
return read_private_key_from_memory((void **) dsa, read_dsa,
|
||||
filedata, filedata_len, passphrase);
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
@@ -523,9 +577,10 @@ libssh2_sha1(const unsigned char *message, unsigned long len,
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"));
|
||||
EVP_DigestUpdate(&ctx, message, len);
|
||||
EVP_DigestFinal(&ctx, out, NULL);
|
||||
if (EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"))) {
|
||||
EVP_DigestUpdate(&ctx, message, len);
|
||||
EVP_DigestFinal(&ctx, out, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -542,9 +597,10 @@ libssh2_md5(const unsigned char *message, unsigned long len,
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"));
|
||||
EVP_DigestUpdate(&ctx, message, len);
|
||||
EVP_DigestFinal(&ctx, out, NULL);
|
||||
if (EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"))) {
|
||||
EVP_DigestUpdate(&ctx, message, len);
|
||||
EVP_DigestFinal(&ctx, out, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
@@ -600,6 +656,7 @@ gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa,
|
||||
return key;
|
||||
}
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
static unsigned char *
|
||||
gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
|
||||
size_t *key_len)
|
||||
@@ -638,6 +695,7 @@ gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
|
||||
*key_len = (size_t)(p - key);
|
||||
return key;
|
||||
}
|
||||
#endif /* LIBSSH_DSA */
|
||||
|
||||
static int
|
||||
gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
|
||||
@@ -693,6 +751,7 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
|
||||
"Unable to allocate memory for private key data");
|
||||
}
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
static int
|
||||
gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
@@ -746,6 +805,7 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for private key data");
|
||||
}
|
||||
#endif /* LIBSSH_DSA */
|
||||
|
||||
int
|
||||
_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
@@ -799,10 +859,12 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||
break;
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
case EVP_PKEY_DSA :
|
||||
st = gen_publickey_from_dsa_evp(
|
||||
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||
break;
|
||||
#endif /* LIBSSH_DSA */
|
||||
|
||||
default :
|
||||
st = _libssh2_error(session,
|
||||
@@ -817,4 +879,71 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
return st;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase)
|
||||
{
|
||||
int st;
|
||||
BIO* bp;
|
||||
EVP_PKEY* pk;
|
||||
|
||||
_libssh2_debug(session,
|
||||
LIBSSH2_TRACE_AUTH,
|
||||
"Computing public key from private key.");
|
||||
|
||||
bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len);
|
||||
if (!bp) {
|
||||
return -1;
|
||||
}
|
||||
if (!EVP_get_cipherbyname("des")) {
|
||||
/* If this cipher isn't loaded it's a pretty good indication that none
|
||||
* are. I have *NO DOUBT* that there's a better way to deal with this
|
||||
* ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on
|
||||
* it.
|
||||
*/
|
||||
OpenSSL_add_all_ciphers();
|
||||
}
|
||||
BIO_reset(bp);
|
||||
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase);
|
||||
BIO_free(bp);
|
||||
|
||||
if (pk == NULL) {
|
||||
return _libssh2_error(session,
|
||||
LIBSSH2_ERROR_FILE,
|
||||
"Unable to extract public key "
|
||||
"from private key file: "
|
||||
"Wrong passphrase or invalid/unrecognized "
|
||||
"private key file format");
|
||||
}
|
||||
|
||||
switch (pk->type) {
|
||||
case EVP_PKEY_RSA :
|
||||
st = gen_publickey_from_rsa_evp(session, method, method_len,
|
||||
pubkeydata, pubkeydata_len, pk);
|
||||
break;
|
||||
#if LIBSSH2_DSA
|
||||
case EVP_PKEY_DSA :
|
||||
st = gen_publickey_from_dsa_evp(session, method, method_len,
|
||||
pubkeydata, pubkeydata_len, pk);
|
||||
break;
|
||||
#endif /* LIBSSH_DSA */
|
||||
default :
|
||||
st = _libssh2_error(session,
|
||||
LIBSSH2_ERROR_FILE,
|
||||
"Unable to extract public key "
|
||||
"from private key file: "
|
||||
"Unsupported private key file format");
|
||||
break;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pk);
|
||||
return st;
|
||||
}
|
||||
|
||||
#endif /* LIBSSH2_OPENSSL */
|
||||
|
@@ -80,7 +80,7 @@
|
||||
# define LIBSSH2_AES 0
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_BLOWFISH
|
||||
#ifdef OPENSSL_NO_BF
|
||||
# define LIBSSH2_BLOWFISH 0
|
||||
#else
|
||||
# define LIBSSH2_BLOWFISH 1
|
||||
@@ -107,6 +107,8 @@
|
||||
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
|
||||
|
||||
#define libssh2_sha1_ctx EVP_MD_CTX
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int libssh2_sha1_init(libssh2_sha1_ctx *ctx);
|
||||
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
@@ -121,6 +123,8 @@ int libssh2_md5_init(libssh2_md5_ctx *);
|
||||
void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char *out);
|
||||
|
||||
#define libssh2_hmac_ctx HMAC_CTX
|
||||
#define libssh2_hmac_ctx_init(ctx) \
|
||||
HMAC_CTX_init(&ctx)
|
||||
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||
HMAC_Init(ctx, key, keylen, EVP_sha1())
|
||||
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||
@@ -171,6 +175,7 @@ void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char
|
||||
#define _libssh2_bn_ctx_new() BN_CTX_new()
|
||||
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
|
||||
#define _libssh2_bn_init() BN_new()
|
||||
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
|
||||
#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom)
|
||||
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx)
|
||||
#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
|
||||
|
115
src/pem.c
115
src/pem.c
@@ -41,15 +41,56 @@
|
||||
static int
|
||||
readline(char *line, int line_size, FILE * fp)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (!line) {
|
||||
return -1;
|
||||
}
|
||||
if (!fgets(line, line_size, fp)) {
|
||||
return -1;
|
||||
}
|
||||
if (*line && line[strlen(line) - 1] == '\n') {
|
||||
line[strlen(line) - 1] = '\0';
|
||||
|
||||
if (*line) {
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
if (*line && line[strlen(line) - 1] == '\r') {
|
||||
line[strlen(line) - 1] = '\0';
|
||||
|
||||
if (*line) {
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\r') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
readline_memory(char *line, size_t line_size,
|
||||
const char *filedata, size_t filedata_len,
|
||||
size_t *filedata_offset)
|
||||
{
|
||||
size_t off, len;
|
||||
|
||||
off = *filedata_offset;
|
||||
|
||||
for (len = 0; off + len < filedata_len && len < line_size; len++) {
|
||||
if (filedata[off + len] == '\n' ||
|
||||
filedata[off + len] == '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len) {
|
||||
memcpy(line, filedata + off, len);
|
||||
*filedata_offset += len;
|
||||
}
|
||||
|
||||
line[len] = '\0';
|
||||
*filedata_offset += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,6 +160,72 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
size_t off = 0;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while (strcmp(line, headerbegin) != 0);
|
||||
|
||||
*line = '\0';
|
||||
|
||||
do {
|
||||
if (*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if (!tmp) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while (strcmp(line, headerend) != 0);
|
||||
|
||||
if (!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (b64data) {
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
read_asn1_length(const unsigned char *data,
|
||||
unsigned int datalen, unsigned int *len)
|
||||
|
29
src/scp.c
29
src/scp.c
@@ -295,14 +295,16 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
}
|
||||
|
||||
snprintf((char *)session->scpRecv_command,
|
||||
session->scpRecv_command_len, "scp -%sf ", sb?"p":"");
|
||||
session->scpRecv_command_len,
|
||||
"scp -%sf ", sb?"p":"");
|
||||
|
||||
cmd_len = strlen((char *)session->scpRecv_command);
|
||||
cmd_len += shell_quotearg(path,
|
||||
&session->scpRecv_command[cmd_len],
|
||||
session->scpRecv_command_len - cmd_len);
|
||||
|
||||
(void) shell_quotearg(path,
|
||||
&session->scpRecv_command[cmd_len],
|
||||
session->scpRecv_command_len - cmd_len);
|
||||
|
||||
session->scpRecv_command[cmd_len] = '\0';
|
||||
session->scpRecv_command_len = cmd_len + 1;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
|
||||
"Opening channel for SCP receive");
|
||||
@@ -790,22 +792,25 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||
|
||||
session->scpSend_command =
|
||||
LIBSSH2_ALLOC(session, session->scpSend_command_len);
|
||||
|
||||
if (!session->scpSend_command) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a command buffer for scp session");
|
||||
"Unable to allocate a command buffer for "
|
||||
"SCP session");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf((char *)session->scpSend_command, session->scpSend_command_len,
|
||||
snprintf((char *)session->scpSend_command,
|
||||
session->scpSend_command_len,
|
||||
"scp -%st ", (mtime || atime)?"p":"");
|
||||
|
||||
cmd_len = strlen((char *)session->scpSend_command);
|
||||
cmd_len += shell_quotearg(path,
|
||||
&session->scpSend_command[cmd_len],
|
||||
session->scpSend_command_len - cmd_len);
|
||||
|
||||
(void)shell_quotearg(path,
|
||||
&session->scpSend_command[cmd_len],
|
||||
session->scpSend_command_len - cmd_len);
|
||||
|
||||
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
|
||||
session->scpSend_command[cmd_len] = '\0';
|
||||
session->scpSend_command_len = cmd_len + 1;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
|
||||
"Opening channel for SCP send");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2011 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2015 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -601,7 +601,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
|
||||
(seconds_to_next == 0 ||
|
||||
seconds_to_next > session->api_timeout)) {
|
||||
time_t now = time (NULL);
|
||||
elapsed_ms = (long)(1000*difftime(start_time, now));
|
||||
elapsed_ms = (long)(1000*difftime(now, start_time));
|
||||
if (elapsed_ms > session->api_timeout) {
|
||||
session->err_code = LIBSSH2_ERROR_TIMEOUT;
|
||||
return LIBSSH2_ERROR_TIMEOUT;
|
||||
|
243
src/userauth.c
243
src/userauth.c
@@ -442,6 +442,76 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *pubkeyfiledata,
|
||||
size_t pubkeyfiledata_len)
|
||||
{
|
||||
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
|
||||
size_t pubkey_len = pubkeyfiledata_len;
|
||||
unsigned int tmp_len;
|
||||
|
||||
if (pubkeyfiledata_len <= 1) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Invalid data in public key file");
|
||||
}
|
||||
|
||||
pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len);
|
||||
if (!pubkey) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for public key data");
|
||||
}
|
||||
|
||||
memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len);
|
||||
|
||||
/*
|
||||
* Remove trailing whitespace
|
||||
*/
|
||||
while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
|
||||
pubkey_len--;
|
||||
|
||||
if (!pubkey_len) {
|
||||
LIBSSH2_FREE(session, pubkey);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Missing public key data");
|
||||
}
|
||||
|
||||
if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) {
|
||||
LIBSSH2_FREE(session, pubkey);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Invalid public key data");
|
||||
}
|
||||
|
||||
sp1++;
|
||||
|
||||
if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
|
||||
/* Assume that the id string is missing, but that it's okay */
|
||||
sp2 = pubkey + pubkey_len;
|
||||
}
|
||||
|
||||
if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len,
|
||||
(char *) sp1, sp2 - sp1)) {
|
||||
LIBSSH2_FREE(session, pubkey);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Invalid key data, not base64 encoded");
|
||||
}
|
||||
|
||||
/* Wasting some bytes here (okay, more than some), but since it's likely
|
||||
* to be freed soon anyway, we'll just avoid the extra free/alloc and call
|
||||
* it a wash
|
||||
*/
|
||||
*method = pubkey;
|
||||
*method_len = sp1 - pubkey - 1;
|
||||
|
||||
*pubkeydata = tmp;
|
||||
*pubkeydata_len = tmp_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* file_read_publickey
|
||||
*
|
||||
@@ -547,7 +617,43 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
memory_read_privatekey(LIBSSH2_SESSION * session,
|
||||
const LIBSSH2_HOSTKEY_METHOD ** hostkey_method,
|
||||
void **hostkey_abstract,
|
||||
const unsigned char *method, int method_len,
|
||||
const char *privkeyfiledata, size_t privkeyfiledata_len,
|
||||
const char *passphrase)
|
||||
{
|
||||
const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =
|
||||
libssh2_hostkey_methods();
|
||||
|
||||
*hostkey_method = NULL;
|
||||
*hostkey_abstract = NULL;
|
||||
while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) {
|
||||
if ((*hostkey_methods_avail)->initPEMFromMemory
|
||||
&& strncmp((*hostkey_methods_avail)->name, (const char *) method,
|
||||
method_len) == 0) {
|
||||
*hostkey_method = *hostkey_methods_avail;
|
||||
break;
|
||||
}
|
||||
hostkey_methods_avail++;
|
||||
}
|
||||
if (!*hostkey_method) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
|
||||
"No handler for specified private key");
|
||||
}
|
||||
|
||||
if ((*hostkey_method)->
|
||||
initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len,
|
||||
(unsigned char *) passphrase,
|
||||
hostkey_abstract)) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Unable to initialize private key from file");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* libssh2_file_read_privatekey
|
||||
* Read a PEM encoded private key from an id_??? style file
|
||||
@@ -595,6 +701,42 @@ struct privkey_file {
|
||||
const char *passphrase;
|
||||
};
|
||||
|
||||
static int
|
||||
sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
const unsigned char *data, size_t data_len, void **abstract)
|
||||
{
|
||||
struct privkey_file *pk_file = (struct privkey_file *) (*abstract);
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
void *hostkey_abstract;
|
||||
struct iovec datavec;
|
||||
int rc;
|
||||
|
||||
rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract,
|
||||
session->userauth_pblc_method,
|
||||
session->userauth_pblc_method_len,
|
||||
pk_file->filename,
|
||||
strlen(pk_file->filename),
|
||||
pk_file->passphrase);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
datavec.iov_base = (void *)data;
|
||||
datavec.iov_len = data_len;
|
||||
|
||||
if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
|
||||
&hostkey_abstract)) {
|
||||
if (privkeyobj->dtor) {
|
||||
privkeyobj->dtor(session, abstract);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (privkeyobj->dtor) {
|
||||
privkeyobj->dtor(session, &hostkey_abstract);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
const unsigned char *data, size_t data_len, void **abstract)
|
||||
@@ -648,9 +790,9 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
||||
|
||||
if (session->userauth_host_state == libssh2_NB_state_idle) {
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
unsigned char *pubkeydata, *sig;
|
||||
unsigned char *pubkeydata, *sig = NULL;
|
||||
size_t pubkeydata_len = 0;
|
||||
size_t sig_len;
|
||||
size_t sig_len = 0;
|
||||
void *abstract;
|
||||
unsigned char buf[5];
|
||||
struct iovec datavec[4];
|
||||
@@ -742,7 +884,9 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
||||
datavec[2].iov_base = (void *)session->userauth_host_packet;
|
||||
datavec[2].iov_len = session->userauth_host_packet_len;
|
||||
|
||||
if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) {
|
||||
if (privkeyobj && privkeyobj->signv &&
|
||||
privkeyobj->signv(session, &sig, &sig_len, 3,
|
||||
datavec, &abstract)) {
|
||||
LIBSSH2_FREE(session, session->userauth_host_method);
|
||||
session->userauth_host_method = NULL;
|
||||
LIBSSH2_FREE(session, session->userauth_host_packet);
|
||||
@@ -753,7 +897,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (privkeyobj->dtor) {
|
||||
if (privkeyobj && privkeyobj->dtor) {
|
||||
privkeyobj->dtor(session, &abstract);
|
||||
}
|
||||
|
||||
@@ -1215,6 +1359,65 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
"username/public key combination");
|
||||
}
|
||||
|
||||
/*
|
||||
* userauth_publickey_frommemory
|
||||
* Authenticate using a keypair from memory
|
||||
*/
|
||||
static int
|
||||
userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
size_t username_len,
|
||||
const char *publickeydata,
|
||||
size_t publickeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase)
|
||||
{
|
||||
unsigned char *pubkeydata = NULL;
|
||||
size_t pubkeydata_len = 0;
|
||||
struct privkey_file privkey_file;
|
||||
void *abstract = &privkey_file;
|
||||
int rc;
|
||||
|
||||
privkey_file.filename = privatekeydata;
|
||||
privkey_file.passphrase = passphrase;
|
||||
|
||||
if (session->userauth_pblc_state == libssh2_NB_state_idle) {
|
||||
if (publickeydata_len && publickeydata) {
|
||||
rc = memory_read_publickey(session, &session->userauth_pblc_method,
|
||||
&session->userauth_pblc_method_len,
|
||||
&pubkeydata, &pubkeydata_len,
|
||||
publickeydata, publickeydata_len);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
else if (privatekeydata_len && privatekeydata) {
|
||||
/* Compute public key from private key. */
|
||||
if (_libssh2_pub_priv_keyfilememory(session,
|
||||
&session->userauth_pblc_method,
|
||||
&session->userauth_pblc_method_len,
|
||||
&pubkeydata, &pubkeydata_len,
|
||||
privatekeydata, privatekeydata_len,
|
||||
passphrase))
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Unable to extract public key "
|
||||
"from private key.");
|
||||
}
|
||||
else {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Invalid data in public and private key.");
|
||||
}
|
||||
}
|
||||
|
||||
rc = _libssh2_userauth_publickey(session, username, username_len,
|
||||
pubkeydata, pubkeydata_len,
|
||||
sign_frommemory, &abstract);
|
||||
if(pubkeydata)
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* userauth_publickey_fromfile
|
||||
* Authenticate using a keypair found in the named files
|
||||
@@ -1267,6 +1470,36 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* libssh2_userauth_publickey_frommemory
|
||||
* Authenticate using a keypair from memory
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
const char *user,
|
||||
size_t user_len,
|
||||
const char *publickeyfiledata,
|
||||
size_t publickeyfiledata_len,
|
||||
const char *privatekeyfiledata,
|
||||
size_t privatekeyfiledata_len,
|
||||
const char *passphrase)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(NULL == passphrase)
|
||||
/* if given a NULL pointer, make it point to a zero-length
|
||||
string to save us from having to check this all over */
|
||||
passphrase="";
|
||||
|
||||
BLOCK_ADJUST(rc, session,
|
||||
userauth_publickey_frommemory(session, user, user_len,
|
||||
publickeyfiledata,
|
||||
publickeyfiledata_len,
|
||||
privatekeyfiledata,
|
||||
privatekeyfiledata_len,
|
||||
passphrase));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* libssh2_userauth_publickey_fromfile_ex
|
||||
* Authenticate using a keypair found in the named files
|
||||
*/
|
||||
@@ -1540,6 +1773,8 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
"keyboard-interactive prompt message");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(session->userauth_kybd_prompts[i].text, s,
|
||||
session->userauth_kybd_prompts[i].length);
|
||||
s += session->userauth_kybd_prompts[i].length;
|
||||
|
||||
/* boolean echo[1] */
|
||||
|
476
src/wincng.c
476
src/wincng.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Marc Hoersken <info@marc-hoersken.de>
|
||||
* Copyright (C) 2013-2015 Marc Hoersken <info@marc-hoersken.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -67,6 +67,11 @@
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
|
||||
#define PEM_RSA_HEADER "-----BEGIN RSA PRIVATE KEY-----"
|
||||
#define PEM_RSA_FOOTER "-----END RSA PRIVATE KEY-----"
|
||||
#define PEM_DSA_HEADER "-----BEGIN DSA PRIVATE KEY-----"
|
||||
#define PEM_DSA_FOOTER "-----END DSA PRIVATE KEY-----"
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
@@ -280,6 +285,24 @@ _libssh2_wincng_random(void *buf, int len)
|
||||
return BCRYPT_SUCCESS(ret) ? 0 : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
_libssh2_wincng_safe_free(void *buf, int len)
|
||||
{
|
||||
#ifndef LIBSSH2_CLEAR_MEMORY
|
||||
(void)len;
|
||||
#endif
|
||||
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
#ifdef LIBSSH2_CLEAR_MEMORY
|
||||
if (len > 0)
|
||||
SecureZeroMemory(buf, len);
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
@@ -322,7 +345,7 @@ _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
|
||||
pbHashObject, dwHashObject,
|
||||
key, keylen, 0);
|
||||
if (!BCRYPT_SUCCESS(ret)) {
|
||||
free(pbHashObject);
|
||||
_libssh2_wincng_safe_free(pbHashObject, dwHashObject);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -355,11 +378,11 @@ _libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx,
|
||||
ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0);
|
||||
|
||||
BCryptDestroyHash(ctx->hHash);
|
||||
ctx->hHash = NULL;
|
||||
|
||||
if (ctx->pbHashObject)
|
||||
free(ctx->pbHashObject);
|
||||
|
||||
memset(ctx, 0, sizeof(_libssh2_wincng_hash_ctx));
|
||||
_libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject);
|
||||
ctx->pbHashObject = NULL;
|
||||
ctx->dwHashObject = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -403,11 +426,11 @@ void
|
||||
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx)
|
||||
{
|
||||
BCryptDestroyHash(ctx->hHash);
|
||||
ctx->hHash = NULL;
|
||||
|
||||
if (ctx->pbHashObject)
|
||||
free(ctx->pbHashObject);
|
||||
|
||||
memset(ctx, 0, sizeof(_libssh2_wincng_hash_ctx));
|
||||
_libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject);
|
||||
ctx->pbHashObject = NULL;
|
||||
ctx->dwHashObject = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -449,17 +472,17 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
|
||||
_libssh2_wincng.hAlgHashSHA1,
|
||||
hash, hashlen);
|
||||
|
||||
free(data);
|
||||
_libssh2_wincng_safe_free(data, datalen);
|
||||
|
||||
if (ret) {
|
||||
free(hash);
|
||||
_libssh2_wincng_safe_free(hash, hashlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
datalen = sig_len;
|
||||
data = malloc(datalen);
|
||||
if (!data) {
|
||||
free(hash);
|
||||
_libssh2_wincng_safe_free(hash, hashlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -474,8 +497,8 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
|
||||
ret = BCryptVerifySignature(ctx->hKey, pPaddingInfo,
|
||||
hash, hashlen, data, datalen, flags);
|
||||
|
||||
free(hash);
|
||||
free(data);
|
||||
_libssh2_wincng_safe_free(hash, hashlen);
|
||||
_libssh2_wincng_safe_free(data, datalen);
|
||||
|
||||
return BCRYPT_SUCCESS(ret) ? 0 : -1;
|
||||
}
|
||||
@@ -513,24 +536,62 @@ _libssh2_wincng_load_private(LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const char *passphrase,
|
||||
unsigned char **ppbEncoded,
|
||||
unsigned long *pcbEncoded)
|
||||
unsigned long *pcbEncoded,
|
||||
int tryLoadRSA, int tryLoadDSA)
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned int datalen;
|
||||
int ret;
|
||||
unsigned char *data = NULL;
|
||||
unsigned int datalen = 0;
|
||||
int ret = -1;
|
||||
|
||||
ret = _libssh2_wincng_load_pem(session, filename, passphrase,
|
||||
"-----BEGIN RSA PRIVATE KEY-----",
|
||||
"-----END RSA PRIVATE KEY-----",
|
||||
&data, &datalen);
|
||||
|
||||
if (ret) {
|
||||
if (ret && tryLoadRSA) {
|
||||
ret = _libssh2_wincng_load_pem(session, filename, passphrase,
|
||||
"-----BEGIN DSA PRIVATE KEY-----",
|
||||
"-----END DSA PRIVATE KEY-----",
|
||||
PEM_RSA_HEADER, PEM_RSA_FOOTER,
|
||||
&data, &datalen);
|
||||
}
|
||||
|
||||
if (ret && tryLoadDSA) {
|
||||
ret = _libssh2_wincng_load_pem(session, filename, passphrase,
|
||||
PEM_DSA_HEADER, PEM_DSA_FOOTER,
|
||||
&data, &datalen);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
*ppbEncoded = data;
|
||||
*pcbEncoded = datalen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
_libssh2_wincng_load_private_memory(LIBSSH2_SESSION *session,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase,
|
||||
unsigned char **ppbEncoded,
|
||||
unsigned long *pcbEncoded,
|
||||
int tryLoadRSA, int tryLoadDSA)
|
||||
{
|
||||
unsigned char *data = NULL;
|
||||
unsigned int datalen = 0;
|
||||
int ret = -1;
|
||||
|
||||
(void)passphrase;
|
||||
|
||||
if (ret && tryLoadRSA) {
|
||||
ret = _libssh2_pem_parse_memory(session,
|
||||
PEM_RSA_HEADER, PEM_RSA_FOOTER,
|
||||
privatekeydata, privatekeydata_len,
|
||||
&data, &datalen);
|
||||
}
|
||||
|
||||
if (ret && tryLoadDSA) {
|
||||
ret = _libssh2_pem_parse_memory(session,
|
||||
PEM_DSA_HEADER, PEM_DSA_FOOTER,
|
||||
privatekeydata, privatekeydata_len,
|
||||
&data, &datalen);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
*ppbEncoded = data;
|
||||
*pcbEncoded = datalen;
|
||||
@@ -568,7 +629,7 @@ _libssh2_wincng_asn_decode(unsigned char *pbEncoded,
|
||||
pbEncoded, cbEncoded, 0, NULL,
|
||||
pbDecoded, &cbDecoded);
|
||||
if (!ret) {
|
||||
free(pbDecoded);
|
||||
_libssh2_wincng_safe_free(pbDecoded, cbDecoded);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -639,7 +700,7 @@ _libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded,
|
||||
*ppbDecoded = pbDecoded;
|
||||
*pcbDecoded = cbDecoded;
|
||||
}
|
||||
free(pbInteger);
|
||||
_libssh2_wincng_safe_free(pbInteger, cbInteger);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -684,10 +745,10 @@ _libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded,
|
||||
*pcbCount = length;
|
||||
} else {
|
||||
for (length = 0; length < index; length++) {
|
||||
if (rpbDecoded[length]) {
|
||||
free(rpbDecoded[length]);
|
||||
rpbDecoded[length] = NULL;
|
||||
}
|
||||
_libssh2_wincng_safe_free(rpbDecoded[length],
|
||||
rcbDecoded[length]);
|
||||
rpbDecoded[length] = NULL;
|
||||
rcbDecoded[length] = 0;
|
||||
}
|
||||
free(rpbDecoded);
|
||||
free(rcbDecoded);
|
||||
@@ -700,7 +761,7 @@ _libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded,
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(pbDecoded);
|
||||
_libssh2_wincng_safe_free(pbDecoded, cbDecoded);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -846,7 +907,7 @@ _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, lpszBlobType,
|
||||
&hKey, key, keylen, 0);
|
||||
if (!BCRYPT_SUCCESS(ret)) {
|
||||
free(key);
|
||||
_libssh2_wincng_safe_free(key, keylen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -854,7 +915,7 @@ _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
*rsa = malloc(sizeof(libssh2_rsa_ctx));
|
||||
if (!(*rsa)) {
|
||||
BCryptDestroyKey(hKey);
|
||||
free(key);
|
||||
_libssh2_wincng_safe_free(key, keylen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -865,32 +926,25 @@ _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
static int
|
||||
_libssh2_wincng_rsa_new_private_parse(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
unsigned char *pbEncoded,
|
||||
unsigned long cbEncoded)
|
||||
{
|
||||
BCRYPT_KEY_HANDLE hKey;
|
||||
unsigned char *pbEncoded, *pbStructInfo;
|
||||
unsigned long cbEncoded, cbStructInfo;
|
||||
unsigned char *pbStructInfo;
|
||||
unsigned long cbStructInfo;
|
||||
int ret;
|
||||
|
||||
(void)session;
|
||||
|
||||
ret = _libssh2_wincng_load_private(session, filename,
|
||||
(const char *)passphrase,
|
||||
&pbEncoded, &cbEncoded);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded,
|
||||
PKCS_RSA_PRIVATE_KEY,
|
||||
&pbStructInfo, &cbStructInfo);
|
||||
|
||||
free(pbEncoded);
|
||||
_libssh2_wincng_safe_free(pbEncoded, cbEncoded);
|
||||
|
||||
if (ret) {
|
||||
return -1;
|
||||
@@ -901,7 +955,7 @@ _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
LEGACY_RSAPRIVATE_BLOB, &hKey,
|
||||
pbStructInfo, cbStructInfo, 0);
|
||||
if (!BCRYPT_SUCCESS(ret)) {
|
||||
free(pbStructInfo);
|
||||
_libssh2_wincng_safe_free(pbStructInfo, cbStructInfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -909,7 +963,7 @@ _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
*rsa = malloc(sizeof(libssh2_rsa_ctx));
|
||||
if (!(*rsa)) {
|
||||
BCryptDestroyKey(hKey);
|
||||
free(pbStructInfo);
|
||||
_libssh2_wincng_safe_free(pbStructInfo, cbStructInfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -918,6 +972,31 @@ _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
(*rsa)->cbKeyObject = cbStructInfo;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
|
||||
int
|
||||
_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded;
|
||||
unsigned long cbEncoded;
|
||||
int ret;
|
||||
|
||||
(void)session;
|
||||
|
||||
ret = _libssh2_wincng_load_private(session, filename,
|
||||
(const char *)passphrase,
|
||||
&pbEncoded, &cbEncoded, 1, 0);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _libssh2_wincng_rsa_new_private_parse(rsa, session,
|
||||
pbEncoded, cbEncoded);
|
||||
#else
|
||||
(void)rsa;
|
||||
(void)filename;
|
||||
@@ -929,6 +1008,41 @@ _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded;
|
||||
unsigned long cbEncoded;
|
||||
int ret;
|
||||
|
||||
(void)session;
|
||||
|
||||
ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len,
|
||||
(const char *)passphrase,
|
||||
&pbEncoded, &cbEncoded, 1, 0);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _libssh2_wincng_rsa_new_private_parse(rsa, session,
|
||||
pbEncoded, cbEncoded);
|
||||
#else
|
||||
(void)rsa;
|
||||
(void)filedata;
|
||||
(void)filedata_len;
|
||||
(void)passphrase;
|
||||
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unable to extract private key from memory: "
|
||||
"Method unsupported in Windows CNG backend");
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
const unsigned char *sig,
|
||||
@@ -983,7 +1097,7 @@ _libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
ret = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
free(data);
|
||||
_libssh2_wincng_safe_free(data, datalen);
|
||||
|
||||
return BCRYPT_SUCCESS(ret) ? 0 : -1;
|
||||
}
|
||||
@@ -995,12 +1109,10 @@ _libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa)
|
||||
return;
|
||||
|
||||
BCryptDestroyKey(rsa->hKey);
|
||||
rsa->hKey = NULL;
|
||||
|
||||
if (rsa->pbKeyObject)
|
||||
free(rsa->pbKeyObject);
|
||||
|
||||
memset(rsa, 0, sizeof(libssh2_rsa_ctx));
|
||||
free(rsa);
|
||||
_libssh2_wincng_safe_free(rsa->pbKeyObject, rsa->cbKeyObject);
|
||||
_libssh2_wincng_safe_free(rsa, sizeof(libssh2_rsa_ctx));
|
||||
}
|
||||
|
||||
|
||||
@@ -1094,7 +1206,7 @@ _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
ret = BCryptImportKeyPair(_libssh2_wincng.hAlgDSA, NULL, lpszBlobType,
|
||||
&hKey, key, keylen, 0);
|
||||
if (!BCRYPT_SUCCESS(ret)) {
|
||||
free(key);
|
||||
_libssh2_wincng_safe_free(key, keylen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1102,7 +1214,7 @@ _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
*dsa = malloc(sizeof(libssh2_dsa_ctx));
|
||||
if (!(*dsa)) {
|
||||
BCryptDestroyKey(hKey);
|
||||
free(key);
|
||||
_libssh2_wincng_safe_free(key, keylen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1113,30 +1225,23 @@ _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded, **rpbDecoded;
|
||||
unsigned long cbEncoded, *rcbDecoded, index, length;
|
||||
static int
|
||||
_libssh2_wincng_dsa_new_private_parse(libssh2_dsa_ctx **dsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
unsigned char *pbEncoded,
|
||||
unsigned long cbEncoded)
|
||||
{
|
||||
unsigned char **rpbDecoded;
|
||||
unsigned long *rcbDecoded, index, length;
|
||||
int ret;
|
||||
|
||||
(void)session;
|
||||
|
||||
ret = _libssh2_wincng_load_private(session, filename,
|
||||
(const char *)passphrase,
|
||||
&pbEncoded, &cbEncoded);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded,
|
||||
&rpbDecoded, &rcbDecoded, &length);
|
||||
|
||||
free(pbEncoded);
|
||||
_libssh2_wincng_safe_free(pbEncoded, cbEncoded);
|
||||
|
||||
if (ret) {
|
||||
return -1;
|
||||
@@ -1155,16 +1260,38 @@ _libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
|
||||
}
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
if (rpbDecoded[index]) {
|
||||
free(rpbDecoded[index]);
|
||||
rpbDecoded[index] = NULL;
|
||||
}
|
||||
_libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]);
|
||||
rpbDecoded[index] = NULL;
|
||||
rcbDecoded[index] = 0;
|
||||
}
|
||||
|
||||
free(rpbDecoded);
|
||||
free(rcbDecoded);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
|
||||
int
|
||||
_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded;
|
||||
unsigned long cbEncoded;
|
||||
int ret;
|
||||
|
||||
ret = _libssh2_wincng_load_private(session, filename,
|
||||
(const char *)passphrase,
|
||||
&pbEncoded, &cbEncoded, 0, 1);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _libssh2_wincng_dsa_new_private_parse(dsa, session,
|
||||
pbEncoded, cbEncoded);
|
||||
#else
|
||||
(void)dsa;
|
||||
(void)filename;
|
||||
@@ -1176,6 +1303,39 @@ _libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded;
|
||||
unsigned long cbEncoded;
|
||||
int ret;
|
||||
|
||||
ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len,
|
||||
(const char *)passphrase,
|
||||
&pbEncoded, &cbEncoded, 0, 1);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _libssh2_wincng_dsa_new_private_parse(dsa, session,
|
||||
pbEncoded, cbEncoded);
|
||||
#else
|
||||
(void)dsa;
|
||||
(void)filedata;
|
||||
(void)filedata_len;
|
||||
(void)passphrase;
|
||||
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unable to extract private key from memory: "
|
||||
"Method unsupported in Windows CNG backend");
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
|
||||
const unsigned char *sig_fixed,
|
||||
@@ -1216,14 +1376,14 @@ _libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa,
|
||||
memcpy(sig_fixed, sig, siglen);
|
||||
}
|
||||
|
||||
free(sig);
|
||||
_libssh2_wincng_safe_free(sig, siglen);
|
||||
} else
|
||||
ret = STATUS_NO_MEMORY;
|
||||
} else
|
||||
ret = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
free(data);
|
||||
_libssh2_wincng_safe_free(data, datalen);
|
||||
|
||||
return BCRYPT_SUCCESS(ret) ? 0 : -1;
|
||||
}
|
||||
@@ -1235,12 +1395,10 @@ _libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa)
|
||||
return;
|
||||
|
||||
BCryptDestroyKey(dsa->hKey);
|
||||
dsa->hKey = NULL;
|
||||
|
||||
if (dsa->pbKeyObject)
|
||||
free(dsa->pbKeyObject);
|
||||
|
||||
memset(dsa, 0, sizeof(libssh2_dsa_ctx));
|
||||
free(dsa);
|
||||
_libssh2_wincng_safe_free(dsa->pbKeyObject, dsa->cbKeyObject);
|
||||
_libssh2_wincng_safe_free(dsa, sizeof(libssh2_dsa_ctx));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1250,6 +1408,7 @@ _libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa)
|
||||
* Windows CNG backend: Key functions
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
static unsigned long
|
||||
_libssh2_wincng_pub_priv_write(unsigned char *key,
|
||||
unsigned long offset,
|
||||
@@ -1265,33 +1424,26 @@ _libssh2_wincng_pub_priv_write(unsigned char *key,
|
||||
return offset;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekey,
|
||||
const char *passphrase)
|
||||
static int
|
||||
_libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
unsigned char *pbEncoded,
|
||||
unsigned long cbEncoded)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded, **rpbDecoded;
|
||||
unsigned long cbEncoded, *rcbDecoded;
|
||||
unsigned char **rpbDecoded;
|
||||
unsigned long *rcbDecoded;
|
||||
unsigned char *key = NULL, *mth = NULL;
|
||||
unsigned long keylen = 0, mthlen = 0;
|
||||
unsigned long index, offset, length;
|
||||
int ret;
|
||||
|
||||
ret = _libssh2_wincng_load_private(session, privatekey, passphrase,
|
||||
&pbEncoded, &cbEncoded);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded,
|
||||
&rpbDecoded, &rcbDecoded, &length);
|
||||
|
||||
free(pbEncoded);
|
||||
_libssh2_wincng_safe_free(pbEncoded, cbEncoded);
|
||||
|
||||
if (ret) {
|
||||
return -1;
|
||||
@@ -1364,10 +1516,9 @@ _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
|
||||
|
||||
for (index = 0; index < length; index++) {
|
||||
if (rpbDecoded[index]) {
|
||||
free(rpbDecoded[index]);
|
||||
rpbDecoded[index] = NULL;
|
||||
}
|
||||
_libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]);
|
||||
rpbDecoded[index] = NULL;
|
||||
rcbDecoded[index] = 0;
|
||||
}
|
||||
|
||||
free(rpbDecoded);
|
||||
@@ -1387,6 +1538,32 @@ _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
|
||||
int
|
||||
_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekey,
|
||||
const char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded;
|
||||
unsigned long cbEncoded;
|
||||
int ret;
|
||||
|
||||
ret = _libssh2_wincng_load_private(session, privatekey, passphrase,
|
||||
&pbEncoded, &cbEncoded, 1, 1);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len,
|
||||
pubkeydata, pubkeydata_len,
|
||||
pbEncoded, cbEncoded);
|
||||
#else
|
||||
(void)method;
|
||||
(void)method_len;
|
||||
@@ -1401,6 +1578,45 @@ _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase)
|
||||
{
|
||||
#ifdef HAVE_LIBCRYPT32
|
||||
unsigned char *pbEncoded;
|
||||
unsigned long cbEncoded;
|
||||
int ret;
|
||||
|
||||
ret = _libssh2_wincng_load_private_memory(session, privatekeydata,
|
||||
privatekeydata_len, passphrase,
|
||||
&pbEncoded, &cbEncoded, 1, 1);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len,
|
||||
pubkeydata, pubkeydata_len,
|
||||
pbEncoded, cbEncoded);
|
||||
#else
|
||||
(void)method;
|
||||
(void)method_len;
|
||||
(void)pubkeydata_len;
|
||||
(void)pubkeydata;
|
||||
(void)privatekeydata;
|
||||
(void)privatekeydata_len;
|
||||
(void)passphrase;
|
||||
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unable to extract public key from private key in memory: "
|
||||
"Method unsupported in Windows CNG backend");
|
||||
#endif /* HAVE_LIBCRYPT32 */
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
@@ -1463,10 +1679,10 @@ _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
|
||||
ret = BCryptImportKey(*type.phAlg, NULL, BCRYPT_KEY_DATA_BLOB, &hKey,
|
||||
pbKeyObject, dwKeyObject, key, keylen, 0);
|
||||
|
||||
free(key);
|
||||
_libssh2_wincng_safe_free(key, keylen);
|
||||
|
||||
if (!BCRYPT_SUCCESS(ret)) {
|
||||
free(pbKeyObject);
|
||||
_libssh2_wincng_safe_free(pbKeyObject, dwKeyObject);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1474,7 +1690,7 @@ _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
|
||||
pbIV = malloc(dwBlockLength);
|
||||
if (!pbIV) {
|
||||
BCryptDestroyKey(hKey);
|
||||
free(pbKeyObject);
|
||||
_libssh2_wincng_safe_free(pbKeyObject, dwKeyObject);
|
||||
return -1;
|
||||
}
|
||||
dwIV = dwBlockLength;
|
||||
@@ -1533,7 +1749,7 @@ _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
memcpy(block, pbOutput, cbOutput);
|
||||
}
|
||||
|
||||
free(pbOutput);
|
||||
_libssh2_wincng_safe_free(pbOutput, cbOutput);
|
||||
} else
|
||||
ret = STATUS_NO_MEMORY;
|
||||
}
|
||||
@@ -1545,13 +1761,15 @@ void
|
||||
_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx)
|
||||
{
|
||||
BCryptDestroyKey(ctx->hKey);
|
||||
ctx->hKey = NULL;
|
||||
|
||||
if (ctx->pbKeyObject) {
|
||||
free(ctx->pbKeyObject);
|
||||
ctx->pbKeyObject = NULL;
|
||||
}
|
||||
_libssh2_wincng_safe_free(ctx->pbKeyObject, ctx->dwKeyObject);
|
||||
ctx->pbKeyObject = NULL;
|
||||
ctx->dwKeyObject = 0;
|
||||
|
||||
memset(ctx, 0, sizeof(_libssh2_cipher_ctx));
|
||||
_libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength);
|
||||
ctx->pbIV = NULL;
|
||||
ctx->dwBlockLength = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1585,6 +1803,12 @@ _libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length)
|
||||
if (length == bn->length)
|
||||
return 0;
|
||||
|
||||
#ifdef LIBSSH2_CLEAR_MEMORY
|
||||
if (bn->bignum && bn->length > 0 && length < bn->length) {
|
||||
SecureZeroMemory(bn->bignum + length, bn->length - length);
|
||||
}
|
||||
#endif
|
||||
|
||||
bignum = realloc(bn->bignum, length);
|
||||
if (!bignum)
|
||||
return -1;
|
||||
@@ -1692,7 +1916,7 @@ _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
|
||||
r->bignum, r->length, &offset,
|
||||
BCRYPT_PAD_NONE);
|
||||
|
||||
free(bignum);
|
||||
_libssh2_wincng_safe_free(bignum, length);
|
||||
|
||||
if (BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng_bignum_resize(r, offset);
|
||||
@@ -1706,7 +1930,7 @@ _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
|
||||
BCryptDestroyKey(hKey);
|
||||
}
|
||||
|
||||
free(key);
|
||||
_libssh2_wincng_safe_free(key, keylen);
|
||||
|
||||
return BCRYPT_SUCCESS(ret) ? 0 : -1;
|
||||
}
|
||||
@@ -1784,6 +2008,10 @@ _libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len,
|
||||
if (offset > 0) {
|
||||
memmove(bn->bignum, bn->bignum + offset, length);
|
||||
|
||||
#ifdef LIBSSH2_CLEAR_MEMORY
|
||||
SecureZeroMemory(bn->bignum + length, offset);
|
||||
#endif
|
||||
|
||||
bignum = realloc(bn->bignum, length);
|
||||
if (bignum) {
|
||||
bn->bignum = bignum;
|
||||
@@ -1805,11 +2033,11 @@ _libssh2_wincng_bignum_free(_libssh2_bn *bn)
|
||||
{
|
||||
if (bn) {
|
||||
if (bn->bignum) {
|
||||
free(bn->bignum);
|
||||
_libssh2_wincng_safe_free(bn->bignum, bn->length);
|
||||
bn->bignum = NULL;
|
||||
}
|
||||
bn->length = 0;
|
||||
free(bn);
|
||||
_libssh2_wincng_safe_free(bn, sizeof(_libssh2_bn));
|
||||
}
|
||||
}
|
||||
|
||||
|
50
src/wincng.h
50
src/wincng.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Marc Hoersken <info@marc-hoersken.de>
|
||||
* Copyright (C) 2013-2015 Marc Hoersken <info@marc-hoersken.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -122,8 +122,8 @@ typedef struct __libssh2_wincng_hash_ctx {
|
||||
|
||||
#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx
|
||||
#define libssh2_sha1_init(ctx) \
|
||||
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
|
||||
SHA_DIGEST_LENGTH, NULL, 0)
|
||||
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
|
||||
SHA_DIGEST_LENGTH, NULL, 0) == 0)
|
||||
#define libssh2_sha1_update(ctx, data, datalen) \
|
||||
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_sha1_final(ctx, hash) \
|
||||
@@ -134,8 +134,8 @@ typedef struct __libssh2_wincng_hash_ctx {
|
||||
|
||||
#define libssh2_md5_ctx _libssh2_wincng_hash_ctx
|
||||
#define libssh2_md5_init(ctx) \
|
||||
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
|
||||
MD5_DIGEST_LENGTH, NULL, 0)
|
||||
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
|
||||
MD5_DIGEST_LENGTH, NULL, 0) == 0)
|
||||
#define libssh2_md5_update(ctx, data, datalen) \
|
||||
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_md5_final(ctx, hash) \
|
||||
@@ -149,6 +149,7 @@ typedef struct __libssh2_wincng_hash_ctx {
|
||||
*/
|
||||
|
||||
#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx
|
||||
#define libssh2_hmac_ctx_init(ctx)
|
||||
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \
|
||||
SHA_DIGEST_LENGTH, key, keylen)
|
||||
@@ -190,6 +191,10 @@ typedef struct __libssh2_wincng_key_ctx {
|
||||
e1, e1_len, e2, e2_len, c, c_len)
|
||||
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
|
||||
_libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase)
|
||||
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
|
||||
filedata_len, passphrase) \
|
||||
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
|
||||
filedata_len, passphrase)
|
||||
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
|
||||
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
|
||||
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
|
||||
@@ -206,8 +211,12 @@ typedef struct __libssh2_wincng_key_ctx {
|
||||
g, g_len, y, y_len, x, x_len) \
|
||||
_libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \
|
||||
g, g_len, y, y_len, x, x_len)
|
||||
#define _libssh2_dsa_new_private(rsactx, s, filename, passphrase) \
|
||||
_libssh2_wincng_dsa_new_private(rsactx, s, filename, passphrase)
|
||||
#define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \
|
||||
_libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase)
|
||||
#define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \
|
||||
filedata_len, passphrase) \
|
||||
_libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \
|
||||
filedata_len, passphrase)
|
||||
#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \
|
||||
_libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig)
|
||||
#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \
|
||||
@@ -221,6 +230,10 @@ typedef struct __libssh2_wincng_key_ctx {
|
||||
|
||||
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
|
||||
_libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
|
||||
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
|
||||
pk, pk_len, pw) \
|
||||
_libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
|
||||
pk, pk_len, pw)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
@@ -303,6 +316,8 @@ _libssh2_bn *_libssh2_wincng_bignum_init(void);
|
||||
|
||||
#define _libssh2_bn_init() \
|
||||
_libssh2_wincng_bignum_init()
|
||||
#define _libssh2_bn_init_from_bin() \
|
||||
_libssh2_bn_init()
|
||||
#define _libssh2_bn_rand(bn, bits, top, bottom) \
|
||||
_libssh2_wincng_bignum_rand(bn, bits, top, bottom)
|
||||
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \
|
||||
@@ -381,6 +396,12 @@ _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase);
|
||||
int
|
||||
_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
int
|
||||
_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
@@ -415,6 +436,12 @@ _libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase);
|
||||
int
|
||||
_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
int
|
||||
_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
|
||||
const unsigned char *sig_fixed,
|
||||
const unsigned char *m,
|
||||
@@ -436,6 +463,15 @@ _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
int
|
||||
_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
|
||||
|
110
tests/CMakeLists.txt
Normal file
110
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,110 @@
|
||||
# Copyright (c) 2014, 2015 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above
|
||||
# copyright notice, this list of conditions and the
|
||||
# following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# Neither the name of the copyright holder nor the names
|
||||
# of any other contributors may be used to endorse or
|
||||
# promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckSymbolExists)
|
||||
include(BundleUtilities)
|
||||
include(CopyRuntimeDependencies)
|
||||
include(SocketLibraries)
|
||||
|
||||
## Platform checks
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
check_include_files(windows.h HAVE_WINDOWS_H)
|
||||
check_include_files(winsock2.h HAVE_WINSOCK2_H)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libssh2_config_cmake.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh2_config.h)
|
||||
|
||||
set(TESTS
|
||||
simple
|
||||
ssh2)
|
||||
|
||||
append_needed_socket_libraries(LIBRARIES)
|
||||
|
||||
foreach(test ${TESTS})
|
||||
add_executable(test-${test} ${test}.c)
|
||||
target_link_libraries(test-${test} libssh2 ${LIBRARIES})
|
||||
target_include_directories(test-${test} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
list(APPEND TEST_TARGETS test-${test})
|
||||
endforeach()
|
||||
|
||||
add_target_to_copy_dependencies(
|
||||
TARGET copy_test_dependencies
|
||||
DEPENDENCIES ${RUNTIME_DEPENDENCIES}
|
||||
BEFORE_TARGETS ${TEST_TARGETS})
|
||||
|
||||
# TODO convert mansyntax.sh into CMake script.
|
||||
# XXX Just because we can find all three programs, doesn't mean sh can
|
||||
# find man and grep
|
||||
find_program(SH_EXECUTABLE sh)
|
||||
find_program(MAN_EXECUTABLE man)
|
||||
find_program(GREP_EXECUTABLE grep)
|
||||
mark_as_advanced(SH_EXECUTABLE MAN_EXECUTABLE GREP_EXECUTABLE)
|
||||
if(SH_EXECUTABLE AND MAN_EXECUTABLE AND GREP_EXECUTABLE)
|
||||
add_test(mansyntax
|
||||
${SH_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/mansyntax.sh")
|
||||
endif()
|
||||
|
||||
add_test(simple test-simple)
|
||||
|
||||
find_program(SSHD_EXECUTABLE sshd)
|
||||
find_program(CHMOD_EXECUTABLE chmod)
|
||||
find_program(KILL_EXECUTABLE kill)
|
||||
mark_as_advanced(SSHD_EXECUTABLE CHMOD_EXECUTABLE KILL_EXECUTABLE)
|
||||
if(SSHD_EXECUTABLE AND CHMOD_EXECUTABLE AND KILL_EXECUTABLE)
|
||||
set(SSHD_TEST_CONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(TEST_NAME ssh2)
|
||||
|
||||
add_custom_command(
|
||||
TARGET test-${TEST_NAME}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/etc
|
||||
${SSHD_TEST_CONFIG_DIR}/etc)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sshd_fixture.sh.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/test-${TEST_NAME}_fixture.sh
|
||||
@ONLY)
|
||||
|
||||
add_test(NAME ssh2 COMMAND ${SH_EXECUTABLE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/test-${TEST_NAME}_fixture.sh
|
||||
$<TARGET_FILE:test-${TEST_NAME}>)
|
||||
|
||||
endif()
|
43
tests/libssh2_config_cmake.h.in
Normal file
43
tests/libssh2_config_cmake.h.in
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Headers */
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
#cmakedefine HAVE_INTTYPES_H
|
||||
#cmakedefine HAVE_SYS_SOCKET_H
|
||||
#cmakedefine HAVE_ARPA_INET_H
|
||||
#cmakedefine HAVE_WINDOWS_H
|
||||
#cmakedefine HAVE_WINSOCK2_H
|
@@ -6,14 +6,15 @@ set -e
|
||||
# Run syntax checks for all manpages in the documentation tree.
|
||||
#
|
||||
|
||||
srcdir=${srcdir:-$PWD}
|
||||
srcdir="`cd $(dirname $0);pwd`"
|
||||
mandir=${srcdir}/../docs
|
||||
|
||||
#
|
||||
# Only test if suitable man is available
|
||||
#
|
||||
if ! man --help | grep -q warnings; then
|
||||
exit 77
|
||||
echo "man version not suitable, skipping tests"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ec=0
|
||||
|
@@ -80,7 +80,7 @@ int main(int argc, char *argv[])
|
||||
if (connect(sock, (struct sockaddr*)(&sin),
|
||||
sizeof(struct sockaddr_in)) != 0) {
|
||||
fprintf(stderr, "failed to connect!\n");
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create a session instance and start it up
|
||||
@@ -89,7 +89,7 @@ int main(int argc, char *argv[])
|
||||
session = libssh2_session_init();
|
||||
if (libssh2_session_startup(session, sock)) {
|
||||
fprintf(stderr, "Failure establishing SSH session\n");
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* At this point we havn't authenticated,
|
||||
|
53
tests/sshd_fixture.sh.in
Normal file
53
tests/sshd_fixture.sh.in
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Written by Simon Josefsson.
|
||||
|
||||
# Start sshd, invoke parameters, saving exit code, kill sshd, and
|
||||
# return exit code.
|
||||
|
||||
srcdir="@SSHD_TEST_CONFIG_DIR@"
|
||||
SSHD="@SSHD_EXECUTABLE@"
|
||||
|
||||
cmd="\"$1\""
|
||||
|
||||
PRIVKEY=$srcdir/etc/user
|
||||
export PRIVKEY
|
||||
PUBKEY=$srcdir/etc/user.pub
|
||||
export PUBKEY
|
||||
|
||||
if test -n "$DEBUG"; then
|
||||
libssh2_sshd_params="-d -d"
|
||||
fi
|
||||
|
||||
chmod go-rwx "$srcdir"/etc/host*
|
||||
"$SSHD" -f /dev/null -h "$srcdir/etc/host" \
|
||||
-o 'Port 4711' \
|
||||
-o 'Protocol 2' \
|
||||
-o "AuthorizedKeysFile \"$srcdir/etc/user.pub\"" \
|
||||
-o 'UsePrivilegeSeparation no' \
|
||||
-o 'StrictModes no' \
|
||||
-D \
|
||||
$libssh2_sshd_params &
|
||||
sshdpid=$!
|
||||
|
||||
trap "kill ${sshdpid}; echo signal killing sshd; exit 1;" EXIT
|
||||
|
||||
: "started sshd (${sshdpid})"
|
||||
|
||||
sleep 3
|
||||
|
||||
if ! kill -0 ${sshdpid}
|
||||
then
|
||||
echo "SSHD exited before test started"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: Invoking $cmd...
|
||||
eval "$cmd"
|
||||
ec=$?
|
||||
: Self-test exit code $ec
|
||||
|
||||
: "killing sshd (${sshdpid})"
|
||||
kill "${sshdpid}" > /dev/null 2>&1
|
||||
trap "" EXIT
|
||||
exit $ec
|
@@ -110,7 +110,7 @@ endif
|
||||
-include $(OBJDIR)/version.inc
|
||||
|
||||
# Global flags for all compilers
|
||||
CFLAGS = $(OPT) -D$(DB) -DLIBSSH2_WIN32 # -DHAVE_CONFIG_H
|
||||
CFLAGS = $(LIBSSH2_CFLAG_EXTRAS) $(OPT) -D$(DB) -DLIBSSH2_WIN32 # -DHAVE_CONFIG_H
|
||||
|
||||
ifeq ($(CC),mwcc)
|
||||
LD = mwld
|
||||
|
Reference in New Issue
Block a user