Skip to content

Commit

Permalink
Basic dockerised test suite.
Browse files Browse the repository at this point in the history
This introduces a test suite for libssh2. It runs OpenSSH in a Docker
container because that works well on Windows (via docker-machine) as
well as Linux. Presumably it works on Mac too with docker-machine, but
I've not tested that.

Because the test suite is docker-machine aware, you can also run it
against a cloud provider, for more realistic network testing, by setting
your cloud provider as your active docker machine. The Appveyor CI setup
in this commit does that because Appveyor doesn't support docker
locally.
  • Loading branch information
alamaison authored Aug 14, 2016
1 parent 1fc7c85 commit cf80f2f
Show file tree
Hide file tree
Showing 30 changed files with 1,337 additions and 47 deletions.
22 changes: 16 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.

sudo: required

services:
- docker

language: c

compiler:
Expand All @@ -59,12 +64,17 @@ env:
- 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
# Fix issue with chrome and 32-bit multilib
# See http://www.omgubuntu.co.uk/2016/03/fix-failed-to-fetch-google-chrome-apt-error-ubuntu
- sudo sed -i -e 's/deb http/deb [arch=amd64] http/' "/etc/apt/sources.list.d/google-chrome.list"
- sudo sed -i -e 's/deb http/deb [arch=amd64] http/' "/opt/google/chrome/cron/google-chrome"
- if [ $ADDRESS_SIZE = '32' ]; then sudo dpkg --add-architecture i386; fi
- if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get update -qq; fi
- if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get install -y gcc-multilib; fi
- if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get install -y libssl-dev:i386 libgcrypt11-dev:i386 build-essential gcc-multilib; fi
- if [ $ADDRESS_SIZE = '32' ]; then sudo dpkg --purge --force-depends gcc-multilib && sudo dpkg --purge --force-depends libssl-dev; fi
- if [ $ADDRESS_SIZE = '64' ]; then sudo apt-get install -y libssl-dev; fi
- if [ $ADDRESS_SIZE = '64' ]; then sudo apt-get install -y libgcrypt11-dev; fi
- if [ $ADDRESS_SIZE = '32' ]; then export TOOLCHAIN_OPTION="-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-Linux-32.cmake"; fi

install:
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ project(libssh2 C)
set(PROJECT_URL "https://www.libssh2.org/")
set(PROJECT_DESCRIPTION "The SSH library")

if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
set (CMAKE_C_FLAGS "--std=gnu90 ${CMAKE_C_FLAGS}")
endif()
else()
set (CMAKE_C_STANDARD 90)
endif()

option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)

# Parse version
Expand Down
24 changes: 21 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ environment:
- GENERATOR: "Visual Studio 9 2008"
BUILD_SHARED_LIBS: OFF

digitalocean_access_token:
secure: 8qRitvrj69Xhf0Tmu27xnz5drmL2YhmOJLGpXIkYyTCC0JNtBoXW6fMcF3u4Uj1+pIQ+TjegQOwYimlz0oivKTro3v3EXro+osAMNJG6NKc=

platform:
- x86
- x64
Expand All @@ -66,19 +69,34 @@ configuration:
- Release

matrix:
fast_finish: true
allow_failures:
- GENERATOR: "Visual Studio 9 2008"
platform: x64

install:
- choco install -y docker
- choco install -y docker-machine

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%"

before_test:
- set DOCKER_MACHINE_NAME=appveyor-%APPVEYOR_PROJECT_SLUG%-%APPVEYOR_JOB_ID%
- ps: if($env:digitalocean_access_token) { echo "Using DigitalOcean for testing." } else { echo "DigitalOcean not available. Skipping testing." }
- ps: if($env:digitalocean_access_token) { docker-machine create --driver digitalocean --digitalocean-access-token $($env:digitalocean_access_token) $($env:DOCKER_MACHINE_NAME) }
- ps: if($env:digitalocean_access_token) { docker-machine env $($env:DOCKER_MACHINE_NAME) --shell powershell | Invoke-Expression }

