Compare commits

...

63 Commits

Author SHA1 Message Date
Daniel Stenberg
cbd5f72339 RELEASE-NOTES: synced with 858930cae5 2015-06-05 17:05:58 +02:00
Marc Hoersken
858930cae5 wincng.c: fixed indentation 2015-05-19 23:12:43 +02:00
sbredahl
08fa27b628 wincng.c: fixed memleak in (block) cipher destructor 2015-05-19 22:59:16 +02:00
Jakob Egger
4383a39d83 libssh2_channel_open: more detailed error message
The error message returned by libssh2_channel_open in case of a server side channel open failure is now more detailed and includes the four standard error conditions in RFC 4254.
2015-05-06 11:28:27 +01:00
Hannes Domani
09c5e59933 kex: fix libgcrypt memory leaks of bignum
Fixes #168.
2015-04-03 17:39:15 +01:00
Marc Hoersken
5a88a86fef configure.ac: check for SecureZeroMemory for clear memory feature 2015-04-03 16:44:53 +02:00
Marc Hoersken
0340d4586e Revert "wincng.c: fix clear memory feature compilation with mingw"
This reverts commit 2d2744efdd.

Autobuilds show that this did not solve the issue.
And it seems like RtlFillMemory is defined to memset,
which would be optimized out by some compilers.
2015-04-03 15:02:39 +02:00
Marc Hoersken
2d2744efdd wincng.c: fix clear memory feature compilation with mingw 2015-04-03 14:48:34 +02:00
LarsNordin-LNdata
e113202098 Enable use of OpenSSL that doesn't have DSA.
Added #if LIBSSH2_DSA for all DSA functions.
2015-04-01 23:04:16 +01:00
LarsNordin-LNdata
983ceafe58 Use correct no-blowfish #define with OpenSSL.
The OpenSSL define is OPENSSL_NO_BF, not OPENSSL_NO_BLOWFISH.
2015-04-01 23:03:28 +01:00
Marc Hoersken
e160ba448e configure: error if explicitly enabled clear-memory is not supported
This takes 22bd8d81d8 and
b8289b625e into account,
but still makes it enabled by default if it is supported
and error out in case it is unsupported and was requested.
2015-03-25 22:42:27 +01:00
Daniel Stenberg
b8289b625e configure: make clear-memory default but only WARN if backend unsupported
... instead of previous ERROR.
2015-03-25 09:57:44 +01:00
Marc Hoersken
5f4c249e42 wincng.h: fix warning about computed return value not being used 2015-03-24 21:46:10 +01:00
Marc Hoersken
6f95c2efd3 nonblocking examples: fix warning about unused tvdiff on Mac OS X 2015-03-24 21:42:10 +01:00
Daniel Stenberg
31a5986c6d openssl: fix compiler warnings 2015-03-24 08:40:43 +01:00
Daniel Stenberg
22bd8d81d8 cofigure: fix --disable-clear-memory check 2015-03-24 08:39:04 +01:00
Marc Hoersken
3d3347c062 scp.c: improved command length calculation
Reduced number of calls to strlen, because shell_quotearg already
returns the length of the resulting string (e.q. quoted path)
which we can add to the existing and known cmd_len.
Removed obsolete call to memset again, because we can put a final
NULL-byte at the end of the string using the calculated length.
2015-03-23 23:17:31 +01:00
Marc Hoersken
2d59b41daa scp.c: improved and streamlined formatting 2015-03-23 23:05:41 +01:00
Marc Hoersken
1e7988cb0d scp.c: fix that scp_recv may transmit not initialised memory 2015-03-23 23:04:24 +01:00
Marc Hoersken
b99204f289 scp.c: fix that scp_send may transmit not initialised memory
Fixes ticket 244. Thanks Torsten.
2015-03-23 22:47:46 +01:00
Marc Hoersken
7ca44fbd94 kex: do not ignore failure of libssh2_sha1_init()
Based upon 43b730ce56.
Fixes ticket 290. Thanks for the suggestion, mstrsn.
2015-03-23 22:25:50 +01:00
Marc Hoersken
41b1cb6751 wincng.h: fix return code of libssh2_md5_init() 2015-03-23 22:23:41 +01:00
Marc Hoersken
84590bc78f openssl.c: fix possible segfault in case EVP_DigestInit fails 2015-03-23 22:07:39 +01:00
Marc Hoersken
864950cf16 wincng.c: fix possible use of uninitialized variables 2015-03-23 21:36:10 +01:00
Marc Hoersken
09a559433e wincng.c: fix unused argument warning if clear memory is not enabled 2015-03-23 21:33:24 +01:00
Marc Hoersken
57dea4df6d wincng: Added explicit clear memory feature to WinCNG backend
This re-introduces the original feature proposed during
the development of the WinCNG crypto backend. It still needs
to be added to libssh2 itself and probably other backends.

