Compare commits

...

98 Commits

Author SHA1 Message Date
Jakub Jelen
301d0e16df Bump version to 0.11.3
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2025-09-09 10:01:48 +02:00
Jakub Jelen
c182a21e11 poll: Use is_locked helper where possible
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit df4e907dff)
2025-08-14 11:02:39 +02:00
Philippe Antoine
3a28fbe5c6 socket: do not free poll object if it is locked
As it may a cause a use after free if `send` fails when
ssh_poll_ctx_dopoll does its callback
ssh_poll_ctx_dopoll still wants to use the poll object later

Signed-off-by: Philippe Antoine <p.antoine@catenacyber.fr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c99261437f)
2025-08-14 11:02:39 +02:00
Andreas Schneider
65f363c9e3 CVE-2025-8114: Fix NULL pointer dereference after allocation failure
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 53ac23ded4)
2025-08-14 11:02:39 +02:00
Jakub Jelen
1c763e29d1 CVE-2025-8277: mbedtls: Avoid leaking ecdh keys
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ffed80f8c0)
2025-08-14 11:02:39 +02:00
Jakub Jelen
7d85085d2a tests: Invoke all combinations of wrong guesses during rekey
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d357a9f3e2)
2025-08-14 11:02:39 +02:00
Jakub Jelen
8e4d67aa9e CVE-2025-8277: ecdh: Free previously allocated pubkeys
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c9d95ab0c7)
2025-08-14 11:02:39 +02:00
Francesco Rollo
266174a6d3 CVE-2025-8277: Fix memory leak of unused ephemeral key pair after client's wrong KEX guess
Signed-off-by: Francesco Rollo <eferollo@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ccff22d378)
2025-08-14 11:02:39 +02:00
Jakub Jelen
87db2659ec CVE-2025-8277: packet: Adjust packet filter to work when DH-GEX is guessed wrongly
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4310a696f2)
2025-08-14 11:02:39 +02:00
Jakub Jelen
0fad4e6307 tests: Enable all key exchange methods in ssh_ping
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 771e19a7a9)
2025-08-14 11:02:39 +02:00
Andreas Schneider
02cbd41b92 tests: Call disable_secmem() before ssh_init()
ssh_init calls ssh_crypto_init() which initializes the secure memory of
gcrypt. Those should actually be just called by the application once.
Lets do that.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2966a4a33c)
2025-08-08 16:11:26 +02:00
Andreas Schneider
750693d10b tests: Reformat cmocka_unit_test calls in torture_threads_pki_rsa.c
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 867630750c)
2025-08-08 16:11:24 +02:00
Jakub Jelen
56953f8aab mbedtls: Avoid one more memory leak
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit 4f239f79c6)
2025-08-08 13:49:35 +02:00
Jakub Jelen
0f1723b5c7 mbedtls: Rename label to match the current meaning
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit b314fd3e04)
2025-08-08 13:49:29 +02:00
Jakub Jelen
f1998d6064 mbedtls: Avoid code duplication between v2 and v3 branches
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit d1ad796496)
2025-08-08 13:49:28 +02:00
Jakub Jelen
d0ef7afdfa pki: Make sure the buffer is zeroized too
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit e2064b743d)
2025-08-08 13:49:26 +02:00
Jakub Jelen
6e459f5756 pki_mbedtls: Simplify memory cleanup
The spread out initialization and variable definition (and alising)
was hell to keep up with and was causing memory issues as reported by valgrind:

==4480== 128 bytes in 1 blocks are definitely lost in loss record 1 of 12
==4480==    at 0x48463F3: calloc (vg_replace_malloc.c:1675)
==4480==    by 0x487D152: mbedtls_mpi_grow (bignum.c:218)
==4480==    by 0x487D6C5: mbedtls_mpi_copy (bignum.c:334)
==4480==    by 0x48B9627: mbedtls_rsa_export (rsa.c:899)
==4480==    by 0x283955: pki_key_to_blob (pki_mbedcrypto.c:976)
==4480==    by 0x24F162: ssh_pki_export_privkey_blob (pki.c:2188)
==4480==    by 0x278001: ssh_pki_openssh_privkey_export (pki_container_openssh.c:546)
==4480==    by 0x24D7D2: ssh_pki_export_privkey_file_format (pki.c:1122)
==4480==    by 0x24D916: torture_pki_rsa_write_privkey_format (torture_pki_rsa.c:895)
==4480==    by 0x24D916: torture_pki_rsa_write_privkey (torture_pki_rsa.c:962)
==4480==    by 0x4865499: ??? (in /usr/lib64/libcmocka.so.0.8.0)
==4480==    by 0x4865C0B: _cmocka_run_group_tests (in /usr/lib64/libcmocka.so.0.8.0)
==4480==    by 0x252115: torture_run_tests (torture_pki_rsa.c:1160)
==4480==    by 0x2546B8: main (torture.c:1984)
==4480==

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit 6d2a3e4eb6)
2025-08-08 13:49:25 +02:00
Jakub Jelen
51746e51f0 mbedcrypto: Refromat pki_key_to_blob()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit 7c34fa783d)
2025-08-08 13:49:23 +02:00
Jakub Jelen
e7ef3f2962 CentOS 9 and 10 were updated to OpenSSL 3.5
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 51bd08027e)
2025-08-08 11:37:19 +02:00
Jakub Jelen
b8d92bbcc7 tests: Fix build script to work also on MacOS correctly
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c2e9d39dbe)
2025-08-08 11:30:53 +02:00
Jakub Jelen
f2aaee53df tests: Add more valgrind supressions for krb5
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ab44f606b2)
2025-08-08 11:29:54 +02:00
Jakub Jelen
b026b24b55 tests: Avoid needless call to pthread_exit()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 444982b38a)
2025-08-08 11:29:50 +02:00
Jakub Jelen
028859ce99 pkd: Cleanup OpenSSL context
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3df61a4e86)
2025-08-08 11:29:45 +02:00
Jakub Jelen
d64f06f98a tests: Cleanup OpenSSL in the forked server processes
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7eefbbd478)
2025-08-08 11:29:32 +02:00
Jakub Jelen
b298a04f96 tests: Cleanup OpenSSL in tests when GSSAPI is built
also from the fuzzer tests

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 08a32ac381)
2025-08-08 11:28:18 +02:00
Jakub Jelen
962012bbf6 Cleanup the loaded pkcs11 provider
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 62762bbbc9)
2025-08-08 11:28:13 +02:00
Jakub Jelen
abfc42fad3 Finalize OpenSSL context from tests to make the valgrind output clean
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ab3e08c2b5)
2025-08-08 11:28:09 +02:00
Jakub Jelen
1ad67bd66e tests: Adjust valgrind supression to match new calls stack
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 809898b980)
2025-08-08 11:24:55 +02:00
Jakub Jelen
f553a6740a pkd: Run hmac-sha1 tests with OpenSSH
This was initially in hurry disabled in
ca4c874a9e because dropbear dropped support for
these HMACs. The follow-up commit enabled running these tests on old dropbear in
c17112f070, but still did not run them on openssh,
when the new dropbear was installed.

This fixes up the above commit to run the HMAC-SHA1 tests with OpenSSH even if
the new dropbear is installed.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 9817392e26)
2025-08-08 11:24:32 +02:00
Nguyễn Thái Ngọc Duy
bac5d3f10a Fix ssh_handle_key_exchange() timeout
See libssh-mirror#311 for background. But in some case, it's possible to
trigger the code in ssh_handle_key_exchange() to move session state
directly to SSH_SESSION_STATE_AUTHENTICATED. The exit condition for this
function is SSH_SESSION_STATE_AUTHENTICATING though, so when it happens,
ssh_handle_key_exchange() will time out eventually.

The fix is straightforward. Tested with the problematic
client (trilead-ssh2) and made sure the bad condition happened (and not
cause timeout)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 168302b9d6)
2025-08-08 11:24:28 +02:00
abdallah elhdad
c8c3d418ee Enable HMAC SHA1 tests for dropbear <2025.87
Signed-off-by: abdallah elhdad <abdallahselhdad@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c17112f070)
2025-08-08 11:23:41 +02:00
Theo Buehler
33be8038fe Unbreak torture_config_make_absolute() on OpenBSD
The torture_config_make_absolute() and its _no_sshdir() version both
segfault on OpenBSD. The reason for this is that the storage returned
by getpwuid() is backed by mmap and is unapped by the getpwnam() call
in ssh_path_expand_tilde(), so a later access to home segfaults. The
possibility of this happening (getpwnam() overwriting values returned
by getpwuid()) is explicitly called out in POSIX.

A simple fix is to work with copies of username and homedir.

Signed-off-by: Theo Buehler <tb@openbsd.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ccb8cf88c8)
2025-08-08 11:22:05 +02:00
Andreas Schneider
dff6c0821e Bump version to 0.11.2
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2025-06-24 10:35:39 +02:00
Jakub Jelen
82175044dc dh-gex: Reformat the dhgex_server_callbacks structure
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 10:15:43 +02:00
Jakub Jelen
8559f59404 dh-gex.c: Fix typo in the constant name
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 10:15:43 +02:00
Jakub Jelen
160fc7df10 packet: Implement missing packet filter for DH GEX
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 10:15:43 +02:00
Jakub Jelen
a9d8a3d448 CVE-2025-5372 libgcrypto: Simplify error checking and handling of return codes in ssh_kdf()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:32:00 +02:00
Jakub Jelen
f13b91c2d8 libgcrypto: Reformat ssh_kdf()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:31:58 +02:00
Jakub Jelen
90b4845e0c CVE-2025-5987 libcrypto: Correctly detect failures of chacha initialization
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:31:53 +02:00
Jakub Jelen
6ddb730a27 CVE-2025-5351 pki_crypto: Avoid double-free on low-memory conditions
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:31:36 +02:00
Jakub Jelen
b35ee876ad CVE-2025-4878 legacy: Properly check return value to avoid NULL pointer dereference
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:28:09 +02:00
Jakub Jelen
697650caa9 CVE-2025-4878 Initialize pointers where possible
This is mostly mechanical change initializing all the pointers I was able to
find with some grep and manual review of sources and examples.

Used the following greps (which yield some false positives though):

    git grep "    \w* *\* *\w*;$"
    git grep " ssh_session \w*;"
    git grep " ssh_channel \w*;"
    git grep " struct ssh_iterator \*\w*;"
    git grep " ssh_bind \w*;"
    git grep " ssh_key \w*;"
    git grep " ssh_string \w*;"
    git grep " ssh_buffer \w*;"
    git grep " HMACCTX \w*;"
    git grep " SHACTX \w*;"
    grep -rinP '^(?!.*=)\s*(?:\w+\s+)*\w+\s*\*\s*\w+\s*;'

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:27:52 +02:00
Jakub Jelen
5504ff4051 CVE-2025-5449 sftpserver: Use constant for return values
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:27:52 +02:00
Jakub Jelen
f79ec51b7f CVE-2025-5449 sftpserver: Fix possible read behind buffer on 32bit arch
On 32b architecture when processing the SFTP packets, the value
0x7ffffffc in the payload_len will overflow to negative integer values,
causing these checks to pass and possibly reading behind the buffer
bounds later.

This affects only SFTP server implementations running on 32b
architecture.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:27:52 +02:00
Jakub Jelen
78485f446a CVE-2025-5449 sftpserver: Avoid NULL dereference for invalid handles
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:08:24 +02:00
Jakub Jelen
3443aec901 CVE-2025-5449 tests: Reproducer for sftp handles exhaustion
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:08:24 +02:00
Jakub Jelen
261612179f CVE-2025-5449 sftpserver: Avoid memory leak when we run out of handles during sftp_open
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:08:24 +02:00
Jakub Jelen
5f4ffda887 CVE-2025-5318: sftpserver: Fix possible buffer overrun
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-06-24 09:08:24 +02:00
Jakub Jelen
6fd9cc8ce3 CVE-2025-4877 base64: Prevent integer overflow and potential OOB
Set maximum input to 256MB to have safe margin to the 1GB trigger point
for 32b arch.

The OOB should not be reachable by any internal code paths as most of
the buffers and strings we use as input for this operation already have
similar limit and none really allows this much of data.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 00f09acbec)
2025-06-24 09:08:24 +02:00
Norbert Pocs
b595cc7ada gitlab-ci.yml: Run fedora without pkcs11
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2971e122d0)
2025-06-23 14:42:35 +02:00
Jakub Jelen
d044b79de0 tests: Remove p11-kit remoting from pkcs11 tests
The p11-kit remoting was initially introduced because softhsm
was crashing during cleanup with OpenSSL 3.0. This was resolved
since then and this code introduces a lot of complexity and
possible bugs, such as when using the mechanisms from PKCS#11 3.0
that are unknown to the p11-kit remoting tool. It decides to remove
them from the list as demonstrated here:

https://github.com/p11-glue/p11-kit/issues/668

This resulted in pkcs11-provider not registering EDDSA siganture
methods to the OpenSSL and failing when asked to provide a singature
by the Ed25519 key from the PKCS#11 token.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 99fcd56135)
2025-06-23 14:37:36 +02:00
Jakub Jelen
827c24055f sftp: Do not fail if the status message does not contain error message
Some SFTP servers (Cisco) do not implement the v3 protocol correctly and do not
send the mandatory part of the status message. This falls back to the v2
behavior when the error message and language tag are not provided.

Fixes: #272

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 0306581f1c)
2025-06-23 13:26:47 +02:00
Lucas Mulling
1eff5d68f4 tests: Cleanup torture_channel_exit_signal
Signed-off-by: Lucas Mulling <lucas.mulling@suse.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 74eb01f26d)
2025-06-23 13:25:45 +02:00
Jakub Jelen
e4ede51d87 pki: Set ECDSA signature buffers secure
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Eshan Kelkar <eshankelkar@galorithm.com>
(cherry picked from commit b8e587e498)
2025-06-23 13:25:35 +02:00
Jakub Jelen
991b4422bd tests: Auth without none method
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit 2a2c714dfa)
2025-06-23 13:25:02 +02:00
Jakub Jelen
1a2c46781c auth: Process outstanding packets before selecting signature algorithm
Originally reported by Till on mailing list here:

https://archive.libssh.org/libssh/2025-05/0000000.html

After some debugging, it turns out the client code does not guarantee
the extensions are processed before making decisions on the signature algorithm
that is being used for authentication, causing false-positive failures.

This does not happen in the tests, where we initially call ssh_userauth_none,
which enumerates authentications methods and as a side effect processes
outstanding packets such as SSH_EXT_INFO message with the server-sig-algs
extension.

When the first function called after `ssh_connect()` is
`ssh_userauth_publickey()`, the `ssh_userauth_request_service()` was wrongly
called only after the signature algorithm compatibility was checked.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit 12baa5200a)
2025-06-23 13:24:59 +02:00
Jakub Jelen
65699380cf buffer: Use sizeof instead of magic number
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit f2b64abcbd)
2025-06-23 13:24:57 +02:00
Praneeth Sarode
52e648c7f1 tests: remove unsupported SHA1 HMAC tests for compatibility with latest dropbear version
Signed-off-by: Praneeth Sarode <praneethsarode@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ca4c874a9e)
2025-06-23 13:24:25 +02:00
Lucas Mulling
66314eeb71 misc: Fix OpenSSH banner parsing
Signed-off-by: Lucas Mulling <lucas.mulling@suse.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit d758990d39)
2025-06-23 13:24:05 +02:00
Jakub Jelen
573e0e48dc sftpserver: Free memory on error condition
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit 69c169e4cb)
2025-06-23 13:23:31 +02:00
Jakub Jelen
a2bb9b5d0c test: Fix potential leak of fds on error
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit f0b9db586b)
2025-06-23 13:23:28 +02:00
Jakub Jelen
0de97c48d0 test: Fix unused variables and potential memory leaks
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit c735b44f83)
2025-06-23 13:23:18 +02:00
Jakub Jelen
eeb498c0e3 Make sure we pass right parameters to buffer_pack
Fixes: #299

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit d00f7b1bf9)
2025-06-23 13:22:47 +02:00
Jakub Jelen
715855d888 tests: Do not build zlib test when built without
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit b14018ecab)
2025-06-23 13:21:37 +02:00
Norbert Pocs
38004ecf94 CmakeLists: Fix multiple digit major version for OpenSSH
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit af10857aa3)
2025-06-23 13:20:31 +02:00
Jakub Jelen
edb1b8ba2c tests: Fix variable names to avoid codespell issues
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a25f9d211d)
2025-06-23 13:17:28 +02:00
Jakub Jelen
1e9e37580f tests: Reproducer for graceful failure on ignored Match arguments
https://gitlab.com/libssh/libssh-mirror/-/issues/291#note_2376323499
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3a52bf1679)
2025-06-23 13:17:17 +02:00
Jakub Jelen
8b5b785e0c config: Be less strict when parsing unknown Match keywords
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f7bdd779d6)
2025-06-23 13:17:12 +02:00
Jakub Jelen
d245706678 config: Fix copy&paste error in error message
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8ef249a4a4)
2025-06-23 13:17:06 +02:00
Jakub Jelen
5911d058f1 tests: Unit test nested quotes
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7f045e2d91)
2025-06-23 13:15:02 +02:00
Jakub Jelen
3daa06dba7 Reproducer for #291
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a10553ae57)
2025-06-23 13:14:56 +02:00
Jakub Jelen
45888d65ba config: Allow escaping quotes inside of quoted tokens
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d1ce336ae3)
2025-06-23 13:14:55 +02:00
Jakub Jelen
33a73594e6 examples: Fix format string unearthed during macos build
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d5456931cc)
2025-06-23 13:14:19 +02:00
Jakub Jelen
9cdcd16e82 cmake: Do not attempt to use -fstack-clash-protection on MacOS M1 chips
This is supported in clang, but only on x86_64 so we need to back down to the
architecture checks. Otherwise the checks pass with warning, but the build
itself fails with errors (-Werror).

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dc18b41357)
2025-06-23 13:14:09 +02:00
Jakub Jelen
12077f7294 clang-format: Update config for clang 19
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 9b9a2ea97d)
2025-06-23 13:13:31 +02:00
Andreas Schneider
f067d9e0d3 torture_config: Use getpwuid() instead of env variables
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit e9b76ff1bd)
2025-06-23 13:13:27 +02:00
Andreas Schneider
ec753057a5 torture_misc: Do not rely on environment variables
The safest way is to use getpwuid().

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit e9046fc069)
2025-06-23 13:13:23 +02:00
Jakub Jelen
39aefd479f zlib: Move conditional compilation inside of the gzip.c
This implements stub for the compression functions and includes the
gzip.c in the compilation target uncoditionally, keeping the WITH_ZLIB
conditional compilation only in the gzip.c

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0cd749a533)
2025-06-23 13:13:18 +02:00
Jakub Jelen
2e5b6beec7 gzip: Move cleanup to separate function
to avoid exposing gzip function into wrapper.c

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 00fce9cb6c)
2025-06-23 13:12:14 +02:00
Jakub Jelen
11c16531f0 gzip: Avoid potential memory leak
Thanks coverity CID 1589436

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a547b7f115)
2025-06-23 13:11:19 +02:00
Jakub Jelen
69ee0062d7 options: Clarify format of HOST option
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 91e228b08b)
2025-06-23 13:10:23 +02:00
Jakub Jelen
13c69821dd Happy new year 2025!
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cbcd6d6f46)
2025-06-23 13:10:16 +02:00
Jakub Jelen
543c730691 packet: Implement logging of SSH2_MSG_DEBUG message
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 49b0c859f9)
2025-06-23 13:10:09 +02:00
Jakub Jelen
97bda86d41 channels: Remove callbacks from freed channels
When the user frees the channel, they no longer expect any callbacks
to be triggered on it. When we delay the close before we receive
the remaining messages, we should not trigger the user callbacks
as it might be already freed.

I believe this is the random torture_session test failures and
errors we are getting from valgrind from time to time.

We keep the callbacks cleanup in the do_cleanup() in case the
calling application sets the callback after free for some reason.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 79ba546cde)
2025-06-23 13:10:05 +02:00
Jakub Jelen
77c9498dbe tests: Close channel before freeying
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c043122655)
2025-06-23 13:09:38 +02:00
Jakub Jelen
404452728d tests: Fix random failure on too fast systems
On mingw we are frequently getting a failure like this:

[  ERROR   ] --- 451 is not within the range 1-450

This means the 50ms sleep did not manage to elapse the 50ms in the timeout
structure. Extending the range to 460 will give use more wiggle room if the
clock is not as it should be.

Related: #273
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 874b75429f)
2025-06-23 13:08:56 +02:00
Jakub Jelen
e111a63acb ci: Skip torture_rand in mingw as it keeps hanging
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f8a6b1e2b3)
2025-06-23 13:08:51 +02:00
Andreas Schneider
054682e72d tests:valgrind: Add suppression memleak in krb5_mcc_generate_new
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4bc40a47a3)
2025-06-23 13:08:02 +02:00
Jakub Jelen
5bff8b5dc6 sftpserver: Do not override the ssh error code
Fixes: https://gitlab.com/libssh/libssh-mirror/-/issues/275#note_2162076660

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit d0ecb5388c)
2025-06-23 13:07:33 +02:00
Axel Lin
758fbdd31b Add #ifndef __VA_NARG__ guard to avoid "__VA_NARG__" redefined warnings
Some SDK already defined __VA_NARG__, so without #ifndef __VA_NARG__ guard
we got a lot of "__VA_NARG__" redefined warnings.
Fix it by adding #ifndef __VA_NARG__ guard in include/libssh/priv.h.

Fixes: #279
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 861590192f)
2025-06-23 13:06:59 +02:00
JamesWrigley
5c0add44e7 Add missing #include's to sftpserver.h
Presumably this header is always imported with all the other necessary ones so
it doesn't usually make a difference, but generating Julia bindings from the
header by itself requires all the types to be defined (e.g. ssh_session,
ssh_channel, etc).

Signed-off-by: James Wrigley <james@puiterwijk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9ad2f6b3b1)
2025-06-23 13:06:40 +02:00
JamesWrigley
9f4e7eb06b Make codespell ignore PENDIN in CI
This is the correct name of a terminal opcode.

Signed-off-by: James Wrigley <james@puiterwijk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ef8e90863b)
2025-06-23 13:06:34 +02:00
Simon Josefsson
1d157c57a3 tests: Permit slow systems to take 1-450 instead of 1-40ms.
Thanks to Jakub Jelen for debugging and suggested fix.  Fixes #273.

Signed-off-by: Simon Josefsson <simon@josefsson.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d29ed23010)
2025-06-23 13:06:28 +02:00
Jakub Jelen
7d35d25297 tests: Do not use global openssl.cnf
The global openssl configuration file automatically loads a pkcs11
provider, but it does it before we set up the token, which makes
the pkcs11 tests failing.

The workaround is to not load the global configuration, which is
delaying the loading of the pkcs11 provider to the time of first
use.

Consequently, this will require separate integration end-to-end
test that will verify the libssh works correctly with the pkcs11
provider loaded early.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit 46d7417620)
2025-06-23 13:06:20 +02:00
Jakub Jelen
4119ad0fd8 ci: Add Centos 10 development container
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
(cherry picked from commit c73a8a824e)
2025-06-23 13:06:15 +02:00
Davidwed
771dc30f79 cmake: Fixed compatibility issues with "CPM.cmake" in combination with the libraries MBedTLS and libgcrypt.
Signed-off-by: Davidwed <davidwe@posteo.de>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7712c7d0f9)
2025-06-23 13:06:11 +02:00
Simon Josefsson
747dd17e64 tests: Permit slow systems to take 300ms instead of 75ms.
Thanks to Jakub Jelen for debugging.  Fixes #273.

Reproduce problem by changing the value to 1ms.

Signed-off-by: Simon Josefsson <simon@josefsson.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d7a0cbcfbb)
2025-06-23 13:05:24 +02:00
Thomas Perale
093431f929 cmake: Only enable CXX when running the coverage
Commit 25a678190c introduced code coverage
collection. That also introduced a dependency to CXX language.

When cross-compiling libssh in an environment that doesn't have a C++ compiler
the following error is raised: "No CMAKE_CXX_COMPILER could be found.".

Since the C++ part is only needed for the coverage part, this commit only enable
that language dependency when actually needing it.

Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit cb0237e85b)
2025-06-23 13:05:02 +02:00
128 changed files with 2724 additions and 1074 deletions

View File

@@ -22,8 +22,7 @@ BinPackArguments: false
BinPackParameters: false BinPackParameters: false
AllowAllArgumentsOnNextLine: false AllowAllArgumentsOnNextLine: false
AllowShortFunctionsOnASingleLine: Empty AllowShortFunctionsOnASingleLine: Empty
# TODO with Clang 19, replace the below with BreakAfterReturnType: ExceptShortType
# BreakAfterReturnType: ExceptShortType
AlwaysBreakAfterReturnType: AllDefinitions AlwaysBreakAfterReturnType: AllDefinitions
AlignEscapedNewlines: Left AlignEscapedNewlines: Left
ForEachMacros: ['ssh_callbacks_iterate'] ForEachMacros: ['ssh_callbacks_iterate']

View File

@@ -3,6 +3,7 @@ variables:
BUILD_IMAGES_PROJECT: libssh/build-images BUILD_IMAGES_PROJECT: libssh/build-images
CENTOS8_BUILD: buildenv-c8s CENTOS8_BUILD: buildenv-c8s
CENTOS9_BUILD: buildenv-c9s CENTOS9_BUILD: buildenv-c9s
CENTOS10_BUILD: buildenv-c10s
FEDORA_BUILD: buildenv-fedora FEDORA_BUILD: buildenv-fedora
MINGW_BUILD: buildenv-mingw MINGW_BUILD: buildenv-mingw
TUMBLEWEED_BUILD: buildenv-tumbleweed TUMBLEWEED_BUILD: buildenv-tumbleweed
@@ -74,8 +75,6 @@ workflow:
.fedora: .fedora:
extends: .tests extends: .tests
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
.tumbleweed: .tumbleweed:
extends: .tests extends: .tests
@@ -107,7 +106,7 @@ review:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script: script:
- ERROR=0 - ERROR=0
codespell --ignore-words-list=keypair,sorce,ned,nd,ue || ERROR=1; codespell --ignore-words-list=keypair,sorce,ned,nd,ue,pendin || ERROR=1;
./.gitlab-ci/clang-format-check.sh || ERROR=1; ./.gitlab-ci/clang-format-check.sh || ERROR=1;
./.gitlab-ci/git-check-signoff-trailer.sh ${CI_MERGE_REQUEST_DIFF_BASE_SHA} || ERROR=1; ./.gitlab-ci/git-check-signoff-trailer.sh ${CI_MERGE_REQUEST_DIFF_BASE_SHA} || ERROR=1;
./.gitlab-ci/shellcheck.sh || ERROR=1; ./.gitlab-ci/shellcheck.sh || ERROR=1;
@@ -122,7 +121,29 @@ review:
############################################################################### ###############################################################################
# CentOS builds # # CentOS builds #
############################################################################### ###############################################################################
centos9s/openssl_3.0.x/x86_64: centos10s/openssl_3.5.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS10_BUILD
extends: .tests
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
script:
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
make -j$(nproc) &&
ctest --output-on-failure
centos10s/openssl_3.5.x/x86_64/fips:
extends: .fips
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS10_BUILD
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
script:
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
make -j$(nproc) &&
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
centos9s/openssl_3.5.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
extends: .tests extends: .tests
variables: variables:
@@ -139,7 +160,7 @@ centos9s/mbedtls_2.x/x86_64:
variables: variables:
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_BLOWFISH_CIPHER=OFF" CMAKE_ADDITIONAL_OPTIONS: "-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_BLOWFISH_CIPHER=OFF"
centos9s/openssl_3.0.x/x86_64/fips: centos9s/openssl_3.5.x/x86_64/fips:
extends: .fips extends: .fips
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
script: script:
@@ -328,7 +349,7 @@ fedora/mingw64:
-DWITH_PCAP=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. && -DUNIT_TESTING=ON .. &&
make -j$(nproc) && make -j$(nproc) &&
ctest --output-on-failure ctest --output-on-failure -E torture_rand
# Unit testing only, no client and pkd testing, because cwrap is not available # Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW # for MinGW
@@ -345,7 +366,7 @@ fedora/mingw32:
-DWITH_PCAP=ON -DWITH_PCAP=ON
-DUNIT_TESTING=ON .. && -DUNIT_TESTING=ON .. &&
make -j$(nproc) && make -j$(nproc) &&
ctest --output-on-failure ctest --output-on-failure -E torture_rand
############################################################################### ###############################################################################