test_script:
- ps: cd _builds
- ctest -VV -C "%CONFIGURATION%" -E ssh2 --output-on-failure
- ps: if($env:digitalocean_access_token) { ctest -VV -C $($env:CONFIGURATION) --output-on-failure }

after_test:
- ps: if($env:digitalocean_access_token) { docker-machine rm -y $($env:DOCKER_MACHINE_NAME) }

on_failure:
- ps: if (Test-Path _builds/CMakeFiles/CMakeOutput.log) { cat _builds/CMakeFiles/CMakeOutput.log }
- ps: if (Test-Path _builds/CMakeFiles/CMakeError.log) { cat _builds/CMakeFiles/CMakeError.log }
- ps: if($env:digitalocean_access_token) { docker-machine rm -y $($env:DOCKER_MACHINE_NAME) }
- ps: if(Test-Path _builds/CMakeFiles/CMakeOutput.log) { cat _builds/CMakeFiles/CMakeOutput.log }
- ps: if(Test-Path _builds/CMakeFiles/CMakeError.log) { cat _builds/CMakeFiles/CMakeError.log }
73 changes: 35 additions & 38 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2014, 2015 Alexander Lamaison <[email protected]>
# Copyright (c) 2014-2016 Alexander Lamaison <[email protected]>
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
Expand Down Expand Up @@ -47,29 +47,53 @@ 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)
"${CMAKE_CURRENT_SOURCE_DIR}/libssh2_config_cmake.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/libssh2_config.h")
append_needed_socket_libraries(LIBRARIES)

set(TESTS
simple
ssh2)
hostkey
hostkey_hash
password_auth_succeeds_with_correct_credentials
password_auth_fails_with_wrong_password
password_auth_fails_with_wrong_username
public_key_auth_fails_with_wrong_key
public_key_auth_succeeds_with_correct_rsa_key
public_key_auth_succeeds_with_correct_dsa_key
keyboard_interactive_auth_fails_with_wrong_response
keyboard_interactive_auth_succeeds_with_correct_response
)

