Compare commits

...

40 Commits

Author SHA1 Message Date
Jakub Jelen
da6d026c12 Relase 0.9.6
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2021-08-19 09:49:25 +02:00
Jakub Jelen
240bda21dc ChangeLog: Fix release date of 0.9.5
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2021-08-18 19:53:10 +02:00
Jakub Jelen
f3652f6da0 tests: Simple reproducer for rekeying with different kex
We do not use SHA1 as it is disabled in many systems

Verifies CVE-2021-3634

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2021-08-18 14:16:23 +02:00
Jakub Jelen
d3060bc84e CVE-2021-3634: Create a separate length for session_id
Normally, the length of session_id and secret_hash is the same,
but if we will get into rekeying with a peer that changes preference
of key exchange algorithm, the new secret hash can be larger or
smaller than the previous session_id causing invalid reads or writes.

Resolves https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35485

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2021-08-18 14:16:18 +02:00
Jakub Jelen
948bcb773e .gitlab-ci: Allow failure of windows runners as they are broken
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6daa95f9c1)
2021-08-17 18:33:24 +02:00
Jakub Jelen
64b3e358f9 Enable freebsd runner also for jjelen
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 592d256a0b)
2021-08-17 18:33:17 +02:00
Andreas Schneider
2422081e55 gitlab-ci: Enable new freebsd runner
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ae44d846b8)
2021-08-17 18:32:45 +02:00
Andreas Schneider
a10aeb9490 gitlab-ci: Use shared Windows runners from gitlab
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7657994aed)
2021-08-17 16:12:32 +02:00
Norbert Pocs
a629f687cd Fix some compiler warnings
Covscan analyzer was used

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 63f97a3d03)
2021-08-17 15:46:54 +02:00
Xiang Xiao
2dda3514d1 packet: Change the last argument of ssh_packet_encrypt to uint32_t
to match the implemntation in packet_crypt.c

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Change-Id: Ib76c3585f67dae22ed0f1dfc10dadcd03c762032
(cherry picked from commit ef02e524df)
2021-08-17 15:46:54 +02:00
Xiang Xiao
c954ff4b2c mbedtls: Change the last argument of cipher_[de|en]crypt_cbc to size_t
to avoid their prototype different from ssh_cipher_struct

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Change-Id: I6cba2d4fea131f13d028226023da692494caa87d
(cherry picked from commit 50934a542d)
2021-08-17 15:46:54 +02:00
Xiang Xiao
7609ac60a1 Fix error: dereferencing pointer to incomplete type ‘struct timeval’
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Change-Id: I99d2016595966d805c9e27b5c2f2a0a5b4ad8611
(cherry picked from commit 07245c1cdd)
2021-08-17 15:46:54 +02:00
Andreas Schneider
2356152329 tests: Fix running timeout tests on gitlab windows runners
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d2a41e606b)
2021-08-17 15:46:54 +02:00
Jakub Jelen
180cfd0799 ed25519: Harmonize arguments to make new gcc happy
This started failing CI on Fedora with new GCC

/builds/jjelen/libssh-mirror/src/external/ed25519.c:80:48: error: argument 1 of type 'unsigned char *' declared as a pointer [-Werror=array-parameter=]
   80 | int crypto_sign_ed25519_keypair(unsigned char *pk,
      |                                 ~~~~~~~~~~~~~~~^~
In file included from /builds/jjelen/libssh-mirror/src/external/ed25519.c:15:
/builds/jjelen/libssh-mirror/include/libssh/ed25519.h:46:48: note: previously declared as an array 'uint8_t[32]' {aka 'unsigned char[32]'}
   46 | int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
      |                                 ~~~~~~~~~~~~~~~^~
/builds/jjelen/libssh-mirror/src/external/ed25519.c:81:48: error: argument 2 of type 'unsigned char *' declared as a pointer [-Werror=array-parameter=]
   81 |                                 unsigned char *sk)
      |                                 ~~~~~~~~~~~~~~~^~
In file included from /builds/jjelen/libssh-mirror/src/external/ed25519.c:15:
/builds/jjelen/libssh-mirror/include/libssh/ed25519.h:46:68: note: previously declared as an array 'uint8_t[64]' {aka 'unsigned char[64]'}
   46 | int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
      |                                                    ~~~~~~~~~~~~~~~~^~
/builds/jjelen/libssh-mirror/src/external/ed25519.c:117:46: error: argument 5 of type 'const unsigned char *' declared as a pointer [-Werror=array-parameter=]
  117 |                         const unsigned char *sk)
      |                         ~~~~~~~~~~~~~~~~~~~~~^~
In file included from /builds/jjelen/libssh-mirror/src/external/ed25519.c:15:
/builds/jjelen/libssh-mirror/include/libssh/ed25519.h:61:27: note: previously declared as an array 'const uint8_t[64]' {aka 'const unsigned char[64]'}
   61 |     const ed25519_privkey sk);
      |     ~~~~~~~~~~~~~~~~~~~~~~^~
/builds/jjelen/libssh-mirror/src/external/ed25519.c:180:51: error: argument 5 of type 'const unsigned char *' declared as a pointer [-Werror=array-parameter=]
  180 |                              const unsigned char *pk)
      |                              ~~~~~~~~~~~~~~~~~~~~~^~
In file included from /builds/jjelen/libssh-mirror/src/external/ed25519.c:15:
/builds/jjelen/libssh-mirror/include/libssh/ed25519.h:76:26: note: previously declared as an array 'const uint8_t[32]' {aka 'const unsigned char[32]'}
   76 |     const ed25519_pubkey pk);
      |     ~~~~~~~~~~~~~~~~~~~~~^~

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 9e0d76fb67)
2021-08-17 15:46:54 +02:00
DDoSolitary
3e51232c69 cmake: Fix Ninja multiple rules error
Currently "cmake -G Ninja" complains about "multiple rules generate
src/libssh_dev.map", because the target has the same name as the output
of the custom command.

Signed-off-by: DDoSolitary <DDoSolitary@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 1a24b424ef)
2021-08-17 15:46:54 +02:00
Jakub Jelen
d8fea02d2b tests: Cover sftp_new_channel function
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 25f9ca83a4)
2021-08-17 15:46:54 +02:00
Pablo Yaggi
265b826f78 fix sftp_new_channel constructs an invalid object
Fixes T273

Signed-off-by: Pablo Yaggi <pyaggi@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 51b7a2421a)
2021-08-17 15:46:54 +02:00
Jakub Jelen
c2c5604077 Reformat sftp_new_channel
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 78036e98ec)
2021-08-17 15:46:54 +02:00
Chris Townsend
51a0adfc18 [winlocks] Include stdlib.h to avoid crash in Windows
Due to the missing include, the compiler makes assumptions and leads to
a crash in ssh_mutex_lock() during runtime.

Signed-off-by: Chris Townsend <christopher.townsend@canonical.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit a5bb333422)
2021-08-17 15:46:54 +02:00
DDoSolitary
b78db5f5d8 cmake: Support build directories with special characters
Signed-off-by: DDoSolitary <DDoSolitary@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c8b2e68fb8)
2021-08-17 15:46:54 +02:00
DDoSolitary
5e2a2be6cd cmake: Avoid setting compiler flags directly
Calling set_target_properties directly overrides previously set flags,
so replace them with target_compile_definitions and target_link_options.

Signed-off-by: DDoSolitary <DDoSolitary@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0679945383)
2021-08-17 15:46:53 +02:00
Jakub Jelen
7cf3866744 pki: Fix memory leak on error path
Thanks coverity

CID 1445481

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b90cc79cbe)
2021-08-17 15:46:53 +02:00
Jakub Jelen
81b17de7f7 config: Support more identity files in configuration
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a9061ab434)
2021-08-17 15:46:53 +02:00
Jakub Jelen
a2a79ec68a dh-gex: Avoid memory leaks
Thanks oss-fuzz

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29611
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ae809b3cbb)
2021-08-17 15:46:53 +02:00
Jakub Jelen
08f96dcca6 Clean memory on failure paths
Thanks oss-fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28490

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 95a4651d86)
2021-08-17 15:46:53 +02:00
Jakub Jelen
435f45291d include: Introduce secure SSH_SIGNATURE_FREE()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 832abe7f4a)
2021-08-17 15:46:53 +02:00
Andreas Schneider
09e9167329 Happy new year 2021!
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6f934cc488)
2021-08-17 15:46:53 +02:00
Kevin Kane
effb421a88 Fix CMake warning about mismatched if/endif arguments during OpenSSL detection
Signed-off-by: Kevin Kane <kkane@microsoft.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 919387ae64)
2021-08-17 15:46:53 +02:00
Dirkjan Bussink
098ae8c4bd Always check return value of ssh_list_new()
Another item identified during code review was cases where the return
value of ssh_list_new() was not properly checked and handled. This
updates all cases that were missing this to handle failure to allocate a
new list.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0987e6065c)
2021-08-17 15:46:53 +02:00
Dirkjan Bussink
04824e2f5e Add safety checks for all ssh_string_fill calls
These calls can fail and the return code should always be checked. These
issues were identified when code review called it out on new code. The
updates here are to existing code with no behavior changes to make
review simpler.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit daeee74edd)
2021-08-17 15:46:53 +02:00
Dirkjan Bussink
0a5b93e479 Ignore request success and failure message if they are not expected
In https://gitlab.com/libssh/libssh-mirror/-/merge_requests/145#note_463232084
behavior in libssh was identified where it diverges from how for example
OpenSSH behaves. In OpenSSH if a request success of failure message is
received, apart from it being treated as a keepalive message, it is
ignored otherwise.

Libssh does handle the unexpected message and triggers an error
condition internally. This means that with the Dropbear behavior where
it replies to a hostkeys-00@openssh.com message even with a want_reply
= 0 (arguably a bug), libssh enters an error state.