Memory is cleared using the function SecureZeroMemory which is
available on Windows systems, just like the WinCNG backend.
2015-03-22 16:52:35 +01:00
Marc Hoersken
77020c7961 wincng.c: fixed mixed line-endings 2015-03-22 16:52:31 +01:00
Marc Hoersken
e52f35d9f4 wincng.c: fixed use of invalid parameter types in a8d14c5dcf 2015-03-22 16:32:50 +01:00
Marc Hoersken
a8d14c5dcf wincng.c: only try to load keys corresponding to the algorithm 2015-03-22 16:29:53 +01:00
Marc Hoersken
0c90b8bd9b wincng.c: moved PEM headers into definitions 2015-03-22 16:22:15 +01:00
Marc Hoersken
3fc17cd69f wincng.h: fixed invalid parameter name 2015-03-22 15:58:22 +01:00
Marc Hoersken
aa4e649d94 wincng: fixed mismatch with declarations in crypto.h 2015-03-22 15:58:00 +01:00
Marc Hoersken
49ea2be885 userauth.c: fixed warning C6001: using uninitialized sig and sig_len 2015-03-22 15:56:48 +01:00
Marc Hoersken
247dfce5fb pem.c: fixed warning C6269: possible incorrect order of operations 2015-03-22 15:54:14 +01:00
Marc Hoersken
71d45d3df1 wincng: add support for authentication keys to be passed in memory
Based upon 18cfec8336 and daa2dfa2db.
2015-03-22 15:41:51 +01:00
Marc Hoersken
daa2dfa2db pem.c: add _libssh2_pem_parse_memory to parse PEM from memory
Requirement to implement 18cfec8336 for Libgcrypt and WinCNG.
2015-03-22 14:39:14 +01:00
Marc Hoersken
1429ad749d pem.c: fix copy and paste mistake from 55d030089b 2015-03-22 13:58:09 +01:00
Marc Hoersken
4078da8d81 userauth.c: fix another possible dereference of a null pointer 2015-03-22 13:53:42 +01:00
Marc Hoersken
0930928810 userauth.c: fix possible dereference of a null pointer 2015-03-22 13:51:47 +01:00
Marc Hoersken
55d030089b pem.c: reduce number of calls to strlen in readline 2015-03-22 13:38:22 +01:00
Will Cosgrove
260410edf3 Initialise HMAC_CTX in more places.
Missed a couple more places we init ctx to avoid openssl threading crash.
2015-03-17 00:06:51 +00:00
Alexander Lamaison
1de36eb5b4 Build build breakage in WinCNG backend caused when adding libssh2_userauth_publickey_frommemory.
The new feature isn't implemented for the WinCNG backend currently, but the WinCNG backend didn't contain any implementation of the required backend functions - even ones that returns an error.  That caused link errors.

This change fixes the problem by providing an implementation of the backend functions that returns an error.
2015-03-16 23:39:30 +00:00
Alexander Lamaison
aa7f9a85f7 Fix breakage in WinCNG backend caused by introducing libssh2_hmac_ctx_init.
The macro was defined to nothing for the libgcrypt backend, but not for WinCNG.  This brings the latter into line with the former.
2015-03-16 23:15:33 +00:00
Daniel Stenberg
41d22ccf26 userauth_publickey_frommemory.3: add AVAILABILITY
... it will be added in 1.6.0
2015-03-15 12:04:10 +01:00
Daniel Stenberg
56f7c0e2a4 libssh2: next version will be called 1.6.0
... since we just added a new function.
2015-03-15 12:03:40 +01:00
Daniel Stenberg
1329dc5155 docs: add libssh2_userauth_publickey_frommemory.3 to dist
The function and man page were added in commit 18cfec8336
2015-03-15 11:48:59 +01:00
Jakob Egger
a1e744bb5e direct_tcpip: Fixed channel write
There were 3 bugs in this loop:
1) Started from beginning after partial writes
2) Aborted when 0 bytes were sent
3) Ignored LIBSSH2_ERROR_EAGAIN

