Compare commits

..

63 Commits

Author SHA1 Message Date
Andreas Schneider
273fb4cfc6 Bump version to 0.8.5
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-29 10:50:51 +01:00
Andreas Schneider
56f7c27852 Bump SO version to 4.7.2
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a4342b97d6)
2018-10-29 09:34:09 +01:00
Mike Frysinger
1285b37b60 doc: fix up various typos and trailing whitespace
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 963c3077a4)
2018-10-28 14:31:12 +01:00
Andreas Schneider
b7de358cdc libcrypto: Fix memory leak in evp_final()
Fixes T116

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a280747462)
2018-10-28 14:31:09 +01:00
Meng Tan
bea6393de0 gssapi: Set correct state after sending GSSAPI_RESPONSE (select mechanism OID)
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bce8d56705)
2018-10-26 09:03:58 +02:00
Sanne Raymaekers
9158cc524c socket: Undouble socket fds
Fixes T115

Signed-off-by: Sanne Raymaekers <sraymaek@redhat.com>
(cherry picked from commit ced05eb6db)
2018-10-26 09:03:40 +02:00
Meng Tan
8ba10ef42b client: Send KEX as soon as banners are exchanged
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b796924fea)
2018-10-24 19:56:36 +02:00
Jakub Jelen
2ff8a09ee6 tests: Verify we can authenticate using ed25519 key
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0386e088eb)
2018-10-19 21:22:21 +02:00
Jakub Jelen
d52fa9a02c tests: Global known_hosts are used for host key verification
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e91bb29e9d)
2018-10-19 21:22:21 +02:00
Jakub Jelen
ec3fdb434c knownhosts: Consult also the global known hosts file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f622c4309b)
2018-10-19 21:22:21 +02:00
Jakub Jelen
d877969db3 options: Set the global known_hosts file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ae6b0e0f49)
2018-10-19 21:22:21 +02:00
Jakub Jelen
b1a7bd21ad tests: Verify the hostkey ordering for negotiation is correct
Previously, not all of the host keys algorithms were used for algorithm
negotiation. This verifies the algorithms list is sane and ordered
with the key types from known hosts in the first place.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bdb3bb9ccd)
2018-10-19 21:22:21 +02:00
Jakub Jelen
0831b85002 tests: Generate valid known_hosts file, fixing the current test
Previously, the file contained the known_hosts strings separated
by NULL bytes which somehow magically worked.

The test was also expecting all the keys from the file will have
the same key type, which was not indeed true.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 32e502a79d)
2018-10-19 21:22:21 +02:00
Jakub Jelen
34d1f5e097 tests: Verify the ecdsa key types are handled correctly
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6ec5a08639)
2018-10-19 21:22:21 +02:00
Jakub Jelen
fcf2cd0d9e kex: Use all supported hostkey algorithms for negotiation
Previously, only the algorithms we had a keys for in known_hosts
were used, which could lead to no-matching algorithms errors if the
one key we used to depend on was removed from the server.

This commit adds also the other algorithms, but lists them only after
all the key types we have in known_hosts file.

Resolves: T105

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 35a6455489)
2018-10-19 21:22:21 +02:00
Jakub Jelen
4a4ca44b19 kex: Honor more host key algorithms than the first one (ssh-ed25519)
The code as it was written used only the first algorithm from
preferred_hostkeys  array and compared it with the list returned
from the known hosts.

This commit is fixing the code so we actually compare each of the
algorithms from both of the lists and returns the intersection.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c1a8c41c5d)
2018-10-19 21:22:21 +02:00
Jakub Jelen
17a6c3f88f knownhosts: Use the correct name for ECDSA keys for host key negotiation
The conversion from  ssh_keytype_e  to string does not work for ECDSA keys,
because different key lengths have different string representation.

The usage of  type_c  should work also for every other key type in future,
but it does not reflrect different signature types (SHA2 extension for RSA
keys), but this early in the key exchange phase, we can not make any
assumptions about supported extensions by the server.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 893b69d82b)
2018-10-19 21:22:21 +02:00
Jakub Jelen
e24bb932ed tests: Do not trace sshd
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9285e8516b)
2018-10-19 21:22:21 +02:00
Andreas Schneider
5c2d444fa8 tests: Add option tests for global and user specific known_hosts
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 49e287006f)
2018-10-19 14:05:23 +02:00
Andreas Schneider
9763563c02 options: Add support for getting the known_hosts locations
Fixes T111

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 85fc0d5b83)
2018-10-19 14:05:21 +02:00
Andreas Schneider
5f9d9f4a53 examples: Explicitly track auth state in samplesshd-kbdint
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0ff566b6dd)
2018-10-19 14:05:16 +02:00
Andreas Schneider
e8f3207a0d messages: Check that the requested service is 'ssh-connection'
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9c200d3ef4)
2018-10-19 14:05:14 +02:00
Meng Tan
e5cee205c1 server: Set correct state after sending INFO_REQUEST (Kbd Interactive)
Signed-off-by: Meng Tan <mtan@wallix.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4ea46eecce)
2018-10-19 14:05:12 +02:00
Andreas Schneider
63056d1bb1 priv: Add ssize_t if not available with MSVC
Fixes T113

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Tested-by: Wolf Wolfswinkel <wolf.wolfswinkel@objectplus.nl>
(cherry picked from commit 009ca5c9dd)
2018-10-19 14:05:08 +02:00
Andreas Schneider
09e4f3d331 packet: Add missing break in ssh_packet_incoming_filter()
CID 1396239

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fe618a35dc)
2018-10-19 14:05:05 +02:00
Andreas Schneider
4b886ac656 src: Fix typos
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 795389ae1b)
2018-10-19 14:05:02 +02:00
Andreas Schneider
789df0b7d0 Bump version to 0.8.4
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:25:01 +02:00
Andreas Schneider
66a222a73c Bump ABI to 4.7.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 60037f3275)
2018-10-16 09:25:01 +02:00
Anderson Toshiyuki Sasaki
09a7638575 CVE-2018-10933: Add tests for packet filtering
Created the test torture_packet_filter.c which tests if packets are
being correctly filtered.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
203818608a CVE-2018-10933: Introduced packet filtering
The packet filter checks required states for the incoming packets and
reject them if they arrived in the wrong state.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
f8c452cbef CVE-2018-10933: Check channel state when OPEN_FAILURE arrives
When a SSH2_MSG_OPEN_FAILURE arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
adeaa69cc5 CVE-2018-10933: Check channel state when OPEN_CONFIRMATION arrives
When a SSH2_MSG_OPEN_CONFIRMATION arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
72bce5ece7 CVE-2018-10933: Set correct state after sending MIC
After sending the client token, the auth state is set as
SSH_AUTH_STATE_GSSAPI_MIC_SENT.  Then this can be expected to be the
state when a USERAUTH_FAILURE or USERAUTH_SUCCESS arrives.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
7819621fc2 CVE-2018-10933: Introduce SSH_AUTH_STATE_AUTH_NONE_SENT
The introduced auth state allows to identify when a request without
authentication information was sent.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
fcfba0d8aa CVE-2018-10933: Introduce SSH_AUTH_STATE_PASSWORD_AUTH_SENT
The introduced auth state allows to identify when authentication using
password was tried.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
b166ac4749 CVE-2018-10933: Introduced new auth states
Introduced the states SSH_AUTH_STATE_PUBKEY_OFFER_SENT and
SSH_AUTH_STATE_PUBKEY_AUTH_SENT to know when SSH2_MSG_USERAUTH_PK_OK and
SSH2_MSG_USERAUTH_SUCCESS should be expected.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Tilo Eckert
160a416ef6 chacha: remove re-declared type
re-declaring typedefs are not supported by some compilers

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
(cherry picked from commit d13517e922)
2018-10-13 22:09:18 +02:00
Tilo Eckert
59071bc4c5 knownhosts: Fix invalid read of known_hosts token
Fixes invalid read introduced by commit 21962d.
Accessing tokens[4] for a known_hosts line of
three tokens led to randomly rejected host keys.

This commit completely removes the check because
the optional comments field may contain whitespace.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
(cherry picked from commit 45058285fc)
2018-10-13 22:09:16 +02:00
Andreas Schneider
2ae63251d3 init: Only add DllMain if we create a shared library
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f747e46f33)
2018-10-09 11:40:54 +02:00
Andreas Schneider
eefae820b5 cmake: Always build position independent code
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-02 15:26:52 +02:00
Anderson Toshiyuki Sasaki
0792fb37b0 messages: Fixed possible memory leak in ssh_message_queue
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cc513c4c9a)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
e23c28a82b examples: Add null checks in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 31202822a7)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
7291b50420 examples: Fix libssh_scp.c code style
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6118628424)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
c1d61617fb examples: Fix possible memory leak in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 00e5ef1b3c)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
488fb47c32 tests: Add frees to avoid memory leak errors
The added frees are unnecessary, but the static analyser does not know.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6eef4b4a3c)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
721132696c tests: Replace ssh_buffer_free() with SSH_BUFFER_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 79e907402e)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
ee034e0484 tests: Replace ssh_string_free() with SSH_STRING_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ca7da823c3)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
d56c8fdfc6 tests: Replace ssh_key_free() with SSH_KEY_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2eaa23a20e)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
4269b62153 tests: Use SSH_STRING_FREE_CHAR
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 143b5e2e50)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
c6c63030c5 include: Add SSH_KEY_FREE
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 11d480134c)
2018-09-27 15:39:20 +02:00
Alberto Aguirre
afa5dbb8b1 sftpserver: allocate packet on sftp_server_new
Ensure sftp_server_new allocates the packet and payload as
sftp_packet_read now expects the packet and payload to be
pre-allocated.

Similarly, ensure sftp_get_client_message does not free the packet.

Signed-off-by: Alberto Aguirre <albaguirre@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 14f5624ff5)
2018-09-25 16:42:08 +02:00
David Wedderwille
bd7e8295e2 connector: Add checks if file descriptor is a socket
Fixes T104

Signed-off-by: David Wedderwille <davidwe@posteo.de>
(cherry picked from commit 9adc2d36eb)
2018-09-25 16:41:31 +02:00
Andreas Schneider
933d9c6b07 socket: Pass MSG_NOSIGNAL to send()
This avoid that we get a SIGPIPE.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1e5e09563a)
2018-09-25 16:41:31 +02:00
Andreas Schneider
0f0eb05e03 socket: Return ssize_t for ssh_socket_unbuffered_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 35bf5334b8)
2018-09-25 16:41:31 +02:00
Andreas Schneider
171a950a80 socket: Reformat ssh_socket_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a7604c7d6e)
2018-09-25 16:41:31 +02:00
Andreas Schneider
b1b1da0f97 socket: Reformat ssh_socket_unbuffered_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c5cadaa982)
2018-09-25 16:41:31 +02:00
Andreas Schneider
7453038d74 socket: Return ssize_t for ssh_socket_unbuffered_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit caf50270c6)
2018-09-25 16:41:31 +02:00
Andreas Schneider
29ef92a95e socket: Reformat ssh_socket_pollcallback()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b7a29c7ffd)
2018-09-25 16:41:31 +02:00
Andreas Schneider
6650685758 socket: Reformat ssh_socket_unbuffered_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 491a42d046)
2018-09-25 16:41:31 +02:00
Andreas Schneider
bdca6b7efa connect: Fix build warning on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 642a1b1aa4)
2018-09-25 16:41:31 +02:00
Andreas Schneider
97b2a61d74 config: Fix building without globbing support
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f709c3ac58)
2018-09-25 16:41:31 +02:00
Andreas Schneider
781ce47dea include: Do not declare ssh_channel_new() twice
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ae2b9a3bde)
2018-09-25 16:41:31 +02:00
Andreas Schneider
277ee932d6 cmake: Add -Wattributs for configure checks
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1d7520b68a)
2018-09-25 16:41:31 +02:00
74 changed files with 3846 additions and 906 deletions

View File

@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults) include(DefineCMakeDefaults)
include(DefineCompilerFlags) include(DefineCompilerFlags)
project(libssh VERSION 0.8.3 LANGUAGES C) project(libssh VERSION 0.8.5 LANGUAGES C)
# global needed variable # global needed variable
set(APPLICATION_NAME ${PROJECT_NAME}) set(APPLICATION_NAME ${PROJECT_NAME})
@@ -22,7 +22,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0 # Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes: # If the source code was changed, but there were no interface changes:
# Increment REVISION. # Increment REVISION.
set(LIBRARY_VERSION "4.7.0") set(LIBRARY_VERSION "4.7.2")
set(LIBRARY_SOVERSION "4") set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked

View File

@@ -1,6 +1,23 @@
ChangeLog ChangeLog
========== ==========
version 0.8.5 (released 2018-10-29)
* Added support to get known_hosts locations with ssh_options_get()
* Fixed preferred algorithm for known hosts negotiations
* Fixed KEX with some server implementations (e.g. Cisco)
* Fixed issues with MSVC
* Fixed keyboard-interactive auth in server mode
(regression from CVE-2018-10933)
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
* Fixed socket fd handling with proxy command
* Fixed a memory leak with OpenSSL
version 0.8.4 (released 2018-10-16)
* Fixed CVE-2018-10933
* Fixed building without globbing support
* Fixed possible memory leaks
* Avoid SIGPIPE on sockets
version 0.8.3 (released 2018-09-21) version 0.8.3 (released 2018-09-21)
* Added support for rsa-sha2 * Added support for rsa-sha2
* Added support to parse private keys in openssh container format * Added support to parse private keys in openssh container format

View File

@@ -273,6 +273,13 @@ int main(void) {
# For detecting attributes we need to treat warnings as # For detecting attributes we need to treat warnings as
# errors # errors
if (UNIX) if (UNIX)
# Get warnings for attributs
check_c_compiler_flag("-Wattributs" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Wattributes")
endif()
# Turn warnings into errors
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR) check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR) if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Werror") set(CMAKE_REQUIRED_FLAGS "-Werror")

View File

@@ -16,3 +16,6 @@ set(CMAKE_COLOR_MAKEFILE ON)
# Create the compile command database for clang by default # Create the compile command database for clang by default
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Always build with -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

View File

@@ -187,7 +187,7 @@ keyboard-interactive authentication, coming from the RFC itself (rfc4256):
the name and prompts. If the server presents names or prompts longer than 30 the name and prompts. If the server presents names or prompts longer than 30
characters, the client MAY truncate these fields to the length it can characters, the client MAY truncate these fields to the length it can
display. If the client does truncate any fields, there MUST be an obvious display. If the client does truncate any fields, there MUST be an obvious
indication that such truncation has occured. indication that such truncation has occurred.
The instruction field SHOULD NOT be truncated. Clients SHOULD use control The instruction field SHOULD NOT be truncated. Clients SHOULD use control
character filtering as discussed in [SSH-ARCH] to avoid attacks by character filtering as discussed in [SSH-ARCH] to avoid attacks by

View File

@@ -4,7 +4,7 @@
Port forwarding comes in SSH protocol in two different flavours: Port forwarding comes in SSH protocol in two different flavours:
direct or reverse port forwarding. Direct port forwarding is also direct or reverse port forwarding. Direct port forwarding is also
named local port forwardind, and reverse port forwarding is also called named local port forwarding, and reverse port forwarding is also called
remote port forwarding. SSH also allows X11 tunnels. remote port forwarding. SSH also allows X11 tunnels.
@@ -26,12 +26,12 @@ Mail client application Google Mail
SSH client =====> SSH server SSH client =====> SSH server
Legend: Legend:
--P-->: port connexion through port P --P-->: port connections through port P
=====>: SSH tunnel =====>: SSH tunnel
@endverbatim @endverbatim
A mail client connects to port 5555 of a client. An encrypted tunnel is A mail client connects to port 5555 of a client. An encrypted tunnel is
established to the server. The server connects to port 143 of Google Mail (the established to the server. The server connects to port 143 of Google Mail (the
end point). Now the local mail client can retreive mail. end point). Now the local mail client can retrieve mail.
@subsection forwarding_reverse Reverse port forwarding @subsection forwarding_reverse Reverse port forwarding
@@ -51,7 +51,7 @@ Example of use of reverse port forwarding:
SSH client <===== SSH server SSH client <===== SSH server
Legend: Legend:
--P-->: port connexion through port P --P-->: port connections through port P
=====>: SSH tunnel =====>: SSH tunnel
@endverbatim @endverbatim
In this example, the SSH client establishes the tunnel, In this example, the SSH client establishes the tunnel,
@@ -148,9 +148,9 @@ To do reverse port forwarding, call ssh_channel_listen_forward(),
then ssh_channel_accept_forward(). then ssh_channel_accept_forward().
When you call ssh_channel_listen_forward(), you can let the remote server When you call ssh_channel_listen_forward(), you can let the remote server
chose the non-priviledged port it should listen to. Otherwise, you can chose chose the non-privileged port it should listen to. Otherwise, you can chose
your own priviledged or non-priviledged port. Beware that you should have your own privileged or non-privileged port. Beware that you should have
administrative priviledges on the remote server to open a priviledged port administrative privileges on the remote server to open a privileged port
(port number < 1024). (port number < 1024).
Below is an example of a very rough web server waiting for connections on port Below is an example of a very rough web server waiting for connections on port

View File