append_needed_socket_libraries(LIBRARIES)
add_library(openssh_fixture STATIC openssh_fixture.h openssh_fixture.c)
target_link_libraries(openssh_fixture ${LIBRARIES})
target_include_directories(openssh_fixture PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")

add_library(session_fixture STATIC session_fixture.h session_fixture.c)
target_link_libraries(session_fixture ${LIBRARIES} openssh_fixture libssh2)
target_include_directories(session_fixture PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")

add_library(runner STATIC runner.c)
target_link_libraries(runner session_fixture)
target_include_directories(runner PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")

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})
add_executable(test_${test} test_${test}.c)
target_link_libraries(test_${test} libssh2 runner ${LIBRARIES})
target_include_directories(test_${test} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
list(APPEND TEST_TARGETS test_${test})

add_test(
NAME test_${test} COMMAND $<TARGET_FILE:test_${test}>
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
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
Expand All @@ -82,30 +106,3 @@ if(SH_EXECUTABLE AND MAN_EXECUTABLE AND GREP_EXECUTABLE)
set(cmd "${cmd} ${CMAKE_CURRENT_SOURCE_DIR}/mansyntax.sh")
add_test(mansyntax ${SH_EXECUTABLE} -c "${cmd}")
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()
12 changes: 12 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@ TESTS_ENVIRONMENT += srcdir=$(top_srcdir)/tests builddir=$(top_builddir)/tests
EXTRA_DIST = ssh2.sh mansyntax.sh
EXTRA_DIST += etc/host etc/host.pub etc/user etc/user.pub
EXTRA_DIST += CMakeLists.txt libssh2_config_cmake.h.in sshd_fixture.sh.in
EXTRA_DIST += key_dsa key_dsa.pub key_dsa_wrong key_dsa_wrong.pub key_rsa key_rsa.pub
EXTRA_DIST += openssh_server/authorized_keys openssh_server/Dockerfile openssh_server/ssh_host_rsa_key
EXTRA_DIST += openssh_fixture.c openssh_fixture.h runner.c session_fixture.c session_fixture.h
EXTRA_DIST += test_hostkey.c test_hostkey_hash.c
EXTRA_DIST += test_keyboard_interactive_auth_fails_with_wrong_response.c
EXTRA_DIST += test_keyboard_interactive_auth_succeeds_with_correct_response.c
EXTRA_DIST += test_password_auth_fails_with_wrong_password.c
EXTRA_DIST += test_password_auth_fails_with_wrong_username.c
EXTRA_DIST += test_password_auth_succeeds_with_correct_credentials.c
EXTRA_DIST += test_public_key_auth_fails_with_wrong_key.c
EXTRA_DIST += test_public_key_auth_succeeds_with_correct_dsa_key.c
EXTRA_DIST += test_public_key_auth_succeeds_with_correct_rsa_key.c
12 changes: 12 additions & 0 deletions tests/key_dsa
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBvAIBAAKBgQCtiYdgpPvFtfi7Ba44DiB+1x8kojjT0nRvn2hU2aa4p4fXI8kd
6Hc57VQO/lLhR9eFpxjP7m+jGwF468Q6NU8xiC71ucep0OoXS7u8RcoIoWfLDtZi
DDlahnZTW04mB5fFxo2y7dYl31vE4TPdSxhqpkvnIBIstMFh2M7Dl0w8/QIVAP95
u6dg1OW6gGsRgiircsy1A9tzAoGBAIzwc5FCnJnzAJm9Hjv0AFV5l/i/DQulZ9pu
EILkNiHCfDR+lTJ8VxAR7J3pgjmvYzeeRvi519ez1YriktDt66kIknQOcHB8ghyg
U+dff79SkDcpg8LnX5xb3cVMgABujA0sSpaW1wwm64RXdvmoQvWu6ympUT0l0dEd
oYVkb4ytAoGAJ+CGwV/1S4j1GVwa6pSP0nj4V86GWXosTTBg7GT+rKWu8lrxIcr6
FzLWgFi/gHoMrgnKWGxO1yF7vkoYM5Yfo84oBYiH+MgpiBuOrZrgzacHsA66JJbU
frESRFWZl2blIPr6Gyjj6cVGgMabK3yCiTRi0v7hwffpm0rKyKv7GooCFQCyaA6T
tkJunHP+F0Xg/WAUV6tcqA==
-----END DSA PRIVATE KEY-----
1 change: 1 addition & 0 deletions tests/key_dsa.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBAK2Jh2Ck+8W1+LsFrjgOIH7XHySiONPSdG+faFTZprinh9cjyR3odzntVA7+UuFH14WnGM/ub6MbAXjrxDo1TzGILvW5x6nQ6hdLu7xFygihZ8sO1mIMOVqGdlNbTiYHl8XGjbLt1iXfW8ThM91LGGqmS+cgEiy0wWHYzsOXTDz9AAAAFQD/ebunYNTluoBrEYIoq3LMtQPbcwAAAIEAjPBzkUKcmfMAmb0eO/QAVXmX+L8NC6Vn2m4QguQ2IcJ8NH6VMnxXEBHsnemCOa9jN55G+LnX17PViuKS0O3rqQiSdA5wcHyCHKBT519/v1KQNymDwudfnFvdxUyAAG6MDSxKlpbXDCbrhFd2+ahC9a7rKalRPSXR0R2hhWRvjK0AAACAJ+CGwV/1S4j1GVwa6pSP0nj4V86GWXosTTBg7GT+rKWu8lrxIcr6FzLWgFi/gHoMrgnKWGxO1yF7vkoYM5Yfo84oBYiH+MgpiBuOrZrgzacHsA66JJbUfrESRFWZl2blIPr6Gyjj6cVGgMabK3yCiTRi0v7hwffpm0rKyKv7Goo= awl03@bounty
12 changes: 12 additions & 0 deletions tests/key_dsa_wrong
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQCE1v/lL1VvjlJMyG7q0wAgl2tqVMzy5h1RVOtDS8bTlXLJg7ks
T63wTmXlp2HedgKkfHCu7AKsjPyg1CTrvRBa8BFEvMoUDARonMwql34aiKVMy/t0
/ehnmCQV+ZMFpsVFnphJpZuXLTW1F3pnEbSNud5sACjbWb51uly5AUynuwIVAOhj
rbNOaAtC1oYki8CVwpkQ8rHhAoGAYSepXRF3GJSjseYgJ2bCgcJS0L9agcvKAf+F
dc+ZDJOchhnZC/hGHsjAfg62KowwKuOYsbcR3S4LJxiERcmRabww+kUIL1E8bLaQ
RbOygNsHU8LyBdSx3WqC2WEOpVkTAjYDWTkbN+qkb53IBoI0GwFt5P9GHvQcAGkj
GJQAWWYCgYAt7vxpDC5Xs6GxbaUupfIP95ZTMx2LqqFjqfT/81nypIHVyIlCnWMi
a0mWGe4qXmHSyk6ZYnsk7Ll6WxdwUrFhd75qERyXlRK2x/v/Q3h9IOwChpHdSFx/
Tq1Zl9vMx3tmS1H0YF9tUdN7g8S5XTUSvYA+0Lzxs/9zOU5fa55+pAIVAKV45RLf
hg2GNXvO68Q4tt3F6kSP
-----END DSA PRIVATE KEY-----
1 change: 1 addition & 0 deletions tests/key_dsa_wrong.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBAITW/+UvVW+OUkzIburTACCXa2pUzPLmHVFU60NLxtOVcsmDuSxPrfBOZeWnYd52AqR8cK7sAqyM/KDUJOu9EFrwEUS8yhQMBGiczCqXfhqIpUzL+3T96GeYJBX5kwWmxUWemEmlm5ctNbUXemcRtI253mwAKNtZvnW6XLkBTKe7AAAAFQDoY62zTmgLQtaGJIvAlcKZEPKx4QAAAIBhJ6ldEXcYlKOx5iAnZsKBwlLQv1qBy8oB/4V1z5kMk5yGGdkL+EYeyMB+DrYqjDAq45ixtxHdLgsnGIRFyZFpvDD6RQgvUTxstpBFs7KA2wdTwvIF1LHdaoLZYQ6lWRMCNgNZORs36qRvncgGgjQbAW3k/0Ye9BwAaSMYlABZZgAAAIAt7vxpDC5Xs6GxbaUupfIP95ZTMx2LqqFjqfT/81nypIHVyIlCnWMia0mWGe4qXmHSyk6ZYnsk7Ll6WxdwUrFhd75qERyXlRK2x/v/Q3h9IOwChpHdSFx/Tq1Zl9vMx3tmS1H0YF9tUdN7g8S5XTUSvYA+0Lzxs/9zOU5fa55+pA== awl03@bounty
27 changes: 27 additions & 0 deletions tests/key_rsa
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAnak1T7zHJ+hVRFBDQ9pf1KVzmd5gaNc7y7NPmL13aOG3sYeJ
evi1x1WM/R3tb8XnUnzZUX9GJN0MYovvZsw9bknG1mDP72LFbGp/gzPddGIKHBBp
vceDaJ85sM/ME3XOtD7uuXQuNAuEHwEzSMMiSIEMcQS+lXIcMLr5xPLEkyNvqsO5
RqSjMTLHKHgY8gLWx7oQ1avokhwuDxF7P3Pqtj+rW2Te6vR0i1H6EyFPsBkzkgNX
b33cus8M1CnTmYTSgJgmHO2LLcGpjQ5sL8T/PWIWHaSqTnkrFXEMysgoteXnAYIL
jzyBaqq2WV4KA3TluGdAP2p8gC32QtKmIuis3QIBIwKCAQB1Hpyhoi2LXCIVfXPM
AU6AtWvRY12PtdSl8uqr+nX2JATNBZlUCTaUE6qQJNxEZyDeMNvzZdxV5gkzQ2Fi
TpQIyRddbH01fJKoTxzlHzbLfAeCj9mFqicahOkHAMN8K6Ddqxe89zhD60w0SgjW
91tLzZQ2sxE70RxBdPQOpbaZLxmUZSVxRgf5djotyZqB4CcGblKCEZYJ9ZemgCnF
gEcSsqcn0Jxfu+aEJ4WinN2orWs+okfgsUu9G9Ozwcy9Ptq1LkIzcwwTIpL7TTDd
LMvhql39a07SysepjFRHxjvXh8Gv+SsLvKQPJHheVv8XoG0dZd+9/Eden9rHKoVm
vGPLAoGBANGDQtv5K/md/3sRGeJ6Ir3/Ao+WMe8C5onck+hW4y/2yQqm3ZLzyZon
KdWRj2q4dnxFZyoyDgX0UHLpM4aSsMRjn4C6vcPLcYaZ9CGB5FWPGZrq+q6vuMGK
V9/fo4ZNFkNK3wo4WCSgxC1Y8XUJc3klOvPVjsmVxZaeZnkukkAFAoGBAMCkqe/S
hrKITzjZuyGN90a2Nq+3xMNGuc400Qvoi27D1OcSn7SJ/K3tVWbENOH3CAlkmlZT
46IM2SRRmM0bxF3aThEwnsD5yPqgz+tcweX+gK3nXnP5JZfYF1kArXk80/eYhNE9
PwnJNXDQMoxaM0/X6BVgQyt03/Q12lH9u0j5AoGAR9U7fp6Su/uoDO/rnhs/HJHy
P9u5WULSsuyKe4uBF8JTjp+cbOXeuIJ0vkCI8WPQ2iZsg37gPI5Hd9rtGDJLPATm
OsOuxslowG9MY0J6K/aMb6EFfbiXHckIL3/gS02hO6SkPgSwgZY0odVaGX+VThtk
q18ppDNZr/vLXL+CmZsCgYEAlJxIlG80tZxaXw5dKIN1nPL2/JUUIZz1vFShQ7Nk
P4EglP+9B52lqr5mc9kwHAe1vhpobns6kvP393IlawbKrsz6ZQg/8/PkLw5XQIli
YPeH1pyKsTyKtvcn9DO5BcE1zaGLB9ApULEpOcUuTwPBLvcDfjRREuUhywT44Coi
w0MCgYAX5yc7/Z3R6M30rGsrgb1Y2siHYsi2LCygUj7TDGQYpaZN4afPJOT5H/Nr
7x7dgZkbOR6PQFm00VgML0XxKih59t0dcQ+2qk1LX5JDKRF/1kER3np6dpceteDu
cC+MEHB/KvijnviAtBZGvD0O7oZgvbkKHESu2igXpAnfXPZFvw==
-----END RSA PRIVATE KEY-----
1 change: 1 addition & 0 deletions tests/key_rsa.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnak1T7zHJ+hVRFBDQ9pf1KVzmd5gaNc7y7NPmL13aOG3sYeJevi1x1WM/R3tb8XnUnzZUX9GJN0MYovvZsw9bknG1mDP72LFbGp/gzPddGIKHBBpvceDaJ85sM/ME3XOtD7uuXQuNAuEHwEzSMMiSIEMcQS+lXIcMLr5xPLEkyNvqsO5RqSjMTLHKHgY8gLWx7oQ1avokhwuDxF7P3Pqtj+rW2Te6vR0i1H6EyFPsBkzkgNXb33cus8M1CnTmYTSgJgmHO2LLcGpjQ5sL8T/PWIWHaSqTnkrFXEMysgoteXnAYILjzyBaqq2WV4KA3TluGdAP2p8gC32QtKmIuis3Q== awl03@bounty
27 changes: 27 additions & 0 deletions tests/libssh2_config_cmake.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,30 @@
#cmakedefine HAVE_ARPA_INET_H
#cmakedefine HAVE_WINDOWS_H
#cmakedefine HAVE_WINSOCK2_H
#cmakedefine HAVE_SNPRINTF

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

0 comments on commit cf80f2f

Please sign in to comment.