See also:
https://trac.libssh2.org/ticket/281
https://trac.libssh2.org/ticket/293
2015-03-15 11:20:17 +01:00
Will Cosgrove
14d9ee01bc Must init HMAC_CTX before using it.
Must init ctx before using it or openssl will reuse the hmac which is not thread safe and causes a crash.
Added libssh2_hmac_ctx_init macro.
2015-03-15 00:16:46 +00:00
Alexander Lamaison
fed47c34e4 Add continuous integration configurations.
Linux-based CI is done by Travis CI.  Windows-based CI is done by Appveyor.
2015-03-15 00:06:15 +00:00
David Calavera
18cfec8336 Allow authentication keys to be passed in memory.
All credits go to Joe Turpin, I'm just reaplying and cleaning his patch:
http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml

* Use an unimplemented error for extracting keys from memory with libgcrypt.
2015-03-14 23:54:49 +00:00
Daniel Stenberg
74624c8ddf docs: include the renamed INSTALL* files in dist 2015-03-14 17:38:21 +01:00
Alexander Lamaison
bbbdf946a7 Prevent collisions between CMake and Autotools in examples/ and tests/. 2015-03-13 07:47:41 +00:00
Alexander Lamaison
042993b8eb Avoid clash between CMake build and Autotools.
Autotools expects a configuration template file at src/libssh2_config.h.in, which buildconf generates.  But the CMake build system has its CMake-specific version of the file at this path.  This means that, if you don't run buildconf, the Autotools build will fail because it configured the wrong header template.

See https://github.com/libssh2/libssh2/pull/8.
2015-03-13 00:21:04 +00:00
Alexander Lamaison
41ed2b71a2 Merge pull request #8 from alamaison/cmake
CMake build system.
2015-03-12 23:13:39 +00:00
Alexander Lamaison
6bf8983368 CMake build system.
Tested:
 - Windows:
    - Visual C++ 2005/2008/2010/2012/2013/MinGW-w64
    - static/shared
    - 32/64-bit
    - OpenSSL/WinCNG
    - Without zlib
 - Linux:
    - GCC 4.6.3/Clang 3.4
    - static/shared
    - 32/64-bit
    - OpenSSL/Libgcrypt
    - With/Without zlib
 - MacOS X
    - AppleClang 6.0.0
    - static
    - 64-bit
    - OpenSSL
    - Without zlib

Conflicts:
	README
2015-03-12 22:48:38 +00:00
Alexander Lamaison
523a552258 Man man syntax tests fail gracefully if man version is not suitable. 2015-03-12 22:11:47 +00:00
Alexander Lamaison
d73e0ec260 Return valid code from test fixture on failure.
The sshd test fixture was returning -1 if an error occurred, but negative error codes aren't technically valid (google it).  Bash on Windows converted them to 0 which made setup failure look as though all tests were passing.
2015-03-12 21:50:11 +00:00
Alexander Lamaison
1fa5fe6059 Let mansyntax.sh work regardless of where it is called from. 2015-03-12 21:48:59 +00:00
Viktor Szakáts
8f00a7471d mingw build: allow to pass custom CFLAGS
Allow to pass custom `CFLAGS` options via environment variable
`LIBSSH2_CFLAG_EXTRAS`. Default and automatically added options of
`GNUmakefile` have preference over custom ones. This addition is useful
for passing f.e. custom CPU tuning or LTO optimization (`-flto
-ffat-lto-objects`) options. The only current way to do this is to edit
`GNUmakefile`. This patch makes it unnecessary.

This is a mirror of similar libcurl patch:
https://github.com/bagder/curl/pull/136
2015-03-12 11:23:23 +01:00
Will Cosgrove
fe3e23022b userauth: Fixed prompt text no longer being copied to the prompts struct
Regression from 031566f9c
2015-03-11 23:11:28 +01:00
Daniel Stenberg
33e1013d7b README: update the git repo locations 2015-03-11 22:40:37 +01:00
Daniel Stenberg
20eb836f4e wait_socket: wrong use of difftime()
With reversed arguments it would always return a negative value...

Bug: https://github.com/bagder/libssh2/issues/1
2015-03-11 12:16:18 +01:00
Daniel Stenberg
6ada234c62 bump: start working toward 1.5.1 now 2015-03-11 08:21:09 +01:00
54 changed files with 3244 additions and 273 deletions

75
.travis.yml Normal file
View 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
View 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
View File

@@ -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

View File

@@ -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
View 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

View 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()

View 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()

View 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
View 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)

View 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()

View 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
View 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()

View File

@@ -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
View 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
View 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

View File

@@ -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

View 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
View 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)

View File

@@ -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));

View 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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -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";

View File

@@ -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

View File

@@ -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
View 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)

View File

@@ -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");
}
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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,

View File

@@ -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
View 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}

View 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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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
View File

@@ -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)

View File

@@ -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");

View File

@@ -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;

View File

@@ -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] */

View File

@@ -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));
}
}

View File

@@ -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
View 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()

View 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

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -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