@@ -42,7 +42,7 @@ you'll usually open a "sftp session" or a "scp session".
The most important object in a SSH connection is the SSH session. In order The most important object in a SSH connection is the SSH session. In order
to allocate a new SSH session, you use ssh_new(). Don't forget to to allocate a new SSH session, you use ssh_new(). Don't forget to
always verify that the allocation successed. always verify that the allocation succeeded.
@code @code
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <stdlib.h> #include <stdlib.h>
@@ -285,9 +285,9 @@ int verify_knownhost(ssh_session session)
The authentication process is the way a service provider can identify a The authentication process is the way a service provider can identify a
user and verify his/her identity. The authorization process is about enabling user and verify his/her identity. The authorization process is about enabling
the authenticated user the access to ressources. In SSH, the two concepts the authenticated user the access to resources. In SSH, the two concepts
are linked. After authentication, the server can grant the user access to are linked. After authentication, the server can grant the user access to
several ressources such as port forwarding, shell, sftp subsystem, and so on. several resources such as port forwarding, shell, sftp subsystem, and so on.
libssh supports several methods of authentication: libssh supports several methods of authentication:
- "none" method. This method allows to get the available authentications - "none" method. This method allows to get the available authentications
@@ -338,7 +338,7 @@ int main()
} }
// Verify the server's identity // Verify the server's identity
// For the source code of verify_knowhost(), check previous example // For the source code of verify_knownhost(), check previous example
if (verify_knownhost(my_ssh_session) < 0) if (verify_knownhost(my_ssh_session) < 0)
{ {
ssh_disconnect(my_ssh_session); ssh_disconnect(my_ssh_session);
@@ -456,7 +456,7 @@ might be recoverable. SSH_FATAL means the connection has an important
problem and isn't probably recoverable. problem and isn't probably recoverable.
Most of time, the error returned are SSH_FATAL, but some functions Most of time, the error returned are SSH_FATAL, but some functions
(generaly the ssh_request_xxx ones) may fail because of server denying request. (generally the ssh_request_xxx ones) may fail because of server denying request.
In these cases, SSH_REQUEST_DENIED is returned. In these cases, SSH_REQUEST_DENIED is returned.
For thread safety, errors are bound to ssh_session objects. For thread safety, errors are bound to ssh_session objects.

View File

@@ -12,13 +12,13 @@ mean that you should not try to know about and understand these details.
libssh is a Free Software / Open Source project. The libssh library libssh is a Free Software / Open Source project. The libssh library
is distributed under LGPL license. The libssh project has nothing to do with is distributed under LGPL license. The libssh project has nothing to do with
"libssh2", which is a completly different and independant project. "libssh2", which is a completely different and independent project.
libssh can run on top of either libgcrypt or libcrypto, libssh can run on top of either libgcrypt or libcrypto,
two general-purpose cryptographic libraries. two general-purpose cryptographic libraries.
This tutorial concentrates for its main part on the "client" side of libssh. This tutorial concentrates for its main part on the "client" side of libssh.
To learn how to accept incoming SSH connexions (how to write a SSH server), To learn how to accept incoming SSH connections (how to write a SSH server),
you'll have to jump to the end of this document. you'll have to jump to the end of this document.
This tutorial describes libssh version 0.5.0. This version is a little different This tutorial describes libssh version 0.5.0. This version is a little different

View File

@@ -2,7 +2,7 @@
@page libssh_tutor_scp Chapter 6: The SCP subsystem @page libssh_tutor_scp Chapter 6: The SCP subsystem
@section scp_subsystem The SCP subsystem @section scp_subsystem The SCP subsystem
The SCP subsystem has far less functionnality than the SFTP subsystem. The SCP subsystem has far less functionality than the SFTP subsystem.
However, if you only need to copy files from and to the remote system, However, if you only need to copy files from and to the remote system,
it does its job. it does its job.
@@ -210,7 +210,7 @@ int scp_receive(ssh_session session, ssh_scp scp)
size = ssh_scp_request_get_size(scp); size = ssh_scp_request_get_size(scp);
filename = strdup(ssh_scp_request_get_filename(scp)); filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp); mode = ssh_scp_request_get_permissions(scp);
printf("Receiving file %s, size %d, permisssions 0%o\n", printf("Receiving file %s, size %d, permissions 0%o\n",
filename, size, mode); filename, size, mode);
free(filename); free(filename);

View File

@@ -100,7 +100,7 @@ Possible errors are:
@subsection sftp_mkdir Creating a directory @subsection sftp_mkdir Creating a directory
The function sftp_mkdir() tahes the "SFTP session" we juste created as The function sftp_mkdir() takes the "SFTP session" we just created as
its first argument. It also needs the name of the file to create, and the its first argument. It also needs the name of the file to create, and the
desired permissions. The permissions are the same as for the usual mkdir() desired permissions. The permissions are the same as for the usual mkdir()
function. To get a comprehensive list of the available permissions, use the function. To get a comprehensive list of the available permissions, use the
@@ -363,14 +363,14 @@ They use a new handle_type, "sftp_dir", which gives access to the
directory being read. directory being read.
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
to a structure with informations about a directory entry: to a structure with information about a directory entry:
- name: the name of the file or directory - name: the name of the file or directory
- size: its size in bytes - size: its size in bytes
- etc. - etc.
sftp_readdir() might return NULL under two conditions: sftp_readdir() might return NULL under two conditions:
- when the end of the directory has been met - when the end of the directory has been met
- when an error occured - when an error occurred
To tell the difference, call sftp_dir_eof(). To tell the difference, call sftp_dir_eof().

View File

@@ -245,7 +245,7 @@ provide a more elegant way to wait for data coming from many sources.
The functions ssh_select() and ssh_channel_select() remind of the standard The functions ssh_select() and ssh_channel_select() remind of the standard
UNIX select(2) function. The idea is to wait for "something" to happen: UNIX select(2) function. The idea is to wait for "something" to happen:
incoming data to be read, outcoming data to block, or an exception to incoming data to be read, outgoing data to block, or an exception to
occur. Both these functions do a "passive wait", i.e. you can safely use occur. Both these functions do a "passive wait", i.e. you can safely use
them repeatedly in a loop, it will not consume exaggerate processor time them repeatedly in a loop, it will not consume exaggerate processor time
and make your computer unresponsive. It is quite common to use these and make your computer unresponsive. It is quite common to use these

View File

@@ -25,148 +25,230 @@ program.
static char **sources; static char **sources;
static int nsources; static int nsources;
static char *destination; static char *destination;
static int verbosity=0; static int verbosity = 0;
struct location { struct location {
int is_ssh; int is_ssh;
char *user; char *user;
char *host; char *host;
char *path; char *path;
ssh_session session; ssh_session session;
ssh_scp scp; ssh_scp scp;
FILE *file; FILE *file;
}; };
enum { enum {
READ, READ,
WRITE WRITE
}; };
static void usage(const char *argv0){ static void usage(const char *argv0) {
fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n" fprintf(stderr, "Usage : %s [options] [[user@]host1:]file1 ... \n"
" [[user@]host2:]destination\n" " [[user@]host2:]destination\n"
"sample scp client - libssh-%s\n", "sample scp client - libssh-%s\n",
// "Options :\n", // "Options :\n",
// " -r : use RSA to verify host public key\n", // " -r : use RSA to verify host public key\n",
argv0, argv0,
ssh_version(0)); ssh_version(0));
exit(0); exit(0);
} }
static int opts(int argc, char **argv){ static int opts(int argc, char **argv) {
int i; int i;
while((i=getopt(argc,argv,"v"))!=-1){
switch(i){ while((i = getopt(argc, argv, "v")) != -1) {
case 'v': switch(i) {
verbosity++; case 'v':
break; verbosity++;
default: break;
fprintf(stderr,"unknown option %c\n",optopt); default:
fprintf(stderr, "unknown option %c\n", optopt);
usage(argv[0]);
return -1;
}
}
nsources = argc - optind - 1;
if (nsources < 1) {
usage(argv[0]); usage(argv[0]);
return -1; return -1;
} }
}
nsources=argc-optind-1; sources = malloc((nsources + 1) * sizeof(char *));
if(nsources < 1){ if (sources == NULL) {
usage(argv[0]); return -1;
return -1; }
}
sources=malloc((nsources + 1) * sizeof(char *)); for(i = 0; i < nsources; ++i) {
if(sources == NULL) sources[i] = argv[optind];
return -1; optind++;
for(i=0;i<nsources;++i){ }
sources[i] = argv[optind];
optind++; sources[i] = NULL;
} destination = argv[optind];
sources[i]=NULL; return 0;
destination=argv[optind];
return 0;
} }
static struct location *parse_location(char *loc){ static void location_free(struct location *loc)
struct location *location; {
char *ptr; if (loc) {
if (loc->path) {
free(loc->path);
}
loc->path = NULL;
if (loc->is_ssh) {
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
if (loc->user) {
free(loc->user);
}
loc->user = NULL;
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
}
free(loc);
}
}
location = malloc(sizeof(struct location)); static struct location *parse_location(char *loc) {
if (location == NULL) { struct location *location;
return NULL; char *ptr;
}
memset(location, 0, sizeof(struct location));
location->host=location->user=NULL; location = malloc(sizeof(struct location));
ptr=strchr(loc,':'); if (location == NULL) {
if(ptr != NULL){ return NULL;
location->is_ssh=1; }
location->path=strdup(ptr+1); memset(location, 0, sizeof(struct location));
*ptr='\0';
ptr=strchr(loc,'@'); location->host = location->user = NULL;
if(ptr != NULL){ ptr = strchr(loc, ':');
location->host=strdup(ptr+1);
*ptr='\0'; if (ptr != NULL) {
location->user=strdup(loc); location->is_ssh = 1;
location->path = strdup(ptr+1);
*ptr = '\0';
ptr = strchr(loc, '@');
if (ptr != NULL) {
location->host = strdup(ptr+1);
*ptr = '\0';
location->user = strdup(loc);
} else {
location->host = strdup(loc);
}
} else { } else {
location->host=strdup(loc); location->is_ssh = 0;
location->path = strdup(loc);
} }
} else { return location;
location->is_ssh=0;
location->path=strdup(loc);
}
return location;
} }
static int open_location(struct location *loc, int flag){ static void close_location(struct location *loc) {
if(loc->is_ssh && flag==WRITE){ int rc;
loc->session=connect_ssh(loc->host,loc->user,verbosity);
if(!loc->session){ if (loc) {
fprintf(stderr,"Couldn't connect to %s\n",loc->host); if (loc->is_ssh) {
return -1; if (loc->scp) {
rc = ssh_scp_close(loc->scp);
if (rc == SSH_ERROR) {
fprintf(stderr,
"Error closing scp: %s\n",
ssh_get_error(loc->session));
}
ssh_scp_free(loc->scp);
loc->scp = NULL;
}
if (loc->session) {
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
}
} else {
if (loc->file) {
fclose(loc->file);
loc->file = NULL;
}
}
} }
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path); }
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session)); static int open_location(struct location *loc, int flag) {
return -1; if (loc->is_ssh && flag == WRITE) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
return 0;
} else if (loc->is_ssh && flag == READ) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_READ, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
return 0;
} else {
loc->file = fopen(loc->path, flag == READ ? "r":"w");
if (!loc->file) {
if (errno == EISDIR) {
if (chdir(loc->path)) {
fprintf(stderr,
"Error changing directory to %s: %s\n",
loc->path, strerror(errno));
return -1;
}
return 0;
}
fprintf(stderr,
"Error opening %s: %s\n",
loc->path, strerror(errno));
return -1;
}
return 0;
} }
if(ssh_scp_init(loc->scp)==SSH_ERROR){ return -1;
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
return -1;
}
return 0;
} else if(loc->is_ssh && flag==READ){
loc->session=connect_ssh(loc->host, loc->user,verbosity);
if(!loc->session){
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
return -1;
}
loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path);
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
return -1;
}
if(ssh_scp_init(loc->scp)==SSH_ERROR){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
return -1;
}
return 0;
} else {
loc->file=fopen(loc->path,flag==READ ? "r":"w");
if(!loc->file){
if(errno==EISDIR){
if(chdir(loc->path)){
fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
return -1;
}
return 0;
}
fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
return -1;
}
return 0;
}
return -1;
} }
/** @brief copies files from source location to destination /** @brief copies files from source location to destination
@@ -174,155 +256,197 @@ static int open_location(struct location *loc, int flag){
* @param dest destination location * @param dest destination location
* @param recursive Copy also directories * @param recursive Copy also directories
*/ */
static int do_copy(struct location *src, struct location *dest, int recursive){ static int do_copy(struct location *src, struct location *dest, int recursive) {
int size; int size;
socket_t fd; socket_t fd;
struct stat s; struct stat s;
int w,r; int w, r;
char buffer[16384]; char buffer[16384];
int total=0; int total = 0;
int mode; int mode;
char *filename = NULL; char *filename = NULL;
/* recursive mode doesn't work yet */ /* recursive mode doesn't work yet */
(void)recursive; (void)recursive;
/* Get the file name and size*/ /* Get the file name and size*/
if(!src->is_ssh){ if (!src->is_ssh) {
fd = fileno(src->file); fd = fileno(src->file);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno)); fprintf(stderr,
return -1; "Invalid file pointer, error: %s\n",
} strerror(errno));
r = fstat(fd, &s); return -1;
if (r < 0) { }
return -1; r = fstat(fd, &s);
} if (r < 0) {
size=s.st_size; return -1;
mode = s.st_mode & ~S_IFMT; }
filename=ssh_basename(src->path); size = s.st_size;
} else { mode = s.st_mode & ~S_IFMT;
size=0; filename = ssh_basename(src->path);
do { } else {
r=ssh_scp_pull_request(src->scp); size = 0;
if(r==SSH_SCP_REQUEST_NEWDIR){ do {
ssh_scp_deny_request(src->scp,"Not in recursive mode"); r = ssh_scp_pull_request(src->scp);
continue; if (r == SSH_SCP_REQUEST_NEWDIR) {
} ssh_scp_deny_request(src->scp, "Not in recursive mode");
if(r==SSH_SCP_REQUEST_NEWFILE){ continue;
size=ssh_scp_request_get_size(src->scp); }
filename=strdup(ssh_scp_request_get_filename(src->scp)); if (r == SSH_SCP_REQUEST_NEWFILE) {
mode=ssh_scp_request_get_permissions(src->scp); size = ssh_scp_request_get_size(src->scp);
//ssh_scp_accept_request(src->scp); filename = strdup(ssh_scp_request_get_filename(src->scp));
break; mode = ssh_scp_request_get_permissions(src->scp);
} //ssh_scp_accept_request(src->scp);
if(r==SSH_ERROR){ break;
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session)); }
if (r == SSH_ERROR) {
fprintf(stderr,
"Error: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename); ssh_string_free_char(filename);
return -1; return -1;
} }
} while(r != SSH_SCP_REQUEST_NEWFILE); } while(r != SSH_SCP_REQUEST_NEWFILE);
} }
if(dest->is_ssh){ if (dest->is_ssh) {
r=ssh_scp_push_file(dest->scp,src->path, size, mode); r = ssh_scp_push_file(dest->scp, src->path, size, mode);
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path); // snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path);
if(r==SSH_ERROR){ if (r == SSH_ERROR) {
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session)); fprintf(stderr,
ssh_string_free_char(filename); "error: %s\n",
ssh_scp_free(dest->scp); ssh_get_error(dest->session));
dest->scp = NULL; ssh_string_free_char(filename);
return -1; ssh_scp_free(dest->scp);
} dest->scp = NULL;
} else { return -1;
if(!dest->file){ }
dest->file=fopen(filename,"w"); } else {
if(!dest->file){ if (!dest->file) {
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno)); dest->file = fopen(filename, "w");
if(src->is_ssh) if (!dest->file) {
ssh_scp_deny_request(src->scp,"Cannot open local file"); fprintf(stderr,
ssh_string_free_char(filename); "Cannot open %s for writing: %s\n",
return -1; filename, strerror(errno));
} if (src->is_ssh) {
} ssh_scp_deny_request(src->scp, "Cannot open local file");
if(src->is_ssh){ }
ssh_scp_accept_request(src->scp); ssh_string_free_char(filename);
} return -1;
} }
do { }
if(src->is_ssh){ if (src->is_ssh) {
r=ssh_scp_read(src->scp,buffer,sizeof(buffer)); ssh_scp_accept_request(src->scp);
if(r==SSH_ERROR){ }
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session)); }
ssh_string_free_char(filename);
return -1;
}
if(r==0)
break;
} else {
r=fread(buffer,1,sizeof(buffer),src->file);
if(r==0)
break;
if(r<0){
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if(dest->is_ssh){
w=ssh_scp_write(dest->scp,buffer,r);
if(w == SSH_ERROR){
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp=NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w=fwrite(buffer,r,1,dest->file);
if(w<=0){
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total+=r;
} while(total < size); do {
ssh_string_free_char(filename); if (src->is_ssh) {
printf("wrote %d bytes\n",total); r = ssh_scp_read(src->scp, buffer, sizeof(buffer));
return 0; if (r == SSH_ERROR) {
fprintf(stderr,
"Error reading scp: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
if (r == 0) {
break;
}
} else {
r = fread(buffer, 1, sizeof(buffer), src->file);
if (r == 0) {
break;
}
if (r < 0) {
fprintf(stderr,
"Error reading file: %s\n",
strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if (dest->is_ssh) {
w = ssh_scp_write(dest->scp, buffer, r);
if (w == SSH_ERROR) {
fprintf(stderr,
"Error writing in scp: %s\n",
ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp = NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w = fwrite(buffer, r, 1, dest->file);
if (w <= 0) {
fprintf(stderr,
"Error writing in local file: %s\n",
strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total += r;
} while(total < size);
ssh_string_free_char(filename);
printf("wrote %d bytes\n", total);
return 0;
} }
int main(int argc, char **argv){ int main(int argc, char **argv) {
struct location *dest, *src; struct location *dest, *src;
int i; int i;
int r; int r;
if(opts(argc,argv)<0) if (opts(argc, argv) < 0) {
return EXIT_FAILURE; r = EXIT_FAILURE;
dest=parse_location(destination); goto end;
if(open_location(dest,WRITE)<0)
return EXIT_FAILURE;
for(i=0;i<nsources;++i){
src=parse_location(sources[i]);
if(open_location(src,READ)<0){
return EXIT_FAILURE;
} }
if(do_copy(src,dest,0) < 0){
break; dest = parse_location(destination);
if (dest == NULL) {
r = EXIT_FAILURE;
goto end;
} }
}
if (dest->is_ssh && dest->scp != NULL) { if (open_location(dest, WRITE) < 0) {
r=ssh_scp_close(dest->scp); location_free(dest);
if(r == SSH_ERROR){ r = EXIT_FAILURE;
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session)); goto end;
ssh_scp_free(dest->scp); }
dest->scp=NULL;
return -1; for (i = 0; i < nsources; ++i) {
} src = parse_location(sources[i]);
} else { if (src == NULL) {
fclose(dest->file); r = EXIT_FAILURE;
dest->file=NULL; goto close_dest;
} }
ssh_disconnect(dest->session);
ssh_finalize(); if (open_location(src, READ) < 0) {
return 0; location_free(src);
r = EXIT_FAILURE;
goto close_dest;
}
if (do_copy(src, dest, 0) < 0) {
close_location(src);
location_free(src);
break;
}
close_location(src);
location_free(src);
}
r = 0;
close_dest:
close_location(dest);
location_free(dest);
end:
return r;
} }

View File

@@ -23,6 +23,7 @@ clients must be made or how a client should react.
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#define SSHD_USER "libssh" #define SSHD_USER "libssh"
#define SSHD_PASSWORD "libssh" #define SSHD_PASSWORD "libssh"
@@ -36,6 +37,7 @@ clients must be made or how a client should react.
#endif #endif
static int port = 22; static int port = 22;
static bool authenticated = false;
#ifdef WITH_PCAP #ifdef WITH_PCAP
static const char *pcap_file = "debug.server.pcap"; static const char *pcap_file = "debug.server.pcap";
@@ -61,11 +63,20 @@ static void cleanup_pcap(void) {
#endif #endif
static int auth_password(const char *user, const char *password){ static int auth_password(const char *user, const char *password)
if(strcmp(user, SSHD_USER)) {
int cmp;
cmp = strcmp(user, SSHD_USER);
if (cmp != 0) {
return 0; return 0;
if(strcmp(password, SSHD_PASSWORD)) }
cmp = strcmp(password, SSHD_PASSWORD);
if (cmp != 0) {
return 0; return 0;
}
authenticated = true;
return 1; // authenticated return 1; // authenticated
} }
#ifdef HAVE_ARGP_H #ifdef HAVE_ARGP_H
@@ -200,6 +211,7 @@ static int kbdint_check_response(ssh_session session) {
return 0; return 0;
} }
authenticated = true;
return 1; return 1;
} }
@@ -328,7 +340,7 @@ int main(int argc, char **argv){
/* proceed to authentication */ /* proceed to authentication */
auth = authenticate(session); auth = authenticate(session);
if(!auth){ if (!auth || !authenticated) {
printf("Authentication error: %s\n", ssh_get_error(session)); printf("Authentication error: %s\n", ssh_get_error(session));
ssh_disconnect(session); ssh_disconnect(session);
return 1; return 1;

View File

@@ -76,6 +76,14 @@ enum ssh_auth_state_e {
SSH_AUTH_STATE_GSSAPI_TOKEN, SSH_AUTH_STATE_GSSAPI_TOKEN,
/** We have sent the MIC and expecting to be authenticated */ /** We have sent the MIC and expecting to be authenticated */
SSH_AUTH_STATE_GSSAPI_MIC_SENT, SSH_AUTH_STATE_GSSAPI_MIC_SENT,
/** We have offered a pubkey to check if it is supported */
SSH_AUTH_STATE_PUBKEY_OFFER_SENT,
/** We have sent pubkey and signature expecting to be authenticated */
SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
/** We have sent a password expecting to be authenticated */
SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
/** We have sent a request without auth information (method 'none') */
SSH_AUTH_STATE_AUTH_NONE_SENT,
}; };
/** @internal /** @internal

View File

@@ -92,7 +92,6 @@ SSH_PACKET_CALLBACK(channel_rcv_close);
SSH_PACKET_CALLBACK(channel_rcv_request); SSH_PACKET_CALLBACK(channel_rcv_request);
SSH_PACKET_CALLBACK(channel_rcv_data); SSH_PACKET_CALLBACK(channel_rcv_data);
ssh_channel ssh_channel_new(ssh_session session);
int channel_default_bufferize(ssh_channel channel, void *data, int len, int channel_default_bufferize(ssh_channel channel, void *data, int len,
int is_stderr); int is_stderr);
int ssh_channel_flush(ssh_channel channel); int ssh_channel_flush(ssh_channel channel);

View File

@@ -45,5 +45,6 @@ char *ssh_find_matching(const char *in_d, const char *what_d);
const char *ssh_kex_get_supported_method(uint32_t algo); const char *ssh_kex_get_supported_method(uint32_t algo);
const char *ssh_kex_get_default_methods(uint32_t algo); const char *ssh_kex_get_default_methods(uint32_t algo);
const char *ssh_kex_get_description(uint32_t algo); const char *ssh_kex_get_description(uint32_t algo);
char *ssh_client_select_hostkeys(ssh_session session);
#endif /* KEX_H_ */ #endif /* KEX_H_ */

View File

@@ -23,5 +23,9 @@
#define SSH_KNOWNHOSTS_H_ #define SSH_KNOWNHOSTS_H_
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session); struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry_file(ssh_session session,
const char *filename,
struct ssh_knownhosts_entry **pentry);
#endif /* SSH_KNOWNHOSTS_H_ */ #endif /* SSH_KNOWNHOSTS_H_ */

View File

@@ -79,7 +79,7 @@
/* libssh version */ /* libssh version */
#define LIBSSH_VERSION_MAJOR 0 #define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 8 #define LIBSSH_VERSION_MINOR 8
#define LIBSSH_VERSION_MICRO 3 #define LIBSSH_VERSION_MICRO 5
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \ #define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \ LIBSSH_VERSION_MINOR, \
@@ -630,6 +630,8 @@ typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata); int echo, int verify, void *userdata);
LIBSSH_API ssh_key ssh_key_new(void); LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
LIBSSH_API void ssh_key_free (ssh_key key); LIBSSH_API void ssh_key_free (ssh_key key);
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key); LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type); LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);

View File

@@ -43,6 +43,12 @@ enum ssh_packet_state_e {
PACKET_STATE_PROCESSING PACKET_STATE_PROCESSING
}; };
enum ssh_packet_filter_result_e {
SSH_PACKET_UNKNOWN,
SSH_PACKET_ALLOWED,
SSH_PACKET_DENIED
};
int ssh_packet_send(ssh_session session); int ssh_packet_send(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_unimplemented); SSH_PACKET_CALLBACK(ssh_packet_unimplemented);

View File

@@ -29,6 +29,7 @@
#ifndef _LIBSSH_PRIV_H #ifndef _LIBSSH_PRIV_H
#define _LIBSSH_PRIV_H #define _LIBSSH_PRIV_H
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -128,6 +129,13 @@ char *strndup(const char *s, size_t n);
# endif /* HAVE__VSNPRINTF */ # endif /* HAVE__VSNPRINTF */
# endif /* HAVE__VSNPRINTF_S */ # endif /* HAVE__VSNPRINTF_S */
# ifndef _SSIZE_T_DEFINED
# undef ssize_t
# include <BaseTsd.h>
typedef _W64 SSIZE_T ssize_t;
# define _SSIZE_T_DEFINED
# endif /* _SSIZE_T_DEFINED */
# endif /* _MSC_VER */ # endif /* _MSC_VER */
struct timeval; struct timeval;

View File

@@ -53,9 +53,14 @@ extern "C" {
typedef uint32_t gid_t; typedef uint32_t gid_t;
#endif /* gid_t */ #endif /* gid_t */
#ifdef _MSC_VER #ifdef _MSC_VER
#ifndef ssize_t
typedef _W64 SSIZE_T ssize_t; # ifndef _SSIZE_T_DEFINED
#endif /* ssize_t */ # undef ssize_t
# include <BaseTsd.h>
typedef _W64 SSIZE_T ssize_t;
# define _SSIZE_T_DEFINED
# endif /* _SSIZE_T_DEFINED */
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#endif /* _WIN32 */ #endif /* _WIN32 */

View File

@@ -34,7 +34,7 @@ ssh_socket ssh_socket_new(ssh_session session);
void ssh_socket_reset(ssh_socket s); void ssh_socket_reset(ssh_socket s);
void ssh_socket_free(ssh_socket s); void ssh_socket_free(ssh_socket s);
void ssh_socket_set_fd(ssh_socket s, socket_t fd); void ssh_socket_set_fd(ssh_socket s, socket_t fd);
socket_t ssh_socket_get_fd_in(ssh_socket s); socket_t ssh_socket_get_fd(ssh_socket s);
#ifndef _WIN32 #ifndef _WIN32
int ssh_socket_unix(ssh_socket s, const char *path); int ssh_socket_unix(ssh_socket s, const char *path);
void ssh_execute_command(const char *command, socket_t in, socket_t out); void ssh_execute_command(const char *command, socket_t in, socket_t out);
@@ -61,8 +61,7 @@ int ssh_socket_set_blocking(socket_t fd);
void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks); void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s); int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_in(ssh_socket s); struct ssh_poll_handle_struct * ssh_socket_get_poll_handle(ssh_socket s);
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_out(ssh_socket s);
int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr); int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr);