This change makes the libssh behavior match OpenSSH to ignore these
messages. The spec is a bit unclear on whether Dropbear is buggy here or
not, but let's be liberal with the input accepted here in libssh.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f6a2f6190c)
2021-08-17 15:46:53 +02:00
Kevin Kane
761a4d5fa2 Provide OPENSSL_CRYPTO_LIBRARIES synonym for OPENSSL_CRYPTO_LIBRARY
FindOpenSSL.cmake usually defines this synonym, but it doesn't on CMake < 3.16 when building on Windows outside of Cygwin.

Signed-off-by: Kevin Kane <kkane@microsoft.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3c33c39455)
2021-08-17 15:46:53 +02:00
Kevin Kane
bd9a4e2498 cmake: Use OPENSSL_CRYPTO_LIBRARIES CMake variable when linking against OpenSSL
The build currently breaks when attempting to link libssh.so using a
statically-linked OpenSSL. -ldl and -lpthread are required when linking
a binary with the static libcrypto.a. The OPENSSL_CRYPTO_LIBRARY does
not include these dependencies when linking against static OpenSSL.
OPENSSL_CRYPTO_LIBRARIES contains the correct dependencies in both
static and shared configurations; -ldl and -lpthread are not required
when linking against shared libcrypto.so.

This change changes all uses of OPENSSL_CRYPTO_LIBRARY to
OPENSSL_CRYPTO_LIBRARIES to let the FindOpenSSL CMake module always
provide the correct libraries at link time.

Signed-off-by: Kevin Kane <kkane@microsoft.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 026879e9f0)
2021-08-17 15:46:53 +02:00
Jakub Jelen
67b7b383b2 wrapper: Avoid memory leak on errors during key exchange
As reported by oss-fuzz

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28075

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9c6404aa49)
2021-08-17 15:46:53 +02:00
Jakub Jelen
1736cb0567 tests: Disable *cbc ciphers in Dropbear tests
These are disabled in latest since Dropbear 2020.79, while
older do not support anything better than aes-ctr ciphers.

We should implement some dynamic algorithm detection for dropbear
too to increase test coverage.

https://bugs.libssh.org/T252

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 635edc8adb)
2021-08-17 15:46:53 +02:00
Dirkjan Bussink
36e56dcd93 Fix handshake bug with AEAD ciphers and no HMAC overlap
There's currently a bug in libssh that a handshake doesn't complete if
there is no overlap between HMAC methods, but when an AEAD cipher is
used.

In case of an AEAD cipher such as chacha20-poly1305 or aes256-gcm, the
HMAC algorithm that is being picked is not relevant. But the problem
here is that the HMAC still needs to have an overlap in the handshake,
even if it is not used afterwards.

This was found with a very strict server side configuration with libssh
where only AEAD ciphers and EtM HMAC modes are accepted. The client
tested against was dropbear.

Dropbear does have support for chacha20-poly1305 and AES GCM modes, but
no support for EtM HMAC modes. This meant that the libssh server in this
case rejected the dropbear client, even though it is perfectly able to
serve it since dropbear supports AEAD algorithms.

The fix implemented here updates the HMAC phase of the handshake to
handle this case. If it detects an AEAD cipher is used, it uses the HMAC
abbreviations for the method instead. This is the same name that is used
in other places as well. It matches the client to server and server to
client values, but it does depend on the order of things in the
ssh_kex_types_e enum, which I'm assuming here is ok since it's explicit.

I've looked at how to add a test for this, but I couldn't really find a
suitable place for it. I would love some tips if this is easily
possible, or if it's easier for someone else to contribute, that's of
course welcome too.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 42741b1883)
2021-08-17 15:46:53 +02:00
Jakub Jelen
f834e10a47 tests: Test MAC algorithm mismatch when AEAD cipher is selected
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 22f89e043b)
2021-08-17 15:46:53 +02:00
Jakub Jelen
deb9fc015e torture: Place additional configuration options before defaults so they can override them
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit f9bd1db8c3)
2021-08-17 15:46:53 +02:00
Jakub Jelen
f8314af85a client: Reset pending_call_state on disconnect
Fixes T251

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 5348267fa8)
2021-08-17 15:46:53 +02:00
Dirkjan Bussink
1fc8266fcb Fix another memory leak on invalid nid value
In 906cc7e7e9 a memory leak was fixed but
a similar one is present here that needs a fix as well.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e4c5f6d3d9)
2021-08-17 11:02:47 +02:00
52 changed files with 1348 additions and 256 deletions

View File

@@ -197,11 +197,13 @@ freebsd/x86_64:
make && ctest --output-on-failure
tags:
- freebsd
- private
except:
- tags
only:
- branches@libssh/libssh-mirror
- branches@cryptomilk/libssh-mirror
- branches@jjelen/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
@@ -455,7 +457,15 @@ tumbleweed/static-analysis:
paths:
- obj/scan
visualstudio/x86_64:
###############################################################################
# Visual Studio builds #
###############################################################################
.vs:
stage: test
cache:
key: vcpkg.${CI_JOB_NAME}
paths:
- .vcpkg
variables:
ErrorActionPreference: STOP
script:
@@ -470,46 +480,45 @@ visualstudio/x86_64:
- cmake --build .
- ctest --output-on-failure
tags:
- vs2017
- windows
- shared-windows
except:
- tags
only:
- branches@libssh/libssh-mirror
- branches@ansasaki/libssh-mirror
- branches@cryptomilk/libssh-mirror
- branches@jjelen/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
visualstudio/x86:
variables:
ErrorActionPreference: STOP
script:
- $env:VCPKG_DEFAULT_TRIPLET="x86-windows"
before_script:
- choco install --no-progress -y cmake
- $env:Path += ';C:\Program Files\CMake\bin'
- If (!(test-path .vcpkg\archives)) { mkdir -p .vcpkg\archives }
- $env:VCPKG_DEFAULT_BINARY_CACHE="$PWD\.vcpkg\archives"
- echo $env:VCPKG_DEFAULT_BINARY_CACHE
- $env:VCPKG_DEFAULT_TRIPLET="$TRIPLET-windows"
- vcpkg install cmocka
- vcpkg install openssl
- vcpkg install zlib
- vcpkg integrate install
- mkdir -p obj; if ($?) {cd obj}; if (! $?) {exit 1}
- cmake
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_TOOLCHAIN_FILE"
-A $PLATFORM
-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
-DPICKY_DEVELOPER=ON
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON ..
- cmake --build .
- ctest --output-on-failure
tags:
- vs2017
- windows
except:
- tags
only:
- branches@libssh/libssh-mirror
- branches@ansasaki/libssh-mirror
- branches@cryptomilk/libssh-mirror
- branches@jjelen/libssh-mirror
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
# The Windows runners are broken for last month
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/-/issues/40
allow_failure: true
visualstudio/x86_64:
extends: .vs
variables:
PLATFORM: "x64"
TRIPLET: "x64"
visualstudio/x86:
extends: .vs
variables:
PLATFORM: "win32"
TRIPLET: "x86"

View File

@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.9.5 LANGUAGES C)
project(libssh VERSION 0.9.6 LANGUAGES C)
# global needed variable
set(APPLICATION_NAME ${PROJECT_NAME})
@@ -22,7 +22,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.8.6")
set(LIBRARY_VERSION "4.8.7")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
@@ -59,7 +59,13 @@ elseif(WITH_MBEDTLS)
endif (NOT MBEDTLS_FOUND)
else (WITH_GCRYPT)
find_package(OpenSSL)
if (NOT OPENSSL_FOUND)
if (OPENSSL_FOUND)
# On CMake < 3.16, OPENSSL_CRYPTO_LIBRARIES is usually a synonym for OPENSSL_CRYPTO_LIBRARY, but is not defined
# when building on Windows outside of Cygwin. We provide the synonym here, if FindOpenSSL didn't define it already.
if (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
endif (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
else (OPENSSL_FOUND)
find_package(GCrypt)
if (NOT GCRYPT_FOUND)
find_package(MbedTLS)
@@ -67,7 +73,7 @@ else (WITH_GCRYPT)
message(FATAL_ERROR "Could not find OpenSSL, GCrypt or mbedTLS")
endif (NOT MBEDTLS_FOUND)
endif (NOT GCRYPT_FOUND)
endif (NOT OPENSSL_FOUND)
endif (OPENSSL_FOUND)
endif(WITH_GCRYPT)
if (UNIT_TESTING)
@@ -203,10 +209,10 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
endif(UPDATE_ABI)
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET})
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET} VERBATIM)
# Link compile database for clangd
execute_process(COMMAND cmake -E create_symlink
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
"${CMAKE_BINARY_DIR}/compile_commands.json"
"${CMAKE_SOURCE_DIR}/compile_commands.json")

View File

@@ -1,7 +1,23 @@
ChangeLog
==========
version 0.9.5 (released 2020-XX-XX)
version 0.9.6 (released 2021-08-26)
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with
different key exchange mechanism
* Fix several memory leaks on error paths
* Reset pending_call_state on disconnect
* Fix handshake bug with AEAD ciphers and no HMAC overlap
* Use OPENSSL_CRYPTO_LIBRARIES in CMake
* Ignore request success and failure message if they are not expected
* Support more identity files in configuration
* Avoid setting compiler flags directly in CMake
* Support build directories with special characters
* Include stdlib.h to avoid crash in Windows
* Fix sftp_new_channel constructs an invalid object
* Fix Ninja multiple rules error
* Several tests fixes
version 0.9.5 (released 2020-09-10)
* CVE-2020-16135: Avoid null pointer dereference in sftpserver (T232)
* Improve handling of library initialization (T222)
* Fix parsing of subsecond times in SFTP (T219)

View File