View File

@@ -1,6 +1,38 @@
CHANGELOG CHANGELOG
========= =========
version 0.11.3 (released 2025-09-09)
* Security:
* CVE-2025-8114: Fix NULL pointer dereference after allocation failure
* CVE-2025-8277: Fix memory leak of ephemeral key pair during repeated wrong KEX
* Potential UAF when send() fails during key exchange
* Fix possible timeout during KEX if client sends authentication too early (#311)
* Cleanup OpenSSL PKCS#11 provider when loaded
* Zeroize buffers containing private key blobs during export
version 0.11.2 (released 2025-06-24)
* Security:
* CVE-2025-4877 - Write beyond bounds in binary to base64 conversion
* CVE-2025-4878 - Use of uninitialized variable in privatekey_from_file()
* CVE-2025-5318 - Likely read beyond bounds in sftp server handle management
* CVE-2025-5351 - Double free in functions exporting keys
* CVE-2025-5372 - ssh_kdf() returns a success code on certain failures
* CVE-2025-5449 - Likely read beyond bounds in sftp server message decoding
* CVE-2025-5987 - Invalid return code for chacha20 poly1305 with OpenSSL
* Compatibility
* Fixed compatibility with CPM.cmake
* Compatibility with OpenSSH 10.0
* Tests compatibility with new Dropbear releases
* Removed p11-kit remoting from the pkcs11 testsuite
* Bugfixes
* Implement missing packet filter for DH GEX
* Properly process the SSH2_MSG_DEBUG message
* Allow escaping quotes in quoted arguments to ssh configuration
* Do not fail with unknown match keywords in ssh configuration
* Process packets before selecting signature algorithm during authentication
* Do not fail hard when the SFTP status message is not sent by noncompliant
servers
version 0.11.1 (released 2024-08-30) version 0.11.1 (released 2024-08-30)
* Fixed default TTY modes that are set when stdin is not connected to tty (#270) * Fixed default TTY modes that are set when stdin is not connected to tty (#270)
* Fixed zlib cleanup procedure, which could crash on i386 * Fixed zlib cleanup procedure, which could crash on i386

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.12.0) cmake_minimum_required(VERSION 3.14.0)
# Specify search path for CMake modules to be loaded by include() # Specify search path for CMake modules to be loaded by include()
# and find_package() # and find_package()
@@ -9,7 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults) include(DefineCMakeDefaults)
include(DefineCompilerFlags) include(DefineCompilerFlags)
project(libssh VERSION 0.11.1 LANGUAGES C CXX) project(libssh VERSION 0.11.3 LANGUAGES C)
# global needed variable # global needed variable
set(APPLICATION_NAME ${PROJECT_NAME}) set(APPLICATION_NAME ${PROJECT_NAME})
@@ -21,7 +21,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.10.1") set(LIBRARY_VERSION "4.10.3")
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
@@ -190,6 +190,7 @@ endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
# Coverage # Coverage
if (WITH_COVERAGE) if (WITH_COVERAGE)
ENABLE_LANGUAGE(CXX)
include(CodeCoverage) include(CodeCoverage)
setup_target_for_coverage_lcov( setup_target_for_coverage_lcov(
NAME "coverage" NAME "coverage"

View File

@@ -92,9 +92,12 @@ if (UNIX)
endif (WITH_STACK_PROTECTOR_STRONG) endif (WITH_STACK_PROTECTOR_STRONG)
if (NOT WINDOWS AND NOT CYGWIN) if (NOT WINDOWS AND NOT CYGWIN)
check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION) # apple m* chips do not support this option
if (WITH_STACK_CLASH_PROTECTION) if (NOT ${CMAKE_SYSTEM_PROCESSOR} STREQUAL arm64)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection") check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION)
if (WITH_STACK_CLASH_PROTECTION)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection")
endif()
endif() endif()
endif() endif()

View File

@@ -117,6 +117,7 @@ function(ADD_CMOCKA_TEST _TARGET_NAME)
${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME} ${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME}
) )
if (WITH_COVERAGE) if (WITH_COVERAGE)
ENABLE_LANGUAGE(CXX)
include(CodeCoverage) include(CodeCoverage)
append_coverage_compiler_flags_to_target(${_TARGET_NAME}) append_coverage_compiler_flags_to_target(${_TARGET_NAME})
endif (WITH_COVERAGE) endif (WITH_COVERAGE)

View File