View File

@@ -1 +1 @@
4.7.0 4.7.2

View File

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

View File

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

View File

@@ -93,7 +93,7 @@ static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int
/* Using a socket ? */ /* Using a socket ? */
if (channel == NULL) { if (channel == NULL) {
fd = ssh_socket_get_fd_in(agent->sock); fd = ssh_socket_get_fd(agent->sock);
pfd.fd = fd; pfd.fd = fd;
pfd.events = do_read ? POLLIN : POLLOUT; pfd.events = do_read ? POLLIN : POLLOUT;

View File

@@ -85,6 +85,10 @@ static int ssh_auth_response_termination(void *user) {
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN: case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT: case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
return 0; return 0;
default: default:
return 1; return 1;
@@ -167,6 +171,10 @@ static int ssh_userauth_get_response(ssh_session session) {
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN: case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT: case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
case SSH_AUTH_STATE_NONE: case SSH_AUTH_STATE_NONE:
/* not reached */ /* not reached */
rc = SSH_AUTH_ERROR; rc = SSH_AUTH_ERROR;
@@ -312,24 +320,30 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok) { SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok) {
int rc; int rc;
SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE, SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, assuming SSH_USERAUTH_INFO_REQUEST"); "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
rc = ssh_packet_userauth_info_request(session,type,packet,user);
#ifdef WITH_GSSAPI
} else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else {
session->auth.state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
}
return rc; if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, "
"assuming SSH_USERAUTH_INFO_REQUEST");
rc = ssh_packet_userauth_info_request(session,type,packet,user);
#ifdef WITH_GSSAPI
} else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else if (session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT) {
session->auth.state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
} else {
session->auth.state = SSH_AUTH_STATE_ERROR;
SSH_LOG(SSH_LOG_TRACE, "SSH_USERAUTH_PK_OK received in wrong state");
rc = SSH_PACKET_USED;
}
return rc;
} }
/** /**
@@ -416,7 +430,7 @@ int ssh_userauth_none(ssh_session session, const char *username) {
} }
session->auth.current_method = SSH_AUTH_METHOD_NONE; session->auth.current_method = SSH_AUTH_METHOD_NONE;
session->auth.state = SSH_AUTH_STATE_NONE; session->auth.state = SSH_AUTH_STATE_AUTH_NONE_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE; session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -553,7 +567,7 @@ int ssh_userauth_try_publickey(ssh_session session,
ssh_string_free(pubkey_s); ssh_string_free(pubkey_s);
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY; session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_NONE; session->auth.state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY; session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -701,7 +715,7 @@ int ssh_userauth_publickey(ssh_session session,
} }
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY; session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_NONE; session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY; session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -797,7 +811,7 @@ static int ssh_userauth_agent_publickey(ssh_session session,
} }
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY; session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_NONE; session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT; session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
@@ -1258,7 +1272,7 @@ int ssh_userauth_password(ssh_session session,
} }
session->auth.current_method = SSH_AUTH_METHOD_PASSWORD; session->auth.current_method = SSH_AUTH_METHOD_PASSWORD;
session->auth.state = SSH_AUTH_STATE_NONE; session->auth.state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD; session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {

View File

@@ -447,7 +447,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
return SSH_ERROR; return SSH_ERROR;
} }
ssh_socket_set_fd(session->socket, fd); ssh_socket_set_fd(session->socket, fd);
ssh_socket_get_poll_handle_out(session->socket); ssh_socket_get_poll_handle(session->socket);
/* We must try to import any keys that could be imported in case /* We must try to import any keys that could be imported in case
* we are not using ssh_bind_listen (which is the other place * we are not using ssh_bind_listen (which is the other place

View File

@@ -171,6 +171,15 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
"Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d", "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
channel->local_channel, channel->local_channel,
channel->remote_channel); channel->remote_channel);
if (channel->state != SSH_CHANNEL_STATE_OPENING) {
SSH_LOG(SSH_LOG_RARE,
"SSH2_MSG_CHANNEL_OPEN_CONFIRMATION received in incorrect "
"channel state %d",
channel->state);
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL, SSH_LOG(SSH_LOG_PROTOCOL,
"Remote window : %lu, maxpacket : %lu", "Remote window : %lu, maxpacket : %lu",
(long unsigned int) channel->remote_window, (long unsigned int) channel->remote_window,
@@ -211,6 +220,14 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
if (channel->state != SSH_CHANNEL_STATE_OPENING) {
SSH_LOG(SSH_LOG_RARE,
"SSH2_MSG_CHANNEL_OPEN_FAILURE received in incorrect channel "
"state %d",
channel->state);
goto error;
}
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session, SSH_REQUEST_DENIED,
"Channel opening failure: channel %u error (%lu) %s", "Channel opening failure: channel %u error (%lu) %s",
channel->local_channel, channel->local_channel,
@@ -219,6 +236,10 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
SAFE_FREE(error); SAFE_FREE(error);
channel->state=SSH_CHANNEL_STATE_OPEN_DENIED; channel->state=SSH_CHANNEL_STATE_OPEN_DENIED;
return SSH_PACKET_USED; return SSH_PACKET_USED;
error:
ssh_set_error(session, SSH_FATAL, "Invalid packet");
return SSH_PACKET_USED;
} }
static int ssh_channel_open_termination(void *c){ static int ssh_channel_open_termination(void *c){

View File

@@ -411,6 +411,14 @@ static void ssh_client_connection_callback(ssh_session session)
ssh_packet_set_default_callbacks(session); ssh_packet_set_default_callbacks(session);
session->session_state = SSH_SESSION_STATE_INITIAL_KEX; session->session_state = SSH_SESSION_STATE_INITIAL_KEX;
rc = ssh_set_client_kex(session);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_send_kex(session, 0);
if (rc < 0) {
goto error;
}
set_status(session, 0.5f); set_status(session, 0.5f);
break; break;
@@ -420,14 +428,19 @@ static void ssh_client_connection_callback(ssh_session session)
case SSH_SESSION_STATE_KEXINIT_RECEIVED: case SSH_SESSION_STATE_KEXINIT_RECEIVED:
set_status(session,0.6f); set_status(session,0.6f);
ssh_list_kex(&session->next_crypto->server_kex); ssh_list_kex(&session->next_crypto->server_kex);
if (ssh_set_client_kex(session) < 0) { if (session->next_crypto->client_kex.methods[0] == NULL) {
goto error; /* in rekeying state if next_crypto client_kex is empty */
rc = ssh_set_client_kex(session);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_send_kex(session, 0);
if (rc < 0) {
goto error;
}
} }
if (ssh_kex_select_methods(session) == SSH_ERROR) if (ssh_kex_select_methods(session) == SSH_ERROR)
goto error; goto error;
if (ssh_send_kex(session, 0) < 0) {
goto error;
}
set_status(session,0.8f); set_status(session,0.8f);
session->session_state=SSH_SESSION_STATE_DH; session->session_state=SSH_SESSION_STATE_DH;
if (dh_handshake(session) == SSH_ERROR) { if (dh_handshake(session) == SSH_ERROR) {

View File

@@ -462,7 +462,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
p = ssh_config_get_str_tok(&s, NULL); p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) { if (p && *parsing) {
#ifdef HAVE_GLOB #if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
local_parse_glob(session, p, parsing, seen); local_parse_glob(session, p, parsing, seen);
#else #else
local_parse_file(session, p, parsing, seen); local_parse_file(session, p, parsing, seen);

View File

@@ -220,7 +220,12 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
static int set_tcp_nodelay(socket_t socket) static int set_tcp_nodelay(socket_t socket)
{ {
int opt = 1; int opt = 1;
return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
return setsockopt(socket,
IPPROTO_TCP,
TCP_NODELAY,
(void *)&opt,
sizeof(opt));
} }
/** /**

View File

@@ -26,6 +26,10 @@
#include "libssh/callbacks.h" #include "libssh/callbacks.h"
#include "libssh/session.h" #include "libssh/session.h"
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/stat.h>
#define CHUNKSIZE 4096 #define CHUNKSIZE 4096
#ifdef _WIN32 #ifdef _WIN32
@@ -40,6 +44,9 @@
# undef unlink # undef unlink
# define unlink _unlink # define unlink _unlink
# endif /* HAVE_IO_H */ # endif /* HAVE_IO_H */
#else
# include <sys/types.h>
# include <sys/socket.h>
#endif #endif
struct ssh_connector_struct { struct ssh_connector_struct {
@@ -51,6 +58,8 @@ struct ssh_connector_struct {
socket_t in_fd; socket_t in_fd;
socket_t out_fd; socket_t out_fd;
bool fd_is_socket;
ssh_poll_handle in_poll; ssh_poll_handle in_poll;
ssh_poll_handle out_poll; ssh_poll_handle out_poll;
@@ -76,6 +85,13 @@ static int ssh_connector_channel_write_wontblock_cb(ssh_session session,
ssh_channel channel, ssh_channel channel,
size_t bytes, size_t bytes,
void *userdata); void *userdata);
static ssize_t ssh_connector_fd_read(ssh_connector connector,
void *buffer,
uint32_t len);
static ssize_t ssh_connector_fd_write(ssh_connector connector,
const void *buffer,
uint32_t len);
static bool ssh_connector_fd_is_socket(socket_t socket);
ssh_connector ssh_connector_new(ssh_session session) ssh_connector ssh_connector_new(ssh_session session)
{ {
@@ -91,6 +107,8 @@ ssh_connector ssh_connector_new(ssh_session session)
connector->in_fd = SSH_INVALID_SOCKET; connector->in_fd = SSH_INVALID_SOCKET;
connector->out_fd = SSH_INVALID_SOCKET; connector->out_fd = SSH_INVALID_SOCKET;
connector->fd_is_socket = false;
ssh_callbacks_init(&connector->in_channel_cb); ssh_callbacks_init(&connector->in_channel_cb);
ssh_callbacks_init(&connector->out_channel_cb); ssh_callbacks_init(&connector->out_channel_cb);
@@ -167,12 +185,14 @@ int ssh_connector_set_out_channel(ssh_connector connector,
void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd) void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd)
{ {
connector->in_fd = fd; connector->in_fd = fd;
connector->fd_is_socket = ssh_connector_fd_is_socket(fd);
connector->in_channel = NULL; connector->in_channel = NULL;
} }
void ssh_connector_set_out_fd(ssh_connector connector, socket_t fd) void ssh_connector_set_out_fd(ssh_connector connector, socket_t fd)
{ {
connector->out_fd = fd; connector->out_fd = fd;
connector->fd_is_socket = ssh_connector_fd_is_socket(fd);
connector->out_channel = NULL; connector->out_channel = NULL;
} }
@@ -223,9 +243,9 @@ static void ssh_connector_reset_pollevents(ssh_connector connector)
static void ssh_connector_fd_in_cb(ssh_connector connector) static void ssh_connector_fd_in_cb(ssh_connector connector)
{ {
unsigned char buffer[CHUNKSIZE]; unsigned char buffer[CHUNKSIZE];
int r; uint32_t toread = CHUNKSIZE;
int toread = CHUNKSIZE; ssize_t r;
int w; ssize_t w;
int total = 0; int total = 0;
int rc; int rc;
@@ -239,7 +259,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
toread = MIN(size, CHUNKSIZE); toread = MIN(size, CHUNKSIZE);
} }
r = read(connector->in_fd, buffer, toread); r = ssh_connector_fd_read(connector, buffer, toread);
if (r < 0) { if (r < 0) {
ssh_connector_except(connector, connector->in_fd); ssh_connector_except(connector, connector->in_fd);
return; return;
@@ -277,7 +297,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
* bytes * bytes
*/ */
while (total != r) { while (total != r) {
w = write(connector->out_fd, buffer + total, r - total); w = ssh_connector_fd_write(connector, buffer + total, r - total);
if (w < 0){ if (w < 0){
ssh_connector_except(connector, connector->out_fd); ssh_connector_except(connector, connector->out_fd);
return; return;
@@ -319,7 +339,7 @@ static void ssh_connector_fd_out_cb(ssh_connector connector){
} else if(r>0) { } else if(r>0) {
/* loop around write in case the write blocks even for CHUNKSIZE bytes */ /* loop around write in case the write blocks even for CHUNKSIZE bytes */
while (total != r){ while (total != r){
w = write(connector->out_fd, buffer + total, r - total); w = ssh_connector_fd_write(connector, buffer + total, r - total);
if (w < 0){ if (w < 0){
ssh_connector_except(connector, connector->out_fd); ssh_connector_except(connector, connector->out_fd);
return; return;
@@ -451,7 +471,7 @@ static int ssh_connector_channel_data_cb(ssh_session session,
ssh_connector_except_channel(connector, connector->out_channel); ssh_connector_except_channel(connector, connector->out_channel);
} }
} else if (connector->out_fd != SSH_INVALID_SOCKET) { } else if (connector->out_fd != SSH_INVALID_SOCKET) {
w = write(connector->out_fd, data, len); w = ssh_connector_fd_write(connector, data, len);
if (w < 0) if (w < 0)
ssh_connector_except(connector, connector->out_fd); ssh_connector_except(connector, connector->out_fd);
} else { } else {
@@ -634,3 +654,96 @@ int ssh_connector_remove_event(ssh_connector connector) {
return SSH_OK; return SSH_OK;
} }
/**
* @internal
*
* @brief Check the file descriptor to check if it is a Windows socket handle.
*
*/
static bool ssh_connector_fd_is_socket(socket_t s)
{
#ifdef _WIN32
struct sockaddr_storage ss;
int len = sizeof(struct sockaddr_storage);
int rc;
rc = getsockname(s, (struct sockaddr *)&ss, &len);
if (rc == 0) {
return true;
}
SSH_LOG(SSH_LOG_TRACE,
"Error %i in getsockname() for fd %d",
WSAGetLastError(),
s);
return false;
#else
struct stat sb;
int rc;
rc = fstat(s, &sb);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
"error %i in fstat() for fd %d",
errno,
s);
return false;
}
/* The descriptor is a socket */
if (S_ISSOCK(sb.st_mode)) {
return true;
}
return false;
#endif /* _WIN32 */
}
/**
* @internal
*
* @brief read len bytes from socket into buffer
*
*/
static ssize_t ssh_connector_fd_read(ssh_connector connector,
void *buffer,
uint32_t len)
{
ssize_t nread = -1;
if (connector->fd_is_socket) {
nread = recv(connector->in_fd,buffer, len, 0);
} else {
nread = read(connector->in_fd,buffer, len);
}
return nread;
}
/**
* @internal
*
* @brief brief writes len bytes from buffer to socket
*
*/
static ssize_t ssh_connector_fd_write(ssh_connector connector,
const void *buffer,
uint32_t len)
{
ssize_t bwritten = -1;
int flags = 0;
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
if (connector->fd_is_socket) {
bwritten = send(connector->out_fd,buffer, len, flags);
} else {
bwritten = write(connector->out_fd, buffer, len);
}
return bwritten;
}

View File

@@ -10,8 +10,6 @@ Public domain.
#include "libssh/chacha.h" #include "libssh/chacha.h"
typedef unsigned int uint32_t;
typedef struct chacha_ctx chacha_ctx; typedef struct chacha_ctx chacha_ctx;
#define U8C(v) (v##U) #define U8C(v) (v##U)

View File

@@ -120,6 +120,7 @@ static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
ssh_set_error_oom(session); ssh_set_error_oom(session);
return SSH_ERROR; return SSH_ERROR;
} }
session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN;
ssh_packet_send(session); ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
@@ -960,8 +961,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
} }
if (maj_stat == GSS_S_COMPLETE) { if (maj_stat == GSS_S_COMPLETE) {
session->auth.state = SSH_AUTH_STATE_NONE;
ssh_gssapi_send_mic(session); ssh_gssapi_send_mic(session);
session->auth.state = SSH_AUTH_STATE_GSSAPI_MIC_SENT;
} }
return SSH_PACKET_USED; return SSH_PACKET_USED;

View File

@@ -224,7 +224,7 @@ int ssh_finalize(void) {
#ifdef _WIN32 #ifdef _WIN32
#ifdef _MSC_VER #if defined(_MSC_VER) && !defined(LIBSSH_STATIC)
/* Library constructor and destructor */ /* Library constructor and destructor */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason, DWORD fdwReason,
@@ -249,7 +249,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,
return TRUE; return TRUE;
} }
#endif /* _MSC_VER */ #endif /* _MSC_VER && !LIBSSH_STATIC */
#endif /* _WIN32 */ #endif /* _WIN32 */

View File

@@ -26,6 +26,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/buffer.h" #include "libssh/buffer.h"
@@ -592,9 +593,11 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
* @returns a cstring containing a comma-separated list of hostkey methods. * @returns a cstring containing a comma-separated list of hostkey methods.
* NULL if no method matches * NULL if no method matches
*/ */
static char *ssh_client_select_hostkeys(ssh_session session) char *ssh_client_select_hostkeys(ssh_session session)
{ {
char methods_buffer[128]={0}; char methods_buffer[128]={0};
char tail_buffer[128]={0};
char *new_hostkeys = NULL;
static const char *preferred_hostkeys[] = { static const char *preferred_hostkeys[] = {
"ssh-ed25519", "ssh-ed25519",
"ecdsa-sha2-nistp521", "ecdsa-sha2-nistp521",
@@ -610,7 +613,7 @@ static char *ssh_client_select_hostkeys(ssh_session session)
struct ssh_iterator *it = NULL; struct ssh_iterator *it = NULL;
size_t algo_count; size_t algo_count;
int needcomma = 0; int needcomma = 0;
int i; size_t i, len;
algo_list = ssh_known_hosts_get_algorithms(session); algo_list = ssh_known_hosts_get_algorithms(session);
if (algo_list == NULL) { if (algo_list == NULL) {
@@ -624,9 +627,11 @@ static char *ssh_client_select_hostkeys(ssh_session session)
} }
for (i = 0; preferred_hostkeys[i] != NULL; ++i) { for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
bool found = false;
for (it = ssh_list_get_iterator(algo_list); for (it = ssh_list_get_iterator(algo_list);
it != NULL; it != NULL;
it = ssh_list_get_iterator(algo_list)) { it = it->next) {
const char *algo = ssh_iterator_value(const char *, it); const char *algo = ssh_iterator_value(const char *, it);
int cmp; int cmp;
int ok; int ok;
@@ -644,10 +649,18 @@ static char *ssh_client_select_hostkeys(ssh_session session)
algo, algo,
sizeof(methods_buffer) - strlen(methods_buffer) - 1); sizeof(methods_buffer) - strlen(methods_buffer) - 1);
needcomma = 1; needcomma = 1;
found = true;
} }
} }
}
ssh_list_remove(algo_list, it); /* Collect the rest of the algorithms in other buffer, that will
* follow the preferred buffer. This will signalize all the algorithms
* we are willing to accept.
*/
if (!found) {
snprintf(tail_buffer + strlen(tail_buffer),
sizeof(tail_buffer) - strlen(tail_buffer),
",%s", preferred_hostkeys[i]);
} }
} }
ssh_list_free(algo_list); ssh_list_free(algo_list);
@@ -658,11 +671,23 @@ static char *ssh_client_select_hostkeys(ssh_session session)
return NULL; return NULL;
} }
/* Append the supported list to the preferred.
* The length is maximum 128 + 128 + 1, which will not overflow
*/
len = strlen(methods_buffer) + strlen(tail_buffer) + 1;
new_hostkeys = malloc(len);
if (new_hostkeys == NULL) {
ssh_set_error_oom(session);
return NULL;
}
snprintf(new_hostkeys, len,
"%s%s", methods_buffer, tail_buffer);
SSH_LOG(SSH_LOG_DEBUG, SSH_LOG(SSH_LOG_DEBUG,
"Changing host key method to \"%s\"", "Changing host key method to \"%s\"",
methods_buffer); new_hostkeys);
return strdup(methods_buffer); return new_hostkeys;
} }
/** /**

View File

@@ -131,17 +131,13 @@ static char **ssh_get_knownhost_line(FILE **file, const char *filename,
return NULL; return NULL;
} }
if(!tokens[0] || !tokens[1] || !tokens[2]) { if(tokens[0] == NULL || tokens[1] == NULL || tokens[2] == NULL) {
/* it should have at least 3 tokens */ /* it should have at least 3 tokens */
tokens_free(tokens); tokens_free(tokens);
continue; continue;
} }
*found_type = tokens[1]; *found_type = tokens[1];
if (tokens[3] || tokens[4]) {
tokens_free(tokens);
continue;
}
return tokens; return tokens;
} }

View File