@@ -101,53 +101,53 @@ if (OPENSSL_FOUND)
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_aes_128_ctr HAVE_OPENSSL_EVP_AES_CTR)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_aes_128_gcm HAVE_OPENSSL_EVP_AES_GCM)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(CRYPTO_ctr128_encrypt HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_DigestSign HAVE_OPENSSL_EVP_DIGESTSIGN)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_DigestVerify HAVE_OPENSSL_EVP_DIGESTVERIFY)
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_symbol_exists(EVP_PKEY_ED25519 "openssl/evp.h" FOUND_OPENSSL_ED25519)
if (HAVE_OPENSSL_EVP_DIGESTSIGN AND HAVE_OPENSSL_EVP_DIGESTVERIFY AND
@@ -156,7 +156,7 @@ if (OPENSSL_FOUND)
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_symbol_exists(EVP_PKEY_X25519 "openssl/evp.h" HAVE_OPENSSL_X25519)
unset(CMAKE_REQUIRED_INCLUDES)

View File

@@ -302,12 +302,13 @@ function(get_file_list _TARGET_NAME)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND}
-DOUTPUT_PATH="${_get_files_list_OUTPUT_PATH}"
-DDIRECTORIES="${_get_files_list_DIRECTORIES}"
-DFILES_PATTERNS="${_get_files_list_FILES_PATTERNS}"
-DOUTPUT_PATH=${_get_files_list_OUTPUT_PATH}
-DDIRECTORIES=${_get_files_list_DIRECTORIES}
-DFILES_PATTERNS=${_get_files_list_FILES_PATTERNS}
-P ${_GET_FILES_LIST_SCRIPT}
COMMENT
"Searching for files"
VERBATIM
)
if (DEFINED _get_files_list_COPY_TO)
@@ -318,6 +319,7 @@ function(get_file_list _TARGET_NAME)
${_FILES_LIST_OUTPUT_PATH} ${_get_files_list_COPY_TO}
DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_TARGET_NAME} to ${_get_files_list_COPY_TO}"
VERBATIM
)
else()
add_custom_target(${_TARGET_NAME} ALL
@@ -369,12 +371,13 @@ function(extract_symbols _TARGET_NAME)
add_custom_target(
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND}
-DOUTPUT_PATH="${_SYMBOLS_OUTPUT_PATH}"
-DHEADERS_LIST_FILE="${_HEADERS_LIST_FILE}"
-DOUTPUT_PATH=${_SYMBOLS_OUTPUT_PATH}
-DHEADERS_LIST_FILE=${_HEADERS_LIST_FILE}
-DFILTER_PATTERN=${_extract_symbols_FILTER_PATTERN}
-P ${_EXTRACT_SYMBOLS_SCRIPT}
DEPENDS ${_extract_symbols_HEADERS_LIST}
COMMENT "Extracting symbols from headers"
VERBATIM
)
if (DEFINED _extract_symbols_COPY_TO)
@@ -385,6 +388,7 @@ function(extract_symbols _TARGET_NAME)
${_SYMBOLS_OUTPUT_PATH} ${_extract_symbols_COPY_TO}
DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_TARGET_NAME} to ${_extract_symbols_COPY_TO}"
VERBATIM
)
else()
add_custom_target(${_TARGET_NAME} ALL
@@ -449,35 +453,37 @@ function(generate_map_file _TARGET_NAME)
${_TARGET_NAME}_int ALL
COMMAND ${CMAKE_COMMAND}
-DABIMAP_EXECUTABLE=${ABIMAP_EXECUTABLE}
-DSYMBOLS="${_SYMBOLS_FILE}"
-DSYMBOLS=${_SYMBOLS_FILE}
-DCURRENT_MAP=${_generate_map_file_CURRENT_MAP}
-DOUTPUT_PATH="${_MAP_OUTPUT_PATH}"
-DOUTPUT_PATH=${_MAP_OUTPUT_PATH}
-DFINAL=${_generate_map_file_FINAL}
-DBREAK_ABI=${_generate_map_file_BREAK_ABI}
-DRELEASE_NAME_VERSION=${_generate_map_file_RELEASE_NAME_VERSION}
-P ${_GENERATE_MAP_SCRIPT}
DEPENDS ${_generate_map_file_SYMBOLS}
COMMENT "Generating the map ${_TARGET_NAME}"
VERBATIM
)
# Add a custom command setting the map as OUTPUT to allow it to be added as
# a generated source
add_custom_command(
OUTPUT ${_MAP_OUTPUT_PATH}
DEPENDS ${_TARGET_NAME}
DEPENDS ${_TARGET_NAME}_copy
)
if (DEFINED _generate_map_file_COPY_TO)
# Copy the generated map back to the COPY_TO
add_custom_target(${_TARGET_NAME} ALL
add_custom_target(${_TARGET_NAME}_copy ALL
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${_MAP_OUTPUT_PATH}
${_generate_map_file_COPY_TO}
DEPENDS ${_TARGET_NAME}_int
COMMENT "Copying ${_MAP_OUTPUT_PATH} to ${_generate_map_file_COPY_TO}"
VERBATIM
)
else()
add_custom_target(${_TARGET_NAME} ALL
add_custom_target(${_TARGET_NAME}_copy ALL
DEPENDS ${_TARGET_NAME}_int
)
endif()

View File

@@ -233,7 +233,7 @@ static int open_location(struct location *loc, int flag) {
loc->file = fopen(loc->path, flag == READ ? "r":"w");
if (!loc->file) {
if (errno == EISDIR) {
if (chdir(loc->path)) {
if (loc->path != NULL && chdir(loc->path)) {
fprintf(stderr,
"Error changing directory to %s: %s\n",
loc->path, strerror(errno));

View File

@@ -88,7 +88,11 @@ cleanup_push(struct cleanup_node_struct** head_ref,
// Allocate memory for node
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
new_node->next = (*head_ref);
if (head_ref != NULL) {
new_node->next = *head_ref;
} else {
new_node->next = NULL;
}
// Copy new_data
new_node->data = new_data;
@@ -514,6 +518,12 @@ message_callback(UNUSED_PARAM(ssh_session session),
pFd = malloc(sizeof *pFd);
cb_chan = malloc(sizeof *cb_chan);
event_fd_data = malloc(sizeof *event_fd_data);
if (pFd == NULL || cb_chan == NULL || event_fd_data == NULL) {
SAFE_FREE(pFd);
SAFE_FREE(cb_chan);
SAFE_FREE(event_fd_data);
return 1;
}
(*pFd) = socket_fd;
event_fd_data->channel = channel;

View File

@@ -126,8 +126,9 @@ struct ssh_crypto_struct {
ssh_curve25519_pubkey curve25519_server_pubkey;
#endif
ssh_string dh_server_signature; /* information used by dh_handshake. */
size_t digest_len; /* len of the two fields below */
size_t session_id_len;
unsigned char *session_id;
size_t digest_len; /* len of the secret hash */
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
unsigned char *encryptIV;
unsigned char *decryptIV;

View File

@@ -1,7 +1,7 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2003-2009 by Aris Adamantiadis
* Copyright (c) 2003-2021 by Aris Adamantiadis and the libssh team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -80,7 +80,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
size_t start, size_t encrypted_size);
unsigned char *ssh_packet_encrypt(ssh_session session,
void *packet,
unsigned int len);
uint32_t len);
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
unsigned char *mac, enum ssh_hmac_e type);
int ssh_packet_set_newkeys(ssh_session session,

View File

@@ -125,6 +125,8 @@ enum ssh_digest_e ssh_key_hash_from_name(const char *name);
/* SSH Signature Functions */
ssh_signature ssh_signature_new(void);
void ssh_signature_free(ssh_signature sign);
#define SSH_SIGNATURE_FREE(x) \
do { ssh_signature_free(x); x = NULL; } while(0)
int ssh_pki_export_signature_blob(const ssh_signature sign,
ssh_string *sign_blob);

View File

@@ -1 +1 @@
4.8.6
4.8.7

View File

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

View File

@@ -16,7 +16,7 @@ if (WIN32)
)
endif (WIN32)
if (OPENSSL_CRYPTO_LIBRARY)
if (OPENSSL_CRYPTO_LIBRARIES)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
@@ -24,9 +24,9 @@ if (OPENSSL_CRYPTO_LIBRARY)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY}
${OPENSSL_CRYPTO_LIBRARIES}
)
endif (OPENSSL_CRYPTO_LIBRARY)
endif (OPENSSL_CRYPTO_LIBRARIES)
if (MBEDTLS_CRYPTO_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
@@ -331,7 +331,7 @@ target_link_libraries(ssh
PRIVATE ${LIBSSH_LINK_LIBRARIES})
if (WIN32 AND NOT BUILD_SHARED_LIBS)
set_target_properties(ssh PROPERTIES COMPILE_FLAGS "-DLIBSSH_STATIC")
target_compile_definitions(ssh PUBLIC "LIBSSH_STATIC")
endif ()
add_library(ssh::ssh ALIAS ssh)
@@ -342,9 +342,7 @@ if (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
set(MAP_PATH "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_dev.map")
endif (ABIMAP_FOUND)
set_target_properties(ssh
PROPERTIES LINK_FLAGS
"-Wl,--version-script,\"${MAP_PATH}\"")
target_link_libraries(ssh PRIVATE "-Wl,--version-script,\"${MAP_PATH}\"")
endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
set_target_properties(ssh
@@ -358,12 +356,12 @@ set_target_properties(ssh
)
if (WITH_VISIBILITY_HIDDEN)
set_target_properties(ssh PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
set_target_properties(ssh PROPERTIES C_VISIBILITY_PRESET hidden)
endif (WITH_VISIBILITY_HIDDEN)
if (MINGW)
set_target_properties(ssh PROPERTIES LINK_FLAGS "-Wl,--enable-stdcall-fixup")
set_target_properties(ssh PROPERTIES COMPILE_FLAGS "-D_POSIX_SOURCE")
target_link_libraries(ssh PRIVATE "-Wl,--enable-stdcall-fixup")
target_compile_definitions(ssh PRIVATE "_POSIX_SOURCE")
endif ()
@@ -412,12 +410,7 @@ if (BUILD_STATIC_LIB)
)
if (WIN32)
set_target_properties(
ssh-static
PROPERTIES
COMPILE_FLAGS
"-DLIBSSH_STATIC"
)
target_compile_definitions(ssh-static PUBLIC "LIBSSH_STATIC")
endif (WIN32)
endif (BUILD_STATIC_LIB)

View File

@@ -29,6 +29,9 @@
#include <errno.h>
#include <time.h>
#include <stdbool.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAVE_SYS_TIME_H */
#ifndef _WIN32
#include <netinet/in.h>
@@ -117,6 +120,13 @@ ssh_channel ssh_channel_new(ssh_session session)
if (session->channels == NULL) {
session->channels = ssh_list_new();
if (session->channels == NULL) {
ssh_set_error_oom(session);
SSH_BUFFER_FREE(channel->stdout_buffer);
SSH_BUFFER_FREE(channel->stderr_buffer);
SAFE_FREE(channel);
return NULL;
}
}
ssh_list_prepend(session->channels, channel);

View File

@@ -721,6 +721,7 @@ error:
}
session->opts.fd = SSH_INVALID_SOCKET;
session->session_state=SSH_SESSION_STATE_DISCONNECTED;
session->pending_call_state = SSH_PENDING_CALL_NONE;
while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
@@ -770,7 +771,7 @@ error:
}
const char *ssh_copyright(void) {
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2019 "
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2021 "
"Aris Adamantiadis, Andreas Schneider "
"and libssh contributors. "
"Distributed under the LGPL, please refer to COPYING "

View File

@@ -425,6 +425,7 @@ ssh_config_parse_line(ssh_session session,
opcode != SOC_HOST &&
opcode != SOC_MATCH &&
opcode != SOC_INCLUDE &&
opcode != SOC_IDENTITY &&
opcode > SOC_UNSUPPORTED) { /* Ignore all unknown types here */
/* Skip all the options that were already applied */
if (seen[opcode] != 0) {

View File

@@ -29,6 +29,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAVE_SYS_TIME_H */
#include "libssh/libssh.h"
#include "libssh/misc.h"

View File

@@ -377,12 +377,12 @@ void ssh_server_curve25519_init(ssh_session session){
*/
static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
/* ECDH keys */
ssh_string q_c_string;
ssh_string q_s_string;
ssh_string q_c_string = NULL;
ssh_string q_s_string = NULL;
ssh_string server_pubkey_blob = NULL;
/* SSH host keys (rsa,dsa,ecdsa) */
ssh_key privkey;
ssh_key privkey = NULL;
enum ssh_digest_e digest = SSH_DIGEST_AUTO;
ssh_string sig_blob = NULL;
int rc;
@@ -402,7 +402,6 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
SSH_FATAL,
"Incorrect size for server Curve25519 public key: %zu",
ssh_string_len(q_c_string));
SSH_STRING_FREE(q_c_string);
goto error;
}
@@ -460,12 +459,17 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
/* add ecdh public key */
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
if (q_s_string == NULL) {
ssh_set_error_oom(session);
goto error;
}
ssh_string_fill(q_s_string,
session->next_crypto->curve25519_server_pubkey,
CURVE25519_PUBKEY_SIZE);
rc = ssh_string_fill(q_s_string,
session->next_crypto->curve25519_server_pubkey,
CURVE25519_PUBKEY_SIZE);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Could not copy public key");
goto error;
}
rc = ssh_buffer_add_ssh_string(session->out_buffer, q_s_string);
SSH_STRING_FREE(q_s_string);
@@ -508,6 +512,8 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){
return SSH_PACKET_USED;
error:
SSH_STRING_FREE(q_c_string);
SSH_STRING_FREE(q_s_string);
ssh_buffer_reinit(session->out_buffer);
session->session_state=SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;

View File

@@ -263,6 +263,8 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
bignum_safe_free(server_pubkey);
goto error;
}
/* The ownership was passed to the crypto structure */
server_pubkey = NULL;
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
SSH_STRING_FREE(pubkey_blob);
@@ -293,6 +295,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
return SSH_PACKET_USED;
error:
SSH_STRING_FREE(pubkey_blob);
ssh_dh_cleanup(session->next_crypto);
session->session_state = SSH_SESSION_STATE_ERROR;

View File

@@ -361,6 +361,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){
rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
NULL, server_pubkey);
if (rc != SSH_OK) {
SSH_STRING_FREE(pubkey_blob);
bignum_safe_free(server_pubkey);
goto error;
}

View File

@@ -77,8 +77,8 @@ static void get_hram(unsigned char *hram,
}
int crypto_sign_ed25519_keypair(unsigned char *pk,
unsigned char *sk)
int crypto_sign_ed25519_keypair(ed25519_pubkey pk,
ed25519_privkey sk)
{
sc25519 scsk;
ge25519 gepk;
@@ -114,7 +114,7 @@ int crypto_sign_ed25519(unsigned char *sm,
uint64_t *smlen,
const unsigned char *m,
uint64_t mlen,
const unsigned char *sk)
const ed25519_privkey sk)
{
sc25519 sck, scs, scsk;
ge25519 ger;
@@ -177,7 +177,7 @@ int crypto_sign_ed25519_open(unsigned char *m,
uint64_t *mlen,
const unsigned char *sm,
uint64_t smlen,
const unsigned char *pk)
const ed25519_pubkey pk)
{
unsigned int i;
int ret;

View File

@@ -255,7 +255,11 @@ int ssh_getpass(const char *prompt,
/* disable nonblocking I/O */
if (fd & O_NDELAY) {
fcntl(0, F_SETFL, fd & ~O_NDELAY);
ok = fcntl(0, F_SETFL, fd & ~O_NDELAY);
if (ok < 0) {
perror("fcntl");
return -1;
}
}
ok = ssh_gets(prompt, buf, len, verify);
@@ -267,7 +271,11 @@ int ssh_getpass(const char *prompt,
/* close fd */
if (fd & O_NDELAY) {
fcntl(0, F_SETFL, fd);
ok = fcntl(0, F_SETFL, fd);
if (ok < 0) {
perror("fcntl");
return -1;
}
}
if (!ok) {

View File

@@ -465,8 +465,8 @@ static ssh_buffer ssh_gssapi_build_mic(ssh_session session)
rc = ssh_buffer_pack(mic_buffer,
"dPbsss",
crypto->digest_len,
(size_t)crypto->digest_len, crypto->session_id,
crypto->session_id_len,
crypto->session_id_len, crypto->session_id,
SSH2_MSG_USERAUTH_REQUEST,
session->gssapi->user,
"ssh-connection",

View File

@@ -138,7 +138,7 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
ssh_mac_update(ctx, key, key_len);
ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
ssh_mac_update(ctx, &letter, 1);
ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
ssh_mac_update(ctx, crypto->session_id, crypto->session_id_len);
ssh_mac_final(digest, ctx);
if (requested_len < output_len) {

View File

@@ -735,13 +735,29 @@ int ssh_set_client_kex(ssh_session session)
return SSH_OK;
}
static const char *ssh_find_aead_hmac(const char *cipher)
{
if (cipher == NULL) {
return NULL;
} else if (strcmp(cipher, "chacha20-poly1305@openssh.com") == 0) {
return "aead-poly1305";
} else if (strcmp(cipher, "aes256-gcm@openssh.com") == 0) {
return "aead-gcm";
} else if (strcmp(cipher, "aes128-gcm@openssh.com") == 0) {
return "aead-gcm";
}
return NULL;
}
/** @brief Select the different methods on basis of client's and
* server's kex messages, and watches out if a match is possible.
*/
int ssh_kex_select_methods (ssh_session session){
int ssh_kex_select_methods (ssh_session session)
{
struct ssh_kex_struct *server = &session->next_crypto->server_kex;
struct ssh_kex_struct *client = &session->next_crypto->client_kex;
char *ext_start = NULL;
const char *aead_hmac = NULL;
int i;
/* Here we should drop the ext-info-c from the list so we avoid matching.
@@ -753,7 +769,15 @@ int ssh_kex_select_methods (ssh_session session){
for (i = 0; i < SSH_KEX_METHODS; i++) {
session->next_crypto->kex_methods[i]=ssh_find_matching(server->methods[i],client->methods[i]);
if(session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){
if (i == SSH_MAC_C_S || i == SSH_MAC_S_C) {
aead_hmac = ssh_find_aead_hmac(session->next_crypto->kex_methods[i-2]);
if (aead_hmac) {
free(session->next_crypto->kex_methods[i]);
session->next_crypto->kex_methods[i] = strdup(aead_hmac);
}
}
if (session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){
ssh_set_error(session,SSH_FATAL,"kex error : no match for method %s: server [%s], client [%s]",
ssh_kex_descriptions[i],server->methods[i],client->methods[i]);
return SSH_ERROR;
@@ -762,31 +786,31 @@ int ssh_kex_select_methods (ssh_session session){
session->next_crypto->kex_methods[i] = strdup("");
}
}
if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){
if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP1_SHA1;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA256;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP16_SHA512;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP18_SHA512;
#ifdef WITH_GEX
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA1;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA256;
#endif /* WITH_GEX */
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP384;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP521;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){
} else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256;
}
SSH_LOG(SSH_LOG_INFO, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
@@ -806,7 +830,8 @@ int ssh_kex_select_methods (ssh_session session){
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(ssh_session session, int server_kex) {
int ssh_send_kex(ssh_session session, int server_kex)
{
struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex :
&session->next_crypto->client_kex);
ssh_string str = NULL;
@@ -1023,7 +1048,7 @@ int ssh_make_sessionid(ssh_session session)
ssh_buffer_get(server_hash),
server_pubkey_blob);
SSH_STRING_FREE(server_pubkey_blob);
if(rc != SSH_OK){
if (rc != SSH_OK){
goto error;
}
@@ -1197,11 +1222,13 @@ int ssh_make_sessionid(ssh_session session)
}
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
session->next_crypto->digest_len);
/* Initial length is the same as secret hash */
session->next_crypto->session_id_len = session->next_crypto->digest_len;
}
#ifdef DEBUG_CRYPTO
printf("Session hash: \n");
ssh_log_hexdump("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
ssh_log_hexdump("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
ssh_log_hexdump("session id", session->next_crypto->session_id, session->next_crypto->session_id_len);
#endif
rc = SSH_OK;

View File

@@ -372,6 +372,7 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
list = ssh_list_new();
if (list == NULL) {
ssh_set_error_oom(session);
SAFE_FREE(host_port);
return NULL;
}

View File

@@ -392,7 +392,7 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
goto out;
}
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
crypto->session_id, crypto->digest_len);
crypto->session_id, crypto->session_id_len);
if (rc != 1) {
goto out;
}

View File

@@ -687,7 +687,7 @@ static void cipher_encrypt(struct ssh_cipher_struct *cipher,
}
static void cipher_encrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len)
size_t len)
{
size_t outlen = 0;
int rc = 0;
@@ -745,7 +745,7 @@ static void cipher_decrypt(struct ssh_cipher_struct *cipher,
}
static void cipher_decrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len)
size_t len)
{
size_t outlen = 0;
int rc = 0;

View File

@@ -513,24 +513,30 @@ static int ssh_message_termination(void *s){
* @warning This function blocks until a message has been received. Betterset up
* a callback if this behavior is unwanted.
*/
ssh_message ssh_message_get(ssh_session session) {
ssh_message msg = NULL;
int rc;
ssh_message ssh_message_get(ssh_session session)
{
ssh_message msg = NULL;
int rc;
msg=ssh_message_pop_head(session);
if(msg) {
return msg;
}
if(session->ssh_message_list == NULL) {
session->ssh_message_list = ssh_list_new();
}
rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_USER,
ssh_message_termination, session);
if(rc || session->session_state == SSH_SESSION_STATE_ERROR)
return NULL;
msg=ssh_list_pop_head(ssh_message, session->ssh_message_list);
msg = ssh_message_pop_head(session);
if (msg != NULL) {
return msg;
}
if (session->ssh_message_list == NULL) {
session->ssh_message_list = ssh_list_new();
if (session->ssh_message_list == NULL) {
ssh_set_error_oom(session);
return NULL;
}
}
rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_USER,
ssh_message_termination, session);
if (rc || session->session_state == SSH_SESSION_STATE_ERROR) {
return NULL;
}
msg = ssh_list_pop_head(ssh_message, session->ssh_message_list);
return msg;
return msg;
}
/**
@@ -708,8 +714,8 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
rc = ssh_buffer_pack(buffer,
"dPbsssbsS",
crypto->digest_len, /* session ID string */
(size_t)crypto->digest_len, crypto->session_id,
crypto->session_id_len, /* session ID string */
crypto->session_id_len, crypto->session_id,
SSH2_MSG_USERAUTH_REQUEST, /* type */
msg->auth_request.username,
service,

View File

@@ -688,10 +688,12 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_ACCEPTED
* - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
* - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
*
* If not in a pending state, message is ignored in the callback handler.
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
@@ -699,21 +701,18 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
break;
}
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_REQUEST_FAILURE: // 82
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_DENIED
* - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
* - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
*
* If not in a pending state, message is ignored in the callback handler.
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
@@ -721,11 +720,6 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
break;
}
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN: // 90
@@ -878,10 +872,12 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
* - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
* - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
*
* If not in a pending state, message is ignored in the callback handler.
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
@@ -895,10 +891,12 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED
* - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
* - To channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
*
* If not in a pending state, message is ignored in the callback handler.
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
@@ -1424,12 +1422,14 @@ void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s){
* @brief sets the callbacks for the packet layer
*/
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks){
if(session->packet_callbacks == NULL){
session->packet_callbacks = ssh_list_new();
}
if (session->packet_callbacks != NULL) {
if (session->packet_callbacks == NULL) {
session->packet_callbacks = ssh_list_new();
if (session->packet_callbacks == NULL) {
ssh_set_error_oom(session);
return;
}
}
ssh_list_append(session->packet_callbacks, callbacks);
}
}
/** @internal
@@ -1899,7 +1899,7 @@ ssh_packet_set_newkeys(ssh_session session,
/* Both sides switched: do the actual switch now */
if (session->next_crypto->used == SSH_DIRECTION_BOTH) {
size_t digest_len;
size_t session_id_len;
if (session->current_crypto != NULL) {
crypto_free(session->current_crypto);
@@ -1916,8 +1916,8 @@ ssh_packet_set_newkeys(ssh_session session,
return SSH_ERROR;
}
digest_len = session->current_crypto->digest_len;
session->next_crypto->session_id = malloc(digest_len);
session_id_len = session->current_crypto->session_id_len;
session->next_crypto->session_id = malloc(session_id_len);
if (session->next_crypto->session_id == NULL) {
ssh_set_error_oom(session);
return SSH_ERROR;
@@ -1925,7 +1925,8 @@ ssh_packet_set_newkeys(ssh_session session,
memcpy(session->next_crypto->session_id,
session->current_crypto->session_id,
digest_len);
session_id_len);
session->next_crypto->session_id_len = session_id_len;
return SSH_OK;
}

View File

@@ -129,6 +129,8 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
}
rc = ssh_pki_import_signature_blob(sig_blob, server_key, &sig);
ssh_string_burn(sig_blob);
SSH_STRING_FREE(sig_blob);
if (rc != SSH_OK) {
goto error;
}
@@ -152,9 +154,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
server_key,
session->next_crypto->secret_hash,
session->next_crypto->digest_len);
ssh_string_burn(sig_blob);
SSH_STRING_FREE(sig_blob);
ssh_signature_free(sig);
SSH_SIGNATURE_FREE(sig);
if (rc == SSH_ERROR) {
goto error;
}
@@ -170,6 +170,9 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
session->ssh_connection_callback(session);
return SSH_PACKET_USED;
error:
SSH_SIGNATURE_FREE(sig);
ssh_string_burn(sig_blob);
SSH_STRING_FREE(sig_blob);
session->session_state = SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
}

View File

@@ -1160,6 +1160,10 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type,
nid = pki_key_ecdsa_nid_from_name(ssh_string_get_char(i));
SSH_STRING_FREE(i);
if (nid == -1) {
ssh_string_burn(e);
SSH_STRING_FREE(e);
ssh_string_burn(exp);
SSH_STRING_FREE(exp);
goto fail;
}
@@ -2086,8 +2090,12 @@ int ssh_pki_export_signature_blob(const ssh_signature sig,
return SSH_ERROR;
}
ssh_string_fill(str, ssh_buffer_get(buf), ssh_buffer_get_len(buf));
rc = ssh_string_fill(str, ssh_buffer_get(buf), ssh_buffer_get_len(buf));
SSH_BUFFER_FREE(buf);
if (rc < 0) {
SSH_STRING_FREE(str);
return SSH_ERROR;
}
*sig_blob = str;
@@ -2328,11 +2336,14 @@ ssh_string ssh_pki_do_sign(ssh_session session,
}
/* Get the session ID */
session_id = ssh_string_new(crypto->digest_len);
session_id = ssh_string_new(crypto->session_id_len);
if (session_id == NULL) {
return NULL;
}
ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);
rc = ssh_string_fill(session_id, crypto->session_id, crypto->session_id_len);
if (rc < 0) {
goto end;
}
/* Fill the input */
sign_input = ssh_buffer_new();
@@ -2389,11 +2400,15 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
}
/* prepend session identifier */
session_id = ssh_string_new(crypto->digest_len);
session_id = ssh_string_new(crypto->session_id_len);
if (session_id == NULL) {
return NULL;
}
ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);
rc = ssh_string_fill(session_id, crypto->session_id, crypto->session_id_len);
if (rc < 0) {
SSH_STRING_FREE(session_id);
return NULL;
}
sig_buf = ssh_buffer_new();
if (sig_buf == NULL) {

View File

@@ -831,7 +831,12 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
goto err;
}
ssh_string_fill(blob, buf->data, buf->length);
rc = ssh_string_fill(blob, buf->data, buf->length);
if (rc < 0) {
ssh_string_free(blob);
goto err;
}
BIO_free(mem);
return blob;
@@ -1383,6 +1388,7 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
const unsigned char *raw_sig_data = NULL;
size_t raw_sig_len;
int rc;
DSA_SIG *dsa_sig;
@@ -1439,7 +1445,11 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
return NULL;
}
ssh_string_fill(sig_blob, buffer, 40);
rc = ssh_string_fill(sig_blob, buffer, 40);
if (rc < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
return sig_blob;
@@ -1516,7 +1526,10 @@ static ssh_string pki_ecdsa_signature_to_blob(const ssh_signature sig)
goto error;
}
ssh_string_fill(sig_blob, ssh_buffer_get(buf), ssh_buffer_get_len(buf));
rc = ssh_string_fill(sig_blob, ssh_buffer_get(buf), ssh_buffer_get_len(buf));
if (rc < 0) {
goto error;
}
SSH_STRING_FREE(r);
SSH_STRING_FREE(s);
@@ -1526,6 +1539,7 @@ static ssh_string pki_ecdsa_signature_to_blob(const ssh_signature sig)
return sig_blob;
error:
SSH_STRING_FREE(sig_blob);
SSH_STRING_FREE(r);
SSH_STRING_FREE(s);
ECDSA_SIG_free(ecdsa_sig);
@@ -1670,7 +1684,11 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
if (r == NULL) {
goto error;
}
ssh_string_fill(r, ssh_string_data(sig_blob), 20);
rc = ssh_string_fill(r, ssh_string_data(sig_blob), 20);
if (rc < 0) {
SSH_STRING_FREE(r);
goto error;
}
pr = ssh_make_string_bn(r);
ssh_string_burn(r);
@@ -1683,7 +1701,11 @@ static int pki_signature_from_dsa_blob(UNUSED_PARAM(const ssh_key pubkey),
if (s == NULL) {
goto error;
}
ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20);
rc = ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20);
if (rc < 0) {
SSH_STRING_FREE(s);
goto error;
}
ps = ssh_make_string_bn(s);
ssh_string_burn(s);