@@ -39,6 +39,15 @@ find_path(GCRYPT_INCLUDE_DIR
include include
) )
find_path(GCRYPT_ERROR_INCLUDE_DIR
NAMES
gpg-error.h
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
find_library(GCRYPT_LIBRARY find_library(GCRYPT_LIBRARY
NAMES NAMES
gcrypt gcrypt
@@ -56,8 +65,10 @@ find_library(GCRYPT_ERROR_LIBRARY
libgpg-error6-0 libgpg-error6-0
HINTS HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS} ${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
) )
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} ${GCRYPT_ERROR_LIBRARY}) set(GCRYPT_LIBRARIES ${GCRYPT_ERROR_LIBRARY} ${GCRYPT_LIBRARY})
if (GCRYPT_INCLUDE_DIR) if (GCRYPT_INCLUDE_DIR)
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]") file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")
@@ -83,5 +94,25 @@ else (GCRYPT_VERSION)
GCRYPT_LIBRARIES) GCRYPT_LIBRARIES)
endif (GCRYPT_VERSION) endif (GCRYPT_VERSION)
# show the GCRYPT_INCLUDE_DIRS and GCRYPT_LIBRARIES variables only in the advanced view # show the GCRYPT_INCLUDE_DIRS, GCRYPT_LIBRARIES and GCRYPT_ERROR_INCLUDE_DIR variables only in the advanced view
mark_as_advanced(GCRYPT_INCLUDE_DIR GCRYPT_LIBRARIES) mark_as_advanced(GCRYPT_INCLUDE_DIR GCRYPT_ERROR_INCLUDE_DIR GCRYPT_LIBRARIES)
if(GCRYPT_FOUND)
if(NOT TARGET libgcrypt::libgcrypt)
add_library(libgcrypt::libgcrypt UNKNOWN IMPORTED)
set_target_properties(libgcrypt::libgcrypt PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GCRYPT_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES libgcrypt::libgcrypt
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${GCRYPT_LIBRARY}")
endif()
if(NOT TARGET libgpg-error::libgpg-error)
add_library(libgpg-error::libgpg-error UNKNOWN IMPORTED)
set_target_properties(libgpg-error::libgpg-error PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GCRYPT_ERROR_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES libgpg-error::libgpg-error
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${GCRYPT_ERROR_LIBRARY}")
endif()
endif()

View File

@@ -110,3 +110,32 @@ endif (MBEDTLS_VERSION)
# show the MBEDTLS_INCLUDE_DIRS and MBEDTLS_LIBRARIES variables only in the advanced view # show the MBEDTLS_INCLUDE_DIRS and MBEDTLS_LIBRARIES variables only in the advanced view
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARIES) mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARIES)
if(MBEDTLS_FOUND)
if(NOT TARGET MbedTLS::mbedcrypto)
add_library(MbedTLS::mbedcrypto UNKNOWN IMPORTED)
set_target_properties(MbedTLS::mbedcrypto PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES MbedTLS::mbedcrypto
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${MBEDTLS_CRYPTO_LIBRARY}")
endif()
if(NOT TARGET MbedTLS::mbedx509)
add_library(MbedTLS::mbedx509 UNKNOWN IMPORTED)
set_target_properties(MbedTLS::mbedx509 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES MbedTLS::mbedx509
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${MBEDTLS_X509_LIBRARY}")
endif()
if(NOT TARGET MbedTLS::mbedtls)
add_library(MbedTLS::mbedtls UNKNOWN IMPORTED)
set_target_properties(MbedTLS::mbedtls PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES MbedTLS::mbedtls
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${MBEDTLS_LIBRARY}")
endif()
endif()

View File

@@ -105,7 +105,7 @@ Here is a small example of password authentication:
@code @code
int authenticate_password(ssh_session session) int authenticate_password(ssh_session session)
{ {
char *password; char *password = NULL;
int rc; int rc;
password = getpass("Enter your password: "); password = getpass("Enter your password: ");
@@ -218,7 +218,7 @@ int authenticate_kbdint(ssh_session session)
rc = ssh_userauth_kbdint(session, NULL, NULL); rc = ssh_userauth_kbdint(session, NULL, NULL);
while (rc == SSH_AUTH_INFO) while (rc == SSH_AUTH_INFO)
{ {
const char *name, *instruction; const char *name = NULL, *instruction = NULL;
int nprompts, iprompt; int nprompts, iprompt;
name = ssh_userauth_kbdint_getname(session); name = ssh_userauth_kbdint_getname(session);
@@ -231,7 +231,7 @@ int authenticate_kbdint(ssh_session session)
printf("%s\n", instruction); printf("%s\n", instruction);
for (iprompt = 0; iprompt < nprompts; iprompt++) for (iprompt = 0; iprompt < nprompts; iprompt++)
{ {
const char *prompt; const char *prompt = NULL;
char echo; char echo;
prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo); prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo);
@@ -251,7 +251,7 @@ int authenticate_kbdint(ssh_session session)
} }
else else
{ {
char *ptr; char *ptr = NULL;
ptr = getpass(prompt); ptr = getpass(prompt);
if (ssh_userauth_kbdint_setanswer(session, iprompt, ptr) < 0) if (ssh_userauth_kbdint_setanswer(session, iprompt, ptr) < 0)
@@ -354,7 +354,7 @@ The following example shows how to retrieve and dispose the issue banner:
int display_banner(ssh_session session) int display_banner(ssh_session session)
{ {
int rc; int rc;
char *banner; char *banner = NULL;
/* /*
*** Does not work without calling ssh_userauth_none() first *** *** Does not work without calling ssh_userauth_none() first ***

View File

@@ -22,7 +22,7 @@ a SSH session that uses this channel:
@code @code
int show_remote_files(ssh_session session) int show_remote_files(ssh_session session)
{ {
ssh_channel channel; ssh_channel channel = NULL;
int rc; int rc;
channel = ssh_channel_new(session); channel = ssh_channel_new(session);

View File

@@ -100,7 +100,7 @@ used to retrieve google's home page from the remote SSH server.
@code @code
int direct_forwarding(ssh_session session) int direct_forwarding(ssh_session session)
{ {
ssh_channel forwarding_channel; ssh_channel forwarding_channel = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n"; char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
int nbytes, nwritten; int nbytes, nwritten;
@@ -161,7 +161,7 @@ local libssh application, which handles them:
int web_server(ssh_session session) int web_server(ssh_session session)
{ {
int rc; int rc;
ssh_channel channel; ssh_channel channel = NULL;
char buffer[256]; char buffer[256];
int nbytes, nwritten; int nbytes, nwritten;
int port = 0; int port = 0;

View File

@@ -79,7 +79,7 @@ Here is a small example of how to use it:
int main() int main()
{ {
ssh_session my_ssh_session; ssh_session my_ssh_session = NULL;
int verbosity = SSH_LOG_PROTOCOL; int verbosity = SSH_LOG_PROTOCOL;
int port = 22; int port = 22;
@@ -126,7 +126,7 @@ Here's an example:
int main() int main()
{ {
ssh_session my_ssh_session; ssh_session my_ssh_session = NULL;
int rc; int rc;
my_ssh_session = ssh_new(); my_ssh_session = ssh_new();
@@ -190,8 +190,8 @@ int verify_knownhost(ssh_session session)
ssh_key srv_pubkey = NULL; ssh_key srv_pubkey = NULL;
size_t hlen; size_t hlen;
char buf[10]; char buf[10];
char *hexa; char *hexa = NULL;
char *p; char *p = NULL;
int cmp; int cmp;
int rc; int rc;
@@ -317,9 +317,9 @@ The example below shows an authentication with password:
int main() int main()
{ {
ssh_session my_ssh_session; ssh_session my_ssh_session = NULL;
int rc; int rc;
char *password; char *password = NULL;
// Open session and set options // Open session and set options
my_ssh_session = ssh_new(); my_ssh_session = ssh_new();
@@ -380,7 +380,7 @@ The example below shows how to execute a remote command:
@code @code
int show_remote_processes(ssh_session session) int show_remote_processes(ssh_session session)
{ {
ssh_channel channel; ssh_channel channel = NULL;
int rc; int rc;
char buffer[256]; char buffer[256];
int nbytes; int nbytes;

View File

@@ -81,10 +81,6 @@ We recommend the users to provide a specific PKCS #11 URI so that it matches onl
If the engine discovers multiple slots that could potentially contain the private keys referenced If the engine discovers multiple slots that could potentially contain the private keys referenced
by the provided PKCS #11 URI, the engine will not try to authenticate. by the provided PKCS #11 URI, the engine will not try to authenticate.
For testing, the SoftHSM PKCS#11 library is used. But it has some issues with For testing, the SoftHSM PKCS#11 library is used.
OpenSSL initialization/cleanup when used with OpenSSL 3.0 so we are using it
indirectly through a p11-kit remoting as described in the following article:
https://p11-glue.github.io/p11-glue/p11-kit/manual/remoting.html
*/ */

View File

@@ -26,7 +26,7 @@ The code sample below achieves these tasks:
@code @code
int shell_session(ssh_session session) int shell_session(ssh_session session)
{ {
ssh_channel channel; ssh_channel channel = NULL;
int rc; int rc;
channel = ssh_channel_new(session); channel = ssh_channel_new(session);

View File

@@ -30,8 +30,8 @@ int authenticate_kbdint(ssh_session session, const char *password)
err = ssh_userauth_kbdint(session, NULL, NULL); err = ssh_userauth_kbdint(session, NULL, NULL);
while (err == SSH_AUTH_INFO) { while (err == SSH_AUTH_INFO) {
const char *instruction; const char *instruction = NULL;
const char *name; const char *name = NULL;
char buffer[128]; char buffer[128];
int i, n; int i, n;
@@ -48,8 +48,8 @@ int authenticate_kbdint(ssh_session session, const char *password)
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
const char *answer; const char *answer = NULL;
const char *prompt; const char *prompt = NULL;
char echo; char echo;
prompt = ssh_userauth_kbdint_getprompt(session, i, &echo); prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
@@ -58,7 +58,7 @@ int authenticate_kbdint(ssh_session session, const char *password)
} }
if (echo) { if (echo) {
char *p; char *p = NULL;
printf("%s", prompt); printf("%s", prompt);
@@ -143,7 +143,7 @@ int authenticate_console(ssh_session session)
int rc; int rc;
int method; int method;
char password[128] = {0}; char password[128] = {0};
char *banner; char *banner = NULL;
// Try to authenticate // Try to authenticate
rc = ssh_userauth_none(session, NULL); rc = ssh_userauth_none(session, NULL);

View File

@@ -22,7 +22,7 @@ clients must be made or how a client should react.
#include <stdio.h> #include <stdio.h>
ssh_session connect_ssh(const char *host, const char *user,int verbosity){ ssh_session connect_ssh(const char *host, const char *user,int verbosity){
ssh_session session; ssh_session session = NULL;
int auth=0; int auth=0;
session=ssh_new(); session=ssh_new();

View File

@@ -5,8 +5,8 @@
#include "examples_common.h" #include "examples_common.h"
int main(void) { int main(void) {
ssh_session session; ssh_session session = NULL;
ssh_channel channel; ssh_channel channel = NULL;
char buffer[256]; char buffer[256];
int rbytes, wbytes, total = 0; int rbytes, wbytes, total = 0;
int rc; int rc;

View File

@@ -38,7 +38,7 @@ int verify_knownhost(ssh_session session)
char buf[10]; char buf[10];
unsigned char *hash = NULL; unsigned char *hash = NULL;
size_t hlen; size_t hlen;
ssh_key srv_pubkey; ssh_key srv_pubkey = NULL;
int rc; int rc;
rc = ssh_get_server_publickey(session, &srv_pubkey); rc = ssh_get_server_publickey(session, &srv_pubkey);

View File

@@ -26,9 +26,9 @@ program.
#define BUF_SIZE 16384 #define BUF_SIZE 16384
#endif #endif
static char **sources; static char **sources = NULL;
static int nsources; static int nsources;
static char *destination; static char *destination = NULL;
static int verbosity = 0; static int verbosity = 0;
struct location { struct location {
@@ -114,9 +114,10 @@ static void location_free(struct location *loc)
} }
} }
static struct location *parse_location(char *loc) { static struct location *parse_location(char *loc)
struct location *location; {
char *ptr; struct location *location = NULL;
char *ptr = NULL;
location = malloc(sizeof(struct location)); location = malloc(sizeof(struct location));
if (location == NULL) { if (location == NULL) {

View File

@@ -35,8 +35,8 @@ clients must be made or how a client should react.
static int authenticated=0; static int authenticated=0;
static int tries = 0; static int tries = 0;
static int error = 0; static int error = 0;
static ssh_channel chan=NULL; static ssh_channel chan = NULL;
static char *username; static char *username = NULL;
static ssh_gssapi_creds client_creds = NULL; static ssh_gssapi_creds client_creds = NULL;
static int auth_password(ssh_session session, const char *user, static int auth_password(ssh_session session, const char *user,
@@ -204,11 +204,12 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL}; static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */ #endif /* HAVE_ARGP_H */
int main(int argc, char **argv){ int main(int argc, char **argv)
ssh_session session; {
ssh_bind sshbind; ssh_session session = NULL;
ssh_event mainloop; ssh_bind sshbind = NULL;
ssh_session client_session; ssh_event mainloop = NULL;
ssh_session client_session = NULL;
struct ssh_server_callbacks_struct cb = { struct ssh_server_callbacks_struct cb = {
.userdata = NULL, .userdata = NULL,
@@ -219,7 +220,7 @@ int main(int argc, char **argv){
char buf[BUF_SIZE]; char buf[BUF_SIZE];
char host[128]=""; char host[128]="";
char *ptr; char *ptr = NULL;
int i,r, rc; int i,r, rc;
sshbind=ssh_bind_new(); sshbind=ssh_bind_new();
@@ -336,4 +337,3 @@ int main(int argc, char **argv){
ssh_finalize(); ssh_finalize();
return 0; return 0;
} }

View File

@@ -244,10 +244,11 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL}; static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */ #endif /* HAVE_ARGP_H */
int main(int argc, char **argv){ int main(int argc, char **argv)
ssh_session session; {
ssh_bind sshbind; ssh_session session = NULL;
ssh_event mainloop; ssh_bind sshbind = NULL;
ssh_event mainloop = NULL;
struct ssh_server_callbacks_struct cb = { struct ssh_server_callbacks_struct cb = {
.userdata = NULL, .userdata = NULL,
.auth_none_function = auth_none, .auth_none_function = auth_none,
@@ -339,4 +340,3 @@ int main(int argc, char **argv){
ssh_finalize(); ssh_finalize();
return 0; return 0;
} }

View File

@@ -174,8 +174,8 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL}; static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */ #endif /* HAVE_ARGP_H */
static const char *name; static const char *name = NULL;
static const char *instruction; static const char *instruction = NULL;
static const char *prompts[2]; static const char *prompts[2];
static char echo[] = { 1, 0 }; static char echo[] = { 1, 0 };
@@ -279,11 +279,12 @@ static int authenticate(ssh_session session) {
return 0; return 0;
} }
int main(int argc, char **argv){ int main(int argc, char **argv)
ssh_session session; {
ssh_bind sshbind; ssh_session session = NULL;
ssh_message message; ssh_bind sshbind = NULL;
ssh_channel chan=0; ssh_message message = NULL;
ssh_channel chan = NULL;
char buf[BUF_SIZE]; char buf[BUF_SIZE];
int auth=0; int auth=0;
int shell=0; int shell=0;
@@ -411,4 +412,3 @@ int main(int argc, char **argv){
ssh_finalize(); ssh_finalize();
return 0; return 0;
} }

View File

@@ -108,7 +108,7 @@ static int fetch_files(ssh_session session){
int size; int size;
char buffer[BUF_SIZE]; char buffer[BUF_SIZE];
int mode; int mode;
char *filename; char *filename = NULL;
int r; int r;
ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*"); ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*");
if(ssh_scp_init(scp) != SSH_OK){ if(ssh_scp_init(scp) != SSH_OK){
@@ -167,7 +167,7 @@ static int fetch_files(ssh_session session){
} }
int main(int argc, char **argv){ int main(int argc, char **argv){
ssh_session session; ssh_session session = NULL;
if(opts(argc,argv)<0) if(opts(argc,argv)<0)
return EXIT_FAILURE; return EXIT_FAILURE;
session=connect_ssh(host,NULL,verbosity); session=connect_ssh(host,NULL,verbosity);

View File

@@ -6,7 +6,7 @@
#define LIMIT 0x100000000UL #define LIMIT 0x100000000UL
int main(void) { int main(void) {
ssh_session session; ssh_session session = NULL;
ssh_channel channel; ssh_channel channel;
char buffer[1024*1024]; char buffer[1024*1024];
int rc; int rc;
@@ -47,7 +47,7 @@ int main(void) {
if(total > LIMIT) if(total > LIMIT)
break; break;
} }
if (rc < 0) { if (rc < 0) {
printf("error : %s\n",ssh_get_error(session)); printf("error : %s\n",ssh_get_error(session));
ssh_channel_close(channel); ssh_channel_close(channel);

View File

@@ -70,6 +70,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h>
#include <poll.h> #include <poll.h>
#include <pthread.h> #include <pthread.h>
#include <stddef.h> #include <stddef.h>
@@ -231,7 +232,7 @@ static void _logging_callback(int priority, const char *function,
milliseconds = _current_timestamp(); milliseconds = _current_timestamp();
fprintf(fp, "[%s.%jd, %d] %s: %s\n", buf, milliseconds, priority, fprintf(fp, "[%s.%" PRId64 ", %d] %s: %s\n", buf, milliseconds, priority,
function, buffer); function, buffer);
fclose(fp); fclose(fp);
} }

View File

@@ -53,7 +53,7 @@ static struct termios terminal;
static char *pcap_file = NULL; static char *pcap_file = NULL;
static char *proxycommand; static char *proxycommand = NULL;
static int auth_callback(const char *prompt, static int auth_callback(const char *prompt,
char *buf, char *buf,
@@ -251,7 +251,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
static void shell(ssh_session session) static void shell(ssh_session session)
{ {
ssh_channel channel; ssh_channel channel = NULL;
struct termios terminal_local; struct termios terminal_local;
int interactive=isatty(0); int interactive=isatty(0);
@@ -339,7 +339,7 @@ static void batch_shell(ssh_session session)
static int client(ssh_session session) static int client(ssh_session session)
{ {
int auth = 0; int auth = 0;
char *banner; char *banner = NULL;
int state; int state;
if (user) { if (user) {
@@ -423,7 +423,7 @@ static void cleanup_pcap(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
ssh_session session; ssh_session session = NULL;
ssh_init(); ssh_init();
session = ssh_new(); session = ssh_new();

View File

@@ -361,7 +361,7 @@ my_fd_data_function(UNUSED_PARAM(socket_t fd),
{ {
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata; struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
ssh_channel channel = event_fd_data->channel; ssh_channel channel = event_fd_data->channel;
ssh_session session; ssh_session session = NULL;
int len, i, wr; int len, i, wr;
char buf[BUF_SIZE]; char buf[BUF_SIZE];
int blocking; int blocking;
@@ -455,8 +455,8 @@ open_tcp_socket(ssh_message msg)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
int forwardsock = -1; int forwardsock = -1;
struct hostent *host; struct hostent *host = NULL;
const char *dest_hostname; const char *dest_hostname = NULL;
int dest_port; int dest_port;
forwardsock = socket(AF_INET, SOCK_STREAM, 0); forwardsock = socket(AF_INET, SOCK_STREAM, 0);
@@ -499,8 +499,8 @@ message_callback(UNUSED_PARAM(ssh_session session),
UNUSED_PARAM(void *userdata)) UNUSED_PARAM(void *userdata))
{ {
ssh_channel channel; ssh_channel channel;
int socket_fd, *pFd; int socket_fd, *pFd = NULL;
struct ssh_channel_callbacks_struct *cb_chan; struct ssh_channel_callbacks_struct *cb_chan = NULL;
struct event_fd_data_struct *event_fd_data; struct event_fd_data_struct *event_fd_data;
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d", _ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d",
@@ -655,8 +655,8 @@ static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
ssh_session session; ssh_session session = NULL;
ssh_bind sshbind; ssh_bind sshbind = NULL;
struct ssh_server_callbacks_struct cb = { struct ssh_server_callbacks_struct cb = {
.userdata = NULL, .userdata = NULL,
.auth_password_function = auth_password, .auth_password_function = auth_password,

View File

@@ -39,7 +39,7 @@ clients must be made or how a client should react.
#define BUF_SIZE 4096 #define BUF_SIZE 4096
#endif #endif
char *host; char *host = NULL;
const char *desthost="localhost"; const char *desthost="localhost";
const char *port="22"; const char *port="22";
@@ -193,7 +193,7 @@ static void forwarding(ssh_session session){
static int client(ssh_session session){ static int client(ssh_session session){
int auth=0; int auth=0;
char *banner; char *banner = NULL;
int state; int state;
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
@@ -246,7 +246,7 @@ void cleanup_pcap(void)
#endif #endif
int main(int argc, char **argv){ int main(int argc, char **argv){
ssh_session session; ssh_session session = NULL;
session = ssh_new(); session = ssh_new();

View File

@@ -223,9 +223,8 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
size_t requested_len); size_t requested_len);
int secure_memcmp(const void *s1, const void *s2, size_t n); int secure_memcmp(const void *s1, const void *s2, size_t n);
#if defined(HAVE_LIBCRYPTO) && !defined(WITH_PKCS11_PROVIDER)
ENGINE *pki_get_engine(void); void compress_cleanup(struct ssh_crypto_struct *crypto);
#endif /* HAVE_LIBCRYPTO */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -121,6 +121,15 @@ typedef BN_CTX* bignum_CTX;
ssh_string pki_key_make_ecpoint_string(const EC_GROUP *g, const EC_POINT *p); ssh_string pki_key_make_ecpoint_string(const EC_GROUP *g, const EC_POINT *p);
int pki_key_ecgroup_name_to_nid(const char *group); int pki_key_ecgroup_name_to_nid(const char *group);
#if defined(WITH_PKCS11_URI)
#if defined(WITH_PKCS11_PROVIDER)
int pki_load_pkcs11_provider(void);
#else
ENGINE *pki_get_engine(void);
#endif
#endif /* WITH_PKCS11_PROVIDER */
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
#endif /* LIBCRYPTO_H_ */ #endif /* LIBCRYPTO_H_ */

View File

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

View File

@@ -58,6 +58,7 @@ extern "C" {
SSH_PACKET_CALLBACK(ssh_packet_unimplemented); SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback); SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback); SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
SSH_PACKET_CALLBACK(ssh_packet_debug_callback);
SSH_PACKET_CALLBACK(ssh_packet_dh_reply); SSH_PACKET_CALLBACK(ssh_packet_dh_reply);
SSH_PACKET_CALLBACK(ssh_packet_newkeys); SSH_PACKET_CALLBACK(ssh_packet_newkeys);
SSH_PACKET_CALLBACK(ssh_packet_service_accept); SSH_PACKET_CALLBACK(ssh_packet_service_accept);

View File

@@ -157,6 +157,7 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx);
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p); int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p);
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s); int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s);
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p); void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p);
bool ssh_poll_is_locked(ssh_poll_handle p);
int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout); int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout);
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session); ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session);
int ssh_event_add_poll(ssh_event event, ssh_poll_handle p); int ssh_event_add_poll(ssh_event event, ssh_poll_handle p);

View File

@@ -384,6 +384,7 @@ void explicit_bzero(void *s, size_t n);
*/ */
#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
#ifndef __VA_NARG__
/** /**
* Get the argument count of variadic arguments * Get the argument count of variadic arguments
*/ */
@@ -415,6 +416,7 @@ void explicit_bzero(void *s, size_t n);
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#endif
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0) #define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)

View File

@@ -29,6 +29,10 @@ extern "C" {
#endif #endif
#include <stdint.h> #include <stdint.h>
#include "libssh/libssh.h"
#include "libssh/sftp.h"
/** /**
* @defgroup libssh_sftp_server The libssh SFTP server API * @defgroup libssh_sftp_server The libssh SFTP server API
* *

View File

@@ -1 +1 @@
4.10.1 4.10.3

View File

@@ -0,0 +1,445 @@
_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_aio_begin_read
sftp_aio_begin_write
sftp_aio_free
sftp_aio_wait_read
sftp_aio_wait_write
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_channel_default_data_callback
sftp_channel_default_subsystem_request
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_expand_path
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_hardlink
sftp_home_directory
sftp_init
sftp_limits
sftp_limits_free
sftp_lsetstat
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_state
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_port
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_pty_size_modes
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_dup
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_base64_format
ssh_pki_export_privkey_file
ssh_pki_export_privkey_file_format
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_request_no_more_sessions
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_issue_banner
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_set_disconnect_message
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_publickey_auto_get_current_identity
ssh_userauth_try_publickey
ssh_version
ssh_vlog
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,445 @@
_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_aio_begin_read
sftp_aio_begin_write
sftp_aio_free
sftp_aio_wait_read
sftp_aio_wait_write
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_channel_default_data_callback
sftp_channel_default_subsystem_request
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_expand_path
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_hardlink
sftp_home_directory
sftp_init
sftp_limits
sftp_limits_free
sftp_lsetstat
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_free
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_parse_config
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_state
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_forward_port
ssh_channel_open_forward_unix
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_pty_size_modes
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_dup
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_open_reply_accept_channel
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_base64_format
ssh_pki_export_privkey_file
ssh_pki_export_privkey_file_format
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_request_no_more_sessions
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_issue_banner
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_get_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_set_disconnect_message
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_default
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_publickey_auto_get_current_identity
ssh_userauth_try_publickey
ssh_version
ssh_vlog
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

@@ -1,6 +1,7 @@
set(LIBSSH_PUBLIC_INCLUDE_DIRS ${libssh_SOURCE_DIR}/include) set(LIBSSH_PUBLIC_INCLUDE_DIRS ${libssh_SOURCE_DIR}/include)
set(LIBSSH_PRIVATE_INCLUDE_DIRS set(LIBSSH_PRIVATE_INCLUDE_DIRS
${libssh_BINARY_DIR}/include
${libssh_BINARY_DIR} ${libssh_BINARY_DIR}
) )
@@ -12,27 +13,13 @@ if (TARGET OpenSSL::Crypto)
list(APPEND LIBSSH_LINK_LIBRARIES OpenSSL::Crypto) list(APPEND LIBSSH_LINK_LIBRARIES OpenSSL::Crypto)
endif () endif ()
if (MBEDTLS_CRYPTO_LIBRARY) if (TARGET MbedTLS::mbedcrypto)
set(LIBSSH_PRIVATE_INCLUDE_DIRS list(APPEND LIBSSH_LINK_LIBRARIES MbedTLS::mbedcrypto)
${LIBSSH_PRIVATE_INCLUDE_DIRS} endif ()
${MBEDTLS_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${MBEDTLS_CRYPTO_LIBRARY}
)
endif (MBEDTLS_CRYPTO_LIBRARY)
if (GCRYPT_LIBRARIES) if (TARGET libgcrypt::libgcrypt)
set(LIBSSH_PRIVATE_INCLUDE_DIRS list(APPEND LIBSSH_LINK_LIBRARIES ${GCRYPT_LIBRARIES})
${LIBSSH_PRIVATE_INCLUDE_DIRS} endif ()
${GCRYPT_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${GCRYPT_LIBRARIES})
endif()
if (WITH_ZLIB) if (WITH_ZLIB)
list(APPEND LIBSSH_LINK_LIBRARIES ZLIB::ZLIB) list(APPEND LIBSSH_LINK_LIBRARIES ZLIB::ZLIB)
@@ -104,6 +91,7 @@ set(libssh_SRCS
ecdh.c ecdh.c
error.c error.c
getpass.c getpass.c
gzip.c
init.c init.c
kdf.c kdf.c
kex.c kex.c
@@ -265,13 +253,6 @@ if (WITH_GEX)
) )
endif (WITH_GEX) endif (WITH_GEX)
if (WITH_ZLIB)
set(libssh_SRCS
${libssh_SRCS}
gzip.c
)
endif(WITH_ZLIB)
if (WITH_GSSAPI AND GSSAPI_FOUND) if (WITH_GSSAPI AND GSSAPI_FOUND)
set(libssh_SRCS set(libssh_SRCS
${libssh_SRCS} ${libssh_SRCS}

View File

@@ -422,8 +422,9 @@ ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
/* caller has to free comment */ /* caller has to free comment */
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session, ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
char **comment) { char **comment)
struct ssh_key_struct *key; {
struct ssh_key_struct *key = NULL;
struct ssh_string_struct *blob = NULL; struct ssh_string_struct *blob = NULL;
struct ssh_string_struct *tmp = NULL; struct ssh_string_struct *tmp = NULL;
int rc; int rc;
@@ -492,10 +493,10 @@ ssh_string ssh_agent_sign_data(ssh_session session,
const ssh_key pubkey, const ssh_key pubkey,
struct ssh_buffer_struct *data) struct ssh_buffer_struct *data)
{ {
ssh_buffer request; ssh_buffer request = NULL;
ssh_buffer reply; ssh_buffer reply = NULL;
ssh_string key_blob; ssh_string key_blob = NULL;
ssh_string sig_blob; ssh_string sig_blob = NULL;
unsigned int type = 0; unsigned int type = 0;
unsigned int flags = 0; unsigned int flags = 0;
uint32_t dlen; uint32_t dlen;

View File

@@ -195,8 +195,9 @@ static int ssh_userauth_get_response(ssh_session session)
* *
* This banner should be shown to user prior to authentication * This banner should be shown to user prior to authentication
*/ */
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner) { SSH_PACKET_CALLBACK(ssh_packet_userauth_banner)
ssh_string banner; {
ssh_string banner = NULL;
(void)type; (void)type;
(void)user; (void)user;
@@ -521,6 +522,17 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* Check if the given public key algorithm is allowed */ /* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type); sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) { if (sig_type_c == NULL) {
@@ -544,13 +556,6 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* public key */ /* public key */
rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s); rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s);
if (rc < 0) { if (rc < 0) {
@@ -652,6 +657,17 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */ /* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type; key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
@@ -678,13 +694,6 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* get public key or cert */ /* get public key or cert */
rc = ssh_pki_export_pubkey_blob(privkey, &str); rc = ssh_pki_export_pubkey_blob(privkey, &str);
if (rc < 0) { if (rc < 0) {
@@ -769,6 +778,10 @@ static int ssh_userauth_agent_publickey(ssh_session session,
return SSH_ERROR; return SSH_ERROR;
} }
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session); rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) { if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN; return SSH_AUTH_AGAIN;
@@ -1682,7 +1695,7 @@ int ssh_userauth_agent_pubkey(ssh_session session,
const char *username, const char *username,
ssh_public_key publickey) ssh_public_key publickey)
{ {
ssh_key key; ssh_key key = NULL;
int rc; int rc;
key = ssh_key_new(); key = ssh_key_new();

View File

@@ -29,6 +29,9 @@
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/buffer.h" #include "libssh/buffer.h"
/* Do not allow encoding more than 256MB of data */
#define BASE64_MAX_INPUT_LEN 256 * 1024 * 1024
static static
const uint8_t alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" const uint8_t alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"
@@ -278,7 +281,15 @@ uint8_t *bin_to_base64(const uint8_t *source, size_t len)
{ {
uint8_t *base64 = NULL; uint8_t *base64 = NULL;
uint8_t *ptr = NULL; uint8_t *ptr = NULL;
size_t flen = len + (3 - (len % 3)); /* round to upper 3 multiple */ size_t flen = 0;
/* Set the artificial upper limit for the input. Otherwise on 32b arch, the
* following line could overflow for sizes larger than SIZE_MAX / 4 */
if (len > BASE64_MAX_INPUT_LEN) {
return NULL;
}
flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
flen = (4 * flen) / 3 + 1; flen = (4 * flen) / 3 + 1;
base64 = malloc(flen); base64 = malloc(flen);

View File

@@ -74,7 +74,7 @@
static socket_t bind_socket(ssh_bind sshbind, const char *hostname, static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
int port) { int port) {
char port_c[6]; char port_c[6];
struct addrinfo *ai; struct addrinfo *ai = NULL;
struct addrinfo hints; struct addrinfo hints;
int opt = 1; int opt = 1;
socket_t s; socket_t s;
@@ -132,8 +132,9 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
return s; return s;
} }
ssh_bind ssh_bind_new(void) { ssh_bind ssh_bind_new(void)
ssh_bind ptr; {
ssh_bind ptr = NULL;
ptr = calloc(1, sizeof(struct ssh_bind_struct)); ptr = calloc(1, sizeof(struct ssh_bind_struct));
if (ptr == NULL) { if (ptr == NULL) {
@@ -218,7 +219,7 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
} }
int ssh_bind_listen(ssh_bind sshbind) { int ssh_bind_listen(ssh_bind sshbind) {
const char *host; const char *host = NULL;
socket_t fd; socket_t fd;
int rc; int rc;
@@ -462,7 +463,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
return SSH_ERROR; return SSH_ERROR;
} }
} else { } else {
char *p; char *p = NULL;
/* If something was set to the session prior to calling this /* If something was set to the session prior to calling this
* function, keep only what is allowed by the options set in * function, keep only what is allowed by the options set in
* sshbind */ * sshbind */

View File

@@ -200,7 +200,7 @@ local_parse_file(ssh_bind bind,
uint8_t *seen, uint8_t *seen,
unsigned int depth) unsigned int depth)
{ {
FILE *f; FILE *f = NULL;
char line[MAX_LINE_SIZE] = {0}; char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0; unsigned int count = 0;
int rv; int rv;
@@ -626,7 +626,7 @@ int ssh_bind_config_parse_file(ssh_bind bind, const char *filename)
{ {
char line[MAX_LINE_SIZE] = {0}; char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0; unsigned int count = 0;
FILE *f; FILE *f = NULL;
uint32_t parser_flags; uint32_t parser_flags;
int rv; int rv;

View File

@@ -371,7 +371,8 @@ int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer,
*/ */
void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len) void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len)
{ {
void *ptr; void *ptr = NULL;
buffer_verify(buffer); buffer_verify(buffer);
if (buffer->used + len < len) { if (buffer->used + len < len) {
@@ -852,7 +853,7 @@ static int ssh_buffer_pack_allocate_va(struct ssh_buffer_struct *buffer,
break; break;
case 'S': case 'S':
string = va_arg(ap, ssh_string); string = va_arg(ap, ssh_string);
needed_size += 4 + ssh_string_len(string); needed_size += sizeof(uint32_t) + ssh_string_len(string);
string = NULL; string = NULL;
break; break;
case 's': case 's':
@@ -926,7 +927,7 @@ ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
va_list ap) va_list ap)
{ {
int rc = SSH_ERROR; int rc = SSH_ERROR;
const char *p; const char *p = NULL;
union { union {
uint8_t byte; uint8_t byte;
uint16_t word; uint16_t word;
@@ -935,7 +936,7 @@ ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
ssh_string string; ssh_string string;
void *data; void *data;
} o; } o;
char *cstring; char *cstring = NULL;
bignum b; bignum b;
size_t len; size_t len;
size_t count; size_t count;
@@ -1094,7 +1095,7 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
va_list ap) va_list ap)
{ {
int rc = SSH_ERROR; int rc = SSH_ERROR;
const char *p = format, *last; const char *p = format, *last = NULL;
union { union {
uint8_t *byte; uint8_t *byte;
uint16_t *word; uint16_t *word;

View File

@@ -122,7 +122,7 @@ int ssh_add_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb)
int ssh_remove_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb) int ssh_remove_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb)
{ {
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
if (channel == NULL || channel->callbacks == NULL){ if (channel == NULL || channel->callbacks == NULL){
return SSH_ERROR; return SSH_ERROR;

View File

@@ -42,7 +42,7 @@ static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher,
void *key, void *key,
void *IV) void *IV)
{ {
struct chacha20_poly1305_keysched *sched; struct chacha20_poly1305_keysched *sched = NULL;
uint8_t *u8key = key; uint8_t *u8key = key;
(void)IV; (void)IV;

View File

@@ -168,7 +168,7 @@ uint32_t ssh_channel_new_id(ssh_session session)
*/ */
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
uint32_t channelid=0; uint32_t channelid=0;
ssh_channel channel; ssh_channel channel = NULL;
int rc; int rc;
(void)type; (void)type;
(void)user; (void)user;
@@ -237,7 +237,7 @@ error:
*/ */
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
ssh_channel channel; ssh_channel channel = NULL;
char *error = NULL; char *error = NULL;
uint32_t code; uint32_t code;
int rc; int rc;
@@ -405,7 +405,7 @@ end:
/* return channel with corresponding local id, or NULL if not found */ /* return channel with corresponding local id, or NULL if not found */
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) { ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id) {
struct ssh_iterator *it; struct ssh_iterator *it;
ssh_channel channel; ssh_channel channel = NULL;
for (it = ssh_list_get_iterator(session->channels); it != NULL ; it=it->next) { for (it = ssh_list_get_iterator(session->channels); it != NULL ; it=it->next) {
channel = ssh_iterator_value(ssh_channel, it); channel = ssh_iterator_value(ssh_channel, it);
@@ -501,7 +501,7 @@ error:
*/ */
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet)
{ {
ssh_channel channel; ssh_channel channel = NULL;
uint32_t chan; uint32_t chan;
int rc; int rc;
@@ -523,7 +523,7 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet)
} }
SSH_PACKET_CALLBACK(channel_rcv_change_window) { SSH_PACKET_CALLBACK(channel_rcv_change_window) {
ssh_channel channel; ssh_channel channel = NULL;
uint32_t bytes; uint32_t bytes;
int rc; int rc;
bool was_empty; bool was_empty;
@@ -694,7 +694,7 @@ SSH_PACKET_CALLBACK(channel_rcv_data)
} }
SSH_PACKET_CALLBACK(channel_rcv_eof) { SSH_PACKET_CALLBACK(channel_rcv_eof) {
ssh_channel channel; ssh_channel channel = NULL;
(void)user; (void)user;
(void)type; (void)type;
@@ -738,8 +738,9 @@ static bool ssh_channel_has_unread_data(ssh_channel channel)
return false; return false;
} }
SSH_PACKET_CALLBACK(channel_rcv_close) { SSH_PACKET_CALLBACK(channel_rcv_close)
ssh_channel channel; {
ssh_channel channel = NULL;
(void)user; (void)user;
(void)type; (void)type;
@@ -980,7 +981,7 @@ int channel_default_bufferize(ssh_channel channel,
void *data, uint32_t len, void *data, uint32_t len,
bool is_stderr) bool is_stderr)
{ {
ssh_session session; ssh_session session = NULL;
if(channel == NULL) { if(channel == NULL) {
return -1; return -1;
@@ -1119,7 +1120,7 @@ int ssh_channel_open_auth_agent(ssh_channel channel)
int ssh_channel_open_forward(ssh_channel channel, const char *remotehost, int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport) int remoteport, const char *sourcehost, int localport)
{ {
ssh_session session; ssh_session session = NULL;
ssh_buffer payload = NULL; ssh_buffer payload = NULL;
ssh_string str = NULL; ssh_string str = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
@@ -1257,7 +1258,7 @@ error:
*/ */
void ssh_channel_free(ssh_channel channel) void ssh_channel_free(ssh_channel channel)
{ {
ssh_session session; ssh_session session = NULL;
if (channel == NULL) { if (channel == NULL) {
return; return;
@@ -1290,6 +1291,11 @@ void ssh_channel_free(ssh_channel channel)
} }
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL; channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
if (channel->callbacks != NULL) {
ssh_list_free(channel->callbacks);
channel->callbacks = NULL;
}
/* The idea behind the flags is the following : it is well possible /* The idea behind the flags is the following : it is well possible
* that a client closes a channel that still exists on the server side. * that a client closes a channel that still exists on the server side.
* We definitively close the channel when we receive a close message *and* * We definitively close the channel when we receive a close message *and*
@@ -1359,7 +1365,7 @@ void ssh_channel_do_free(ssh_channel channel)
*/ */
int ssh_channel_send_eof(ssh_channel channel) int ssh_channel_send_eof(ssh_channel channel)
{ {
ssh_session session; ssh_session session = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
int err; int err;
@@ -1420,7 +1426,7 @@ error:
*/ */
int ssh_channel_close(ssh_channel channel) int ssh_channel_close(ssh_channel channel)
{ {
ssh_session session; ssh_session session = NULL;
int rc = 0; int rc = 0;
if(channel == NULL) { if(channel == NULL) {
@@ -1516,7 +1522,7 @@ static int channel_write_common(ssh_channel channel,
const void *data, const void *data,
uint32_t len, int is_stderr) uint32_t len, int is_stderr)
{ {
ssh_session session; ssh_session session = NULL;
uint32_t origlen = len; uint32_t origlen = len;
size_t effectivelen; size_t effectivelen;
int rc; int rc;
@@ -1616,7 +1622,8 @@ static int channel_write_common(ssh_channel channel,
rc = ssh_buffer_pack(session->out_buffer, rc = ssh_buffer_pack(session->out_buffer,
"dP", "dP",
effectivelen, effectivelen,
(size_t)effectivelen, data); (size_t)effectivelen,
data);
if (rc != SSH_OK) { if (rc != SSH_OK) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
goto error; goto error;
@@ -1771,7 +1778,7 @@ void ssh_channel_set_blocking(ssh_channel channel, int blocking)
* @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state. * @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state.
*/ */
SSH_PACKET_CALLBACK(ssh_packet_channel_success){ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
ssh_channel channel; ssh_channel channel = NULL;
(void)type; (void)type;
(void)user; (void)user;
@@ -1807,7 +1814,7 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
* @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state. * @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state.
*/ */
SSH_PACKET_CALLBACK(ssh_packet_channel_failure){ SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
ssh_channel channel; ssh_channel channel = NULL;
(void)type; (void)type;
(void)user; (void)user;
@@ -1956,7 +1963,7 @@ error:
int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *terminal, int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *terminal,
int col, int row, const unsigned char* modes, size_t modes_len) int col, int row, const unsigned char* modes, size_t modes_len)
{ {
ssh_session session; ssh_session session = NULL;
ssh_buffer buffer = NULL; ssh_buffer buffer = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
@@ -1991,7 +1998,8 @@ int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *terminal
0, /* pix */ 0, /* pix */
0, /* pix */ 0, /* pix */
(uint32_t)modes_len, (uint32_t)modes_len,
modes_len, modes); (size_t)modes_len,
modes);
if (rc != SSH_OK) { if (rc != SSH_OK) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
@@ -2284,7 +2292,7 @@ static ssh_channel ssh_channel_accept(ssh_session session, int channeltype,
#endif #endif
ssh_message msg = NULL; ssh_message msg = NULL;
ssh_channel channel = NULL; ssh_channel channel = NULL;
struct ssh_iterator *iterator; struct ssh_iterator *iterator = NULL;
int t; int t;
/* /*
@@ -2947,7 +2955,7 @@ error:
int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count, int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
int is_stderr) int is_stderr)
{ {
ssh_session session; ssh_session session = NULL;
char *buffer_tmp = NULL; char *buffer_tmp = NULL;
int r; int r;
uint32_t total=0; uint32_t total=0;
@@ -3083,7 +3091,7 @@ int ssh_channel_read_timeout(ssh_channel channel,
int is_stderr, int is_stderr,
int timeout_ms) int timeout_ms)
{ {
ssh_session session; ssh_session session = NULL;
ssh_buffer stdbuf; ssh_buffer stdbuf;
uint32_t len; uint32_t len;
struct ssh_channel_read_termination_struct ctx; struct ssh_channel_read_termination_struct ctx;
@@ -3193,7 +3201,7 @@ int ssh_channel_read_nonblocking(ssh_channel channel,
uint32_t count, uint32_t count,
int is_stderr) int is_stderr)
{ {
ssh_session session; ssh_session session = NULL;
uint32_t to_read; uint32_t to_read;
int rc; int rc;
int blocking; int blocking;
@@ -3305,8 +3313,8 @@ int ssh_channel_poll(ssh_channel channel, int is_stderr)
*/ */
int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr) int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr)
{ {
ssh_session session; ssh_session session = NULL;
ssh_buffer stdbuf; ssh_buffer stdbuf = NULL;
struct ssh_channel_read_termination_struct ctx; struct ssh_channel_read_termination_struct ctx;
size_t len; size_t len;
int rc; int rc;
@@ -3508,7 +3516,7 @@ channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
ssh_channel *echans, ssh_channel *rout, ssh_channel *echans, ssh_channel *rout,
ssh_channel *wout, ssh_channel *eout) ssh_channel *wout, ssh_channel *eout)
{ {
ssh_channel chan; ssh_channel chan = NULL;
int i; int i;
int j = 0; int j = 0;
@@ -3589,7 +3597,7 @@ static size_t count_ptrs(ssh_channel *ptrs)
int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
ssh_channel *exceptchans, struct timeval * timeout) ssh_channel *exceptchans, struct timeval * timeout)
{ {
ssh_channel *rchans, *wchans, *echans; ssh_channel *rchans = NULL, *wchans = NULL, *echans = NULL;
ssh_channel dummy = NULL; ssh_channel dummy = NULL;
ssh_event event = NULL; ssh_event event = NULL;
int rc; int rc;
@@ -3782,7 +3790,7 @@ int ssh_channel_write_stderr(ssh_channel channel, const void *data, uint32_t len
int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost, int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport) int remoteport, const char *sourcehost, int localport)
{ {
ssh_session session; ssh_session session = NULL;
ssh_buffer payload = NULL; ssh_buffer payload = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
@@ -3846,7 +3854,7 @@ error:
int ssh_channel_open_x11(ssh_channel channel, int ssh_channel_open_x11(ssh_channel channel,
const char *orig_addr, int orig_port) const char *orig_addr, int orig_port)
{ {
ssh_session session; ssh_session session = NULL;
ssh_buffer payload = NULL; ssh_buffer payload = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;

View File

@@ -785,7 +785,7 @@ ssh_session_set_disconnect_message(ssh_session session, const char *message)
void void
ssh_disconnect(ssh_session session) ssh_disconnect(ssh_session session)
{ {
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
int rc; int rc;
if (session == NULL) { if (session == NULL) {
@@ -895,7 +895,7 @@ error:
*/ */
const char *ssh_copyright(void) const char *ssh_copyright(void)
{ {
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2024 " return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2025 "
"Aris Adamantiadis, Andreas Schneider " "Aris Adamantiadis, Andreas Schneider "
"and libssh contributors. " "and libssh contributors. "
"Distributed under the LGPL, please refer to COPYING " "Distributed under the LGPL, please refer to COPYING "

View File

@@ -211,7 +211,7 @@ local_parse_file(ssh_session session,
unsigned int depth, unsigned int depth,
bool global) bool global)
{ {
FILE *f; FILE *f = NULL;
char line[MAX_LINE_SIZE] = {0}; char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0; unsigned int count = 0;
int rv; int rv;
@@ -894,9 +894,11 @@ ssh_config_parse_line(ssh_session session,
/* Here we match only one argument */ /* Here we match only one argument */
p = ssh_config_get_str_tok(&s, NULL); p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') { if (p == NULL || p[0] == '\0') {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session,
"line %d: ERROR - Match user keyword " SSH_FATAL,
"requires argument", count); "line %d: ERROR - Match localuser keyword "
"requires argument",
count);
SAFE_FREE(x); SAFE_FREE(x);
return -1; return -1;
} }
@@ -1008,17 +1010,17 @@ ssh_config_parse_line(ssh_session session,
case MATCH_UNKNOWN: case MATCH_UNKNOWN:
default: default:
ssh_set_error(session, SSH_FATAL, SSH_LOG(SSH_LOG_WARN,
"ERROR - Unknown argument '%s' for Match keyword", p); "Unknown argument '%s' for Match keyword. Not matching",
SAFE_FREE(x); p);
return -1; result = 0;
break;
} }
} while (p != NULL && p[0] != '\0'); } while (p != NULL && p[0] != '\0');
if (args == 0) { if (args == 0) {
ssh_set_error(session, SSH_FATAL, SSH_LOG(SSH_LOG_WARN,
"ERROR - Match keyword requires an argument"); "ERROR - Match keyword requires an argument. Not matching");
SAFE_FREE(x); result = 0;
return -1;
} }
*parsing = result; *parsing = result;
break; break;
@@ -1460,7 +1462,7 @@ int ssh_config_parse_file(ssh_session session, const char *filename)
{ {
char line[MAX_LINE_SIZE] = {0}; char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0; unsigned int count = 0;
FILE *f; FILE *f = NULL;
int parsing, rv; int parsing, rv;
bool global = 0; bool global = 0;

View File

@@ -39,8 +39,8 @@
*/ */
char *ssh_config_get_cmd(char **str) char *ssh_config_get_cmd(char **str)
{ {
register char *c; register char *c = NULL;
char *r; char *r = NULL;
/* Ignore leading spaces */ /* Ignore leading spaces */
for (c = *str; *c; c++) { for (c = *str; *c; c++) {
@@ -67,7 +67,7 @@ out:
*/ */
char *ssh_config_get_token(char **str) char *ssh_config_get_token(char **str)
{ {
register char *c; register char *c = NULL;
bool had_equal = false; bool had_equal = false;
char *r = NULL; char *r = NULL;
@@ -82,6 +82,13 @@ char *ssh_config_get_token(char **str)
if (*c == '\"') { if (*c == '\"') {
for (r = ++c; *c; c++) { for (r = ++c; *c; c++) {
if (*c == '\"' || *c == '\n') { if (*c == '\"' || *c == '\n') {
if (*c == '\"' && r != c && *(c - 1) == '\\') {
/* Escaped quote: Move the remaining one char left */
int remaining_len = strlen(c);
memmove(c - 1, c, remaining_len);
c[remaining_len - 1] = '\0';
continue;
}
*c = '\0'; *c = '\0';
c++; c++;
break; break;
@@ -116,7 +123,7 @@ out:
long ssh_config_get_long(char **str, long notfound) long ssh_config_get_long(char **str, long notfound)
{ {
char *p, *endp; char *p = NULL, *endp = NULL;
long i; long i;
p = ssh_config_get_token(str); p = ssh_config_get_token(str);
@@ -133,7 +140,7 @@ long ssh_config_get_long(char **str, long notfound)
const char *ssh_config_get_str_tok(char **str, const char *def) const char *ssh_config_get_str_tok(char **str, const char *def)
{ {
char *p; char *p = NULL;
p = ssh_config_get_token(str); p = ssh_config_get_token(str);
if (p && *p) { if (p && *p) {
@@ -145,7 +152,7 @@ const char *ssh_config_get_str_tok(char **str, const char *def)
int ssh_config_get_yesno(char **str, int notfound) int ssh_config_get_yesno(char **str, int notfound)
{ {
const char *p; const char *p = NULL;
p = ssh_config_get_str_tok(str, NULL); p = ssh_config_get_str_tok(str, NULL);
if (p == NULL) { if (p == NULL) {

View File

@@ -189,8 +189,8 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
} }
if (bind_addr) { if (bind_addr) {
struct addrinfo *bind_ai; struct addrinfo *bind_ai = NULL;
struct addrinfo *bind_itr; struct addrinfo *bind_itr = NULL;
SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr); SSH_LOG(SSH_LOG_PACKET, "Resolving %s", bind_addr);

View File

@@ -627,8 +627,9 @@ error:
return rc; return rc;
} }
int ssh_connector_remove_event(ssh_connector connector) { int ssh_connector_remove_event(ssh_connector connector)
ssh_session session; {
ssh_session session = NULL;
if (connector->in_poll != NULL) { if (connector->in_poll != NULL) {
ssh_event_remove_poll(connector->event, connector->in_poll); ssh_event_remove_poll(connector->event, connector->in_poll);

View File

@@ -571,12 +571,12 @@ error:
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request); static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request);
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_init); static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_init);
static ssh_packet_callback dhgex_server_callbacks[]= { static ssh_packet_callback dhgex_server_callbacks[] = {
NULL, /* SSH_MSG_KEX_DH_GEX_REQUEST_OLD */ NULL, /* SSH_MSG_KEX_DH_GEX_REQUEST_OLD */
NULL, /* SSH_MSG_KEX_DH_GEX_GROUP */ NULL, /* SSH_MSG_KEX_DH_GEX_GROUP */
ssh_packet_server_dhgex_init, /* SSH_MSG_KEX_DH_GEX_INIT */ ssh_packet_server_dhgex_init, /* SSH_MSG_KEX_DH_GEX_INIT */
NULL, /* SSH_MSG_KEX_DH_GEX_REPLY */ NULL, /* SSH_MSG_KEX_DH_GEX_REPLY */
ssh_packet_server_dhgex_request /* SSH_MSG_GEX_DH_GEX_REQUEST */ ssh_packet_server_dhgex_request /* SSH_MSG_KEX_DH_GEX_REQUEST */
}; };

View File

@@ -404,9 +404,14 @@ done:
*/ */
int ssh_dh_init_common(struct ssh_crypto_struct *crypto) int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
{ {
struct dh_ctx *ctx; struct dh_ctx *ctx = NULL;
int rc; int rc;
/* Cleanup any previously allocated dh_ctx */
if (crypto->dh_ctx != NULL) {
ssh_dh_cleanup(crypto);
}
ctx = calloc(1, sizeof(*ctx)); ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) { if (ctx == NULL) {
return SSH_ERROR; return SSH_ERROR;

View File

@@ -237,6 +237,11 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
struct dh_ctx *ctx = NULL; struct dh_ctx *ctx = NULL;
int rc; int rc;
/* Cleanup any previously allocated dh_ctx */
if (crypto->dh_ctx != NULL) {
ssh_dh_cleanup(crypto);
}
ctx = calloc(1, sizeof(*ctx)); ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) { if (ctx == NULL) {
return SSH_ERROR; return SSH_ERROR;

View File

@@ -191,6 +191,17 @@ static ssh_string ssh_ecdh_generate(ssh_session session)
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
return NULL; return NULL;
} }
/* Free any previously allocated privkey */
if (session->next_crypto->ecdh_privkey != NULL) {
#if OPENSSL_VERSION_NUMBER < 0x30000000L
EC_KEY_free(session->next_crypto->ecdh_privkey);
#else
EVP_PKEY_free(session->next_crypto->ecdh_privkey);
#endif
session->next_crypto->ecdh_privkey = NULL;
}
session->next_crypto->ecdh_privkey = key; session->next_crypto->ecdh_privkey = key;
return pubkey_string; return pubkey_string;
} }
@@ -219,6 +230,7 @@ int ssh_client_ecdh_init(ssh_session session)
return SSH_ERROR; return SSH_ERROR;
} }
ssh_string_free(session->next_crypto->ecdh_client_pubkey);
session->next_crypto->ecdh_client_pubkey = client_pubkey; session->next_crypto->ecdh_client_pubkey = client_pubkey;
/* register the packet callbacks */ /* register the packet callbacks */
@@ -444,7 +456,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init)
ssh_string q_c_string = NULL; ssh_string q_c_string = NULL;
ssh_string q_s_string = NULL; ssh_string q_s_string = NULL;
/* SSH host keys (rsa, ed25519 and ecdsa) */ /* SSH host keys (rsa, ed25519 and ecdsa) */
ssh_key privkey; ssh_key privkey = NULL;
enum ssh_digest_e digest = SSH_DIGEST_AUTO; enum ssh_digest_e digest = SSH_DIGEST_AUTO;
ssh_string sig_blob = NULL; ssh_string sig_blob = NULL;
ssh_string pubkey_blob = NULL; ssh_string pubkey_blob = NULL;

View File

@@ -101,8 +101,15 @@ int ssh_client_ecdh_init(ssh_session session)
goto out; goto out;
} }
/* Free any previously allocated privkey */
if (session->next_crypto->ecdh_privkey != NULL) {
gcry_sexp_release(session->next_crypto->ecdh_privkey);
session->next_crypto->ecdh_privkey = NULL;
}
session->next_crypto->ecdh_privkey = key; session->next_crypto->ecdh_privkey = key;
key = NULL; key = NULL;
SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey);
session->next_crypto->ecdh_client_pubkey = client_pubkey; session->next_crypto->ecdh_client_pubkey = client_pubkey;
client_pubkey = NULL; client_pubkey = NULL;
@@ -132,9 +139,9 @@ int ecdh_build_k(ssh_session session)
#else #else
size_t k_len = 0; size_t k_len = 0;
enum ssh_key_exchange_e kex_type = session->next_crypto->kex_type; enum ssh_key_exchange_e kex_type = session->next_crypto->kex_type;
ssh_string s; ssh_string s = NULL;
#endif #endif
ssh_string pubkey_raw; ssh_string pubkey_raw = NULL;
gcry_sexp_t pubkey = NULL; gcry_sexp_t pubkey = NULL;
ssh_string privkey = NULL; ssh_string privkey = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
@@ -267,12 +274,12 @@ int ecdh_build_k(ssh_session session)
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){
gpg_error_t err; gpg_error_t err;
/* ECDH keys */ /* ECDH keys */
ssh_string q_c_string; ssh_string q_c_string = NULL;
ssh_string q_s_string; ssh_string q_s_string = NULL;
gcry_sexp_t param = NULL; gcry_sexp_t param = NULL;
gcry_sexp_t key = NULL; gcry_sexp_t key = NULL;
/* SSH host keys (rsa, ed25519 and ecdsa) */ /* SSH host keys (rsa, ed25519 and ecdsa) */
ssh_key privkey; ssh_key privkey = NULL;
enum ssh_digest_e digest = SSH_DIGEST_AUTO; enum ssh_digest_e digest = SSH_DIGEST_AUTO;
ssh_string sig_blob = NULL; ssh_string sig_blob = NULL;
ssh_string pubkey_blob = NULL; ssh_string pubkey_blob = NULL;

View File

@@ -70,6 +70,12 @@ int ssh_client_ecdh_init(ssh_session session)
return SSH_ERROR; return SSH_ERROR;
} }
/* Free any previously allocated privkey */
if (session->next_crypto->ecdh_privkey != NULL) {
mbedtls_ecp_keypair_free(session->next_crypto->ecdh_privkey);
SAFE_FREE(session->next_crypto->ecdh_privkey);
}
session->next_crypto->ecdh_privkey = malloc(sizeof(mbedtls_ecp_keypair)); session->next_crypto->ecdh_privkey = malloc(sizeof(mbedtls_ecp_keypair));
if (session->next_crypto->ecdh_privkey == NULL) { if (session->next_crypto->ecdh_privkey == NULL) {
return SSH_ERROR; return SSH_ERROR;
@@ -110,6 +116,7 @@ int ssh_client_ecdh_init(ssh_session session)
goto out; goto out;
} }
SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey);
session->next_crypto->ecdh_client_pubkey = client_pubkey; session->next_crypto->ecdh_client_pubkey = client_pubkey;
client_pubkey = NULL; client_pubkey = NULL;

View File

@@ -47,7 +47,7 @@ int ssh_gcry_dec2bn(bignum *bn, const char *data) {
char *ssh_gcry_bn2dec(bignum bn) { char *ssh_gcry_bn2dec(bignum bn) {
bignum bndup, num, ten; bignum bndup, num, ten;
char *ret; char *ret = NULL;
int count, count2; int count, count2;
int size, rsize; int size, rsize;
char decnum; char decnum;

View File

@@ -46,7 +46,7 @@
*/ */
static int ssh_gets(const char *prompt, char *buf, size_t len, int verify) static int ssh_gets(const char *prompt, char *buf, size_t len, int verify)
{ {
char *tmp; char *tmp = NULL;
char *ptr = NULL; char *ptr = NULL;
int ok = 0; int ok = 0;
@@ -78,7 +78,7 @@ static int ssh_gets(const char *prompt, char *buf, size_t len, int verify)
} }
if (verify) { if (verify) {
char *key_string; char *key_string = NULL;
key_string = calloc(1, len); key_string = calloc(1, len);
if (key_string == NULL) { if (key_string == NULL) {

View File

@@ -159,7 +159,7 @@ ssh_gssapi_handle_userauth(ssh_session session, const char *user,
gss_name_t server_name; /* local server fqdn */ gss_name_t server_name; /* local server fqdn */
OM_uint32 maj_stat, min_stat; OM_uint32 maj_stat, min_stat;
size_t i; size_t i;
char *ptr; char *ptr = NULL;
gss_OID_set supported; /* oids supported by server */ gss_OID_set supported; /* oids supported by server */
gss_OID_set both_supported; /* oids supported by both client and server */ gss_OID_set both_supported; /* oids supported by both client and server */
gss_OID_set selected; /* oid selected for authentication */ gss_OID_set selected; /* oid selected for authentication */
@@ -313,7 +313,7 @@ ssh_gssapi_name_to_char(gss_name_t name)
{ {
gss_buffer_desc buffer; gss_buffer_desc buffer;
OM_uint32 maj_stat, min_stat; OM_uint32 maj_stat, min_stat;
char *ptr; char *ptr = NULL;
maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); maj_stat = gss_display_name(&min_stat, name, &buffer, NULL);
ssh_gssapi_log_error(SSH_LOG_DEBUG, ssh_gssapi_log_error(SSH_LOG_DEBUG,
"converting name", "converting name",
@@ -331,9 +331,10 @@ ssh_gssapi_name_to_char(gss_name_t name)
} }
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server)
ssh_string token; {
char *hexa; ssh_string token = NULL;
char *hexa = NULL;
OM_uint32 maj_stat, min_stat; OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER;
gss_name_t client_name = GSS_C_NO_NAME; gss_name_t client_name = GSS_C_NO_NAME;
@@ -357,7 +358,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
} }
if (ssh_callbacks_exists(session->server_callbacks, gssapi_accept_sec_ctx_function)){ if (ssh_callbacks_exists(session->server_callbacks, gssapi_accept_sec_ctx_function)){
ssh_string out_token=NULL; ssh_string out_token = NULL;
rc = session->server_callbacks->gssapi_accept_sec_ctx_function(session, rc = session->server_callbacks->gssapi_accept_sec_ctx_function(session,
token, &out_token, session->server_callbacks->userdata); token, &out_token, session->server_callbacks->userdata);
if (rc == SSH_ERROR){ if (rc == SSH_ERROR){
@@ -473,7 +474,7 @@ static ssh_buffer ssh_gssapi_build_mic(ssh_session session)
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic) SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic)
{ {
ssh_string mic_token; ssh_string mic_token = NULL;
OM_uint32 maj_stat, min_stat; OM_uint32 maj_stat, min_stat;
gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER; gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER;
gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER; gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER;
@@ -635,7 +636,7 @@ static int ssh_gssapi_match(ssh_session session, gss_OID_set *valid_oids)
gss_name_t client_id = GSS_C_NO_NAME; gss_name_t client_id = GSS_C_NO_NAME;
gss_OID oid; gss_OID oid;
unsigned int i; unsigned int i;
char *ptr; char *ptr = NULL;
int ret; int ret;
if (session->gssapi->client.client_deleg_creds == NULL) { if (session->gssapi->client.client_deleg_creds == NULL) {
@@ -837,11 +838,11 @@ static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s)
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
int rc; int rc;
ssh_string oid_s; ssh_string oid_s = NULL;
gss_uint32 maj_stat, min_stat; gss_uint32 maj_stat, min_stat;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
char *hexa; char *hexa = NULL;
(void)type; (void)type;
(void)user; (void)user;
@@ -956,10 +957,11 @@ static int ssh_gssapi_send_mic(ssh_session session)
return ssh_packet_send(session); return ssh_packet_send(session);
} }
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client)
{
int rc; int rc;
ssh_string token; ssh_string token = NULL;
char *hexa; char *hexa = NULL;
OM_uint32 maj_stat, min_stat; OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER;
(void)user; (void)user;

View File

@@ -26,13 +26,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <zlib.h>
#include "libssh/buffer.h" #include "libssh/buffer.h"
#include "libssh/crypto.h" #include "libssh/crypto.h"
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/session.h" #include "libssh/session.h"
#ifdef WITH_ZLIB
#include <zlib.h>
#ifndef BLOCKSIZE #ifndef BLOCKSIZE
#define BLOCKSIZE 4092 #define BLOCKSIZE 4092
#endif #endif
@@ -50,6 +52,7 @@ initcompress(ssh_session session, int level)
status = deflateInit(stream, level); status = deflateInit(stream, level);
if (status != Z_OK) { if (status != Z_OK) {
deflateEnd(stream);
SAFE_FREE(stream); SAFE_FREE(stream);
ssh_set_error(session, ssh_set_error(session,
SSH_FATAL, SSH_FATAL,
@@ -158,6 +161,7 @@ initdecompress(ssh_session session)
status = inflateInit(stream); status = inflateInit(stream);
if (status != Z_OK) { if (status != Z_OK) {
inflateEnd(stream);
SAFE_FREE(stream); SAFE_FREE(stream);
ssh_set_error(session, ssh_set_error(session,
SSH_FATAL, SSH_FATAL,
@@ -258,3 +262,41 @@ decompress_buffer(ssh_session session, ssh_buffer buf, size_t maxlen)
SSH_BUFFER_FREE(dest); SSH_BUFFER_FREE(dest);
return 0; return 0;
} }
void
compress_cleanup(struct ssh_crypto_struct *crypto)
{
if (crypto->compress_out_ctx) {
deflateEnd(crypto->compress_out_ctx);
}
SAFE_FREE(crypto->compress_out_ctx);
if (crypto->compress_in_ctx) {
inflateEnd(crypto->compress_in_ctx);
}
SAFE_FREE(crypto->compress_in_ctx);
}
#else /* WITH_ZLIB */
int
compress_buffer(UNUSED_PARAM(ssh_session session), UNUSED_PARAM(ssh_buffer buf))
{
/* without zlib compiled in, this should never happen */
return -1;
}
int
decompress_buffer(UNUSED_PARAM(ssh_session session),
UNUSED_PARAM(ssh_buffer buf),
UNUSED_PARAM(size_t maxlen))
{
/* without zlib compiled in, this should never happen */
return -1;
}
void
compress_cleanup(UNUSED_PARAM(struct ssh_crypto_struct *crypto))
{
/* no-op */
}
#endif /* WITH_ZLIB */

View File

@@ -313,7 +313,7 @@ static int cmp_first_kex_algo(const char *client_str,
size_t client_kex_len; size_t client_kex_len;
size_t server_kex_len; size_t server_kex_len;
char *colon; char *colon = NULL;
int is_wrong = 1; int is_wrong = 1;
@@ -751,7 +751,7 @@ char *ssh_client_select_hostkeys(ssh_session session)
int ssh_set_client_kex(ssh_session session) int ssh_set_client_kex(ssh_session session)
{ {
struct ssh_kex_struct *client = &session->next_crypto->client_kex; struct ssh_kex_struct *client = &session->next_crypto->client_kex;
const char *wanted; const char *wanted = NULL;
int ok; int ok;
int i; int i;
@@ -1042,7 +1042,7 @@ int ssh_send_kex(ssh_session session)
rc = ssh_buffer_pack(session->out_buffer, rc = ssh_buffer_pack(session->out_buffer,
"bP", "bP",
SSH2_MSG_KEXINIT, SSH2_MSG_KEXINIT,
16, (size_t)16,
kex->cookie); /* cookie */ kex->cookie); /* cookie */
if (rc != SSH_OK) if (rc != SSH_OK)
goto error; goto error;
@@ -1367,10 +1367,10 @@ int ssh_make_sessionid(ssh_session session)
rc = ssh_buffer_pack(buf, rc = ssh_buffer_pack(buf,
"dPdPS", "dPdPS",
ssh_buffer_get_len(client_hash), ssh_buffer_get_len(client_hash),
ssh_buffer_get_len(client_hash), (size_t)ssh_buffer_get_len(client_hash),
ssh_buffer_get(client_hash), ssh_buffer_get(client_hash),
ssh_buffer_get_len(server_hash), ssh_buffer_get_len(server_hash),
ssh_buffer_get_len(server_hash), (size_t)ssh_buffer_get_len(server_hash),
ssh_buffer_get(server_hash), ssh_buffer_get(server_hash),
server_pubkey_blob); server_pubkey_blob);
SSH_STRING_FREE(server_pubkey_blob); SSH_STRING_FREE(server_pubkey_blob);
@@ -1466,9 +1466,11 @@ int ssh_make_sessionid(ssh_session session)
rc = ssh_buffer_pack(buf, rc = ssh_buffer_pack(buf,
"dPdP", "dPdP",
CURVE25519_PUBKEY_SIZE, CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey, (size_t)CURVE25519_PUBKEY_SIZE,
session->next_crypto->curve25519_client_pubkey,
CURVE25519_PUBKEY_SIZE, CURVE25519_PUBKEY_SIZE,
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_server_pubkey); (size_t)CURVE25519_PUBKEY_SIZE,
session->next_crypto->curve25519_server_pubkey);
if (rc != SSH_OK) { if (rc != SSH_OK) {
goto error; goto error;
@@ -1485,6 +1487,8 @@ int ssh_make_sessionid(ssh_session session)
ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf)); ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf));
#endif #endif
/* Set rc for the following switch statement in case we goto error. */
rc = SSH_ERROR;
switch (session->next_crypto->kex_type) { switch (session->next_crypto->kex_type) {
case SSH_KEX_DH_GROUP1_SHA1: case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1: case SSH_KEX_DH_GROUP14_SHA1:
@@ -1544,6 +1548,7 @@ int ssh_make_sessionid(ssh_session session)
session->next_crypto->secret_hash); session->next_crypto->secret_hash);
break; break;
} }
/* During the first kex, secret hash and session ID are equal. However, after /* During the first kex, secret hash and session ID are equal. However, after
* a key re-exchange, a new secret hash is calculated. This hash will not replace * a key re-exchange, a new secret hash is calculated. This hash will not replace
* but complement existing session id. * but complement existing session id.
@@ -1552,6 +1557,7 @@ int ssh_make_sessionid(ssh_session session)
session->next_crypto->session_id = malloc(session->next_crypto->digest_len); session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
if (session->next_crypto->session_id == NULL) { if (session->next_crypto->session_id == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
rc = SSH_ERROR;
goto error; goto error;
} }
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash, memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,

View File

@@ -79,8 +79,8 @@ static struct ssh_tokens_st *ssh_get_knownhost_line(FILE **file,
const char **found_type) const char **found_type)
{ {
char buffer[MAX_LINE_SIZE] = {0}; char buffer[MAX_LINE_SIZE] = {0};
char *ptr; char *ptr = NULL;
struct ssh_tokens_st *tokens; struct ssh_tokens_st *tokens = NULL;
if (*file == NULL) { if (*file == NULL) {
*file = fopen(filename,"r"); *file = fopen(filename,"r");
@@ -149,7 +149,7 @@ static struct ssh_tokens_st *ssh_get_knownhost_line(FILE **file,
static int check_public_key(ssh_session session, char **tokens) { static int check_public_key(ssh_session session, char **tokens) {
ssh_string pubkey_blob = NULL; ssh_string pubkey_blob = NULL;
ssh_buffer pubkey_buffer; ssh_buffer pubkey_buffer;
char *pubkey_64; char *pubkey_64 = NULL;
int rc; int rc;
/* ssh-rsa, ssh-ed25519, .. */ /* ssh-rsa, ssh-ed25519, .. */
@@ -205,11 +205,11 @@ static int match_hashed_host(const char *host, const char *sourcehash)
* hash := HMAC_SHA1(key=salt,data=host) * hash := HMAC_SHA1(key=salt,data=host)
*/ */
unsigned char buffer[256] = {0}; unsigned char buffer[256] = {0};
ssh_buffer salt; ssh_buffer salt = NULL;
ssh_buffer hash; ssh_buffer hash = NULL;
HMACCTX mac; HMACCTX mac = NULL;
char *source; char *source = NULL;
char *b64hash; char *b64hash = NULL;
int match, rc; int match, rc;
size_t size; size_t size;
@@ -304,14 +304,14 @@ static int match_hashed_host(const char *host, const char *sourcehash)
int ssh_is_server_known(ssh_session session) int ssh_is_server_known(ssh_session session)
{ {
FILE *file = NULL; FILE *file = NULL;
char *host; char *host = NULL;
char *hostport; char *hostport = NULL;
const char *type; const char *type = NULL;
int match; int match;
int i = 0; int i = 0;
char *files[3]; char *files[3] = {0};
struct ssh_tokens_st *tokens; struct ssh_tokens_st *tokens = NULL;
int ret = SSH_SERVER_NOT_KNOWN; int ret = SSH_SERVER_NOT_KNOWN;
@@ -443,12 +443,13 @@ int ssh_is_server_known(ssh_session session)
* @deprecated Please use ssh_session_export_known_hosts_entry() * @deprecated Please use ssh_session_export_known_hosts_entry()
* @brief This function is deprecated. * @brief This function is deprecated.
*/ */
char * ssh_dump_knownhost(ssh_session session) { char *ssh_dump_knownhost(ssh_session session)
{
ssh_key server_pubkey = NULL; ssh_key server_pubkey = NULL;
char *host; char *host = NULL;
char *hostport; char *hostport = NULL;
char *buffer; char *buffer = NULL;
char *b64_key; char *b64_key = NULL;
int rc; int rc;
if (session->opts.host == NULL) { if (session->opts.host == NULL) {
@@ -513,9 +514,9 @@ char * ssh_dump_knownhost(ssh_session session) {
*/ */
int ssh_write_knownhost(ssh_session session) int ssh_write_knownhost(ssh_session session)
{ {
FILE *file; FILE *file = NULL;
char *buffer = NULL; char *buffer = NULL;
char *dir; char *dir = NULL;
int rc; int rc;
if (session->opts.knownhosts == NULL) { if (session->opts.knownhosts == NULL) {

View File

@@ -61,7 +61,7 @@ static int hash_hostname(const char *name,
size_t *hash_size) size_t *hash_size)
{ {
int rc; int rc;
HMACCTX mac_ctx; HMACCTX mac_ctx = NULL;
mac_ctx = hmac_init(salt, salt_size, SSH_HMAC_SHA1); mac_ctx = hmac_init(salt, salt_size, SSH_HMAC_SHA1);
if (mac_ctx == NULL) { if (mac_ctx == NULL) {
@@ -81,8 +81,8 @@ static int hash_hostname(const char *name,
static int match_hashed_hostname(const char *host, const char *hashed_host) static int match_hashed_hostname(const char *host, const char *hashed_host)
{ {
char *hashed; char *hashed = NULL;
char *b64_hash; char *b64_hash = NULL;
ssh_buffer salt = NULL; ssh_buffer salt = NULL;
ssh_buffer hash = NULL; ssh_buffer hash = NULL;
unsigned char hashed_buf[256] = {0}; unsigned char hashed_buf[256] = {0};
@@ -229,7 +229,7 @@ static int ssh_known_hosts_read_entries(const char *match,
char line[MAX_LINE_SIZE]; char line[MAX_LINE_SIZE];
size_t lineno = 0; size_t lineno = 0;
size_t len = 0; size_t len = 0;
FILE *fp; FILE *fp = NULL;
int rc; int rc;
fp = fopen(filename, "r"); fp = fopen(filename, "r");
@@ -288,7 +288,7 @@ static int ssh_known_hosts_read_entries(const char *match,
for (it = ssh_list_get_iterator(*entries); for (it = ssh_list_get_iterator(*entries);
it != NULL; it != NULL;
it = it->next) { it = it->next) {
struct ssh_knownhosts_entry *entry2; struct ssh_knownhosts_entry *entry2 = NULL;
int cmp; int cmp;
entry2 = ssh_iterator_value(struct ssh_knownhosts_entry *, it); entry2 = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
cmp = ssh_known_hosts_entries_compare(entry, entry2); cmp = ssh_known_hosts_entries_compare(entry, entry2);
@@ -312,8 +312,8 @@ error:
static char *ssh_session_get_host_port(ssh_session session) static char *ssh_session_get_host_port(ssh_session session)
{ {
char *host_port; char *host_port = NULL;
char *host; char *host = NULL;
if (session->opts.host == NULL) { if (session->opts.host == NULL) {
ssh_set_error(session, ssh_set_error(session,
@@ -530,7 +530,7 @@ char *ssh_known_hosts_get_algorithms_names(ssh_session session)
char *host_port = NULL; char *host_port = NULL;
size_t count; size_t count;
bool needcomma = false; bool needcomma = false;
char *names; char *names = NULL;
int rc; int rc;
@@ -638,7 +638,7 @@ int ssh_known_hosts_parse_line(const char *hostname,
{ {
struct ssh_knownhosts_entry *e = NULL; struct ssh_knownhosts_entry *e = NULL;
char *known_host = NULL; char *known_host = NULL;
char *p; char *p = NULL;
char *save_tok = NULL; char *save_tok = NULL;
enum ssh_keytypes_e key_type; enum ssh_keytypes_e key_type;
int match = 0; int match = 0;

View File

@@ -48,7 +48,7 @@ int ssh_auth_list(ssh_session session) {
int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int ssh_userauth_offer_pubkey(ssh_session session, const char *username,
int type, ssh_string publickey) int type, ssh_string publickey)
{ {
ssh_key key; ssh_key key = NULL;
int rc; int rc;
(void) type; /* unused */ (void) type; /* unused */
@@ -70,7 +70,7 @@ int ssh_userauth_pubkey(ssh_session session,
ssh_string publickey, ssh_string publickey,
ssh_private_key privatekey) ssh_private_key privatekey)
{ {
ssh_key key; ssh_key key = NULL;
int rc; int rc;
(void) publickey; /* unused */ (void) publickey; /* unused */
@@ -376,10 +376,11 @@ void publickey_free(ssh_public_key key) {
SAFE_FREE(key); SAFE_FREE(key);
} }
ssh_public_key publickey_from_privatekey(ssh_private_key prv) { ssh_public_key publickey_from_privatekey(ssh_private_key prv)
struct ssh_public_key_struct *p; {
ssh_key privkey; struct ssh_public_key_struct *p = NULL;
ssh_key pubkey; ssh_key privkey = NULL;
ssh_key pubkey = NULL;
int rc; int rc;
privkey = ssh_key_new(); privkey = ssh_key_new();
@@ -423,8 +424,8 @@ ssh_private_key privatekey_from_file(ssh_session session,
const char *passphrase) { const char *passphrase) {
ssh_auth_callback auth_fn = NULL; ssh_auth_callback auth_fn = NULL;
void *auth_data = NULL; void *auth_data = NULL;
ssh_private_key privkey; ssh_private_key privkey = NULL;
ssh_key key; ssh_key key = NULL;
int rc; int rc;
(void) type; /* unused */ (void) type; /* unused */
@@ -440,7 +441,7 @@ ssh_private_key privatekey_from_file(ssh_session session,
auth_fn, auth_fn,
auth_data, auth_data,
&key); &key);
if (rc == SSH_ERROR) { if (rc != SSH_OK) {
return NULL; return NULL;
} }
@@ -492,7 +493,7 @@ void privatekey_free(ssh_private_key prv) {
ssh_string publickey_from_file(ssh_session session, const char *filename, ssh_string publickey_from_file(ssh_session session, const char *filename,
int *type) { int *type) {
ssh_key key; ssh_key key = NULL;
ssh_string key_str = NULL; ssh_string key_str = NULL;
int rc; int rc;
@@ -525,9 +526,10 @@ int ssh_type_from_name(const char *name) {
return ssh_key_type_from_name(name); return ssh_key_type_from_name(name);
} }
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) { ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s)
struct ssh_public_key_struct *pubkey; {
ssh_key key; struct ssh_public_key_struct *pubkey = NULL;
ssh_key key = NULL;
int rc; int rc;
(void) session; /* unused */ (void) session; /* unused */
@@ -562,9 +564,10 @@ ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
return pubkey; return pubkey;
} }
ssh_string publickey_to_string(ssh_public_key pubkey) { ssh_string publickey_to_string(ssh_public_key pubkey)
ssh_key key; {
ssh_string key_blob; ssh_key key = NULL;
ssh_string key_blob = NULL;
int rc; int rc;
if (pubkey == NULL) { if (pubkey == NULL) {
@@ -609,11 +612,11 @@ int ssh_publickey_to_file(ssh_session session,
ssh_string pubkey, ssh_string pubkey,
int type) int type)
{ {
FILE *fp; FILE *fp = NULL;
char *user; char *user = NULL;
char buffer[1024]; char buffer[1024];
char host[256]; char host[256];
unsigned char *pubkey_64; unsigned char *pubkey_64 = NULL;
size_t len; size_t len;
int rc; int rc;
if(session==NULL) if(session==NULL)
@@ -680,9 +683,9 @@ int ssh_try_publickey_from_file(ssh_session session,
const char *keyfile, const char *keyfile,
ssh_string *publickey, ssh_string *publickey,
int *type) { int *type) {
char *pubkey_file; char *pubkey_file = NULL;
size_t len; size_t len;
ssh_string pubkey_string; ssh_string pubkey_string = NULL;
int pubkey_type; int pubkey_type;
if (session == NULL || keyfile == NULL || publickey == NULL || type == NULL) { if (session == NULL || keyfile == NULL || publickey == NULL || type == NULL) {

View File

@@ -49,8 +49,9 @@
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
#else #else
#include <openssl/param_build.h>
#include <openssl/core_names.h> #include <openssl/core_names.h>
#include <openssl/param_build.h>
#include <openssl/provider.h>
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
#include <openssl/rand.h> #include <openssl/rand.h>
#if defined(WITH_PKCS11_URI) && !defined(WITH_PKCS11_PROVIDER) #if defined(WITH_PKCS11_URI) && !defined(WITH_PKCS11_PROVIDER)
@@ -96,7 +97,37 @@ void ssh_reseed(void){
#endif #endif
} }
#if defined(WITH_PKCS11_URI) && !defined(WITH_PKCS11_PROVIDER) #if defined(WITH_PKCS11_URI)
#if defined(WITH_PKCS11_PROVIDER)
static OSSL_PROVIDER *provider = NULL;
static bool pkcs11_provider_failed = false;
int pki_load_pkcs11_provider(void)
{
if (OSSL_PROVIDER_available(NULL, "pkcs11") == 1) {
/* the provider is already available.
* Loaded through a configuration file? */
return SSH_OK;
}
if (pkcs11_provider_failed) {
/* the loading failed previously -- do not retry */
return SSH_ERROR;
}
provider = OSSL_PROVIDER_try_load(NULL, "pkcs11", 1);
if (provider != NULL) {
return SSH_OK;
}
SSH_LOG(SSH_LOG_TRACE,
"Failed to load the pkcs11 provider: %s",
ERR_error_string(ERR_get_error(), NULL));
/* Do not attempt to load it again */
pkcs11_provider_failed = true;
return SSH_ERROR;
}
#else
static ENGINE *engine = NULL; static ENGINE *engine = NULL;
ENGINE *pki_get_engine(void) ENGINE *pki_get_engine(void)
@@ -128,7 +159,8 @@ ENGINE *pki_get_engine(void)
} }
return engine; return engine;
} }
#endif /* defined(WITH_PKCS11_URI) && !defined(WITH_PKCS11_PROVIDER) */ #endif /* defined(WITH_PKCS11_PROVIDER) */
#endif /* defined(WITH_PKCS11_URI) */
#ifdef HAVE_OPENSSL_EVP_KDF_CTX #ifdef HAVE_OPENSSL_EVP_KDF_CTX
#if OPENSSL_VERSION_NUMBER < 0x30000000L #if OPENSSL_VERSION_NUMBER < 0x30000000L
@@ -168,7 +200,7 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
uint8_t key_type, unsigned char *output, uint8_t key_type, unsigned char *output,
size_t requested_len) size_t requested_len)
{ {
int rc = -1; int ret = SSH_ERROR, rv;
#if OPENSSL_VERSION_NUMBER < 0x30000000L #if OPENSSL_VERSION_NUMBER < 0x30000000L
EVP_KDF_CTX *ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF); EVP_KDF_CTX *ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
#else #else
@@ -202,81 +234,86 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
} }
#if OPENSSL_VERSION_NUMBER < 0x30000000L #if OPENSSL_VERSION_NUMBER < 0x30000000L
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, rv = EVP_KDF_ctrl(ctx,
EVP_KDF_CTRL_SET_MD,
sshkdf_digest_to_md(crypto->digest_type)); sshkdf_digest_to_md(crypto->digest_type));
if (rc != 1) { if (rv != 1) {
goto out; goto out;
} }
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key, key_len); rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key, key_len);
if (rc != 1) { if (rv != 1) {
goto out; goto out;
} }
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, rv = EVP_KDF_ctrl(ctx,
crypto->secret_hash, crypto->digest_len); EVP_KDF_CTRL_SET_SSHKDF_XCGHASH,
if (rc != 1) { crypto->secret_hash,
crypto->digest_len);
if (rv != 1) {
goto out; goto out;
} }
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, key_type); rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, key_type);
if (rc != 1) { if (rv != 1) {
goto out; goto out;
} }
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, rv = EVP_KDF_ctrl(ctx,
crypto->session_id, crypto->session_id_len); EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
if (rc != 1) { crypto->session_id,
crypto->session_id_len);
if (rv != 1) {
goto out; goto out;
} }
rc = EVP_KDF_derive(ctx, output, requested_len); rv = EVP_KDF_derive(ctx, output, requested_len);
if (rc != 1) { if (rv != 1) {
goto out; goto out;
} }
#else #else
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST, rv = OSSL_PARAM_BLD_push_utf8_string(param_bld,
md, strlen(md)); OSSL_KDF_PARAM_DIGEST,
if (rc != 1) { md,
rc = -1; strlen(md));
if (rv != 1) {
goto out; goto out;
} }
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY, rv = OSSL_PARAM_BLD_push_octet_string(param_bld,
key, key_len); OSSL_KDF_PARAM_KEY,
if (rc != 1) { key,
rc = -1; key_len);
if (rv != 1) {
goto out; goto out;
} }
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, rv = OSSL_PARAM_BLD_push_octet_string(param_bld,
OSSL_KDF_PARAM_SSHKDF_XCGHASH, OSSL_KDF_PARAM_SSHKDF_XCGHASH,
crypto->secret_hash, crypto->secret_hash,
crypto->digest_len); crypto->digest_len);
if (rc != 1) { if (rv != 1) {
rc = -1;
goto out; goto out;
} }
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, rv = OSSL_PARAM_BLD_push_octet_string(param_bld,
OSSL_KDF_PARAM_SSHKDF_SESSION_ID, OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
crypto->session_id, crypto->session_id,
crypto->session_id_len); crypto->session_id_len);
if (rc != 1) { if (rv != 1) {
rc = -1;
goto out; goto out;
} }
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE, rv = OSSL_PARAM_BLD_push_utf8_string(param_bld,
(const char*)&key_type, 1); OSSL_KDF_PARAM_SSHKDF_TYPE,
if (rc != 1) { (const char *)&key_type,
rc = -1; 1);
if (rv != 1) {
goto out; goto out;
} }
params = OSSL_PARAM_BLD_to_param(param_bld); params = OSSL_PARAM_BLD_to_param(param_bld);
if (params == NULL) { if (params == NULL) {
rc = -1;
goto out; goto out;
} }
rc = EVP_KDF_derive(ctx, output, requested_len, params); rv = EVP_KDF_derive(ctx, output, requested_len, params);
if (rc != 1) { if (rv != 1) {
rc = -1;
goto out; goto out;
} }
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
ret = SSH_OK;
out: out:
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
@@ -284,8 +321,8 @@ out:
OSSL_PARAM_free(params); OSSL_PARAM_free(params);
#endif #endif
EVP_KDF_CTX_free(ctx); EVP_KDF_CTX_free(ctx);
if (rc < 0) { if (ret < 0) {
return rc; return ret;
} }
return 0; return 0;
} }
@@ -794,9 +831,9 @@ chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher,
SSH_LOG(SSH_LOG_TRACE, "EVP_CIPHER_CTX_new failed"); SSH_LOG(SSH_LOG_TRACE, "EVP_CIPHER_CTX_new failed");
goto out; goto out;
} }
ret = EVP_EncryptInit_ex(ctx->header_evp, EVP_chacha20(), NULL, rv = EVP_EncryptInit_ex(ctx->header_evp, EVP_chacha20(), NULL,
u8key + CHACHA20_KEYLEN, NULL); u8key + CHACHA20_KEYLEN, NULL);
if (ret != 1) { if (rv != 1) {
SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit failed"); SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit failed");
goto out; goto out;
} }
@@ -1397,6 +1434,14 @@ void ssh_crypto_finalize(void)
engine = NULL; engine = NULL;
} }
#endif #endif
#if defined(WITH_PKCS11_URI)
#if defined(WITH_PKCS11_PROVIDER)
if (provider != NULL) {
OSSL_PROVIDER_unload(provider);
provider = NULL;
}
#endif /* WITH_PKCS11_PROVIDER */
#endif /* WITH_PKCS11_URI */
libcrypto_initialized = 0; libcrypto_initialized = 0;
} }

View File

@@ -133,7 +133,7 @@ cipher_init(struct ssh_cipher_struct *cipher,
void *IV) void *IV)
{ {
const mbedtls_cipher_info_t *cipher_info = NULL; const mbedtls_cipher_info_t *cipher_info = NULL;
mbedtls_cipher_context_t *ctx; mbedtls_cipher_context_t *ctx = NULL;
size_t key_bitlen = 0; size_t key_bitlen = 0;
size_t iv_size = 0; size_t iv_size = 0;
int rc; int rc;

View File

@@ -44,7 +44,7 @@
static LIBSSH_THREAD int ssh_log_level; static LIBSSH_THREAD int ssh_log_level;
static LIBSSH_THREAD ssh_logging_callback ssh_log_cb; static LIBSSH_THREAD ssh_logging_callback ssh_log_cb;
static LIBSSH_THREAD void *ssh_log_userdata; static LIBSSH_THREAD void *ssh_log_userdata = NULL;
/** /**
* @defgroup libssh_log The SSH logging functions * @defgroup libssh_log The SSH logging functions

View File

@@ -521,7 +521,7 @@ static void ssh_message_queue(ssh_session session, ssh_message message)
*/ */
ssh_message ssh_message_pop_head(ssh_session session){ ssh_message ssh_message_pop_head(ssh_session session){
ssh_message msg=NULL; ssh_message msg=NULL;
struct ssh_iterator *i; struct ssh_iterator *i = NULL;
if(session->ssh_message_list == NULL) if(session->ssh_message_list == NULL)
return NULL; return NULL;
i=ssh_list_get_iterator(session->ssh_message_list); i=ssh_list_get_iterator(session->ssh_message_list);
@@ -535,7 +535,7 @@ ssh_message ssh_message_pop_head(ssh_session session){
/* Returns 1 if there is a message available */ /* Returns 1 if there is a message available */
static int ssh_message_termination(void *s){ static int ssh_message_termination(void *s){
ssh_session session = s; ssh_session session = s;
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
if(session->session_state == SSH_SESSION_STATE_ERROR) if(session->session_state == SSH_SESSION_STATE_ERROR)
return 1; return 1;
it = ssh_list_get_iterator(session->ssh_message_list); it = ssh_list_get_iterator(session->ssh_message_list);
@@ -736,7 +736,7 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
ssh_string algo) ssh_string algo)
{ {
struct ssh_crypto_struct *crypto = NULL; struct ssh_crypto_struct *crypto = NULL;
ssh_buffer buffer; ssh_buffer buffer = NULL;
ssh_string str=NULL; ssh_string str=NULL;
int rc; int rc;
@@ -757,8 +757,9 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
rc = ssh_buffer_pack(buffer, rc = ssh_buffer_pack(buffer,
"dPbsssbsS", "dPbsssbsS",
crypto->session_id_len, /* session ID string */ (uint32_t)crypto->session_id_len, /* session ID string */
crypto->session_id_len, crypto->session_id, crypto->session_id_len,
crypto->session_id,
SSH2_MSG_USERAUTH_REQUEST, /* type */ SSH2_MSG_USERAUTH_REQUEST, /* type */
msg->auth_request.username, msg->auth_request.username,
service, service,
@@ -975,9 +976,9 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
#ifdef WITH_GSSAPI #ifdef WITH_GSSAPI
if (strcmp(method, "gssapi-with-mic") == 0) { if (strcmp(method, "gssapi-with-mic") == 0) {
uint32_t n_oid; uint32_t n_oid;
ssh_string *oids; ssh_string *oids = NULL;
ssh_string oid; ssh_string oid = NULL;
char *hexa; char *hexa = NULL;
int i; int i;
ssh_buffer_get_u32(packet, &n_oid); ssh_buffer_get_u32(packet, &n_oid);
n_oid=ntohl(n_oid); n_oid=ntohl(n_oid);
@@ -1061,7 +1062,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
uint32_t nanswers; uint32_t nanswers;
uint32_t i; uint32_t i;
ssh_string tmp; ssh_string tmp = NULL;
int rc; int rc;
ssh_message msg = NULL; ssh_message msg = NULL;
@@ -1301,7 +1302,7 @@ end:
* @returns SSH_OK on success, SSH_ERROR if an error occurred. * @returns SSH_OK on success, SSH_ERROR if an error occurred.
*/ */
int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan) { int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_channel chan) {
ssh_session session; ssh_session session = NULL;
int rc; int rc;
if (msg == NULL) { if (msg == NULL) {
@@ -1352,7 +1353,7 @@ int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_c
* @returns NULL in case of error * @returns NULL in case of error
*/ */
ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) { ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) {
ssh_channel chan; ssh_channel chan = NULL;
int rc; int rc;
if (msg == NULL) { if (msg == NULL) {

View File

@@ -401,7 +401,7 @@ int ssh_is_ipaddr(const char *str)
char *ssh_lowercase(const char* str) char *ssh_lowercase(const char* str)
{ {
char *new, *p; char *new = NULL, *p = NULL;
if (str == NULL) { if (str == NULL) {
return NULL; return NULL;
@@ -455,7 +455,7 @@ char *ssh_hostport(const char *host, int port)
char *ssh_get_hexa(const unsigned char *what, size_t len) char *ssh_get_hexa(const unsigned char *what, size_t len)
{ {
const char h[] = "0123456789abcdef"; const char h[] = "0123456789abcdef";
char *hexa; char *hexa = NULL;
size_t i; size_t i;
size_t hlen = len * 3; size_t hlen = len * 3;
@@ -725,7 +725,7 @@ struct ssh_list *ssh_list_new(void)
void ssh_list_free(struct ssh_list *list) void ssh_list_free(struct ssh_list *list)
{ {
struct ssh_iterator *ptr, *next; struct ssh_iterator *ptr = NULL, *next = NULL;
if (!list) if (!list)
return; return;
ptr = list->root; ptr = list->root;
@@ -746,7 +746,7 @@ struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list)
struct ssh_iterator *ssh_list_find(const struct ssh_list *list, void *value) struct ssh_iterator *ssh_list_find(const struct ssh_list *list, void *value)
{ {
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
for (it = ssh_list_get_iterator(list); it != NULL ; it = it->next) for (it = ssh_list_get_iterator(list); it != NULL ; it = it->next)
if (it->data == value) if (it->data == value)
@@ -836,7 +836,7 @@ int ssh_list_prepend(struct ssh_list *list, const void *data)
void ssh_list_remove(struct ssh_list *list, struct ssh_iterator *iterator) void ssh_list_remove(struct ssh_list *list, struct ssh_iterator *iterator)
{ {
struct ssh_iterator *ptr, *prev; struct ssh_iterator *ptr = NULL, *prev = NULL;
if (list == NULL) { if (list == NULL) {
return; return;
@@ -977,7 +977,7 @@ char *ssh_dirname (const char *path)
char *ssh_basename (const char *path) char *ssh_basename (const char *path)
{ {
char *new = NULL; char *new = NULL;
const char *s; const char *s = NULL;
size_t len; size_t len;
if (path == NULL || *path == '\0') { if (path == NULL || *path == '\0') {
@@ -1115,8 +1115,8 @@ int ssh_mkdirs(const char *pathname, mode_t mode)
*/ */
char *ssh_path_expand_tilde(const char *d) char *ssh_path_expand_tilde(const char *d)
{ {
char *h = NULL, *r; char *h = NULL, *r = NULL;
const char *p; const char *p = NULL;
size_t ld; size_t ld;
size_t lh = 0; size_t lh = 0;
@@ -1131,7 +1131,7 @@ char *ssh_path_expand_tilde(const char *d)
#ifdef _WIN32 #ifdef _WIN32
return strdup(d); return strdup(d);
#else #else
struct passwd *pw; struct passwd *pw = NULL;
size_t s = p - d; size_t s = p - d;
char u[128]; char u[128];
@@ -1192,7 +1192,7 @@ char *ssh_path_expand_escape(ssh_session session, const char *s)
char *buf = NULL; char *buf = NULL;
char *r = NULL; char *r = NULL;
char *x = NULL; char *x = NULL;
const char *p; const char *p = NULL;
size_t i, l; size_t i, l;
r = ssh_path_expand_tilde(s); r = ssh_path_expand_tilde(s);
@@ -1345,8 +1345,8 @@ char *ssh_path_expand_escape(ssh_session session, const char *s)
*/ */
int ssh_analyze_banner(ssh_session session, int server) int ssh_analyze_banner(ssh_session session, int server)
{ {
const char *banner; const char *banner = NULL;
const char *openssh; const char *openssh = NULL;
if (server) { if (server) {
banner = session->clientbanner; banner = session->clientbanner;
@@ -1397,6 +1397,7 @@ int ssh_analyze_banner(ssh_session session, int server)
char *tmp = NULL; char *tmp = NULL;
unsigned long int major = 0UL; unsigned long int major = 0UL;
unsigned long int minor = 0UL; unsigned long int minor = 0UL;
int off = 0;
/* /*
* The banner is typical: * The banner is typical:
@@ -1416,8 +1417,9 @@ int ssh_analyze_banner(ssh_session session, int server)
} }
errno = 0; errno = 0;
minor = strtoul(openssh + 10, &tmp, 10); off = major >= 10 ? 11 : 10;
if ((tmp == (openssh + 10)) || minor = strtoul(openssh + off, &tmp, 10);
if ((tmp == (openssh + off)) ||
((errno == ERANGE) && (major == ULONG_MAX)) || ((errno == ERANGE) && (major == ULONG_MAX)) ||
((errno != 0) && (major == 0)) || ((errno != 0) && (major == 0)) ||
(minor > 100)) { (minor > 100)) {

View File

@@ -67,7 +67,7 @@
*/ */
int ssh_options_copy(ssh_session src, ssh_session *dest) int ssh_options_copy(ssh_session src, ssh_session *dest)
{ {
ssh_session new; ssh_session new = NULL;
struct ssh_iterator *it = NULL; struct ssh_iterator *it = NULL;
struct ssh_list *list = NULL; struct ssh_list *list = NULL;
char *id = NULL; char *id = NULL;
@@ -311,7 +311,14 @@ int ssh_options_set_algo(ssh_session session,
* following: * following:
* *
* - SSH_OPTIONS_HOST: * - SSH_OPTIONS_HOST:
* The hostname or ip address to connect to (const char *). * The hostname or ip address to connect to. It can be also in
* the format of URI, containing also username, such as
* [username@]hostname. The IPv6 addresses can be enclosed
* within square braces, for example [::1]. The IPv4 address
* supports any format supported by OS. The hostname needs to be
* encoded to match RFC1035, so for IDN it needs to be encoded
* in punycode.
* (const char *).
* *
* - SSH_OPTIONS_PORT: * - SSH_OPTIONS_PORT:
* The port to connect to (unsigned int). * The port to connect to (unsigned int).
@@ -645,8 +652,8 @@ int ssh_options_set_algo(ssh_session session,
int ssh_options_set(ssh_session session, enum ssh_options_e type, int ssh_options_set(ssh_session session, enum ssh_options_e type,
const void *value) const void *value)
{ {
const char *v; const char *v = NULL;
char *p, *q; char *p = NULL, *q = NULL;
long int i; long int i;
unsigned int u; unsigned int u;
int rc; int rc;
@@ -1510,7 +1517,7 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
*/ */
int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value) int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
{ {
char* src = NULL; char *src = NULL;
if (session == NULL) { if (session == NULL) {
return SSH_ERROR; return SSH_ERROR;
@@ -1532,7 +1539,7 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
break; break;
case SSH_OPTIONS_IDENTITY: { case SSH_OPTIONS_IDENTITY: {
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
it = ssh_list_get_iterator(session->opts.identity); it = ssh_list_get_iterator(session->opts.identity);
if (it == NULL) { if (it == NULL) {
it = ssh_list_get_iterator(session->opts.identity_non_exp); it = ssh_list_get_iterator(session->opts.identity_non_exp);
@@ -1814,7 +1821,7 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv)
*/ */
int ssh_options_parse_config(ssh_session session, const char *filename) int ssh_options_parse_config(ssh_session session, const char *filename)
{ {
char *expanded_filename; char *expanded_filename = NULL;
int r; int r;
if (session == NULL) { if (session == NULL) {
@@ -1860,7 +1867,7 @@ out:
int ssh_options_apply(ssh_session session) int ssh_options_apply(ssh_session session)
{ {
char *tmp; char *tmp = NULL;
int rc; int rc;
if (session->opts.sshdir == NULL) { if (session->opts.sshdir == NULL) {
@@ -2209,8 +2216,8 @@ ssh_bind_options_set(ssh_bind sshbind,
const void *value) const void *value)
{ {
bool allowed; bool allowed;
char *p, *q; char *p = NULL, *q = NULL;
const char *v; const char *v = NULL;
int i, rc; int i, rc;
char **wanted_methods = sshbind->wanted_methods; char **wanted_methods = sshbind->wanted_methods;
@@ -2584,7 +2591,7 @@ static char *ssh_bind_options_expand_escape(ssh_bind sshbind, const char *s)
char *buf = NULL; char *buf = NULL;
char *r = NULL; char *r = NULL;
char *x = NULL; char *x = NULL;
const char *p; const char *p = NULL;
size_t i, l; size_t i, l;
r = ssh_path_expand_tilde(s); r = ssh_path_expand_tilde(s);
@@ -2690,7 +2697,7 @@ static char *ssh_bind_options_expand_escape(ssh_bind sshbind, const char *s)
int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename) int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename)
{ {
int rc = 0; int rc = 0;
char *expanded_filename; char *expanded_filename = NULL;
if (sshbind == NULL) { if (sshbind == NULL) {
return -1; return -1;

View File

@@ -52,9 +52,9 @@
static ssh_packet_callback default_packet_handlers[]= { static ssh_packet_callback default_packet_handlers[]= {
ssh_packet_disconnect_callback, // SSH2_MSG_DISCONNECT 1 ssh_packet_disconnect_callback, // SSH2_MSG_DISCONNECT 1
ssh_packet_ignore_callback, // SSH2_MSG_IGNORE 2 ssh_packet_ignore_callback, // SSH2_MSG_IGNORE 2
ssh_packet_unimplemented, // SSH2_MSG_UNIMPLEMENTED 3 ssh_packet_unimplemented, // SSH2_MSG_UNIMPLEMENTED 3
ssh_packet_ignore_callback, // SSH2_MSG_DEBUG 4 ssh_packet_debug_callback, // SSH2_MSG_DEBUG 4
#if WITH_SERVER #if WITH_SERVER
ssh_packet_service_request, // SSH2_MSG_SERVICE_REQUEST 5 ssh_packet_service_request, // SSH2_MSG_SERVICE_REQUEST 5
#else #else
@@ -294,6 +294,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
* or session_state == SSH_SESSION_STATE_INITIAL_KEX * or session_state == SSH_SESSION_STATE_INITIAL_KEX
* - dh_handshake_state == DH_STATE_INIT * - dh_handshake_state == DH_STATE_INIT
* or dh_handshake_state == DH_STATE_INIT_SENT (re-exchange) * or dh_handshake_state == DH_STATE_INIT_SENT (re-exchange)
* or dh_handshake_state == DH_STATE_REQUEST_SENT (dh-gex)
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange) * or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
* *
* Transitions: * Transitions:
@@ -313,6 +314,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
if ((session->dh_handshake_state != DH_STATE_INIT) && if ((session->dh_handshake_state != DH_STATE_INIT) &&
(session->dh_handshake_state != DH_STATE_INIT_SENT) && (session->dh_handshake_state != DH_STATE_INIT_SENT) &&
(session->dh_handshake_state != DH_STATE_REQUEST_SENT) &&
(session->dh_handshake_state != DH_STATE_FINISHED)) (session->dh_handshake_state != DH_STATE_FINISHED))
{ {
rc = SSH_PACKET_DENIED; rc = SSH_PACKET_DENIED;
@@ -366,7 +368,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */ * */
if (!session->server) { if (session->client) {
rc = SSH_PACKET_DENIED; rc = SSH_PACKET_DENIED;
break; break;
} }
@@ -389,6 +391,8 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
// SSH2_MSG_ECMQV_REPLY: // 31 // SSH2_MSG_ECMQV_REPLY: // 31
// SSH2_MSG_KEX_DH_GEX_GROUP: // 31 // SSH2_MSG_KEX_DH_GEX_GROUP: // 31
/* Client only */
/* /*
* States required: * States required:
* - session_state == SSH_SESSION_STATE_DH * - session_state == SSH_SESSION_STATE_DH
@@ -399,6 +403,11 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */ * */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_DH) { if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED; rc = SSH_PACKET_DENIED;
break; break;
@@ -413,15 +422,98 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
rc = SSH_PACKET_ALLOWED; rc = SSH_PACKET_ALLOWED;
break; break;
case SSH2_MSG_KEX_DH_GEX_INIT: // 32 case SSH2_MSG_KEX_DH_GEX_INIT: // 32
/* TODO Not filtered */ /* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_GROUP_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_GROUP_SENT
* then calls ssh_packet_server_dhgex_init which triggers:
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
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_GROUP_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED; rc = SSH_PACKET_ALLOWED;
break; break;
case SSH2_MSG_KEX_DH_GEX_REPLY: // 33 case SSH2_MSG_KEX_DH_GEX_REPLY: // 33
/* TODO Not filtered */
/* Client only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
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; rc = SSH_PACKET_ALLOWED;
break; break;
case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34 case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34
/* TODO Not filtered */
/* 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 ssh_packet_server_dhgex_request which triggers:
* - session->dh_handshake_state = DH_STATE_GROUP_SENT
* */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
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; rc = SSH_PACKET_ALLOWED;
break; break;
case SSH2_MSG_USERAUTH_REQUEST: // 50 case SSH2_MSG_USERAUTH_REQUEST: // 50
@@ -1303,7 +1395,6 @@ ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
ssh_buffer_pass_bytes_end(session->in_buffer, padding); ssh_buffer_pass_bytes_end(session->in_buffer, padding);
compsize = ssh_buffer_get_len(session->in_buffer); compsize = ssh_buffer_get_len(session->in_buffer);
#ifdef WITH_ZLIB
if (crypto && crypto->do_compress_in && if (crypto && crypto->do_compress_in &&
ssh_buffer_get_len(session->in_buffer) > 0) { ssh_buffer_get_len(session->in_buffer) > 0) {
rc = decompress_buffer(session, session->in_buffer, rc = decompress_buffer(session, session->in_buffer,
@@ -1312,7 +1403,6 @@ ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
goto error; goto error;
} }
} }
#endif /* WITH_ZLIB */
payloadsize = ssh_buffer_get_len(session->in_buffer); payloadsize = ssh_buffer_get_len(session->in_buffer);
if (session->recv_seq == UINT32_MAX) { if (session->recv_seq == UINT32_MAX) {
/* Overflowing sequence numbers is always fishy */ /* Overflowing sequence numbers is always fishy */
@@ -1430,8 +1520,8 @@ error:
static void ssh_packet_socket_controlflow_callback(int code, void *userdata) static void ssh_packet_socket_controlflow_callback(int code, void *userdata)
{ {
ssh_session session = userdata; ssh_session session = userdata;
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
ssh_channel channel; ssh_channel channel = NULL;
if (code == SSH_SOCKET_FLOW_WRITEWONTBLOCK) { if (code == SSH_SOCKET_FLOW_WRITEWONTBLOCK) {
SSH_LOG(SSH_LOG_TRACE, "sending channel_write_wontblock callback"); SSH_LOG(SSH_LOG_TRACE, "sending channel_write_wontblock callback");
@@ -1704,7 +1794,6 @@ static int packet_send2(ssh_session session)
lenfield_blocksize = 0; lenfield_blocksize = 0;
} }
#ifdef WITH_ZLIB
if (crypto != NULL && crypto->do_compress_out && if (crypto != NULL && crypto->do_compress_out &&
ssh_buffer_get_len(session->out_buffer) > 0) { ssh_buffer_get_len(session->out_buffer) > 0) {
rc = compress_buffer(session,session->out_buffer); rc = compress_buffer(session,session->out_buffer);
@@ -1713,7 +1802,6 @@ static int packet_send2(ssh_session session)
} }
currentlen = ssh_buffer_get_len(session->out_buffer); currentlen = ssh_buffer_get_len(session->out_buffer);
} }
#endif /* WITH_ZLIB */
compsize = currentlen; compsize = currentlen;
/* compressed payload + packet len (4) + padding_size len (1) */ /* compressed payload + packet len (4) + padding_size len (1) */
/* totallen - lenfield_blocksize - etm_packet_offset must be equal to 0 (mod blocksize) */ /* totallen - lenfield_blocksize - etm_packet_offset must be equal to 0 (mod blocksize) */
@@ -1894,7 +1982,7 @@ int ssh_packet_send(ssh_session session)
/* We finished the key exchange so we can try to send our queue now */ /* We finished the key exchange so we can try to send our queue now */
if (rc == SSH_OK && type == SSH2_MSG_NEWKEYS) { if (rc == SSH_OK && type == SSH2_MSG_NEWKEYS) {
struct ssh_iterator *it; struct ssh_iterator *it = NULL;
if (session->flags & SSH_SESSION_FLAG_KEX_STRICT) { if (session->flags & SSH_SESSION_FLAG_KEX_STRICT) {
/* reset packet sequence number when running in strict kex mode */ /* reset packet sequence number when running in strict kex mode */

View File

@@ -92,7 +92,7 @@ SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback)
/** /**
* @internal * @internal
* *
* @brief Handle a SSH_IGNORE and SSH_DEBUG packet. * @brief Handle a SSH_IGNORE packet.
*/ */
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback) SSH_PACKET_CALLBACK(ssh_packet_ignore_callback)
{ {
@@ -101,11 +101,37 @@ SSH_PACKET_CALLBACK(ssh_packet_ignore_callback)
(void)type; (void)type;
(void)packet; (void)packet;
SSH_LOG(SSH_LOG_DEBUG, SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_IGNORE packet");
"Received %s packet",
type == SSH2_MSG_IGNORE ? "SSH_MSG_IGNORE" : "SSH_MSG_DEBUG"); return SSH_PACKET_USED;
}
/**
* @internal
*
* @brief Handle a SSH_DEBUG packet.
*/
SSH_PACKET_CALLBACK(ssh_packet_debug_callback)
{
uint8_t always_display = -1;
char *message = NULL;
int rc;
(void)session; /* unused */
(void)type;
(void)user;
rc = ssh_buffer_unpack(packet, "bs", &always_display, &message);
if (rc != SSH_OK) {
SSH_LOG(SSH_LOG_PACKET, "Error reading debug message");
return SSH_PACKET_USED;
}
SSH_LOG(SSH_LOG_DEBUG,
"Received SSH_MSG_DEBUG packet with message %s%s",
message,
always_display != 0 ? " (always display)" : "");
SAFE_FREE(message);
/* TODO: handle a graceful disconnect */
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }

View File

@@ -262,7 +262,7 @@ int ssh_packet_hmac_verify(ssh_session session,
{ {
struct ssh_crypto_struct *crypto = NULL; struct ssh_crypto_struct *crypto = NULL;
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0}; unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
HMACCTX ctx; HMACCTX ctx = NULL;
size_t hmaclen = DIGEST_MAX_LEN; size_t hmaclen = DIGEST_MAX_LEN;
uint32_t seq; uint32_t seq;
int cmp; int cmp;

View File

@@ -344,7 +344,7 @@ enum ssh_digest_e ssh_key_hash_from_name(const char *name)
*/ */
int ssh_key_algorithm_allowed(ssh_session session, const char *type) int ssh_key_algorithm_allowed(ssh_session session, const char *type)
{ {
const char *allowed_list; const char *allowed_list = NULL;
if (session->client) { if (session->client) {
allowed_list = session->opts.pubkey_accepted_types; allowed_list = session->opts.pubkey_accepted_types;
@@ -711,7 +711,7 @@ int ssh_key_cmp(const ssh_key k1,
ssh_signature ssh_signature_new(void) ssh_signature ssh_signature_new(void)
{ {
struct ssh_signature_struct *sig; struct ssh_signature_struct *sig = NULL;
sig = malloc(sizeof(struct ssh_signature_struct)); sig = malloc(sizeof(struct ssh_signature_struct));
if (sig == NULL) { if (sig == NULL) {
@@ -799,7 +799,7 @@ int ssh_pki_import_privkey_base64(const char *b64_key,
void *auth_data, void *auth_data,
ssh_key *pkey) ssh_key *pkey)
{ {
ssh_key key; ssh_key key = NULL;
char *openssh_header = NULL; char *openssh_header = NULL;
if (b64_key == NULL || pkey == NULL) { if (b64_key == NULL || pkey == NULL) {
@@ -979,8 +979,8 @@ int ssh_pki_import_privkey_file(const char *filename,
void *auth_data, void *auth_data,
ssh_key *pkey) { ssh_key *pkey) {
struct stat sb; struct stat sb;
char *key_buf; char *key_buf = NULL;
FILE *file; FILE *file = NULL;
off_t size; off_t size;
int rc; int rc;
char err_msg[SSH_ERRNO_MSG_MAX] = {0}; char err_msg[SSH_ERRNO_MSG_MAX] = {0};
@@ -1180,8 +1180,8 @@ ssh_pki_export_privkey_file(const ssh_key privkey,
/* temporary function to migrate seamlessly to ssh_key */ /* temporary function to migrate seamlessly to ssh_key */
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key) ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
{ {
ssh_public_key pub; ssh_public_key pub = NULL;
ssh_key tmp; ssh_key tmp = NULL;
if (key == NULL) { if (key == NULL) {
return NULL; return NULL;
@@ -1219,7 +1219,7 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key) ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key)
{ {
ssh_private_key privkey; ssh_private_key privkey = NULL;
privkey = calloc(1, sizeof(struct ssh_private_key_struct)); privkey = calloc(1, sizeof(struct ssh_private_key_struct));
if (privkey == NULL) { if (privkey == NULL) {
@@ -1536,9 +1536,9 @@ static int pki_import_cert_buffer(ssh_buffer buffer,
enum ssh_keytypes_e type, enum ssh_keytypes_e type,
ssh_key *pkey) ssh_key *pkey)
{ {
ssh_buffer cert; ssh_buffer cert = NULL;
ssh_string tmp_s; ssh_string tmp_s = NULL;
const char *type_c; const char *type_c = NULL;
ssh_key key = NULL; ssh_key key = NULL;
int rc; int rc;
@@ -2105,7 +2105,7 @@ error:
int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey, int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey,
ssh_key *pkey) ssh_key *pkey)
{ {
ssh_key pubkey; ssh_key pubkey = NULL;
if (privkey == NULL || !ssh_key_is_private(privkey)) { if (privkey == NULL || !ssh_key_is_private(privkey)) {
return SSH_ERROR; return SSH_ERROR;
@@ -2143,7 +2143,7 @@ int ssh_pki_export_privkey_to_pubkey(const ssh_key privkey,
int ssh_pki_export_pubkey_blob(const ssh_key key, int ssh_pki_export_pubkey_blob(const ssh_key key,
ssh_string *pblob) ssh_string *pblob)
{ {
ssh_string blob; ssh_string blob = NULL;
if (key == NULL) { if (key == NULL) {
return SSH_OK; return SSH_OK;
@@ -2178,7 +2178,7 @@ int ssh_pki_export_pubkey_blob(const ssh_key key,
int ssh_pki_export_privkey_blob(const ssh_key key, int ssh_pki_export_privkey_blob(const ssh_key key,
ssh_string *pblob) ssh_string *pblob)
{ {
ssh_string blob; ssh_string blob = NULL;
if (key == NULL) { if (key == NULL) {
return SSH_OK; return SSH_OK;
@@ -2208,8 +2208,8 @@ int ssh_pki_export_privkey_blob(const ssh_key key,
int ssh_pki_export_pubkey_base64(const ssh_key key, int ssh_pki_export_pubkey_base64(const ssh_key key,
char **b64_key) char **b64_key)
{ {
ssh_string key_blob; ssh_string key_blob = NULL;
unsigned char *b64; unsigned char *b64 = NULL;
if (key == NULL || b64_key == NULL) { if (key == NULL || b64_key == NULL) {
return SSH_ERROR; return SSH_ERROR;
@@ -2248,9 +2248,9 @@ int ssh_pki_export_pubkey_file(const ssh_key key,
{ {
char key_buf[MAX_LINE_SIZE]; char key_buf[MAX_LINE_SIZE];
char host[256]; char host[256];
char *b64_key; char *b64_key = NULL;
char *user; char *user = NULL;
FILE *fp; FILE *fp = NULL;
int rc; int rc;
if (key == NULL || filename == NULL || *filename == '\0') { if (key == NULL || filename == NULL || *filename == '\0') {
@@ -2311,7 +2311,7 @@ int ssh_pki_export_pubkey_file(const ssh_key key,
* @returns SSH_OK on success, SSH_ERROR otherwise. * @returns SSH_OK on success, SSH_ERROR otherwise.
**/ **/
int ssh_pki_copy_cert_to_privkey(const ssh_key certkey, ssh_key privkey) { int ssh_pki_copy_cert_to_privkey(const ssh_key certkey, ssh_key privkey) {
ssh_buffer cert_buffer; ssh_buffer cert_buffer = NULL;
int rc, cmp; int rc, cmp;
if (certkey == NULL || privkey == NULL) { if (certkey == NULL || privkey == NULL) {
@@ -2352,7 +2352,7 @@ int ssh_pki_export_signature_blob(const ssh_signature sig,
ssh_string *sig_blob) ssh_string *sig_blob)
{ {
ssh_buffer buf = NULL; ssh_buffer buf = NULL;
ssh_string str; ssh_string str = NULL;
int rc; int rc;
if (sig == NULL || sig_blob == NULL) { if (sig == NULL || sig_blob == NULL) {
@@ -2416,7 +2416,7 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
enum ssh_keytypes_e type; enum ssh_keytypes_e type;
enum ssh_digest_e hash_type; enum ssh_digest_e hash_type;
ssh_string algorithm = NULL, blob = NULL; ssh_string algorithm = NULL, blob = NULL;
ssh_buffer buf; ssh_buffer buf = NULL;
const char *alg = NULL; const char *alg = NULL;
uint8_t flags = 0; uint8_t flags = 0;
uint32_t counter = 0; uint32_t counter = 0;
@@ -2637,10 +2637,14 @@ int ssh_pki_signature_verify(ssh_session session,
return SSH_ERROR; return SSH_ERROR;
} }
rc = ssh_buffer_pack(sk_buffer, "PbdP", rc = ssh_buffer_pack(sk_buffer,
SHA256_DIGEST_LEN, application_hash, "PbdP",
sig->sk_flags, sig->sk_counter, (size_t)SHA256_DIGEST_LEN,
SHA256_DIGEST_LEN, input_hash); application_hash,
sig->sk_flags,
sig->sk_counter,
(size_t)SHA256_DIGEST_LEN,
input_hash);
if (rc != SSH_OK) { if (rc != SSH_OK) {
SSH_BUFFER_FREE(sk_buffer); SSH_BUFFER_FREE(sk_buffer);
explicit_bzero(input_hash, SHA256_DIGEST_LEN); explicit_bzero(input_hash, SHA256_DIGEST_LEN);
@@ -2734,7 +2738,8 @@ ssh_string ssh_pki_do_sign(ssh_session session,
rc = ssh_buffer_pack(sign_input, rc = ssh_buffer_pack(sign_input,
"SP", "SP",
session_id, session_id,
ssh_buffer_get_len(sigbuf), ssh_buffer_get(sigbuf)); (size_t)ssh_buffer_get_len(sigbuf),
ssh_buffer_get(sigbuf));
if (rc != SSH_OK) { if (rc != SSH_OK) {
goto end; goto end;
} }
@@ -2767,9 +2772,9 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
const ssh_key pubkey) const ssh_key pubkey)
{ {
struct ssh_crypto_struct *crypto = NULL; struct ssh_crypto_struct *crypto = NULL;
ssh_string session_id; ssh_string session_id = NULL;
ssh_string sig_blob; ssh_string sig_blob = NULL;
ssh_buffer sig_buf; ssh_buffer sig_buf = NULL;
int rc; int rc;
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH); crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);

View File

@@ -234,12 +234,12 @@ ssh_pki_openssh_import(const char *text_key,
bool private) bool private)
{ {
const char *ptr = text_key; const char *ptr = text_key;
const char *end; const char *end = NULL;
char *base64; char *base64 = NULL;
int cmp; int cmp;
int rc; int rc;
int i; int i;
ssh_buffer buffer = NULL, privkey_buffer=NULL; ssh_buffer buffer = NULL, privkey_buffer = NULL;
char *magic = NULL, *ciphername = NULL, *kdfname = NULL; char *magic = NULL, *ciphername = NULL, *kdfname = NULL;
uint32_t nkeys = 0, checkint1 = 0, checkint2 = 0xFFFF; uint32_t nkeys = 0, checkint1 = 0, checkint2 = 0xFFFF;
ssh_string kdfoptions = NULL; ssh_string kdfoptions = NULL;
@@ -507,14 +507,14 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
{ {
ssh_buffer buffer = NULL; ssh_buffer buffer = NULL;
ssh_string str = NULL, blob = NULL; ssh_string str = NULL, blob = NULL;
ssh_string pubkey_s=NULL; ssh_string pubkey_s = NULL;
ssh_buffer privkey_buffer = NULL; ssh_buffer privkey_buffer = NULL;
uint32_t rnd; uint32_t rnd;
uint32_t rounds = 16; uint32_t rounds = 16;
ssh_string salt=NULL; ssh_string salt = NULL;
ssh_string kdf_options=NULL; ssh_string kdf_options = NULL;
int to_encrypt=0; int to_encrypt=0;
unsigned char *b64; unsigned char *b64 = NULL;
uint32_t str_len, len; uint32_t str_len, len;
uint8_t padding = 1; uint8_t padding = 1;
int ok; int ok;
@@ -552,7 +552,8 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
"ddPs", "ddPs",
rnd, /* checkint 1 & 2 */ rnd, /* checkint 1 & 2 */
rnd, rnd,
ssh_string_len(blob), ssh_string_data(blob), ssh_string_len(blob),
ssh_string_data(blob),
"" /* comment */); "" /* comment */);
if (rc == SSH_ERROR){ if (rc == SSH_ERROR){
goto error; goto error;
@@ -621,15 +622,17 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
rc = ssh_buffer_pack(buffer, rc = ssh_buffer_pack(buffer,
"PssSdSdP", "PssSdSdP",
(size_t)strlen(OPENSSH_AUTH_MAGIC) + 1, OPENSSH_AUTH_MAGIC, strlen(OPENSSH_AUTH_MAGIC) + 1,
OPENSSH_AUTH_MAGIC,
to_encrypt ? "aes128-cbc" : "none", /* ciphername */ to_encrypt ? "aes128-cbc" : "none", /* ciphername */
to_encrypt ? "bcrypt" : "none", /* kdfname */ to_encrypt ? "bcrypt" : "none", /* kdfname */
kdf_options, /* kdfoptions */ kdf_options, /* kdfoptions */
(uint32_t) 1, /* nkeys */ (uint32_t)1, /* nkeys */
pubkey_s, pubkey_s,
(uint32_t)ssh_buffer_get_len(privkey_buffer), ssh_buffer_get_len(privkey_buffer),
/* rest of buffer is a string */ /* rest of buffer is a string */
(size_t)ssh_buffer_get_len(privkey_buffer), ssh_buffer_get(privkey_buffer)); (size_t)ssh_buffer_get_len(privkey_buffer),
ssh_buffer_get(privkey_buffer));
if (rc != SSH_OK) { if (rc != SSH_OK) {
goto error; goto error;
} }

View File

@@ -46,7 +46,6 @@
#include <openssl/param_build.h> #include <openssl/param_build.h>
#if defined(WITH_PKCS11_URI) && defined(WITH_PKCS11_PROVIDER) #if defined(WITH_PKCS11_URI) && defined(WITH_PKCS11_PROVIDER)
#include <openssl/store.h> #include <openssl/store.h>
#include <openssl/provider.h>
#endif #endif
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
@@ -338,7 +337,7 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
int ok; int ok;
#else #else
const char *group_name = OSSL_EC_curve_nid2name(nid); const char *group_name = OSSL_EC_curve_nid2name(nid);
OSSL_PARAM_BLD *param_bld; OSSL_PARAM_BLD *param_bld = NULL;
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
key->ecdsa_nid = nid; key->ecdsa_nid = nid;
@@ -1429,6 +1428,8 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
if (buffer == NULL) { if (buffer == NULL) {
return NULL; return NULL;
} }
/* The buffer will contain sensitive information. Make sure it is erased */
ssh_buffer_set_secure(buffer);
if (key->cert != NULL) { if (key->cert != NULL) {
rc = ssh_buffer_add_buffer(buffer, key->cert); rc = ssh_buffer_add_buffer(buffer, key->cert);
@@ -1632,6 +1633,7 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
bignum_safe_free(bn); bignum_safe_free(bn);
bignum_safe_free(be); bignum_safe_free(be);
OSSL_PARAM_free(params); OSSL_PARAM_free(params);
params = NULL;
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
break; break;
} }
@@ -1665,7 +1667,7 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
EC_GROUP *group = NULL; EC_GROUP *group = NULL;
EC_POINT *point = NULL; EC_POINT *point = NULL;
const void *pubkey; const void *pubkey = NULL;
size_t pubkey_len; size_t pubkey_len;
OSSL_PARAM *locate_param = NULL; OSSL_PARAM *locate_param = NULL;
#else #else
@@ -1803,6 +1805,7 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
bignum_safe_free(bd); bignum_safe_free(bd);
OSSL_PARAM_free(params); OSSL_PARAM_free(params);
params = NULL;
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
break; break;
} }
@@ -1871,7 +1874,7 @@ static ssh_string pki_ecdsa_signature_to_blob(const ssh_signature sig)
const unsigned char *raw_sig_data = NULL; const unsigned char *raw_sig_data = NULL;
size_t raw_sig_len; size_t raw_sig_len;
ECDSA_SIG *ecdsa_sig; ECDSA_SIG *ecdsa_sig = NULL;
int rc; int rc;
@@ -2060,8 +2063,8 @@ static int pki_signature_from_ecdsa_blob(UNUSED_PARAM(const ssh_key pubkey),
ECDSA_SIG *ecdsa_sig = NULL; ECDSA_SIG *ecdsa_sig = NULL;
BIGNUM *pr = NULL, *ps = NULL; BIGNUM *pr = NULL, *ps = NULL;
ssh_string r; ssh_string r = NULL;
ssh_string s; ssh_string s = NULL;
ssh_buffer buf = NULL; ssh_buffer buf = NULL;
uint32_t rlen; uint32_t rlen;
@@ -2078,6 +2081,9 @@ static int pki_signature_from_ecdsa_blob(UNUSED_PARAM(const ssh_key pubkey),
return SSH_ERROR; return SSH_ERROR;
} }
/* The buffer will contain sensitive information. Make sure it is erased */
ssh_buffer_set_secure(buf);
rc = ssh_buffer_add_data(buf, rc = ssh_buffer_add_data(buf,
ssh_string_data(sig_blob), ssh_string_data(sig_blob),
ssh_string_len(sig_blob)); ssh_string_len(sig_blob));
@@ -2714,9 +2720,6 @@ error:
} }
#ifdef WITH_PKCS11_URI #ifdef WITH_PKCS11_URI
#ifdef WITH_PKCS11_PROVIDER
static bool pkcs11_provider_failed = false;
#endif
/** /**
* @internal * @internal
@@ -2782,19 +2785,10 @@ int pki_uri_import(const char *uri_name,
/* The provider can be either configured in openssl.cnf or dynamically /* The provider can be either configured in openssl.cnf or dynamically
* loaded, assuming it does not need any special configuration */ * loaded, assuming it does not need any special configuration */
if (OSSL_PROVIDER_available(NULL, "pkcs11") == 0 && rv = pki_load_pkcs11_provider();
!pkcs11_provider_failed) { if (rv != SSH_OK) {
OSSL_PROVIDER *pkcs11_provider = NULL; SSH_LOG(SSH_LOG_TRACE, "Failed to load or initialize pkcs11 provider");
goto fail;
pkcs11_provider = OSSL_PROVIDER_try_load(NULL, "pkcs11", 1);
if (pkcs11_provider == NULL) {
SSH_LOG(SSH_LOG_TRACE,
"Failed to initialize provider: %s",
ERR_error_string(ERR_get_error(), NULL));
/* Do not attempt to load it again */
pkcs11_provider_failed = true;
goto fail;
}
} }
store = OSSL_STORE_open(uri_name, NULL, NULL, NULL, NULL); store = OSSL_STORE_open(uri_name, NULL, NULL, NULL, NULL);

View File

@@ -62,7 +62,7 @@ int pki_ed25519_sign(const ssh_key privkey,
size_t hlen) size_t hlen)
{ {
int rc; int rc;
uint8_t *buffer; uint8_t *buffer = NULL;
uint64_t dlen = 0; uint64_t dlen = 0;
buffer = malloc(hlen + ED25519_SIG_LEN); buffer = malloc(hlen + ED25519_SIG_LEN);
@@ -104,8 +104,8 @@ int pki_ed25519_verify(const ssh_key pubkey,
size_t hlen) size_t hlen)
{ {
uint64_t mlen = 0; uint64_t mlen = 0;
uint8_t *buffer; uint8_t *buffer = NULL;
uint8_t *buffer2; uint8_t *buffer2 = NULL;
int rc; int rc;
if (pubkey == NULL || sig == NULL || if (pubkey == NULL || sig == NULL ||

View File

@@ -245,7 +245,7 @@ int pki_ed25519_private_key_to_blob(ssh_buffer buffer, const ssh_key privkey)
*/ */
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig) ssh_string pki_ed25519_signature_to_blob(ssh_signature sig)
{ {
ssh_string sig_blob; ssh_string sig_blob = NULL;
int rc; int rc;
#ifdef HAVE_LIBCRYPTO #ifdef HAVE_LIBCRYPTO

View File

@@ -150,7 +150,7 @@ static ssh_string asn1_get_int(ssh_buffer buffer) {
static ssh_string asn1_get_bit_string(ssh_buffer buffer) static ssh_string asn1_get_bit_string(ssh_buffer buffer)
{ {
ssh_string str; ssh_string str = NULL;
unsigned char type; unsigned char type;
uint32_t size; uint32_t size;
unsigned char unused, last, *p = NULL; unsigned char unused, last, *p = NULL;
@@ -1409,6 +1409,8 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
if (buffer == NULL) { if (buffer == NULL) {
return NULL; return NULL;
} }
/* The buffer will contain sensitive information. Make sure it is erased */
ssh_buffer_set_secure(buffer);
if (key->cert != NULL) { if (key->cert != NULL) {
rc = ssh_buffer_add_buffer(buffer, key->cert); rc = ssh_buffer_add_buffer(buffer, key->cert);
@@ -1694,9 +1696,9 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
case SSH_KEYTYPE_ECDSA_P521: case SSH_KEYTYPE_ECDSA_P521:
#ifdef HAVE_GCRYPT_ECC #ifdef HAVE_GCRYPT_ECC
{ {
ssh_string R; ssh_string R = NULL;
ssh_string S; ssh_string S = NULL;
ssh_buffer b; ssh_buffer b = NULL;
b = ssh_buffer_new(); b = ssh_buffer_new();
if (b == NULL) { if (b == NULL) {
@@ -1837,8 +1839,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
case SSH_KEYTYPE_SK_ECDSA: case SSH_KEYTYPE_SK_ECDSA:
#ifdef HAVE_GCRYPT_ECC #ifdef HAVE_GCRYPT_ECC
{ /* build ecdsa siganature */ { /* build ecdsa siganature */
ssh_buffer b; ssh_buffer b = NULL;
ssh_string r, s; ssh_string r = NULL, s = NULL;
uint32_t rlen; uint32_t rlen;
b = ssh_buffer_new(); b = ssh_buffer_new();
@@ -1846,6 +1848,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_signature_free(sig); ssh_signature_free(sig);
return NULL; return NULL;
} }
/* The buffer will contain sensitive information. */
ssh_buffer_set_secure(b);
rc = ssh_buffer_add_data(b, rc = ssh_buffer_add_data(b,
ssh_string_data(sig_blob), ssh_string_data(sig_blob),

View File

@@ -864,7 +864,12 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
ssh_string type_s = NULL; ssh_string type_s = NULL;
ssh_string e = NULL; ssh_string e = NULL;
ssh_string n = NULL; ssh_string n = NULL;
ssh_string p = NULL;
ssh_string q = NULL;
ssh_string d = NULL;
ssh_string iqmp = NULL;
ssh_string str = NULL; ssh_string str = NULL;
int rc;
#if MBEDTLS_VERSION_MAJOR > 2 #if MBEDTLS_VERSION_MAJOR > 2
mbedtls_mpi E = {0}; mbedtls_mpi E = {0};
mbedtls_mpi N = {0}; mbedtls_mpi N = {0};
@@ -872,18 +877,21 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
mbedtls_mpi IQMP = {0}; mbedtls_mpi IQMP = {0};
mbedtls_mpi P = {0}; mbedtls_mpi P = {0};
mbedtls_mpi Q = {0}; mbedtls_mpi Q = {0};
#endif
int rc;
#if MBEDTLS_VERSION_MAJOR > 2
mbedtls_mpi_init(&E); mbedtls_mpi_init(&E);
mbedtls_mpi_init(&N); mbedtls_mpi_init(&N);
mbedtls_mpi_init(&D);
mbedtls_mpi_init(&IQMP);
mbedtls_mpi_init(&P);
mbedtls_mpi_init(&Q);
#endif #endif
buffer = ssh_buffer_new(); buffer = ssh_buffer_new();
if (buffer == NULL) { if (buffer == NULL) {
return NULL; return NULL;
} }
/* The buffer will contain sensitive information. Make sure it is erased */
ssh_buffer_set_secure(buffer);
if (key->cert != NULL) { if (key->cert != NULL) {
rc = ssh_buffer_add_buffer(buffer, key->cert); rc = ssh_buffer_add_buffer(buffer, key->cert);
@@ -909,279 +917,241 @@ ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type)
} }
switch (key->type) { switch (key->type) {
case SSH_KEYTYPE_RSA: { case SSH_KEYTYPE_RSA: {
mbedtls_rsa_context *rsa; mbedtls_rsa_context *rsa = NULL;
if (mbedtls_pk_can_do(key->pk, MBEDTLS_PK_RSA) == 0) { mbedtls_mpi *E_ptr = NULL, *N_ptr = NULL;
SSH_BUFFER_FREE(buffer);
return NULL;
}
rsa = mbedtls_pk_rsa(*key->pk); if (mbedtls_pk_can_do(key->pk, MBEDTLS_PK_RSA) == 0) {
SSH_BUFFER_FREE(buffer);
#if MBEDTLS_VERSION_MAJOR > 2 return NULL;
rc = mbedtls_rsa_export(rsa, &N, NULL, NULL, NULL, &E);
if (rc != 0) {
goto fail;
}
e = ssh_make_bignum_string(&E);
if (e == NULL) {
goto fail;
}
n = ssh_make_bignum_string(&N);
if (n == NULL) {
goto fail;
}
#else
e = ssh_make_bignum_string(&rsa->E);
if (e == NULL) {
goto fail;
}
n = ssh_make_bignum_string(&rsa->N);
if (n == NULL) {
goto fail;
}
#endif
if (type == SSH_KEY_PUBLIC) {
/* The N and E parts are swapped in the public key export ! */
rc = ssh_buffer_add_ssh_string(buffer, e);
if (rc < 0) {
goto fail;
}
rc = ssh_buffer_add_ssh_string(buffer, n);
if (rc < 0) {
goto fail;
}
} else if (type == SSH_KEY_PRIVATE) {
ssh_string p = NULL;
ssh_string q = NULL;
ssh_string d = NULL;
ssh_string iqmp = NULL;
rc = ssh_buffer_add_ssh_string(buffer, n);
if (rc < 0) {
goto fail;
}
rc = ssh_buffer_add_ssh_string(buffer, e);
if (rc < 0) {
goto fail;
}
#if MBEDTLS_VERSION_MAJOR > 2
rc = mbedtls_rsa_export(rsa, NULL, &P, &Q, &D, NULL);
if (rc != 0) {
goto fail;
}
p = ssh_make_bignum_string(&P);
if (p == NULL) {
goto fail;
}
q = ssh_make_bignum_string(&Q);
if (q == NULL) {
goto fail;
}
d = ssh_make_bignum_string(&D);
if (d == NULL) {
goto fail;
}
rc = mbedtls_rsa_export_crt(rsa, NULL, NULL, &IQMP);
if (rc != 0) {
goto fail;
}
iqmp = ssh_make_bignum_string(&IQMP);
if (iqmp == NULL) {
goto fail;
}
#else
p = ssh_make_bignum_string(&rsa->P);
if (p == NULL) {
goto fail;
}
q = ssh_make_bignum_string(&rsa->Q);
if (q == NULL) {
goto fail;
}
d = ssh_make_bignum_string(&rsa->D);
if (d == NULL) {
goto fail;
}
iqmp = ssh_make_bignum_string(&rsa->QP);
if (iqmp == NULL) {
goto fail;
}
#endif
rc = ssh_buffer_add_ssh_string(buffer, d);
if (rc < 0) {
goto fail;
}
rc = ssh_buffer_add_ssh_string(buffer, iqmp);
if (rc < 0) {
goto fail;
}
rc = ssh_buffer_add_ssh_string(buffer, p);
if (rc < 0) {
goto fail;
}
rc = ssh_buffer_add_ssh_string(buffer, q);
if (rc < 0) {
goto fail;
}
ssh_string_burn(d);
SSH_STRING_FREE(d);
d = NULL;
ssh_string_burn(iqmp);
SSH_STRING_FREE(iqmp);
iqmp = NULL;
ssh_string_burn(p);
SSH_STRING_FREE(p);
p = NULL;
ssh_string_burn(q);
SSH_STRING_FREE(q);
q = NULL;
}
ssh_string_burn(e);
SSH_STRING_FREE(e);
e = NULL;
ssh_string_burn(n);
SSH_STRING_FREE(n);
n = NULL;
break;
} }
case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521:
case SSH_KEYTYPE_SK_ECDSA:
type_s =
ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid));
if (type_s == NULL) {
SSH_BUFFER_FREE(buffer);
return NULL;
}
rc = ssh_buffer_add_ssh_string(buffer, type_s); rsa = mbedtls_pk_rsa(*key->pk);
SSH_STRING_FREE(type_s); #if MBEDTLS_VERSION_MAJOR > 2
rc = mbedtls_rsa_export(rsa, &N, NULL, NULL, NULL, &E);
if (rc != 0) {
goto out;
}
E_ptr = &E;
N_ptr = &N;
#else
E_ptr = &rsa->E;
N_ptr = &rsa->N;
#endif
e = ssh_make_bignum_string(E_ptr);
if (e == NULL) {
goto out;
}
n = ssh_make_bignum_string(N_ptr);
if (n == NULL) {
goto out;
}
if (type == SSH_KEY_PUBLIC) {
/* The N and E parts are swapped in the public key export ! */
rc = ssh_buffer_add_ssh_string(buffer, e);
if (rc < 0) { if (rc < 0) {
SSH_BUFFER_FREE(buffer); goto out;
return NULL;
} }
e = make_ecpoint_string(&key->ecdsa->MBEDTLS_PRIVATE(grp), rc = ssh_buffer_add_ssh_string(buffer, n);
&key->ecdsa->MBEDTLS_PRIVATE(Q)); if (rc < 0) {
goto out;
}
} else if (type == SSH_KEY_PRIVATE) {
mbedtls_mpi *P_ptr = NULL, *Q_ptr = NULL, *D_ptr = NULL;
mbedtls_mpi *IQMP_ptr = NULL;
if (e == NULL) { rc = ssh_buffer_add_ssh_string(buffer, n);
SSH_BUFFER_FREE(buffer); if (rc < 0) {
return NULL; goto out;
} }
rc = ssh_buffer_add_ssh_string(buffer, e); rc = ssh_buffer_add_ssh_string(buffer, e);
if (rc < 0) { if (rc < 0) {
goto fail; goto out;
} }
ssh_string_burn(e); #if MBEDTLS_VERSION_MAJOR > 2
SSH_STRING_FREE(e); rc = mbedtls_rsa_export(rsa, NULL, &P, &Q, &D, NULL);
e = NULL; if (rc != 0) {
goto out;
}
if (type == SSH_KEY_PRIVATE) { rc = mbedtls_rsa_export_crt(rsa, NULL, NULL, &IQMP);
ssh_string d = NULL; if (rc != 0) {
d = ssh_make_bignum_string(&key->ecdsa->MBEDTLS_PRIVATE(d)); goto out;
}
if (d == NULL) { P_ptr = &P;
SSH_BUFFER_FREE(buffer); Q_ptr = &Q;
return NULL; D_ptr = &D;
} IQMP_ptr = &IQMP;
#else
P_ptr = &rsa->P;
Q_ptr = &rsa->Q;
D_ptr = &rsa->D;
IQMP_ptr = &rsa->QP;
#endif
rc = ssh_buffer_add_ssh_string(buffer, d); p = ssh_make_bignum_string(P_ptr);
if (rc < 0) { if (p == NULL) {
goto fail; goto out;
} }
ssh_string_burn(d); q = ssh_make_bignum_string(Q_ptr);
SSH_STRING_FREE(d); if (q == NULL) {
d = NULL; goto out;
} else if (key->type == SSH_KEYTYPE_SK_ECDSA) { }
/* public key can contain certificate sk information */
d = ssh_make_bignum_string(D_ptr);
if (d == NULL) {
goto out;
}
iqmp = ssh_make_bignum_string(IQMP_ptr);
if (iqmp == NULL) {
goto out;
}
rc = ssh_buffer_add_ssh_string(buffer, d);
if (rc < 0) {
goto out;
}
rc = ssh_buffer_add_ssh_string(buffer, iqmp);
if (rc < 0) {
goto out;
}
rc = ssh_buffer_add_ssh_string(buffer, p);
if (rc < 0) {
goto out;
}
rc = ssh_buffer_add_ssh_string(buffer, q);
if (rc < 0) {
goto out;
}
}
break;
}
case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521:
case SSH_KEYTYPE_SK_ECDSA:
type_s =
ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid));
if (type_s == NULL) {
SSH_BUFFER_FREE(buffer);
return NULL;
}
rc = ssh_buffer_add_ssh_string(buffer, type_s);
SSH_STRING_FREE(type_s);
if (rc < 0) {
SSH_BUFFER_FREE(buffer);
return NULL;
}
e = make_ecpoint_string(&key->ecdsa->MBEDTLS_PRIVATE(grp),
&key->ecdsa->MBEDTLS_PRIVATE(Q));
if (e == NULL) {
SSH_BUFFER_FREE(buffer);
return NULL;
}
rc = ssh_buffer_add_ssh_string(buffer, e);
if (rc < 0) {
goto out;
}
if (type == SSH_KEY_PRIVATE) {
d = ssh_make_bignum_string(&key->ecdsa->MBEDTLS_PRIVATE(d));
if (d == NULL) {
SSH_BUFFER_FREE(buffer);
goto out;
}
rc = ssh_buffer_add_ssh_string(buffer, d);
if (rc < 0) {
goto out;
}
} else if (key->type == SSH_KEYTYPE_SK_ECDSA) {
/* public key can contain certificate sk information */
rc = ssh_buffer_add_ssh_string(buffer, key->sk_application);
if (rc < 0) {
goto out;
}
}
break;
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_SK_ED25519:
if (type == SSH_KEY_PUBLIC) {
rc = pki_ed25519_public_key_to_blob(buffer, key);
if (rc == SSH_ERROR) {
goto out;
}
/* public key can contain certificate sk information */
if (key->type == SSH_KEYTYPE_SK_ED25519) {
rc = ssh_buffer_add_ssh_string(buffer, key->sk_application); rc = ssh_buffer_add_ssh_string(buffer, key->sk_application);
if (rc < 0) { if (rc < 0) {
goto fail; goto out;
}
}
break;
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_SK_ED25519:
if (type == SSH_KEY_PUBLIC) {
rc = pki_ed25519_public_key_to_blob(buffer, key);
if (rc == SSH_ERROR) {
goto fail;
}
/* public key can contain certificate sk information */
if (key->type == SSH_KEYTYPE_SK_ED25519) {
rc = ssh_buffer_add_ssh_string(buffer, key->sk_application);
if (rc < 0) {
goto fail;
}
}
} else {
rc = pki_ed25519_private_key_to_blob(buffer, key);
if (rc == SSH_ERROR) {
goto fail;
} }
} }
break; } else {
default: rc = pki_ed25519_private_key_to_blob(buffer, key);
goto fail; if (rc == SSH_ERROR) {
goto out;
}
}
break;
default:
goto out;
} }
makestring: makestring:
str = ssh_string_new(ssh_buffer_get_len(buffer)); str = ssh_string_new(ssh_buffer_get_len(buffer));
if (str == NULL) { if (str == NULL) {
goto fail; goto out;
} }
rc = ssh_string_fill(str, ssh_buffer_get(buffer), rc = ssh_string_fill(str,
ssh_buffer_get_len(buffer)); ssh_buffer_get(buffer),
ssh_buffer_get_len(buffer));
if (rc < 0) { if (rc < 0) {
goto fail; ssh_string_burn(str);
SSH_STRING_FREE(str);
} }
out:
SSH_BUFFER_FREE(buffer); SSH_BUFFER_FREE(buffer);
#if MBEDTLS_VERSION_MAJOR > 2
mbedtls_mpi_free(&N);
mbedtls_mpi_free(&E);
#endif
return str;
fail:
SSH_BUFFER_FREE(buffer);
ssh_string_burn(str);
SSH_STRING_FREE(str);
ssh_string_burn(e); ssh_string_burn(e);
SSH_STRING_FREE(e); SSH_STRING_FREE(e);
ssh_string_burn(n); ssh_string_burn(n);
SSH_STRING_FREE(n); SSH_STRING_FREE(n);
ssh_string_burn(d);
SSH_STRING_FREE(d);
ssh_string_burn(iqmp);
SSH_STRING_FREE(iqmp);
ssh_string_burn(p);
SSH_STRING_FREE(p);
ssh_string_burn(q);
SSH_STRING_FREE(q);
#if MBEDTLS_VERSION_MAJOR > 2 #if MBEDTLS_VERSION_MAJOR > 2
mbedtls_mpi_free(&N); mbedtls_mpi_free(&N);
mbedtls_mpi_free(&E); mbedtls_mpi_free(&E);
mbedtls_mpi_free(&D);
mbedtls_mpi_free(&IQMP);
mbedtls_mpi_free(&P);
mbedtls_mpi_free(&Q);
#endif #endif
return NULL; return str;
} }
ssh_string pki_signature_to_blob(const ssh_signature sig) ssh_string pki_signature_to_blob(const ssh_signature sig)
@@ -1195,9 +1165,9 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521: { case SSH_KEYTYPE_ECDSA_P521: {
ssh_string r; ssh_string r = NULL;
ssh_string s; ssh_string s = NULL;
ssh_buffer b; ssh_buffer b = NULL;
int rc; int rc;
b = ssh_buffer_new(); b = ssh_buffer_new();
@@ -1351,9 +1321,9 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521: case SSH_KEYTYPE_ECDSA_P521:
case SSH_KEYTYPE_SK_ECDSA: { case SSH_KEYTYPE_SK_ECDSA: {
ssh_buffer b; ssh_buffer b = NULL;
ssh_string r; ssh_string r = NULL;
ssh_string s; ssh_string s = NULL;
size_t rlen; size_t rlen;
b = ssh_buffer_new(); b = ssh_buffer_new();

View File

@@ -422,7 +422,7 @@ void ssh_poll_set_events(ssh_poll_handle p, short events)
{ {
p->events = events; p->events = events;
if (p->ctx != NULL) { if (p->ctx != NULL) {
if (p->lock_cnt == 0) { if (!ssh_poll_is_locked(p)) {
p->ctx->pollfds[p->x.idx].events = events; p->ctx->pollfds[p->x.idx].events = events;
} else if (!(p->ctx->pollfds[p->x.idx].events & POLLOUT)) { } else if (!(p->ctx->pollfds[p->x.idx].events & POLLOUT)) {
/* if locked, allow only setting POLLOUT to prevent recursive /* if locked, allow only setting POLLOUT to prevent recursive
@@ -560,8 +560,8 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx)
static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size) static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size)
{ {
ssh_poll_handle *pollptrs; ssh_poll_handle *pollptrs = NULL;
ssh_pollfd_t *pollfds; ssh_pollfd_t *pollfds = NULL;
pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * new_size); pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * new_size);
if (pollptrs == NULL) { if (pollptrs == NULL) {
@@ -669,6 +669,20 @@ void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p)
} }
} }
/**
* @brief Returns if a poll object is locked.
*
* @param p Pointer to an already allocated poll object.
* @returns true if the poll object is locked; false otherwise.
*/
bool ssh_poll_is_locked(ssh_poll_handle p)
{
if (p == NULL) {
return false;
}
return p->lock_cnt > 0;
}
/** /**
* @brief Poll all the sockets associated through a poll object with a * @brief Poll all the sockets associated through a poll object with a
* poll context. If any of the events are set after the poll, the * poll context. If any of the events are set after the poll, the
@@ -703,7 +717,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
* output buffer */ * output buffer */
for (i = 0; i < ctx->polls_used; i++) { for (i = 0; i < ctx->polls_used; i++) {
/* The lock allows only POLLOUT events: drop the rest */ /* The lock allows only POLLOUT events: drop the rest */
if (ctx->pollptrs[i]->lock_cnt > 0) { if (ssh_poll_is_locked(ctx->pollptrs[i])) {
ctx->pollfds[i].events &= POLLOUT; ctx->pollfds[i].events &= POLLOUT;
} }
} }
@@ -862,7 +876,7 @@ ssh_event_add_fd(ssh_event event, socket_t fd, short events,
ssh_event_callback cb, void *userdata) ssh_event_callback cb, void *userdata)
{ {
ssh_poll_handle p; ssh_poll_handle p;
struct ssh_event_fd_wrapper *pw; struct ssh_event_fd_wrapper *pw = NULL;
if(event == NULL || event->ctx == NULL || cb == NULL if(event == NULL || event->ctx == NULL || cb == NULL
|| fd == SSH_INVALID_SOCKET) { || fd == SSH_INVALID_SOCKET) {
@@ -932,7 +946,7 @@ int ssh_event_add_session(ssh_event event, ssh_session session)
{ {
ssh_poll_handle p; ssh_poll_handle p;
#ifdef WITH_SERVER #ifdef WITH_SERVER
struct ssh_iterator *iterator; struct ssh_iterator *iterator = NULL;
#endif #endif
if(event == NULL || event->ctx == NULL || session == NULL) { if(event == NULL || event->ctx == NULL || session == NULL) {
@@ -1079,7 +1093,7 @@ int ssh_event_remove_session(ssh_event event, ssh_session session)
register size_t i, used; register size_t i, used;
int rc = SSH_ERROR; int rc = SSH_ERROR;
#ifdef WITH_SERVER #ifdef WITH_SERVER
struct ssh_iterator *iterator; struct ssh_iterator *iterator = NULL;
#endif #endif
if (event == NULL || event->ctx == NULL || session == NULL) { if (event == NULL || event->ctx == NULL || session == NULL) {

View File

@@ -85,8 +85,8 @@ int server_set_kex(ssh_session session)
{ {
struct ssh_kex_struct *server = &session->next_crypto->server_kex; struct ssh_kex_struct *server = &session->next_crypto->server_kex;
int i, j, rc; int i, j, rc;
const char *wanted, *allowed; const char *wanted = NULL, *allowed = NULL;
char *kept; char *kept = NULL;
char hostkeys[128] = {0}; char hostkeys[128] = {0};
enum ssh_keytypes_e keytype; enum ssh_keytypes_e keytype;
size_t len; size_t len;
@@ -211,9 +211,10 @@ int ssh_server_init_kex(ssh_session session) {
return server_set_kex(session); return server_set_kex(session);
} }
static int ssh_server_send_extensions(ssh_session session) { static int ssh_server_send_extensions(ssh_session session)
{
int rc; int rc;
const char *hostkey_algorithms; const char *hostkey_algorithms = NULL;
SSH_LOG(SSH_LOG_PACKET, "Sending SSH_MSG_EXT_INFO"); SSH_LOG(SSH_LOG_PACKET, "Sending SSH_MSG_EXT_INFO");
@@ -278,8 +279,8 @@ ssh_get_key_params(ssh_session session,
ssh_key *privkey, ssh_key *privkey,
enum ssh_digest_e *digest) enum ssh_digest_e *digest)
{ {
ssh_key pubkey; ssh_key pubkey = NULL;
ssh_string pubkey_blob; ssh_string pubkey_blob = NULL;
int rc; int rc;
switch(session->srv.hostkey) { switch(session->srv.hostkey) {
@@ -522,6 +523,7 @@ static int ssh_server_kex_termination(void *s){
ssh_session session = s; ssh_session session = s;
if (session->session_state != SSH_SESSION_STATE_ERROR && if (session->session_state != SSH_SESSION_STATE_ERROR &&
session->session_state != SSH_SESSION_STATE_AUTHENTICATING && session->session_state != SSH_SESSION_STATE_AUTHENTICATING &&
session->session_state != SSH_SESSION_STATE_AUTHENTICATED &&
session->session_state != SSH_SESSION_STATE_DISCONNECTED) session->session_state != SSH_SESSION_STATE_DISCONNECTED)
return 0; return 0;
else else
@@ -720,8 +722,9 @@ static int ssh_message_service_request_reply_default(ssh_message msg) {
* *
* @returns SSH_OK when success otherwise SSH_ERROR * @returns SSH_OK when success otherwise SSH_ERROR
*/ */
int ssh_message_service_reply_success(ssh_message msg) { int ssh_message_service_reply_success(ssh_message msg)
ssh_session session; {
ssh_session session = NULL;
int rc; int rc;
if (msg == NULL) { if (msg == NULL) {
@@ -1128,8 +1131,9 @@ int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pu
* *
* @returns SSH_OK on success, otherwise SSH_ERROR * @returns SSH_OK on success, otherwise SSH_ERROR
*/ */
int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) { int ssh_message_auth_reply_pk_ok_simple(ssh_message msg)
ssh_string algo; {
ssh_string algo = NULL;
ssh_string pubkey_blob = NULL; ssh_string pubkey_blob = NULL;
int ret; int ret;

View File

@@ -59,7 +59,7 @@
*/ */
ssh_session ssh_new(void) ssh_session ssh_new(void)
{ {
ssh_session session; ssh_session session = NULL;
char *id = NULL; char *id = NULL;
int rc; int rc;
@@ -294,7 +294,7 @@ void ssh_free(ssh_session session)
/* options */ /* options */
if (session->opts.identity) { if (session->opts.identity) {
char *id; char *id = NULL;
for (id = ssh_list_pop_head(char *, session->opts.identity); for (id = ssh_list_pop_head(char *, session->opts.identity);
id != NULL; id != NULL;
@@ -305,7 +305,7 @@ void ssh_free(ssh_session session)
} }
if (session->opts.identity_non_exp) { if (session->opts.identity_non_exp) {
char *id; char *id = NULL;
for (id = ssh_list_pop_head(char *, session->opts.identity_non_exp); for (id = ssh_list_pop_head(char *, session->opts.identity_non_exp);
id != NULL; id != NULL;
@@ -1222,7 +1222,7 @@ int ssh_get_publickey_hash(const ssh_key key,
unsigned char **hash, unsigned char **hash,
size_t *hlen) size_t *hlen)
{ {
ssh_string blob; ssh_string blob = NULL;
unsigned char *h = NULL; unsigned char *h = NULL;
int rc; int rc;
@@ -1234,7 +1234,7 @@ int ssh_get_publickey_hash(const ssh_key key,
switch (type) { switch (type) {
case SSH_PUBLICKEY_HASH_SHA1: case SSH_PUBLICKEY_HASH_SHA1:
{ {
SHACTX ctx; SHACTX ctx = NULL;
h = calloc(1, SHA_DIGEST_LEN); h = calloc(1, SHA_DIGEST_LEN);
if (h == NULL) { if (h == NULL) {
@@ -1266,7 +1266,7 @@ int ssh_get_publickey_hash(const ssh_key key,
break; break;
case SSH_PUBLICKEY_HASH_SHA256: case SSH_PUBLICKEY_HASH_SHA256:
{ {
SHA256CTX ctx; SHA256CTX ctx = NULL;
h = calloc(1, SHA256_DIGEST_LEN); h = calloc(1, SHA256_DIGEST_LEN);
if (h == NULL) { if (h == NULL) {
@@ -1298,7 +1298,7 @@ int ssh_get_publickey_hash(const ssh_key key,
break; break;
case SSH_PUBLICKEY_HASH_MD5: case SSH_PUBLICKEY_HASH_MD5:
{ {
MD5CTX ctx; MD5CTX ctx = NULL;
/* In FIPS mode, we cannot use MD5 */ /* In FIPS mode, we cannot use MD5 */
if (ssh_fips_mode()) { if (ssh_fips_mode()) {

View File

@@ -361,10 +361,10 @@ int
sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len) sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len)
{ {
sftp_packet packet = sftp->read_packet; sftp_packet packet = sftp->read_packet;
int nread; size_t nread;
int payload_len; size_t payload_len;
unsigned int data_offset; size_t data_offset;
int to_read, rc; size_t to_read, rc;
if (packet->sftp == NULL) { if (packet->sftp == NULL) {
packet->sftp = sftp; packet->sftp = sftp;
@@ -380,7 +380,7 @@ sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len)
packet->type = PULL_BE_U8(data, 4); packet->type = PULL_BE_U8(data, 4);
/* We should check the legality of payload length */ /* We should check the legality of payload length */
if (payload_len + sizeof(uint32_t) > len || payload_len < 0) { if (payload_len > len - sizeof(uint32_t) || payload_len < sizeof(uint8_t)) {
return SSH_ERROR; return SSH_ERROR;
} }
@@ -399,10 +399,12 @@ sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len)
} }
/* /*
* We should return how many bytes we decoded, including packet length header * We should return how many bytes we decoded, including packet length
* and the payload length. * header and the payload length.
* This can't overflow as we pulled this from unit32_t and checked this fits
* into the buffer's max size of 0x10000000 (256MB).
*/ */
return payload_len + sizeof(uint32_t); return (int)(payload_len + sizeof(uint32_t));
} }
/* Get the last sftp error */ /* Get the last sftp error */

View File

@@ -894,12 +894,8 @@ sftp_status_message parse_status_msg(sftp_message msg)
&status->langmsg); &status->langmsg);
if (rc != SSH_OK && msg->sftp->version >= 3) { if (rc != SSH_OK && msg->sftp->version >= 3) {
/* These are mandatory from version 3 */ SSH_LOG(SSH_LOG_WARN,
SAFE_FREE(status); "Invalid SSH_FXP_STATUS message. Missing error message.");
ssh_set_error(msg->sftp->session, SSH_FATAL,
"Invalid SSH_FXP_STATUS message");
sftp_set_error(msg->sftp, SSH_FX_FAILURE);
return NULL;
} }
if (status->errormsg == NULL) if (status->errormsg == NULL)

View File

@@ -258,13 +258,11 @@ error:
sftp_client_message sftp_get_client_message(sftp_session sftp) sftp_client_message sftp_get_client_message(sftp_session sftp)
{ {
ssh_session session = sftp->session; sftp_packet packet = NULL;
sftp_packet packet;
packet = sftp_packet_read(sftp); packet = sftp_packet_read(sftp);
if (packet == NULL) { if (packet == NULL) {
ssh_set_error_oom(session); return NULL;
return NULL;
} }
return sftp_make_client_message(sftp, packet); return sftp_make_client_message(sftp, packet);
} }
@@ -348,8 +346,8 @@ void sftp_client_message_free(sftp_client_message msg)
int int
sftp_reply_name(sftp_client_message msg, const char *name, sftp_attributes attr) sftp_reply_name(sftp_client_message msg, const char *name, sftp_attributes attr)
{ {
ssh_buffer out; ssh_buffer out = NULL;
ssh_string file; ssh_string file = NULL;
out = ssh_buffer_new(); out = ssh_buffer_new();
if (out == NULL) { if (out == NULL) {
@@ -430,7 +428,7 @@ int
sftp_reply_names_add(sftp_client_message msg, const char *file, sftp_reply_names_add(sftp_client_message msg, const char *file,
const char *longname, sftp_attributes attr) const char *longname, sftp_attributes attr)
{ {
ssh_string name; ssh_string name = NULL;
name = ssh_string_from_char(file); name = ssh_string_from_char(file);
if (name == NULL) { if (name == NULL) {
@@ -500,8 +498,8 @@ int sftp_reply_names(sftp_client_message msg)
int int
sftp_reply_status(sftp_client_message msg, uint32_t status, const char *message) sftp_reply_status(sftp_client_message msg, uint32_t status, const char *message)
{ {
ssh_buffer out; ssh_buffer out = NULL;
ssh_string s; ssh_string s = NULL;
out = ssh_buffer_new(); out = ssh_buffer_new();
if (out == NULL) { if (out == NULL) {
@@ -657,7 +655,7 @@ int sftp_reply_version(sftp_client_message client_msg)
*/ */
ssh_string sftp_handle_alloc(sftp_session sftp, void *info) ssh_string sftp_handle_alloc(sftp_session sftp, void *info)
{ {
ssh_string ret; ssh_string ret = NULL;
uint32_t val; uint32_t val;
uint32_t i; uint32_t i;
@@ -704,7 +702,7 @@ void *sftp_handle(sftp_session sftp, ssh_string handle)
memcpy(&val, ssh_string_data(handle), sizeof(uint32_t)); memcpy(&val, ssh_string_data(handle), sizeof(uint32_t));
if (val > SFTP_HANDLES) { if (val >= SFTP_HANDLES) {
return NULL; return NULL;
} }
@@ -928,6 +926,7 @@ process_open(sftp_client_message client_msg)
sftp_reply_handle(client_msg, handle_s); sftp_reply_handle(client_msg, handle_s);
ssh_string_free(handle_s); ssh_string_free(handle_s);
} else { } else {
free(h);
close(fd); close(fd);
SSH_LOG(SSH_LOG_PROTOCOL, "Failed to allocate handle"); SSH_LOG(SSH_LOG_PROTOCOL, "Failed to allocate handle");
sftp_reply_status(client_msg, SSH_FX_FAILURE, sftp_reply_status(client_msg, SSH_FX_FAILURE,
@@ -953,7 +952,7 @@ process_read(sftp_client_message client_msg)
ssh_string_len(handle)); ssh_string_len(handle));
h = sftp_handle(sftp, handle); h = sftp_handle(sftp, handle);
if (h->type == SFTP_FILE_HANDLE) { if (h != NULL && h->type == SFTP_FILE_HANDLE) {
fd = h->fd; fd = h->fd;
} }
@@ -1011,7 +1010,7 @@ process_write(sftp_client_message client_msg)
ssh_string_len(handle)); ssh_string_len(handle));
h = sftp_handle(sftp, handle); h = sftp_handle(sftp, handle);
if (h->type == SFTP_FILE_HANDLE) { if (h != NULL && h->type == SFTP_FILE_HANDLE) {
fd = h->fd; fd = h->fd;
} }
if (fd < 0) { if (fd < 0) {
@@ -1056,7 +1055,11 @@ process_close(sftp_client_message client_msg)
ssh_string_len(handle)); ssh_string_len(handle));
h = sftp_handle(sftp, handle); h = sftp_handle(sftp, handle);
if (h->type == SFTP_FILE_HANDLE) { if (h == NULL) {
SSH_LOG(SSH_LOG_PROTOCOL, "invalid handle");
sftp_reply_status(client_msg, SSH_FX_INVALID_HANDLE, "Invalid handle");
return SSH_OK;
} else if (h->type == SFTP_FILE_HANDLE) {
int fd = h->fd; int fd = h->fd;
close(fd); close(fd);
ret = SSH_OK; ret = SSH_OK;
@@ -1114,6 +1117,7 @@ process_opendir(sftp_client_message client_msg)
sftp_reply_handle(client_msg, handle_s); sftp_reply_handle(client_msg, handle_s);
ssh_string_free(handle_s); ssh_string_free(handle_s);
} else { } else {
free(h);
closedir(dir); closedir(dir);
sftp_reply_status(client_msg, SSH_FX_FAILURE, "No handle available"); sftp_reply_status(client_msg, SSH_FX_FAILURE, "No handle available");
} }
@@ -1223,7 +1227,7 @@ process_readdir(sftp_client_message client_msg)
ssh_string_len(handle)); ssh_string_len(handle));
h = sftp_handle(sftp, client_msg->handle); h = sftp_handle(sftp, client_msg->handle);
if (h->type == SFTP_DIR_HANDLE) { if (h != NULL && h->type == SFTP_DIR_HANDLE) {
dir = h->dirp; dir = h->dirp;
handle_name = h->name; handle_name = h->name;
} }
@@ -1542,7 +1546,7 @@ process_readlink(sftp_client_message client_msg)
const char *filename = sftp_client_message_get_filename(client_msg); const char *filename = sftp_client_message_get_filename(client_msg);
char buf[PATH_MAX]; char buf[PATH_MAX];
int len = -1; int len = -1;
const char *err_msg; const char *err_msg = NULL;
int status = SSH_FX_OK; int status = SSH_FX_OK;
SSH_LOG(SSH_LOG_PROTOCOL, "Processing readlink %s", filename); SSH_LOG(SSH_LOG_PROTOCOL, "Processing readlink %s", filename);
@@ -1825,13 +1829,13 @@ sftp_channel_default_data_callback(UNUSED_PARAM(ssh_session session),
if (sftpp == NULL) { if (sftpp == NULL) {
SSH_LOG(SSH_LOG_WARNING, "NULL userdata passed to callback"); SSH_LOG(SSH_LOG_WARNING, "NULL userdata passed to callback");
return -1; return SSH_ERROR;
} }
sftp = *sftpp; sftp = *sftpp;
decode_len = sftp_decode_channel_data_to_packet(sftp, data, len); decode_len = sftp_decode_channel_data_to_packet(sftp, data, len);
if (decode_len == -1) if (decode_len == SSH_ERROR)
return -1; return SSH_ERROR;
msg = sftp_get_client_message_from_packet(sftp); msg = sftp_get_client_message_from_packet(sftp);
rc = process_client_message(msg); rc = process_client_message(msg);

View File

@@ -478,7 +478,7 @@ void ssh_socket_close(ssh_socket s)
#endif #endif
} }
if (s->poll_handle != NULL) { if (s->poll_handle != NULL && !ssh_poll_is_locked(s->poll_handle)) {
ssh_poll_free(s->poll_handle); ssh_poll_free(s->poll_handle);
s->poll_handle = NULL; s->poll_handle = NULL;
} }

View File

@@ -106,7 +106,7 @@ int ssh_string_fill(struct ssh_string_struct *s, const void *data, size_t len) {
* @note The null byte is not copied nor counted in the output string. * @note The null byte is not copied nor counted in the output string.
*/ */
struct ssh_string_struct *ssh_string_from_char(const char *what) { struct ssh_string_struct *ssh_string_from_char(const char *what) {
struct ssh_string_struct *ptr; struct ssh_string_struct *ptr = NULL;
size_t len; size_t len;
if(what == NULL) { if(what == NULL) {
@@ -180,7 +180,7 @@ const char *ssh_string_get_char(struct ssh_string_struct *s)
*/ */
char *ssh_string_to_char(struct ssh_string_struct *s) { char *ssh_string_to_char(struct ssh_string_struct *s) {
size_t len; size_t len;
char *new; char *new = NULL;
if (s == NULL) { if (s == NULL) {
return NULL; return NULL;
@@ -219,7 +219,7 @@ void ssh_string_free_char(char *s) {
* @return Newly allocated copy of the string, NULL on error. * @return Newly allocated copy of the string, NULL on error.
*/ */
struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) { struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) {
struct ssh_string_struct *new; struct ssh_string_struct *new = NULL;
size_t len; size_t len;
if (s == NULL) { if (s == NULL) {

View File

@@ -82,7 +82,7 @@ static struct ssh_threads_callbacks_struct ssh_threads_winlock =
void ssh_mutex_lock(SSH_MUTEX *mutex) void ssh_mutex_lock(SSH_MUTEX *mutex)
{ {
void *rc; void *rc = NULL;
CRITICAL_SECTION *mutex_tmp = NULL; CRITICAL_SECTION *mutex_tmp = NULL;

View File

@@ -38,10 +38,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef WITH_ZLIB
#include <zlib.h>
#endif
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/session.h" #include "libssh/session.h"
#include "libssh/crypto.h" #include "libssh/crypto.h"
@@ -152,7 +148,7 @@ static void cipher_free(struct ssh_cipher_struct *cipher) {
struct ssh_crypto_struct *crypto_new(void) struct ssh_crypto_struct *crypto_new(void)
{ {
struct ssh_crypto_struct *crypto; struct ssh_crypto_struct *crypto = NULL;
crypto = calloc(1, sizeof(struct ssh_crypto_struct)); crypto = calloc(1, sizeof(struct ssh_crypto_struct));
if (crypto == NULL) { if (crypto == NULL) {
@@ -185,7 +181,10 @@ void crypto_free(struct ssh_crypto_struct *crypto)
#endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_VERSION_NUMBER */
#elif defined HAVE_GCRYPT_ECC #elif defined HAVE_GCRYPT_ECC
gcry_sexp_release(crypto->ecdh_privkey); gcry_sexp_release(crypto->ecdh_privkey);
#endif #elif defined HAVE_LIBMBEDCRYPTO
mbedtls_ecp_keypair_free(crypto->ecdh_privkey);
SAFE_FREE(crypto->ecdh_privkey);
#endif /* HAVE_LIBGCRYPT */
crypto->ecdh_privkey = NULL; crypto->ecdh_privkey = NULL;
} }
#endif #endif
@@ -198,17 +197,7 @@ void crypto_free(struct ssh_crypto_struct *crypto)
explicit_bzero(crypto->secret_hash, crypto->digest_len); explicit_bzero(crypto->secret_hash, crypto->digest_len);
SAFE_FREE(crypto->secret_hash); SAFE_FREE(crypto->secret_hash);
} }
#ifdef WITH_ZLIB compress_cleanup(crypto);
if (crypto->compress_out_ctx) {
deflateEnd(crypto->compress_out_ctx);
}
SAFE_FREE(crypto->compress_out_ctx);
if (crypto->compress_in_ctx) {
inflateEnd(crypto->compress_in_ctx);
}
SAFE_FREE(crypto->compress_in_ctx);
#endif /* WITH_ZLIB */
SAFE_FREE(crypto->encryptIV); SAFE_FREE(crypto->encryptIV);
SAFE_FREE(crypto->decryptIV); SAFE_FREE(crypto->decryptIV);
SAFE_FREE(crypto->encryptMAC); SAFE_FREE(crypto->encryptMAC);

View File

@@ -23,6 +23,12 @@ if (NOT WIN32)
${TORTURE_LINK_LIBRARIES} ${TORTURE_LINK_LIBRARIES}
pthread) pthread)
endif(NOT WIN32) endif(NOT WIN32)
if (WITH_GSSAPI AND GSSAPI_FOUND)
find_package(OpenSSL 1.1.1 REQUIRED)
set(TORTURE_LINK_LIBRARIES
${TORTURE_LINK_LIBRARIES}
OpenSSL::Crypto)
endif (WITH_GSSAPI AND GSSAPI_FOUND)
# create test library # create test library
add_library(${TORTURE_LIBRARY} add_library(${TORTURE_LIBRARY}
@@ -99,10 +105,12 @@ add_subdirectory(unittests)
# OpenSSH Capabilities are required for all unit tests # OpenSSH Capabilities are required for all unit tests
find_program(SSH_EXECUTABLE NAMES ssh) find_program(SSH_EXECUTABLE NAMES ssh)
if (SSH_EXECUTABLE) if (SSH_EXECUTABLE)
file(SIZE ${SSH_EXECUTABLE} SSH_EXECUTABLE_SIZE)
execute_process(COMMAND ${SSH_EXECUTABLE} -V ERROR_VARIABLE OPENSSH_VERSION_STR) execute_process(COMMAND ${SSH_EXECUTABLE} -V ERROR_VARIABLE OPENSSH_VERSION_STR)
string(REGEX REPLACE "^.*OpenSSH_([0-9]).[0-9].*$" "\\1" OPENSSH_VERSION_MAJOR "${OPENSSH_VERSION_STR}") string(REGEX REPLACE "^.*OpenSSH_([0-9]+).[0-9].*$" "\\1" OPENSSH_VERSION_MAJOR "${OPENSSH_VERSION_STR}")
string(REGEX REPLACE "^.*OpenSSH_[0-9].([0-9]).*$" "\\1" OPENSSH_VERSION_MINOR "${OPENSSH_VERSION_STR}") string(REGEX REPLACE "^.*OpenSSH_[0-9]+.([0-9]).*$" "\\1" OPENSSH_VERSION_MINOR "${OPENSSH_VERSION_STR}")
set(OPENSSH_VERSION "${OPENSSH_VERSION_MAJOR}.${OPENSSH_VERSION_MINOR}") set(OPENSSH_VERSION "${OPENSSH_VERSION_MAJOR}.${OPENSSH_VERSION_MINOR}")
add_definitions(-DOPENSSH_VERSION_MAJOR=${OPENSSH_VERSION_MAJOR} -DOPENSSH_VERSION_MINOR=${OPENSSH_VERSION_MINOR})
if("${OPENSSH_VERSION}" VERSION_LESS "6.3") if("${OPENSSH_VERSION}" VERSION_LESS "6.3")
# ssh - Q was introduced in 6.3 # ssh - Q was introduced in 6.3
message("Version less than 6.3, hardcoding cipher list") message("Version less than 6.3, hardcoding cipher list")
@@ -162,6 +170,22 @@ if (SSH_EXECUTABLE)
endif() endif()
find_program(DROPBEAR_EXECUTABLE NAMES dbclient)
if (DROPBEAR_EXECUTABLE)
execute_process(COMMAND ${DROPBEAR_EXECUTABLE} -V ERROR_VARIABLE DROPBEAR_VERSION_STR)
string(REGEX REPLACE "^.*Dropbear v([0-9]+)\\.([0-9]+).*$" "\\1.\\2" DROPBEAR_VERSION "${DROPBEAR_VERSION_STR}")
set(DROPBEAR_VERSION "${DROPBEAR_VERSION}")
# HMAC-SHA1 support was removed in version 2025.87
if("${DROPBEAR_VERSION}" VERSION_LESS "2025.87")
message("Dropbear Version less than 2025.87, enabling dropbear HMAC-SHA1 tests")
add_definitions(-DDROPBEAR_SUPPORTS_HMAC_SHA1)
endif()
else()
message(STATUS "Could NOT find Dropbear (missing: dbclient executable)")
set(DROPBEAR_EXECUTABLE "/bin/false")
endif()
find_program(SSHD_EXECUTABLE find_program(SSHD_EXECUTABLE
NAME NAME
sshd sshd
@@ -170,6 +194,20 @@ find_program(SSHD_EXECUTABLE
/usr/sbin /usr/sbin
/usr/local/sbin) /usr/local/sbin)
if (WITH_PKCS11_URI)
find_package(softhsm)
if (NOT SOFTHSM_FOUND)
message(SEND_ERROR "Could not find softhsm module!")
endif (NOT SOFTHSM_FOUND)
find_library(PKCS11SPY
NAMES
pkcs11-spy.so
)
#Copy the script to setup PKCS11 tokens
file(COPY pkcs11/setup-softhsm-tokens.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pkcs11 FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
endif (WITH_PKCS11_URI)
if (CLIENT_TESTING OR SERVER_TESTING) if (CLIENT_TESTING OR SERVER_TESTING)
find_package(socket_wrapper 1.1.5 REQUIRED) find_package(socket_wrapper 1.1.5 REQUIRED)
find_package(nss_wrapper 1.1.2 REQUIRED) find_package(nss_wrapper 1.1.2 REQUIRED)
@@ -188,35 +226,6 @@ if (CLIENT_TESTING OR SERVER_TESTING)
/usr/bin /usr/bin
/usr/local/bin) /usr/local/bin)
if (WITH_PKCS11_URI)
find_package(softhsm)
if (NOT SOFTHSM_FOUND)
message(SEND_ERROR "Could not find softhsm module!")
endif (NOT SOFTHSM_FOUND)
find_library(PKCS11SPY
NAMES
pkcs11-spy.so
)
if (WITH_PKCS11_PROVIDER)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(P11_KIT p11-kit-1)
if (P11_KIT_FOUND)
pkg_get_variable(P11_MODULE_PATH p11-kit-1 p11_module_path)
set(P11_KIT_CLIENT ${P11_MODULE_PATH}/p11-kit-client.so)
endif (P11_KIT_FOUND)
endif (PKG_CONFIG_FOUND)
endif (WITH_PKCS11_PROVIDER)
endif (WITH_PKCS11_URI)
find_program(SSH_EXECUTABLE NAMES ssh)
if (SSH_EXECUTABLE)
execute_process(COMMAND ${SSH_EXECUTABLE} -V ERROR_VARIABLE OPENSSH_VERSION_STR)
string(REGEX REPLACE "^.*OpenSSH_([0-9]).[0-9].*$" "\\1" OPENSSH_VERSION_MAJOR "${OPENSSH_VERSION_STR}")
string(REGEX REPLACE "^.*OpenSSH_[0-9].([0-9]).*$" "\\1" OPENSSH_VERSION_MINOR "${OPENSSH_VERSION_STR}")
add_definitions(-DOPENSSH_VERSION_MAJOR=${OPENSSH_VERSION_MAJOR} -DOPENSSH_VERSION_MINOR=${OPENSSH_VERSION_MINOR})
endif()
set(LOCAL_USER "nobody") set(LOCAL_USER "nobody")
set(LOCAL_UID "65533") set(LOCAL_UID "65533")
find_program(ID_EXECUTABLE NAMES id) find_program(ID_EXECUTABLE NAMES id)
@@ -337,11 +346,6 @@ if (CLIENT_TESTING OR SERVER_TESTING)
${CMAKE_CURRENT_BINARY_DIR}/home/doe/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE) ${CMAKE_CURRENT_BINARY_DIR}/home/doe/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
endif () endif ()
if (WITH_PKCS11_URI)
#Copy the script to setup PKCS11 tokens
file(COPY pkcs11/setup-softhsm-tokens.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pkcs11 FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
endif (WITH_PKCS11_URI)
file(COPY gss/kdcsetup.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/gss FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) file(COPY gss/kdcsetup.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/gss FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}") message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}")

View File

@@ -1247,6 +1247,38 @@ static void torture_auth_pubkey_rsa_key_size_nonblocking(void **state)
SSH_KEY_FREE(privkey); SSH_KEY_FREE(privkey);
} }
static void torture_auth_pubkey_skip_none(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
char bob_ssh_key[1024];
ssh_key privkey = NULL;
struct passwd *pwd = NULL;
int rc;
pwd = getpwnam("bob");
assert_non_null(pwd);
snprintf(bob_ssh_key, sizeof(bob_ssh_key), "%s/.ssh/id_rsa", pwd->pw_dir);
/* Authenticate as alice with bob his pubkey */
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_int_equal(rc, SSH_OK);
rc = ssh_connect(session);
assert_int_equal(rc, SSH_OK);
/* Skip the ssh_userauth_none() here */
rc = ssh_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey);
assert_int_equal(rc, SSH_OK);
rc = ssh_userauth_publickey(session, NULL, privkey);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
SSH_KEY_FREE(privkey);
}
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
struct CMUnitTest tests[] = { struct CMUnitTest tests[] = {
@@ -1334,6 +1366,9 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_auth_pubkey_rsa_key_size_nonblocking, cmocka_unit_test_setup_teardown(torture_auth_pubkey_rsa_key_size_nonblocking,
pubkey_setup, pubkey_setup,
session_teardown), session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_pubkey_skip_none,
pubkey_setup,
session_teardown),
}; };
ssh_init(); ssh_init();

View File

@@ -240,6 +240,14 @@ int torture_run_tests(void) {
session_teardown), session_teardown),
}; };
/* Do not use system openssl.cnf for the pkcs11 uri tests.
* It can load a pkcs11 provider too early before we will set up environment
* variables that are needed for the pkcs11 provider to access correct
* tokens, causing unexpected failures.
* Make sure this comes before ssh_init(), which initializes OpenSSL!
*/
setenv("OPENSSL_CONF", "/dev/null", 1);
ssh_init(); ssh_init();
torture_filter_tests(tests); torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown); rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);

View File

@@ -272,5 +272,5 @@ torture_run_tests(void)
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown); rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
ssh_finalize(); ssh_finalize();
pthread_exit((void *)&rc); return rc;
} }

View File

@@ -31,6 +31,7 @@
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/session.h" #include "libssh/session.h"
#include "libssh/crypto.h" #include "libssh/crypto.h"
#include "libssh/token.h"
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
@@ -96,6 +97,7 @@ static int session_teardown(void **state)
struct torture_state *s = *state; struct torture_state *s = *state;
ssh_free(s->ssh.session); ssh_free(s->ssh.session);
s->ssh.session = NULL;
return 0; return 0;
} }
@@ -148,7 +150,7 @@ static void torture_rekey_default(void **state)
ssh_disconnect(s->ssh.session); ssh_disconnect(s->ssh.session);
} }
static void sanity_check_session(void **state) static void sanity_check_session_size(void **state, uint64_t rekey_limit)
{ {
struct torture_state *s = *state; struct torture_state *s = *state;
struct ssh_crypto_struct *c = NULL; struct ssh_crypto_struct *c = NULL;
@@ -156,9 +158,9 @@ static void sanity_check_session(void **state)
c = s->ssh.session->current_crypto; c = s->ssh.session->current_crypto;
assert_non_null(c); assert_non_null(c);
assert_int_equal(c->in_cipher->max_blocks, assert_int_equal(c->in_cipher->max_blocks,
bytes / c->in_cipher->blocksize); rekey_limit / c->in_cipher->blocksize);
assert_int_equal(c->out_cipher->max_blocks, assert_int_equal(c->out_cipher->max_blocks,
bytes / c->out_cipher->blocksize); rekey_limit / c->out_cipher->blocksize);
/* when strict kex is used, the newkeys reset the sequence number */ /* when strict kex is used, the newkeys reset the sequence number */
if ((s->ssh.session->flags & SSH_SESSION_FLAG_KEX_STRICT) != 0) { if ((s->ssh.session->flags & SSH_SESSION_FLAG_KEX_STRICT) != 0) {
assert_int_equal(c->out_cipher->packets, s->ssh.session->send_seq); assert_int_equal(c->out_cipher->packets, s->ssh.session->send_seq);
@@ -170,6 +172,10 @@ static void sanity_check_session(void **state)
assert_true(c->in_cipher->packets < s->ssh.session->recv_seq); assert_true(c->in_cipher->packets < s->ssh.session->recv_seq);
} }
} }
static void sanity_check_session(void **state)
{
sanity_check_session_size(state, bytes);
}
/* We lower the rekey limits manually and check that the rekey /* We lower the rekey limits manually and check that the rekey
* really happens when sending data * really happens when sending data
@@ -275,7 +281,7 @@ static int session_setup_sftp_client(void **state)
/* To trigger rekey by receiving data, the easiest thing is probably to /* To trigger rekey by receiving data, the easiest thing is probably to
* use sftp * use sftp
*/ */
static void torture_rekey_recv(void **state) static void torture_rekey_recv_size(void **state, uint64_t rekey_limit)
{ {
struct torture_state *s = *state; struct torture_state *s = *state;
struct ssh_crypto_struct *c = NULL; struct ssh_crypto_struct *c = NULL;
@@ -290,7 +296,7 @@ static void torture_rekey_recv(void **state)
mode_t mask; mode_t mask;
int rc; int rc;
sanity_check_session(state); sanity_check_session_size(state, rekey_limit);
/* Copy the initial secret hash = session_id so we know we changed keys later */ /* Copy the initial secret hash = session_id so we know we changed keys later */
c = s->ssh.session->current_crypto; c = s->ssh.session->current_crypto;
assert_non_null(c); assert_non_null(c);
@@ -324,8 +330,10 @@ static void torture_rekey_recv(void **state)
/* The rekey limit was restored in the new crypto to the same value */ /* The rekey limit was restored in the new crypto to the same value */
c = s->ssh.session->current_crypto; c = s->ssh.session->current_crypto;
assert_int_equal(c->in_cipher->max_blocks, bytes / c->in_cipher->blocksize); assert_int_equal(c->in_cipher->max_blocks,
assert_int_equal(c->out_cipher->max_blocks, bytes / c->out_cipher->blocksize); rekey_limit / c->in_cipher->blocksize);
assert_int_equal(c->out_cipher->max_blocks,
rekey_limit / c->out_cipher->blocksize);
/* Check that the secret hash is different than initially */ /* Check that the secret hash is different than initially */
assert_memory_not_equal(secret_hash, c->secret_hash, c->digest_len); assert_memory_not_equal(secret_hash, c->secret_hash, c->digest_len);
free(secret_hash); free(secret_hash);
@@ -333,6 +341,11 @@ static void torture_rekey_recv(void **state)
torture_sftp_close(s->ssh.tsftp); torture_sftp_close(s->ssh.tsftp);
ssh_disconnect(s->ssh.session); ssh_disconnect(s->ssh.session);
} }
static void torture_rekey_recv(void **state)
{
torture_rekey_recv_size(state, bytes);
}
#endif /* WITH_SFTP */ #endif /* WITH_SFTP */
/* Rekey time requires rekey after specified time and is off by default. /* Rekey time requires rekey after specified time and is off by default.
@@ -836,6 +849,81 @@ static void torture_rekey_guess_wrong_recv(void **state)
torture_rekey_recv(state); torture_rekey_recv(state);
} }
static void torture_rekey_guess_all_combinations(void **state)
{
struct torture_state *s = *state;
char sshd_config[256] = "";
char client_kex[256] = "";
const char *supported = NULL;
struct ssh_tokens_st *s_tok = NULL;
uint64_t rekey_limit = 0;
int rc, i, j;
/* The rekey limit is 1/2 of the transferred file size so we will likely get
* 2 rekeys per test, which still runs for acceptable time */
rekey_limit = atoll(SSH_EXECUTABLE_SIZE);
rekey_limit /= 2;
if (ssh_fips_mode()) {
supported = ssh_kex_get_fips_methods(SSH_KEX);
} else {
supported = ssh_kex_get_supported_method(SSH_KEX);
}
assert_non_null(supported);
s_tok = ssh_tokenize(supported, ',');
assert_non_null(s_tok);
for (i = 0; s_tok->tokens[i]; i++) {
/* Skip algorithms not supported by the OpenSSH server */
if (strstr(OPENSSH_KEX, s_tok->tokens[i]) == NULL) {
SSH_LOG(SSH_LOG_INFO, "Server: %s [skipping]", s_tok->tokens[i]);
continue;
}
SSH_LOG(SSH_LOG_INFO, "Server: %s", s_tok->tokens[i]);
snprintf(sshd_config,
sizeof(sshd_config),
"KexAlgorithms %s",
s_tok->tokens[i]);
/* This sets an only supported kex algorithm that we do not have as
* a first option in the client */
torture_update_sshd_config(state, sshd_config);
for (j = 0; s_tok->tokens[j]; j++) {
if (i == j) {
continue;
}
session_setup(state);
/* Make the client send the first_kex_packet_follows flag during key
* exchange as well as during the rekey */
s->ssh.session->send_first_kex_follows = true;
rc = ssh_options_set(s->ssh.session,
SSH_OPTIONS_REKEY_DATA,
&rekey_limit);
assert_ssh_return_code(s->ssh.session, rc);
/* Client kex preference will have the second of the pair and the
* server one as a second to negotiate on the second attempt */
snprintf(client_kex,
sizeof(client_kex),
"%s,%s",
s_tok->tokens[j],
s_tok->tokens[i]);
SSH_LOG(SSH_LOG_INFO, "Client: %s", client_kex);
rc = ssh_options_set(s->ssh.session,
SSH_OPTIONS_KEY_EXCHANGE,
client_kex);
assert_ssh_return_code(s->ssh.session, rc);
session_setup_sftp(state);
torture_rekey_recv_size(state, rekey_limit);
session_teardown(state);
}
}
ssh_tokens_free(s_tok);
}
#endif /* WITH_SFTP */ #endif /* WITH_SFTP */
int torture_run_tests(void) { int torture_run_tests(void) {
@@ -905,6 +993,7 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_rekey_guess_wrong_recv, cmocka_unit_test_setup_teardown(torture_rekey_guess_wrong_recv,
session_setup, session_setup,
session_teardown), session_teardown),
cmocka_unit_test(torture_rekey_guess_all_combinations),
#endif /* WITH_SFTP */ #endif /* WITH_SFTP */
}; };

View File

@@ -450,12 +450,13 @@ static void torture_channel_exit_signal(void **state)
rc = ssh_channel_request_send_signal(channel, "TERM"); rc = ssh_channel_request_send_signal(channel, "TERM");
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
exit_status = ssh_channel_get_exit_state(channel, rc = ssh_channel_get_exit_state(channel,
&exit_status, &exit_status,
&exit_signal, &exit_signal,
&core_dumped); &core_dumped);
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
assert_int_equal(exit_status, 0); assert_int_equal(exit_status, (uint32_t)-1);
assert_string_equal(exit_signal, "TERM"); assert_string_equal(exit_signal, "TERM");
SAFE_FREE(exit_signal); SAFE_FREE(exit_signal);
} }
@@ -574,6 +575,18 @@ static void torture_pubkey_hash(void **state)
} }
} }
static void torture_openssh_banner_version(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int openssh_version = ssh_get_openssh_version(session);
int cmake_openssh_version = SSH_VERSION_INT(OPENSSH_VERSION_MAJOR, OPENSSH_VERSION_MINOR, 0);
assert_int_equal(openssh_version, cmake_openssh_version);
}
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
struct CMUnitTest tests[] = { struct CMUnitTest tests[] = {
@@ -619,6 +632,9 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_pubkey_hash, cmocka_unit_test_setup_teardown(torture_pubkey_hash,
session_setup, session_setup,
session_teardown), session_teardown),
cmocka_unit_test_setup_teardown(torture_openssh_banner_version,
session_setup,
session_teardown),
}; };
ssh_init(); ssh_init();

View File

@@ -2,9 +2,7 @@ project(fuzzing CXX)
macro(fuzzer name) macro(fuzzer name)
add_executable(${name} ${name}.c) add_executable(${name} ${name}.c)
target_link_libraries(${name} target_link_libraries(${name} PRIVATE ${TORTURE_LINK_LIBRARIES})
PRIVATE
ssh::static pthread)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set_target_properties(${name} set_target_properties(${name}
PROPERTIES PROPERTIES

Some files were not shown because too many files have changed in this diff Show More