@@ -182,11 +182,16 @@ static int known_hosts_read_line(FILE *fp,
return -1; return -1;
} }
/* This method reads the known_hosts file referenced by the path
* in filename argument, and entries matching the match argument
* will be added to the list in entries argument.
* If the entries list is NULL, it will allocate a new list. Caller
* is responsible to free it even if an error occurs.
*/
static int ssh_known_hosts_read_entries(const char *match, static int ssh_known_hosts_read_entries(const char *match,
const char *filename, const char *filename,
struct ssh_list **entries) struct ssh_list **entries)
{ {
struct ssh_list *entry_list;
char line[8192]; char line[8192];
size_t lineno = 0; size_t lineno = 0;
size_t len = 0; size_t len = 0;
@@ -195,13 +200,18 @@ static int ssh_known_hosts_read_entries(const char *match,
fp = fopen(filename, "r"); fp = fopen(filename, "r");
if (fp == NULL) { if (fp == NULL) {
return SSH_ERROR; SSH_LOG(SSH_LOG_WARN, "Failed to open the known_hosts file '%s': %s",
filename, strerror(errno));
/* The missing file is not an error here */
return SSH_OK;
} }
entry_list = ssh_list_new(); if (*entries == NULL) {
if (entry_list == NULL) { *entries = ssh_list_new();
fclose(fp); if (*entries == NULL) {
return SSH_ERROR; fclose(fp);
return SSH_ERROR;
}
} }
for (rc = known_hosts_read_line(fp, line, sizeof(line), &len, &lineno); for (rc = known_hosts_read_line(fp, line, sizeof(line), &len, &lineno);
@@ -231,15 +241,12 @@ static int ssh_known_hosts_read_entries(const char *match,
} else if (rc != SSH_OK) { } else if (rc != SSH_OK) {
goto error; goto error;
} }
ssh_list_append(entry_list, entry); ssh_list_append(*entries, entry);
} }
*entries = entry_list;
fclose(fp); fclose(fp);
return SSH_OK; return SSH_OK;
error: error:
ssh_list_free(entry_list);
fclose(fp); fclose(fp);
return SSH_ERROR; return SSH_ERROR;
} }
@@ -323,8 +330,23 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
rc = ssh_known_hosts_read_entries(host_port, rc = ssh_known_hosts_read_entries(host_port,
session->opts.knownhosts, session->opts.knownhosts,
&entry_list); &entry_list);
if (rc != 0) {
ssh_list_free(entry_list);
ssh_list_free(list);
return NULL;
}
rc = ssh_known_hosts_read_entries(host_port,
session->opts.global_knownhosts,
&entry_list);
SAFE_FREE(host_port); SAFE_FREE(host_port);
if (rc != 0) { if (rc != 0) {
ssh_list_free(entry_list);
ssh_list_free(list);
return NULL;
}
if (entry_list == NULL) {
ssh_list_free(list); ssh_list_free(list);
return NULL; return NULL;
} }
@@ -340,12 +362,10 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
it != NULL; it != NULL;
it = ssh_list_get_iterator(entry_list)) { it = ssh_list_get_iterator(entry_list)) {
struct ssh_knownhosts_entry *entry = NULL; struct ssh_knownhosts_entry *entry = NULL;
enum ssh_keytypes_e key_type;
const char *algo = NULL; const char *algo = NULL;
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it); entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
key_type = ssh_key_type(entry->publickey); algo = entry->publickey->type_c;
algo = ssh_key_type_to_char(key_type);
rc = ssh_list_append(list, algo); rc = ssh_list_append(list, algo);
if (rc != SSH_OK) { if (rc != SSH_OK) {
@@ -556,8 +576,17 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
rc = ssh_known_hosts_read_entries(host_port, rc = ssh_known_hosts_read_entries(host_port,
session->opts.knownhosts, session->opts.knownhosts,
&entry_list); &entry_list);
if (rc != 0) {
ssh_list_free(entry_list);
return SSH_KNOWN_HOSTS_UNKNOWN;
}
rc = ssh_known_hosts_read_entries(host_port,
session->opts.global_knownhosts,
&entry_list);
SAFE_FREE(host_port); SAFE_FREE(host_port);
if (rc != 0) { if (rc != 0) {
ssh_list_free(entry_list);
return SSH_KNOWN_HOSTS_UNKNOWN; return SSH_KNOWN_HOSTS_UNKNOWN;
} }
@@ -621,7 +650,7 @@ int ssh_session_export_known_hosts_entry(ssh_session session,
if (session->current_crypto == NULL) { if (session->current_crypto == NULL) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"No current crypto context, please connnect first"); "No current crypto context, please connect first");
SAFE_FREE(host); SAFE_FREE(host);
return SSH_ERROR; return SSH_ERROR;
} }
@@ -657,10 +686,11 @@ int ssh_session_export_known_hosts_entry(ssh_session session,
} }
/** /**
* @brief Add the current connected server to the known_hosts file. * @brief Add the current connected server to the user known_hosts file.
* *
* This adds the currently connected server to the known_hosts file by * This adds the currently connected server to the known_hosts file by
* appending a new line at the end. * appending a new line at the end. The global known_hosts file is considered
* read-only so it is not touched by this function.
* *
* @param[in] session The session to use to write the entry. * @param[in] session The session to use to write the entry.
* *
@@ -747,6 +777,7 @@ ssh_known_hosts_check_server_key(const char *hosts_entry,
filename, filename,
&entry_list); &entry_list);
if (rc != 0) { if (rc != 0) {
ssh_list_free(entry_list);
return SSH_KNOWN_HOSTS_UNKNOWN; return SSH_KNOWN_HOSTS_UNKNOWN;
} }
@@ -824,9 +855,7 @@ enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry(ssh_session session, ssh_session_get_known_hosts_entry(ssh_session session,
struct ssh_knownhosts_entry **pentry) struct ssh_knownhosts_entry **pentry)
{ {
ssh_key server_pubkey = NULL; enum ssh_known_hosts_e old_rv, rv = SSH_KNOWN_HOSTS_UNKNOWN;
char *host_port = NULL;
enum ssh_known_hosts_e found = SSH_KNOWN_HOSTS_UNKNOWN;
if (session->opts.knownhosts == NULL) { if (session->opts.knownhosts == NULL) {
if (ssh_options_apply(session) < 0) { if (ssh_options_apply(session) < 0) {
@@ -838,6 +867,65 @@ ssh_session_get_known_hosts_entry(ssh_session session,
} }
} }
rv = ssh_session_get_known_hosts_entry_file(session,
session->opts.knownhosts,
pentry);
if (rv == SSH_KNOWN_HOSTS_OK) {
/* We already found a match in the first file: return */
return rv;
}
old_rv = rv;
rv = ssh_session_get_known_hosts_entry_file(session,
session->opts.global_knownhosts,
pentry);
/* If we did not find any match at all: we report the previous result */
if (rv == SSH_KNOWN_HOSTS_UNKNOWN) {
return old_rv;
}
/* We found some match: return it */
return rv;
}
/**
* @brief Get the known_hosts entry for the current connected session
* from the given known_hosts file.
*
* @param[in] session The session to validate.
*
* @param[in] filename The filename to parse.
*
* @param[in] pentry A pointer to store the allocated known hosts entry.
*
* @returns SSH_KNOWN_HOSTS_OK: The server is known and has not changed.\n
* SSH_KNOWN_HOSTS_CHANGED: The server key has changed. Either you
* are under attack or the administrator
* changed the key. You HAVE to warn the
* user about a possible attack.\n
* SSH_KNOWN_HOSTS_OTHER: The server gave use a key of a type while
* we had an other type recorded. It is a
* possible attack.\n
* SSH_KNOWN_HOSTS_UNKNOWN: The server is unknown. User should
* confirm the public key hash is correct.\n
* SSH_KNOWN_HOSTS_NOT_FOUND: The known host file does not exist. The
* host is thus unknown. File will be
* created if host key is accepted.\n
* SSH_KNOWN_HOSTS_ERROR: There had been an eror checking the host.
*
* @see ssh_knownhosts_entry_free()
*/
enum ssh_known_hosts_e
ssh_session_get_known_hosts_entry_file(ssh_session session,
const char *filename,
struct ssh_knownhosts_entry **pentry)
{
ssh_key server_pubkey = NULL;
char *host_port = NULL;
enum ssh_known_hosts_e found = SSH_KNOWN_HOSTS_UNKNOWN;
server_pubkey = ssh_dh_get_current_server_publickey(session); server_pubkey = ssh_dh_get_current_server_publickey(session);
if (server_pubkey == NULL) { if (server_pubkey == NULL) {
ssh_set_error(session, ssh_set_error(session,
@@ -854,7 +942,7 @@ ssh_session_get_known_hosts_entry(ssh_session session,
} }
found = ssh_known_hosts_check_server_key(host_port, found = ssh_known_hosts_check_server_key(host_port,
session->opts.knownhosts, filename,
server_pubkey, server_pubkey,
pentry); pentry);
SAFE_FREE(host_port); SAFE_FREE(host_port);

View File

@@ -196,6 +196,7 @@ void evp_update(EVPCTX ctx, const void *data, unsigned long len)
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
{ {
EVP_DigestFinal(ctx, md, mdlen); EVP_DigestFinal(ctx, md, mdlen);
EVP_MD_CTX_free(ctx);
} }
#endif #endif

View File

@@ -430,6 +430,13 @@ void ssh_message_queue(ssh_session session, ssh_message message){
} }
if (session->ssh_message_list != NULL) { if (session->ssh_message_list != NULL) {
ssh_list_append(session->ssh_message_list, message); ssh_list_append(session->ssh_message_list, message);
} else {
/* If the message list couldn't be allocated, the message can't be
* enqueued */
ssh_message_reply_default(message);
ssh_set_error_oom(session);
ssh_message_free(message);
return;
} }
} }
} }
@@ -697,6 +704,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
ssh_message msg = NULL; ssh_message msg = NULL;
char *service = NULL; char *service = NULL;
char *method = NULL; char *method = NULL;
int cmp;
int rc; int rc;
(void)user; (void)user;
@@ -723,6 +731,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
service, method, service, method,
msg->auth_request.username); msg->auth_request.username);
cmp = strcmp(service, "ssh-connection");
if (cmp != 0) {
SSH_LOG(SSH_LOG_WARNING,
"Invalid service request: %s",
service);
goto end;
}
if (strcmp(method, "none") == 0) { if (strcmp(method, "none") == 0) {
msg->auth_request.method = SSH_AUTH_METHOD_NONE; msg->auth_request.method = SSH_AUTH_METHOD_NONE;

View File

@@ -1022,6 +1022,12 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
* remote host. When not explicitly set, it will be read * remote host. When not explicitly set, it will be read
* from the ~/.ssh/config file. * from the ~/.ssh/config file.
* *
* - SSH_OPTIONS_GLOBAL_KNOWNHOSTS:
* Get the path to the global known_hosts file being used.
*
* - SSH_OPTIONS_KNOWNHOSTS:
* Get the path to the known_hosts file being used.
*
* @param value The value to get into. As a char**, space will be * @param value The value to get into. As a char**, space will be
* allocated by the function for the value, it is * allocated by the function for the value, it is
* your responsibility to free the memory using * your responsibility to free the memory using
@@ -1064,6 +1070,14 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
src = session->opts.ProxyCommand; src = session->opts.ProxyCommand;
break; break;
} }
case SSH_OPTIONS_KNOWNHOSTS: {
src = session->opts.knownhosts;
break;
}
case SSH_OPTIONS_GLOBAL_KNOWNHOSTS: {
src = session->opts.global_knownhosts;
break;
}
default: default:
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type); ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
return SSH_ERROR; return SSH_ERROR;
@@ -1356,6 +1370,17 @@ int ssh_options_apply(ssh_session session) {
free(session->opts.knownhosts); free(session->opts.knownhosts);
session->opts.knownhosts = tmp; session->opts.knownhosts = tmp;
if (session->opts.global_knownhosts == NULL) {
tmp = strdup("/etc/ssh/ssh_known_hosts");
} else {
tmp = ssh_path_expand_escape(session, session->opts.global_knownhosts);
}
if (tmp == NULL) {
return -1;
}
free(session->opts.global_knownhosts);
session->opts.global_knownhosts = tmp;
if (session->opts.ProxyCommand != NULL) { if (session->opts.ProxyCommand != NULL) {
tmp = ssh_path_expand_escape(session, session->opts.ProxyCommand); tmp = ssh_path_expand_escape(session, session->opts.ProxyCommand);
if (tmp == NULL) { if (tmp == NULL) {

View File

@@ -128,6 +128,798 @@ static ssh_packet_callback default_packet_handlers[]= {
ssh_packet_channel_failure, // SSH2_MSG_CHANNEL_FAILURE 100 ssh_packet_channel_failure, // SSH2_MSG_CHANNEL_FAILURE 100
}; };
/** @internal
* @brief check if the received packet is allowed for the current session state
* @param session current ssh_session
* @returns SSH_PACKET_ALLOWED if the packet is allowed; SSH_PACKET_DENIED
* if the packet arrived in wrong state; SSH_PACKET_UNKNOWN if the packet type
* is unknown
*/
static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session session)
{
enum ssh_packet_filter_result_e rc;
#ifdef DEBUG_PACKET
SSH_LOG(SSH_LOG_PACKET, "Filtering packet type %d",
session->in_packet.type);
#endif
switch(session->in_packet.type) {
case SSH2_MSG_DISCONNECT: // 1
/*
* States required:
* - None
*
* Transitions:
* - session->socket->state = SSH_SOCKET_CLOSED
* - session->session_state = SSH_SESSION_STATE_ERROR
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_IGNORE: // 2
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_UNIMPLEMENTED: // 3
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_DEBUG: // 4
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_SERVICE_REQUEST: // 5
/* Server only */
/*
* States required:
* - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->dh_handshake_state == DH_STATE_FINISHED
*
* Transitions:
* - None
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_SERVICE_ACCEPT: // 6
/*
* States required:
* - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->dh_handshake_state == DH_STATE_FINISHED
* - session->auth.service_state == SSH_AUTH_SERVICE_SENT
*
* Transitions:
* - auth.service_state = SSH_AUTH_SERVICE_ACCEPTED
* */
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
/* TODO check if only auth service can be requested */
if (session->auth.service_state != SSH_AUTH_SERVICE_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_EXT_INFO: // 7
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_handshake_state == DH_STATE_FINISHED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXINIT: // 20
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* or session_state == SSH_SESSION_STATE_INITIAL_KEX
* - dh_handshake_state == DH_STATE_INIT
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT
* - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED
*
* On server:
* - session->session_state = SSH_SESSION_STATE_DH
* */
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATED) &&
(session->session_state != SSH_SESSION_STATE_INITIAL_KEX))
{
rc = SSH_PACKET_DENIED;
break;
}
if ((session->dh_handshake_state != DH_STATE_INIT) &&
(session->dh_handshake_state != DH_STATE_FINISHED))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_NEWKEYS: // 21
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_NEWKEYS_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_FINISHED
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATING
* if session->flags & SSH_SESSION_FLAG_AUTHENTICATED
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* */
/* If DH has not been started, reject message */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in NEWKEYS_SENT state */
if (session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXDH_INIT: // 30
// SSH2_MSG_KEX_ECDH_INIT: // 30
// SSH2_MSG_ECMQV_INIT: // 30
// SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: // 30
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT_SENT
* then calls dh_handshake_server which triggers:
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in initial state */
if (session->dh_handshake_state != DH_STATE_INIT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXDH_REPLY: // 31
// SSH2_MSG_KEX_ECDH_REPLY: // 31
// SSH2_MSG_ECMQV_REPLY: // 31
// SSH2_MSG_KEX_DH_GEX_GROUP: // 31
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT_SENT
*
* Transitions:
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_INIT: // 32
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REPLY: // 33
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_REQUEST: // 50
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
*
* Transitions:
* - if authentication was successful:
* - session_state = SSH_SESSION_STATE_AUTHENTICATED
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_FAILURE: // 51
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* or session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
* or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
*
* Transitions:
* - if unpacking failed:
* - session->auth.state = SSH_AUTH_ERROR
* - if failure was partial:
* - session->auth.state = SSH_AUTH_PARTIAL
* - else:
* - session->auth.state = SSH_AUTH_STATE_FAILED
* */
/* If this is a server, reject the message */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_SUCCESS: // 52
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
* or session->auth.state == SSH_AUTH_STATE_AUTH_NONE_SENT
*
* Transitions:
* - session->auth.state = SSH_AUTH_STATE_SUCCESS
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED
* - sessions->auth.current_method = SSH_AUTH_METHOD_UNKNOWN
* */
/* If this is a server, reject the message */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) &&
(session->auth.state != SSH_AUTH_STATE_PUBKEY_AUTH_SENT) &&
(session->auth.state != SSH_AUTH_STATE_PASSWORD_AUTH_SENT) &&
(session->auth.state != SSH_AUTH_STATE_GSSAPI_MIC_SENT) &&
(session->auth.state != SSH_AUTH_STATE_AUTH_NONE_SENT))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_BANNER: // 53
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_PK_OK: // 60
// SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // 60
// SSH2_MSG_USERAUTH_INFO_REQUEST: // 60
// SSH2_MSG_USERAUTH_GSSAPI_RESPONSE: // 60
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* or
* session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
* or
* session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
*
* Transitions:
* Depending on the current state, the message is treated
* differently:
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* - session->auth.state = SSH_AUTH_STATE_INFO
* - session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
* - session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN
* - session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
* - session->auth.state = SSH_AUTH_STATE_PK_OK
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) &&
(session->auth.state != SSH_AUTH_STATE_PUBKEY_OFFER_SENT) &&
(session->auth.state != SSH_AUTH_STATE_GSSAPI_REQUEST_SENT))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_INFO_RESPONSE: // 61
// SSH2_MSG_USERAUTH_GSSAPI_TOKEN: // 61
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session_state->auth.state == SSH_SESSION_STATE_GSSAPI_TOKEN
* or
* session_state->auth.state == SSH_SESSION_STATE_INFO
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth.state != SSH_AUTH_STATE_INFO) &&
(session->auth.state != SSH_AUTH_STATE_GSSAPI_TOKEN))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE: // 63
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_ERROR: // 64
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_ERRTOK: // 65
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_MIC: // 66
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session->gssapi->state == SSH_GSSAPI_STATE_RCV_MIC
*
* Transitions:
* Depending on the result of the verification, the states are
* changed:
* - SSH_AUTH_SUCCESS:
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* - session->flags != SSH_SESSION_FLAG_AUTHENTICATED
* - SSH_AUTH_PARTIAL:
* - None
* - any other case:
* - None
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_GLOBAL_REQUEST: // 80
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_REQUEST_SUCCESS: // 81
/*
* 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
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
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
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
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
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: // 91
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_OPEN
* - channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN_FAILURE: // 92
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_OPEN_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_WINDOW_ADJUST: // 93
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_DATA: // 94
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_EXTENDED_DATA: // 95
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_EOF: // 96
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_CLOSE: // 97
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_CLOSED
* - channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_REQUEST: // 98
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - Depends on the request
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_SUCCESS: // 99
/*
* 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
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_FAILURE: // 100
/*
* 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
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
default:
/* Unknown message, do not filter */
rc = SSH_PACKET_UNKNOWN;
goto end;
}
end:
#ifdef DEBUG_PACKET
if (rc == SSH_PACKET_DENIED) {
SSH_LOG(SSH_LOG_PACKET, "REJECTED packet type %d: ",
session->in_packet.type);
}
if (rc == SSH_PACKET_UNKNOWN) {
SSH_LOG(SSH_LOG_PACKET, "UNKNOWN packet type %d",
session->in_packet.type);
}
#endif
return rc;
}
/* in nonblocking mode, socket_read will read as much as it can, and return */ /* in nonblocking mode, socket_read will read as much as it can, and return */
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */ /* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
/* in blocking mode, it will read at least len bytes and will block until it's ok. */ /* in blocking mode, it will read at least len bytes and will block until it's ok. */
@@ -158,6 +950,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
uint32_t packet_len, compsize, payloadsize; uint32_t packet_len, compsize, payloadsize;
uint8_t padding; uint8_t padding;
size_t processed = 0; /* number of byte processed from the callback */ size_t processed = 0; /* number of byte processed from the callback */
enum ssh_packet_filter_result_e filter_result;
if(session->current_crypto != NULL) { if(session->current_crypto != NULL) {
current_macsize = hmac_digest_len(session->current_crypto->in_hmac); current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
@@ -345,8 +1138,21 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]", "packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
session->in_packet.type, packet_len, padding, compsize, payloadsize); session->in_packet.type, packet_len, padding, compsize, payloadsize);
/* Execute callbacks */ /* Check if the packet is expected */
ssh_packet_process(session, session->in_packet.type); filter_result = ssh_packet_incoming_filter(session);
switch(filter_result) {
case SSH_PACKET_ALLOWED:
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
break;
case SSH_PACKET_DENIED:
goto error;
case SSH_PACKET_UNKNOWN:
ssh_packet_send_unimplemented(session, session->recv_seq - 1);
break;
}
session->packet_state = PACKET_STATE_INIT; session->packet_state = PACKET_STATE_INIT;
if (processed < receivedlen) { if (processed < receivedlen) {
/* Handle a potential packet left in socket buffer */ /* Handle a potential packet left in socket buffer */

View File

@@ -312,7 +312,7 @@ static int ssh_pcap_context_connect(ssh_pcap_context ctx){
return SSH_ERROR; return SSH_ERROR;
if(session->socket==NULL) if(session->socket==NULL)
return SSH_ERROR; return SSH_ERROR;
fd=ssh_socket_get_fd_in(session->socket); fd = ssh_socket_get_fd(session->socket);
/* TODO: adapt for windows */ /* TODO: adapt for windows */
if(fd<0) if(fd<0)
return SSH_ERROR; return SSH_ERROR;

View File

@@ -790,7 +790,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
case SSH_KEYTYPE_UNKNOWN: case SSH_KEYTYPE_UNKNOWN:
default: default:
BIO_free(mem); BIO_free(mem);
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", key->type); SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", key->type);
return NULL; return NULL;
} }
@@ -916,7 +916,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
case SSH_KEYTYPE_RSA_CERT01: case SSH_KEYTYPE_RSA_CERT01:
case SSH_KEYTYPE_UNKNOWN: case SSH_KEYTYPE_UNKNOWN:
BIO_free(mem); BIO_free(mem);
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type); SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
return NULL; return NULL;
} }

View File

@@ -998,7 +998,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_UNKNOWN: case SSH_KEYTYPE_UNKNOWN:
default: default:
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type); SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
return NULL; return NULL;
} }

View File

@@ -533,19 +533,17 @@ int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p) {
* *
* @return 0 on success, < 0 on error * @return 0 on success, < 0 on error
*/ */
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s) { int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s)
ssh_poll_handle p_in, p_out; {
int ret; ssh_poll_handle p;
p_in=ssh_socket_get_poll_handle_in(s); int ret;
if(p_in==NULL)
return -1; p = ssh_socket_get_poll_handle(s);
ret = ssh_poll_ctx_add(ctx,p_in); if (p == NULL) {
if(ret != 0) return -1;
}
ret = ssh_poll_ctx_add(ctx,p);
return ret; return ret;
p_out=ssh_socket_get_poll_handle_out(s);
if(p_in != p_out)
ret = ssh_poll_ctx_add(ctx,p_out);
return ret;
} }