View File

@@ -214,6 +214,7 @@ int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key)
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig)
{
ssh_string sig_blob;
int rc;
#ifdef HAVE_OPENSSL_ED25519
/* When using the OpenSSL implementation, the signature is stored in raw_sig
@@ -235,11 +236,15 @@ ssh_string pki_ed25519_signature_to_blob(ssh_signature sig)
}
#ifdef HAVE_OPENSSL_ED25519
ssh_string_fill(sig_blob, ssh_string_data(sig->raw_sig),
ssh_string_len(sig->raw_sig));
rc = ssh_string_fill(sig_blob, ssh_string_data(sig->raw_sig),
ssh_string_len(sig->raw_sig));
#else
ssh_string_fill(sig_blob, sig->ed25519_sig, ED25519_SIG_LEN);
rc = ssh_string_fill(sig_blob, sig->ed25519_sig, ED25519_SIG_LEN);
#endif
if (rc < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
return sig_blob;
}

View File

@@ -1765,6 +1765,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
gcry_sexp_t sexp;
size_t size = 0;
ssh_string sig_blob = NULL;
int rc;
switch(sig->type) {
case SSH_KEYTYPE_DSS:
@@ -1812,7 +1813,11 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
return NULL;
}
ssh_string_fill(sig_blob, buffer, 40);
rc = ssh_string_fill(sig_blob, buffer, 40);
if (rc < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
break;
case SSH_KEYTYPE_RSA:
sexp = gcry_sexp_find_token(sig->rsa_sig, "s", 0);
@@ -1829,13 +1834,16 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
if (sig_blob == NULL) {
return NULL;
}
ssh_string_fill(sig_blob, discard_const_p(char, s), size);
rc = ssh_string_fill(sig_blob, discard_const_p(char, s), size);
gcry_sexp_release(sexp);
if (rc < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
break;
case SSH_KEYTYPE_ED25519:
sig_blob = pki_ed25519_signature_to_blob(sig);
break;
sig_blob = pki_ed25519_signature_to_blob(sig);
break;
case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521:
@@ -1844,7 +1852,6 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
ssh_string R;
ssh_string S;
ssh_buffer b;
int rc;
b = ssh_buffer_new();
if (b == NULL) {
@@ -1885,9 +1892,13 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
return NULL;
}
ssh_string_fill(sig_blob,
rc = ssh_string_fill(sig_blob,
ssh_buffer_get(b), ssh_buffer_get_len(b));
SSH_BUFFER_FREE(b);
if (rc < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
break;
}
#endif

View File

@@ -832,8 +832,13 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
return NULL;
}
ssh_string_fill(sig_blob, ssh_buffer_get(b), ssh_buffer_get_len(b));
rc = ssh_string_fill(sig_blob, ssh_buffer_get(b), ssh_buffer_get_len(b));
SSH_BUFFER_FREE(b);
if (rc < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
break;
}
case SSH_KEYTYPE_ED25519:
@@ -1074,9 +1079,13 @@ static ssh_string rsa_do_sign_hash(const unsigned char *digest,
return NULL;
}
ssh_string_fill(sig_blob, sig, slen);
ok = ssh_string_fill(sig_blob, sig, slen);
explicit_bzero(sig, slen);
SAFE_FREE(sig);
if (ok < 0) {
SSH_STRING_FREE(sig_blob);
return NULL;
}
return sig_blob;
}

View File

@@ -32,6 +32,9 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAVE_SYS_TIME_H */
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
@@ -173,32 +176,56 @@ error:
return NULL;
}
sftp_session sftp_new_channel(ssh_session session, ssh_channel channel){
sftp_session sftp;
sftp_session
sftp_new_channel(ssh_session session, ssh_channel channel)
{
sftp_session sftp = NULL;
if (session == NULL) {
return NULL;
}
if (session == NULL) {
return NULL;
}
sftp = calloc(1, sizeof(struct sftp_session_struct));
if (sftp == NULL) {
ssh_set_error_oom(session);
sftp = calloc(1, sizeof(struct sftp_session_struct));
if (sftp == NULL) {
ssh_set_error_oom(session);
return NULL;
}
return NULL;
}
sftp->ext = sftp_ext_new();
if (sftp->ext == NULL) {
ssh_set_error_oom(session);
goto error;
}
sftp->ext = sftp_ext_new();
if (sftp->ext == NULL) {
ssh_set_error_oom(session);
sftp->read_packet = calloc(1, sizeof(struct sftp_packet_struct));
if (sftp->read_packet == NULL) {
ssh_set_error_oom(session);
goto error;
}
sftp->read_packet->payload = ssh_buffer_new();
if (sftp->read_packet->payload == NULL) {
ssh_set_error_oom(session);
goto error;
}
sftp->session = session;
sftp->channel = channel;
return sftp;
error:
if (sftp->ext != NULL) {
sftp_ext_free(sftp->ext);
}
if (sftp->read_packet != NULL) {
if (sftp->read_packet->payload != NULL) {
SSH_BUFFER_FREE(sftp->read_packet->payload);
}
SAFE_FREE(sftp->read_packet);
}
SAFE_FREE(sftp);
return NULL;
}
sftp->session = session;
sftp->channel = channel;
return sftp;
}
#ifdef WITH_SERVER

View File

@@ -26,6 +26,7 @@
#include <windows.h>
#include <winbase.h>
#include <errno.h>
#include <stdlib.h>
static int ssh_winlock_mutex_init (void **priv)
{

View File

@@ -182,8 +182,9 @@ void crypto_free(struct ssh_crypto_struct *crypto)
crypto->ecdh_privkey = NULL;
}
#endif
SAFE_FREE(crypto->dh_server_signature);
if (crypto->session_id != NULL) {
explicit_bzero(crypto->session_id, crypto->digest_len);
explicit_bzero(crypto->session_id, crypto->session_id_len);
SAFE_FREE(crypto->session_id);
}
if (crypto->secret_hash != NULL) {

View File

@@ -37,6 +37,7 @@ if (WITH_SFTP)
endif()
set(LIBSSH_CLIENT_TESTS
${LIBSSH_CLIENT_TESTS}
torture_sftp_init
torture_sftp_ext
torture_sftp_canonicalize_path
torture_sftp_dir

View File

@@ -45,6 +45,16 @@ static int sshd_teardown(void **state) {
return 0;
}
static int sshd_setup_hmac(void **state)
{
torture_setup_sshd_server(state, false);
/* Set MAC to be something other than what the client will offer */
torture_update_sshd_config(state, "MACs hmac-sha2-512");
return 0;
}
static int session_setup(void **state) {
struct torture_state *s = *state;
int verbosity = torture_libssh_verbosity();
@@ -412,6 +422,20 @@ static void torture_algorithms_aes256_gcm(void **state)
test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-gcm@openssh.com", NULL);
}
static void torture_algorithms_aes128_gcm_mac(void **state)
{
struct torture_state *s = *state;
test_algorithm(s->ssh.session, NULL/*kex*/, "aes128-gcm@openssh.com", "hmac-sha1");
}
static void torture_algorithms_aes256_gcm_mac(void **state)
{
struct torture_state *s = *state;
test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-gcm@openssh.com", "hmac-sha1");
}
static void torture_algorithms_3des_cbc_hmac_sha1(void **state) {
struct torture_state *s = *state;
@@ -548,6 +572,19 @@ static void torture_algorithms_chacha20_poly1305(void **state)
"chacha20-poly1305@openssh.com",
NULL);
}
static void torture_algorithms_chacha20_poly1305_mac(void **state)
{
struct torture_state *s = *state;
if (ssh_fips_mode()) {
skip();
}
test_algorithm(s->ssh.session,
NULL, /*kex*/
"chacha20-poly1305@openssh.com",
"hmac-sha1"); /* different from the server */
}
#endif /* OPENSSH_CHACHA20_POLY1305_OPENSSH_COM */
static void torture_algorithms_zlib(void **state) {
@@ -951,10 +988,30 @@ int torture_run_tests(void) {
#endif
};
struct CMUnitTest tests_hmac[] = {
cmocka_unit_test_setup_teardown(torture_algorithms_aes128_gcm_mac,
session_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_algorithms_aes256_gcm_mac,
session_setup,
session_teardown),
#ifdef OPENSSH_CHACHA20_POLY1305_OPENSSH_COM
cmocka_unit_test_setup_teardown(torture_algorithms_chacha20_poly1305_mac,
session_setup,
session_teardown),
#endif /* OPENSSH_CHACHA20_POLY1305_OPENSSH_COM */
};
ssh_init();
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
if (rc != 0) {
return rc;
}
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests_hmac, sshd_setup_hmac, sshd_teardown);
ssh_finalize();

View File

@@ -38,6 +38,8 @@
#include <fcntl.h>
#include <pwd.h>
static uint64_t bytes = 2048; /* 2KB (more than the authentication phase) */
static int sshd_setup(void **state)
{
torture_setup_sshd_server(state, false);
@@ -153,7 +155,6 @@ static void torture_rekey_send(void **state)
int rc;
char data[256];
unsigned int i;
uint64_t bytes = 2048; /* 2KB (more than the authentication phase) */
struct ssh_crypto_struct *c = NULL;
unsigned char *secret_hash = NULL;
@@ -234,8 +235,6 @@ static void session_setup_sftp(void **state)
assert_non_null(s->ssh.tsftp);
}
uint64_t bytes = 2048; /* 2KB */
static int session_setup_sftp_client(void **state)
{
struct torture_state *s = *state;
@@ -439,6 +438,153 @@ static void torture_rekey_server_send(void **state)
ssh_disconnect(s->ssh.session);
}
static void torture_rekey_different_kex(void **state)
{
struct torture_state *s = *state;
int rc;
char data[256];
unsigned int i;
struct ssh_crypto_struct *c = NULL;
unsigned char *secret_hash = NULL;
size_t secret_hash_len = 0;
const char *kex1 = "diffie-hellman-group14-sha256,curve25519-sha256,ecdh-sha2-nistp256";
const char *kex2 = "diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,ecdh-sha2-nistp521";
/* Use short digest for initial key exchange */
rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_KEY_EXCHANGE, kex1);
assert_ssh_return_code(s->ssh.session, rc);
rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_REKEY_DATA, &bytes);
assert_ssh_return_code(s->ssh.session, rc);
rc = ssh_connect(s->ssh.session);
assert_ssh_return_code(s->ssh.session, rc);
/* The blocks limit is set correctly */
c = s->ssh.session->current_crypto;
assert_int_equal(c->in_cipher->max_blocks,
bytes / c->in_cipher->blocksize);
assert_int_equal(c->out_cipher->max_blocks,
bytes / c->out_cipher->blocksize);
/* We should have less encrypted packets than transfered (first are not encrypted) */
assert_true(c->out_cipher->packets < s->ssh.session->send_seq);
assert_true(c->in_cipher->packets < s->ssh.session->recv_seq);
/* Copy the initial secret hash = session_id so we know we changed keys later */
secret_hash = malloc(c->digest_len);
assert_non_null(secret_hash);
memcpy(secret_hash, c->secret_hash, c->digest_len);
secret_hash_len = c->digest_len;
assert_int_equal(secret_hash_len, 32); /* SHA256 len */
/* OpenSSH can not rekey before authentication so authenticate here */
rc = ssh_userauth_none(s->ssh.session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_int_equal(ssh_get_error_code(s->ssh.session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(s->ssh.session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
rc = ssh_userauth_publickey_auto(s->ssh.session, NULL, NULL);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
/* Now try to change preference of key exchange algorithm to something with larger digest */
rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_KEY_EXCHANGE, kex2);
assert_ssh_return_code(s->ssh.session, rc);
/* send ignore packets of up to 1KB to trigger rekey. Send litle bit more
* to make sure the rekey it completes with all different ciphers (paddings */
memset(data, 0, sizeof(data));
memset(data, 'A', 128);
for (i = 0; i < 20; i++) {
ssh_send_ignore(s->ssh.session, data);
ssh_handle_packets(s->ssh.session, 50);
}
/* The rekey limit was restored in the new crypto to the same value */
c = s->ssh.session->current_crypto;
assert_int_equal(c->in_cipher->max_blocks, bytes / c->in_cipher->blocksize);
assert_int_equal(c->out_cipher->max_blocks, bytes / c->out_cipher->blocksize);
/* Check that the secret hash is different than initially */
assert_int_equal(c->digest_len, 64); /* SHA512 len */
assert_memory_not_equal(secret_hash, c->secret_hash, secret_hash_len);
/* Session ID stays same after one rekey */
assert_memory_equal(secret_hash, c->session_id, secret_hash_len);
free(secret_hash);
assert_int_equal(ssh_is_connected(s->ssh.session), 1);
assert_int_equal(s->ssh.session->session_state, SSH_SESSION_STATE_AUTHENTICATED);
ssh_disconnect(s->ssh.session);
}
static void torture_rekey_server_different_kex(void **state)
{
struct torture_state *s = *state;
int rc;
char data[256];
unsigned int i;
struct ssh_crypto_struct *c = NULL;
unsigned char *secret_hash = NULL;
size_t secret_hash_len = 0;
const char *sshd_config = "RekeyLimit 2K none";
const char *kex1 = "diffie-hellman-group14-sha256,curve25519-sha256,ecdh-sha2-nistp256";
const char *kex2 = "diffie-hellman-group18-sha512,diffie-hellman-group16-sha512";
/* Use short digest for initial key exchange */
rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_KEY_EXCHANGE, kex1);
assert_ssh_return_code(s->ssh.session, rc);
torture_update_sshd_config(state, sshd_config);
rc = ssh_connect(s->ssh.session);
assert_ssh_return_code(s->ssh.session, rc);
/* Copy the initial secret hash = session_id so we know we changed keys later */
c = s->ssh.session->current_crypto;
secret_hash = malloc(c->digest_len);
assert_non_null(secret_hash);
memcpy(secret_hash, c->secret_hash, c->digest_len);
secret_hash_len = c->digest_len;
assert_int_equal(secret_hash_len, 32); /* SHA256 len */
/* OpenSSH can not rekey before authentication so authenticate here */
rc = ssh_userauth_none(s->ssh.session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_int_equal(ssh_get_error_code(s->ssh.session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(s->ssh.session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
rc = ssh_userauth_publickey_auto(s->ssh.session, NULL, NULL);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
/* Now try to change preference of key exchange algorithm to something with larger digest */
rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_KEY_EXCHANGE, kex2);
assert_ssh_return_code(s->ssh.session, rc);
/* send ignore packets of up to 1KB to trigger rekey. Send litle bit more
* to make sure the rekey it completes with all different ciphers (paddings */
memset(data, 0, sizeof(data));
memset(data, 'A', 128);
for (i = 0; i < 25; i++) {
ssh_send_ignore(s->ssh.session, data);
ssh_handle_packets(s->ssh.session, 50);
}
/* Check that the secret hash is different than initially */
c = s->ssh.session->current_crypto;
assert_int_equal(c->digest_len, 64); /* SHA512 len */
assert_memory_not_equal(secret_hash, c->secret_hash, secret_hash_len);
/* Session ID stays same after one rekey */
assert_memory_equal(secret_hash, c->session_id, secret_hash_len);
free(secret_hash);
ssh_disconnect(s->ssh.session);
}
#ifdef WITH_SFTP
static int session_setup_sftp_server(void **state)
{
@@ -522,6 +668,9 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_rekey_send,
session_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_rekey_different_kex,
session_setup,
session_teardown),
/* Note, that this modifies the sshd_config */
cmocka_unit_test_setup_teardown(torture_rekey_server_send,
session_setup,
@@ -531,6 +680,9 @@ int torture_run_tests(void) {
session_setup_sftp_server,
session_teardown),
#endif /* WITH_SFTP */
cmocka_unit_test_setup_teardown(torture_rekey_server_different_kex,
session_setup,
session_teardown),
/* TODO verify the two rekey are possible and the states are not broken after rekey */
};

View File

@@ -0,0 +1,106 @@
#include "config.h"
#define LIBSSH_STATIC
#include "torture.h"
#include "sftp.c"
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
static int sshd_setup(void **state)
{
torture_setup_sshd_server(state, false);
return 0;
}
static int sshd_teardown(void **state) {
torture_teardown_sshd_server(state);
return 0;
}
static void session_setup(void **state)
{
struct torture_state *s = *state;
struct passwd *pwd;
int rc;
pwd = getpwnam("bob");
assert_non_null(pwd);
rc = setuid(pwd->pw_uid);
assert_return_code(rc, errno);
s->ssh.session = torture_ssh_session(s,
TORTURE_SSH_SERVER,
NULL,
TORTURE_SSH_USER_ALICE,
NULL);
assert_non_null(s->ssh.session);
s->ssh.tsftp = torture_sftp_session(s->ssh.session);
assert_non_null(s->ssh.tsftp);
}
static void session_setup_channel(void **state)
{
struct torture_state *s = *state;
struct passwd *pwd = NULL;
ssh_channel c = NULL;
int rc;
pwd = getpwnam("bob");
assert_non_null(pwd);
rc = setuid(pwd->pw_uid);
assert_return_code(rc, errno);
s->ssh.session = torture_ssh_session(s,
TORTURE_SSH_SERVER,
NULL,
TORTURE_SSH_USER_ALICE,
NULL);
assert_non_null(s->ssh.session);
c = ssh_channel_new(s->ssh.session);
assert_non_null(c);
s->ssh.tsftp = torture_sftp_session_channel(s->ssh.session, c);
assert_non_null(s->ssh.tsftp);
}
static int session_teardown(void **state)
{
struct torture_state *s = *state;
torture_rmdirs(s->ssh.tsftp->testdir);
torture_sftp_close(s->ssh.tsftp);
ssh_disconnect(s->ssh.session);
ssh_free(s->ssh.session);
return 0;
}
int torture_run_tests(void) {
int rc;
struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(session_setup,
NULL,
session_teardown),
cmocka_unit_test_setup_teardown(session_setup_channel,
NULL,
session_teardown)
};
ssh_init();
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
ssh_finalize();
return rc;
}

View File

@@ -392,45 +392,37 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#endif
#define PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
#define PKDTESTS_CIPHER_COMMON(f, client, ciphercmd) \
f(client, rsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_rsa, teardown) \
f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_rsa, teardown) \
f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_521, teardown)
#define PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
PKDTESTS_CIPHER_COMMON(f, client, ciphercmd) \
f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown)
#ifdef HAVE_DSA
#define PKDTESTS_CIPHER(f, client, ciphercmd) \
/* Ciphers. */ \
PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \
f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \
PKDTESTS_CIPHER_COMMON(f, client, ciphercmd) \
f(client, dsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_dsa, teardown) \
f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \
f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown) \
f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown)
f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown)
#else
#define PKDTESTS_CIPHER(f, client, ciphercmd) \
/* Ciphers. */ \
PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown)
PKDTESTS_CIPHER_COMMON(f, client, ciphercmd)
#endif
#define CHACHA20 "chacha20-poly1305@openssh.com"
@@ -451,10 +443,16 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
/* Ciphers. */ \
PKDTESTS_CIPHER_OPENSSHONLY_FIPS(f, client, ciphercmd) \
f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \
f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \
f(client, dsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_dsa, teardown) \
f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \
f(client, dsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_dsa, teardown) \
f(client, dsa_chacha20, ciphercmd(CHACHA20), setup_dsa, teardown) \
f(client, dsa_aes128_gcm, ciphercmd(AES128_GCM), setup_dsa, teardown) \
@@ -469,20 +467,32 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
f(client, ed25519_aes128_gcm, ciphercmd(AES128_GCM), setup_ed25519, teardown) \
f(client, ed25519_aes256_gcm, ciphercmd(AES256_GCM), setup_ed25519, teardown) \
f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#else
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
/* Ciphers. */ \
PKDTESTS_CIPHER_OPENSSHONLY_FIPS(f, client, ciphercmd) \
f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
f(client, ed25519_3des_cbc, ciphercmd("3des-cbc"), setup_ed25519, teardown) \
@@ -493,13 +503,22 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ed25519_aes192_cbc, ciphercmd("aes192-cbc"), setup_ed25519, teardown) \
f(client, ed25519_aes192_ctr, ciphercmd("aes192-ctr"), setup_ed25519, teardown) \
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#endif