View File

@@ -1039,6 +1039,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
msg->session->kbdint->prompts = NULL; msg->session->kbdint->prompts = NULL;
msg->session->kbdint->echo = NULL; msg->session->kbdint->echo = NULL;
} }
msg->session->auth.state = SSH_AUTH_STATE_INFO;
return rc; return rc;
} }

View File

@@ -536,7 +536,7 @@ socket_t ssh_get_fd(ssh_session session) {
return -1; return -1;
} }
return ssh_socket_get_fd_in(session->socket); return ssh_socket_get_fd(session->socket);
} }
/** /**
@@ -599,7 +599,7 @@ void ssh_set_fd_except(ssh_session session) {
* @return SSH_OK on success, SSH_ERROR otherwise. * @return SSH_OK on success, SSH_ERROR otherwise.
*/ */
int ssh_handle_packets(ssh_session session, int timeout) { int ssh_handle_packets(ssh_session session, int timeout) {
ssh_poll_handle spoll_in,spoll_out; ssh_poll_handle spoll;
ssh_poll_ctx ctx; ssh_poll_ctx ctx;
int tm = timeout; int tm = timeout;
int rc; int rc;
@@ -608,17 +608,13 @@ int ssh_handle_packets(ssh_session session, int timeout) {
return SSH_ERROR; return SSH_ERROR;
} }
spoll_in = ssh_socket_get_poll_handle_in(session->socket); spoll = ssh_socket_get_poll_handle(session->socket);
spoll_out = ssh_socket_get_poll_handle_out(session->socket); ssh_poll_add_events(spoll, POLLIN);
ssh_poll_add_events(spoll_in, POLLIN); ctx = ssh_poll_get_ctx(spoll);
ctx = ssh_poll_get_ctx(spoll_in);
if (!ctx) { if (!ctx) {
ctx = ssh_poll_get_default_ctx(session); ctx = ssh_poll_get_default_ctx(session);
ssh_poll_ctx_add(ctx, spoll_in); ssh_poll_ctx_add(ctx, spoll);
if (spoll_in != spoll_out) {
ssh_poll_ctx_add(ctx, spoll_out);
}
} }
if (timeout == SSH_TIMEOUT_USER) { if (timeout == SSH_TIMEOUT_USER) {

View File

@@ -211,10 +211,31 @@ sftp_session sftp_server_new(ssh_session session, ssh_channel chan){
return NULL; return NULL;
} }
sftp->read_packet = calloc(1, sizeof(struct sftp_packet_struct));
if (sftp->read_packet == NULL) {
goto error;
}
sftp->read_packet->payload = ssh_buffer_new();
if (sftp->read_packet->payload == NULL) {
goto error;
}
sftp->session = session; sftp->session = session;
sftp->channel = chan; sftp->channel = chan;
return sftp; return sftp;
error:
ssh_set_error_oom(session);
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;
} }
int sftp_server_init(sftp_session sftp){ int sftp_server_init(sftp_session sftp){

View File

@@ -232,8 +232,6 @@ sftp_client_message sftp_get_client_message(sftp_session sftp) {
return NULL; return NULL;
} }
sftp_packet_free(packet);
return msg; return msg;
} }

View File

@@ -74,8 +74,7 @@ enum ssh_socket_states_e {
}; };
struct ssh_socket_struct { struct ssh_socket_struct {
socket_t fd_in; socket_t fd;
socket_t fd_out;
int fd_is_socket; int fd_is_socket;
int last_errno; int last_errno;
int read_wontblock; /* reading now on socket will int read_wontblock; /* reading now on socket will
@@ -87,15 +86,17 @@ struct ssh_socket_struct {
ssh_buffer in_buffer; ssh_buffer in_buffer;
ssh_session session; ssh_session session;
ssh_socket_callbacks callbacks; ssh_socket_callbacks callbacks;
ssh_poll_handle poll_in; ssh_poll_handle poll_handle;
ssh_poll_handle poll_out;
}; };
static int sockets_initialized = 0; static int sockets_initialized = 0;
static int ssh_socket_unbuffered_read(ssh_socket s, void *buffer, uint32_t len); static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer, void *buffer,
uint32_t len); uint32_t len);
static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
const void *buffer,
uint32_t len);
/** /**
* \internal * \internal
@@ -146,8 +147,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
return NULL; return NULL;
} }
s->fd_in = SSH_INVALID_SOCKET; s->fd = SSH_INVALID_SOCKET;
s->fd_out= SSH_INVALID_SOCKET;
s->last_errno = -1; s->last_errno = -1;
s->fd_is_socket = 1; s->fd_is_socket = 1;
s->session = session; s->session = session;
@@ -167,7 +167,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
s->read_wontblock = 0; s->read_wontblock = 0;
s->write_wontblock = 0; s->write_wontblock = 0;
s->data_except = 0; s->data_except = 0;
s->poll_in=s->poll_out=NULL; s->poll_handle = NULL;
s->state=SSH_SOCKET_NONE; s->state=SSH_SOCKET_NONE;
return s; return s;
} }
@@ -178,8 +178,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
* @param[in] s socket to rest * @param[in] s socket to rest
*/ */
void ssh_socket_reset(ssh_socket s){ void ssh_socket_reset(ssh_socket s){
s->fd_in = SSH_INVALID_SOCKET; s->fd = SSH_INVALID_SOCKET;
s->fd_out= SSH_INVALID_SOCKET;
s->last_errno = -1; s->last_errno = -1;
s->fd_is_socket = 1; s->fd_is_socket = 1;
ssh_buffer_reinit(s->in_buffer); ssh_buffer_reinit(s->in_buffer);
@@ -187,7 +186,7 @@ void ssh_socket_reset(ssh_socket s){
s->read_wontblock = 0; s->read_wontblock = 0;
s->write_wontblock = 0; s->write_wontblock = 0;
s->data_except = 0; s->data_except = 0;
s->poll_in=s->poll_out=NULL; s->poll_handle = NULL;
s->state=SSH_SOCKET_NONE; s->state=SSH_SOCKET_NONE;
} }
@@ -216,13 +215,18 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks){
* @return 0 on success, < 0 when the poll object has been removed * @return 0 on success, < 0 when the poll object has been removed
* from its poll context. * from its poll context.
*/ */
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
int revents, void *v_s) { socket_t fd,
int revents,
void *v_s)
{
ssh_socket s = (ssh_socket)v_s; ssh_socket s = (ssh_socket)v_s;
char buffer[MAX_BUF_SIZE]; char buffer[MAX_BUF_SIZE];
int r; ssize_t nread;
int rc;
int err = 0; int err = 0;
socklen_t errlen = sizeof(err); socklen_t errlen = sizeof(err);
/* Do not do anything if this socket was already closed */ /* Do not do anything if this socket was already closed */
if (!ssh_socket_is_open(s)) { if (!ssh_socket_is_open(s)) {
return -1; return -1;
@@ -236,16 +240,18 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
/* Check if we are in a connecting state */ /* Check if we are in a connecting state */
if (s->state == SSH_SOCKET_CONNECTING) { if (s->state == SSH_SOCKET_CONNECTING) {
s->state = SSH_SOCKET_ERROR; s->state = SSH_SOCKET_ERROR;
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen); rc = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
if (r < 0) { if (rc < 0) {
err = errno; err = errno;
} }
s->last_errno = err; s->last_errno = err;
ssh_socket_close(s); ssh_socket_close(s);
if (s->callbacks && s->callbacks->connected) { if (s->callbacks != NULL && s->callbacks->connected != NULL) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR, err, s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR,
err,
s->callbacks->userdata); s->callbacks->userdata);
} }
return -1; return -1;
} }
/* Then we are in a more standard kind of error */ /* Then we are in a more standard kind of error */
@@ -254,56 +260,62 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
} }
if ((revents & POLLIN) && s->state == SSH_SOCKET_CONNECTED) { if ((revents & POLLIN) && s->state == SSH_SOCKET_CONNECTED) {
s->read_wontblock = 1; s->read_wontblock = 1;
r = ssh_socket_unbuffered_read(s, buffer, sizeof(buffer)); nread = ssh_socket_unbuffered_read(s, buffer, sizeof(buffer));
if (r < 0) { if (nread < 0) {
if (p != NULL) { if (p != NULL) {
ssh_poll_remove_events(p, POLLIN); ssh_poll_remove_events(p, POLLIN);
} }
if (s->callbacks && s->callbacks->exception) {
if (s->callbacks != NULL && s->callbacks->exception != NULL) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR, s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno, s->callbacks->userdata); s->last_errno,
s->callbacks->userdata);
/* p may have been freed, so don't use it /* p may have been freed, so don't use it
* anymore in this function */ * anymore in this function */
p = NULL; p = NULL;
return -2; return -2;
} }
} }
if (r == 0) { if (nread == 0) {
if (p != NULL) { if (p != NULL) {
ssh_poll_remove_events(p, POLLIN); ssh_poll_remove_events(p, POLLIN);
} }
if (p != NULL) { if (p != NULL) {
ssh_poll_remove_events(p, POLLIN); ssh_poll_remove_events(p, POLLIN);
} }
if (s->callbacks && s->callbacks->exception) { if (s->callbacks != NULL && s->callbacks->exception != NULL) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF, s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF,
0, s->callbacks->userdata); 0,
s->callbacks->userdata);
/* p may have been freed, so don't use it /* p may have been freed, so don't use it
* anymore in this function */ * anymore in this function */
p = NULL; p = NULL;
return -2; return -2;
} }
} }
if (r > 0) {
if (s->session->socket_counter != NULL) { if (s->session->socket_counter != NULL) {
s->session->socket_counter->in_bytes += r; s->session->socket_counter->in_bytes += nread;
} }
/* Bufferize the data and then call the callback */
r = ssh_buffer_add_data(s->in_buffer, buffer, r); /* Bufferize the data and then call the callback */
if (r < 0) { rc = ssh_buffer_add_data(s->in_buffer, buffer, nread);
return -1; if (rc < 0) {
} return -1;
if (s->callbacks && s->callbacks->data) { }
do { if (s->callbacks != NULL && s->callbacks->data != NULL) {
r = s->callbacks->data(ssh_buffer_get(s->in_buffer), do {
ssh_buffer_get_len(s->in_buffer), nread = s->callbacks->data(ssh_buffer_get(s->in_buffer),
s->callbacks->userdata); ssh_buffer_get_len(s->in_buffer),
ssh_buffer_pass_bytes(s->in_buffer, r); s->callbacks->userdata);
} while ((r > 0) && (s->state == SSH_SOCKET_CONNECTED)); ssh_buffer_pass_bytes(s->in_buffer, nread);
/* p may have been freed, so don't use it } while ((nread > 0) && (s->state == SSH_SOCKET_CONNECTED));
* anymore in this function */
p = NULL; /* p may have been freed, so don't use it
} * anymore in this function */
p = NULL;
} }
} }
#ifdef _WIN32 #ifdef _WIN32
@@ -311,6 +323,8 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
#else #else
if (revents & POLLOUT) { if (revents & POLLOUT) {
#endif #endif
uint32_t len;
/* First, POLLOUT is a sign we may be connected */ /* First, POLLOUT is a sign we may be connected */
if (s->state == SSH_SOCKET_CONNECTING) { if (s->state == SSH_SOCKET_CONNECTING) {
SSH_LOG(SSH_LOG_PACKET, "Received POLLOUT in connecting state"); SSH_LOG(SSH_LOG_PACKET, "Received POLLOUT in connecting state");
@@ -318,26 +332,32 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
if (p != NULL) { if (p != NULL) {
ssh_poll_set_events(p, POLLOUT | POLLIN); ssh_poll_set_events(p, POLLOUT | POLLIN);
} }
r = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
if (r < 0) { rc = ssh_socket_set_blocking(ssh_socket_get_fd(s));
if (rc < 0) {
return -1; return -1;
} }
if (s->callbacks && s->callbacks->connected) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK, 0, if (s->callbacks != NULL && s->callbacks->connected != NULL) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,
0,
s->callbacks->userdata); s->callbacks->userdata);
} }
return 0; return 0;
} }
/* So, we can write data */ /* So, we can write data */
s->write_wontblock=1; s->write_wontblock = 1;
if (p != NULL) { if (p != NULL) {
ssh_poll_remove_events(p, POLLOUT); ssh_poll_remove_events(p, POLLOUT);
} }
/* If buffered data is pending, write it */ /* If buffered data is pending, write it */
if (ssh_buffer_get_len(s->out_buffer) > 0) { len = ssh_buffer_get_len(s->out_buffer);
if (len > 0) {
ssh_socket_nonblocking_flush(s); ssh_socket_nonblocking_flush(s);
} else if (s->callbacks && s->callbacks->controlflow) { } else if (s->callbacks != NULL && s->callbacks->controlflow != NULL) {
/* Otherwise advertise the upper level that write can be done */ /* Otherwise advertise the upper level that write can be done */
SSH_LOG(SSH_LOG_TRACE,"sending control flow event"); SSH_LOG(SSH_LOG_TRACE,"sending control flow event");
s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK, s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK,
@@ -345,36 +365,27 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
} }
/* TODO: Find a way to put back POLLOUT when buffering occurs */ /* TODO: Find a way to put back POLLOUT when buffering occurs */
} }
/* Return -1 if one of the poll handlers disappeared */
return (s->poll_in == NULL || s->poll_out == NULL) ? -1 : 0; /* Return -1 if the poll handler disappeared */
if (s->poll_handle == NULL) {
return -1;
}
return 0;
} }
/** @internal /** @internal
* @brief returns the input poll handle corresponding to the socket, * @brief returns the poll handle corresponding to the socket,
* creates it if it does not exist. * creates it if it does not exist.
* @returns allocated and initialized ssh_poll_handle object * @returns allocated and initialized ssh_poll_handle object
*/ */
ssh_poll_handle ssh_socket_get_poll_handle_in(ssh_socket s){ ssh_poll_handle ssh_socket_get_poll_handle(ssh_socket s)
if(s->poll_in) {
return s->poll_in; if (s->poll_handle) {
s->poll_in=ssh_poll_new(s->fd_in,0,ssh_socket_pollcallback,s); return s->poll_handle;
if(s->fd_in == s->fd_out && s->poll_out == NULL) }
s->poll_out=s->poll_in; s->poll_handle = ssh_poll_new(s->fd,0,ssh_socket_pollcallback,s);
return s->poll_in; return s->poll_handle;
}
/** @internal
* @brief returns the output poll handle corresponding to the socket,
* creates it if it does not exist.
* @returns allocated and initialized ssh_poll_handle object
*/
ssh_poll_handle ssh_socket_get_poll_handle_out(ssh_socket s){
if(s->poll_out)
return s->poll_out;
s->poll_out=ssh_poll_new(s->fd_out,0,ssh_socket_pollcallback,s);
if(s->fd_in == s->fd_out && s->poll_in == NULL)
s->poll_in=s->poll_out;
return s->poll_out;
} }
/** \internal /** \internal
@@ -431,27 +442,17 @@ int ssh_socket_unix(ssh_socket s, const char *path) {
void ssh_socket_close(ssh_socket s){ void ssh_socket_close(ssh_socket s){
if (ssh_socket_is_open(s)) { if (ssh_socket_is_open(s)) {
#ifdef _WIN32 #ifdef _WIN32
CLOSE_SOCKET(s->fd_in); CLOSE_SOCKET(s->fd);
/* fd_in = fd_out under win32 */
s->last_errno = WSAGetLastError(); s->last_errno = WSAGetLastError();
#else #else
if (s->fd_out != s->fd_in && s->fd_out != -1) { CLOSE_SOCKET(s->fd);
CLOSE_SOCKET(s->fd_out);
}
CLOSE_SOCKET(s->fd_in);
s->last_errno = errno; s->last_errno = errno;
#endif #endif
} }
if(s->poll_in != NULL){ if(s->poll_handle != NULL){
if(s->poll_out == s->poll_in) ssh_poll_free(s->poll_handle);
s->poll_out = NULL; s->poll_handle=NULL;
ssh_poll_free(s->poll_in);
s->poll_in=NULL;
}
if(s->poll_out != NULL){
ssh_poll_free(s->poll_out);
s->poll_out=NULL;
} }
s->state = SSH_SOCKET_CLOSED; s->state = SSH_SOCKET_CLOSED;
@@ -466,128 +467,116 @@ void ssh_socket_close(ssh_socket s){
* file descriptors * file descriptors
*/ */
void ssh_socket_set_fd(ssh_socket s, socket_t fd) { void ssh_socket_set_fd(ssh_socket s, socket_t fd) {
s->fd_in = s->fd_out = fd; s->fd = fd;
if (s->poll_in) { if (s->poll_handle) {
ssh_poll_set_fd(s->poll_in,fd); ssh_poll_set_fd(s->poll_handle,fd);
} else { } else {
s->state = SSH_SOCKET_CONNECTING; s->state = SSH_SOCKET_CONNECTING;
/* POLLOUT is the event to wait for in a nonblocking connect */ /* POLLOUT is the event to wait for in a nonblocking connect */
ssh_poll_set_events(ssh_socket_get_poll_handle_in(s), POLLOUT); ssh_poll_set_events(ssh_socket_get_poll_handle(s), POLLOUT);
#ifdef _WIN32 #ifdef _WIN32
ssh_poll_add_events(ssh_socket_get_poll_handle_in(s), POLLWRNORM); ssh_poll_add_events(ssh_socket_get_poll_handle(s), POLLWRNORM);
#endif #endif
} }
} }
/**
* @internal
* @brief sets the input file descriptor of the socket.
* @param[out] s ssh_socket to update
* @param[in] fd file descriptor to set
*/
void ssh_socket_set_fd_in(ssh_socket s, socket_t fd) {
s->fd_in = fd;
if(s->poll_in)
ssh_poll_set_fd(s->poll_in,fd);
}
/**
* @internal
* @brief sets the output file descriptor of the socket.
* @param[out] s ssh_socket to update
* @param[in] fd file descriptor to set
*/
void ssh_socket_set_fd_out(ssh_socket s, socket_t fd) {
s->fd_out = fd;
if(s->poll_out)
ssh_poll_set_fd(s->poll_out,fd);
}
/** \internal /** \internal
* \brief returns the input file descriptor of the socket * \brief returns the input file descriptor of the socket
*/ */
socket_t ssh_socket_get_fd_in(ssh_socket s) { socket_t ssh_socket_get_fd(ssh_socket s)
return s->fd_in; {
return s->fd;
} }
/** \internal /** \internal
* \brief returns nonzero if the socket is open * \brief returns nonzero if the socket is open
*/ */
int ssh_socket_is_open(ssh_socket s) { int ssh_socket_is_open(ssh_socket s) {
return s->fd_in != SSH_INVALID_SOCKET; return s->fd != SSH_INVALID_SOCKET;
} }
/** \internal /** \internal
* \brief read len bytes from socket into buffer * \brief read len bytes from socket into buffer
*/ */
static int ssh_socket_unbuffered_read(ssh_socket s, void *buffer, uint32_t len) { static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
int rc = -1; void *buffer,
uint32_t len)
{
ssize_t rc = -1;
if (s->data_except) { if (s->data_except) {
return -1; return -1;
} }
if(s->fd_is_socket) if (s->fd_is_socket) {
rc = recv(s->fd_in,buffer, len, 0); rc = recv(s->fd,buffer, len, 0);
else } else {
rc = read(s->fd_in,buffer, len); rc = read(s->fd,buffer, len);
}
#ifdef _WIN32 #ifdef _WIN32
s->last_errno = WSAGetLastError(); s->last_errno = WSAGetLastError();
#else #else
s->last_errno = errno; s->last_errno = errno;
#endif #endif
s->read_wontblock = 0; s->read_wontblock = 0;
if (rc < 0) { if (rc < 0) {
s->data_except = 1; s->data_except = 1;
} }
return rc; return rc;
} }
/** \internal /** \internal
* \brief writes len bytes from buffer to socket * \brief writes len bytes from buffer to socket
*/ */
static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer, static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
uint32_t len) { const void *buffer,
int w = -1; uint32_t len)
{
ssize_t w = -1;
int flags = 0;
if (s->data_except) { #ifdef MSG_NOSIGNAL
return -1; flags |= MSG_NOSIGNAL;
}
if (s->fd_is_socket)
w = send(s->fd_out,buffer, len, 0);
else
w = write(s->fd_out, buffer, len);
#ifdef _WIN32
s->last_errno = WSAGetLastError();
#else
s->last_errno = errno;
#endif #endif
s->write_wontblock = 0;
/* Reactive the POLLOUT detector in the poll multiplexer system */
if(s->poll_out){
SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
}
if (w < 0) {
s->data_except = 1;
}
return w; if (s->data_except) {
return -1;
}
if (s->fd_is_socket) {
w = send(s->fd, buffer, len, flags);
} else {
w = write(s->fd, buffer, len);
}
#ifdef _WIN32
s->last_errno = WSAGetLastError();
#else
s->last_errno = errno;
#endif
s->write_wontblock = 0;
/* Reactive the POLLOUT detector in the poll multiplexer system */
if (s->poll_handle) {
SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
ssh_poll_set_events(s->poll_handle,ssh_poll_get_events(s->poll_handle) | POLLOUT);
}
if (w < 0) {
s->data_except = 1;
}
return w;
} }
/** \internal /** \internal
* \brief returns nonzero if the current socket is in the fd_set * \brief returns nonzero if the current socket is in the fd_set
*/ */
int ssh_socket_fd_isset(ssh_socket s, fd_set *set) { int ssh_socket_fd_isset(ssh_socket s, fd_set *set) {
if(s->fd_in == SSH_INVALID_SOCKET) { if(s->fd == SSH_INVALID_SOCKET) {
return 0; return 0;
} }
return FD_ISSET(s->fd_in,set) || FD_ISSET(s->fd_out,set); return FD_ISSET(s->fd,set);
} }
/** \internal /** \internal
@@ -595,22 +584,16 @@ int ssh_socket_fd_isset(ssh_socket s, fd_set *set) {
*/ */
void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd) { void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd) {
if (s->fd_in == SSH_INVALID_SOCKET) { if (s->fd == SSH_INVALID_SOCKET) {
return; return;
} }
FD_SET(s->fd_in,set); FD_SET(s->fd,set);
FD_SET(s->fd_out,set);
if (s->fd_in >= 0 && if (s->fd >= 0 &&
s->fd_in >= *max_fd && s->fd >= *max_fd &&
s->fd_in != SSH_INVALID_SOCKET) { s->fd != SSH_INVALID_SOCKET) {
*max_fd = s->fd_in + 1; *max_fd = s->fd + 1;
}
if (s->fd_out >= 0 &&
s->fd_out >= *max_fd &&
s->fd_out != SSH_INVALID_SOCKET) {
*max_fd = s->fd_out + 1;
} }
} }
@@ -636,67 +619,78 @@ int ssh_socket_write(ssh_socket s, const void *buffer, int len) {
* \brief starts a nonblocking flush of the output buffer * \brief starts a nonblocking flush of the output buffer
* *
*/ */
int ssh_socket_nonblocking_flush(ssh_socket s) { int ssh_socket_nonblocking_flush(ssh_socket s)
ssh_session session = s->session; {
uint32_t len; ssh_session session = s->session;
int w; uint32_t len;
if (!ssh_socket_is_open(s)) { if (!ssh_socket_is_open(s)) {
session->alive = 0; session->alive = 0;
if(s->callbacks && s->callbacks->exception){ if (s->callbacks && s->callbacks->exception) {
s->callbacks->exception( s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
SSH_SOCKET_EXCEPTION_ERROR, s->last_errno,
s->last_errno,s->callbacks->userdata); s->callbacks->userdata);
}else{ } else {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session,
"Writing packet: error on socket (or connection closed): %s", SSH_FATAL,
strerror(s->last_errno)); "Writing packet: error on socket (or connection "
"closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR;
} }
return SSH_ERROR; len = ssh_buffer_get_len(s->out_buffer);
} if (!s->write_wontblock && s->poll_handle && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_handle, POLLOUT);
len = ssh_buffer_get_len(s->out_buffer); return SSH_AGAIN;
if (!s->write_wontblock && s->poll_out && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
return SSH_AGAIN;
}
if (s->write_wontblock && len > 0) {
w = ssh_socket_unbuffered_write(s, ssh_buffer_get(s->out_buffer), len);
if (w < 0) {
session->alive = 0;
ssh_socket_close(s);
if(s->callbacks && s->callbacks->exception){
s->callbacks->exception(
SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,s->callbacks->userdata);
}else{
ssh_set_error(session, SSH_FATAL,
"Writing packet: error on socket (or connection closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR;
} }
ssh_buffer_pass_bytes(s->out_buffer, w);
if (s->session->socket_counter != NULL) { if (s->write_wontblock && len > 0) {
s->session->socket_counter->out_bytes += w; ssize_t bwritten;
bwritten = ssh_socket_unbuffered_write(s,
ssh_buffer_get(s->out_buffer),
len);
if (bwritten < 0) {
session->alive = 0;
ssh_socket_close(s);
if (s->callbacks && s->callbacks->exception) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,
s->callbacks->userdata);
} else {
ssh_set_error(session,
SSH_FATAL,
"Writing packet: error on socket (or connection "
"closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR;
}
ssh_buffer_pass_bytes(s->out_buffer, bwritten);
if (s->session->socket_counter != NULL) {
s->session->socket_counter->out_bytes += bwritten;
}
} }
}
/* Is there some data pending? */ /* Is there some data pending? */
len = ssh_buffer_get_len(s->out_buffer); len = ssh_buffer_get_len(s->out_buffer);
if (s->poll_out && len > 0) { if (s->poll_handle && len > 0) {
/* force the poll system to catch pollout events */ /* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT); ssh_poll_add_events(s->poll_handle, POLLOUT);
return SSH_AGAIN; return SSH_AGAIN;
} }
/* all data written */ /* all data written */
return SSH_OK; return SSH_OK;
} }
void ssh_socket_set_write_wontblock(ssh_socket s) { void ssh_socket_set_write_wontblock(ssh_socket s) {
@@ -751,10 +745,10 @@ int ssh_socket_get_status(ssh_socket s) {
int ssh_socket_get_poll_flags(ssh_socket s) { int ssh_socket_get_poll_flags(ssh_socket s) {
int r = 0; int r = 0;
if (s->poll_in != NULL && (ssh_poll_get_events (s->poll_in) & POLLIN) > 0) { if (s->poll_handle != NULL && (ssh_poll_get_events (s->poll_handle) & POLLIN) > 0) {
r |= SSH_READ_PENDING; r |= SSH_READ_PENDING;
} }
if (s->poll_out != NULL && (ssh_poll_get_events (s->poll_out) & POLLOUT) > 0) { if (s->poll_handle != NULL && (ssh_poll_get_events (s->poll_handle) & POLLOUT) > 0) {
r |= SSH_WRITE_PENDING; r |= SSH_WRITE_PENDING;
} }
return r; return r;
@@ -844,19 +838,15 @@ void ssh_execute_command(const char *command, socket_t in, socket_t out){
*/ */
int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){ int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){
socket_t in_pipe[2]; socket_t pair[2];
socket_t out_pipe[2];
int pid; int pid;
int rc; int rc;
if(s->state != SSH_SOCKET_NONE) if (s->state != SSH_SOCKET_NONE) {
return SSH_ERROR; return SSH_ERROR;
rc = pipe(in_pipe);
if (rc < 0) {
return SSH_ERROR;
} }
rc = pipe(out_pipe);
rc = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
if (rc < 0) { if (rc < 0) {
return SSH_ERROR; return SSH_ERROR;
} }
@@ -864,20 +854,18 @@ int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){
SSH_LOG(SSH_LOG_PROTOCOL,"Executing proxycommand '%s'",command); SSH_LOG(SSH_LOG_PROTOCOL,"Executing proxycommand '%s'",command);
pid = fork(); pid = fork();
if(pid == 0){ if(pid == 0){
ssh_execute_command(command,out_pipe[0],in_pipe[1]); ssh_execute_command(command,pair[0],pair[0]);
} }
close(in_pipe[1]); close(pair[0]);
close(out_pipe[0]); SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]);
SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",in_pipe[0],out_pipe[1]); ssh_socket_set_fd(s, pair[1]);
ssh_socket_set_fd_in(s,in_pipe[0]);
ssh_socket_set_fd_out(s,out_pipe[1]);
s->state=SSH_SOCKET_CONNECTED; s->state=SSH_SOCKET_CONNECTED;
s->fd_is_socket=0; s->fd_is_socket=0;
/* POLLOUT is the event to wait for in a nonblocking connect */ /* POLLOUT is the event to wait for in a nonblocking connect */
ssh_poll_set_events(ssh_socket_get_poll_handle_in(s),POLLIN); ssh_poll_set_events(ssh_socket_get_poll_handle(s), POLLIN | POLLOUT);
ssh_poll_set_events(ssh_socket_get_poll_handle_out(s),POLLOUT); if(s->callbacks && s->callbacks->connected) {
if(s->callbacks && s->callbacks->connected)
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata); s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata);
}
return SSH_OK; return SSH_OK;
} }

View File

@@ -121,6 +121,8 @@ if (CLIENT_TESTING)
file(COPY keys/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) file(COPY keys/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/id_ecdsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) file(COPY keys/id_ecdsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/id_ecdsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) file(COPY keys/id_ecdsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/id_ed25519 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/id_ed25519.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
# Allow to auth with bob his public keys on alice account # Allow to auth with bob his public keys on alice account
configure_file(keys/id_rsa.pub ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys @ONLY) configure_file(keys/id_rsa.pub ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys @ONLY)
@@ -128,6 +130,10 @@ if (CLIENT_TESTING)
file(READ keys/id_ecdsa.pub CONTENTS) file(READ keys/id_ecdsa.pub CONTENTS)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys "${CONTENTS}") file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys "${CONTENTS}")
# append ed25519 public key
file(READ keys/id_ed25519.pub CONTENTS)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys "${CONTENTS}")
# Copy the signed key to an alternative directory in bob's homedir. # Copy the signed key to an alternative directory in bob's homedir.
file(COPY keys/certauth/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) file(COPY keys/certauth/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/certauth/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) file(COPY keys/certauth/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)

View File

@@ -534,8 +534,8 @@ static void torture_auth_cert(void **state) {
rc = ssh_userauth_publickey(session, NULL, privkey); rc = ssh_userauth_publickey(session, NULL, privkey);
assert_int_equal(rc, SSH_AUTH_SUCCESS); assert_int_equal(rc, SSH_AUTH_SUCCESS);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(cert); SSH_KEY_FREE(cert);
} }
static void torture_auth_agent_cert(void **state) { static void torture_auth_agent_cert(void **state) {
@@ -559,7 +559,7 @@ static void torture_auth_pubkey_types(void **state)
rc = ssh_connect(session); rc = ssh_connect(session);
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
rc = ssh_userauth_none(session,NULL); rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */ /* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
@@ -596,7 +596,7 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
rc = ssh_connect(session); rc = ssh_connect(session);
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
rc = ssh_userauth_none(session,NULL); rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */ /* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
@@ -622,6 +622,44 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
} }
static void torture_auth_pubkey_types_ed25519(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_ssh_return_code(session, rc);
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
/* Enable only DSA keys -- authentication should fail */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-dss");
assert_ssh_return_code(session, rc);
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
assert_int_equal(rc, SSH_AUTH_DENIED);
/* Verify we can use also ed25519 keys */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-ed25519");
assert_ssh_return_code(session, rc);
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
static void torture_auth_pubkey_types_nonblocking(void **state) static void torture_auth_pubkey_types_nonblocking(void **state)
{ {
struct torture_state *s = *state; struct torture_state *s = *state;
@@ -634,7 +672,7 @@ static void torture_auth_pubkey_types_nonblocking(void **state)
rc = ssh_connect(session); rc = ssh_connect(session);
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
ssh_set_blocking(session,0); ssh_set_blocking(session, 0);
do { do {
rc = ssh_userauth_none(session, NULL); rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN); } while (rc == SSH_AUTH_AGAIN);
@@ -681,7 +719,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
rc = ssh_connect(session); rc = ssh_connect(session);
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
ssh_set_blocking(session,0); ssh_set_blocking(session, 0);
do { do {
rc = ssh_userauth_none(session, NULL); rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN); } while (rc == SSH_AUTH_AGAIN);
@@ -704,7 +742,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
} while (rc == SSH_AUTH_AGAIN); } while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_DENIED); assert_int_equal(rc, SSH_AUTH_DENIED);
/* Verify we can use also ECDSA keys with their various names */ /* Verify we can use also ECDSA key to authenticate */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ecdsa-sha2-nistp256"); "ecdsa-sha2-nistp256");
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
@@ -716,6 +754,52 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
} }
static void torture_auth_pubkey_types_ed25519_nonblocking(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_ssh_return_code(session, rc);
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
ssh_set_blocking(session, 0);
do {
rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
/* Enable only DSA keys -- authentication should fail */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-dss");
assert_ssh_return_code(session, rc);
do {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_DENIED);
/* Verify we can use also ED25519 key to authenticate */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-ed25519");
assert_ssh_return_code(session, rc);
do {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
@@ -771,6 +855,12 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ecdsa_nonblocking, cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ecdsa_nonblocking,
pubkey_setup, pubkey_setup,
session_teardown), session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519,
pubkey_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519_nonblocking,
pubkey_setup,
session_teardown),
}; };
ssh_init(); ssh_init();