View File

@@ -421,7 +421,8 @@ ssh_bind torture_ssh_bind(const char *addr,
#ifdef WITH_SFTP
struct torture_sftp *torture_sftp_session(ssh_session session) {
struct torture_sftp *torture_sftp_session_channel(ssh_session session, ssh_channel channel)
{
struct torture_sftp *t;
char template[] = "/tmp/ssh_torture_XXXXXX";
char *p;
@@ -437,9 +438,26 @@ struct torture_sftp *torture_sftp_session(ssh_session session) {
}
t->ssh = session;
t->sftp = sftp_new(session);
if (t->sftp == NULL) {
goto failed;
if (channel == NULL) {
t->sftp = sftp_new(session);
if (t->sftp == NULL) {
goto failed;
}
} else {
t->sftp = sftp_new_channel(session, channel);
if (t->sftp == NULL) {
goto failed;
}
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK) {
goto failed;
}
rc = ssh_channel_request_sftp(channel);
if (rc != SSH_OK) {
goto failed;
}
}
rc = sftp_init(t->sftp);
@@ -470,6 +488,11 @@ failed:
return NULL;
}
struct torture_sftp *torture_sftp_session(ssh_session session)
{
return torture_sftp_session_channel(session, NULL);
}
void torture_sftp_close(struct torture_sftp *t) {
if (t == NULL) {
return;
@@ -629,7 +652,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"\n"
"StrictModes no\n"
"\n"
"%s" /* Here comes UsePam */
"%s\n" /* Here comes UsePam */
"%s" /* The space for test-specific options */
"\n"
/* add all supported algorithms */
"HostKeyAlgorithms " OPENSSH_KEYS "\n"
@@ -644,8 +668,7 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT\n"
"AcceptEnv LC_IDENTIFICATION LC_ALL LC_LIBSSH\n"
"\n"
"PidFile %s\n"
"%s\n"; /* The space for test-specific options */
"PidFile %s\n";
/* FIPS config */
const char fips_config_string[]=
"Port 22\n"
@@ -663,7 +686,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"\n"
"StrictModes no\n"
"\n"
"%s" /* UsePam */
"%s\n" /* Here comes UsePam */
"%s" /* The space for test-specific options */
"\n"
"Ciphers "
"aes256-gcm@openssh.com,aes256-ctr,aes256-cbc,"
@@ -692,8 +716,7 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT\n"
"AcceptEnv LC_IDENTIFICATION LC_ALL LC_LIBSSH\n"
"\n"
"PidFile %s\n" /* PID file */
"%s\n"; /* The space for test-specific options */
"PidFile %s\n"; /* PID file */
const char usepam_yes[] =
"UsePAM yes\n"
"KbdInteractiveAuthentication yes\n";
@@ -794,8 +817,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
trusted_ca_pubkey,
sftp_server,
usepam,
s->srv_pidfile,
additional_config);
additional_config,
s->srv_pidfile);
} else {
snprintf(sshd_config, sizeof(sshd_config),
config_string,
@@ -808,8 +831,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
trusted_ca_pubkey,
sftp_server,
usepam,
s->srv_pidfile,
additional_config);
additional_config,
s->srv_pidfile);
}
torture_write_file(s->srv_config, sshd_config);