View File

@@ -167,6 +167,10 @@ static void torture_knownhosts_precheck(void **state)
"127.0.0.10 %s\n", "127.0.0.10 %s\n",
torture_get_testkey_pub(SSH_KEYTYPE_ED25519, 0)); torture_get_testkey_pub(SSH_KEYTYPE_ED25519, 0));
fprintf(file,
"127.0.0.10 %s\n",
torture_get_testkey_pub(SSH_KEYTYPE_ECDSA, 521));
fclose(file); fclose(file);
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
@@ -176,7 +180,7 @@ static void torture_knownhosts_precheck(void **state)
assert_non_null(algo_list); assert_non_null(algo_list);
algo_count = ssh_list_count(algo_list); algo_count = ssh_list_count(algo_list);
assert_int_equal(algo_count, 2); assert_int_equal(algo_count, 3);
it = ssh_list_get_iterator(algo_list); it = ssh_list_get_iterator(algo_list);
assert_non_null(it); assert_non_null(it);
@@ -190,6 +194,13 @@ static void torture_knownhosts_precheck(void **state)
algo = ssh_iterator_value(const char *, it); algo = ssh_iterator_value(const char *, it);
assert_string_equal(algo, "ssh-ed25519"); assert_string_equal(algo, "ssh-ed25519");
ssh_list_remove(algo_list, it);
it = ssh_list_get_iterator(algo_list);
assert_non_null(it);
algo = ssh_iterator_value(const char *, it);
assert_string_equal(algo, "ecdsa-sha2-nistp521");
ssh_list_free(algo_list); ssh_list_free(algo_list);
} }

View File

@@ -39,7 +39,7 @@ set(CTEST_SOURCE_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/source")
set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build") set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build")
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp) set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp)
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS " --trace-children-skip=sshd") set(CTEST_MEMORYCHECK_COMMAND_OPTIONS " --trace-children-skip=${SSHD_EXECUTABLE}")
find_program(CTEST_GIT_COMMAND NAMES git) find_program(CTEST_GIT_COMMAND NAMES git)
find_program(CTEST_COVERAGE_COMMAND NAMES gcov) find_program(CTEST_COVERAGE_COMMAND NAMES gcov)

8
tests/keys/id_ed25519 Normal file
View File

@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCLo6vx1lX6ZZoe05lWTkuwrJUZN0T8hEer5UF9KPhOVgAAAKg+IRNSPiET
UgAAAAtzc2gtZWQyNTUxOQAAACCLo6vx1lX6ZZoe05lWTkuwrJUZN0T8hEer5UF9KPhOVg
AAAED2zFg52qYItoZaSUnir4VKubTxJveL9D2oWK7Prg/O24ujq/HWVfplmh7TmVZOS7Cs
lRk3RPyER6vlQX0o+E5WAAAAHmpqZWxlbkB0NDcwcy5qamVsZW4ucmVkaGF0LmNvbQECAw
QFBgc=
-----END OPENSSH PRIVATE KEY-----

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIujq/HWVfplmh7TmVZOS7CslRk3RPyER6vlQX0o+E5W jjelen@t470s.jjelen.redhat.com

View File

@@ -35,6 +35,9 @@ target_compile_options(torture_knownhosts_parsing PRIVATE ${DEFAULT_C_COMPILE_FL
add_cmocka_test(torture_hashes torture_hashes.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(torture_hashes torture_hashes.c ${TEST_TARGET_LIBRARIES})
target_compile_options(torture_hashes PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_compile_options(torture_hashes PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
add_cmocka_test(torture_packet_filter torture_packet_filter.c ${TORTURE_LIBRARY})
target_compile_options(torture_packet_filter PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
if (CMAKE_USE_PTHREADS_INIT) if (CMAKE_USE_PTHREADS_INIT)
add_cmocka_test(torture_rand torture_rand.c ${TEST_TARGET_LIBRARIES}) add_cmocka_test(torture_rand torture_rand.c ${TEST_TARGET_LIBRARIES})
target_compile_options(torture_rand PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_compile_options(torture_rand PRIVATE ${DEFAULT_C_COMPILE_FLAGS})

View File

@@ -22,7 +22,7 @@ static int setup(void **state) {
} }
static int teardown(void **state) { static int teardown(void **state) {
ssh_buffer_free(*state); SSH_BUFFER_FREE(*state);
return 0; return 0;
} }
@@ -125,9 +125,9 @@ static void torture_ssh_buffer_get_ssh_string(void **state) {
for(l=0;l<k;++l){ for(l=0;l<k;++l){
ssh_string str = ssh_buffer_get_ssh_string(buffer); ssh_string str = ssh_buffer_get_ssh_string(buffer);
assert_null(str); assert_null(str);
ssh_string_free(str); SSH_STRING_FREE(str);
} }
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
} }
} }
} }
@@ -161,7 +161,7 @@ static void torture_ssh_buffer_add_format(void **state) {
assert_int_equal(len, sizeof(verif) - 1); assert_int_equal(len, sizeof(verif) - 1);
assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1); assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);
ssh_string_free(s); SSH_STRING_FREE(s);
} }
static void torture_ssh_buffer_get_format(void **state) { static void torture_ssh_buffer_get_format(void **state) {

View File

@@ -170,21 +170,21 @@ static void torture_config_from_file(void **state) {
assert_non_null(v); assert_non_null(v);
assert_string_equal(v, PROXYCMD); assert_string_equal(v, PROXYCMD);
ssh_string_free_char(v); SSH_STRING_FREE_CHAR(v);
ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v); ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v);
assert_true(ret == 0); assert_true(ret == 0);
assert_non_null(v); assert_non_null(v);
assert_string_equal(v, ID_FILE); assert_string_equal(v, ID_FILE);
ssh_string_free_char(v); SSH_STRING_FREE_CHAR(v);
ret = ssh_options_get(session, SSH_OPTIONS_USER, &v); ret = ssh_options_get(session, SSH_OPTIONS_USER, &v);
assert_true(ret == 0); assert_true(ret == 0);
assert_non_null(v); assert_non_null(v);
assert_string_equal(v, USERNAME); assert_string_equal(v, USERNAME);
ssh_string_free_char(v); SSH_STRING_FREE_CHAR(v);
assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS); assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS);
@@ -223,14 +223,14 @@ static void torture_config_glob(void **state) {
assert_non_null(v); assert_non_null(v);
assert_string_equal(v, PROXYCMD); assert_string_equal(v, PROXYCMD);
ssh_string_free_char(v); SSH_STRING_FREE_CHAR(v);
ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v); ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v);
assert_true(ret == 0); assert_true(ret == 0);
assert_non_null(v); assert_non_null(v);
assert_string_equal(v, ID_FILE); assert_string_equal(v, ID_FILE);
ssh_string_free_char(v); SSH_STRING_FREE_CHAR(v);
#endif /* HAVE_GLOB */ #endif /* HAVE_GLOB */
} }

View File

@@ -41,88 +41,91 @@ static int setup_rsa_key(void **state)
static int teardown(void **state) static int teardown(void **state)
{ {
ssh_key_free(*state); SSH_KEY_FREE(*state);
return 0; return 0;
} }
static void torture_md5_hash(void **state) static void torture_md5_hash(void **state)
{ {
ssh_key pubkey = *state; ssh_key pubkey = *state;
unsigned char *hash = NULL; char *hash = NULL;
char *hexa = NULL; char *hexa = NULL;
size_t hlen; size_t hlen;
int rc = 0; int rc = 0;
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen); rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
(unsigned char **)&hash, &hlen);
assert_true(rc == 0); assert_true(rc == 0);
hexa = ssh_get_hexa(hash, hlen); hexa = ssh_get_hexa((unsigned char *)hash, hlen);
ssh_string_free_char((char *)hash); SSH_STRING_FREE_CHAR(hash);
assert_string_equal(hexa, assert_string_equal(hexa,
"50:15:a0:9b:92:bf:33:1c:01:c5:8c:fe:18:fa:ce:78"); "50:15:a0:9b:92:bf:33:1c:01:c5:8c:fe:18:fa:ce:78");
ssh_string_free_char(hexa); SSH_STRING_FREE_CHAR(hexa);
} }
static void torture_sha1_hash(void **state) static void torture_sha1_hash(void **state)
{ {
ssh_key pubkey = *state; ssh_key pubkey = *state;
unsigned char *hash = NULL; char *hash = NULL;
char *sha1 = NULL; char *sha1 = NULL;
int rc = 0; int rc = 0;
size_t hlen; size_t hlen;
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen); rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA1,
(unsigned char **)&hash, &hlen);
assert_true(rc == 0); assert_true(rc == 0);
sha1 = ssh_get_b64_unpadded(hash, hlen); sha1 = ssh_get_b64_unpadded((unsigned char *)hash, hlen);
ssh_string_free_char((char *)hash); SSH_STRING_FREE_CHAR(hash);
assert_string_equal(sha1, "6wP+houujQmxLBiFugTcoeoODCM"); assert_string_equal(sha1, "6wP+houujQmxLBiFugTcoeoODCM");
ssh_string_free_char(sha1); SSH_STRING_FREE_CHAR(sha1);
} }
static void torture_sha256_hash(void **state) static void torture_sha256_hash(void **state)
{ {
ssh_key pubkey = *state; ssh_key pubkey = *state;
unsigned char *hash = NULL; char *hash = NULL;
char *sha256 = NULL; char *sha256 = NULL;
int rc = 0; int rc = 0;
size_t hlen; size_t hlen;
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen); rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256,
(unsigned char **)&hash, &hlen);
assert_true(rc == 0); assert_true(rc == 0);
sha256 = ssh_get_b64_unpadded(hash, hlen); sha256 = ssh_get_b64_unpadded((unsigned char *)hash, hlen);
ssh_string_free_char((char *)hash); SSH_STRING_FREE_CHAR(hash);
assert_string_equal(sha256, "jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII"); assert_string_equal(sha256, "jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII");
ssh_string_free_char(sha256); SSH_STRING_FREE_CHAR(sha256);
} }
static void torture_sha256_fingerprint(void **state) static void torture_sha256_fingerprint(void **state)
{ {
ssh_key pubkey = *state; ssh_key pubkey = *state;
unsigned char *hash = NULL; char *hash = NULL;
char *sha256 = NULL; char *sha256 = NULL;
int rc = 0; int rc = 0;
size_t hlen; size_t hlen;
rc = ssh_get_publickey_hash(pubkey, rc = ssh_get_publickey_hash(pubkey,
SSH_PUBLICKEY_HASH_SHA256, SSH_PUBLICKEY_HASH_SHA256,
&hash, (unsigned char **)&hash,
&hlen); &hlen);
assert_true(rc == 0); assert_true(rc == 0);
sha256 = ssh_get_fingerprint_hash(SSH_PUBLICKEY_HASH_SHA256, sha256 = ssh_get_fingerprint_hash(SSH_PUBLICKEY_HASH_SHA256,
hash, (unsigned char *)hash,
hlen); hlen);
ssh_string_free_char(discard_const(hash)); SSH_STRING_FREE_CHAR(hash);
assert_string_equal(sha256, assert_string_equal(sha256,
"SHA256:jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII"); "SHA256:jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII");
ssh_string_free_char(sha256); SSH_STRING_FREE_CHAR(sha256);
} }
int torture_run_tests(void) { int torture_run_tests(void) {

View File

@@ -111,7 +111,7 @@ static void torture_pubkey_from_file(void **state) {
assert_true(rc == 0); assert_true(rc == 0);
ssh_string_free(pubkey); SSH_STRING_FREE(pubkey);
/* test if it returns 1 if pubkey doesn't exist */ /* test if it returns 1 if pubkey doesn't exist */
unlink(LIBSSH_RSA_TESTKEY ".pub"); unlink(LIBSSH_RSA_TESTKEY ".pub");
@@ -119,11 +119,17 @@ static void torture_pubkey_from_file(void **state) {
rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
assert_true(rc == 1); assert_true(rc == 1);
/* This free is unnecessary, but the static analyser does not know */
SSH_STRING_FREE(pubkey);
/* test if it returns -1 if privkey doesn't exist */ /* test if it returns -1 if privkey doesn't exist */
unlink(LIBSSH_RSA_TESTKEY); unlink(LIBSSH_RSA_TESTKEY);
rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
assert_true(rc == -1); assert_true(rc == -1);
/* This free is unnecessary, but the static analyser does not know */
SSH_STRING_FREE(pubkey);
} }
static int torture_read_one_line(const char *filename, char *buffer, size_t len) { static int torture_read_one_line(const char *filename, char *buffer, size_t len) {
@@ -210,8 +216,8 @@ static void torture_pubkey_generate_from_privkey(void **state) {
assert_string_equal(pubkey_line_orig, pubkey_line_new); assert_string_equal(pubkey_line_orig, pubkey_line_new);
ssh_string_free(pubkey_orig); SSH_STRING_FREE(pubkey_orig);
ssh_string_free(pubkey_new); SSH_STRING_FREE(pubkey_new);
} }
/** /**

View File

@@ -42,18 +42,24 @@ static int setup_knownhosts_file(void **state)
nwritten = fwrite(LOCALHOST_PATTERN_ED25519, nwritten = fwrite(LOCALHOST_PATTERN_ED25519,
sizeof(char), sizeof(char),
sizeof(LOCALHOST_PATTERN_ED25519), strlen(LOCALHOST_PATTERN_ED25519),
fp); fp);
if (nwritten != sizeof(LOCALHOST_PATTERN_ED25519)) { if (nwritten != strlen(LOCALHOST_PATTERN_ED25519)) {
fclose(fp);
return -1;
}
nwritten = fwrite("\n", sizeof(char), 1, fp);
if (nwritten != 1) {
fclose(fp); fclose(fp);
return -1; return -1;
} }
nwritten = fwrite(LOCALHOST_RSA_LINE, nwritten = fwrite(LOCALHOST_RSA_LINE,
sizeof(char), sizeof(char),
sizeof(LOCALHOST_RSA_LINE), strlen(LOCALHOST_RSA_LINE),
fp); fp);
if (nwritten != sizeof(LOCALHOST_RSA_LINE)) { if (nwritten != strlen(LOCALHOST_RSA_LINE)) {
fclose(fp); fclose(fp);
return -1; return -1;
} }
@@ -210,6 +216,8 @@ static void torture_knownhosts_read_file(void **state)
const char *knownhosts_file = *state; const char *knownhosts_file = *state;
struct ssh_list *entry_list = NULL; struct ssh_list *entry_list = NULL;
struct ssh_iterator *it = NULL; struct ssh_iterator *it = NULL;
struct ssh_knownhosts_entry *entry = NULL;
enum ssh_keytypes_e type;
int rc; int rc;
rc = ssh_known_hosts_read_entries("localhost", rc = ssh_known_hosts_read_entries("localhost",
@@ -219,22 +227,27 @@ static void torture_knownhosts_read_file(void **state)
assert_non_null(entry_list); assert_non_null(entry_list);
it = ssh_list_get_iterator(entry_list); it = ssh_list_get_iterator(entry_list);
assert_non_null(it); assert_non_null(it);
for (;it != NULL; it = it->next) {
struct ssh_knownhosts_entry *entry = NULL;
enum ssh_keytypes_e type;
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it); /* First key in known hosts file is ED25519 */
assert_non_null(entry); entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
assert_non_null(entry);
assert_string_equal(entry->hostname, "localhost"); assert_string_equal(entry->hostname, "localhost");
type = ssh_key_type(entry->publickey); type = ssh_key_type(entry->publickey);
assert_int_equal(type, SSH_KEYTYPE_ED25519); assert_int_equal(type, SSH_KEYTYPE_ED25519);
}
it = it->next;
/* Second key in known hosts file is RSA */
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
assert_non_null(entry);
assert_string_equal(entry->hostname, "localhost");
type = ssh_key_type(entry->publickey);
assert_int_equal(type, SSH_KEYTYPE_RSA);
it = ssh_list_get_iterator(entry_list); it = ssh_list_get_iterator(entry_list);
for (;it != NULL; it = it->next) { for (;it != NULL; it = it->next) {
struct ssh_knownhosts_entry *entry = NULL;
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it); entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
SSH_KNOWNHOSTS_ENTRY_FREE(entry); SSH_KNOWNHOSTS_ENTRY_FREE(entry);
} }
@@ -252,6 +265,8 @@ static void torture_knownhosts_host_exists(void **state)
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file); ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
/* This makes sure the system's known_hosts are not used */
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, "/dev/null");
found = ssh_session_has_known_hosts_entry(session); found = ssh_session_has_known_hosts_entry(session);
assert_int_equal(found, SSH_KNOWN_HOSTS_OK); assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
@@ -264,6 +279,89 @@ static void torture_knownhosts_host_exists(void **state)
ssh_free(session); ssh_free(session);
} }
static void torture_knownhosts_host_exists_global(void **state)
{
const char *knownhosts_file = *state;
enum ssh_known_hosts_e found;
ssh_session session;
session = ssh_new();
assert_non_null(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
/* This makes sure the user's known_hosts are not used */
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
found = ssh_session_has_known_hosts_entry(session);
assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
assert_true(found == SSH_KNOWN_HOSTS_OK);
ssh_options_set(session, SSH_OPTIONS_HOST, "wurstbrot");
found = ssh_session_has_known_hosts_entry(session);
assert_true(found == SSH_KNOWN_HOSTS_UNKNOWN);
ssh_free(session);
}
static void
torture_knownhosts_algorithms(void **state)
{
const char *knownhosts_file = *state;
char *algo_list = NULL;
ssh_session session;
const char *expect = "ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521,"
"ecdsa-sha2-nistp384,ecdsa-sha2-nistp256"
#ifdef HAVE_DSA
",ssh-dss"
#endif
;
session = ssh_new();
assert_non_null(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
/* This makes sure the system's known_hosts are not used */
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, "/dev/null");
algo_list = ssh_client_select_hostkeys(session);
assert_non_null(algo_list);
assert_string_equal(algo_list, expect);
free(algo_list);
ssh_free(session);
}
static void
torture_knownhosts_algorithms_global(void **state)
{
const char *knownhosts_file = *state;
char *algo_list = NULL;
ssh_session session;
const char *expect = "ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521,"
"ecdsa-sha2-nistp384,ecdsa-sha2-nistp256"
#ifdef HAVE_DSA
",ssh-dss"
#endif
;
session = ssh_new();
assert_non_null(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
/* This makes sure the current-user's known hosts are not used */
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
algo_list = ssh_client_select_hostkeys(session);
assert_non_null(algo_list);
assert_string_equal(algo_list, expect);
free(algo_list);
ssh_free(session);
}
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
struct CMUnitTest tests[] = { struct CMUnitTest tests[] = {
@@ -279,6 +377,15 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists, cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists,
setup_knownhosts_file, setup_knownhosts_file,
teardown_knownhosts_file), teardown_knownhosts_file),
cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists_global,
setup_knownhosts_file,
teardown_knownhosts_file),
cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms,
setup_knownhosts_file,
teardown_knownhosts_file),
cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms_global,
setup_knownhosts_file,
teardown_knownhosts_file),
}; };
ssh_init(); ssh_init();

View File

@@ -346,6 +346,76 @@ static void torture_options_get_identity(void **state) {
free(identity); free(identity);
} }
static void torture_options_set_global_knownhosts(void **state)
{
ssh_session session = *state;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
"/etc/libssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.global_knownhosts,
"/etc/libssh/known_hosts");
}
static void torture_options_get_global_knownhosts(void **state)
{
ssh_session session = *state;
char *str = NULL;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
"/etc/libssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.global_knownhosts,
"/etc/libssh/known_hosts");
rc = ssh_options_get(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, &str);
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.global_knownhosts,
"/etc/libssh/known_hosts");
SSH_STRING_FREE_CHAR(str);
}
static void torture_options_set_knownhosts(void **state)
{
ssh_session session = *state;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_KNOWNHOSTS,
"/home/libssh/.ssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.knownhosts,
"/home/libssh/.ssh/known_hosts");
}
static void torture_options_get_knownhosts(void **state)
{
ssh_session session = *state;
char *str = NULL;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_KNOWNHOSTS,
"/home/libssh/.ssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.knownhosts,
"/home/libssh/.ssh/known_hosts");
rc = ssh_options_get(session, SSH_OPTIONS_KNOWNHOSTS, &str);
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.knownhosts,
"/home/libssh/.ssh/known_hosts");
SSH_STRING_FREE_CHAR(str);
}
static void torture_options_proxycommand(void **state) { static void torture_options_proxycommand(void **state) {
ssh_session session = *state; ssh_session session = *state;
int rc; int rc;
@@ -560,7 +630,7 @@ static void torture_bind_options_import_key(void **state)
/* set invalid key */ /* set invalid key */
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key); rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key);
assert_int_equal(rc, -1); assert_int_equal(rc, -1);
ssh_key_free(key); SSH_KEY_FREE(key);
/* set rsa key */ /* set rsa key */
base64_key = torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0); base64_key = torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0);
@@ -604,6 +674,10 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_options_get_user, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_get_user, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_identity, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_set_identity, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_get_identity, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_get_identity, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_global_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_get_global_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_get_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_ciphers, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_set_ciphers, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_key_exchange, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_set_key_exchange, setup, teardown),

View File

@@ -104,8 +104,7 @@ static void torture_packet(const char *cipher,
assert_non_null(session->out_buffer); assert_non_null(session->out_buffer);
ssh_buffer_add_data(session->out_buffer, test_data, payload_len); ssh_buffer_add_data(session->out_buffer, test_data, payload_len);
session->socket->fd_out = sockets[0]; session->socket->fd = sockets[0];
session->socket->fd_in = -2;
session->socket->write_wontblock = 1; session->socket->write_wontblock = 1;
rc = ssh_packet_send(session); rc = ssh_packet_send(session);
assert_int_equal(rc, SSH_OK); assert_int_equal(rc, SSH_OK);
@@ -126,8 +125,7 @@ static void torture_packet(const char *cipher,
} }
close(sockets[0]); close(sockets[0]);
close(sockets[1]); close(sockets[1]);
session->socket->fd_in = SSH_INVALID_SOCKET; session->socket->fd = SSH_INVALID_SOCKET;
session->socket->fd_out = SSH_INVALID_SOCKET;
ssh_free(session); ssh_free(session);
} }

View File

@@ -0,0 +1,502 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2018 by Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
/*
* This test checks if the messages accepted by the packet filter were intented
* to be accepted.
*
* The process consists in 2 steps:
* - Try the filter with a message type in an arbitrary state
* - If the message is accepted by the filter, check if the message is in the
* set of accepted states.
*
* Only the values selected by the flag (COMPARE_*) are considered.
* */
#include "config.h"
#define LIBSSH_STATIC
#include "torture.h"
#include "libssh/priv.h"
#include "libssh/libssh.h"
#include "libssh/session.h"
#include "libssh/auth.h"
#include "libssh/ssh2.h"
#include "libssh/packet.h"
#include "packet.c"
#define COMPARE_SESSION_STATE 1
#define COMPARE_ROLE (1 << 1)
#define COMPARE_DH_STATE (1 << 2)
#define COMPARE_AUTH_STATE (1 << 3)
#define COMPARE_GLOBAL_REQ_STATE (1 << 4)
#define COMPARE_CURRENT_METHOD (1 << 5)
#define SESSION_STATE_COUNT 11
#define DH_STATE_COUNT 4
#define AUTH_STATE_COUNT 15
#define GLOBAL_REQ_STATE_COUNT 5
#define MESSAGE_COUNT 100 // from 1 to 100
#define ROLE_CLIENT 0
#define ROLE_SERVER 1
/*
* This is the list of currently unfiltered message types.
* Only unrecognized types should be in this list.
* */
static uint8_t unfiltered[] = {
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
22, 23, 24, 25, 26, 27, 28, 29,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
54, 55, 56, 57, 58, 59,
62,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
83, 84, 85, 86, 87, 88, 89,
};
typedef struct global_state_st {
/* If the bit in this flag is zero, the corresponding state is not
* considered, working as a wildcard (meaning any value is accepted) */
uint32_t flags;
uint8_t role;
enum ssh_session_state_e session;
enum ssh_dh_state_e dh;
enum ssh_auth_state_e auth;
enum ssh_channel_request_state_e global_req;
} global_state;
static int cmp_state(const void *e1, const void *e2)
{
global_state *s1 = (global_state *) e1;
global_state *s2 = (global_state *) e2;
/* Compare role (client == 0 or server == 1)*/
if (s1->role < s2->role) {
return -1;
}
else if (s1->role > s2->role) {
return 1;
}
/* Compare session state */
if (s1->session < s2->session) {
return -1;
}
else if (s1->session > s2->session) {
return 1;
}
/* Compare DH state */
if (s1->dh < s2->dh) {
return -1;
}
else if (s1->dh > s2->dh) {
return 1;
}
/* Compare auth */
if (s1->auth < s2->auth) {
return -1;
}
else if (s1->auth > s2->auth) {
return 1;
}
/* Compare global_req */
if (s1->global_req < s2->global_req) {
return -1;
}
else if (s1->global_req > s2->global_req) {
return 1;
}
/* If all equal, they are equal */
return 0;
}
static int cmp_state_search(const void *key, const void *array_element)
{
global_state *s1 = (global_state *) key;
global_state *s2 = (global_state *) array_element;
int result = 0;
if (s2->flags & COMPARE_ROLE) {
/* Compare role (client == 0 or server == 1)*/
if (s1->role < s2->role) {
return -1;
}
else if (s1->role > s2->role) {
return 1;
}
}
if (s2->flags & COMPARE_SESSION_STATE) {
/* Compare session state */
if (s1->session < s2->session) {
result = -1;
goto end;
}
else if (s1->session > s2->session) {
result = 1;
goto end;
}
}
if (s2->flags & COMPARE_DH_STATE) {
/* Compare DH state */
if (s1->dh < s2->dh) {
result = -1;
goto end;
}
else if (s1->dh > s2->dh) {
result = 1;
goto end;
}
}
if (s2->flags & COMPARE_AUTH_STATE) {
/* Compare auth */
if (s1->auth < s2->auth) {
result = -1;
goto end;
}
else if (s1->auth > s2->auth) {
result = 1;
goto end;
}
}
if (s2->flags & COMPARE_GLOBAL_REQ_STATE) {
/* Compare global_req */
if (s1->global_req < s2->global_req) {
result = -1;
goto end;
}
else if (s1->global_req > s2->global_req) {
result = 1;
goto end;
}
}
end:
return result;
}
static int is_state_accepted(global_state *tested, global_state *accepted,
int accepted_len)
{
global_state *found = NULL;
found = bsearch(tested, accepted, accepted_len, sizeof(global_state),
cmp_state_search);
if (found != NULL) {
return 1;
}
return 0;
}
static int cmp_uint8(const void *i, const void *j)
{
uint8_t e1 = *((uint8_t *)i);
uint8_t e2 = *((uint8_t *)j);
if (e1 < e2) {
return -1;
}
else if (e1 > e2) {
return 1;
}
return 0;
}
static int check_unfiltered(uint8_t msg_type)
{
uint8_t *found;
found = bsearch(&msg_type, unfiltered, sizeof(unfiltered)/sizeof(uint8_t),
sizeof(uint8_t), cmp_uint8);
if (found != NULL) {
return 1;
}
return 0;
}
static void torture_packet_filter_check_unfiltered(void **state)
{
ssh_session session;
int role_c;
int auth_c;
int session_c;
int dh_c;
int global_req_c;
uint8_t msg_type;
enum ssh_packet_filter_result_e rc;
int in_unfiltered;
session = ssh_new();
for (msg_type = 1; msg_type <= MESSAGE_COUNT; msg_type++) {
session->in_packet.type = msg_type;
for (role_c = 0; role_c < 2; role_c++) {
session->server = role_c;
for (session_c = 0; session_c < SESSION_STATE_COUNT; session_c++) {
session->session_state = session_c;
for (dh_c = 0; dh_c < DH_STATE_COUNT; dh_c++) {
session->dh_handshake_state = dh_c;
for (auth_c = 0; auth_c < AUTH_STATE_COUNT; auth_c++) {
session->auth.state = auth_c;
for (global_req_c = 0;
global_req_c < GLOBAL_REQ_STATE_COUNT;
global_req_c++)
{
session->global_req_state = global_req_c;
rc = ssh_packet_incoming_filter(session);
if (rc == SSH_PACKET_UNKNOWN) {
in_unfiltered = check_unfiltered(msg_type);
if (!in_unfiltered) {
fprintf(stderr, "Message type %d UNFILTERED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_unfiltered, 1);
}
else {
in_unfiltered = check_unfiltered(msg_type);
if (in_unfiltered) {
fprintf(stderr, "Message type %d NOT UNFILTERED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_unfiltered, 0);
}
}
}
}
}
}
}
ssh_free(session);
}
static int check_message_in_all_states(global_state accepted[],
int accepted_count, uint8_t msg_type)
{
ssh_session session;
int role_c;
int auth_c;
int session_c;
int dh_c;
int global_req_c;
enum ssh_packet_filter_result_e rc;
int in_accepted;
global_state key;
session = ssh_new();
/* Sort the accepted array so that the elements can be searched using
* bsearch */
qsort(accepted, accepted_count, sizeof(global_state), cmp_state);
session->in_packet.type = msg_type;
for (role_c = 0; role_c < 2; role_c++) {
session->server = role_c;
key.role = role_c;
for (session_c = 0; session_c < SESSION_STATE_COUNT; session_c++) {
session->session_state = session_c;
key.session = session_c;
for (dh_c = 0; dh_c < DH_STATE_COUNT; dh_c++) {
session->dh_handshake_state = dh_c;
key.dh = dh_c;
for (auth_c = 0; auth_c < AUTH_STATE_COUNT; auth_c++) {
session->auth.state = auth_c;
key.auth = auth_c;
for (global_req_c = 0;
global_req_c < GLOBAL_REQ_STATE_COUNT;
global_req_c++)
{
session->global_req_state = global_req_c;
key.global_req = global_req_c;
rc = ssh_packet_incoming_filter(session);
if (rc == SSH_PACKET_ALLOWED) {
in_accepted = is_state_accepted(&key, accepted,
accepted_count);
if (!in_accepted) {
fprintf(stderr, "Message type %d ALLOWED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_accepted, 1);
}
else if (rc == SSH_PACKET_DENIED) {
in_accepted = is_state_accepted(&key, accepted, accepted_count);
if (in_accepted) {
fprintf(stderr, "Message type %d DENIED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_accepted, 0);
}
else {
fprintf(stderr, "Message type %d UNFILTERED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
}
}
}
}
}
ssh_free(session);
return 0;
}
static void torture_packet_filter_check_auth_success(void **state)
{
int rc;
global_state accepted[] = {
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_GSSAPI_MIC_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_KBDINT_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE |
COMPARE_CURRENT_METHOD),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_AUTH_NONE_SENT,
}
};
int accepted_count = 5;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_USERAUTH_SUCCESS);
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_channel_open(void **state)
{
int rc;
/* The only condition to accept a CHANNEL_OPEN 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_OPEN);
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_unfiltered),
};
ssh_init();
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, NULL, NULL);
ssh_finalize();
return rc;
}

View File

@@ -82,7 +82,7 @@ static void torture_pki_dsa_import_pubkey_file(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state) static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state)
@@ -97,7 +97,7 @@ static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_dsa_import_privkey_base64(void **state) static void torture_pki_dsa_import_privkey_base64(void **state)
@@ -115,7 +115,7 @@ static void torture_pki_dsa_import_privkey_base64(void **state)
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
#ifdef HAVE_LIBCRYPTO #ifdef HAVE_LIBCRYPTO
@@ -154,8 +154,8 @@ static void torture_pki_dsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
/* Test with passphrase */ /* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY_PASSPHRASE, rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY_PASSPHRASE,
@@ -192,8 +192,8 @@ static void torture_pki_dsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
} }
#endif #endif
@@ -215,8 +215,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1),
@@ -247,8 +246,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1),
@@ -259,7 +257,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
assert_true(rc == -1); assert_true(rc == -1);
/* This free in unnecessary, but the static analyser does not know */ /* This free in unnecessary, but the static analyser does not know */
ssh_key_free(key); SSH_KEY_FREE(key);
#ifndef HAVE_LIBCRYPTO #ifndef HAVE_LIBCRYPTO
/* test if it returns -1 if passphrase is NULL */ /* test if it returns -1 if passphrase is NULL */
@@ -272,7 +270,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
assert_true(rc == -1); assert_true(rc == -1);
/* This free in unnecessary, but the static analyser does not know */ /* This free in unnecessary, but the static analyser does not know */
ssh_key_free(key); SSH_KEY_FREE(key);
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
} }
@@ -299,8 +297,7 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(keystring, rc = ssh_pki_import_privkey_base64(keystring,
@@ -328,8 +325,7 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(keystring, rc = ssh_pki_import_privkey_base64(keystring,
@@ -339,6 +335,9 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
/* This free is unnecessary, but the static analyser does not know */
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is NULL */ /* test if it returns -1 if passphrase is NULL */
rc = ssh_pki_import_privkey_base64(keystring, rc = ssh_pki_import_privkey_base64(keystring,
NULL, NULL,
@@ -346,6 +345,9 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
/* This free is unnecessary, but the static analyser does not know */
SSH_KEY_FREE(key);
} }
@@ -371,8 +373,8 @@ static void torture_pki_dsa_publickey_from_privatekey(void **state)
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_dsa_import_cert_file(void **state) static void torture_pki_dsa_import_cert_file(void **state)
@@ -392,7 +394,7 @@ static void torture_pki_dsa_import_cert_file(void **state)
rc = ssh_key_is_public(cert); rc = ssh_key_is_public(cert);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(cert); SSH_KEY_FREE(cert);
} }
static void torture_pki_dsa_publickey_base64(void **state) static void torture_pki_dsa_publickey_base64(void **state)
@@ -443,7 +445,7 @@ static void torture_pki_dsa_publickey_base64(void **state)
free(b64_key); free(b64_key);
free(key_buf); free(key_buf);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_dsa_generate_pubkey_from_privkey(void **state) static void torture_pki_dsa_generate_pubkey_from_privkey(void **state)
@@ -482,8 +484,8 @@ static void torture_pki_dsa_generate_pubkey_from_privkey(void **state)
pubkey_generated, pubkey_generated,
len); len);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_dsa_duplicate_key(void **state) static void torture_pki_dsa_duplicate_key(void **state)
@@ -503,7 +505,7 @@ static void torture_pki_dsa_duplicate_key(void **state)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY,
NULL, NULL,
@@ -530,11 +532,11 @@ static void torture_pki_dsa_duplicate_key(void **state)
rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(privkey_dup); SSH_KEY_FREE(privkey_dup);
ssh_string_free_char(b64_key); SSH_STRING_FREE_CHAR(b64_key);
ssh_string_free_char(b64_key_gen); SSH_STRING_FREE_CHAR(b64_key_gen);
} }
static void torture_pki_dsa_generate_key(void **state) static void torture_pki_dsa_generate_key(void **state)
@@ -553,8 +555,7 @@ static void torture_pki_dsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,DSA_HASH,20); rc = pki_signature_verify(session,sign,key,DSA_HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 2048, &key); rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 2048, &key);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
@@ -564,8 +565,7 @@ static void torture_pki_dsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,DSA_HASH,20); rc = pki_signature_verify(session,sign,key,DSA_HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 3072, &key); rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 3072, &key);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
@@ -575,8 +575,7 @@ static void torture_pki_dsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,DSA_HASH,20); rc = pki_signature_verify(session,sign,key,DSA_HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
ssh_free(session); ssh_free(session);
} }