View File

@@ -111,6 +111,7 @@ ssh_bind torture_ssh_bind(const char *addr,
const char *private_key_file);
struct torture_sftp *torture_sftp_session(ssh_session session);
struct torture_sftp *torture_sftp_session_channel(ssh_session session, ssh_channel channel);
void torture_sftp_close(struct torture_sftp *t);
void torture_write_file(const char *filename, const char *data);

View File

@@ -138,6 +138,9 @@ static void torture_callbacks_execute_list(void **state){
};
(void)state;
assert_non_null(list);
ssh_callbacks_init(&c1);
ssh_callbacks_init(&c2);
ssh_callbacks_init(&c3);
@@ -213,6 +216,8 @@ static void torture_callbacks_iterate(void **state){
(void)state; /* unused */
assert_non_null(list);
ssh_callbacks_init(&c1);
ssh_callbacks_init(&c2);

View File

@@ -209,7 +209,8 @@ static void torture_timeout_elapsed(void **state){
struct ssh_timestamp ts;
(void) state;
ssh_timestamp_init(&ts);
usleep(50000);
usleep(30000);
assert_true(ssh_timeout_elapsed(&ts,25));
assert_false(ssh_timeout_elapsed(&ts,30000));
assert_false(ssh_timeout_elapsed(&ts,75));

View File

@@ -517,12 +517,108 @@ static void torture_packet_filter_check_channel_open(void **state)
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_channel_success(void **state)
{
int rc;
/* The only condition to accept a CHANNEL_SUCCESS is to be authenticated */
global_state accepted[] = {
{
.flags = COMPARE_SESSION_STATE,
.session = SSH_SESSION_STATE_AUTHENTICATED,
}
};
int accepted_count = 1;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_CHANNEL_SUCCESS);
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_channel_failure(void **state)
{
int rc;
/* The only condition to accept a CHANNEL_FAILURE is to be authenticated */
global_state accepted[] = {
{
.flags = COMPARE_SESSION_STATE,
.session = SSH_SESSION_STATE_AUTHENTICATED,
}
};
int accepted_count = 1;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_CHANNEL_FAILURE);
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_request_success(void **state)
{
int rc;
/* The only condition to accept a REQUEST_SUCCESS is to be authenticated */
global_state accepted[] = {
{
.flags = COMPARE_SESSION_STATE,
.session = SSH_SESSION_STATE_AUTHENTICATED,
}
};
int accepted_count = 1;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_REQUEST_SUCCESS);
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_request_failure(void **state)
{
int rc;
/* The only condition to accept a REQUEST_FAILURE is to be authenticated */
global_state accepted[] = {
{
.flags = COMPARE_SESSION_STATE,
.session = SSH_SESSION_STATE_AUTHENTICATED,
}
};
int accepted_count = 1;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_REQUEST_FAILURE);
assert_int_equal(rc, 0);
}
int torture_run_tests(void)
{
int rc;
struct CMUnitTest tests[] = {
cmocka_unit_test(torture_packet_filter_check_auth_success),
cmocka_unit_test(torture_packet_filter_check_channel_open),
cmocka_unit_test(torture_packet_filter_check_channel_success),
cmocka_unit_test(torture_packet_filter_check_channel_failure),
cmocka_unit_test(torture_packet_filter_check_request_success),
cmocka_unit_test(torture_packet_filter_check_request_failure),
cmocka_unit_test(torture_packet_filter_check_unfiltered),
cmocka_unit_test(torture_packet_filter_check_msg_ext_info)
};

View File

@@ -796,7 +796,8 @@ static void torture_pki_ed25519_verify(void **state){
assert_true(rc == SSH_OK);
assert_non_null(pubkey);
ssh_string_fill(blob, ref_signature, ED25519_SIG_LEN);
rc = ssh_string_fill(blob, ref_signature, ED25519_SIG_LEN);
assert_int_equal(rc, 0);
sig = pki_signature_from_blob(pubkey, blob, SSH_KEYTYPE_ED25519, SSH_DIGEST_AUTO);
assert_non_null(sig);
@@ -853,7 +854,8 @@ static void torture_pki_ed25519_verify_bad(void **state){
/* alter signature and expect false result */
for (i=0; i < ED25519_SIG_LEN; ++i){
ssh_string_fill(blob, ref_signature, ED25519_SIG_LEN);
rc = ssh_string_fill(blob, ref_signature, ED25519_SIG_LEN);
assert_int_equal(rc, 0);
((uint8_t *)ssh_string_data(blob))[i] ^= 0xff;
sig = pki_signature_from_blob(pubkey, blob, SSH_KEYTYPE_ED25519, SSH_DIGEST_AUTO);
assert_non_null(sig);

View File

@@ -48,8 +48,9 @@ struct ssh_cipher_struct fake_out_cipher = {
};
struct ssh_crypto_struct test_crypto = {
.digest_len = 32,
.session_id_len = 32,
.session_id = secret,
.digest_len = 32,
.secret_hash = secret,
.in_cipher = &fake_in_cipher,
.out_cipher = &fake_out_cipher,
@@ -68,7 +69,9 @@ static void torture_session_keys(UNUSED_PARAM(void **state))
int rc;
k_string = ssh_string_new(32);
ssh_string_fill(k_string, key, 32);
rc = ssh_string_fill(k_string, key, 32);
assert_int_equal(rc, 0);
test_crypto.shared_secret = ssh_make_string_bn(k_string);
rc = ssh_generate_session_keys(&session);