View File

@@ -121,7 +121,7 @@ static void torture_pki_ecdsa_import_pubkey_file(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state) static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state)
@@ -136,7 +136,7 @@ static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ecdsa_import_privkey_base64(void **state) static void torture_pki_ecdsa_import_privkey_base64(void **state)
@@ -158,7 +158,7 @@ static void torture_pki_ecdsa_import_privkey_base64(void **state)
assert_true(rc == 1); assert_true(rc == 1);
free(key_str); free(key_str);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_ecdsa_publickey_from_privatekey(void **state) static void torture_pki_ecdsa_publickey_from_privatekey(void **state)
@@ -181,8 +181,8 @@ static void torture_pki_ecdsa_publickey_from_privatekey(void **state)
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
free(key_str); free(key_str);
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ecdsa_publickey_base64(void **state) static void torture_pki_ecdsa_publickey_base64(void **state)
@@ -219,7 +219,7 @@ static void torture_pki_ecdsa_publickey_base64(void **state)
free(b64_key); free(b64_key);
free(key_buf); free(key_buf);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state) static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state)
@@ -261,8 +261,8 @@ static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state)
len = torture_pubkey_len(pubkey_original); len = torture_pubkey_len(pubkey_original);
assert_int_equal(strncmp(pubkey_original, pubkey_generated, len), 0); assert_int_equal(strncmp(pubkey_original, pubkey_generated, len), 0);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ecdsa_duplicate_key(void **state) static void torture_pki_ecdsa_duplicate_key(void **state)
@@ -281,7 +281,7 @@ static void torture_pki_ecdsa_duplicate_key(void **state)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY,
NULL, NULL,
@@ -307,11 +307,11 @@ static void torture_pki_ecdsa_duplicate_key(void **state)
rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(privkey_dup); SSH_KEY_FREE(privkey_dup);
ssh_string_free_char(b64_key); SSH_STRING_FREE_CHAR(b64_key);
ssh_string_free_char(b64_key_gen); SSH_STRING_FREE_CHAR(b64_key_gen);
} }
/* Test case for bug #147: Private ECDSA key duplication did not carry /* Test case for bug #147: Private ECDSA key duplication did not carry
@@ -342,9 +342,9 @@ static void torture_pki_ecdsa_duplicate_then_demote(void **state)
assert_true(rc == 0); assert_true(rc == 0);
assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid); assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(privkey_dup); SSH_KEY_FREE(privkey_dup);
} }
static void torture_pki_generate_key_ecdsa(void **state) static void torture_pki_generate_key_ecdsa(void **state)
@@ -373,8 +373,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0); assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 384, &key); rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 384, &key);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
@@ -391,8 +390,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0); assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key); rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
@@ -409,8 +407,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0); assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
ssh_free(session); ssh_free(session);
} }
@@ -451,8 +448,8 @@ static void torture_pki_ecdsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
/* Test with passphrase */ /* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY_PASSPHRASE, rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY_PASSPHRASE,
@@ -489,8 +486,8 @@ static void torture_pki_ecdsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
} }
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
@@ -508,7 +505,7 @@ static void torture_pki_ecdsa_name(void **state, const char *expected_name)
etype_char =ssh_pki_key_ecdsa_name(key); etype_char =ssh_pki_key_ecdsa_name(key);
assert_true(strcmp(etype_char, expected_name) == 0); assert_true(strcmp(etype_char, expected_name) == 0);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_ecdsa_name256(void **state) static void torture_pki_ecdsa_name256(void **state)

View File

@@ -62,7 +62,7 @@ static void torture_pki_ed25519_import_pubkey_file(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state) static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state)
@@ -77,7 +77,7 @@ static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ed25519_import_privkey_base64(void **state) static void torture_pki_ed25519_import_privkey_base64(void **state)
@@ -106,7 +106,7 @@ static void torture_pki_ed25519_import_privkey_base64(void **state)
assert_true(rc == 1); assert_true(rc == 1);
free(key_str); free(key_str);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
@@ -141,7 +141,7 @@ static void torture_pki_ed25519_import_export_privkey_base64(void **state)
NULL, NULL,
&b64_key); &b64_key);
assert_return_code(rc, errno); assert_return_code(rc, errno);
ssh_key_free(key); SSH_KEY_FREE(key);
rc = ssh_pki_import_privkey_base64(b64_key, rc = ssh_pki_import_privkey_base64(b64_key,
passphrase, passphrase,
@@ -157,7 +157,7 @@ static void torture_pki_ed25519_import_export_privkey_base64(void **state)
assert_true(rc == 1); assert_true(rc == 1);
SSH_STRING_FREE_CHAR(b64_key); SSH_STRING_FREE_CHAR(b64_key);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_ed25519_publickey_from_privatekey(void **state) static void torture_pki_ed25519_publickey_from_privatekey(void **state)
@@ -184,8 +184,8 @@ static void torture_pki_ed25519_publickey_from_privatekey(void **state)
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ed25519_publickey_base64(void **state) static void torture_pki_ed25519_publickey_base64(void **state)
@@ -222,7 +222,7 @@ static void torture_pki_ed25519_publickey_base64(void **state)
free(b64_key); free(b64_key);
free(key_buf); free(key_buf);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state) static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state)
@@ -261,8 +261,8 @@ static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state)
pubkey_generated, pubkey_generated,
len); len);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_ed25519_generate_key(void **state) static void torture_pki_ed25519_generate_key(void **state)
@@ -293,8 +293,7 @@ static void torture_pki_ed25519_generate_key(void **state)
assert_true(rc == SSH_ERROR); assert_true(rc == SSH_ERROR);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL;
ssh_free(session); ssh_free(session);
} }
@@ -336,7 +335,7 @@ static void torture_pki_ed25519_write_privkey(void **state)
assert_true(rc == 0); assert_true(rc == 0);
unlink(LIBSSH_ED25519_TESTKEY); unlink(LIBSSH_ED25519_TESTKEY);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
/* do the same with passphrase */ /* do the same with passphrase */
rc = ssh_pki_export_privkey_file(origkey, rc = ssh_pki_export_privkey_file(origkey,
torture_get_testkey_passphrase(), torture_get_testkey_passphrase(),
@@ -365,8 +364,8 @@ static void torture_pki_ed25519_write_privkey(void **state)
assert_true(rc == 0); assert_true(rc == 0);
unlink(LIBSSH_ED25519_TESTKEY); unlink(LIBSSH_ED25519_TESTKEY);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
/* Test with passphrase */ /* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_ED25519_TESTKEY_PASSPHRASE, rc = ssh_pki_import_privkey_file(LIBSSH_ED25519_TESTKEY_PASSPHRASE,
@@ -404,8 +403,8 @@ static void torture_pki_ed25519_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
} }
static void torture_pki_ed25519_sign(void **state) static void torture_pki_ed25519_sign(void **state)
@@ -441,8 +440,8 @@ static void torture_pki_ed25519_sign(void **state)
assert_memory_equal(ssh_string_data(blob), ref_signature, sizeof(ref_signature)); assert_memory_equal(ssh_string_data(blob), ref_signature, sizeof(ref_signature));
/* ssh_print_hexa("signature", ssh_string_data(blob), ssh_string_len(blob)); */ /* ssh_print_hexa("signature", ssh_string_data(blob), ssh_string_len(blob)); */
ssh_signature_free(sig); ssh_signature_free(sig);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_string_free(blob); SSH_STRING_FREE(blob);
} }
@@ -473,8 +472,8 @@ static void torture_pki_ed25519_verify(void **state){
ssh_signature_free(sig); ssh_signature_free(sig);
/* alter signature and expect false result */ /* alter signature and expect false result */
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_string_free(blob); SSH_STRING_FREE(blob);
free(pkey_ptr); free(pkey_ptr);
} }
@@ -509,8 +508,8 @@ static void torture_pki_ed25519_verify_bad(void **state){
ssh_signature_free(sig); ssh_signature_free(sig);
} }
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_string_free(blob); SSH_STRING_FREE(blob);
free(pkey_ptr); free(pkey_ptr);
} }
@@ -535,8 +534,7 @@ static void torture_pki_ed25519_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(testkey, rc = ssh_pki_import_privkey_base64(testkey,
@@ -545,7 +543,7 @@ static void torture_pki_ed25519_import_privkey_base64_passphrase(void **state)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_ed25519_privkey_dup(void **state) static void torture_pki_ed25519_privkey_dup(void **state)
@@ -572,8 +570,8 @@ static void torture_pki_ed25519_privkey_dup(void **state)
dup = ssh_key_dup(key); dup = ssh_key_dup(key);
assert_non_null(dup); assert_non_null(dup);
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_key_free(dup); SSH_KEY_FREE(dup);
} }
static void torture_pki_ed25519_pubkey_dup(void **state) static void torture_pki_ed25519_pubkey_dup(void **state)
@@ -609,8 +607,8 @@ static void torture_pki_ed25519_pubkey_dup(void **state)
assert_true(rc == 1); assert_true(rc == 1);
SAFE_FREE(pub_str); SAFE_FREE(pub_str);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_key_free(dup); SSH_KEY_FREE(dup);
} }
int torture_run_tests(void) { int torture_run_tests(void) {

View File

@@ -84,7 +84,7 @@ static void torture_pki_rsa_import_pubkey_file(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state) static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state)
@@ -99,7 +99,7 @@ static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_rsa_import_privkey_base64_NULL_key(void **state) static void torture_pki_rsa_import_privkey_base64_NULL_key(void **state)
@@ -131,7 +131,7 @@ static void torture_pki_rsa_import_privkey_base64_NULL_str(void **state)
rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key); rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_rsa_import_privkey_base64(void **state) static void torture_pki_rsa_import_privkey_base64(void **state)
@@ -160,7 +160,7 @@ static void torture_pki_rsa_import_privkey_base64(void **state)
assert_true(rc == 1); assert_true(rc == 1);
free(key_str); free(key_str);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_rsa_publickey_from_privatekey(void **state) static void torture_pki_rsa_publickey_from_privatekey(void **state)
@@ -185,8 +185,8 @@ static void torture_pki_rsa_publickey_from_privatekey(void **state)
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_rsa_copy_cert_to_privkey(void **state) static void torture_pki_rsa_copy_cert_to_privkey(void **state)
@@ -239,9 +239,9 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
rc = ssh_pki_copy_cert_to_privkey(cert, privkey); rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
assert_true(rc == SSH_ERROR); assert_true(rc == SSH_ERROR);
ssh_key_free(cert); SSH_KEY_FREE(cert);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_rsa_import_cert_file(void **state) { static void torture_pki_rsa_import_cert_file(void **state) {
@@ -260,7 +260,7 @@ static void torture_pki_rsa_import_cert_file(void **state) {
rc = ssh_key_is_public(cert); rc = ssh_key_is_public(cert);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(cert); SSH_KEY_FREE(cert);
} }
static void torture_pki_rsa_publickey_base64(void **state) static void torture_pki_rsa_publickey_base64(void **state)
@@ -297,7 +297,7 @@ static void torture_pki_rsa_publickey_base64(void **state)
free(b64_key); free(b64_key);
free(key_buf); free(key_buf);
ssh_key_free(key); SSH_KEY_FREE(key);
} }
static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) { static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) {
@@ -335,8 +335,8 @@ static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) {
pubkey_generated, pubkey_generated,
len); len);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
} }
static void torture_pki_rsa_duplicate_key(void **state) static void torture_pki_rsa_duplicate_key(void **state)
@@ -356,7 +356,7 @@ static void torture_pki_rsa_duplicate_key(void **state)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY,
NULL, NULL,
@@ -382,11 +382,11 @@ static void torture_pki_rsa_duplicate_key(void **state)
rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(privkey_dup); SSH_KEY_FREE(privkey_dup);
ssh_string_free_char(b64_key); SSH_STRING_FREE_CHAR(b64_key);
ssh_string_free_char(b64_key_gen); SSH_STRING_FREE_CHAR(b64_key_gen);
} }
static void torture_pki_rsa_generate_key(void **state) static void torture_pki_rsa_generate_key(void **state)
@@ -405,7 +405,7 @@ static void torture_pki_rsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,RSA_HASH,20); rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL; key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key); rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key);
@@ -416,7 +416,7 @@ static void torture_pki_rsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,RSA_HASH,20); rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL; key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key); rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key);
@@ -427,7 +427,7 @@ static void torture_pki_rsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,RSA_HASH,20); rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key=NULL; key=NULL;
ssh_free(session); ssh_free(session);
@@ -477,7 +477,7 @@ static void torture_pki_rsa_sha2(void **state)
ssh_signature_free(sign); ssh_signature_free(sign);
/* Cleanup */ /* Cleanup */
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_free(session); ssh_free(session);
} }
@@ -518,8 +518,8 @@ static void torture_pki_rsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
/* Test with passphrase */ /* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY_PASSPHRASE, rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY_PASSPHRASE,
@@ -557,8 +557,8 @@ static void torture_pki_rsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(origkey); SSH_KEY_FREE(origkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
} }
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
@@ -581,8 +581,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1),
@@ -591,8 +590,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
#ifndef HAVE_LIBCRYPTO #ifndef HAVE_LIBCRYPTO
/* test if it returns -1 if passphrase is NULL */ /* test if it returns -1 if passphrase is NULL */
@@ -603,8 +601,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
#endif #endif
} }
@@ -631,8 +628,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(keystring, rc = ssh_pki_import_privkey_base64(keystring,
@@ -641,8 +637,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is NULL */ /* test if it returns -1 if passphrase is NULL */
/* libcrypto asks for a passphrase, so skip this test */ /* libcrypto asks for a passphrase, so skip this test */
@@ -652,8 +647,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
} }
int torture_run_tests(void) { int torture_run_tests(void) {

View File

@@ -87,7 +87,7 @@ static void *thread_growing_buffer(void *threadid)
} }
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -134,14 +134,14 @@ static void *thread_growing_buffer_shifting(void *threadid)
if (ssh_buffer_get_len(buffer) * 4 < buffer->allocated) { if (ssh_buffer_get_len(buffer) * 4 < buffer->allocated) {
assert_true(ssh_buffer_get_len(buffer) * 4 >= buffer->allocated); assert_true(ssh_buffer_get_len(buffer) * 4 >= buffer->allocated);
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
} }
} }
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -198,7 +198,7 @@ static void *thread_buffer_prepend(void *threadid)
assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10); assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10);
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -247,9 +247,9 @@ static void *thread_ssh_buffer_get_ssh_string(void *threadid)
for (l = 0; l < k; ++l) { for (l = 0; l < k; ++l) {
ssh_string str = ssh_buffer_get_ssh_string(buffer); ssh_string str = ssh_buffer_get_ssh_string(buffer);
assert_null(str); assert_null(str);
ssh_string_free(str); SSH_STRING_FREE(str);
} }
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
} }
} }
} }
@@ -316,10 +316,10 @@ static void *thread_ssh_buffer_add_format(void *threadid)
assert_int_equal(len, sizeof(verif) - 1); assert_int_equal(len, sizeof(verif) - 1);
assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1); assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);
ssh_string_free(s); SSH_STRING_FREE(s);
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -397,7 +397,7 @@ static void *thread_ssh_buffer_get_format(void *threadid) {
SAFE_FREE(s2); SAFE_FREE(s2);
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -458,7 +458,7 @@ static void *thread_ssh_buffer_get_format_error(void *threadid)
assert_true(s2 == NULL); assert_true(s2 == NULL);
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -514,7 +514,7 @@ static void *thread_buffer_pack_badformat(void *threadid)
* it could crash the process */ * it could crash the process */
/* Teardown */ /* Teardown */
ssh_buffer_free(buffer); SSH_BUFFER_FREE(buffer);
pthread_exit(NULL); pthread_exit(NULL);
} }

View File

@@ -143,7 +143,7 @@ static void *thread_pki_rsa_import_pubkey_file(void *threadid)
assert_return_code(rc, errno); assert_return_code(rc, errno);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -201,7 +201,7 @@ static void *thread_pki_rsa_import_privkey_base64_NULL_str(void *threadid)
rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key); rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -242,7 +242,7 @@ static void *thread_pki_rsa_import_privkey_base64(void *threadid)
assert_true(ok); assert_true(ok);
free(key_str); free(key_str);
ssh_key_free(key); SSH_KEY_FREE(key);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -283,8 +283,8 @@ static void *thread_pki_rsa_publickey_from_privatekey(void *threadid)
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
assert_non_null(pubkey); assert_non_null(pubkey);
ssh_key_free(key); SSH_KEY_FREE(key);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -349,9 +349,9 @@ static void *thread_pki_rsa_copy_cert_to_privkey(void *threadid)
rc = ssh_pki_copy_cert_to_privkey(cert, privkey); rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
assert_true(rc == SSH_ERROR); assert_true(rc == SSH_ERROR);
ssh_key_free(cert); SSH_KEY_FREE(cert);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -383,7 +383,7 @@ static void *thread_pki_rsa_import_cert_file(void *threadid)
rc = ssh_key_is_public(cert); rc = ssh_key_is_public(cert);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(cert); SSH_KEY_FREE(cert);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -432,7 +432,7 @@ static void *thread_pki_rsa_publickey_base64(void *threadid)
free(b64_key); free(b64_key);
free(key_buf); free(key_buf);
ssh_key_free(key); SSH_KEY_FREE(key);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -464,7 +464,7 @@ static void *thread_pki_rsa_duplicate_key(void *threadid)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0); assert_true(rc == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY,
NULL, NULL,
@@ -489,11 +489,11 @@ static void *thread_pki_rsa_duplicate_key(void *threadid)
cmp = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); cmp = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(cmp == 0); assert_true(cmp == 0);
ssh_key_free(pubkey); SSH_KEY_FREE(pubkey);
ssh_key_free(privkey); SSH_KEY_FREE(privkey);
ssh_key_free(privkey_dup); SSH_KEY_FREE(privkey_dup);
ssh_string_free_char(b64_key); SSH_STRING_FREE_CHAR(b64_key);
ssh_string_free_char(b64_key_gen); SSH_STRING_FREE_CHAR(b64_key_gen);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -531,8 +531,7 @@ static void *thread_pki_rsa_generate_key(void *threadid)
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key); rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key);
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
@@ -545,8 +544,7 @@ static void *thread_pki_rsa_generate_key(void *threadid)
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key); rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key);
@@ -560,7 +558,7 @@ static void *thread_pki_rsa_generate_key(void *threadid)
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL; key = NULL;
ssh_free(session); ssh_free(session);
@@ -596,8 +594,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
rc = ssh_key_is_private(key); rc = ssh_key_is_private(key);
assert_true(rc == 1); assert_true(rc == 1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1),
@@ -606,8 +603,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
#ifndef HAVE_LIBCRYPTO #ifndef HAVE_LIBCRYPTO
/* test if it returns -1 if passphrase is NULL */ /* test if it returns -1 if passphrase is NULL */
@@ -618,8 +614,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
NULL, NULL,
&key); &key);
assert_true(rc == -1); assert_true(rc == -1);
ssh_key_free(key); SSH_KEY_FREE(key);
key = NULL;
#endif #endif
pthread_exit(NULL); pthread_exit(NULL);
} }