Compare commits

..

450 Commits

Author SHA1 Message Date
Jakub Jelen
d18bd23358 Bump version to 0.9.8
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
5dfe742737 Generate new 2k certificate key working in FIPS
The original key had 2018 bits, which falls short for current security
requirements

Steps I used:

$ ssh-keygen -f tests/keys/certauth/id_rsa -t rsa -b 2048 -C libssh_torture_auth -N ''
$ ssh-keygen -s tests/keys/user_ca -I torture_auth_carlos -n alice ./tests/keys/certauth/id_rsa.pub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8b9b45066b)
2023-12-18 17:57:27 +01:00
Jakub Jelen
aef4a47000 CVE-2023-6918: tests: Code coverage for ssh_get_pubkey_hash()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
9276027c68 CVE-2023-6918: kdf: Detect context init failures
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
a45a3c940d CVE-2023-6918: Systematically check return values when calculating digests
with all crypto backends

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
882d9cb5c8 CVE-2023-6918: Remove unused evp functions and types
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
93c1dbd69f CVE-2023-6918: kdf: Reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
768d1ed30c CVE-2023-48795: tests: Adjust calculation to strict kex
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
03bbbc9e4c CVE-2023-48795: Strip extensions from both kex lists for matching
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Aris Adamantiadis
fd49482555 CVE-2023-48795: Server side mitigations
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Aris Adamantiadis
87b93be5a2 CVE-2023-48795: client side mitigation
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
6a8a18c73e CVE-2023-6004: torture_misc: Add tests for ipv6 link-local
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
cdaec0d627 CVE-2023-6004: misc: Add ipv6 link-local check for an ip address
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
a0dbe0d556 CVE-2023-6004: torture_misc: Add test for ssh_is_ipaddr
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
8cf4f4bfda CVE-2023-6004: torture_proxycommand: Add test for proxycommand injection
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
4d7ae19e9c CVE-2023-6004: config_parser: Check for valid syntax of a hostname if it is a domain name
This prevents code injection.
The domain name syntax checker is based on RFC1035.

Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
234ecdf4d9 CVE-2023-6004: torture_misc: Add test for ssh_check_hostname_syntax
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
efb24b6472 CVE-2023-6004: misc: Add function to check allowed characters of a hostname
The hostname can be a domain name or an ip address. The colon has to be
allowed because of IPv6 even it is prohibited in domain names.

Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
a5b8bd0d88 CVE-2023-6004: options: Simplify the hostname parsing in ssh_options_set
Using ssh_config_parse_uri can simplify the parsing of the host
parsing inside the function of ssh_options_set

Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
c3234e5f94 CVE-2023-6004: config_parser: Allow multiple '@' in usernames
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Norbert Pocs
11bd6e6ad9 CVE-2023-6004: torture_config: Allow multiple '@' in usernames
Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-12-18 17:57:27 +01:00
Jakub Jelen
8b8584ce5f channels: Avoid out-of-bounds writes
CID 1470005

Thanks coverity

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 9c19ba7f33)
(cherry picked from commit d58a4cbd4047ea3aa9d41a820e1978b5f0c49ea5)
2023-12-18 17:57:23 +01:00
Jakub Jelen
2dffb97007 session: Avoid potential null dereference on low-memory conditions
CID 1500478

Thanks coverity

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit ebea7d9023)
(cherry picked from commit 1c6e7dd3c33e0681964631c1ebc619160a09a4bd)
2023-12-18 17:57:18 +01:00
Jakub Jelen
70fef935b2 Bump version to 0.9.7
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:41:53 +02:00
Norbert Pocs
b3d19cc31d CVE-2023-2283:pki_crypto: Remove unnecessary NULL check
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:41:08 +02:00
Norbert Pocs
05de7cb6ac CVE-2023-2283:pki_crypto: Fix possible authentication bypass
The return value is changed by the call to pki_key_check_hash_compatible
causing the possibility of returning SSH_OK if memory allocation error
happens later in the function.

The assignment of SSH_ERROR if the verification fails is no longer needed,
because the value of the variable is already SSH_ERROR.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:41:03 +02:00
Jakub Jelen
b733df6ddc CVE-2023-1667:tests: Client coverage for key exchange with kex guessing
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:51 +02:00
Jakub Jelen
18576cf98f CVE-2023-1667:kex: Add support for sending first_kex_packet_follows flag
This is not completely straightforward as it requires us to do some state
shuffling.

We introduce internal flag that can turn this on in client side, so far for
testing only as we do not want to universally enable this. We also repurpose the
server flag indicating the guess was wrong also for the client to make desired
decisions.

If we found out our guess was wrong, we need to hope the server was able to
figure out this much, we need to revert the DH FSM state, drop the callbacks
from the "wrong" key exchange method and initiate the right one.

The server side is already tested by the pkd_hello_i1, which is executing tests
against dropbrear clients, which is using this flag by default out of the box.

Tested manually also with the pkd_hello --rekey to make sure the server is able
to handle the rekeying with all key exchange methods.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:48 +02:00
Jakub Jelen
0c855d2949 CVE-2023-1667:kex: Correctly handle last fields of KEXINIT also in the client side
Previously, the last two fields of KEXINIT were considered as always zero for
the key exchange. This was true for the sending side, but might have not been
true for the received KEXINIT from the peer.

This moves the construction of these two fields closer to their reading or
writing, instead of hardcoding them on the last possible moment before they go
as input to the hashing function.

This also allows accepting the first_kex_packet_follows on the client side, even
though there is no kex algorithm now that would allow this.

It also avoid memory leaks in case the server_set_kex() or ssh_set_client_kex()
gets called multiple times, ensuring the algorithms will not change under our
hands.

It also makes use of a new flag to track if we sent KEXINIT.

Previously, this was tracked only implicitly by the content of the
session->next_crypto->{server,client}_kex (local kex). If it was not set, we
considered it was not send. But given that we need to check the local kex even
before sending it when we receive first_kex_packet_follows flag in the KEXINIT,
this can no longer be used.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:47 +02:00
Jakub Jelen
aaa3d4fc7d CVE-2023-1667:dh: Expose the callback cleanup functions
These will be helpful when we already sent the first key exchange packet, but we
found out that our guess was wrong and we need to initiate different key
exchange method with different callbacks.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:41 +02:00
Jakub Jelen
c4f05c28aa CVE-2023-1667:kex: Factor out the kex mapping to internal enum
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:39 +02:00
Jakub Jelen
abcf9699aa CVE-2023-1667:kex: Remove needless function argument
The information if the session is client or server session is already part of
the session structure so this argument only duplicated information.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:37 +02:00
Jakub Jelen
6887a5bb20 CVE-2023-1667:packet: Do not allow servers to initiate handshake
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:36 +02:00
Jakub Jelen
85ddd8b34e CVE-2023-1667:packet_cb: Log more verbose error if signature verification fails
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-05-04 13:40:23 +02:00
Jakub Jelen
4637c87f2d token: Add missing whitespace
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:52 +02:00
Jakub Jelen
d1e1aea0b6 kex: Reformat ssh_kex_select_methods
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:50 +02:00
Jakub Jelen
e9741edcde client: Reformat ssh_client_connection_callback
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:48 +02:00
Jakub Jelen
1529bbd7ac wrapper: Reformat crypto_new
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:45 +02:00
Jakub Jelen
27e39655c5 Reformat struct ssh_session_struct
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:43 +02:00
Jakub Jelen
1b5e183544 server: Reformat ssh_server_connection_callback
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:41 +02:00
Jakub Jelen
fef76366db Reformat ssh_packet_kexinit()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:38 +02:00
Jakub Jelen
cef34a78ef kex: Reformat ssh_send_kex
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:36 +02:00
Jakub Jelen
cf1c67ddb4 packet: Reformat callback handling functions
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:34 +02:00
Jakub Jelen
e72f58811f server: Reformat callback_receive_banner
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:32 +02:00
Jakub Jelen
b923d25fef server: Reformat ssh_handle_key_exchange
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:30 +02:00
Jakub Jelen
545724b7df packet: Fix indentation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:28 +02:00
Jakub Jelen
9844dd5f79 kex: Clarify the comment
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:25 +02:00
Jakub Jelen
cd8ef68b84 gssapi: Free mic_buffer on all code paths (GHSL-2023-042)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:22 +02:00
Jakub Jelen
cee5f9f69c gssapi: Release output_token on error path (GHSL-2023-041)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:20 +02:00
Jakub Jelen
acfa6e3cac gssapi: Release actual_mechs on exit (GHSL-2023-040)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:17 +02:00
Jakub Jelen
3f92520c74 gssapi: Free output token on exit path (GHSL-2023-039)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:15 +02:00
Jakub Jelen
587166577f gssapi: Free mic_token_buffer on before return (GHSL-2023-038)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:12 +02:00
Jakub Jelen
6a7c1f4e5d gssapi: Release output_token (GHSL-2023-037)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:10 +02:00
Jakub Jelen
dd899b7591 gssapi: Avoid memory leaks of selected OID (GHSL-2023-036)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:07 +02:00
Jakub Jelen
6c85771200 gssapi: Release buffer on error path (GHSL-2023-035)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:05 +02:00
Jakub Jelen
2830726c53 gssapi: Free both_supported on error paths (GHSL-2023-033)
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:51:02 +02:00
Jakub Jelen
e8c959084f kex: Avoid NULL pointer dereference (GHSL-2023-032)
Thanks Phil Turnbull from Github

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:59 +02:00
Anderson Toshiyuki Sasaki
a94ac4c080 tests: Verify error returned by kill
Verify the error code returned by kill() in torture_terminate_process().
The error code is raised when killing the process failed.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c8222dc1f6)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:22 +02:00
Anderson Toshiyuki Sasaki
7f20bbca62 tests: Use a common function to start sshd
In torture_reload_sshd_server(), instead of trying to use SIGHUP to
reload the configuration file, kill the original process and create a
new one with the new configuration.  With this change, both
torture_setup_sshd_server() and torture_reload_sshd_server() need to
start sshd, with the only difference in the configuration setup.  The
shared code to start the sshd server was moved to a new introduced
internal function torture_start_sshd_server().

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 35224092eb)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:22 +02:00
Jakub Jelen
761ba97145 tests: Give server more time to start
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 12d5c136f2)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:22 +02:00
Jakub Jelen
5d8c346225 ci: Test FIPS mode only on CentOS 8
CentOS 9 FIPS mode is too different for this libssh version and Fedora
FIPS mode is not maintained.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:19 +02:00
Jakub Jelen
754048b419 ci: Add CentOS 8 and 9 to CI
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:17 +02:00
Jakub Jelen
7b44e23e6f tests: Skip ciphers not supported by OpenSSH
This is a problem in recent Fedora, as the 0.9 branch still supports
blowfish, while OpenSSH dropped this support in 7.6.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:14 +02:00
Jakub Jelen
c26414972a ci: Sync VS targets with master
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:50:11 +02:00
Jakub Jelen
31a33fd2fd tests: Send a bit more to make sure rekey is completed
This was for some reason failing on CentOS 7 in 0.10 branch so bringing this to
the master too.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-28 11:49:15 +02:00
Jakub Jelen
3beac46361 tests: Update to unbreak agent_cert test for CentOS 8
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2ba5a5e976)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-17 18:11:30 +02:00
Jakub Jelen
fea290212a tests: Skip the workaround forcing SHA1 signatures
In certificate authentication with OpenSSH 8.0, the SHA2 signatures were
not accepted correctly [1]. This was not an issue up until the OpenSSH
8.8p1, which does no longer allow SHA1 signatures by default so this
broke the CI and tests against the new OpenSSH [2].

Fixes !107

[1] https://bugzilla.mindrot.org/show_bug.cgi?id=3016
[2] https://gitlab.com/libssh/libssh-mirror/-/issues/107

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 86ee3f5a00)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-17 18:11:30 +02:00
Jakub Jelen
81320d35f3 examples: Fix build issue with new clang 15
The error was  the following

/builds/libssh/libssh-mirror/examples/sshnetcat.c:241:18: error: a function
declaration without a prototype is deprecated in all versions of C
[-Werror,-Wstrict-prototypes]
void cleanup_pcap(){
                 ^
                  void

and similar

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 22f0f0dd60)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-17 18:11:29 +02:00
Andreas Schneider
cb8245a0e4 misc: Fix expanding port numbers
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 648baf0f3c)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-17 18:11:29 +02:00
Andreas Schneider
fd1add66cf misc: Fix format truncation in ssh_path_expand_escape()
error: ‘%u’ directive output may be truncated writing between 1 and 10
bytes into a region of size 6.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 20406e51c9)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-17 15:52:36 +02:00
Andreas Schneider
ea075e3f2e tests: Fix rekey test so it passes on build systems
The test failed on Fedora Koji and openSUSE Build Service on i686 only. Probably
the rekey on the server needs longer here to collect enough entropy. So we need
to try harder before we stop :-)

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b3b3fbfa1d)

Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-04-17 15:34:54 +02:00
Andreas Schneider
6b89f4d206 cpack: Do not package .cache directory used by clangd 2021-08-26 15:11:07 +02:00
Jakub Jelen
da6d026c12 Relase 0.9.6
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2021-08-19 09:49:25 +02:00
Jakub Jelen
240bda21dc ChangeLog: Fix release date of 0.9.5
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2021-08-18 19:53:10 +02:00
Jakub Jelen
f3652f6da0 tests: Simple reproducer for rekeying with different kex
We do not use SHA1 as it is disabled in many systems

Verifies CVE-2021-3634

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

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

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

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

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

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

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

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

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

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

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

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

CID 1445481

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

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

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

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

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

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

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

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

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

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

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

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

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

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

https://bugs.libssh.org/T252

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

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

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

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

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

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

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

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

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e4c5f6d3d9)
2021-08-17 11:02:47 +02:00
Jakub Jelen
0cceefd49d Bump version to 0.9.5
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2020-09-10 14:44:47 +02:00
Jakub Jelen
8af24251c1 Add a new location of sftp-server on Tumbleweed
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit ff599a9c53)
2020-09-02 17:14:54 +02:00
Jakub Jelen
645106a1ca tests: Enable all CASignatureAlgorithms as SHA1 certificates are now disabled in OpenSSH 8.2p1
This option is unknown to older OpenSSH versions (for example CentOS 7
with OpenSSH 7.4) so we can not add it everywhere.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 44de453b22)
2020-08-13 17:35:09 +02:00
Jakub Jelen
6672a457fb tests: Enable RSA SHA1 certs for testing against older OpenSSH
The OpenSSH 7.4 or 7.6 in Ubuntu and CentOS 7 does not support SHA2
RSA certificates and libssh automatically falls back to SHA1, which
is not allowed by default.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit db948bdac8)
2020-08-13 17:35:09 +02:00
Jakub Jelen
737ba4a680 CMakeLists: Shorten the keys lists passed to the ssh command
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c106cd1f83)
2020-08-13 17:35:09 +02:00
Jakub Jelen
d4b07d1675 tests: Use the path to SSH executable consistently
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2892b49a37)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
d462cc30c9 pkd client run user executable
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9e7de14d59)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
c7f35f4d49 pkd: fix snprintf compiler warning
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bba5fa18ed)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
6a1dc7df87 tests: use detected sshd path
The static sshd directory wasn't matching the detected sshd and prevented the testcases to be run against local OpenSSH builts

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1089948346)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
41e54ce042 tests: use OpenSSH-provided ciphers
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7ec67011c5)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
a7c0ccd35e tests: search for netcat binary
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 177e76f753)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
9ec6923479 pkd: use detected OpenSSH supported key types
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3d2570ff5f)
2020-08-13 17:35:09 +02:00
Aris Adamantiadis
d9e37c4e09 tests: detect OpenSSH supported ciphers
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3063a57fc8)
2020-08-13 17:35:09 +02:00
Anderson Toshiyuki Sasaki
56ebe3c7d0 pki_crypto: Use temporary pointer when using i2d_*
These functions modify the provided pointer by advancing to the end of
if (point to the byte after the last written).  This makes the pointer
invalid, making necessary to use a temporary variable.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fe18ef2798)
2020-08-13 17:32:15 +02:00
Anderson Toshiyuki Sasaki
e0c7d78a39 tests: Do not parse configuration file in torture_knownhosts
The test might fail if there is a local configuration file that changes
the location of the known_hosts file.  The test should not be affected
by configuration files present in the testing environment.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f10d80047c)
2020-06-24 11:41:04 +02:00
Anderson Toshiyuki Sasaki
74e162c67f channel: Do not return error if the server closed the channel
If the server properly closed the channel, the client should not return
error if it finds the channel closed.

Fixes T231

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 750e4f3f9d)
2020-06-23 19:58:07 +02:00
Anderson Toshiyuki Sasaki
039054ea6e examples: Tolerate incomplete writes in exec example
Previously, the exec example would fail if it could not write the whole
read buffer to stdout.  With this changes, the exec example will be able
to write parts of the buffer until the whole buffer is written.

This makes the exec example to run when the stdout buffer is small.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b0518552f1)
2020-06-23 19:57:55 +02:00
Anderson Toshiyuki Sasaki
1da78553dc tests: Add test for CVE-2019-14889
The test checks if a command appended to the file path is not executed.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1694606e12)
2020-06-23 19:57:12 +02:00
Andreas Schneider
c5dfc2d5ce buffer: Add NULL check for 'buffer' argument
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 245ad744b5)
2020-06-08 09:15:26 +02:00
Andreas Schneider
f760781cb8 buffer: Reformat ssh_buffer_add_data()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 10b3ebbe61)
2020-06-08 09:15:24 +02:00
Andreas Schneider
8316bf1177 sftpserver: Add missing return check for ssh_buffer_add_data()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2782cb0495)
2020-06-08 09:15:22 +02:00
Andreas Schneider
e631ebb3e2 sftpserver: Add missing NULL check for ssh_buffer_new()
Thanks to Ramin Farajpour Cami for spotting this.

Fixes T232

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 533d881b0f)
2020-06-08 09:15:20 +02:00
David Wedderwille
dcc0b9d7aa cmake: add _POSIX_SOURCE
Fixes T228

Signed-off-by: David Wedderwille <davidwe@posteo.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 641a80be74)
2020-05-15 18:43:26 +02:00
Heiko Thiery
b1bbd20dfa cmake: Add autogenerated libssh_version.h
Set the cmake project verision to the autogenerated file to have a single
point to set the version. This will be included in the libssh.h file.

Pair-Programmed-With: Andreas Schneider <asn@cryptomilk.org>
Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bee8ed82ab)
2020-05-07 11:59:09 +02:00
Jakub Jelen
929a6b7d50 pki: Mark explicit fall through
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7c20875891)
2020-05-05 14:33:32 +02:00
Jakub Jelen
88d676cf1a external: Do not confuse new gcc
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0c7a772301)
2020-05-05 14:33:30 +02:00
Jakub Jelen
b93c9ae641 client: Properly indicate fall through
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c45cfce166)
2020-05-05 14:33:27 +02:00
Heiko Thiery
a77d89d3ea session: add missing return value documentation
Add SSH_AGAIN as return value to ssh_handle_packets documentation.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e76332bbd6)
2020-05-05 14:33:24 +02:00
Jakub Jelen
4276560680 channels: Avoid returning SSH_AGAIN from ssh_channel_poll_timeout()
This addresses a regression introduced in 3bad0607, partially fixed in 022409e9,
but the function was still able to return SSH_AGAIN, which was not expected by
callers.

Based on discussion in [1] and [2]

[1] https://gitlab.com/libssh/libssh-mirror/-/merge_requests/101
[2] https://www.libssh.org/archive/libssh/2020-03/0000029.html

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 6417f5a3ca)
2020-05-05 14:33:01 +02:00
Jakub Jelen
a7ce241652 channels: reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit fe0fcbbc67)
2020-05-05 14:32:59 +02:00
Jakub Jelen
1c7cfaba9c examples: Avoid unused parameter warnings and reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit c2f64108a1)
2020-05-05 14:32:57 +02:00
Jakub Jelen
98c91e68fa examples: Add missing includes
Fixes: T225

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 58d53f1397)
2020-05-05 14:32:31 +02:00
Jakub Jelen
078cb4c6f3 libcrypto-compat: Fix indentation and return value
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit eebb02fff5)
2020-05-05 14:32:27 +02:00
Rosen Penev
5972d7a98e libcrypto: remove deprecated API usage
EVP_CIPHER_CTX_init was replaced with _reset.

Removed EVP_CIPHER_CTX_cleanup. The successive _free call handles that.

Removed old SSLeay function usage.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 54296787a7)
2020-05-05 14:32:23 +02:00
Rosen Penev
d35fdfbdb4 libcrypto-compat: add extra functions
Added extra functions. The next commit will switch to them.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 70478619ce)
2020-05-05 14:32:15 +02:00
Laurent Bigonville
7ee7ff94ba Fix FTBFS on hurd-i386
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=933015

Signed-off-by: Laurent Bigonville <bigon@bigon.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit a881c318ac)
2020-05-05 14:32:09 +02:00
Laurent Bigonville
c42aab0122 Make the documentation reproducible
Signed-off-by: Laurent Bigonville <bigon@bigon.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5f1d0c4795)
2020-05-05 14:32:07 +02:00
StefanBruens
69e97057c7 Correctly parse v4 subsecond timestamps
All subsecond timestamps are only in the packets if both the
SUBSECOND_TIMES flag and the timestamp flag, e.g. ATTR_ACCESSTIME
are set.

SUBSECOND_TIMES are not very common across server implementations
(e.g. openssh does not include it, nor does libssh's sftpserver
implementation), but this interpretation of the SFTP protocol draft
is used by WinSCP and lftp.

Fixes T219.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1ff6dda616)
2020-05-05 14:32:04 +02:00
Anderson Toshiyuki Sasaki
3025eeace3 client: Check if the library is initialized in ssh_connect()
If the library is not initialized, SSH_ERROR is returned and the error
message is set properly.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e3e3a27863)
2020-05-05 14:31:59 +02:00
Anderson Toshiyuki Sasaki
ffb0007768 client: Reformat ssh_connect()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0f33eecc01)
2020-05-05 14:31:58 +02:00
Anderson Toshiyuki Sasaki
a99b8a3979 init: Introduce internal is_ssh_initialized()
The introduced function returns whether the library is initialized or
not.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dba2114ed7)
2020-05-05 14:31:53 +02:00
Anderson Toshiyuki Sasaki
0a450f0251 init: Clarify the need to call ssh_{init, finalize}()
When libssh is statically linked, it is necessary to explicitly call
ssh_init() before calling any other provided API.  It is also necessary
to call ssh_finalize() before exiting to free allocated resources.

Fixes T222

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e3e52394c1)
2020-05-05 14:31:49 +02:00
Andreas Schneider
9e9df61244 Bump version to 0.9.4
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2020-04-09 09:30:20 +02:00
Andreas Schneider
958afb1c6a CVE-2020-1730: Fix a possible segfault when zeroing AES-CTR key
Fixes T213

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit b36272eac1)
2020-04-09 09:30:00 +02:00
Anderson Toshiyuki Sasaki
e510de0315 kex: Add support for diffie-hellman-group14-sha256
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9eb1ce88ae)
2020-04-06 11:36:35 +02:00
Andreas Schneider
34c596182d dh-gex: Check return value of ssh_get_random()
CID #1422162

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d2f0d3270a)
2020-04-06 11:36:33 +02:00
Andreas Schneider
1a18d9cce2 cmake: Fix building with threading support on MinGW
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit a9a7c2dc29)
2020-04-06 11:36:30 +02:00
Anderson Toshiyuki Sasaki
4c83d19c48 auth: Fix memory leak in ssh_userauth_publickey_auto()
When a key is rejected, free the allocated memory before returning.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6bd2b93f43)
2020-03-29 09:59:52 +02:00
Andreas Schneider
673bf1ff09 doc: Fix a doxygen warning
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 46c54e5ddb)
2020-03-27 13:15:30 +01:00
Andreas Schneider
fe1fe49617 doc: Make sure we parse the server and sftp documentation
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bbfce454de)
2020-03-27 13:15:28 +01:00
Andreas Schneider
316f46f833 doc: Add SSH auth callback to libssh_auth doc group
Fixes T217

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3e5dc99198)
2020-03-27 13:15:26 +01:00
Jon Simons
0dd71375e7 pki: fix pki_key_ecdsa_to_key_type thread-safety
Resolves https://bugs.libssh.org/T214.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3664ba2800)
2020-02-11 10:16:00 +01:00
Andreas Schneider
9a10cef920 channels: Fix ssh_channel_poll_timeout() not returing available bytes
Fixes T211

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 022409e99c)
2020-01-23 11:03:44 +01:00
Jakub Jelen
6fcd0940e3 packet_crypt: Check return values from AEAD deciphering
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e31e7b0406)
2020-01-23 10:31:44 +01:00
Jakub Jelen
0c8dbf5c81 curve25519: Avoid memory leaks
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6644f8ca3b)
2020-01-23 10:31:38 +01:00
Anderson Toshiyuki Sasaki
a0aa62fffe gitlab-ci: Create obj directory for Windows builds
The obj directory is not created anymore when the git repository is
cloned.  Create the directory during the build.

Also set the variable "ErrorActionPreference: STOP" to make the build to
fail if an error occurs.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7f5e14698f)
2020-01-23 09:53:48 +01:00
Andreas Schneider
402c922a9e pki_crypto: Fix possible memory leak on error
CID #1409680

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 72498bac5f)
2020-01-23 09:50:41 +01:00
Andreas Schneider
112e32ba86 messages: Add missing NULL check
CID #1409678

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4b4f568a68)
2020-01-23 09:50:35 +01:00
Andreas Schneider
e2c5f5c7d1 tests: Use correct assert function for ssh return codes
CID #1398983

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6324014866)
2020-01-23 09:50:33 +01:00
Jakub Jelen
6dcfa25c9b socket: Fix the error message
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3a6751f3d2)
2020-01-23 09:50:04 +01:00
Jakub Jelen
eed8d8e957 socket: Kill the proxy command if it still runs on disconnect
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dd64980662)
2020-01-23 09:50:01 +01:00
Jakub Jelen
1935e15cd4 pki_gcrypt: Warn about unsupported PEM export in gcrypt
Based on the following mail thread:

https://www.libssh.org/archive/libssh/2019-12/0000027.html

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 24f450fed1)
2020-01-23 09:49:52 +01:00
Jakub Jelen
238dbabef8 tests: Unbreak strict builds on Ubuntu
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9d5616a18c)
2020-01-23 09:49:45 +01:00
Jakub Jelen
ee7ee2404a libgcrypt: Do not leak memory with invalid key lengths
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7e692ee1b6)
2020-01-23 09:49:35 +01:00
Jakub Jelen
6205cad534 pki_gcrypt: Do not confuse static analyzers
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dd54ffb2f1)
2020-01-23 09:49:30 +01:00
Jakub Jelen
d5a37e2bf5 legacy,keys: Fix the macro conditions
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3642224ee5)
2020-01-23 09:49:26 +01:00
Jakub Jelen
226d2a16b0 mbedcrypto_missing: Always check return values
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9b858f57c5)
2020-01-23 09:49:22 +01:00
Jakub Jelen
46105f4aa6 mbedcrypto_missing: Avoid potential memory leaks as reported by csbuild
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 13c88a2e0a)
2020-01-23 09:49:19 +01:00
Jakub Jelen
62f7004d5a pki_mbedtls: Avoid potential memory leaks
reported by csbuild

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 059b6851dc)
2020-01-23 09:49:16 +01:00
Jakub Jelen
d7358ee5a7 pki_mbedtls: Do not warn about unused arguments
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 71ba61cc5b)
2020-01-23 09:49:12 +01:00
Jakub Jelen
ec8cedd803 options: Avoid needless assignment as reported by csbuild
The error was

 src/options.c:971:13: warning: Value stored to 'u' is never read
 #            u = 0;
 #            ^   ~
 src/options.c:971:13: note: Value stored to 'u' is never read
 #            u = 0;
 #            ^   ~
 #  969|           case SSH_OPTIONS_KBDINT_AUTH:
 #  970|           case SSH_OPTIONS_GSSAPI_AUTH:
 #  971|->             u = 0;
 #  972|               if (value == NULL) {
 #  973|                   ssh_set_error_invalid(session);

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 30cc1568f4)
2020-01-23 09:49:07 +01:00
Jakub Jelen
92124ae65a tests: Do not require strict host key checking in openssh
as nothing really sets these keys up and they are probably preserverd
from some previous test, which is really not a good testing strategy.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8eda4165cf)
2020-01-23 09:49:02 +01:00
Jakub Jelen
ea198fee43 tests: Avoid needless assignment as reported by csbuild
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1563bddf88)
2020-01-23 09:48:36 +01:00
Jakub Jelen
393cd36c01 kex: Avoid always-false comparisons as reported by csbuild
/builds/jjelen/libssh-mirror/src/kex.c:360:17: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] <--[cc]
  360 |         if (len < 0) {
      |                 ^
/builds/jjelen/libssh-mirror/src/kex.c:372:17: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] <--[cc]
  372 |         if (len < 0) {
      |                 ^

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e2841908fb)
2020-01-23 09:48:32 +01:00
Aris Adamantiadis
93bf0ab6a3 tests: fix typos
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 23c529c888)
2020-01-23 09:47:57 +01:00
Jon Simons
251f60c031 curve25519: fix uninitialized arg to EVP_PKEY_derive
Ensure that the `keylen` argument as provided to `EVP_PKEY_derive`
is initialized, otherwise depending on stack contents, the function
call may fail.

Fixes T205.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b94ecf18bd)
2019-12-16 12:59:58 +01:00
Jakub Jelen
b33dcda94d torture: Accept whole pid_t range
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d2a32ca6d3)
2019-12-11 11:39:01 +01:00
Aris Adamantiadis
f0335d1b59 tests: bigger sshd config buffer (fixes #T180)
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e42307bbe3)
2019-12-11 11:38:58 +01:00
Andreas Schneider
ed87c2221c include: Rename __unused__ to __attr_unused__
This avoids a collision with valgrind.h

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 742d81ec5d)
2019-12-11 11:38:56 +01:00
Jakub Jelen
ac2f4853bb init: Fix documentation about return values of void functions
Fixes T203

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b03818aaed)
2019-12-11 11:38:54 +01:00
Andreas Schneider
64ce53fdba Bump version to 0.9.3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2019-12-09 19:26:16 +01:00
Andreas Schneider
295739e0c8 cpack: Ignore patch files
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ecc78ec154)
2019-12-09 19:26:16 +01:00
Jakub Jelen
101ffd70a7 config: Ignore empty lines to avoid OOB array access
Fixes T187

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 574690ae2e)
2019-12-09 16:39:24 +01:00
Jakub Jelen
45878b131c tests: Check behavior of match_pattern()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c7cacf986f)
2019-12-09 16:39:22 +01:00
Jakub Jelen
21adb54dc6 match: Limit possible recursion when parsing wildcards to a sensible number
Fixes T186

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 31f9c39479)
2019-12-09 16:38:37 +01:00
Jakub Jelen
13fa009a2e match: Avoid recursion with many asterisks in pattern
Partially fixes T186

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cf0beff987)
2019-12-09 16:38:37 +01:00
Andreas Schneider
8600015b3e pki: Fix possible information leak via uninitialized stack buffer
Fixes T190

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 178b53f924)
2019-12-09 16:38:37 +01:00
Andreas Schneider
8f20ece14f pki_container_openssh: Initialize pointers to NULL
Fixes T190

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e065d2bb3f)
2019-12-09 16:38:37 +01:00
Andreas Schneider
d15fa16213 SSH-01-012: Fix information leak via uninitialized stack buffer
Fixes T190

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9d67ca251c)
2019-12-09 16:38:37 +01:00
Andreas Schneider
a91e5f7585 SSH-01-010: Improve documentation for fingerprinting functions
Fixes T184

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit cb0ccf372e)
2019-12-09 16:38:37 +01:00
Jakub Jelen
7b7b2acd23 doc: Use https where possible
Related to T196

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1fa1a467ed)
2019-12-09 16:38:37 +01:00
Jakub Jelen
1c66217875 doc: Update the list of RFCs and clearly mention which are not implemented in libssh
Fixes T196

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 606a97c4d6)
2019-12-09 16:38:37 +01:00
Anderson Toshiyuki Sasaki
95eb071c22 tests: Add a test for SCP with protocol message injection
Test if the file name is correctly escaped to avoid protocol message
injection.

Fixes T189

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit cc9db5b56c)
2019-12-09 16:38:37 +01:00
Anderson Toshiyuki Sasaki
d117de188f scp: Do not allow newlines in pushed files names
When pushing files or directories, encode the newlines contained in the
names as the string "\\n".  This way the user cannot inject protocol
messages through the file name.

Fixes T189

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bab7ba0146)
2019-12-09 16:38:37 +01:00
Anderson Toshiyuki Sasaki
ae68f13a78 misc: Add a function to encode newlines
Given a string, the added function encodes existing newline characters
('\n') as the string "\\n" and puts into a given output buffer.

The output buffer must have at least 2 times the length of the input
string plus 1 for the terminating '\0'. In the worst case, each
character can be replaced by 2 characters.

Fixes T189

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c9ce8fa40b)
2019-12-09 16:38:37 +01:00
Andreas Schneider
ad49f0a556 gzip: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6c79ed9801)
2019-12-09 16:38:37 +01:00
Andreas Schneider
975eb87c19 knownhosts: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7ae47df16a)
2019-12-09 16:38:37 +01:00
Andreas Schneider
a888b65ff5 pcap: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6734516278)
2019-12-09 16:38:37 +01:00
Andreas Schneider
375724bafe base64: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3cf665a53d)
2019-12-09 16:38:37 +01:00
Andreas Schneider
b7b9c6d5b9 packet: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 35799bb1c6)
2019-12-09 16:38:37 +01:00
Andreas Schneider
1c7efb7b46 socket: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 476bde4d69)
2019-12-09 16:38:37 +01:00
Andreas Schneider
128fb03d7e examples: Use SSH_STRING_FREE_CHAR()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0938d397be)
2019-12-09 16:38:37 +01:00
Andreas Schneider
994b653161 tests: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4e809ef122)
2019-12-09 16:38:37 +01:00
Andreas Schneider
9817d13de0 dh-gex: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 80d092037f)
2019-12-09 16:38:37 +01:00
Andreas Schneider
41cd5f4012 message: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 45d9802e1b)
2019-12-09 16:38:37 +01:00
Andreas Schneider
e6fdb28faf message: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5db5e7e527)
2019-12-09 16:38:36 +01:00
Andreas Schneider
b21cba0c3c pki_container_openssh: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d7abfe7e8f)
2019-12-09 16:38:36 +01:00
Andreas Schneider
7498167e6c pki_container_openssh: Use SSH_STRING_FREE
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f422fb02f6)
2019-12-09 16:38:36 +01:00
Andreas Schneider
f1b1355975 gssapi: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b719f705c6)
2019-12-09 16:38:36 +01:00
Andreas Schneider
83a8c87b08 gssapi: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3b8fcbad24)
2019-12-09 16:38:36 +01:00
Andreas Schneider
48c34509f2 kex: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3ab8b76921)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0469458194 kex: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7c3a6ca6bc)
2019-12-09 16:38:36 +01:00
Andreas Schneider
d0dc57be06 agent: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6eb34cec33)
2019-12-09 16:38:36 +01:00
Andreas Schneider
7f7c249e15 agent: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 45ee892327)
2019-12-09 16:38:36 +01:00
Andreas Schneider
a64aa7406b server: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 321b27b788)
2019-12-09 16:38:36 +01:00
Andreas Schneider
81650a7652 ecdh_mbedcrypto: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ac33b3adbc)
2019-12-09 16:38:36 +01:00
Andreas Schneider
26a29ee362 dh: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5e21c24fab)
2019-12-09 16:38:36 +01:00
Andreas Schneider
7f5d851f6e ecdh: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit abe1bf910e)
2019-12-09 16:38:36 +01:00
Andreas Schneider
b1f4b6ffec channels: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 752c906ea7)
2019-12-09 16:38:36 +01:00
Andreas Schneider
1788f98543 channels: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1832ed4fef)
2019-12-09 16:38:36 +01:00
Andreas Schneider
413ee92572 sftp: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4cae57c581)
2019-12-09 16:38:36 +01:00
Andreas Schneider
d6664d248b sftp: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9384a18e91)
2019-12-09 16:38:36 +01:00
Andreas Schneider
14e19ee37e packet_cb: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 88a3dd86f1)
2019-12-09 16:38:36 +01:00
Andreas Schneider
7fe7203f06 sftpserver: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 449c0d66cc)
2019-12-09 16:38:36 +01:00
Andreas Schneider
02ed74711f packet_cb: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4cd084f13b)
2019-12-09 16:38:36 +01:00
Andreas Schneider
55cbb64f44 curve25519: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9020f4e63a)
2019-12-09 16:38:36 +01:00
Andreas Schneider
acc109eb67 auth: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6596ee9fb2)
2019-12-09 16:38:36 +01:00
Andreas Schneider
54e7c8d21a session: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 25f1c80950)
2019-12-09 16:38:36 +01:00
Andreas Schneider
a8b2a874de session: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5e6cb6891f)
2019-12-09 16:38:36 +01:00
Andreas Schneider
deaf3f3195 pki_mbedcrypto: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0684f1b94a)
2019-12-09 16:38:36 +01:00
Andreas Schneider
123e8448e6 pki_mbedcrypto: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 42547772df)
2019-12-09 16:38:36 +01:00
Andreas Schneider
ba563611ee ecdh_crypto: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 288bbd5bd0)
2019-12-09 16:38:36 +01:00
Andreas Schneider
69b4860404 pki_crypto: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8525b4bb01)
2019-12-09 16:38:36 +01:00
Andreas Schneider
564e298989 pki_crypto: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d97770b025)
2019-12-09 16:38:36 +01:00
Andreas Schneider
5a41514d8d pki: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f89cf79c49)
2019-12-09 16:38:36 +01:00
Andreas Schneider
8f0ab53b7b pki: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 189fd76589)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0016888942 ecdh_gcrypt: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2786a3e96a)
2019-12-09 16:38:36 +01:00
Andreas Schneider
ce045cf5ed libcrypto: Use SSH_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 09dfda8489)
2019-12-09 16:38:36 +01:00
Andreas Schneider
5ae2a05ca1 pki_gcrypt: Use SSH_BUFFER_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9a112f1548)
2019-12-09 16:38:36 +01:00
Andreas Schneider
8dcaf4bfa3 pki_gcrypt: Use SSS_STRING_FREE()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4e2d85745f)
2019-12-09 16:38:36 +01:00
Andreas Schneider
6c392befcc SSH-01-007: Fix possible double free of ssh strings
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 032f25aab3)
2019-12-09 16:38:36 +01:00
Andreas Schneider
5b55eefb96 gssapi: Make sure buffer is initialized
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit da81b99df1)
2019-12-09 16:38:36 +01:00
Andreas Schneider
9fc8e095ce SSH-01-006: Add missing NULL check in sftp_open()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit af2aeba838)
2019-12-09 16:38:36 +01:00
Andreas Schneider
65918ec38a SSH-01-006: Add missing NULL check in server_set_kex()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9ae81c5ceb)
2019-12-09 16:38:36 +01:00
Andreas Schneider
2caedc0d0d SSH-01-006: Add missing NULL check in ssh_scp_push_directory()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8aa2bbd0dc)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0187b71912 SSH-01-006: Add missing NULL checks in ssh_scp_push_file64()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit fff4120cbf)
2019-12-09 16:38:36 +01:00
Andreas Schneider
053a23b50d SSH-01-006: Add missing NULL checks in pki_signature_from_rsa_blob()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7b9cbcebe5)
2019-12-09 16:38:36 +01:00
Andreas Schneider
2b52a8df4d SSH-01-006: Add missing NULL check in ssh_pki_do_sign_agent()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 56d571ab81)
2019-12-09 16:38:36 +01:00
Andreas Schneider
fa33b61102 SSH-01-006: Add missing NULL check in ssh_packet_hmac_verify()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 69daa602b8)
2019-12-09 16:38:36 +01:00
Andreas Schneider
563e1fc821 SSH-01-006: Add missing NULL check in gzip_decompress()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 924dc5aed8)
2019-12-09 16:38:36 +01:00
Andreas Schneider
f6c8e87c3e SSH-01-006: Add missing NULL check in ssh_gssapi_handle_userauth()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6b8ab4bcd2)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0ff2cfe0e6 SSH-01-006: Add missing NULL check in ssh_gssapi_handle_userauth()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit af2ea417da)
2019-12-09 16:38:36 +01:00
Andreas Schneider
828f8dd106 SSH-01-006: Add missing NULL check in ssh_gssapi_build_mic()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c7172c183f)
2019-12-09 16:38:36 +01:00
Andreas Schneider
5f5a6e15b3 SSH-01-006: Add missing NULL check in ssh_gssapi_oid_from_string()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 33cca875c2)
2019-12-09 16:38:36 +01:00
Andreas Schneider
e5b403f83a SSH-01-006: Add missing NULL check for ssh_packet_get_current_crypto()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b55d7f3b73)
2019-12-09 16:38:36 +01:00
Andreas Schneider
11cb618c75 SSH-01-006: Add missing ENOMEM check in ssh_gssapi_auth_mic()
Fixes T193

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7588979977)
2019-12-09 16:38:36 +01:00
Andreas Schneider
338e6cece5 cmake: Add -Wsign-compare to CFLAGS
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ab26db203e)
2019-12-09 16:38:36 +01:00
Andreas Schneider
4603105e0b socket: Pass port as uint16_t to ssh_socket_connect()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d60640cd0e)
2019-12-09 16:38:36 +01:00
Andreas Schneider
ee1f8512a4 bignum: Print ssh_make_string_bn() using SSH_LOG()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 64155b4f97)
2019-12-09 16:38:36 +01:00
Andreas Schneider
278ed59501 bignum: Fix integer types for ssh_make_bignum_string()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 64cd7e7ce2)
2019-12-09 16:38:36 +01:00
Andreas Schneider
9e9d35164b base64: Fix size types of bin_to_base64()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f5bc5147b9)
2019-12-09 16:38:36 +01:00
Andreas Schneider
a011f853ed base64: Reformat bin_to_base64()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b5160ce9e0)
2019-12-09 16:38:36 +01:00
Andreas Schneider
c98d024b9a base64: Make alphabet and const uint8_t
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit fdb7cb8f17)
2019-12-09 16:38:36 +01:00
Andreas Schneider
d5b10f569d base64: Reformat _bin_to_base64()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit fe9991b3c6)
2019-12-09 16:38:36 +01:00
Andreas Schneider
31f65d1ffb auth: Cast echo to char in ssh_userauth_kbdint_getprompt()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 159d95c26c)
2019-12-09 16:38:36 +01:00
Andreas Schneider
44e37c2546 include: Mark SSH_AUTH flags as unsigned
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5ef416fd35)
2019-12-09 16:38:36 +01:00
Andreas Schneider
35188b3843 agent: Return uint32_t for ssh_agent_get_ident_count()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1be68139bb)
2019-12-09 16:38:36 +01:00
Andreas Schneider
76aeedad1b agent: Reformat ssh_agent_get_ident_count()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c820d2a2dc)
2019-12-09 16:38:36 +01:00
Andreas Schneider
66419896f7 sftpserver: Fix integer type in sftp_reply_data()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b18acbdc7e)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0cb50ef31a sftp: Avoid comparison of integers of different sizes
This casts ssize_t len to size_t.

Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d672b1d7c4)
2019-12-09 16:38:36 +01:00
Andreas Schneider
88e40516c9 sftp: Cast sftp version to int
This is a public struct and the version should be unsigned there.

Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d40f33c400)
2019-12-09 16:38:36 +01:00
Andreas Schneider
f45aa46322 sftp: Use uint32_t for sftp extension count
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c29840060b)
2019-12-09 16:38:36 +01:00
Andreas Schneider
dbf757e3e8 sftp: Fix integer types in sftp_extension_supported()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 98824d6e11)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0a404349bc sftp: Fix integer types in sftp_read()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 839fab6df4)
2019-12-09 16:38:36 +01:00
Andreas Schneider
e9b74b5cb7 sftp: Fix integer types in sftp_write() and sftp_packet_write()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6b105624bf)
2019-12-09 16:38:36 +01:00
Andreas Schneider
6a0cbc73bd sftp: Remove internal function from sftp.h
Those are not marked as LIBSSH_API so not part of the public API and the
symbols aren't exported!

Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit db4345fb36)
2019-12-09 16:38:36 +01:00
Andreas Schneider
40ee7d2b38 server: Cast auth_methods to uint32_t
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6cef3e10bf)
2019-12-09 16:38:36 +01:00
Andreas Schneider
7db565601d server: Make sure methods is a valid value before casting
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 442d22da60)
2019-12-09 16:38:36 +01:00
Andreas Schneider
95faeb498f pki_crypto: Cast return value of EVP_PKEY_size() to size_t
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3cca9994d4)
2019-12-09 16:38:36 +01:00
Andreas Schneider
db97435a41 packet: Fix size types in ssh_packet_need_rekey()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 53635dff7e)
2019-12-09 16:38:36 +01:00
Andreas Schneider
c72a3495d0 options: Define constants as unsigned in ssh_options_set()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b7c628ff06)
2019-12-09 16:38:36 +01:00
Andreas Schneider
f2487f07f5 options: Define constants as unsigned in ssh_bind_options_set()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7823df8343)
2019-12-09 16:38:36 +01:00
Andreas Schneider
675d85e538 kex: Use a len variable for length checks in ssh_packet_kexinit()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit be34ff967f)
2019-12-09 16:38:36 +01:00
Andreas Schneider
dfd73d7cb2 sc25519: Fix integer types of sc25519_add()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 815f874964)
2019-12-09 16:38:36 +01:00
Andreas Schneider
db68813cb9 sc25519: Fix integer types in sc25519_mul()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f2d40fb94c)
2019-12-09 16:38:36 +01:00
Andreas Schneider
affb43a45f fe25519: Fix integer types of fe25519_iszero()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 31b26934b0)
2019-12-09 16:38:36 +01:00
Andreas Schneider
1e71951a51 include: Fix integer type of dh_pn and dh_pmax
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 922a2aee99)
2019-12-09 16:38:36 +01:00
Andreas Schneider
297aed60c4 channels: Return size_t for count_ptrs()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 500481e101)
2019-12-09 16:38:36 +01:00
Andreas Schneider
4e5dfd677e channels: Fix integer and bool argument of channel_default_bufferize()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit dad2720355)
2019-12-09 16:38:36 +01:00
Andreas Schneider
34fd4ebfc3 channels: Fix type of arguments of grow_window()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6f39deefcd)
2019-12-09 16:38:36 +01:00
Andreas Schneider
0080ac1f03 channels: Fix type of arguments of channel_open()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0abd187dba)
2019-12-09 16:38:36 +01:00
Andreas Schneider
dd4eb4a288 channels: Use ssize_t for to_read
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 07a57b74ba)
2019-12-09 16:38:36 +01:00
Andreas Schneider
a967258649 channels: Reformat ssh_channel_read_nonblocking()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8d671efdbd)
2019-12-09 16:38:36 +01:00
Andreas Schneider
e0e3636c60 channels: Use a size_t variable for length check
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3bad060738)
2019-12-09 16:38:36 +01:00
Andreas Schneider
c0e5393927 channesl: Reformat ssh_channel_poll_timeout()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit fbe115abba)
2019-12-09 16:38:36 +01:00
Andreas Schneider
36bdcb85b3 auth: Fix integer type in ssh_kbdint_free()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 66c4857c4a)
2019-12-09 16:38:36 +01:00
Andreas Schneider
cf34ba92bf auth: Fix integer type in ssh_kbdint_clean()
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1434b4a279)
2019-12-09 16:38:36 +01:00
Andreas Schneider
f5f547f35e examples: Fix integer types in libssh_scp.c
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8d62257172)
2019-12-09 16:38:36 +01:00
Andreas Schneider
1eed0cbd3d examples: Remove internal include from sshd_direct-tcpip.c
Fixes T188

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0773696ee5)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
1668bd8baf CVE-2019-14889: scp: Quote location to be used on shell
Single quote file paths to be used on commands to be executed on remote
shell.

Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3830c7ae6e)
2019-12-09 16:38:36 +01:00
Andreas Schneider
245be62438 CVE-2019-14889: scp: Don't allow file path longer than 32kb
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0b5ee39726)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
8ce782f9ec CVE-2019-14889: tests: Add unit tests for ssh_quote_file_name()
Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b82d2caa90)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
db34fd44fb CVE-2019-14889: misc: Add function to quote file names
The added function quote file names strings to be used in a shell.
Special cases are treated for the charactes '\'' and '!'.

Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c4ad1aba98)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
00dd3f864b CVE-2019-14889: scp: Log SCP warnings received from the server
Fixes T181

Previously, warnings received from the server were ignored.  With this
change the warning message sent by the server will be logged.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c75d417d06)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
52550994c5 CVE-2019-14889: scp: Reformat scp.c
Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 42c727d0c1)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
182d363b27 CVE-2019-14889: tests: Add tests for SCP client
Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 27bcac6845)
2019-12-09 16:38:36 +01:00
Andreas Schneider
f9189a8a9a packet: Do not deref a NULL pointer in ssh_packet_set_newkeys()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e00ef9635a)
2019-12-09 16:38:36 +01:00
Andreas Schneider
56c079cbb2 SSH-01-003: Add cipher NULL checks to ssh_packet_get_current_crypto()
Fixes T183

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e60fc79542)
2019-12-09 16:38:36 +01:00
Jakub Jelen
ab24d64241 Use only one variable denoting the size of methods arrays
Previously, there was non-consistent usage of constans SSH_KEX_METHODS,
KEX_METHODS_SIZE and of magic number 10 to reference the arrays used
for algorithm negotiation by peers. This commit settles down to the single
constant and its usage throughout the whole codebase.

Fixes T195

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c8a621c606)
2019-12-09 16:38:36 +01:00
Anderson Toshiyuki Sasaki
7856ae594b session: Initialize states explicitly
In ssh_session_new(), initialize the state machines states explicitly
for better readability.

Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ec67ad47eb)
2019-12-09 16:38:35 +01:00
Anderson Toshiyuki Sasaki
eeb9ae15c7 messages: Set signature state explicitly
In ssh_message_new(), initialize msg->auth_request.signature_state
explicitly for better readability.

Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 553eab748a)
2019-12-09 16:38:35 +01:00
Anderson Toshiyuki Sasaki
8837d32d92 channels: Initialize states explicitly
In ssh_channel_new(), initialize channel->state and
channel->request_state explicitly for better readability.

Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2f1f662d46)
2019-12-09 16:38:35 +01:00
Anderson Toshiyuki Sasaki
0408d8d851 auth: Set auto_state->state explicitly
When a new ssh_auth_auto_state_struct is allocated in
ssh_userauth_publickey_auto(), initialize the state explicitly for
better readability.

Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7e3995d2dd)
2019-12-09 16:38:35 +01:00
Anderson Toshiyuki Sasaki
bab8d84d13 session: Use ssh_packet_state_e instead of int
Use the enum type instead of int in the ssh_session_struct

Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 77bd8ed4c0)
2019-12-09 16:38:35 +01:00
Anderson Toshiyuki Sasaki
6ee159d9d2 messages: Use ssh_publickey_state_e instead of char
Use the enum type instead of char in the ssh_auth_request struct

Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 39f6ba2dc9)
2019-12-09 16:38:35 +01:00
Anderson Toshiyuki Sasaki
71ff06d04a session: Reformat ssh_new()
Fixes T194

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3f64fb3b3b)
2019-12-09 16:38:35 +01:00
Andreas Schneider
7851f216af cmake: Fix building libssh as a static lib on Windows
Fixes T198

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c54fd03e50)
2019-11-18 11:38:27 +01:00
Andreas Schneider
9b316fe8b9 gitlab-ci: Make sure we have enough git commits for csbuild
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit db632015be)
2019-11-08 15:44:17 +01:00
Andreas Schneider
389efc234b src: Add missing ABI files
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-11-07 16:19:45 +01:00
Andreas Schneider
f1e44a79a9 Bump version to 0.9.2
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2019-11-07 16:19:00 +01:00
Jakub Jelen
54cf7b92ed server: Use really the negotiated signature type
Generally, when the extension negotiation is enabled and client supports
SHA2 algorithms for RSA, they are supposed to be prioritized against the
old SHA1. If it is not (ssh-rsa is listed in front of rsa-sha2-* hostkey
algorithms during negotiation), the server wrongly tries to provide the
new typo of signature, ignoring the negotiated algirithm

This commit propagates the digest algorithm from negotiation to the actual
signature functions, which were previously responsible for decision
about the hash algorithm based just on the negotiated extensions.

Fixes T191

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1ebf506913)
2019-11-07 16:14:46 +01:00
Andreas Schneider
f0b676a9f0 gitlab-ci: Disable client testing as pam_wrapper is broken on TW
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit fbc2912dde)
2019-11-07 16:14:46 +01:00
Andreas Schneider
cc190b21b2 cmake: Fix setting up cwrap for server testing
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit ea4f71721f)
2019-11-07 16:14:46 +01:00
Andreas Schneider
a775324c35 cmake: Do not use cached LIBSSH_PUBLIC_INCLUDE_DIRS
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 4ab0fb2b48)
2019-11-07 16:14:46 +01:00
Andreas Schneider
5de765ebd5 cmake: Rename static library
This is only compiled for tests and fuzzers!

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 8c36a865f2)
2019-11-07 16:14:46 +01:00
Andreas Schneider
9de970160d cmake: Create ssh library directly as libssh
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 82c57c1f36)
2019-11-07 16:14:46 +01:00
Andreas Schneider
8a7abf2480 cmake: Add option to build shared libs
See https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit c2c3545391)
2019-11-07 16:14:46 +01:00
Andreas Schneider
920c08eaf8 cmake: Remove WITH_STATIC_LIB
We will honor BUILD_SHARED_LIBS from cmake next.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 729c92606c)
2019-11-07 16:14:46 +01:00
Andreas Schneider
c0fa85a43d cmake: Don't cache LIBSSH_LINK_LIBRARIES
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 498b63949e)
2019-11-07 16:14:46 +01:00
Andreas Schneider
be16481be2 cmake:pkd: Don't use LIBSSH_LINK_LIBRARIES
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 39f7ddaa06)
2019-11-07 16:14:46 +01:00
Andreas Schneider
c4ac076607 cmake: Remove libsocket
This is already part of LIBSSH_REQUIRED_LIBRARIES

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 2fcc15c5dc)
2019-11-07 16:14:46 +01:00
Andreas Schneider
ff534bc2fe cmake: Use target_include_directories()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 5e2788d4c5)
2019-11-07 16:14:46 +01:00
Anderson Toshiyuki Sasaki
27096c3c0f cmake: Only use OpenSSL Ed25519 implementation when possible
It is possible for OpenSSL to have the type EVP_PKEY_ED25519 in
openssl/evp.h, but not the single shot functions EVP_DigestSign() and
EVP_DigestVerify() which are required to generate Ed25519 signatures.

Only switch to use OpenSSL Ed25519 implementation when OpenSSL have all
required types and functions.

Fixes: T197

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 21655e396c)
2019-11-07 16:14:46 +01:00
Andreas Schneider
8a6ddc0a48 gitlab-ci: Mips is dead
Debian removed the cross compiling toolchain. So lets drop it.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d02c06268e)
2019-11-04 09:48:40 +01:00
Andreas Schneider
0c951b9f27 channel: Document ssh_channel_request_sftp()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e5767bf0b7)
2019-11-04 09:48:38 +01:00
Andreas Schneider
37529f16a8 auth: Add missing include for explicit_bzero()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4a113159b2)
2019-11-04 09:48:36 +01:00
Andreas Schneider
e89106b9f7 cpack: Ignore compule_database.json and clangd dir
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit a4b95268ee)
2019-10-25 17:29:55 +02:00
Andreas Schneider
67c0ce3d21 cmake: Bump version to 0.9.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2019-10-25 16:11:17 +02:00
Andreas Schneider
f618689c82 cmake: Bump library version
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2019-10-25 16:11:17 +02:00
Andreas Schneider
aaeaca8c6e cmake: Link compile database to source dir for clangd
See
https://github.com/ycm-core/YouCompleteMe
https://github.com/abingham/emacs-ycmd

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d4328069652635a431e13db0d7c8cbe02af21082)
2019-10-25 16:11:17 +02:00
Jakub Jelen
58c26f4823 packet: On failure, do not use uninitialized crypto
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit e9e8292370)
2019-10-25 16:11:17 +02:00
Jakub Jelen
c888d9c690 packet_crypt: Avoid out of bounds access in debug functions
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 5a0177def0)
2019-10-25 16:11:17 +02:00
Anderson Toshiyuki Sasaki
07df7bb4e6 tests: Do not parse global config in torture_ssh_session()
Do not parse global config file in sessions created by
torture_ssh_session().

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8a50dbc6ba)
2019-10-25 16:11:17 +02:00
Anderson Toshiyuki Sasaki
5aecfb5a96 tests: Do not parse global configuration when testing server
This removes the tests which uses external configuration files.  This
makes the tests no not change behaviour depending on the environment
they are being executed.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 85239c8ea0)
2019-10-25 16:11:17 +02:00
Anderson Toshiyuki Sasaki
50b37f2991 tests: Do not process server config during tests
In pkd tests, avoid processing the global server configuration file.
This is to allow testing with algorithms not allowed in the global
server configuration.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 040aa0edfe)
2019-10-25 16:11:17 +02:00
Anderson Toshiyuki Sasaki
a47a291303 tests: Do not process config when reinitializing session
Do not process system-wide configuration when reinitializing a session
during testing.  This could lead to different settings set from the
expected one (which was initialized during test setup).

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f97a8b4e3f)
2019-10-25 16:11:17 +02:00
Anderson Toshiyuki Sasaki
f199bd4879 tests: Use temporary file for known_hosts
Previously, the tests were sharing the same file path to create the
known_hosts file, which can create a race condition if the tests run in
parallel.  Such file was deleted between tests.

By using different different files for each test, the risk of race
conditions is eliminated. Moreover, it makes unnecessary to destroy the
file between tests.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d4fe8e1f62)
2019-10-25 16:11:17 +02:00
Anderson Toshiyuki Sasaki
4f7cb6076a pki_crypto: Support Ed25519 keys in PEM files
This adds support for Ed25519 keys from files in PEM format when using
OpenSSL with Ed25519 support.  The default encoding for the PEM file is
expected to be PKCS#8.  Encrypted files are supported.

For the lack of an API, it is not possible to export keys in PEM format,
only in OpenSSH format.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit a3a0529b41)
2019-09-30 16:58:07 +02:00
Anderson Toshiyuki Sasaki
3f6820694e cmake: Do not build internal ed25519 when unnecessary
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 61e6b6cc59)
2019-09-30 16:57:59 +02:00
Anderson Toshiyuki Sasaki
0da6597fe4 curve25519: Use OpenSSL X25519 implementation
If supported, use OpenSSL X25519 implementation for the curve25519 key
exchange.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d463f67aba)
2019-09-30 16:57:48 +02:00
Anderson Toshiyuki Sasaki
0a13045f68 cmake: Detect OpenSSL X25519 support
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0b7f7d2cf7)
2019-09-30 16:57:39 +02:00
Anderson Toshiyuki Sasaki
b56ffd8424 pki: Remove unused function pki_signature_verify()
This removes unused function pki_signature_verify()
from pki_{crypto, mbedcrypto, gcrypt}.  The function was also removed
from include/libssh/pki_priv.h.  The function ssh_pki_signature_verify()
was changed to receive a const unsigned char *input.

All tests calling pki_signature_verify() were changed to call
ssh_pki_signature_verify() instead.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 55cd04fbee)
2019-09-30 16:57:31 +02:00
Anderson Toshiyuki Sasaki
c60ac3fe02 pki_crypto: Use OpenSSL for Ed25519 signatures
Use OpenSSL to generate and verify Ed25519 signatures, if supported.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2a2c1c98bf)
2019-09-30 16:57:23 +02:00
Anderson Toshiyuki Sasaki
84eab65edc pki: Move common Ed25519 functions to pki_ed25519_common.c
This is a preparation to use the Ed25519 implementation from OpenSSL.

The function pki_ed25519_sig_to_blob() was renamed to
pki_ed25519_signature_to_blob() and pki_ed25519_sig_from_blob() was
renamed to pki_signature_from_ed25519_blob() to follow the naming for
other algorithms.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bdcaf55b90)
2019-09-30 16:57:16 +02:00
Anderson Toshiyuki Sasaki
7c3e37bf4c cmake: Detect OpenSSL support for Ed25519
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit a0b84a8cd5)
2019-09-30 16:57:07 +02:00
Anderson Toshiyuki Sasaki
ab9921ee6a pki_mbedcrypto: Do not treat Ed25519 as a special case
Generate and verify Ed25519 signatures along with the other signature
types.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 97adbfe087)
2019-09-30 16:56:59 +02:00
Anderson Toshiyuki Sasaki
9296bcd4bb pki_gcrypt: Do not treat Ed25519 as a special case
Verify the Ed25519 signature in pki_verify_data_signature() along with
the other signature types.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 38ede2e225)
2019-09-30 16:56:50 +02:00
Anderson Toshiyuki Sasaki
24f39761f3 pki_crypto: Use EVP_DigestSign* and EVP_DigestVerify*
Use the newer APIs EVP_DigestSign{Init}() and EVP_DigestVerify{Init}()
to generate and verify signatures instead of the older EVP_Sign{Init,
Update, Final} and EVP_Verify{Init, Update, Final} if supported.

Also use the single shot signature/verification if supported as all the
input is provided at once.

This is a preparation to use Ed25519 implementation from OpenSSL.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 90944a3651)
2019-09-30 16:56:39 +02:00
Anderson Toshiyuki Sasaki
49e8a4ef19 torture_pki_ed25519: Use public key to verify signatures
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7452f0ded8)
2019-09-30 16:56:24 +02:00
Anderson Toshiyuki Sasaki
d7e1141c1e gitlab-ci: Move cmake from prep to build command in csbuild
This is required to avoid csbuild scan failures when a commit removes
source files.  The command prep is run only once before all the builds,
making csbuild to try to compile the old files using the configuration
files generated for the newest version.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7ffa3c358d)
2019-09-30 16:54:43 +02:00
Andreas Schneider
fd5c598477 gitlab-ci: Turn DEBUG_CRYPTO on for standard crypto lib builds
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4799915a36)
2019-09-30 16:54:27 +02:00
Jakub Jelen
de4034bfe0 buffer: Simplify handling of the return codes
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e72429f205)
2019-09-30 16:00:30 +02:00
Jakub Jelen
6ccd84bae9 buffer: Avoid use of uninitialized values
Fixes the following oss-fuzz bug:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17565

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aff7c500d5)
2019-09-30 16:00:19 +02:00
Jakub Jelen
e4c281c7ce dh-gex: Correctly free modulus and generator with openssl
Fixes T176

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit aac682f60e)
2019-09-30 16:00:09 +02:00
Jakub Jelen
93541fe150 channels: Correctly reports failed channels opening
Fixes T75

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 2f05243a4a)
2019-09-30 15:59:53 +02:00
Jakub Jelen
e6ba98a0aa Reformat channel_open()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 89a9eb8811)
2019-09-30 15:59:37 +02:00
Jakub Jelen
6dcb960501 channels: Do not use deprecated functions in the example code
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 3cf2b41f5e)
2019-09-30 15:59:27 +02:00
Jakub Jelen
fcacc7fe8c options: Do not attempt to expand percents in PKCS#11 URIs
With the old token parser, the data was simply broken on the = sign even
if the uri was in quotes and ignored.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 223cc96239)
2019-09-30 15:59:17 +02:00
Jakub Jelen
f078f53911 tests: Verify the localuser match works
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 61b1e0e7e9)
2019-09-30 15:59:07 +02:00
Jakub Jelen
27f5bfd129 config: Support match localuser
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 6500134259)
2019-09-30 15:58:57 +02:00
Jakub Jelen
4a0cbe396d config: Make the matching case sensitive as documented in ssh_config manual pages
> note that keywords are case-insensitive and arguments are case-sensitive

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 9b8b312b88)
2019-09-30 15:58:46 +02:00
Jakub Jelen
a1812e9ac1 Skip the proxycommand test in case the netcat is not avaliable
Fixes: T142

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 4900ab6ca9)
2019-09-30 15:58:36 +02:00
Jakub Jelen
0e3dbd6c69 sftp: Improve the documentation of sftp_init() and sftp_new()
Fixes: T137

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 618b858e49)
2019-09-30 15:53:44 +02:00
Jakub Jelen
d2af62624d known_hosts: Avoid using deprecated functions (even from deprecated functions)
Fixes: T165

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 83fa060cec)
2019-09-30 15:42:26 +02:00
Richard W.M. Jones
93113ccfb9 misc: Allow %% to escape a single % in paths.
For example "%d/config%%1" is expanded to "~/.ssh/config%1".

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3737e5f0e7)
2019-08-08 10:36:50 +02:00
Andreas Schneider
9ffaa12012 dh: Add ssh_dh_debug_crypto()
We should call it where we have access to the crypto structure.

Pair-Programmed-With: Jakub Jelen <jjelen@redhat.com>
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 92d3efec81)
2019-08-08 09:45:38 +02:00
Andreas Schneider
ae5146f7ba bignum: Pass const to ssh_print_bignum()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4e25ee6124)
2019-08-08 09:45:36 +02:00
Andreas Schneider
dd554ebb32 pki_mbedcrypto: Add missing misc.h header file
For ssh_log_hexdump().

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 89ab7b23f8)
2019-08-08 09:45:14 +02:00
Anderson Toshiyuki Sasaki
fae61f1d09 tests: Skip testing 1024 bits key generation in FIPS mode
In torture_threads_pki_rsa, skip the test which generates 1024 bits RSA
key pair when in FIPS mode.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3a61cd34a9)
2019-08-08 09:45:10 +02:00
Anderson Toshiyuki Sasaki
9e8e5f5cb2 knownhosts: Use ssh_mkdirs() instead of ssh_mkdir()
Previously, if the path to known_hosts file set through
SSH_OPTIONS_KNOWNHOSTS included missing directories,
ssh_session_update_known_hosts() would fail.  The added test case checks
that this is not the case anymore.

The logic of checking if the directory is accessible before creating it
was replaced by creating the directory if opening the file failed.  This
is to minimize the risk of TOCTOU race conditions.

Fixes: T166

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5b18bcb0ac)
2019-08-08 09:45:08 +02:00
Anderson Toshiyuki Sasaki
80c1dbdb61 misc: Introduce internal function ssh_mkdirs()
If the given path includes missing directories, ssh_mkdirs() tries to
create them recursively.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 742918cb1c)
2019-08-08 09:45:06 +02:00
Anderson Toshiyuki Sasaki
4505c076b3 misc: Introduce internal function ssh_dir_writeable()
The introduced internal function checks if the provided path is for an
existing directory which is accessible for writing.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7857cd1aa5)
2019-08-08 09:45:04 +02:00
Jakub Jelen
99dc2002b9 libcrypto: Avoid incompatible pointers
Fixes: T164

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e42d44e48a)
2019-08-08 09:44:54 +02:00
Jakub Jelen
878d8320c1 pki_container_openssh: Avoid bogus newline in debug message
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 683096ae7e)
2019-08-08 09:44:47 +02:00
Jakub Jelen
80e729fe33 pki_container_openssh: Reformat whitespace
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3811c73f8f)
2019-08-08 09:44:45 +02:00
Jakub Jelen
47945671af examples: Load ED25519 key when loading all keys
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cc92e74309)
2019-08-08 09:44:43 +02:00
Anderson Toshiyuki Sasaki
b2e7ef6836 Replace ssh_print_hexa() with ssh_log_hexdump()
Replace all occurrences of the deprecated function ssh_print_hexa() with
the introduced ssh_log_hexdump().

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 68baebbd62)
2019-08-08 09:44:18 +02:00
Anderson Toshiyuki Sasaki
651fea9f14 misc: Introduce ssh_log_hexdump()
The introduced internal function is intended to be a replacement for the
deprecated function ssh_print_hexa().

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 33927f3ae8)
2019-08-08 09:44:15 +02:00
Anderson Toshiyuki Sasaki
f10db964b5 tests: Try PEM files with leading white spaces
This adds a reproducer for T123.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c03c9b88d1)
2019-08-08 09:44:09 +02:00
Anderson Toshiyuki Sasaki
703f0a0f36 pki: Search OpenSSH header not only at the beginning
Try to find the OpenSSH private key header not only at the beginning of
the file.  This makes the parser to skip comments and white spaces.

Fixes: T76
Fixes: T123

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 88d777e678)
2019-08-08 09:42:47 +02:00
Andreas Schneider
7b8d57fbb6 tests: Use the correct assert function in test server
CID 1398983

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2019-07-08 18:39:47 +02:00
Andreas Schneider
8e793d930e tests: Fix #ifdef in torture_server_config
This should stop detecting it as dead code.

CID 1402934

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2019-07-08 18:39:44 +02:00
Andreas Schneider
cc2feabe73 examples: Fix freeing the channel in ssh_client
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2019-07-08 18:39:41 +02:00
Andreas Schneider
4d57d73faf examples: Update header in ssh_client
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b275045ac8)
2019-07-08 16:49:51 +02:00
Andreas Schneider
4bd9041afb exmples: Use SSH_CONNECTOR_STDINOUT in client example
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b5a8547d91)
2019-07-08 16:49:48 +02:00
Andreas Schneider
74e084f76c include: Add define for SSH_CONNECTOR_STDINOUT
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1a26c57af2)
2019-07-08 16:49:47 +02:00
Andreas Schneider
6c80718c0d cmake: Fix linking shared and static libraries
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 915c006a30)
2019-07-08 16:48:05 +02:00
Andreas Schneider
a330806e4b dh_crypto: Use size_t for loop variable
Also don't declare the variable in the loop.

Fixes #157

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2884f97bc5)
2019-07-08 16:48:01 +02:00
Stefan Strogin
3b01c328ab libcrypto: fix compilation with LibreSSL
LibreSSL does not support FIPS mode, check for FIPS_mode() in
ConfigureChecks.cmake.

Signed-off-by: Stefan Strogin <steils@gentoo.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0d4658740b)
2019-07-08 16:47:59 +02:00
Andreas Schneider
5b981a9e3d tests: Use C99 initilizer in test_server.c
This fixes a clang build warning.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit fed31c1ca3)
2019-07-04 16:32:46 +02:00
Andreas Schneider
36dc66da81 cmake: Write libssh-config.cmake using EXPORTS
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 68533147e2)
2019-07-04 16:29:32 +02:00
Andreas Schneider
2a3718de51 cmake: Use GNUInstallDirs for installation
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 24af712931)
2019-07-04 16:29:29 +02:00
Anderson Toshiyuki Sasaki
1fd68ec732 kex: Do not ignore keys in known_hosts files
Previously, if the SSH_OPTIONS_HOSTKEYS option was set by any mean,
including the client configuration file, the keys in known_hosts files
wouldn't be considered before advertising the list of wanted host keys.

This could result in the client requesting the server to provide a
signature using a key not present in the known_hosts files (e.g. when
the first wanted algorithm in SSH_OPTIONS_HOSTKEYS is not present in the
known_hosts files), causing a host key mismatch and possible key
rejection.

Now, the keys present in the known_hosts files are prioritized over the
other wanted keys.  This do not change the fact that only keys of types
present in the list set in SSH_OPTIONS_HOSTKEYS will be accepted and
prioritized following the order defined by such list.

The new wanted list of hostkeys is given by:
 - The keys present in known_hosts files, ordered by preference defined
   in SSH_OPTIONS_HOSTKEYS.  If the option is not set, a default order
   of preference is used.
 - The other keys present in the same option are appended without adding
   duplicates.  If the option is not set, the default list of keys is
   used.

Fixes: T156

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f18a7cc17e)
2019-07-04 11:26:37 +02:00
Anderson Toshiyuki Sasaki
fa3caa61fd knownhosts: Introduced ssh_known_hosts_get_algorithms_names()
The added internal function obtain a newly allocated string containing a
list of the signature types that can be generated by the keys present in
the known_hosts files, separated by commas.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 65a38759ca)
2019-07-04 11:26:27 +02:00
Anderson Toshiyuki Sasaki
aaa978ad06 token: Added function to remove duplicates
Added a function to remove duplicates from lists.  This function is used
in a new provided function to append lists removing duplicates.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 548753b338)
2019-07-04 11:26:19 +02:00
Anderson Toshiyuki Sasaki
b9530cedbe knownhosts: Read knownhosts file only if found
Avoid trying to open the files if they are not accessible.  This was
already treated as a non-error, but with this we save one function call.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e5a64a3d6b)
2019-07-04 11:26:10 +02:00
Anderson Toshiyuki Sasaki
7ff0af7543 tests: Check if known_hosts works with single unaccessible file
Make sure known hosts check works when local known_hosts file is
unaccessible, but the host is present in global known_hosts file.

Remove double return value check in previous existing test.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ad68de7271)
2019-07-04 11:26:00 +02:00
Anderson Toshiyuki Sasaki
b040856ccf knownhosts: Fix possible memory leak
The memory allocated for host_port can leak if the global knownhosts
file is unaccessible.

Found by address sanitizer build in CI.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit fe248414fe)
2019-07-04 11:25:35 +02:00
Andreas Schneider
79900e5246 Bump version to 0.9.0
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2019-06-28 08:06:35 +02:00
Anderson Toshiyuki Sasaki
63b0399373 tests: Added a check for unaccessible global known_hosts
Verify that the check process will not fail if the global known_hosts
file is not accessible and the local known_hosts file contain the host.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8e42ed8220)
2019-06-28 08:06:35 +02:00
Anderson Toshiyuki Sasaki
39665fd9c5 knownhosts: Fixed a typo
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5617eaf0e2)
2019-06-28 08:06:35 +02:00
Anderson Toshiyuki Sasaki
83f0be1f04 knownhosts: Do not fail if global known_hosts file is inaccessible
Previously, if the global known_hosts file (default:
/etc/ssh/ssh_known_hosts) was inaccessible, the check for known hosts
failed.  This makes the check to fail if both files are inaccessible.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4adb13d9e3)
2019-06-28 08:06:35 +02:00
Anderson Toshiyuki Sasaki
3bc5f88f77 connect: Code style formatting
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit da50b12051)
2019-06-27 10:37:46 +02:00
Anderson Toshiyuki Sasaki
466ca07626 connect: Removed unused code
The internal function ssh_connect_host() is not used.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a82993b320)
2019-06-27 10:37:44 +02:00
Anderson Toshiyuki Sasaki
b6e757d692 packet: Check return value when sending unimplemented
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6a9185636f)
2019-06-27 10:37:43 +02:00
Anderson Toshiyuki Sasaki
3f2375e948 packet: Reformat ssh_packet_process()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a1ee22eb64)
2019-06-27 10:37:41 +02:00
Anderson Toshiyuki Sasaki
4d06c2f283 auth: Do not print error message for SSH_AGAIN
In non-blocking mode, it is expected SSH_AGAIN to be returned many
times.  Do not flood the log with error messages.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1d54a3880d)
2019-06-27 10:37:40 +02:00
Anderson Toshiyuki Sasaki
0298bfbbf0 examples: Check ssh_event_dopoll() return value
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b1ff11f416)
2019-06-27 10:37:39 +02:00
Anderson Toshiyuki Sasaki
2399a9f8de dh-gex: Check return code ssh_dh_keypair_get_keys()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 25bb6eef96)
2019-06-27 10:37:37 +02:00
Anderson Toshiyuki Sasaki
79756c5c56 gitlab-ci: Re-enable client tests in CentOS7
The tests were disabled because of failures in torture_auth.  The server
tests are not enabled because the pkd tests are failing.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d00ff451db)
2019-06-27 09:56:57 +02:00
Anderson Toshiyuki Sasaki
e8510043d2 pki: Add workarounds for old OpenSSH
When we are talking to old OpenSSH versions which does not support
rsa-sha2-{256,512}-cert-v01@openssh.com or SHA2 in certificates,
fallback to old supported values.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4b7ce75e1f)
2019-06-27 09:56:55 +02:00
Anderson Toshiyuki Sasaki
1f7889f271 tests/pkd: Fix elif without expression
This was introduced during fixes to run pkd tests in FIPS mode.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c8f49becfd)
2019-06-27 09:56:53 +02:00
Anderson Toshiyuki Sasaki
89efd56217 tests: Add a server test case for unknown global request
The test checks if the server handles unknown global requests properly.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f64814b7be)
2019-06-27 09:56:52 +02:00
Anderson Toshiyuki Sasaki
e3fca31c59 tests: Introduce torture_client_global_requests
Added a test case where invalid global requests are sent to the server
which should reject them, but not stop working.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit abf5712160)
2019-06-27 09:56:50 +02:00
Anderson Toshiyuki Sasaki
d71a7976dd messages: Reject tcpip-forward requests as client
When the session is a client session, reject tcpip-forward requests.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1aef599ab1)
2019-06-27 09:56:49 +02:00
Anderson Toshiyuki Sasaki
8fe8d13e29 messages: Consume unknown global requests messages
When an unknown global request is received, consume the message to avoid
sending UNIMPLEMENTED later.  Only report the failure if the request
wants a reply.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3d7d3f303e)
2019-06-27 09:56:47 +02:00
Andreas Schneider
722f979790 Update ChangeLog to add FIPS
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 220f1e1435)
2019-06-24 16:05:05 +02:00
Jakub Jelen
2c60ef04d9 tests: Skip 1k RSA key generation in FIPS
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 17a531d2af)
2019-06-24 15:42:02 +02:00
Jakub Jelen
ec486d13db pki_crypto: Correct error checking after RSA key generation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit a80547bdf9)
2019-06-24 15:42:01 +02:00
Jakub Jelen
ebfe46f6ad tests: Filter out bogus output from openssh in FIPS Mode
The OpenSSH in RHEL 8 in FIPS Mode outputs information about this on start
and it needs to be skipped for the version detection (and build) to pass:

$ ssh -V
FIPS mode initialized
OpenSSH_8.0p1, OpenSSL 1.1.1c FIPS  28 May 2019

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit a4fa514549)
2019-06-24 15:42:00 +02:00
Jakub Jelen
3c0897b975 tests: Add reproducer for T76
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit d5095a55b9)
2019-06-24 15:41:58 +02:00
Jakub Jelen
993e0df81e pki: Search for the PEM headers not only on the start of the key file
Fixes: T76 for gcrypt and mbedtls backends

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit d627cba476)
2019-06-24 15:41:57 +02:00
Jakub Jelen
551188d99b pki: Reformat pki_privatekey_type_from_string()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 23c837f4d0)
2019-06-24 15:41:56 +02:00
Jakub Jelen
cafafe8f5a tests: Reproducer for proxy command with stderr output (T130)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit bd69ac63ca)
2019-06-24 15:41:54 +02:00
Jakub Jelen
c6c7856b51 socket: Do not process stderr of proxy commands (Fixes T130)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 6c49c41c19)
2019-06-24 15:41:53 +02:00
Jakub Jelen
ea71af9c22 socket: Reformat the rest of the file
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit bd65568749)
2019-06-24 15:41:51 +02:00
Andreas Schneider
bb98413fc1 Bump version to 0.8.91
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-06-14 15:35:51 +02:00
Andreas Schneider
2a8cd81e8f Update ChangeLog
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-06-14 15:34:07 +02:00
402 changed files with 22617 additions and 65597 deletions

View File

@@ -1,29 +0,0 @@
---
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: LLVM
IndentWidth: 4
UseTab: Never
AllowShortIfStatementsOnASingleLine: false
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterFunction: true
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeElse: false
BeforeWhile: false
IndentCaseLabels: false
IndentCaseBlocks: false
ColumnLimit: 80
AlignAfterOpenBracket: Align
AllowAllParametersOfDeclarationOnNextLine: false
BinPackArguments: false
BinPackParameters: false
AllowAllArgumentsOnNextLine: false
AllowShortFunctionsOnASingleLine: Empty
BreakAfterReturnType: ExceptShortType
AlwaysBreakAfterReturnType: AllDefinitions
AlignEscapedNewlines: Left
ForEachMacros: ['ssh_callbacks_iterate']
AlignConsecutiveMacros: 'Consecutive'

View File

@@ -1,18 +0,0 @@
root = true
[*]
charset = utf-8
max_line_length = 80
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{c,h}]
indent_style = space
indent_size = 4
tab_width = 4
[{CMakeLists.txt,*.cmake}]
indent_style = space
indent_size = 4
tab_width = 4

3
.gitignore vendored
View File

@@ -1,5 +1,6 @@
*.a
*.o
.*
*.swp
*~$
cscope.*
@@ -9,5 +10,3 @@ compile_commands.json
tags
/build
/obj*
doc/tags.xml
.DS_Store

File diff suppressed because it is too large Load Diff

View File

@@ -1,42 +0,0 @@
#!/bin/bash
INSTALL_DIR1=${1}
INSTALL_DIR2=${2}
abidiff \
--headers-dir1 "${INSTALL_DIR1}/include/libssh/" \
--headers-dir2 "${INSTALL_DIR2}/include/libssh/" \
"${INSTALL_DIR1}/lib64/libssh.so" \
"${INSTALL_DIR2}/lib64/libssh.so" \
--fail-no-debug-info
abiret=$?
ABIDIFF_ERROR=$(((abiret & 0x01) != 0))
ABIDIFF_USAGE_ERROR=$(((abiret & 0x02) != 0))
ABIDIFF_ABI_CHANGE=$(((abiret & 0x04) != 0))
ABIDIFF_ABI_INCOMPATIBLE_CHANGE=$(((abiret & 0x08) != 0))
ABIDIFF_UNKNOWN_BIT_SET=$(((abiret & 0xf0) != 0))
if [ $ABIDIFF_ERROR -ne 0 ]; then
echo "abidiff reported ABIDIFF_ERROR."
exit 1
fi
if [ $ABIDIFF_USAGE_ERROR -ne 0 ]; then
echo "abidiff reported ABIDIFF_USAGE_ERROR."
exit 1
fi
if [ $ABIDIFF_UNKNOWN_BIT_SET -ne 0 ]; then
echo "abidiff reported ABIDIFF_UNKNOWN_BIT_SET."
exit 1
fi
if [ $ABIDIFF_ABI_INCOMPATIBLE_CHANGE -ne 0 ]; then
echo "abidiff result ABIDIFF_ABI_INCOMPATIBLE_CHANGE, this breaks the API!"
exit 1
fi
if [ $ABIDIFF_ABI_CHANGE -ne 0 ]; then
echo "Ignoring abidiff result ABI_CHANGE"
fi
exit 0

View File

@@ -1,12 +0,0 @@
#!/bin/sh
# Based on Github Action
# https://github.com/yshui/git-clang-format-lint
diff=$(git-clang-format --diff --commit "$CI_MERGE_REQUEST_DIFF_BASE_SHA")
[ "$diff" = "no modified files to format" ] && exit 0
[ "$diff" = "clang-format did not modify any files" ] && exit 0
printf "You have introduced coding style breakages, suggested changes:\n\n"
echo "${diff}" | colordiff
exit 1

View File

@@ -1,36 +0,0 @@
#!/bin/bash
if [ $# != 1 ]; then
echo "Usage: $0 UPSTREAM_COMMIT_SHA"
exit 1
fi
failed=0
if [ -z "$CI_COMMIT_SHA" ]; then
echo "CI_COMMIT_SHA is not set"
exit 1
fi
CI_COMMIT_RANGE="$1..$CI_COMMIT_SHA"
red='\033[0;31m'
blue='\033[0;34m'
echo -e "${blue}Checking commit range: $CI_COMMIT_RANGE"
echo
echo
for commit in $(git rev-list "$CI_COMMIT_RANGE"); do
git show -s --format=%B "$commit" | grep "^Signed-off-by: " >/dev/null 2>&1
ret=$?
if [ $ret -eq 1 ]; then
echo -e "${red} >>> Missing Signed-off-by trailer in commit $commit"
failed=$(("$failed" + 1))
fi
done
echo
echo
exit $failed

View File

@@ -1,56 +0,0 @@
#!/bin/bash
# Simplified and de-github-ed version of
# https://github.com/ludeeus/action-shellcheck/blob/master/action.yaml
statuscode=0
declare -a filepaths
shebangregex="^#! */[^ ]*/(env *)?[abk]*sh"
set -f # temporarily disable globbing so that globs in inputs aren't expanded
while IFS= read -r -d '' file; do
filepaths+=("$file")
done < <(find . \
-type f \
'(' \
-name '*.bash' \
-o -name '.bashrc' \
-o -name 'bashrc' \
-o -name '.bash_aliases' \
-o -name '.bash_completion' \
-o -name '.bash_login' \
-o -name '.bash_logout' \
-o -name '.bash_profile' \
-o -name 'bash_profile' \
-o -name '*.ksh' \
-o -name 'suid_profile' \
-o -name '*.zsh' \
-o -name '.zlogin' \
-o -name 'zlogin' \
-o -name '.zlogout' \
-o -name 'zlogout' \
-o -name '.zprofile' \
-o -name 'zprofile' \
-o -name '.zsenv' \
-o -name 'zsenv' \
-o -name '.zshrc' \
-o -name 'zshrc' \
-o -name '*.sh' \
-o -path '*/.profile' \
-o -path '*/profile' \
-o -name '*.shlib' \
')' \
-print0)
while IFS= read -r -d '' file; do
head -n1 "$file" | grep -Eqs "$shebangregex" || continue
filepaths+=("$file")
done < <(find . \
-type f ! -name '*.*' -perm /111 \
-print0)
shellcheck "${filepaths[@]}" || statuscode=$?
set +f # re-enable globbing
exit "$statuscode"

View File

@@ -1,16 +0,0 @@
Add a description of the new feature/bug fix. Reference any relevant bugs.
## Checklist
* [ ] Commits have `Signed-off-by:` with name/author being identical to the commit author
* [ ] Code modified for feature
* [ ] Test suite updated with functionality tests
* [ ] Test suite updated with negative tests
* [ ] Documentation updated
* [ ] The project pipelines timeout is [extended](https://docs.gitlab.com/ee/ci/pipelines/settings.html#set-a-limit-for-how-long-jobs-can-run) at least to 2 hours.
## Reviewer's checklist:
* [ ] Any issues marked for closing are addressed
* [ ] There is a test suite reasonably covering new functionality or modifications
* [ ] Function naming, parameters, return values, types, etc., are consistent and according to [CONTRIBUTING.md](https://gitlab.com/libssh/libssh-mirror/-/blob/master/CONTRIBUTING.md)
* [ ] This feature/change has adequate documentation added
* [ ] No obvious mistakes in the code

View File

@@ -1,10 +0,0 @@
#
# GitLeaks Repo Specific Configuration
#
# This allowlist is used to help Red Hat ignore false positives during its code
# scans.
[allowlist]
paths = [
'''tests/*''',
]

View File

@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.12.0)
cmake_minimum_required(VERSION 3.3.0)
cmake_policy(SET CMP0048 NEW)
# 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()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
@@ -9,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.11.00 LANGUAGES C)
project(libssh VERSION 0.9.8 LANGUAGES C)
# global needed variable
set(APPLICATION_NAME ${PROJECT_NAME})
@@ -21,7 +22,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.10.0")
set(LIBRARY_VERSION "4.8.9")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
@@ -41,8 +42,6 @@ macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source buil
# Copy library files to a lib sub-directory
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(LIBSSSH_PC_REQUIRES_PRIVATE "")
# search for libraries
if (WITH_ZLIB)
find_package(ZLIB REQUIRED)
@@ -50,12 +49,32 @@ endif (WITH_ZLIB)
if (WITH_GCRYPT)
find_package(GCrypt 1.5.0 REQUIRED)
message(WARNING "libgcrypt cryptographic backend is deprecated and will be removed in future releases.")
if (NOT GCRYPT_FOUND)
message(FATAL_ERROR "Could not find GCrypt")
endif (NOT GCRYPT_FOUND)
elseif(WITH_MBEDTLS)
find_package(MbedTLS REQUIRED)
else()
find_package(OpenSSL 1.1.1 REQUIRED)
endif()
if (NOT MBEDTLS_FOUND)
message(FATAL_ERROR "Could not find mbedTLS")
endif (NOT MBEDTLS_FOUND)
else (WITH_GCRYPT)
find_package(OpenSSL)
if (OPENSSL_FOUND)
# On CMake < 3.16, OPENSSL_CRYPTO_LIBRARIES is usually a synonym for OPENSSL_CRYPTO_LIBRARY, but is not defined
# when building on Windows outside of Cygwin. We provide the synonym here, if FindOpenSSL didn't define it already.
if (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
endif (NOT DEFINED OPENSSL_CRYPTO_LIBRARIES)
else (OPENSSL_FOUND)
find_package(GCrypt)
if (NOT GCRYPT_FOUND)
find_package(MbedTLS)
if (NOT MBEDTLS_FOUND)
message(FATAL_ERROR "Could not find OpenSSL, GCrypt or mbedTLS")
endif (NOT MBEDTLS_FOUND)
endif (NOT GCRYPT_FOUND)
endif (OPENSSL_FOUND)
endif(WITH_GCRYPT)
if (UNIT_TESTING)
find_package(CMocka REQUIRED)
@@ -68,7 +87,6 @@ find_package(Threads)
if (WITH_GSSAPI)
find_package(GSSAPI)
list(APPEND LIBSSH_PC_REQUIRES_PRIVATE ${GSSAPI_PC_REQUIRES})
endif (WITH_GSSAPI)
if (WITH_NACL)
@@ -78,6 +96,10 @@ if (WITH_NACL)
endif (NOT NACL_FOUND)
endif (WITH_NACL)
if (BSD OR SOLARIS OR OSX)
find_package(Argp)
endif (BSD OR SOLARIS OR OSX)
# Disable symbol versioning in non UNIX platforms
if (UNIX)
find_package(ABIMap 0.3.1)
@@ -89,18 +111,14 @@ endif (UNIX)
include(ConfigureChecks.cmake)
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
if (NOT HAVE_ARGP_PARSE)
find_package(Argp)
endif (NOT HAVE_ARGP_PARSE)
# check subdirectories
add_subdirectory(doc)
add_subdirectory(include)
add_subdirectory(src)
# pkg-config file
if (UNIX OR MINGW)
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc @ONLY)
if (UNIX)
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
@@ -109,7 +127,7 @@ install(
COMPONENT
pkgconfig
)
endif (UNIX OR MINGW)
endif (UNIX)
# CMake config files
include(CMakePackageConfigHelpers)
@@ -191,36 +209,16 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
endif(UPDATE_ABI)
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
# Coverage
if (WITH_COVERAGE)
ENABLE_LANGUAGE(CXX)
include(CodeCoverage)
setup_target_for_coverage_lcov(
NAME "coverage"
EXECUTABLE make test
DEPENDENCIES ssh tests)
set(GCOVR_ADDITIONAL_ARGS --xml-pretty --exclude-unreachable-branches --print-summary)
setup_target_for_coverage_gcovr_xml(
NAME "coverage_xml"
EXECUTABLE make test
DEPENDENCIES ssh tests)
endif (WITH_COVERAGE)
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET} VERBATIM)
get_directory_property(hasParent PARENT_DIRECTORY)
if(NOT(hasParent))
# Link compile database for clangd if we are the master project
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
"${CMAKE_BINARY_DIR}/compile_commands.json"
"${CMAKE_SOURCE_DIR}/compile_commands.json")
endif()
# Link compile database for clangd
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
"${CMAKE_BINARY_DIR}/compile_commands.json"
"${CMAKE_SOURCE_DIR}/compile_commands.json")
message(STATUS "********************************************")
message(STATUS "********** ${PROJECT_NAME} build options : **********")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Coverage: ${WITH_COVERAGE}")
message(STATUS "zlib support: ${WITH_ZLIB}")
message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
message(STATUS "libmbedTLS support: ${WITH_MBEDTLS}")
@@ -229,15 +227,11 @@ message(STATUS "SFTP support: ${WITH_SFTP}")
message(STATUS "Server support : ${WITH_SERVER}")
message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
message(STATUS "GEX support : ${WITH_GEX}")
message(STATUS "Support insecure none cipher and MAC : ${WITH_INSECURE_NONE}")
message(STATUS "Support exec : ${WITH_EXEC}")
message(STATUS "Pcap debugging support : ${WITH_PCAP}")
message(STATUS "Build shared library: ${BUILD_SHARED_LIBS}")
message(STATUS "Unit testing: ${UNIT_TESTING}")
message(STATUS "Client code testing: ${CLIENT_TESTING}")
message(STATUS "Blowfish cipher support: ${HAVE_BLOWFISH}")
message(STATUS "PKCS #11 URI support: ${WITH_PKCS11_URI}")
message(STATUS "With PKCS #11 provider support: ${WITH_PKCS11_PROVIDER}")
message(STATUS "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
set(_SERVER_TESTING OFF)
if (WITH_SERVER)
set(_SERVER_TESTING ${SERVER_TESTING})
@@ -252,15 +246,9 @@ message(STATUS "Benchmarks: ${WITH_BENCHMARKS}")
message(STATUS "Symbol versioning: ${WITH_SYMBOL_VERSIONING}")
message(STATUS "Allow ABI break: ${WITH_ABI_BREAK}")
message(STATUS "Release is final: ${WITH_FINAL}")
if (WITH_HERMETIC_USR)
message(STATUS "User global client config: ${USR_GLOBAL_CLIENT_CONFIG}")
endif ()
message(STATUS "Global client config: ${GLOBAL_CLIENT_CONFIG}")
if (WITH_SERVER)
if (WITH_HERMETIC_USR)
message(STATUS "User global bind config: ${USR_GLOBAL_BIND_CONFIG}")
endif ()
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
message(STATUS "Global bind config: ${GLOBAL_BIND_CONFIG}")
endif()
message(STATUS "********************************************")

View File

@@ -1,573 +0,0 @@
# How to contribute a patch to libssh
Please checkout the libssh source code using git.
For contributions we prefer Merge Requests on Gitlab:
https://gitlab.com/libssh/libssh-mirror/
This way you get continuous integration which runs the complete libssh
testsuite for you.
For larger code changes, breaking the changes up into a set of simple
patches, each of which does a single thing, are much easier to review.
Patch sets like that will most likely have an easier time being merged
into the libssh code than large single patches that make lots of
changes in one large diff.
Also bugfixes and new features should be covered by tests. We use the cmocka
and cwrap framework for our testing and you can simply run it locally by
calling `make test`.
## Ownership of the contributed code
libssh is a project with distributed copyright ownership, which means
we prefer the copyright on parts of libssh to be held by individuals
rather than corporations if possible. There are historical legal
reasons for this, but one of the best ways to explain it is that it's
much easier to work with individuals who have ownership than corporate
legal departments if we ever need to make reasonable compromises with
people using and working with libssh.
We track the ownership of every part of libssh via https://git.libssh.org,
our source code control system, so we know the provenance of every piece
of code that is committed to libssh.
So if possible, if you're doing libssh changes on behalf of a company
who normally owns all the work you do please get them to assign
personal copyright ownership of your changes to you as an individual,
that makes things very easy for us to work with and avoids bringing
corporate legal departments into the picture.
If you can't do this we can still accept patches from you owned by
your employer under a standard employment contract with corporate
copyright ownership. It just requires a simple set-up process first.
We use a process very similar to the way things are done in the Linux
Kernel community, so it should be very easy to get a sign off from
your corporate legal department. The only changes we've made are to
accommodate the license we use, which is LGPLv2 (or later) whereas the
Linux kernel uses GPLv2.
The process is called signing.
## How to sign your work
Once you have permission to contribute to libssh from your employer, simply
email a copy of the following text from your corporate email address to:
contributing@libssh.org
```
libssh Developer's Certificate of Origin. Version 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the appropriate
version of the GNU General Public License; or
(b) The contribution is based upon previous work that, to the best of
my knowledge, is covered under an appropriate open source license
and I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under
the GNU General Public License, in the appropriate version; or
(c) The contribution was provided directly to me by some other
person who certified (a) or (b) and I have not modified it.
(d) I understand and agree that this project and the contribution are
public and that a record of the contribution (including all
metadata and personal information I submit with it, including my
sign-off) is maintained indefinitely and may be redistributed
consistent with the libssh Team's policies and the requirements of
the GNU GPL where they are relevant.
(e) I am granting this work to this project under the terms of the
GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of
the License, or (at the option of the project) any later version.
https://www.gnu.org/licenses/lgpl-2.1.html
```
We will maintain a copy of that email as a record that you have the
rights to contribute code to libssh under the required licenses whilst
working for the company where the email came from.
Then when sending in a patch via the normal mechanisms described
above, add a line that states:
Signed-off-by: Random J Developer <random@developer.example.org>
using your real name and the email address you sent the original email
you used to send the libssh Developer's Certificate of Origin to us
(sorry, no pseudonyms or anonymous contributions.)
That's it! Such code can then quite happily contain changes that have
copyright messages such as:
(c) Example Corporation.
and can be merged into the libssh codebase in the same way as patches
from any other individual. You don't need to send in a copy of the
libssh Developer's Certificate of Origin for each patch, or inside each
patch. Just the sign-off message is all that is required once we've
received the initial email.
## Continuous Integration
Contributing patches through Merge Request workflow on Gitlab allows us to run
various checks on various configuration as part of Gitlab CI. Unfortunately,
some pipelines are slower (as they involve building dependencies) so the default
timeout of 1 hour needs to be extended at least to 2 hours. This can be done in
project settings of your libssh fork:
https://docs.gitlab.com/ee/ci/pipelines/settings.html#set-a-limit-for-how-long-jobs-can-run
Otherwise you will encounter errors like these, usually on visualstudio builds:
```
ERROR: Job failed: execution took longer than 1h0m0s seconds
The script exceeded the maximum execution time set for the job
```
Note, that the built dependencies are cached so after successful build in your
namespace, the rebuilds should be much faster.
# Coding conventions in the libssh tree
## Quick Start
Coding style guidelines are about reducing the number of unnecessary
reformatting patches and making things easier for developers to work together.
You don't have to like them or even agree with them, but once put in place we
all have to abide by them (or vote to change them). However, coding style
should never outweigh coding itself and so the guidelines described here are
hopefully easy enough to follow as they are very common and supported by tools
and editors.
The basic style for C code, is the Linux kernel coding style (See
Documentation/CodingStyle in the kernel source tree). This closely matches what
libssh developers use already anyways, with a few exceptions as mentioned
below.
But to save you the trouble of reading the Linux kernel style guide, here
are the highlights.
* Maximum Line Width is 80 Characters
The reason is not about people with low-res screens but rather sticking
to 80 columns prevents you from easily nesting more than one level of
if statements or other code blocks.
* Use 4 Spaces to Indent
* No Trailing Whitespace
Clean up your files before committing.
* Follow the K&R guidelines. We won't go through all of them here. Do you
have a copy of "The C Programming Language" anyways right?
## Editor Hints
### Emacs
Add the follow to your $HOME/.emacs file:
(add-hook 'c-mode-hook
(lambda ()
(c-set-style "linux")
(c-toggle-auto-state)))
## Neovim/VIM
For the basic vi editor included with all variants of \*nix, add the
following to ~/.config/nvim/init.rc or ~/.vimrc:
set ts=4 sw=4 et cindent
You can use the Vim gitmodline plugin to store this in the git config:
https://git.cryptomilk.org/projects/vim-gitmodeline.git/
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:
if has("syntax") && (&t_Co > 2 || has("gui_running"))
syntax on
function! ActivateInvisibleCharIndicator()
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
highlight TrailingSpace ctermbg=Red
endf
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
endif
" Show tabs, trailing whitespace, and continued lines visually
set list listchars=tab:»·,trail:·,extends:…
" highlight overly long lines same as TODOs.
set textwidth=80
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
## FAQ & Statement Reference
### Comments
Comments should always use the standard C syntax. C++ style comments are not
currently allowed.
The lines before a comment should be empty. If the comment directly belongs to
the following code, there should be no empty line after the comment, except if
the comment contains a summary of multiple following code blocks.
This is good:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/**
* @brief This is a doxygen comment.
*
* This is a more detailed explanation of
* this simple function.
*
* @param[in] param1 The parameter value of the function.
*
* @param[out] result1 The result value of the function.
*
* @return 0 on success and -1 on error.
*/
int example(int param1, int *result1);
This is bad:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/*This is a one line comment.*/
/* This is a multi line comment,
with some more words...*/
/*
* This is a multi line comment,
* with some more words...*/
### Indentation & Whitespace & 80 columns
To avoid confusion, indentations have to be 4 spaces. Do not use tabs!. When
wrapping parameters for function calls, align the parameter list with the first
parameter on the previous line. For example,
var1 = foo(arg1,
arg2,
arg3);
The previous example is intended to illustrate alignment of function
parameters across lines and not as encourage for gratuitous line
splitting. Never split a line before columns 70 - 79 unless you
have a really good reason. Be smart about formatting.
### If, switch, & Code blocks
Always follow an 'if' keyword with a space but don't include additional
spaces following or preceding the parentheses in the conditional.
This is good:
if (x == 1)
This is bad:
if ( x == 1 )
or
if (x==1)
Yes we have a lot of code that uses the second and third form and we are trying
to clean it up without being overly intrusive.
Note that this is a rule about parentheses following keywords and not
functions. Don't insert a space between the name and left parentheses when
invoking functions.
Braces for code blocks used by for, if, switch, while, do..while, etc. should
begin on the same line as the statement keyword and end on a line of their own.
You should always include braces, even if the block only contains one
statement. **NOTE**: Functions are different and the beginning left brace should
be located in the first column on the next line.
If the beginning statement has to be broken across lines due to length, the
beginning brace should be on a line of its own.
The exception to the ending rule is when the closing brace is followed by
another language keyword such as else or the closing while in a do..while loop.
Good examples:
if (x == 1) {
printf("good\n");
}
for (x = 1; x < 10; x++) {
print("%d\n", x);
}
for (really_really_really_really_long_var_name = 0;
really_really_really_really_long_var_name < 10;
really_really_really_really_long_var_name++)
{
print("%d\n", really_really_really_really_long_var_name);
}
do {
printf("also good\n");
} while (1);
Bad examples:
while (1)
{
print("I'm in a loop!\n"); }
for (x=1;
x<10;
x++)
{
print("no good\n");
}
if (i < 10)
print("I should be in braces.\n");
### Goto
While many people have been academically taught that "goto"s are fundamentally
evil, they can greatly enhance readability and reduce memory leaks when used as
the single exit point from a function. But in no libssh world what so ever is a
goto outside of a function or block of code a good idea.
Good Examples:
int function foo(int y)
{
int *z = NULL;
int rc = 0;
if (y < 10) {
z = malloc(sizeof(int)*y);
if (z == NULL) {
rc = 1;
goto done;
}
}
print("Allocated %d elements.\n", y);
done:
if (z != NULL) {
free(z);
}
return rc;
}
### Initialize pointers
All pointer variables **MUST** be initialized to `NULL`. History has
demonstrated that uninitialized pointer variables have lead to various
bugs and security issues.
Pointers **MUST** be initialized even if the assignment directly follows
the declaration, like pointer2 in the example below, because the
instructions sequence may change over time.
Good Example:
char *pointer1 = NULL;
char *pointer2 = NULL;
pointer2 = some_func2();
...
pointer1 = some_func1();
### Typedefs
libssh tries to avoid `typedef struct { .. } x_t;` so we do always try to use
`struct x { .. };`. We know there are still such typedefs in the code, but for
new code, please don't do that anymore.
### Make use of helper variables
Please try to avoid passing function calls as function parameters in new code.
This makes the code much easier to read and it's also easier to use the "step"
command within gdb.
Good Example:
char *name;
name = get_some_name();
if (name == NULL) {
...
}
rc = some_function_my_name(name);
...
Bad Example:
rc = some_function_my_name(get_some_name());
...
Please try to avoid passing function return values to if- or while-conditions.
The reason for this is better handling of code under a debugger.
Good example:
x = malloc(sizeof(short) * 10);
if (x == NULL) {
fprintf(stderr, "Unable to alloc memory!\n");
}
Bad example:
if ((x = malloc(sizeof(short)*10)) == NULL ) {
fprintf(stderr, "Unable to alloc memory!\n");
}
There are exceptions to this rule. One example is walking a data structure in
an iterator style:
while ((opt = poptGetNextOpt(pc)) != -1) {
... do something with opt ...
}
But in general, please try to avoid this pattern.
### Control-Flow changing macros
Macros like `STATUS_NOT_OK_RETURN` that change control flow (return/goto/etc)
from within the macro are considered bad, because they look like function calls
that never change control flow. Please do not introduce them.
### Switch/case indentation
The `case` should not be indented to avoid wasting too much horizontal space.
When the case block contains local variables that need to be wrapped in braces,
they should not be indented again either.
Good example:
switch (x) {
case 0:
do_stuff();
break;
case 1: {
int y;
do_stuff();
break;
}
default:
do_other_stuff();
break;
}
Bad example:
switch (x) {
case 0:
do_stuff();
break;
case 1:
{
int y;
do_stuff();
break;
}
default:
do_other_stuff();
break;
}
## ABI Versioning and Symbol Management
To maintain [ABI](https://en.wikipedia.org/wiki/Application_binary_interface) stability
and ensure backward compatibility, libssh uses **symbol versioning** to track and manage
exported functions and variables. This allows libssh to introduce new symbols or modify
existing functions in an ABI-compatible way.
When introducing a new symbol:
1. Use the `LIBSSH_API` macro to mark the symbol as part of the public API.
2. If you have [abimap](https://github.com/ansasaki/abimap) installed, the new symbols are
automatically generated in the `src/libssh_dev.map` file in the **build** directory and used automatically for building the updated library. But, depending on the version of `abimap` under use, you may face linker errors like: `unable to find version dependency LIBSSH_4_9_0`. In this case, you need to manually replace the existing `src/libssh.map` file with the generated `libssh_dev.map` file to update the symbol versioning.
3. If you do not have abimap installed, the modified/added symbols must manually be added to the
`src/libssh.map` file. The symbols must be added in the following format (assuming that 4_10_0 is the latest released version):
```
LIBSSH_AFTER_4_10_0
{
global:
new_function;
new_variable;
} LIBSSH_4_10_0;
```
4. After following either of the above steps, the library can be successfully built and
tested without any linker errors.
5. When submitting the patch, make sure that any new symbols have been added to `libssh.map` as described in step 3, so that the new additions may not be excluded from the next release due to human error.
Also, to maintain ABI compatibility, existing symbols must not be removed. Instead, they can
be marked as deprecated using the `LIBSSH_DEPRECATED` macro. This allows the symbol to be
removed in a future release without breaking the ABI.
Have fun and happy libssh hacking!
The libssh Team

View File

@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
# SOURCE GENERATOR
set(CPACK_SOURCE_GENERATOR "TXZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]bare/;/[.]git/;/[.]git;/[.]clangd/;/[.]cache/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git;/[.]clangd/;/[.]cache/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
### NSIS INSTALLER

View File

@@ -1,151 +1,17 @@
CHANGELOG
=========
version 0.11.0 (released 2024-07-31)
* Deprecations and Removals:
* Dropped support for DSA
* Deprecated Blowfish cipher (will be removed in next release)
* Deprecated SSH_BIND_OPTIONS_{RSA,ECDSA}KEY in favor of generic HOSTKEY
* Removed the usage of deprecated OpenSSL APIs (Note: Minimum supported
OpenSSL version is 1.1.1)
* Disabled preauth compression (zlib) by default
* Support for pkcs#11 engines are deprecated, pkcs11-provider is used instead
* Deprecation of old async SFTP API
* libgcrypt cryptographic backend is deprecated
* Deprecation of knownhosts hashing
* SFTP Improvements:
* Added support for async SFTP IO
* Added support for sftp_limits() and applied capping to SFTP read/write
operations accordingly
* Added sftp_home_directory() API support for sftp extension "home-directory"
* Added sftp_lsetstat() API for lsetstat extensions
* Added sftp_expand_path() to canonicalize path using expand-path@openssh.com
extension
* Implemented stat and realpath in sftpserver
* Added sftp_readlink() API to support hardlink@openssh.com
* New extensible callback based SFTP server
* Introduced the posix-rename@openssh.com extension
* New functions and features:
* Added support for PKCS #11 provider for OpenSSL 3.0
* Added testing for GSSAPI Authentication
* Implemented proxy jump using libssh
* Recategorized loglevels to show fatal errors and alignment with OpenSSH
log levels
* Added ssh_channel_request_pty_size_modes() API to set terminal modes for
PTYs
* Added function to check username syntax
* Added support to check all keys in authorized_keys instead of one in
example server implementation
* Handled hostkey similar to OpenSSH
* Added ssh_session_socket_close() API in order to not close socket passed
through options on error conditions
* Added option SSH_BIND_OPTIONS_IMPORT_KEY_STR to read user-supplied key
string in ssh_bind_options_set()
* Improved log handling around ssh_set_callbacks
* Added ssh_set_error_invalid in ssh_options_set()
* Prevented signature blob to start with 1 bit in libgcrypt
* Added support to unbreak key comparison of Ed25519 keys imported from PEM
or OpenSSH container
* Added support to calculate missing CRT parameters when building RSA key
* Added ssh_pki_export_privkey_base64_format() and
ssh_pki_export_privkey_file_format() to support exporting keys in different
formats (PEM, OpenSSH)
* Added support to compare certificates and handle automatic certificate
authentication
* Added support to make compile-commands generation conditional
* Built fuzzers for normal testing
* Avoided passing other events to callbacks when called recursively
* Added control master and path options
* Refactored channel_rcv_data, check for errors and report more useful errors
* Added support to connect to other host addresses than just the first one
* Terminated the server properly when the MaxAuthTries is reached
* Added support for no-more-sessions@openssh.com request in both client and
server
* Added callback to support forwarded-tcpip requests
* Bumped minimal CMake version to 3.12
* Added support for MBedTLS 3.6.x
* Added support for +,-,^ modifiers in front of algorithm lists in options
* Added callbacks for channel open response, and channel request response
* Replaced chroot() from chroot_wrapper internal library with chroot()
from priv_wrapper package
* Added a placeholder for non-expanded identities
* Improved handling of channel transfer window sizes
version 0.10.6 (released 2023-12-18)
ChangeLog
==========
version 0.9.8 (released 2023-12-18)
* Fix CVE-2023-6004: Command injection using proxycommand
* Fix CVE-2023-48795: Potential downgrade attack using strict kex
* Fix CVE-2023-6918: Missing checks for return values of MD functions
* Fix ssh_send_issue_banner() for CMD(PowerShell)
* Avoid passing other events to callbacks when poll is called recursively (#202)
* Allow @ in usernames when parsing from URI composes
version 0.10.5 (released 2023-05-04)
* Fix CVE-2023-1667: a NULL dereference during rekeying with algorithm guessing
* Fix CVE-2023-2283: a possible authorization bypass in
pki_verify_data_signature under low-memory conditions.
* Fix several memory leaks in GSSAPI handling code
* Escape braces in ProxyCommand created from ProxyJump options for zsh
compatibility.
* Fix pkg-config path relocation for MinGW
* Improve doxygen documentation
* Fix build with cygwin due to the glob support
* Do not enqueue outgoing packets after sending SSH2_MSG_NEWKEYS
* Add support for SSH_SUPPRESS_DEPRECATED
* Avoid functions declarations without prototype to build with clang 15
* Fix spelling issues
* Avoid expanding KnownHosts, ProxyCommands and IdentityFiles repetitively
* Add support sk-* keys through configuration
* Improve checking for Argp library
* Log information about received extensions
* Correctly handle rekey with delayed compression
* Move the EC keys handling to OpenSSL 3.0 API
* Record peer disconnect message
* Avoid deadlock when write buffering occurs and we call poll recursively to
flush the output buffer
* Disable preauthentication compression by default
* Add CentOS 8 Stream / OpenSSL 1.1.1 to CI
* Add accidentally removed default compile flags
* Solve incorrect parsing of ProxyCommand option
version 0.10.4 (released 2022-09-07)
* Fixed issues with KDF on big endian
version 0.10.3 (released 2022-09-05)
* Fixed possible infinite loop in known hosts checking
version 0.10.2 (released 2022-09-02)
* Fixed tilde expansion when handling include directives
* Fixed building the shared torture library
* Made rekey test more robust (fixes running on i586 build systems e.g koji)
version 0.10.1 (released 2022-08-30)
* Fixed proxycommand support
* Fixed musl libc support
version 0.10.0 (released 2022-08-26)
* Added support for OpenSSL 3.0
* Added support for mbedTLS 3
* Added support for Smart Cards (through openssl pkcs11 engine)
* Added support for chacha20-poly1305@openssh.com with libgcrypt
* Added support ed25519 keys in PEM files
* Added support for sk-ecdsa and sk-ed25519 (server side)
* Added support for limiting RSA key sizes and not accepting small one by
default
* Added support for ssh-agent on Windows
* Added ssh_userauth_publickey_auto_get_current_identity() API
* Added ssh_vlog() API
* Added ssh_send_issue_banner() API
* Added ssh_session_set_disconnect_message() API
* Added new configuration options:
+ IdentityAgent
+ ModuliFile
* Provided X11 client example
* Disabled DSA support at build time by default (will be removed in the next
release)
* Deprecated the SCP API!
* Deprecated old pubkey, privatekey API
* Avoided some needless large stack buffers to minimize memory footprint
* Removed support for OpenSSL < 1.0.1
version 0.9.7 (released 2023-05-04)
* Fix CVE-2023-1667: a NULL dereference during rekeying with algorithm guessing
* Fix CVE-2023-2283: a possible authorization bypass in
pki_verify_data_signature under low-memory conditions.
* Fix several memory leaks in GSSAPI handling code
* Build and test related backports
version 0.9.6 (released 2021-08-26)
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with
@@ -178,7 +44,7 @@ version 0.9.4 (released 2020-04-09)
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
AES-CTR keys with OpenSSL
* Added diffie-hellman-group14-sha256
* Fixed several possible memory leaks
* Fixed serveral possible memory leaks
version 0.9.3 (released 2019-12-10)
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
@@ -214,7 +80,7 @@ version 0.9.1 (released 2019-10-25)
* Fixed deprecation issues (T165)
* Fixed known_hosts directory creation (T166)
version 0.9.0 (released 2019-02-xx)
version 0.9.0 (released 2019-06-28)
* Added support for AES-GCM
* Added improved rekeying support
* Added performance improvements
@@ -229,6 +95,71 @@ version 0.9.0 (released 2019-02-xx)
* Improved documentation
* Improved OpenSSL API usage for KEX, DH, and signatures
version 0.8.7 (released 2019-02-25)
* Fixed handling extension flags in the server implementation
* Fixed exporting ed25519 private keys
* Fixed corner cases for rsa-sha2 signatures
* Fixed some issues with connector
version 0.8.6 (released 2018-12-24)
* Fixed compilation issues with different OpenSSL versions
* Fixed StrictHostKeyChecking in new knownhosts API
* Fixed ssh_send_keepalive() with packet filter
* Fixed possible crash with knownhosts options
* Fixed issus with rekeying
* Fixed strong ECDSA keys
* Fixed some issues with rsa-sha2 extentions
* Fixed access violation in ssh_init() (static linking)
* Fixed ssh_channel_close() handling
version 0.8.5 (released 2018-10-29)
* Added support to get known_hosts locations with ssh_options_get()
* Fixed preferred algorithm for known hosts negotiations
* Fixed KEX with some server implementations (e.g. Cisco)
* Fixed issues with MSVC
* Fixed keyboard-interactive auth in server mode
(regression from CVE-2018-10933)
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
* Fixed socket fd handling with proxy command
* Fixed a memory leak with OpenSSL
version 0.8.4 (released 2018-10-16)
* Fixed CVE-2018-10933
* Fixed building without globbing support
* Fixed possible memory leaks
* Avoid SIGPIPE on sockets
version 0.8.3 (released 2018-09-21)
* Added support for rsa-sha2
* Added support to parse private keys in openssh container format
(other than ed25519)
* Added support for diffie-hellman-group18-sha512 and
diffie-hellman-group16-sha512
* Added ssh_get_fingerprint_hash()
* Added ssh_pki_export_privkey_base64()
* Added support for Match keyword in config file
* Improved performance and reduced memory footprint for sftp
* Fixed ecdsa publickey auth
* Fixed reading a closed channel
* Added support to announce posix-rename@openssh.com and
hardlink@openssh.com in the sftp server
version 0.8.2 (released 2018-08-30)
* Added sha256 fingerprints for pubkeys
* Improved compiler flag detection
* Fixed race condition in reading sftp messages
* Fixed doxygen generation and added modern style
* Fixed library initialization on Windows
* Fixed __bounded__ attribute detection
* Fixed a bug in the options parser
* Fixed documentation for new knwon_hosts API
version 0.8.1 (released 2018-08-13)
* Fixed version number in the header
* Fixed version number in pkg-config and cmake config
* Fixed library initialization
* Fixed attribute detection
version 0.8.0 (released 2018-08-10)
* Removed support for deprecated SSHv1 protocol
* Added new connector API for clients
@@ -329,7 +260,7 @@ version 0.6.1 (released 2014-02-08)
* Fixed DSA signature extraction.
* Fixed some memory leaks.
* Fixed read of non-connected socket.
* Fixed thread detection.
* Fixed thread dectection.
version 0.6.0 (released 2014-01-08)
* Added new publicy key API.
@@ -354,7 +285,7 @@ version 0.6.0 (released 2014-01-08)
version 0.5.5 (released 2013-07-26)
* BUG 103: Fix ProxyCommand parsing.
* Fix setting -D_FORTIFY_SOURCE=2.
* Fix pollset error return if empty.
* Fix pollset error return if emtpy.
* Fix NULL pointer checks in channel functions.
* Several bugfixes.
@@ -370,7 +301,7 @@ version 0.5.3 (released 2012-11-20)
* BUG #84 - Fix bug in sftp_mkdir not returning on error.
* BUG #85 - Fixed a possible channel infinite loop if the connection dropped.
* BUG #88 - Added missing channel request_state and set it to accepted.
* BUG #89 - Reset error state to no error on successful SSHv1 authentication.
* BUG #89 - Reset error state to no error on successful SSHv1 authentiction.
* Fixed a possible use after free in ssh_free().
* Fixed multiple possible NULL pointer dereferences.
* Fixed multiple memory leaks in error paths.
@@ -431,7 +362,7 @@ version 0.4.7 (released 2010-12-28)
* Fixed a possible memory leak in ssh_get_user_home().
* Fixed a memory leak in sftp_xstat.
* Fixed uninitialized fd->revents member.
* Fixed timeout value in ssh_channel_accept().
* Fixed timout value in ssh_channel_accept().
* Fixed length checks in ssh_analyze_banner().
* Fixed a possible data overread and crash bug.
* Fixed setting max_fd which breaks ssh_select().
@@ -454,7 +385,7 @@ version 0.4.5 (released 2010-07-13)
* Added option to bind a client to an ip address.
* Fixed the ssh socket polling function.
* Fixed Windows related bugs in bsd_poll().
* Fixed several build warnings.
* Fixed serveral build warnings.
version 0.4.4 (released 2010-06-01)
* Fixed a bug in the expand function for escape sequences.
@@ -473,17 +404,17 @@ version 0.4.3 (released 2010-05-18)
* Fixed sftp_chown.
* Fixed sftp_rename on protocol version 3.
* Fixed a blocking bug in channel_poll.
* Fixed config parsing which has overwritten user specified values.
* Fixed config parsing wich has overwritten user specified values.
* Fixed hashed [host]:port format in knownhosts
* Fixed Windows build.
* Fixed doublefree happening after a negotiation error.
* Fixed doublefree happening after a negociation error.
* Fixed aes*-ctr with <= OpenSSL 0.9.7b.
* Fixed some documentation.
* Fixed exec example which has broken read usage.
* Fixed broken algorithm choice for server.
* Fixed a typo that we don't export all symbols.
* Removed the unneeded dependency to doxygen.
* Build examples only on the Linux platform.
* Build examples only on the Linux plattform.
version 0.4.2 (released 2010-03-15)
* Added owner and group information in sftp attributes.
@@ -505,7 +436,7 @@ version 0.4.1 (released 2010-02-13)
* Added an example for exec.
* Added private key type detection feature in privatekey_from_file().
* Fixed zlib compression fallback.
* Fixed kex bug that client preference should be priority
* Fixed kex bug that client preference should be prioritary
* Fixed known_hosts file set by the user.
* Fixed a memleak in channel_accept().
* Fixed underflow when leave_function() are unbalanced
@@ -563,6 +494,14 @@ version 0.3.2 (released 2009-08-05)
* Fixed compilation on Solaris.
* Fixed SSHv1 compilation.
version 0.3.1 (released 2009-07-14)
* Added return code SSH_SERVER_FILE_NOT_FOUND.
* Fixed compilation of SSHv1.
* Fixed several memory leaks.
* Fixed possible infinite loops.
* Fixed a possible crash bug.
* Fixed build warnings.
* Fixed cmake on BSD.
version 0.3.1 (released 2009-07-14)
* Added return code SSH_SERVER_FILE_NOT_FOUND.
* Fixed compilation of SSHv1.
@@ -612,7 +551,7 @@ version 0.2 (released 2007-11-29)
version 0.11-dev
* Server implementation development.
* Small bug corrected when connecting to sun ssh servers.
* Channel weirdness corrected (writing huge data packets)
* Channel wierdness corrected (writing huge data packets)
* Channel_read_nonblocking added
* Channel bug where stderr wasn't correctly read fixed.
* Added sftp_file_set_nonblocking(), which is nonblocking SFTP IO
@@ -643,7 +582,7 @@ version 0.11-dev
* Keyboard-interactive authentication working.
version 0.1 (released 2004-03-05)
* Beginning of sftp subsystem implementation.
* Begining of sftp subsystem implementation.
* Some cleanup into channels implementation
* Now every channel functions is called by its CHANNEL handler.
* Added channel_poll() and channel_read().
@@ -664,7 +603,7 @@ version 0.0.4 (released 2003-10-10)
* Added a wrapper.c file. The goal is to provide a similar API to every
cryptographic functions. bignums and sha/md5 are wrapped now.
* More work than it first looks.
* Support for other crypto libs planned (lighter libs)
* Support for other crypto libs planed (lighter libs)
* Fixed stupid select() bug.
* Libssh now compiles and links with openssl 0.9.6
* RSA pubkey authentication code now works !

View File

@@ -16,6 +16,7 @@ if (UNIX)
endif()
endif()
add_c_compiler_flag("-std=gnu99" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wpedantic" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wall" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wshadow" SUPPORTED_COMPILER_FLAGS)
@@ -42,13 +43,6 @@ if (UNIX)
add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wmissing-field-initializers" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wsign-compare" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wold-style-definition" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=old-style-definition" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wimplicit-int" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=implicit-int" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Wint-conversion" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=int-conversion" SUPPORTED_COMPILER_FLAGS)
add_c_compiler_flag("-Werror=unused-variable" SUPPORTED_COMPILER_FLAGS)
check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
if (REQUIRED_FLAGS_WFORMAT)
@@ -76,7 +70,7 @@ if (UNIX)
check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG)
if (WITH_STACK_PROTECTOR_STRONG)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong")
# This is needed as Solaris has a separate libssp
# This is needed as Solaris has a seperate libssp
if (SOLARIS)
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong")
endif()
@@ -84,21 +78,16 @@ if (UNIX)
check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
if (WITH_STACK_PROTECTOR)
list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector")
# This is needed as Solaris has a separate libssp
# This is needed as Solaris has a seperate libssp
if (SOLARIS)
list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector")
endif()
endif()
endif (WITH_STACK_PROTECTOR_STRONG)
if (NOT WINDOWS AND NOT CYGWIN)
# apple m* chips do not support this option
if (NOT ${CMAKE_SYSTEM_PROCESSOR} STREQUAL arm64)
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()
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()
if (PICKY_DEVELOPER)

View File

@@ -44,8 +44,6 @@ int main(void){ return 0; }
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
# HEADER FILES
check_function_exists(argp_parse HAVE_ARGP_PARSE)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${ARGP_INCLUDE_DIR})
check_include_file(argp.h HAVE_ARGP_H)
unset(CMAKE_REQUIRED_INCLUDES)
@@ -64,7 +62,6 @@ check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(byteswap.h HAVE_BYTESWAP_H)
check_include_file(glob.h HAVE_GLOB_H)
check_include_file(valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H)
check_include_file(ifaddrs.h HAVE_IFADDRS_H)
if (WIN32)
check_include_file(io.h HAVE_IO_H)
@@ -78,31 +75,89 @@ endif (WIN32)
if (OPENSSL_FOUND)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES OpenSSL::Crypto)
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
if (NOT HAVE_OPENSSL_DES_H)
message(FATAL_ERROR "Could not detect openssl/des.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
if (NOT HAVE_OPENSSL_AES_H)
message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()
if (WITH_BLOWFISH_CIPHER)
check_include_file(openssl/blowfish.h HAVE_BLOWFISH)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_aes_128_ctr HAVE_OPENSSL_EVP_AES_CTR)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_aes_128_gcm HAVE_OPENSSL_EVP_AES_GCM)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(CRYPTO_ctr128_encrypt HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
check_function_exists(EVP_KDF_CTX_new HAVE_OPENSSL_EVP_KDF_CTX_NEW)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
check_function_exists(EVP_chacha20 HAVE_OPENSSL_EVP_CHACHA20)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_DigestSign HAVE_OPENSSL_EVP_DIGESTSIGN)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_DigestVerify HAVE_OPENSSL_EVP_DIGESTVERIFY)
check_function_exists(OPENSSL_ia32cap_loc HAVE_OPENSSL_IA32CAP_LOC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_symbol_exists(EVP_PKEY_ED25519 "openssl/evp.h" FOUND_OPENSSL_ED25519)
if (HAVE_OPENSSL_EVP_DIGESTSIGN AND HAVE_OPENSSL_EVP_DIGESTVERIFY AND
FOUND_OPENSSL_ED25519)
set(HAVE_OPENSSL_ED25519 1)
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_symbol_exists(EVP_PKEY_X25519 "openssl/evp.h" HAVE_OPENSSL_X25519)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)
@@ -120,13 +175,12 @@ if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS)
if (HAVE_OPENSSL_ECC)
set(HAVE_ECC 1)
endif (HAVE_OPENSSL_ECC)
if (HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID OR HAVE_OPENSSL_EVP_KDF_CTX_NEW)
set(HAVE_OPENSSL_EVP_KDF_CTX 1)
endif (HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID OR HAVE_OPENSSL_EVP_KDF_CTX_NEW)
endif ()
if (NOT WITH_MBEDTLS)
set(HAVE_DSA 1)
endif (NOT WITH_MBEDTLS)
# FUNCTIONS
check_function_exists(isblank HAVE_ISBLANK)
@@ -224,32 +278,11 @@ if (GCRYPT_FOUND)
set(HAVE_GCRYPT_ECC 1)
set(HAVE_ECC 1)
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
if (NOT GCRYPT_VERSION VERSION_LESS "1.7.0")
set(HAVE_GCRYPT_CHACHA_POLY 1)
set(HAVE_GCRYPT_CURVE25519 1)
endif (NOT GCRYPT_VERSION VERSION_LESS "1.7.0")
endif (GCRYPT_FOUND)
if (MBEDTLS_FOUND)
set(HAVE_LIBMBEDCRYPTO 1)
set(HAVE_ECC 1)
set(CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIR}/mbedtls")
check_include_file(chacha20.h HAVE_MBEDTLS_CHACHA20_H)
check_include_file(poly1305.h HAVE_MBEDTLS_POLY1305_H)
if (MBEDTLS_VERSION VERSION_LESS "3.0.0")
check_symbol_exists(MBEDTLS_ECP_DP_CURVE25519_ENABLED "config.h" HAVE_MBEDTLS_CURVE25519)
else()
check_symbol_exists(MBEDTLS_ECP_DP_CURVE25519_ENABLED "mbedtls_config.h" HAVE_MBEDTLS_CURVE25519)
endif()
if (WITH_BLOWFISH_CIPHER)
check_include_file(blowfish.h HAVE_BLOWFISH)
endif()
unset(CMAKE_REQUIRED_INCLUDES)
endif (MBEDTLS_FOUND)
if (CMAKE_USE_PTHREADS_INIT)
@@ -283,7 +316,7 @@ int main(void) {
# For detecting attributes we need to treat warnings as
# errors
if (UNIX OR MINGW)
# Get warnings for attributes
# Get warnings for attributs
check_c_compiler_flag("-Wattributes" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
string(APPEND CMAKE_REQUIRED_FLAGS "-Wattributes ")
@@ -338,23 +371,6 @@ int main(void) {
return 0;
}" HAVE_FALLTHROUGH_ATTRIBUTE)
check_c_source_compiles("
#define WEAK __attribute__((weak))
WEAK int sum(int a, int b)
{
return a + b;
}
int main(void)
{
int i = sum(2, 2);
(void)i;
return 0;
}" HAVE_WEAK_ATTRIBUTE)
if (NOT WIN32)
check_c_source_compiles("
#define __unused __attribute__((unused))
@@ -448,28 +464,6 @@ if (WITH_GSSAPI AND NOT GSSAPI_FOUND)
set(WITH_GSSAPI 0)
endif (WITH_GSSAPI AND NOT GSSAPI_FOUND)
if (WITH_PKCS11_URI)
if (WITH_GCRYPT)
message(FATAL_ERROR "PKCS #11 is not supported for gcrypt.")
set(WITH_PKCS11_URI 0)
elseif (WITH_MBEDTLS)
message(FATAL_ERROR "PKCS #11 is not supported for mbedcrypto")
set(WITH_PKCS11_URI 0)
elseif (OPENSSL_FOUND AND OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0")
find_library(PKCS11_PROVIDER
NAMES
pkcs11.so
PATH_SUFFIXES
ossl-modules
)
if (NOT PKCS11_PROVIDER)
set(WITH_PKCS11_PROVIDER 0)
message(WARNING "Could not find pkcs11 provider! Falling back to engines")
message(WARNING "The support for engines is deprecated in OpenSSL and will be removed from libssh in the future releases.")
endif (NOT PKCS11_PROVIDER)
endif ()
endif()
# ENDIAN
if (NOT WIN32)
test_big_endian(WORDS_BIGENDIAN)

View File

@@ -2,32 +2,26 @@ option(WITH_GSSAPI "Build with GSSAPI support" ON)
option(WITH_ZLIB "Build with ZLIB support" ON)
option(WITH_SFTP "Build with SFTP support" ON)
option(WITH_SERVER "Build with SSH server support" ON)
option(WITH_DEBUG_CRYPTO "Build with crypto debug output" OFF)
option(WITH_DEBUG_CRYPTO "Build with cryto debug output" OFF)
option(WITH_DEBUG_PACKET "Build with packet debug output" OFF)
option(WITH_DEBUG_CALLTRACE "Build with calltrace debug output" ON)
option(WITH_GCRYPT "Compile against libgcrypt (deprecated)" OFF)
option(WITH_GCRYPT "Compile against libgcrypt" OFF)
option(WITH_MBEDTLS "Compile against libmbedtls" OFF)
option(WITH_BLOWFISH_CIPHER "Compile with blowfish support" OFF)
option(WITH_PCAP "Compile with Pcap generation support" ON)
option(WITH_INTERNAL_DOC "Compile doxygen internal documentation" OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(WITH_PKCS11_URI "Build with PKCS#11 URI support" OFF)
option(WITH_PKCS11_PROVIDER "Use the PKCS#11 provider for accessing pkcs11 objects" OFF)
option(UNIT_TESTING "Build with unit tests" OFF)
option(CLIENT_TESTING "Build with client tests; requires openssh" OFF)
option(SERVER_TESTING "Build with server tests; requires openssh and dropbear" OFF)
option(GSSAPI_TESTING "Build with GSSAPI tests; requires krb5-server,krb5-libs and krb5-workstation" OFF)
option(WITH_BENCHMARKS "Build benchmarks tools; enables unit testing and client tests" OFF)
option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
option(WITH_EXAMPLES "Build examples" ON)
option(WITH_NACL "Build with libnacl (curve25519)" ON)
option(WITH_SYMBOL_VERSIONING "Build with symbol versioning" ON)
option(WITH_ABI_BREAK "Allow ABI break" OFF)
option(WITH_GEX "Enable DH Group exchange mechanisms" ON)
option(WITH_INSECURE_NONE "Enable insecure none cipher and MAC algorithms (not suitable for production!)" OFF)
option(WITH_EXEC "Enable libssh to execute arbitrary commands from configuration files or options (match exec, proxy commands and OpenSSH-based proxy-jumps)." ON)
option(FUZZ_TESTING "Build with fuzzer for the server and client (automatically enables none cipher!)" OFF)
option(FUZZ_TESTING "Build with fuzzer for the server" OFF)
option(PICKY_DEVELOPER "Build with picky developer flags" OFF)
option(WITH_HERMETIC_USR "Build with support for hermetic /usr/" OFF)
if (WITH_ZLIB)
set(WITH_LIBZ ON)
@@ -40,7 +34,7 @@ if (WITH_BENCHMARKS)
set(CLIENT_TESTING ON)
endif()
if (UNIT_TESTING OR CLIENT_TESTING OR SERVER_TESTING OR GSSAPI_TESTING)
if (UNIT_TESTING OR CLIENT_TESTING OR SERVER_TESTING)
set(BUILD_STATIC_LIB ON)
endif()
@@ -59,16 +53,3 @@ endif (NOT GLOBAL_BIND_CONFIG)
if (NOT GLOBAL_CLIENT_CONFIG)
set(GLOBAL_CLIENT_CONFIG "/etc/ssh/ssh_config")
endif (NOT GLOBAL_CLIENT_CONFIG)
if (WITH_HERMETIC_USR)
set(USR_GLOBAL_BIND_CONFIG "/usr${GLOBAL_BIND_CONFIG}")
set(USR_GLOBAL_CLIENT_CONFIG "/usr${GLOBAL_CLIENT_CONFIG}")
endif (WITH_HERMETIC_USR)
if (FUZZ_TESTING)
set(WITH_INSECURE_NONE ON)
endif (FUZZ_TESTING)
if (WIN32)
set(WITH_EXEC 0)
endif(WIN32)

19
INSTALL
View File

@@ -7,13 +7,11 @@
In order to build libssh, you need to install several components:
- A C compiler
- [CMake](https://www.cmake.org) >= 3.12.0
- [CMake](https://www.cmake.org) >= 2.6.0.
- [openssl](https://www.openssl.org) >= 0.9.8
or
- [gcrypt](https://www.gnu.org/directory/Security/libgcrypt.html) >= 1.4
- [libz](https://www.zlib.net) >= 1.2
- [openssl](https://www.openssl.org) >= 1.1.1
or
- [gcrypt](https://www.gnu.org/directory/Security/libgcrypt.html) >= 1.5
or
- [Mbed TLS](https://www.trustedfirmware.org/projects/mbed-tls/)
optional:
- [cmocka](https://cmocka.org/) >= 1.1.0
@@ -21,7 +19,6 @@ optional:
- [nss_wrapper](https://cwrap.org/) >= 1.1.2
- [uid_wrapper](https://cwrap.org/) >= 1.2.0
- [pam_wrapper](https://cwrap.org/) >= 1.0.1
- [priv_wrapper](https://cwrap.org/) >= 1.0.0
Note that these version numbers are version we know works correctly. If you
build and run libssh successfully with an older version, please let us know.
@@ -38,16 +35,14 @@ First, you need to configure the compilation, using CMake. Go inside the
`build` dir. Create it if it doesn't exist.
GNU/Linux, MacOS X, MSYS/MinGW:
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
cmake -DUNIT_TESTING=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
make
On Windows you should choose a makefile generator with -G or use
On Windows you should choose a makefile gernerator with -G or use
cmake-gui.exe ..
To enable building tests use -DUNIT_TESTING=ON. For this, the
[cmocka](https://cmocka.org) dependency is required.
To enable additional client tests against a local OpenSSH server, add the
compile option -DCLIENT_TESTING=ON. These tests require an OpenSSH
server package and some wrapper libraries (see optional requirements) to

2
README
View File

@@ -36,7 +36,7 @@ https://www.libssh.org
4* Contributing
-_-_-_-_-_-_-_-_-_
Please read the file 'CONTRIBUTING.md' next to this README file. It explains
Please read the file 'SubmittingPatches' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Have fun and happy libssh hacking!

375
README.CodingStyle Normal file
View File

@@ -0,0 +1,375 @@
Coding conventions in the libssh tree
======================================
===========
Quick Start
===========
Coding style guidelines are about reducing the number of unnecessary
reformatting patches and making things easier for developers to work together.
You don't have to like them or even agree with them, but once put in place we
all have to abide by them (or vote to change them). However, coding style
should never outweigh coding itself and so the guidelines described here are
hopefully easy enough to follow as they are very common and supported by tools
and editors.
The basic style for C code, is the Linux kernel coding style (See
Documentation/CodingStyle in the kernel source tree). This closely matches what
libssh developers use already anyways, with a few exceptions as mentioned
below.
But to save you the trouble of reading the Linux kernel style guide, here
are the highlights.
* Maximum Line Width is 80 Characters
The reason is not about people with low-res screens but rather sticking
to 80 columns prevents you from easily nesting more than one level of
if statements or other code blocks.
* Use 4 Spaces to Indent
* No Trailing Whitespace
Clean up your files before committing.
* Follow the K&R guidelines. We won't go through all of them here. Do you
have a copy of "The C Programming Language" anyways right?
=============
Editor Hints
=============
Emacs
------
Add the follow to your $HOME/.emacs file:
(add-hook 'c-mode-hook
(lambda ()
(c-set-style "linux")
(c-toggle-auto-state)))
Vim
----
For the basic vi editor included with all variants of \*nix, add the
following to $HOME/.vimrc:
set ts=4 sw=4 et cindent
You can use the Vim gitmodline plugin to store this in the git config:
https://git.cryptomilk.org/projects/vim-gitmodeline.git/
For Vim, the following settings in $HOME/.vimrc will also deal with
displaying trailing whitespace:
if has("syntax") && (&t_Co > 2 || has("gui_running"))
syntax on
function! ActivateInvisibleCharIndicator()
syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
highlight TrailingSpace ctermbg=Red
endf
autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
endif
" Show tabs, trailing whitespace, and continued lines visually
set list listchars=tab:»·,trail:·,extends:…
" highlight overly long lines same as TODOs.
set textwidth=80
autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
==========================
FAQ & Statement Reference
==========================
Comments
---------
Comments should always use the standard C syntax. C++ style comments are not
currently allowed.
The lines before a comment should be empty. If the comment directly belongs to
the following code, there should be no empty line after the comment, except if
the comment contains a summary of multiple following code blocks.
This is good:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/**
* @brief This is a doxygen comment.
*
* This is a more detailed explanation of
* this simple function.
*
* @param[in] param1 The parameter value of the function.
*
* @param[out] result1 The result value of the function.
*
* @return 0 on success and -1 on error.
*/
int example(int param1, int *result1);
This is bad:
...
int i;
/*
* This is a multi line comment,
* which explains the logical steps we have to do:
*
* 1. We need to set i=5, because...
* 2. We need to call complex_fn1
*/
/* This is a one line comment about i = 5. */
i = 5;
/*
* This is a multi line comment,
* explaining the call to complex_fn1()
*/
ret = complex_fn1();
if (ret != 0) {
...
/*This is a one line comment.*/
/* This is a multi line comment,
with some more words...*/
/*
* This is a multi line comment,
* with some more words...*/
Indention & Whitespace & 80 columns
------------------------------------
To avoid confusion, indentations have to be 4 spaces. Do not use tabs!. When
wrapping parameters for function calls, align the parameter list with the first
parameter on the previous line. For example,
var1 = foo(arg1,
arg2,
arg3);
The previous example is intended to illustrate alignment of function
parameters across lines and not as encourage for gratuitous line
splitting. Never split a line before columns 70 - 79 unless you
have a really good reason. Be smart about formatting.
If, switch, & Code blocks
--------------------------
Always follow an 'if' keyword with a space but don't include additional
spaces following or preceding the parentheses in the conditional.
This is good:
if (x == 1)
This is bad:
if ( x == 1 )
or
if (x==1)
Yes we have a lot of code that uses the second and third form and we are trying
to clean it up without being overly intrusive.
Note that this is a rule about parentheses following keywords and not
functions. Don't insert a space between the name and left parentheses when
invoking functions.
Braces for code blocks used by for, if, switch, while, do..while, etc. should
begin on the same line as the statement keyword and end on a line of their own.
You should always include braces, even if the block only contains one
statement. NOTE: Functions are different and the beginning left brace should
be located in the first column on the next line.
If the beginning statement has to be broken across lines due to length, the
beginning brace should be on a line of its own.
The exception to the ending rule is when the closing brace is followed by
another language keyword such as else or the closing while in a do..while loop.
Good examples:
if (x == 1) {
printf("good\n");
}
for (x = 1; x < 10; x++) {
print("%d\n", x);
}
for (really_really_really_really_long_var_name = 0;
really_really_really_really_long_var_name < 10;
really_really_really_really_long_var_name++)
{
print("%d\n", really_really_really_really_long_var_name);
}
do {
printf("also good\n");
} while (1);
Bad examples:
while (1)
{
print("I'm in a loop!\n"); }
for (x=1;
x<10;
x++)
{
print("no good\n");
}
if (i < 10)
print("I should be in braces.\n");
Goto
-----
While many people have been academically taught that "goto"s are fundamentally
evil, they can greatly enhance readability and reduce memory leaks when used as
the single exit point from a function. But in no libssh world what so ever is a
goto outside of a function or block of code a good idea.
Good Examples:
int function foo(int y)
{
int *z = NULL;
int rc = 0;
if (y < 10) {
z = malloc(sizeof(int)*y);
if (z == NULL) {
rc = 1;
goto done;
}
}
print("Allocated %d elements.\n", y);
done:
if (z != NULL) {
free(z);
}
return rc;
}
Initialize pointers
-------------------
All pointer variables MUST be initialized to NULL. History has
demonstrated that uninitialized pointer variables have lead to various
bugs and security issues.
Pointers MUST be initialized even if the assignment directly follows
the declaration, like pointer2 in the example below, because the
instructions sequence may change over time.
Good Example:
char *pointer1 = NULL;
char *pointer2 = NULL;
pointer2 = some_func2();
...
pointer1 = some_func1();
Typedefs
---------
libssh tries to avoid "typedef struct { .. } x_t;" so we do always try to use
"struct x { .. };". We know there are still such typedefs in the code, but for
new code, please don't do that anymore.
Make use of helper variables
-----------------------------
Please try to avoid passing function calls as function parameters in new code.
This makes the code much easier to read and it's also easier to use the "step"
command within gdb.
Good Example:
char *name;
name = get_some_name();
if (name == NULL) {
...
}
rc = some_function_my_name(name);
...
Bad Example:
rc = some_function_my_name(get_some_name());
...
Please try to avoid passing function return values to if- or while-conditions.
The reason for this is better handling of code under a debugger.
Good example:
x = malloc(sizeof(short) * 10);
if (x == NULL) {
fprintf(stderr, "Unable to alloc memory!\n");
}
Bad example:
if ((x = malloc(sizeof(short)*10)) == NULL ) {
fprintf(stderr, "Unable to alloc memory!\n");
}
There are exceptions to this rule. One example is walking a data structure in
an iterator style:
while ((opt = poptGetNextOpt(pc)) != -1) {
... do something with opt ...
}
But in general, please try to avoid this pattern.
Control-Flow changing macros
-----------------------------
Macros like STATUS_NOT_OK_RETURN that change control flow (return/goto/etc)
from within the macro are considered bad, because they look like function calls
that never change control flow. Please do not introduce them.

View File

@@ -1,5 +1,4 @@
[![pipeline status](https://gitlab.com/libssh/libssh-mirror/badges/master/pipeline.svg)](https://gitlab.com/libssh/libssh-mirror/commits/master)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libssh)
```
_ _ _ _
@@ -37,7 +36,7 @@ https://www.libssh.org
# Contributing
Please read the file 'CONTRIBUTING.md' next to this README file. It explains
Please read the file 'SubmittingPatches' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Have fun and happy libssh hacking!

118
SubmittingPatches Normal file
View File

@@ -0,0 +1,118 @@
How to contribute a patch to libssh
====================================
Please checkout the libssh source code using git. Change the code and then
use "git format-patch" to create a patch. The patch should be signed (see
below) and send it to libssh@libssh.org, or attach it to a bug report at
https://red.libssh.org/
For larger code changes, breaking the changes up into a set of simple
patches, each of which does a single thing, are much easier to review.
Patch sets like that will most likely have an easier time being merged
into the libssh code than large single patches that make lots of
changes in one large diff.
Ownership of the contributed code
==================================
libssh is a project with distributed copyright ownership, which means
we prefer the copyright on parts of libssh to be held by individuals
rather than corporations if possible. There are historical legal
reasons for this, but one of the best ways to explain it is that it's
much easier to work with individuals who have ownership than corporate
legal departments if we ever need to make reasonable compromises with
people using and working with libssh.
We track the ownership of every part of libssh via https://git.libssh.org,
our source code control system, so we know the provenance of every piece
of code that is committed to libssh.
So if possible, if you're doing libssh changes on behalf of a company
who normally owns all the work you do please get them to assign
personal copyright ownership of your changes to you as an individual,
that makes things very easy for us to work with and avoids bringing
corporate legal departments into the picture.
If you can't do this we can still accept patches from you owned by
your employer under a standard employment contract with corporate
copyright ownership. It just requires a simple set-up process first.
We use a process very similar to the way things are done in the Linux
Kernel community, so it should be very easy to get a sign off from
your corporate legal department. The only changes we've made are to
accommodate the license we use, which is LGPLv2 (or later) whereas the
Linux kernel uses GPLv2.
The process is called signing.
How to sign your work
----------------------
Once you have permission to contribute to libssh from your employer, simply
email a copy of the following text from your corporate email address to:
contributing@libssh.org
libssh Developer's Certificate of Origin. Version 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the appropriate
version of the GNU General Public License; or
(b) The contribution is based upon previous work that, to the best of
my knowledge, is covered under an appropriate open source license
and I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under
the GNU General Public License, in the appropriate version; or
(c) The contribution was provided directly to me by some other
person who certified (a) or (b) and I have not modified it.
(d) I understand and agree that this project and the contribution are
public and that a record of the contribution (including all
metadata and personal information I submit with it, including my
sign-off) is maintained indefinitely and may be redistributed
consistent with the libssh Team's policies and the requirements of
the GNU GPL where they are relevant.
(e) I am granting this work to this project under the terms of the
GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of
the License, or (at the option of the project) any later version.
https://www.gnu.org/licenses/lgpl-2.1.html
We will maintain a copy of that email as a record that you have the
rights to contribute code to libssh under the required licenses whilst
working for the company where the email came from.
Then when sending in a patch via the normal mechanisms described
above, add a line that states:
Signed-off-by: Random J Developer <random@developer.example.org>
using your real name and the email address you sent the original email
you used to send the libssh Developer's Certificate of Origin to us
(sorry, no pseudonyms or anonymous contributions.)
That's it! Such code can then quite happily contain changes that have
copyright messages such as:
(c) Example Corporation.
and can be merged into the libssh codebase in the same way as patches
from any other individual. You don't need to send in a copy of the
libssh Developer's Certificate of Origin for each patch, or inside each
patch. Just the sign-off message is all that is required once we've
received the initial email.
Have fun and happy libssh hacking !
The libssh Team

View File

@@ -116,10 +116,5 @@ function(ADD_CMOCKA_TEST _TARGET_NAME)
add_test(${_TARGET_NAME}
${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME}
)
if (WITH_COVERAGE)
ENABLE_LANGUAGE(CXX)
include(CodeCoverage)
append_coverage_compiler_flags_to_target(${_TARGET_NAME})
endif (WITH_COVERAGE)
endfunction (ADD_CMOCKA_TEST)

View File

@@ -1,750 +0,0 @@
# Copyright (c) 2012 - 2017, Lars Bilke
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# CHANGES:
#
# 2012-01-31, Lars Bilke
# - Enable Code Coverage
#
# 2013-09-17, Joakim Söderberg
# - Added support for Clang.
# - Some additional usage instructions.
#
# 2016-02-03, Lars Bilke
# - Refactored functions to use named parameters
#
# 2017-06-02, Lars Bilke
# - Merged with modified version from github.com/ufz/ogs
#
# 2019-05-06, Anatolii Kurotych
# - Remove unnecessary --coverage flag
#
# 2019-12-13, FeRD (Frank Dana)
# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor
# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments.
# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY
# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list
# - Set lcov basedir with -b argument
# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be
# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().)
# - Delete output dir, .info file on 'make clean'
# - Remove Python detection, since version mismatches will break gcovr
# - Minor cleanup (lowercase function names, update examples...)
#
# 2019-12-19, FeRD (Frank Dana)
# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets
#
# 2020-01-19, Bob Apthorpe
# - Added gfortran support
#
# 2020-02-17, FeRD (Frank Dana)
# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters
# in EXCLUDEs, and remove manual escaping from gcovr targets
#
# 2021-01-19, Robin Mueller
# - Add CODE_COVERAGE_VERBOSE option which will allow to print out commands which are run
# - Added the option for users to set the GCOVR_ADDITIONAL_ARGS variable to supply additional
# flags to the gcovr command
#
# 2020-05-04, Mihchael Davis
# - Add -fprofile-abs-path to make gcno files contain absolute paths
# - Fix BASE_DIRECTORY not working when defined
# - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines
#
# 2021-05-10, Martin Stump
# - Check if the generator is multi-config before warning about non-Debug builds
#
# 2022-02-22, Marko Wehle
# - Change gcovr output from -o <filename> for --xml <filename> and --html <filename> output respectively.
# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt".
#
# 2022-09-28, Sebastian Mueller
# - fix append_coverage_compiler_flags_to_target to correctly add flags
# - replace "-fprofile-arcs -ftest-coverage" with "--coverage" (equivalent)
#
# USAGE:
#
# 1. Copy this file into your cmake modules path.
#
# 2. Add the following line to your CMakeLists.txt (best inside an if-condition
# using a CMake option() to enable it just optionally):
# include(CodeCoverage)
#
# 3. Append necessary compiler flags for all supported source files:
# append_coverage_compiler_flags()
# Or for specific target:
# append_coverage_compiler_flags_to_target(YOUR_TARGET_NAME)
#
# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og
#
# 4. If you need to exclude additional directories from the report, specify them
# using full paths in the COVERAGE_EXCLUDES variable before calling
# setup_target_for_coverage_*().
# Example:
# set(COVERAGE_EXCLUDES
# '${PROJECT_SOURCE_DIR}/src/dir1/*'
# '/path/to/my/src/dir2/*')
# Or, use the EXCLUDE argument to setup_target_for_coverage_*().
# Example:
# setup_target_for_coverage_lcov(
# NAME coverage
# EXECUTABLE testrunner
# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*")
#
# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set
# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR)
# Example:
# set(COVERAGE_EXCLUDES "dir1/*")
# setup_target_for_coverage_gcovr_html(
# NAME coverage
# EXECUTABLE testrunner
# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src"
# EXCLUDE "dir2/*")
#
# 5. Use the functions described below to create a custom make target which
# runs your test executable and produces a code coverage report.
#
# 6. Build a Debug build:
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# make
# make my_coverage_target
#
include(CMakeParseArguments)
option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE)
# Check prereqs
find_program( GCOV_PATH gcov )
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
find_program( FASTCOV_PATH NAMES fastcov fastcov.py )
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
find_program( CPPFILT_PATH NAMES c++filt )
if(NOT GCOV_PATH)
message(FATAL_ERROR "gcov not found! Aborting...")
endif() # NOT GCOV_PATH
# Check supported compiler (Clang, GNU and Flang)
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(LANG ${LANGUAGES})
if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3)
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
endif()
elseif(NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU"
AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang")
message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
endif()
endforeach()
set(COVERAGE_COMPILER_FLAGS "-g --coverage -fprofile-update=atomic"
CACHE INTERNAL "")
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
if(HAVE_cxx_fprofile_abs_path)
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
endif()
if(CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCCompilerFlag)
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
if(HAVE_c_fprofile_abs_path)
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
endif()
set(CMAKE_Fortran_FLAGS_COVERAGE
${COVERAGE_COMPILER_FLAGS}
CACHE STRING "Flags used by the Fortran compiler during coverage builds."
FORCE )
set(CMAKE_CXX_FLAGS_COVERAGE
${COVERAGE_COMPILER_FLAGS}
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE )
set(CMAKE_C_FLAGS_COVERAGE
${COVERAGE_COMPILER_FLAGS}
CACHE STRING "Flags used by the C compiler during coverage builds."
FORCE )
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used for linking binaries during coverage builds."
FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
FORCE )
mark_as_advanced(
CMAKE_Fortran_FLAGS_COVERAGE
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
link_libraries(gcov)
endif()
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# setup_target_for_coverage_lcov(
# NAME testrunner_coverage # New target name
# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES testrunner # Dependencies to build first
# BASE_DIRECTORY "../" # Base directory for report
# # (defaults to PROJECT_SOURCE_DIR)
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
# # to BASE_DIRECTORY, with CMake 3.4+)
# NO_DEMANGLE # Don't demangle C++ symbols
# # even if c++filt is found
# )
function(setup_target_for_coverage_lcov)
set(options NO_DEMANGLE SONARQUBE)
set(oneValueArgs BASE_DIRECTORY NAME)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT LCOV_PATH)
message(FATAL_ERROR "lcov not found! Aborting...")
endif() # NOT LCOV_PATH
if(NOT GENHTML_PATH)
message(FATAL_ERROR "genhtml not found! Aborting...")
endif() # NOT GENHTML_PATH
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
if(DEFINED Coverage_BASE_DIRECTORY)
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
else()
set(BASEDIR ${PROJECT_SOURCE_DIR})
endif()
# Collect excludes (CMake 3.4+: Also compute absolute paths)
set(LCOV_EXCLUDES "")
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_LCOV_EXCLUDES})
if(CMAKE_VERSION VERSION_GREATER 3.4)
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
endif()
list(APPEND LCOV_EXCLUDES "${EXCLUDE}")
endforeach()
list(REMOVE_DUPLICATES LCOV_EXCLUDES)
# Conditional arguments
if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE})
set(GENHTML_EXTRA_ARGS "--demangle-cpp")
endif()
# Setting up commands which will be run to generate coverage data.
# Cleanup lcov
set(LCOV_CLEAN_CMD
${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory .
-b ${BASEDIR} --zerocounters
)
# Create baseline to make sure untouched files show up in the report
set(LCOV_BASELINE_CMD
${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -b
${BASEDIR} -o ${Coverage_NAME}.base
)
# Run tests
set(LCOV_EXEC_TESTS_CMD
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
)
# Capturing lcov counters and generating report
set(LCOV_CAPTURE_CMD
${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . -b
${BASEDIR} --capture --output-file ${Coverage_NAME}.capture
)
# add baseline counters
set(LCOV_BASELINE_COUNT_CMD
${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base
-a ${Coverage_NAME}.capture --output-file ${Coverage_NAME}.total
)
# filter collected data to final coverage report
set(LCOV_FILTER_CMD
${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove
${Coverage_NAME}.total ${LCOV_EXCLUDES} --output-file ${Coverage_NAME}.info
)
# Generate HTML output
set(LCOV_GEN_HTML_CMD
${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o
${Coverage_NAME} ${Coverage_NAME}.info
)
if(${Coverage_SONARQUBE})
# Generate SonarQube output
set(GCOVR_XML_CMD
${GCOVR_PATH} --sonarqube ${Coverage_NAME}_sonarqube.xml -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS}
${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR}
)
set(GCOVR_XML_CMD_COMMAND
COMMAND ${GCOVR_XML_CMD}
)
set(GCOVR_XML_CMD_BYPRODUCTS ${Coverage_NAME}_sonarqube.xml)
set(GCOVR_XML_CMD_COMMENT COMMENT "SonarQube code coverage info report saved in ${Coverage_NAME}_sonarqube.xml.")
endif()
if(CODE_COVERAGE_VERBOSE)
message(STATUS "Executed command report")
message(STATUS "Command to clean up lcov: ")
string(REPLACE ";" " " LCOV_CLEAN_CMD_SPACED "${LCOV_CLEAN_CMD}")
message(STATUS "${LCOV_CLEAN_CMD_SPACED}")
message(STATUS "Command to create baseline: ")
string(REPLACE ";" " " LCOV_BASELINE_CMD_SPACED "${LCOV_BASELINE_CMD}")
message(STATUS "${LCOV_BASELINE_CMD_SPACED}")
message(STATUS "Command to run the tests: ")
string(REPLACE ";" " " LCOV_EXEC_TESTS_CMD_SPACED "${LCOV_EXEC_TESTS_CMD}")
message(STATUS "${LCOV_EXEC_TESTS_CMD_SPACED}")
message(STATUS "Command to capture counters and generate report: ")
string(REPLACE ";" " " LCOV_CAPTURE_CMD_SPACED "${LCOV_CAPTURE_CMD}")
message(STATUS "${LCOV_CAPTURE_CMD_SPACED}")
message(STATUS "Command to add baseline counters: ")
string(REPLACE ";" " " LCOV_BASELINE_COUNT_CMD_SPACED "${LCOV_BASELINE_COUNT_CMD}")
message(STATUS "${LCOV_BASELINE_COUNT_CMD_SPACED}")
message(STATUS "Command to filter collected data: ")
string(REPLACE ";" " " LCOV_FILTER_CMD_SPACED "${LCOV_FILTER_CMD}")
message(STATUS "${LCOV_FILTER_CMD_SPACED}")
message(STATUS "Command to generate lcov HTML output: ")
string(REPLACE ";" " " LCOV_GEN_HTML_CMD_SPACED "${LCOV_GEN_HTML_CMD}")
message(STATUS "${LCOV_GEN_HTML_CMD_SPACED}")
if(${Coverage_SONARQUBE})
message(STATUS "Command to generate SonarQube XML output: ")
string(REPLACE ";" " " GCOVR_XML_CMD_SPACED "${GCOVR_XML_CMD}")
message(STATUS "${GCOVR_XML_CMD_SPACED}")
endif()
endif()
# Setup target
add_custom_target(${Coverage_NAME}
COMMAND ${LCOV_CLEAN_CMD}
COMMAND ${LCOV_BASELINE_CMD}
COMMAND ${LCOV_EXEC_TESTS_CMD}
COMMAND ${LCOV_CAPTURE_CMD}
COMMAND ${LCOV_BASELINE_COUNT_CMD}
COMMAND ${LCOV_FILTER_CMD}
COMMAND ${LCOV_GEN_HTML_CMD}
${GCOVR_XML_CMD_COMMAND}
# Set output files as GENERATED (will be removed on 'make clean')
BYPRODUCTS
${Coverage_NAME}.base
${Coverage_NAME}.capture
${Coverage_NAME}.total
${Coverage_NAME}.info
${GCOVR_XML_CMD_BYPRODUCTS}
${Coverage_NAME}/index.html
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
VERBATIM # Protect arguments to commands
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
)
# Show where to find the lcov info report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info."
${GCOVR_XML_CMD_COMMENT}
)
# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
)
endfunction() # setup_target_for_coverage_lcov
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# setup_target_for_coverage_gcovr_xml(
# NAME ctest_coverage # New target name
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES executable_target # Dependencies to build first
# BASE_DIRECTORY "../" # Base directory for report
# # (defaults to PROJECT_SOURCE_DIR)
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
# # to BASE_DIRECTORY, with CMake 3.4+)
# )
# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the
# GCVOR command.
function(setup_target_for_coverage_gcovr_xml)
set(options NONE)
set(oneValueArgs BASE_DIRECTORY NAME)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT GCOVR_PATH)
message(FATAL_ERROR "gcovr not found! Aborting...")
endif() # NOT GCOVR_PATH
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
if(DEFINED Coverage_BASE_DIRECTORY)
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
else()
set(BASEDIR ${PROJECT_SOURCE_DIR})
endif()
# Collect excludes (CMake 3.4+: Also compute absolute paths)
set(GCOVR_EXCLUDES "")
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
if(CMAKE_VERSION VERSION_GREATER 3.4)
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
endif()
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach()
list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
# Combine excludes to several -e arguments
set(GCOVR_EXCLUDE_ARGS "")
foreach(EXCLUDE ${GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDE_ARGS "-e")
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
endforeach()
# Set up commands which will be run to generate coverage data
# Run tests
set(GCOVR_XML_EXEC_TESTS_CMD
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
)
# Running gcovr
set(GCOVR_XML_CMD
${GCOVR_PATH} --xml ${Coverage_NAME}.xml -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS}
${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR}
)
if(CODE_COVERAGE_VERBOSE)
message(STATUS "Executed command report")
message(STATUS "Command to run tests: ")
string(REPLACE ";" " " GCOVR_XML_EXEC_TESTS_CMD_SPACED "${GCOVR_XML_EXEC_TESTS_CMD}")
message(STATUS "${GCOVR_XML_EXEC_TESTS_CMD_SPACED}")
message(STATUS "Command to generate gcovr XML coverage data: ")
string(REPLACE ";" " " GCOVR_XML_CMD_SPACED "${GCOVR_XML_CMD}")
message(STATUS "${GCOVR_XML_CMD_SPACED}")
endif()
add_custom_target(${Coverage_NAME}
COMMAND ${GCOVR_XML_EXEC_TESTS_CMD}
COMMAND ${GCOVR_XML_CMD}
BYPRODUCTS ${Coverage_NAME}.xml
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
VERBATIM # Protect arguments to commands
COMMENT "Running gcovr to produce Cobertura code coverage report."
)
# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml."
)
endfunction() # setup_target_for_coverage_gcovr_xml
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# setup_target_for_coverage_gcovr_html(
# NAME ctest_coverage # New target name
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES executable_target # Dependencies to build first
# BASE_DIRECTORY "../" # Base directory for report
# # (defaults to PROJECT_SOURCE_DIR)
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
# # to BASE_DIRECTORY, with CMake 3.4+)
# )
# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the
# GCVOR command.
function(setup_target_for_coverage_gcovr_html)
set(options NONE)
set(oneValueArgs BASE_DIRECTORY NAME)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT GCOVR_PATH)
message(FATAL_ERROR "gcovr not found! Aborting...")
endif() # NOT GCOVR_PATH
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
if(DEFINED Coverage_BASE_DIRECTORY)
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
else()
set(BASEDIR ${PROJECT_SOURCE_DIR})
endif()
# Collect excludes (CMake 3.4+: Also compute absolute paths)
set(GCOVR_EXCLUDES "")
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
if(CMAKE_VERSION VERSION_GREATER 3.4)
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
endif()
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach()
list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
# Combine excludes to several -e arguments
set(GCOVR_EXCLUDE_ARGS "")
foreach(EXCLUDE ${GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDE_ARGS "-e")
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
endforeach()
# Set up commands which will be run to generate coverage data
# Run tests
set(GCOVR_HTML_EXEC_TESTS_CMD
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
)
# Create folder
set(GCOVR_HTML_FOLDER_CMD
${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
)
# Running gcovr
set(GCOVR_HTML_CMD
${GCOVR_PATH} --html ${Coverage_NAME}/index.html --html-details -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS}
${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR}
)
if(CODE_COVERAGE_VERBOSE)
message(STATUS "Executed command report")
message(STATUS "Command to run tests: ")
string(REPLACE ";" " " GCOVR_HTML_EXEC_TESTS_CMD_SPACED "${GCOVR_HTML_EXEC_TESTS_CMD}")
message(STATUS "${GCOVR_HTML_EXEC_TESTS_CMD_SPACED}")
message(STATUS "Command to create a folder: ")
string(REPLACE ";" " " GCOVR_HTML_FOLDER_CMD_SPACED "${GCOVR_HTML_FOLDER_CMD}")
message(STATUS "${GCOVR_HTML_FOLDER_CMD_SPACED}")
message(STATUS "Command to generate gcovr HTML coverage data: ")
string(REPLACE ";" " " GCOVR_HTML_CMD_SPACED "${GCOVR_HTML_CMD}")
message(STATUS "${GCOVR_HTML_CMD_SPACED}")
endif()
add_custom_target(${Coverage_NAME}
COMMAND ${GCOVR_HTML_EXEC_TESTS_CMD}
COMMAND ${GCOVR_HTML_FOLDER_CMD}
COMMAND ${GCOVR_HTML_CMD}
BYPRODUCTS ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html # report directory
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
VERBATIM # Protect arguments to commands
COMMENT "Running gcovr to produce HTML code coverage report."
)
# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
)
endfunction() # setup_target_for_coverage_gcovr_html
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# setup_target_for_coverage_fastcov(
# NAME testrunner_coverage # New target name
# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES testrunner # Dependencies to build first
# BASE_DIRECTORY "../" # Base directory for report
# # (defaults to PROJECT_SOURCE_DIR)
# EXCLUDE "src/dir1/" "src/dir2/" # Patterns to exclude.
# NO_DEMANGLE # Don't demangle C++ symbols
# # even if c++filt is found
# SKIP_HTML # Don't create html report
# POST_CMD perl -i -pe s!${PROJECT_SOURCE_DIR}/!!g ctest_coverage.json # E.g. for stripping source dir from file paths
# )
function(setup_target_for_coverage_fastcov)
set(options NO_DEMANGLE SKIP_HTML)
set(oneValueArgs BASE_DIRECTORY NAME)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES FASTCOV_ARGS GENHTML_ARGS POST_CMD)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT FASTCOV_PATH)
message(FATAL_ERROR "fastcov not found! Aborting...")
endif()
if(NOT Coverage_SKIP_HTML AND NOT GENHTML_PATH)
message(FATAL_ERROR "genhtml not found! Aborting...")
endif()
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
if(Coverage_BASE_DIRECTORY)
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
else()
set(BASEDIR ${PROJECT_SOURCE_DIR})
endif()
# Collect excludes (Patterns, not paths, for fastcov)
set(FASTCOV_EXCLUDES "")
foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_FASTCOV_EXCLUDES})
list(APPEND FASTCOV_EXCLUDES "${EXCLUDE}")
endforeach()
list(REMOVE_DUPLICATES FASTCOV_EXCLUDES)
# Conditional arguments
if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE})
set(GENHTML_EXTRA_ARGS "--demangle-cpp")
endif()
# Set up commands which will be run to generate coverage data
set(FASTCOV_EXEC_TESTS_CMD ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS})
set(FASTCOV_CAPTURE_CMD ${FASTCOV_PATH} ${Coverage_FASTCOV_ARGS} --gcov ${GCOV_PATH}
--search-directory ${BASEDIR}
--process-gcno
--output ${Coverage_NAME}.json
--exclude ${FASTCOV_EXCLUDES}
)
set(FASTCOV_CONVERT_CMD ${FASTCOV_PATH}
-C ${Coverage_NAME}.json --lcov --output ${Coverage_NAME}.info
)
if(Coverage_SKIP_HTML)
set(FASTCOV_HTML_CMD ";")
else()
set(FASTCOV_HTML_CMD ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS}
-o ${Coverage_NAME} ${Coverage_NAME}.info
)
endif()
set(FASTCOV_POST_CMD ";")
if(Coverage_POST_CMD)
set(FASTCOV_POST_CMD ${Coverage_POST_CMD})
endif()
if(CODE_COVERAGE_VERBOSE)
message(STATUS "Code coverage commands for target ${Coverage_NAME} (fastcov):")
message(" Running tests:")
string(REPLACE ";" " " FASTCOV_EXEC_TESTS_CMD_SPACED "${FASTCOV_EXEC_TESTS_CMD}")
message(" ${FASTCOV_EXEC_TESTS_CMD_SPACED}")
message(" Capturing fastcov counters and generating report:")
string(REPLACE ";" " " FASTCOV_CAPTURE_CMD_SPACED "${FASTCOV_CAPTURE_CMD}")
message(" ${FASTCOV_CAPTURE_CMD_SPACED}")
message(" Converting fastcov .json to lcov .info:")
string(REPLACE ";" " " FASTCOV_CONVERT_CMD_SPACED "${FASTCOV_CONVERT_CMD}")
message(" ${FASTCOV_CONVERT_CMD_SPACED}")
if(NOT Coverage_SKIP_HTML)
message(" Generating HTML report: ")
string(REPLACE ";" " " FASTCOV_HTML_CMD_SPACED "${FASTCOV_HTML_CMD}")
message(" ${FASTCOV_HTML_CMD_SPACED}")
endif()
if(Coverage_POST_CMD)
message(" Running post command: ")
string(REPLACE ";" " " FASTCOV_POST_CMD_SPACED "${FASTCOV_POST_CMD}")
message(" ${FASTCOV_POST_CMD_SPACED}")
endif()
endif()
# Setup target
add_custom_target(${Coverage_NAME}
# Cleanup fastcov
COMMAND ${FASTCOV_PATH} ${Coverage_FASTCOV_ARGS} --gcov ${GCOV_PATH}
--search-directory ${BASEDIR}
--zerocounters
COMMAND ${FASTCOV_EXEC_TESTS_CMD}
COMMAND ${FASTCOV_CAPTURE_CMD}
COMMAND ${FASTCOV_CONVERT_CMD}
COMMAND ${FASTCOV_HTML_CMD}
COMMAND ${FASTCOV_POST_CMD}
# Set output files as GENERATED (will be removed on 'make clean')
BYPRODUCTS
${Coverage_NAME}.info
${Coverage_NAME}.json
${Coverage_NAME}/index.html # report directory
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
VERBATIM # Protect arguments to commands
COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report."
)
set(INFO_MSG "fastcov code coverage info report saved in ${Coverage_NAME}.info and ${Coverage_NAME}.json.")
if(NOT Coverage_SKIP_HTML)
string(APPEND INFO_MSG " Open ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html in your browser to view the coverage report.")
endif()
# Show where to find the fastcov info report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo ${INFO_MSG}
)
endfunction() # setup_target_for_coverage_fastcov
function(append_coverage_compiler_flags)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
endfunction() # append_coverage_compiler_flags
# Setup coverage for specific library
function(append_coverage_compiler_flags_to_target name)
separate_arguments(_flag_list NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}")
target_compile_options(${name} PRIVATE ${_flag_list})
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
target_link_libraries(${name} PRIVATE gcov)
endif()
endfunction()

View File

@@ -6,7 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Put the include dirs which are in the source or build tree
# before all other include dirs, so the headers in the sources
# are preferred over the already installed ones
# are prefered over the already installed ones
# since cmake 2.4.1
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON)

View File

@@ -36,9 +36,9 @@ if (UNIX AND NOT WIN32)
CACHE STRING "Flags used by the linker during MEMORYSANITIZER builds.")
# Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover=undefined,integer"
set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.")
set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover=undefined,integer"
set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover"
CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.")
set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")

View File

@@ -50,28 +50,15 @@ file(READ ${HEADERS_LIST_FILE} HEADERS_LIST)
set(symbols)
foreach(header ${HEADERS_LIST})
file(READ ${header} header_content)
# Filter only lines containing the FILTER_PATTERN
# separated from the function name with one optional newline
string(REGEX MATCHALL
"${FILTER_PATTERN}[^(\n]*\n?[^(\n]*[(]"
contain_filter
"${header_content}"
)
# Remove the optional newline now
string(REGEX REPLACE
"(.+)\n?(.*)"
"\\1\\2"
oneline
"${contain_filter}"
file(STRINGS ${header} contain_filter
REGEX "^.*${FILTER_PATTERN}.*[(]"
)
# Remove function-like macros
# and anything with two underscores that sounds suspicious
foreach(line ${oneline})
if (NOT ${line} MATCHES ".*(#[ ]*define|__)")
foreach(line ${contain_filter})
if (NOT ${line} MATCHES ".*#[ ]*define")
list(APPEND not_macro ${line})
endif()
endforeach()

View File

@@ -220,12 +220,13 @@
# Search for python which is required
if (ABIMap_FIND_REQURIED)
find_package(Python REQUIRED)
find_package(PythonInterp REQUIRED)
else()
find_package(Python)
find_package(PythonInterp)
endif()
if (TARGET Python::Interpreter)
if (PYTHONINTERP_FOUND)
# Search for abimap tool used to generate the map files
find_program(ABIMAP_EXECUTABLE NAMES abimap DOC "path to the abimap executable")
mark_as_advanced(ABIMAP_EXECUTABLE)

View File

@@ -1,8 +1,4 @@
# - Try to find ARGP
#
# The argp can be either shipped as part of libc (ex. glibc) or as a separate
# library that requires additional linking (ex. Windows, Mac, musl libc, ...)
#
# Once done this will define
#
# ARGP_ROOT_DIR - Set this variable to the root installation of ARGP
@@ -64,7 +60,7 @@ if (ARGP_LIBRARY)
endif (ARGP_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Argp DEFAULT_MSG ARGP_LIBRARIES ARGP_INCLUDE_DIR)
find_package_handle_standard_args(ARGP DEFAULT_MSG ARGP_LIBRARIES ARGP_INCLUDE_DIR)
# show the ARGP_INCLUDE_DIR and ARGP_LIBRARIES variables only in the advanced view
mark_as_advanced(ARGP_INCLUDE_DIR ARGP_LIBRARIES)

View File

@@ -39,15 +39,6 @@ find_path(GCRYPT_INCLUDE_DIR
include
)
find_path(GCRYPT_ERROR_INCLUDE_DIR
NAMES
gpg-error.h
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
find_library(GCRYPT_LIBRARY
NAMES
gcrypt
@@ -65,10 +56,8 @@ find_library(GCRYPT_ERROR_LIBRARY
libgpg-error6-0
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
set(GCRYPT_LIBRARIES ${GCRYPT_ERROR_LIBRARY} ${GCRYPT_LIBRARY})
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY} ${GCRYPT_ERROR_LIBRARY})
if (GCRYPT_INCLUDE_DIR)
file(STRINGS "${GCRYPT_INCLUDE_DIR}/gcrypt.h" _gcrypt_version_str REGEX "^#define GCRYPT_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]")
@@ -94,25 +83,5 @@ else (GCRYPT_VERSION)
GCRYPT_LIBRARIES)
endif (GCRYPT_VERSION)
# 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_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()
# show the GCRYPT_INCLUDE_DIRS and GCRYPT_LIBRARIES variables only in the advanced view
mark_as_advanced(GCRYPT_INCLUDE_DIR GCRYPT_LIBRARIES)

View File

@@ -5,14 +5,12 @@
# GSSAPI_ROOT_DIR - Set this variable to the root installation of GSSAPI
#
# Read-Only variables:
# GSSAPI_FLAVOR_MIT - set to TRUE if MIT Kerberos has been found
# GSSAPI_FLAVOR_MIT - set to TURE if MIT Kerberos has been found
# GSSAPI_FLAVOR_HEIMDAL - set to TRUE if Heimdal Keberos has been found
# GSSAPI_FOUND - system has GSSAPI
# GSSAPI_INCLUDE_DIR - the GSSAPI include directory
# GSSAPI_LIBRARIES - Link these to use GSSAPI
# GSSAPI_DEFINITIONS - Compiler switches required for using GSSAPI
# GSSAPI_PC_REQUIRES - pkg-config module name if found, needed for
# Requires.private for static linking
#
#=============================================================================
# Copyright (c) 2013 Andreas Schneider <asn@cryptomilk.org>
@@ -26,23 +24,12 @@
#=============================================================================
#
set(_mit_modname "mit-krb5-gssapi")
set(_heimdal_modname "heimdal-gssapi")
if(NOT _GSSAPI_ROOT_HINTS AND NOT _GSSAPI_ROOT_PATHS)
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_search_module(_GSSAPI ${_mit_modname} ${_heimdal_modname})
endif()
endif()
find_path(GSSAPI_ROOT_DIR
NAMES
include/gssapi.h
include/gssapi/gssapi.h
HINTS
${_GSSAPI_ROOT_HINTS}
"${_GSSAPI_INCLUDEDIR}"
PATHS
${_GSSAPI_ROOT_PATHS}
)
@@ -330,15 +317,9 @@ endif (GSSAPI_FLAVOR_HEIMDAL)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GSSAPI DEFAULT_MSG GSSAPI_LIBRARIES GSSAPI_INCLUDE_DIR)
if(GSSAPI_FOUND)
if(_GSSAPI_FOUND) # via pkg-config
if (GSSAPI_FLAVOR_MIT)
set(GSSAPI_PC_REQUIRES ${_mit_modname})
elseif (GSSAPI_FLAVOR_HEIMDAL)
set(GSSAPI_PC_REQUIRES ${_heimdal_modname})
endif()
endif()
endif()
if (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES)
set(GSSAPI_FOUND TRUE)
endif (GSSAPI_INCLUDE_DIRS AND GSSAPI_LIBRARIES)
# show the GSSAPI_INCLUDE_DIR and GSSAPI_LIBRARIES variables only in the advanced view
mark_as_advanced(GSSAPI_INCLUDE_DIR GSSAPI_LIBRARIES)
# show the GSSAPI_INCLUDE_DIRS and GSSAPI_LIBRARIES variables only in the advanced view
mark_as_advanced(GSSAPI_INCLUDE_DIRS GSSAPI_LIBRARIES)

View File

@@ -34,7 +34,7 @@ set(_MBEDTLS_ROOT_HINTS_AND_PATHS
find_path(MBEDTLS_INCLUDE_DIR
NAMES
mbedtls/ssl.h
mbedtls/config.h
HINTS
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
@@ -72,23 +72,13 @@ find_library(MBEDTLS_X509_LIBRARY
set(MBEDTLS_LIBRARIES ${MBEDTLS_SSL_LIBRARY} ${MBEDTLS_CRYPTO_LIBRARY}
${MBEDTLS_X509_LIBRARY})
# mbedtls 2.8
if (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" _mbedtls_version_str REGEX
"^#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"[0-9]+.[0-9]+.[0-9]+\"")
string(REGEX REPLACE "^.*MBEDTLS_VERSION_STRING.*([0-9]+\\.[0-9]+\\.[0-9]+).*$"
string(REGEX REPLACE "^.*MBEDTLS_VERSION_STRING.*([0-9]+.[0-9]+.[0-9]+).*"
"\\1" MBEDTLS_VERSION "${_mbedtls_version_str}")
endif()
# mbedtls 3.6
if (NOT MBEDTLS_VERSION AND MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h" _mbedtls_version_str REGEX
"^#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"[0-9]+.[0-9]+.[0-9]+\"")
string(REGEX REPLACE "^.*MBEDTLS_VERSION_STRING.*([0-9]+\\.[0-9]+\\.[0-9]+).*$"
"\\1" MBEDTLS_VERSION "${_mbedtls_version_str}")
endif()
endif ()
include(FindPackageHandleStandardArgs)
if (MBEDTLS_VERSION)
@@ -103,8 +93,8 @@ if (MBEDTLS_VERSION)
in the system variable MBEDTLS_ROOT_DIR"
)
else (MBEDTLS_VERSION)
find_package_handle_standard_args(MbedTLS
"Could NOT find mbedTLS, try to set the path to mbedTLS root folder in
find_package_handle_standard_args(MBedTLS
"Could NOT find mbedTLS, try to set the path to mbedLS root folder in
the system variable MBEDTLS_ROOT_DIR"
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARIES)
@@ -112,32 +102,3 @@ endif (MBEDTLS_VERSION)
# show the MBEDTLS_INCLUDE_DIRS and MBEDTLS_LIBRARIES variables only in the advanced view
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

@@ -1,36 +0,0 @@
# - Try to find softhsm
# Once done this will define
#
# SOFTHSM_FOUND - system has softhsm
# SOFTHSM_LIBRARIES - Link these to use softhsm
#
#=============================================================================
# Copyright (c) 2019 Sahana Prasad <sahana@redhat.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
#
find_library(SOFTHSM2_LIBRARY
NAMES
softhsm2
)
if (SOFTHSM2_LIBRARY)
set(SOFTHSM_LIBRARIES
${SOFTHSM_LIBRARIES}
${SOFTHSM2_LIBRARY}
)
endif (SOFTHSM2_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(softhsm DEFAULT_MSG SOFTHSM_LIBRARIES)
# show the SOFTHSM_INCLUDE_DIR and SOFTHSM_LIBRARIES variables only in the advanced view
mark_as_advanced(SOFTHSM_LIBRARIES)

View File

@@ -9,11 +9,9 @@
#cmakedefine SOURCEDIR "${SOURCEDIR}"
/* Global bind configuration file path */
#cmakedefine USR_GLOBAL_BIND_CONFIG "${USR_GLOBAL_BIND_CONFIG}"
#cmakedefine GLOBAL_BIND_CONFIG "${GLOBAL_BIND_CONFIG}"
/* Global client configuration file path */
#cmakedefine USR_GLOBAL_CLIENT_CONFIG "${USR_GLOBAL_CLIENT_CONFIG}"
#cmakedefine GLOBAL_CLIENT_CONFIG "${GLOBAL_CLIENT_CONFIG}"
/************************** HEADER FILES *************************/
@@ -60,15 +58,15 @@
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#cmakedefine HAVE_IFADDRS_H 1
/* Define to 1 if you have the <openssl/aes.h> header file. */
#cmakedefine HAVE_OPENSSL_AES_H 1
/* Define to 1 if you have the <wspiapi.h> header file. */
#cmakedefine HAVE_WSPIAPI_H 1
/* Define to 1 if you have the <openssl/blowfish.h> header file. */
#cmakedefine HAVE_OPENSSL_BLOWFISH_H 1
/* Define to 1 if you have the <openssl/des.h> header file. */
#cmakedefine HAVE_OPENSSL_DES_H 1
@@ -84,38 +82,62 @@
/* Define to 1 if you have the <pthread.h> header file. */
#cmakedefine HAVE_PTHREAD_H 1
/* Define to 1 if you have elliptic curve cryptography in openssl */
/* Define to 1 if you have eliptic curve cryptography in openssl */
#cmakedefine HAVE_OPENSSL_ECC 1
/* Define to 1 if mbedTLS supports curve25519 */
#cmakedefine HAVE_MBEDTLS_CURVE25519 1
/* Define to 1 if you have elliptic curve cryptography in gcrypt */
/* Define to 1 if you have eliptic curve cryptography in gcrypt */
#cmakedefine HAVE_GCRYPT_ECC 1
/* Define to 1 if you have elliptic curve cryptography */
/* Define to 1 if you have eliptic curve cryptography */
#cmakedefine HAVE_ECC 1
/* Define to 1 if you have gl_flags as a glob_t struct member */
/* Define to 1 if you have DSA */
#cmakedefine HAVE_DSA 1
/* Define to 1 if you have gl_flags as a glob_t sturct member */
#cmakedefine HAVE_GLOB_GL_FLAGS_MEMBER 1
/* Define to 1 if you have gcrypt with ChaCha20/Poly1305 support */
#cmakedefine HAVE_GCRYPT_CHACHA_POLY 1
/* Define to 1 if you have OpenSSL with Ed25519 support */
#cmakedefine HAVE_OPENSSL_ED25519 1
/* Define to 1 if you have gcrypt with curve25519 support */
#cmakedefine HAVE_GCRYPT_CURVE25519
/* Define to 1 if you have OpenSSL with X25519 support */
#cmakedefine HAVE_OPENSSL_X25519 1
/*************************** FUNCTIONS ***************************/
/* Define to 1 if you have the `EVP_chacha20' function. */
#cmakedefine HAVE_OPENSSL_EVP_CHACHA20 1
/* Define to 1 if you have the `EVP_aes128_ctr' function. */
#cmakedefine HAVE_OPENSSL_EVP_AES_CTR 1
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' or `EVP_KDF_CTX_new` function. */
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX 1
/* Define to 1 if you have the `EVP_aes128_cbc' function. */
#cmakedefine HAVE_OPENSSL_EVP_AES_CBC 1
/* Define to 1 if you have the `EVP_aes128_gcm' function. */
#cmakedefine HAVE_OPENSSL_EVP_AES_GCM 1
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
#cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1
/* Define to 1 if you have the `CRYPTO_ctr128_encrypt' function. */
#cmakedefine HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT 1
/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
#cmakedefine HAVE_OPENSSL_EVP_CIPHER_CTX_NEW 1
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' function. */
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID 1
/* Define to 1 if you have the `FIPS_mode' function. */
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
/* Define to 1 if you have the `EVP_DigestSign' function. */
#cmakedefine HAVE_OPENSSL_EVP_DIGESTSIGN 1
/* Define to 1 if you have the `EVP_DigestVerify' function. */
#cmakedefine HAVE_OPENSSL_EVP_DIGESTVERIFY 1
/* Define to 1 if you have the `OPENSSL_ia32cap_loc' function. */
#cmakedefine HAVE_OPENSSL_IA32CAP_LOC 1
/* Define to 1 if you have the `snprintf' function. */
#cmakedefine HAVE_SNPRINTF 1
@@ -188,9 +210,6 @@
/* Define to 1 if you have the `cmocka_set_test_filter' function. */
#cmakedefine HAVE_CMOCKA_SET_TEST_FILTER 1
/* Define to 1 if we have support for blowfish */
#cmakedefine HAVE_BLOWFISH 1
/*************************** LIBRARIES ***************************/
/* Define to 1 if you have the `crypto' library (-lcrypto). */
@@ -215,7 +234,6 @@
#cmakedefine HAVE_FALLTHROUGH_ATTRIBUTE 1
#cmakedefine HAVE_UNUSED_ATTRIBUTE 1
#cmakedefine HAVE_WEAK_ATTRIBUTE 1
#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
@@ -242,14 +260,6 @@
/* Define to 1 if you want to enable DH group exchange algorithms */
#cmakedefine WITH_GEX 1
/* Define to 1 if you want to enable insecure none cipher and MAC */
#cmakedefine WITH_INSECURE_NONE 1
/* Define to 1 if you want to allow libssh to execute arbitrary commands from
* configuration files or options (match exec, proxy commands and OpenSSH-based
* proxy-jumps). */
#cmakedefine WITH_EXEC 1
/* Define to 1 if you want to enable blowfish cipher support */
#cmakedefine WITH_BLOWFISH_CIPHER 1
@@ -268,12 +278,6 @@
/* Define to 1 if you want to enable NaCl support */
#cmakedefine WITH_NACL 1
/* Define to 1 if you want to enable PKCS #11 URI support */
#cmakedefine WITH_PKCS11_URI 1
/* Define to 1 if we want to build a support for PKCS #11 provider. */
#cmakedefine WITH_PKCS11_PROVIDER 1
/*************************** ENDIAN *****************************/
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most

View File

@@ -14,13 +14,11 @@ if (DOXYGEN_FOUND)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_MARKDOWN_SUPPORT YES)
set(DOXYGEN_FULL_PATH_NAMES NO)
set(DOXYGEN_GENERATE_TAGFILE "tags.xml")
set(DOXYGEN_PREDEFINED DOXYGEN
WITH_SERVER
WITH_SFTP
PRINTF_ATTRIBUTE\(x,y\))
set(DOXYGEN_DOT_GRAPH_MAX_NODES 100)
PRINTF_ATTRIBUTE(x,y))
set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style)
set(DOXYGEN_HTML_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/that_style/header.html)
@@ -36,44 +34,6 @@ if (DOXYGEN_FOUND)
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/folderclosed.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/folderopen.svg
${CMAKE_CURRENT_SOURCE_DIR}/that_style/js/striped_bg.js)
set(DOXYGEN_EXCLUDE_PATTERNS */src/external/* fe25519.h ge25519.h sc25519.h
blf.h)
set(DOXYGEN_EXCLUDE_SYMBOLS_STRUCTS chacha20_poly1305_keysched,dh_ctx,dh_ctx,dh_keypair,error_struct,
packet_struct,pem_get_password_struct,ssh_tokens_st,
sftp_attributes_struct,sftp_client_message_struct,
sftp_dir_struct,sftp_ext_struct,sftp_file_struct,sftp_message_struct,
sftp_packet_struct,sftp_request_queue_struct,sftp_session_struct,
sftp_status_message_struct,ssh_agent_state_struct,
ssh_agent_struct,ssh_auth_auto_state_struct,ssh_auth_request,
ssh_bind_config_keyword_table_s,ssh_bind_config_match_keyword_table_s,
ssh_bind_struct,ssh_buffer_struct,ssh_channel_callbacks_struct,
ssh_channel_read_termination_struct,ssh_channel_request,
ssh_channel_request_open,ssh_channel_struct,ssh_cipher_struct,
ssh_common_struct,ssh_config_keyword_table_s,
ssh_config_match_keyword_table_s,ssh_connector_struct,
ssh_counter_struct,ssh_crypto_struct,ssh_event_fd_wrapper,
ssh_event_struct,ssh_global_request,ssh_gssapi_struct,ssh_hmac_struct,
ssh_iterator,ssh_kbdint_struct,ssh_kex_struct,ssh_key_struct,
ssh_knownhosts_entry,ssh_list,ssh_mac_ctx_struct,ssh_message_struct,
ssh_packet_callbacks_struct,ssh_packet_header,ssh_poll_ctx_struct,
ssh_poll_handle_struct,ssh_pollfd_struct,ssh_private_key_struct,
ssh_public_key_struct,ssh_scp_struct,ssh_service_request,
ssh_session_struct,ssh_signature_struct,ssh_socket_struct,
ssh_string_struct,ssh_threads_callbacks_struct,ssh_timestamp,)
set(DOXYGEN_EXCLUDE_SYMBOLS_MACRO SSH_FXP*,SSH_SOCKET*,SERVERBANNER,SOCKOPT_TYPE_ARG4,SSH_FILEXFER*,
SSH_FXF*,SSH_S_*,SFTP_*,NSS_BUFLEN_PASSWD,CLOCK,MAX_LINE_SIZE,
PKCS11_URI,KNOWNHOSTS_MAXTYPES,)
set(DOXYGEN_EXCLUDE_SYMBOLS_TYPEDEFS sftp_attributes,sftp_client_message,sftp_dir,sftp_ext,sftp_file,
sftp_message,sftp_packet,sftp_request_queue,sftp_session,
sftp_status_message,sftp_statvfs_t,poll_fn,ssh_callback_int,
ssh_callback_data,ssh_callback_int_int,ssh_message_callback,
ssh_channel_callback_int,ssh_channel_callback_data,ssh_callbacks,
ssh_gssapi_select_oid_callback,ssh_gssapi_accept_sec_ctx_callback,
ssh_gssapi_verify_mic_callback,ssh_server_callbacks,ssh_socket_callbacks,
ssh_packet_callbacks,ssh_channel_callbacks,ssh_bind,ssh_bind_callbacks,)
set(DOXYGEN_EXCLUDE_SYMBOLS ${DOXYGEN_EXCLUDE_SYMBOLS_STRUCTS}
${DOXYGEN_EXCLUDE_SYMBOLS_MACRO}
${DOXYGEN_EXCLUDE_SYMBOLS_TYPEDEFS})
# This updates the Doxyfile if we do changes here
set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in")
@@ -84,8 +44,6 @@ if (DOXYGEN_FOUND)
${CMAKE_SOURCE_DIR}/include/libssh
${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(docs_coverage COMMAND ${CMAKE_SOURCE_DIR}/doc/doc_coverage.sh ${CMAKE_BINARY_DIR})
endif() # DOXYGEN_FOUND
endif() # CMAKE_VERSION

View File

@@ -1,101 +0,0 @@
# Install a FreeBSD CI instance
Install the following packages:
```
pkg install -y bash git gmake cmake cmocka openssl wget pkgconf ccache bash
```
Create gitlab-runner user:
```
pw group add -n gitlab-runner
pw user add -n gitlab-runner -g gitlab-runner -s /usr/local/bin/bash
mkdir /home/gitlab-runner
chown gitlab-runner:gitlab-runner /home/gitlab-runner
```
Get the gitlab-runner binary for freebsd:
```
wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-freebsd-amd64
chmod +x /usr/local/bin/gitlab-runner
```
Create a log file and allow access:
```
touch /var/log/gitlab_runner.log && chown gitlab-runner:gitlab-runner /var/log/gitlab_runner.log
```
We need a start script to run it on boot:
```
mkdir -p /usr/local/etc/rc.d
cat > /usr/local/etc/rc.d/gitlab_runner << EOF
#!/usr/local/bin/bash
# PROVIDE: gitlab_runner
# REQUIRE: DAEMON NETWORKING
# BEFORE:
# KEYWORD:
. /etc/rc.subr
name="gitlab_runner"
rcvar="gitlab_runner_enable"
load_rc_config $name
user="gitlab-runner"
user_home="/home/gitlab-runner"
command="/usr/local/bin/gitlab-runner run"
pidfile="/var/run/${name}.pid"
start_cmd="gitlab_runner_start"
stop_cmd="gitlab_runner_stop"
status_cmd="gitlab_runner_status"
gitlab_runner_start()
{
export USER=${user}
export HOME=${user_home}
if checkyesno ${rcvar}; then
cd ${user_home}
/usr/sbin/daemon -u ${user} -p ${pidfile} ${command} > /var/log/gitlab_runner.log 2>&1
fi
}
gitlab_runner_stop()
{
if [ -f ${pidfile} ]; then
kill `cat ${pidfile}`
fi
}
gitlab_runner_status()
{
if [ ! -f ${pidfile} ] || kill -0 `cat ${pidfile}`; then
echo "Service ${name} is not running."
else
echo "${name} appears to be running."
fi
}
run_rc_command $1
EOF
chmod +x /usr/local/etc/rc.d/gitlab_runner
```
Register your gitlab-runner with your gitlab project
```
su gitlab-runner -c 'gitlab-runner register'
```
Start the gitlab runner service:
```
sysrc -f /etc/rc.conf "gitlab_runner_enable=YES"
service gitlab_runner start
```

View File

@@ -33,9 +33,6 @@ The process of authenticating by public key to a server is the following:
used to authenticate the user).
- then, you retrieve the private key for this key and send a message
proving that you know that private key.
- when several identity files are specified, then the order of processing of
these files is from the last-mentioned to the first one
(if specified in the ~/.ssh/config, then starting from the bottom to the top).
The function ssh_userauth_autopubkey() does this using the available keys in
"~/.ssh/". The return values are the following:
@@ -105,7 +102,7 @@ Here is a small example of password authentication:
@code
int authenticate_password(ssh_session session)
{
char *password = NULL;
char *password;
int rc;
password = getpass("Enter your password: ");
@@ -218,7 +215,7 @@ int authenticate_kbdint(ssh_session session)
rc = ssh_userauth_kbdint(session, NULL, NULL);
while (rc == SSH_AUTH_INFO)
{
const char *name = NULL, *instruction = NULL;
const char *name, *instruction;
int nprompts, iprompt;
name = ssh_userauth_kbdint_getname(session);
@@ -231,7 +228,7 @@ int authenticate_kbdint(ssh_session session)
printf("%s\n", instruction);
for (iprompt = 0; iprompt < nprompts; iprompt++)
{
const char *prompt = NULL;
const char *prompt;
char echo;
prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo);
@@ -251,7 +248,7 @@ int authenticate_kbdint(ssh_session session)
}
else
{
char *ptr = NULL;
char *ptr;
ptr = getpass(prompt);
if (ssh_userauth_kbdint_setanswer(session, iprompt, ptr) < 0)
@@ -354,7 +351,7 @@ The following example shows how to retrieve and dispose the issue banner:
int display_banner(ssh_session session)
{
int rc;
char *banner = NULL;
char *banner;
/*
*** Does not work without calling ssh_userauth_none() first ***

View File

@@ -22,7 +22,7 @@ a SSH session that uses this channel:
@code
int show_remote_files(ssh_session session)
{
ssh_channel channel = NULL;
ssh_channel channel;
int rc;
channel = ssh_channel_new(session);
@@ -91,10 +91,4 @@ that it used:
}
@endcode
Warning: In a single channel, only ONE command can be executed!
If you want to executed multiple commands, allocate separate channels for
them or consider opening interactive shell.
Attempting to run multiple consecutive commands in one channel will fail.
*/

View File

@@ -3,13 +3,13 @@ curve25519-sha256@libssh.org.txt Aris Adamantiadis <aris@badcode.be>
1. Introduction
This document describes the key exchange method curve25519-sha256@libssh.org
This document describes the key exchange methode curve25519-sha256@libssh.org
for SSH version 2 protocol. It is provided as an alternative to the existing
key exchange mechanisms based on either Diffie-Hellman or Elliptic Curve Diffie-
Hellman [RFC5656].
The reason is the following : During summer of 2013, revelations from ex-
consultant at NSA Edward Snowden gave proof that NSA willingly inserts backdoors
into software, hardware components and published standards. While it is still
into softwares, hardware components and published standards. While it is still
believed that the mathematics behind ECC cryptography are still sound and solid,
some people (including Bruce Schneier [SCHNEIER]), showed their lack of confidence
in NIST-published curves such as nistp256, nistp384, nistp521, for which constant
@@ -42,8 +42,8 @@ The following is an overview of the key exchange process:
Client Server
------ ------
Generate ephemeral key pair.
SSH_MSG_KEX_ECDH_INIT -------->
Verify that client public key
SSH_MSG_KEX_ECDH_INIT -------->
Verify that client public key
length is 32 bytes.
Generate ephemeral key pair.
Compute shared secret.
@@ -55,7 +55,7 @@ Compute shared secret.
Generate exchange hash.
Verify server's signature.
* Optional but strongly recommended as this protects against MITM attacks.
* Optional but strongly recommanded as this protects against MITM attacks.
This is implemented using the same messages as described in RFC5656 chapter 4
@@ -109,7 +109,7 @@ This number is calculated using the following procedure:
side's public key and the local private key scalar.
The whole 32 bytes of the number X are then converted into a big integer k.
This conversion follows the network byte order. This step differs from
This conversion follows the network byte order. This step differs from
RFC5656.
[RFC5656] https://tools.ietf.org/html/rfc5656

View File

@@ -1,52 +0,0 @@
#!/bin/bash
################################################################################
# .doc_coverage.sh #
# Script to detect overall documentation coverage of libssh. The script uses #
# doxygen to generate the documentation then parses it's output. #
# #
# maintainer: Norbert Pocs <npocs@redhat.com> #
################################################################################
BUILD_DIR="$1"
DOXYFILE_PATH="$BUILD_DIR/doc/Doxyfile.docs"
INDEX_XML_PATH="$BUILD_DIR/doc/xml/index.xml"
# filters
F_EXCLUDE_FILES=' wrapper.h legacy.h crypto.h priv.h chacha.h curve25519.h '
F_UNDOC_FUNC='(function).*is not documented'
F_FUNC='kind="function"'
F_HEADERS='libssh_8h_|group__libssh__'
F_CUT_BEFORE='.*<name>'
F_CUT_AFTER='<\/name><\/member>'
# Doxygen options
O_QUIET='QUIET=YES'
O_GEN_XML='GENERATE_XML=YES'
# check if build dir given
if [ $# -eq 0 ]; then
echo "Please provide the build directory e.g.: ./build"
exit 255
fi
# modify doxyfile to our needs:
# QUIET - less output
# GENERATE_XML - xml needed to inspect all the functions
# (note: the options are needed to be on separate lines)
# We want to exclude irrelevant files
MOD_DOXYFILE=$(cat "$DOXYFILE_PATH"; echo "$O_QUIET"; echo "$O_GEN_XML")
MOD_DOXYFILE=${MOD_DOXYFILE//EXCLUDE_PATTERNS.*=/EXCLUDE_PATTERNS=$F_EXCLUDE_FILES/g}
# call doxygen to get the warning messages
# and also generate the xml for inspection
DOXY_WARNINGS=$(echo "$MOD_DOXYFILE" | doxygen - 2>&1)
# get the number of undocumented functions
UNDOC_FUNC=$(echo "$DOXY_WARNINGS" | grep -cE "$F_UNDOC_FUNC")
# filter out the lines consisting of functions of our interest
FUNC_LINES=$(grep "$F_FUNC" "$INDEX_XML_PATH" | grep -E "$F_HEADERS")
# cut the irrelevant information and leave just the function names
ALL_FUNC=$(echo "$FUNC_LINES" | sed -e "s/$F_CUT_BEFORE//g" -e "s/$F_CUT_AFTER//")
# remove duplicates and get the number of functions
ALL_FUNC=$(echo "$ALL_FUNC" | sort - | uniq | wc -l)
# percentage of the documented functions
awk "BEGIN {printf \"Documentation coverage is %.2f%\n\", 100 - (${UNDOC_FUNC}/${ALL_FUNC}*100)}"

View File

@@ -100,8 +100,8 @@ used to retrieve google's home page from the remote SSH server.
@code
int direct_forwarding(ssh_session session)
{
ssh_channel forwarding_channel = NULL;
int rc = SSH_ERROR;
ssh_channel forwarding_channel;
int rc;
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
int nbytes, nwritten;
@@ -161,12 +161,10 @@ local libssh application, which handles them:
int web_server(ssh_session session)
{
int rc;
ssh_channel channel = NULL;
ssh_channel channel;
char buffer[256];
int nbytes, nwritten;
int port = 0;
char *peer_address = NULL;
int peer_port = 0;
char *helloworld = ""
"HTTP/1.1 200 OK\n"
"Content-Type: text/html\n"
@@ -189,8 +187,7 @@ int web_server(ssh_session session)
return rc;
}
channel = ssh_channel_open_forward_port(session, 60000, &port,
&peer_address, &peer_port);
channel = ssh_channel_accept_forward(session, 60000, &port);
if (channel == NULL)
{
fprintf(stderr, "Error waiting for incoming connection: %s\n",
@@ -207,7 +204,6 @@ int web_server(ssh_session session)
ssh_get_error(session));
ssh_channel_send_eof(channel);
ssh_channel_free(channel);
ssh_string_free_char(peer_address);
return SSH_ERROR;
}
if (strncmp(buffer, "GET /", 5)) continue;
@@ -220,15 +216,13 @@ int web_server(ssh_session session)
ssh_get_error(session));
ssh_channel_send_eof(channel);
ssh_channel_free(channel);
ssh_string_free_char(peer_address);
return SSH_ERROR;
}
printf("Sent answer to %s:%d\n", peer_address, peer_port);
printf("Sent answer\n");
}
ssh_channel_send_eof(channel);
ssh_channel_free(channel);
ssh_string_free_char(peer_address);
return SSH_OK;
}
@endcode

View File

@@ -5,7 +5,7 @@
A SSH session goes through the following steps:
- Before connecting to the server, you can set up if you wish one or other
server public key authentication, i.e. RSA, ED25519 or ECDSA. You can choose
server public key authentication, i.e. DSA or RSA. You can choose
cryptographic algorithms you trust and compression algorithms if any. You
must of course set up the hostname.
@@ -15,7 +15,7 @@ A SSH session goes through the following steps:
file.
- The client must authenticate: the classical ways are password, or
public keys (from ecdsa, ed25519 and rsa key-pairs generated by openssh).
public keys (from dsa and rsa key-pairs generated by openssh).
If a SSH agent is running, it is possible to use it.
- Now that the user has been authenticated, you must open one or several
@@ -79,7 +79,7 @@ Here is a small example of how to use it:
int main()
{
ssh_session my_ssh_session = NULL;
ssh_session my_ssh_session;
int verbosity = SSH_LOG_PROTOCOL;
int port = 22;
@@ -126,7 +126,7 @@ Here's an example:
int main()
{
ssh_session my_ssh_session = NULL;
ssh_session my_ssh_session;
int rc;
my_ssh_session = ssh_new();
@@ -190,8 +190,8 @@ int verify_knownhost(ssh_session session)
ssh_key srv_pubkey = NULL;
size_t hlen;
char buf[10];
char *hexa = NULL;
char *p = NULL;
char *hexa;
char *p;
int cmp;
int rc;
@@ -317,9 +317,9 @@ The example below shows an authentication with password:
int main()
{
ssh_session my_ssh_session = NULL;
ssh_session my_ssh_session;
int rc;
char *password = NULL;
char *password;
// Open session and set options
my_ssh_session = ssh_new();
@@ -380,7 +380,7 @@ The example below shows how to execute a remote command:
@code
int show_remote_processes(ssh_session session)
{
ssh_channel channel = NULL;
ssh_channel channel;
int rc;
char buffer[256];
int nbytes;

View File

@@ -14,8 +14,8 @@ libssh is a Free Software / Open Source project. The libssh library
is distributed under LGPL license. The libssh project has nothing to do with
"libssh2", which is a completely different and independent project.
libssh can run on top of either libcrypto, mbedtls or libgcrypt (deprecated)
general-purpose cryptographic libraries.
libssh can run on top of either libgcrypt or libcrypto,
two general-purpose cryptographic libraries.
This tutorial concentrates for its main part on the "client" side of libssh.
To learn how to accept incoming SSH connections (how to write a SSH server),
@@ -44,10 +44,6 @@ Table of contents:
@subpage libssh_tutor_threads
@subpage libssh_tutor_pkcs11
@subpage libssh_tutor_sftp_aio
@subpage libssh_tutor_todo
*/

View File

@@ -19,11 +19,11 @@ the interesting functions as you go.
The libssh library provides:
- <strong>Key Exchange Methods</strong>: <i>sntrup761x25519-sha512@openssh.com, curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256,ssh-dss
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5, none
- <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
@@ -33,12 +33,12 @@ The libssh library provides:
- <strong>Thread-safe</strong>: Just don't share sessions
- <strong>Non-blocking</strong>: it can be used both blocking and non-blocking
- <strong>Your sockets</strong>: the app hands over the socket, or uses libssh sockets
- <b>OpenSSL</b>, <b>MBedTLS</b> or <b>gcrypt</b> (deprecated): builds with either
- <b>OpenSSL</b> or <b>gcrypt</b>: builds with either
@section main-additional-features Additional Features
- Client <b>and</b> server support
- SSHv2 protocol support
- SSHv2 and SSHv1 protocol support
- Supports <a href="https://test.libssh.org/" target="_blank">Linux, UNIX, BSD, Solaris, OS/2 and Windows</a>
- Automated test cases with nightly <a href="https://test.libssh.org/" target="_blank">tests</a>
- Event model based on poll(2), or a poll(2)-emulation.
@@ -149,7 +149,7 @@ The libssh Team
@subsection main-rfc-secsh Secure Shell (SSH)
The following RFC documents described SSH-2 protocol as an Internet standard.
The following RFC documents described SSH-2 protcol as an Internet standard.
- <a href="https://tools.ietf.org/html/rfc4250" target="_blank">RFC 4250</a>,
The Secure Shell (SSH) Protocol Assigned Numbers
@@ -211,17 +211,15 @@ It was later modified and expanded by the following RFCs.
(only the "server-sig-algs" extension implemented)
- <a href="https://tools.ietf.org/html/rfc8332" target="_blank">RFC 8332</a>,
Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol
- <a href="https://tools.ietf.org/html/rfc8709" target="_blank">RFC 8709</a>,
Ed25519 and Ed448 Public Key Algorithms for the Secure Shell (SSH) Protocol
- <a href="https://tools.ietf.org/html/rfc8709" target="_blank">RFC 8731</a>,
Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448
- <a href="https://tools.ietf.org/html/rfc9142" target="_blank">RFC 9142</a>,
Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)
There are also drafts that are being currently developed and followed.
- <a href="https://tools.ietf.org/html/draft-miller-ssh-agent-03" target="_blank">draft-miller-ssh-agent-08</a>
- <a href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-kex-sha2-10" target="_blank">draft-ietf-curdle-ssh-kex-sha2-10</a>
Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH)
- <a href="https://tools.ietf.org/html/draft-miller-ssh-agent-03" target="_blank">draft-miller-ssh-agent-03</a>
SSH Agent Protocol
- <a href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-12" target="_blank">draft-ietf-curdle-ssh-curves-12</a>
Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448
Interesting cryptography documents:

View File

@@ -1,86 +0,0 @@
/**
@page libssh_tutor_pkcs11 Chapter 9: Authentication using PKCS #11 URIs
@section how_to How to use PKCS #11 URIs in libssh?
PKCS #11 is a Cryptographic Token Interface Standard that provides an API
to devices like smart cards that store cryptographic private information.
Such cryptographic devices are referenced as tokens. A mechanism through which
objects stored on the tokens can be uniquely identified is called PKCS #11 URI
(Uniform Resource Identifier) and is defined in RFC 7512
(https://tools.ietf.org/html/rfc7512).
# Pre-requisites (OpenSSL < 3.0):
OpenSSL 1.x defines an abstract layer called the "engine" to achieve
cryptographic acceleration. The engine_pkcs11 module acts like an interface
between the PKCS #11 modules and the OpenSSL application.
To build and use libssh with PKCS #11 support:
1. Enable the cmake option: $ cmake -DWITH_PKCS11_URI=ON
2. Build with OpenSSL.
3. Install and configure engine_pkcs11 (https://github.com/OpenSC/libp11).
4. Plug in a working smart card or configure softhsm (https://www.opendnssec.org/softhsm).
@warning The support for Engines was deprecated in OpenSSL 3.0 so this approach
is deprecated in libssh 0.11.x.
# Pre-requisites (OpenSSL 3.0.8+)
The OpenSSL 3.0 is deprecating usage of low-level engines in favor of high-level
"providers" to provide alternative implementation of cryptographic operations
or acceleration.
To build and use libssh with PKCS #11 support using OpenSSL providers:
1. Install and configure pkcs11 provider (https://github.com/latchset/pkcs11-provider).
2. Enable the cmake options: $ cmake -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
3. Build with OpenSSL.
4. Plug in a working smart card or configure softhsm (https://www.opendnssec.org/softhsm).
# New API functions
The functions ssh_pki_import_pubkey_file() and ssh_pki_import_privkey_file() that
import the public and private keys from files respectively are now modified to support
PKCS #11 URIs. These functions automatically detect if the provided filename is a file path
or a PKCS #11 URI (when it begins with "pkcs11:"). If a PKCS #11 URI is detected,
the engine is loaded and initialized. Through the engine, the private/public key
corresponding to the PKCS #11 URI are loaded from the PKCS #11 device.
If you wish to authenticate using public keys on your own, follow the steps mentioned under
"Authentication with public keys" in Chapter 2 - A deeper insight into authentication.
The function pki_uri_import() is used to populate the public/private ssh_key from the
engine with PKCS #11 URIs as the look up.
Here is a minimalistic example of public key authentication using PKCS #11 URIs:
@code
int authenticate_pkcs11_URI(ssh_session session)
{
int rc;
char priv_uri[1042] = "pkcs11:token=my-token;object=my-object;type=private?pin-value=1234";
rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, priv_uri);
assert_int_equal(rc, SSH_OK)
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
if (rc == SSH_AUTH_ERROR)
{
fprintf(stderr, "Authentication with PKCS #11 URIs failed: %s\n",
ssh_get_error(session));
return SSH_AUTH_ERROR;
}
return rc;
}
@endcode
@subsection Caveats
We recommend the users to provide a specific PKCS #11 URI so that it matches only a single slot in the engine.
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.
For testing, the SoftHSM PKCS#11 library is used.
*/

View File

@@ -139,7 +139,7 @@ Unlike its equivalent in the SCP subsystem, this function does NOT change the
current directory to the newly created subdirectory.
@subsection sftp_write Writing to a file on the remote computer
@subsection sftp_write Copying a file to the remote computer
You handle the contents of a remote file just like you would do with a
local file: you open the file in a given mode, move the file pointer in it,
@@ -203,14 +203,16 @@ int sftp_helloworld(ssh_session session, sftp_session sftp)
@subsection sftp_read Reading a file from the remote computer
A synchronous read from a remote file is done using sftp_read(). This
section describes how to download a remote file using sftp_read(). The
next section will discuss more about synchronous/asynchronous read/write
operations using libssh sftp API.
The nice thing with reading a file over the network through SFTP is that it
can be done both in a synchronous way or an asynchronous way. If you read the file
asynchronously, your program can do something else while it waits for the
results to come.
Synchronous read is done with sftp_read().
Files are normally transferred in chunks. A good chunk size is 16 KB. The following
example transfers the remote file "/etc/profile" in 16 KB chunks. For each chunk we
request, sftp_read() blocks till the data has been received:
request, sftp_read blocks till the data has been received:
@code
// Good chunk size
@@ -271,39 +273,87 @@ int sftp_read_sync(ssh_session session, sftp_session sftp)
}
@endcode
@subsection sftp_aio Performing an asynchronous read/write on a file on the remote computer
Asynchronous read is done in two steps, first sftp_async_read_begin(), which
returns a "request handle", and then sftp_async_read(), which uses that request handle.
If the file has been opened in nonblocking mode, then sftp_async_read()
might return SSH_AGAIN, which means that the request hasn't completed yet
and that the function should be called again later on. Otherwise,
sftp_async_read() waits for the data to come. To open a file in nonblocking mode,
call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode.
sftp_read() performs a "synchronous" read operation on a remote file.
This means that sftp_read() will first request the server to read some
data from the remote file and then would wait until the server response
containing data to read (or an error) arrives at the client side.
The example below reads a very big file in asynchronous, nonblocking, mode. Each
time the data is not ready yet, a counter is incremented.
sftp_write() performs a "synchronous" write operation on a remote file.
This means that sftp_write() will first request the server to write some
data to the remote file and then would wait until the server response
containing information about the status of the write operation arrives at the
client side.
@code
// Good chunk size
#define MAX_XFER_BUF_SIZE 16384
If your client program wants to do something other than waiting for the
response after requesting a read/write, the synchronous sftp_read() and
sftp_write() can't be used. In such a case the "asynchronous" sftp aio API
should be used.
int sftp_read_async(ssh_session session, sftp_session sftp)
{
int access_type;
sftp_file file;
char buffer[MAX_XFER_BUF_SIZE];
int async_request;
int nbytes;
long counter;
int rc;
Please go through @ref libssh_tutor_sftp_aio for a detailed description
of the sftp aio API.
access_type = O_RDONLY;
file = sftp_open(sftp, "some_very_big_file",
access_type, 0);
if (file == NULL) {
fprintf(stderr, "Can't open file for reading: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
sftp_file_set_nonblocking(file);
The sftp aio API provides two categories of functions :
- sftp_aio_begin_*() : For requesting a read/write from the server.
- sftp_aio_wait_*() : For waiting for the response of a previously
issued read/write request from the server.
async_request = sftp_async_read_begin(file, sizeof(buffer));
counter = 0L;
usleep(10000);
if (async_request >= 0) {
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
async_request);
} else {
nbytes = -1;
}
Hence, the client program can call sftp_aio_begin_*() to request a read/write
and then can perform any number of operations (other than waiting) before
calling sftp_aio_wait_*() for waiting for the response of the previously
issued request.
while (nbytes > 0 || nbytes == SSH_AGAIN) {
if (nbytes > 0) {
write(1, buffer, nbytes);
async_request = sftp_async_read_begin(file, sizeof(buffer));
} else {
counter++;
}
usleep(10000);
We call read/write operations performed in the manner described above as
"asynchronous" read/write operations on a remote file.
if (async_request >= 0) {
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
async_request);
} else {
nbytes = -1;
}
}
if (nbytes < 0) {
fprintf(stderr, "Error while reading file: %s\n",
ssh_get_error(session));
sftp_close(file);
return SSH_ERROR;
}
printf("The counter has reached value: %ld\n", counter);
rc = sftp_close(file);
if (rc != SSH_OK) {
fprintf(stderr, "Can't close the read file: %s\n",
ssh_get_error(session));
return rc;
}
return SSH_OK;
}
@endcode
@subsection sftp_ls Listing the contents of a directory

View File

@@ -1,705 +0,0 @@
/**
@page libssh_tutor_sftp_aio Chapter 10: The SFTP asynchronous I/O
@section sftp_aio_api The SFTP asynchronous I/O
NOTE : Please read @ref libssh_tutor_sftp before reading this page. The
synchronous sftp_read() and sftp_write() have been described there.
SFTP AIO stands for "SFTP Asynchronous Input/Output". This API contains
functions which perform async read/write operations on remote files.
File transfers performed using the asynchronous sftp aio API can be
significantly faster than the file transfers performed using the synchronous
sftp read/write API (see sftp_read() and sftp_write()).
The sftp aio API functions are divided into two categories :
- sftp_aio_begin_*() [see sftp_aio_begin_read(), sftp_aio_begin_write()]:
These functions send a request for an i/o operation to the server and
provide the caller an sftp aio handle corresponding to the sent request.
- sftp_aio_wait_*() [see sftp_aio_wait_read(), sftp_aio_wait_write()]:
These functions wait for the server response corresponding to a previously
issued request. Which request ? the request corresponding to the sftp aio
handle supplied by the caller to these functions.
Conceptually, you can think of the sftp aio handle as a request identifier.
Technically, the sftp_aio_begin_*() functions dynamically allocate memory to
store information about the i/o request they send and provide the caller a
handle to this memory, we call this handle an sftp aio handle.
sftp_aio_wait_*() functions use the information stored in that memory (handled
by the caller supplied sftp aio handle) to identify a request, and then they
wait for that request's response. These functions also release the memory
handled by the caller supplied sftp aio handle (except when they return
SSH_AGAIN).
sftp_aio_free() can also be used to release the memory handled by an sftp aio
handle but unlike the sftp_aio_wait_*() functions, it doesn't wait for a
response. This should be used to release the memory corresponding to an sftp
aio handle when some failure occurs. An example has been provided at the
end of this page to show the usage of sftp_aio_free().
To begin with, this tutorial will provide basic examples that describe the
usage of sftp aio API to perform a single read/write operation.
The later sections describe the usage of the sftp aio API to obtain faster file
transfers as compared to the transfers performed using the synchronous sftp
read/write API.
On encountering an error, the sftp aio API functions set the sftp and ssh
errors just like any other libssh sftp API function. These errors can be
obtained using sftp_get_error(), ssh_get_error() and ssh_get_error_code().
The code examples provided on this page ignore error handling for the sake of
brevity.
@subsection sftp_aio_read Using the sftp aio API for reading (a basic example)
For performing an async read operation on a sftp file (see sftp_open()),
the first step is to call sftp_aio_begin_read() to send a read request to the
server. The caller is provided an sftp aio handle corresponding to the sent
read request.
The second step is to pass a pointer to this aio handle to
sftp_aio_wait_read(), this function waits for the server response which
indicates the success/failure of the read request. On success, the response
indicates EOF or contains the data read from the sftp file.
The following code example shows how a read operation can be performed
on an sftp file using the sftp aio API.
@code
ssize_t read_chunk(sftp_file file, void *buf, size_t to_read)
{
ssize_t bytes_requested, bytes_read;
// Variable to store an sftp aio handle
sftp_aio aio = NULL;
// Send a read request to the sftp server
bytes_requested = sftp_aio_begin_read(file, to_read, &aio);
if (bytes_requested == SSH_ERROR) {
// handle error
}
// Here its possible that (bytes_requested < to_read) as specified in
// the function documentation of sftp_aio_begin_read()
// Wait for the response of the read request corresponding to the
// sftp aio handle stored in the aio variable.
bytes_read = sftp_aio_wait_read(&aio, buf, to_read);
if (bytes_read == SSH_ERROR) {
// handle error
}
return bytes_read;
}
@endcode
@subsection sftp_aio_write Using the sftp aio API for writing (a basic example)
For performing an async write operation on a sftp file (see sftp_open()),
the first step is to call sftp_aio_begin_write() to send a write request to
the server. The caller is provided an sftp aio handle corresponding to the
sent write request.
The second step is to pass a pointer to this aio handle to
sftp_aio_wait_write(), this function waits for the server response which
indicates the success/failure of the write request.
The following code example shows how a write operation can be performed on an
sftp file using the sftp aio API.
@code
ssize_t write_chunk(sftp_file file, void *buf, size_t to_write)
{
ssize_t bytes_requested, bytes_written;
// Variable to store an sftp aio handle
sftp_aio aio = NULL;
// Send a write request to the sftp server
bytes_requested = sftp_aio_begin_write(file, buf, to_write, &aio);
if (bytes_requested == SSH_ERROR) {
// handle error
}
// Here its possible that (bytes_requested < to_write) as specified in
// the function documentation of sftp_aio_begin_write()
// Wait for the response of the write request corresponding to
// the sftp aio handle stored in the aio variable.
bytes_written = sftp_aio_wait_write(&aio);
if (bytes_written == SSH_ERROR) {
// handle error
}
return bytes_written;
}
@endcode
@subsection sftp_aio_actual_use Using the sftp aio API to speed up a transfer
The above examples were provided to introduce the sftp aio API.
This is not how the sftp aio API is intended to be used, because the
above usage offers no advantage over the synchronous sftp read/write API
which does the same thing i.e issue a request and then immediately wait for
its response.
The facility that the sftp aio API provides is that the user can do
anything between issuing a request and getting the corresponding response.
Any number of operations can be performed after calling sftp_aio_begin_*()
[which issues a request] and before calling sftp_aio_wait_*() [which waits
for a response]
The code can leverage this feature by calling sftp_aio_begin_*() multiple times
to issue multiple requests before calling sftp_aio_wait_*() to wait for the
response of an earlier issued request. This approach will keep a certain number
of requests outstanding at the client side.
After issuing those requests, while the client code does something else (for
example waiting for an outstanding request's response, processing an obtained
response, issuing another request or any other operation the client wants
to perform), at the same time :
- Some of those outstanding requests may be travelling over the
network towards the server.
- Some of the outstanding requests may have reached the server and may
be queued for processing at the server side.
- Some of the outstanding requests may have been processed and the
corresponding responses may be travelling over the network towards the
client.
- Some of the responses corresponding to the outstanding requests may
have already reached the client side.
Clearly in this case, operations that the client performs and operations
involved in transfer/processing of a outstanding request can occur in
parallel. Also, operations involved in transfer/processing of two or more
outstanding requests may also occur in parallel (for example when one request
travels to the server, another request's response may be incoming towards the
client). Such kind of parallelism makes the overall transfer faster as compared
to a transfer performed using the synchronous sftp read/write API.
When the synchronous sftp read/write API is used to perform a transfer,
a strict sequence is followed:
- The client issues a single read/write request.
- Then waits for its response.
- On obtaining the response, the client processes it.
- After the processing ends, the client issues the next read/write request.
A file transfer performed in this manner would be slower than the case where
multiple read/write requests are kept outstanding at the client side. Because
here at any given time, operations related to transfer/processing of only one
request/response pair occurs. This is in contrast to the multiple outstanding
requests scenario where operations related to transfer/processing of multiple
request/response pairs may occur at the same time.
Although it's true that keeping multiple requests outstanding can speed up a
transfer, those outstanding requests come at a cost of increased memory
consumption both at the client side and the server side. Hence care must be
taken to use a reasonable limit for the number of requests kept outstanding.
The further sections provide code examples to show how uploads/downloads
can be performed using the sftp aio API and the concept of outstanding requests
discussed in this section. In those code examples, error handling has been
ignored and at some places pseudo code has been used for the sake of brevity.
The complete code for performing uploads/downloads using the sftp aio API,
can be found at https://gitlab.com/libssh/libssh-mirror/-/tree/master.
- libssh benchmarks for uploads performed using the sftp aio API [See
tests/benchmarks/bench_sftp.c]
- libssh benchmarks for downloads performed using the sftp aio API. [See
tests/benchmarks/bench_sftp.c]
- libssh sftp ft API code for performing a local to remote transfer (upload).
[See src/sftp_ft.c]
- libssh sftp ft API code for performing a remote to local transfer
(download). [See src/sftp_ft.c]
@subsection sftp_aio_cap Capping applied by the sftp aio API
Before the code examples for uploads and downloads, its important
to know about the capping applied by the sftp aio API.
sftp_aio_begin_read() caps the number of bytes the caller can request
to read from the remote file. That cap is the value of the max_read_length
field of the sftp_limits_t returned by sftp_limits(). Say that cap is LIM
and the caller passes x as the number of bytes to read to
sftp_aio_begin_read(), then (assuming no error occurs) :
- if x <= LIM, then sftp_aio_begin_read() will request the server
to read x bytes from the remote file, and will return x.
- if x > LIM, then sftp_aio_begin_read() will request the server
to read LIM bytes from the remote file and will return LIM.
Hence to request server to read x bytes (> LIM), the caller would have
to call sftp_aio_begin_read() multiple times, typically in a loop and
break out of the loop when the summation of return values of the multiple
sftp_aio_begin_read() calls becomes equal to x.
For the sake of simplicity, the code example for download in the upcoming
section would always ask sftp_aio_begin_read() to read x <= LIM bytes,
so that its return value is guaranteed to be x, unless an error occurs.
Similarly, sftp_aio_begin_write() caps the number of bytes the caller
can request to write to the remote file. That cap is the value of
max_write_length field of the sftp_limits_t returned by sftp_limits().
Say that cap is LIM and the caller passes x as the number of bytes to
write to sftp_aio_begin_write(), then (assuming no error occurs) :
- if x <= LIM, then sftp_aio_begin_write() will request the server
to write x bytes to the remote file, and will return x.
- if x > LIM, then sftp_aio_begin_write() will request the server
to write LIM bytes to the remote file and will return LIM.
Hence to request server to write x bytes (> LIM), the caller would have
to call sftp_aio_begin_write() multiple times, typically in a loop and
break out of the loop when the summation of return values of the multiple
sftp_aio_begin_write() calls becomes equal to x.
For the sake of simplicity, the code example for upload in the upcoming
section would always ask sftp_aio_begin_write() to write x <= LIM bytes,
so that its return value is guaranteed to be x, unless an error occurs.
@subsection sftp_aio_download_example Performing a download using the sftp aio API
Terminologies used in the following code snippets :
- sftp : The sftp_session opened using sftp_new() and initialised using
sftp_init()
- file : The sftp file handle of the remote file to download data
from. (See sftp_open())
- file_size : the size of the sftp file to download. This size can be obtained
by statting the remote file to download (e.g by using sftp_stat())
- We will need to maintain a queue which will be used to store the sftp aio
handles corresponding to the outstanding requests.
First, we issue the read requests while ensuring that their count
doesn't exceed a particular limit decided by us, and the number of bytes
requested don't exceed the size of the file to download.
@code
sftp_aio aio = NULL;
// Chunk size to use for the transfer
size_t chunk_size;
// For the limits structure that would be used
// by the code to set the chunk size
sftp_limits_t lim = NULL;
// Max number of requests to keep outstanding at a time
size_t in_flight_requests = 5;
// Number of bytes for which requests have been sent
size_t total_bytes_requested = 0;
// Number of bytes which have been downloaded
size_t bytes_downloaded = 0;
// Buffer to use for the download
char *buffer = NULL;
// Helper variables
size_t to_read;
ssize_t bytes_requested;
// Get the sftp limits
lim = sftp_limits(sftp);
if (lim == NULL) {
// handle error
}
// Set the chunk size for download = the max limit for reading
// The reason for this has been given in the "Capping applied by
// the sftp aio API" section (Its to make the code simpler)
//
// Assigning a size_t type variable a uint64_t type value here,
// theoretically could cause an overflow, but practically
// max_read_length would never exceed SIZE_MAX so its okay.
chunk_size = lim->max_read_length;
buffer = malloc(chunk_size);
if (buffer == NULL) {
// handle error
}
... // Code to open the remote file (to download) using sftp_open().
... // Code to stat the remote file's file size.
... // Code to open the local file in which downloaded data is to be stored.
... // Code to initialize the queue which will be used to store sftp aio
// handles.
for (i = 0;
i < in_flight_requests && total_bytes_requested < file_size;
++i) {
to_read = file_size - total_bytes_requested;
if (to_read > chunk_size) {
to_read = chunk_size;
}
// Issue a read request
bytes_requested = sftp_aio_begin_read(file, to_read, &aio);
if (bytes_requested == SSH_ERROR) {
// handle error
}
if ((size_t)bytes_requested < to_read) {
// Should not happen for this code, as the to_read is <=
// max limit for reading (chunk size), so there is no reason
// for sftp_aio_begin_read() to return a lesser value.
}
total_bytes_requested += (size_t)bytes_requested;
// Pseudo code
ENQUEUE aio in the queue;
}
@endcode
At this point, at max in_flight_requests number of requests may be
outstanding. Now we wait for the response corresponding to the earliest
issued outstanding request.
On getting that response, we issue another read request if there are
still some bytes in the sftp file (to download) for which we haven't sent the
read request. (This happens when total_bytes_requested < file_size)
This issuing of another read request (under a condition) is done to
keep the number of outstanding requests equal to the value of the
in_flight_requests variable.
This process has to be repeated for every remaining outstanding request.
@code
while (the queue is not empty) {
// Pseudo code
aio = DEQUEUE an sftp aio handle from the queue of sftp aio handles;
// Wait for the response of the request corresponding to the aio
bytes_read = sftp_aio_wait_read(&aio, buffer, chunk_size);
if (bytes_read == SSH_ERROR) {
//handle error
}
bytes_downloaded += bytes_read;
if (bytes_read != chunk_size && bytes_downloaded != file_size) {
// A short read encountered on the remote file before reaching EOF,
// short read before reaching EOF should never happen for the sftp aio
// API which respects the max limit for reading. This probably
// indicates a bad server.
}
// Pseudo code
WRITE bytes_read bytes from the buffer into the local file
in which downloaded data is to be stored ;
if (total_bytes_requested == file_size) {
// no need to issue more read requests
continue;
}
// else issue a read request
to_read = file_size - total_bytes_requested;
if (to_read > chunk_size) {
to_read = chunk_size;
}
bytes_requested = sftp_aio_begin_read(file, to_read, &aio);
if (bytes_requested == SSH_ERROR) {
// handle error
}
if ((size_t)bytes_requested < to_read) {
// Should not happen for this code, as the to_read is <=
// max limit for reading (chunk size), so there is no reason
// for sftp_aio_begin_read() to return a lesser value.
}
total_bytes_requested += bytes_requested;
// Pseudo code
ENQUEUE aio in the queue;
}
free(buffer);
sftp_limits_free(lim);
... // Code to destroy the queue which was used to store the sftp aio
// handles.
@endcode
After exiting the while (the queue is not empty) loop, the download
would've been complete (assuming no error occurs).
@subsection sftp_aio_upload_example Performing an upload using the sftp aio API
Terminologies used in the following code snippets :
- sftp : The sftp_session opened using sftp_new() and initialised using
sftp_init()
- file : The sftp file handle of the remote file in which uploaded data
is to be stored. (See sftp_open())
- file_size : The size of the local file to upload. This size can be
obtained by statting the local file to upload (e.g by using stat())
- We will need maintain a queue which will be used to store the sftp aio
handles corresponding to the outstanding requests.
First, we issue the write requests while ensuring that their count
doesn't exceed a particular limit decided by us, and the number of bytes
requested to write don't exceed the size of the file to upload.
@code
sftp_aio aio = NULL;
// The chunk size to use for the transfer
size_t chunk_size;
// For the limits structure that would be used by
// the code to set the chunk size
sftp_limits_t lim = NULL;
// Max number of requests to keep outstanding at a time
size_t in_flight_requests = 5;
// Total number of bytes for which write requests have been sent
size_t total_bytes_requested = 0;
// Buffer to use for the upload
char *buffer = NULL;
// Helper variables
size_t to_write;
ssize_t bytes_requested;
// Get the sftp limits
lim = sftp_limits(sftp);
if (lim == NULL) {
// handle error
}
// Set the chunk size for upload = the max limit for writing.
// The reason for this has been given in the "Capping applied by
// the sftp aio API" section (Its to make the code simpler)
//
// Assigning a size_t type variable a uint64_t type value here,
// theoretically could cause an overflow, but practically
// max_write_length would never exceed SIZE_MAX so its okay.
chunk_size = lim->max_write_length;
buffer = malloc(chunk_size);
if (buffer == NULL) {
// handle error
}
... // Code to open the local file (to upload) [e.g using open(), fopen()].
... // Code to stat the local file's file size [e.g using stat()].
... // Code to open the remote file in which uploaded data will be stored [see
// sftp_open()].
... // Code to initialize the queue which will be used to store sftp aio
// handles.
for (i = 0;
i < in_flight_requests && total_bytes_requested < file_size;
++i) {
to_write = file_size - total_bytes_requested;
if (to_write > chunk_size) {
to_write = chunk_size;
}
// Pseudo code
READ to_write bytes from the local file (to upload) into the buffer;
bytes_requested = sftp_aio_begin_write(file, buffer, to_write, &aio);
if (bytes_requested == SSH_ERROR) {
// handle error
}
if ((size_t)bytes_requested < to_write) {
// Should not happen for this code, as the to_write is <=
// max limit for writing (chunk size), so there is no reason
// for sftp_aio_begin_write() to return a lesser value.
}
total_bytes_requested += (size_t)bytes_requested;
// Pseudo code
ENQUEUE aio in the queue;
}
@endcode
At this point, at max in_flight_requests number of requests may be
outstanding. Now we wait for the response corresponding to the earliest
issued outstanding request.
On getting that response, we issue another write request if there are
still some bytes in the local file (to upload) for which we haven't sent
the write request. (This happens when total_bytes_requested < file_size)
This issuing of another write request (under a condition) is done to
keep the number of outstanding requests equal to the value of the
in_flight_requests variable.
This process has to be repeated for every remaining outstanding request.
@code
while (the queue is not empty) {
// Pseudo code
aio = DEQUEUE an sftp aio handle from the queue of sftp aio handles;
// Wait for the response of the request corresponding to the aio
bytes_written = sftp_aio_wait_write(&aio);
if (bytes_written == SSH_ERROR) {
// handle error
}
// sftp_aio_wait_write() won't report a short write, so no need
// to check for a short write here.
if (total_bytes_requested == file_size) {
// no need to issue more write requests
continue;
}
// else issue a write request
to_write = file_size - total_bytes_requested;
if (to_write > chunk_size) {
to_write = chunk_size;
}
// Pseudo code
READ to_write bytes from the local file (to upload) into a buffer;
bytes_requested = sftp_aio_begin_write(file, buffer, to_write, &aio);
if (bytes_requested == SSH_ERROR) {
// handle error
}
if ((size_t)bytes_requested < to_write) {
// Should not happen for this code, as the to_write is <=
// max limit for writing (chunk size), so there is no reason
// for sftp_aio_begin_write() to return a lesser value.
}
total_bytes_requested += (size_t)bytes_requested;
// Pseudo code
ENQUEUE aio in the queue;
}
free(buffer);
... // Code to destroy the queue which was used to store the sftp aio
// handles.
@endcode
After exiting the while (the queue is not empty) loop, the upload
would've been complete (assuming no error occurs).
@subsection sftp_aio_free Example showing the usage of sftp_aio_free()
The purpose of sftp_aio_free() was discussed at the beginning of this page,
the following code example shows how it can be used during cleanup.
@code
void print_sftp_error(sftp_session sftp)
{
if (sftp == NULL) {
return;
}
fprintf(stderr, "sftp error : %d\n", sftp_get_error(sftp));
fprintf(stderr, "ssh error : %s\n", ssh_get_error(sftp->session));
}
// Returns 0 on success, -1 on error
int write_strings(sftp_file file)
{
const char * strings[] = {
"This is the first string",
"This is the second string",
"This is the third string",
"This is the fourth string"
};
size_t string_count = sizeof(strings) / sizeof(strings[0]);
size_t i;
sftp_session sftp = NULL;
sftp_aio aio = NULL;
int rc;
if (file == NULL) {
return -1;
}
... // Code to initialize the queue which will be used to store sftp aio
// handles
sftp = file->sftp;
for (i = 0; i < string_count; ++i) {
rc = sftp_aio_begin_write(file,
strings[i],
strlen(strings[i]),
&aio);
if (rc == SSH_ERROR) {
print_sftp_error(sftp);
goto err;
}
// Pseudo code
ENQUEUE aio in the queue of sftp aio handles
}
for (i = 0; i < string_count; ++i) {
// Pseudo code
aio = DEQUEUE an sftp aio handle from the queue of sftp aio handles;
rc = sftp_aio_wait_write(&aio);
if (rc == SSH_ERROR) {
print_sftp_error(sftp);
goto err;
}
}
... // Code to destroy the queue in which sftp aio handles were
// stored
return 0;
err:
while (queue is not empty) {
// Pseudo code
aio = DEQUEUE an sftp aio handle from the queue of sftp aio handles;
sftp_aio_free(aio);
}
... // Code to destroy the queue in which sftp aio handles were
// stored.
return -1;
}
@endcode
*/

View File

@@ -26,7 +26,7 @@ The code sample below achieves these tasks:
@code
int shell_session(ssh_session session)
{
ssh_channel channel = NULL;
ssh_channel channel;
int rc;
channel = ssh_channel_new(session);
@@ -65,17 +65,8 @@ to as a "pty", for "pseudo-teletype". The remote processes won't see the
difference with a real text-oriented terminal.
If needed, you request the pty with the function ssh_channel_request_pty().
If you want define its dimensions (number of rows and columns),
call ssh_channel_request_pty_size() instead. It's also possible to change
the dimensions after creating the pty with ssh_channel_change_pty_size().
These two functions configure the pty using the same terminal modes that
stdin has. If stdin isn't a TTY, they use default modes that configure
the pty with in canonical mode and e.g. preserving CR and LF characters.
If you want to change the terminal modes used by the pty (e.g. to change
CRLF handling), use ssh_channel_request_pty_size_modes(). This function
accepts an additional "modes" buffer that is expected to contain encoded
terminal modes according to RFC 4254 section 8.
Then you define its dimensions (number of rows and columns)
with ssh_channel_change_pty_size().
Be your session interactive or not, the next step is to request a
shell with ssh_channel_request_shell().
@@ -329,36 +320,18 @@ int interactive_shell_session(ssh_session session, ssh_channel channel)
If your remote application is graphical, you can forward the X11 protocol to
your local computer.
To do that, you first declare a callback to manage channel_open_request_x11_function.
Then you create the forwarding tunnel for the X11 protocol with ssh_channel_request_x11().
To do that, you first declare that you accept X11 connections with
ssh_channel_accept_x11(). Then you create the forwarding tunnel for
the X11 protocol with ssh_channel_request_x11().
The following code performs channel initialization and shell session
opening, and handles a parallel X11 connection:
@code
#include <libssh/callbacks.h>
ssh_channel x11channel = NULL;
ssh_channel x11_open_request_callback(ssh_session session, const char *shost, int sport, void *userdata)
{
x11channel = ssh_channel_new(session);
return x11channel;
}
int interactive_shell_session(ssh_channel channel)
{
int rc;
struct ssh_callbacks_struct cb =
{
.channel_open_request_x11_function = x11_open_request_callback,
.userdata = NULL
};
ssh_callbacks_init(&cb);
rc = ssh_set_callbacks(session, &cb);
if (rc != SSH_OK) return rc;
ssh_channel x11channel;
rc = ssh_channel_request_pty(channel);
if (rc != SSH_OK) return rc;
@@ -377,15 +350,12 @@ int interactive_shell_session(ssh_channel channel)
}
@endcode
Don't forget to check the $DISPLAY environment variable on the remote
Don't forget to set the $DISPLAY environment variable on the remote
side, or the remote applications won't try using the X11 tunnel:
@code
$ echo $DISPLAY
localhost:10.0
$ export DISPLAY=:0
$ xclock &
@endcode
See an implementation example at https://gitlab.com/libssh/libssh-mirror/-/tree/master/examples/ssh_X11_client.c for details.
*/

View File

@@ -303,6 +303,7 @@ span.lineno {
padding-right: 4px;
text-align: right;
color: black;
height: 100px;
white-space: pre;
border-right: 3px solid #1d7567;
background-color: #323232; }

View File

@@ -29,63 +29,40 @@ if (UNIX AND NOT WIN32)
add_executable(samplesftp samplesftp.c ${examples_SRCS})
target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesftp ssh::ssh)
if (WITH_SERVER)
add_executable(sample_sftpserver sample_sftpserver.c ${examples_SRCS})
target_compile_options(sample_sftpserver PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(sample_sftpserver ssh::ssh ${ARGP_LIBRARIES})
endif (WITH_SERVER)
endif (WITH_SFTP)
add_executable(ssh-client ssh_client.c ${examples_SRCS})
target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh-client ssh::ssh)
add_executable(ssh-X11-client ssh_X11_client.c ${examples_SRCS})
target_compile_options(ssh-X11-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh-X11-client ssh::ssh)
if (WITH_SERVER AND (ARGP_LIBRARIES OR HAVE_ARGP_H))
if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H))
if (HAVE_LIBUTIL)
add_executable(ssh_server_fork ssh_server.c)
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS} -DWITH_FORK)
target_link_libraries(ssh_server_fork ssh::ssh ${ARGP_LIBRARIES} util)
add_executable(ssh_server_pthread ssh_server.c)
target_compile_options(ssh_server_pthread PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh_server_pthread ssh::ssh ${ARGP_LIBRARIES} pthread util)
add_executable(ssh_server_fork ssh_server_fork.c)
target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(ssh_server_fork ssh::ssh ${ARGP_LIBRARY} util)
endif (HAVE_LIBUTIL)
if (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-cb samplesshd-cb.c)
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-cb ssh::ssh ${ARGP_LIBRARY})
add_executable(proxy proxy.c)
target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(proxy ssh::ssh ${ARGP_LIBRARIES})
target_link_libraries(proxy ssh::ssh ${ARGP_LIBRARY})
add_executable(sshd_direct-tcpip sshd_direct-tcpip.c)
target_compile_options(sshd_direct-tcpip PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(sshd_direct-tcpip ssh::ssh ${ARGP_LIBRARIES})
target_link_libraries(sshd_direct-tcpip ssh::ssh ${ARGP_LIBRARY})
endif (WITH_GSSAPI AND GSSAPI_FOUND)
add_executable(samplesshd-kbdint samplesshd-kbdint.c)
target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-kbdint ssh::ssh ${ARGP_LIBRARIES})
add_executable(keygen2 keygen2.c ${examples_SRCS})
target_compile_options(keygen2 PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(keygen2 ssh::ssh ${ARGP_LIBRARIES})
target_link_libraries(samplesshd-kbdint ssh::ssh ${ARGP_LIBRARY})
endif()
endif (UNIX AND NOT WIN32)
if (WITH_SERVER)
add_executable(samplesshd-cb samplesshd-cb.c)
target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(samplesshd-cb ssh::ssh)
if (ARGP_LIBRARIES OR HAVE_ARGP_H)
target_link_libraries(samplesshd-cb ${ARGP_LIBRARIES})
endif(ARGP_LIBRARIES OR HAVE_ARGP_H)
endif()
add_executable(exec exec.c ${examples_SRCS})
target_compile_options(exec PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(exec ssh::ssh)

View File

@@ -30,8 +30,8 @@ int authenticate_kbdint(ssh_session session, const char *password)
err = ssh_userauth_kbdint(session, NULL, NULL);
while (err == SSH_AUTH_INFO) {
const char *instruction = NULL;
const char *name = NULL;
const char *instruction;
const char *name;
char buffer[128];
int i, n;
@@ -48,8 +48,8 @@ int authenticate_kbdint(ssh_session session, const char *password)
}
for (i = 0; i < n; i++) {
const char *answer = NULL;
const char *prompt = NULL;
const char *answer;
const char *prompt;
char echo;
prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
@@ -58,7 +58,7 @@ int authenticate_kbdint(ssh_session session, const char *password)
}
if (echo) {
char *p = NULL;
char *p;
printf("%s", prompt);
@@ -66,6 +66,7 @@ int authenticate_kbdint(ssh_session session, const char *password)
return SSH_AUTH_ERROR;
}
buffer[sizeof(buffer) - 1] = '\0';
if ((p = strchr(buffer, '\n'))) {
*p = '\0';
}
@@ -74,7 +75,7 @@ int authenticate_kbdint(ssh_session session, const char *password)
return SSH_AUTH_ERROR;
}
memset(buffer, 0, sizeof(buffer));
memset(buffer, 0, strlen(buffer));
} else {
if (password && strstr(prompt, "Password:")) {
answer = password;
@@ -142,11 +143,11 @@ int authenticate_console(ssh_session session)
int rc;
int method;
char password[128] = {0};
char *banner = NULL;
char *banner;
// Try to authenticate
rc = ssh_userauth_none(session, NULL);
if (rc == SSH_AUTH_ERROR || !ssh_is_connected(session)) {
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
}
@@ -155,7 +156,7 @@ int authenticate_console(ssh_session session)
while (rc != SSH_AUTH_SUCCESS) {
if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
rc = ssh_userauth_gssapi(session);
if (rc == SSH_AUTH_ERROR || !ssh_is_connected(session)) {
if(rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
@@ -165,7 +166,7 @@ int authenticate_console(ssh_session session)
// Try to authenticate with public key first
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
if (rc == SSH_AUTH_ERROR || !ssh_is_connected(session)) {
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
@@ -205,7 +206,7 @@ int authenticate_console(ssh_session session)
// Try to authenticate with keyboard interactive";
if (method & SSH_AUTH_METHOD_INTERACTIVE) {
rc = authenticate_kbdint(session, NULL);
if (rc == SSH_AUTH_ERROR || !ssh_is_connected(session)) {
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
@@ -220,7 +221,7 @@ int authenticate_console(ssh_session session)
// Try to authenticate with password
if (method & SSH_AUTH_METHOD_PASSWORD) {
rc = ssh_userauth_password(session, NULL, password);
if (rc == SSH_AUTH_ERROR || !ssh_is_connected(session)) {
if (rc == SSH_AUTH_ERROR) {
error(session);
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {

View File

@@ -21,50 +21,47 @@ clients must be made or how a client should react.
#include "examples_common.h"
#include <stdio.h>
ssh_session connect_ssh(const char *host, const char *user, int verbosity)
{
ssh_session session = NULL;
int auth = 0;
ssh_session connect_ssh(const char *host, const char *user,int verbosity){
ssh_session session;
int auth=0;
session = ssh_new();
if (session == NULL) {
return NULL;
}
session=ssh_new();
if (session == NULL) {
return NULL;
}
if (user != NULL) {
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
ssh_free(session);
return NULL;
}
if(user != NULL){
if (ssh_options_set(session, SSH_OPTIONS_USER, user) < 0) {
ssh_free(session);
return NULL;
}
}
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
ssh_free(session);
return NULL;
}
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
if (ssh_connect(session)) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
if (verify_knownhost(session) < 0) {
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
auth = authenticate_console(session);
if (auth == SSH_AUTH_SUCCESS) {
return session;
} else if (auth == SSH_AUTH_DENIED) {
fprintf(stderr, "Authentication failed\n");
} else {
fprintf(stderr,
"Error while authenticating : %s\n",
ssh_get_error(session));
}
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
ssh_free(session);
return NULL;
}
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
if(ssh_connect(session)){
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
if(verify_knownhost(session)<0){
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
auth=authenticate_console(session);
if(auth==SSH_AUTH_SUCCESS){
return session;
} else if(auth==SSH_AUTH_DENIED){
fprintf(stderr,"Authentication failed\n");
} else {
fprintf(stderr,"Error while authenticating : %s\n",ssh_get_error(session));
}
ssh_disconnect(session);
ssh_free(session);
return NULL;
}

View File

@@ -16,7 +16,7 @@ clients must be made or how a client should react.
#include <libssh/libssh.h>
/** Zero a structure */
#define ZERO_STRUCT(x) memset(&(x), 0, sizeof(x))
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
int authenticate_console(ssh_session session);
int authenticate_kbdint(ssh_session session, const char *password);

View File

@@ -5,8 +5,8 @@
#include "examples_common.h"
int main(void) {
ssh_session session = NULL;
ssh_channel channel = NULL;
ssh_session session;
ssh_channel channel;
char buffer[256];
int rbytes, wbytes, total = 0;
int rc;
@@ -17,7 +17,7 @@ int main(void) {
return 1;
}
channel = ssh_channel_new(session);
channel = ssh_channel_new(session);;
if (channel == NULL) {
ssh_disconnect(session);
ssh_free(session);

View File

@@ -27,14 +27,14 @@ int main(void)
rv = ssh_pki_generate(SSH_KEYTYPE_ED25519, 0, &key);
if (rv != SSH_OK) {
fprintf(stderr, "Failed to generate private key");
return -1;
return -1;
}
/* Write it to a file testkey in the current directory */
/* Write it to a file testkey in the current dirrectory */
rv = ssh_pki_export_privkey_file(key, NULL, NULL, NULL, "testkey");
if (rv != SSH_OK) {
fprintf(stderr, "Failed to write private key file");
return -1;
return -1;
}
return 0;

View File

@@ -1,526 +0,0 @@
/*
* keygen2.c - Generate SSH keys using libssh
* Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*/
/*
* Copyright (c) 2019 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
#include "config.h"
#include <libssh/libssh.h>
#include <stdio.h>
#include <stdlib.h>
#include <argp.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
struct arguments_st {
enum ssh_keytypes_e type;
unsigned long bits;
char *file;
char *passphrase;
char *format;
int action_list;
};
static struct argp_option options[] = {
{
.name = "bits",
.key = 'b',
.arg = "BITS",
.flags = 0,
.doc = "The size of the key to be generated. "
"If omitted, a default value is used depending on the TYPE. "
"Accepted values are: "
"1024, 2048, 3072 (default), 4096, and 8192 for TYPE=\"rsa\"; "
"256 (default), 384, and 521 for TYPE=\"ecdsa\"; "
"can be omitted for TYPE=\"ed25519\" "
"(it will be ignored if provided).\n",
.group = 0
},
{
.name = "file",
.key = 'f',
.arg = "FILE",
.flags = 0,
.doc = "The output file. "
"If not provided, the used file name will be generated "
"according to the key type as \"id_TYPE\" "
"(e.g. \"id_rsa\" for type \"rsa\"). "
"The public key file name is generated from the private key "
"file name by appending \".pub\".\n",
.group = 0
},
{
.name = "passphrase",
.key = 'p',
.arg = "PASSPHRASE",
.flags = 0,
.doc = "The passphrase used to encrypt the private key. "
"If omitted the file will not be encrypted.\n",
.group = 0
},
{
.name = "type",
.key = 't',
.arg = "TYPE",
.flags = 0,
.doc = "The type of the key to be generated. "
"Accepted values are: "
"\"rsa\", \"ecdsa\", and \"ed25519\".\n",
.group = 0
},
{
.name = "list",
.key = 'l',
.arg = NULL,
.flags = 0,
.doc = "List the Fingerprint of the given key\n",
.group = 0
},
{
.name = "format",
.key = 'm',
.arg = "FORMAT",
.flags = 0,
.doc = "Write the file in specific format. The supported values are "
"'PEM'and 'OpenSSH' file format. By default Ed25519 "
"keys are exported in OpenSSH format and others in PEM.\n",
.group = 0
},
{
/* End of the options */
0
},
};
/* Parse a single option. */
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure.
*/
struct arguments_st *arguments = NULL;
error_t rc = 0;
if (state == NULL) {
return EINVAL;
}
arguments = state->input;
if (arguments == NULL) {
fprintf(stderr, "Error: NULL pointer to arguments structure "
"provided\n");
rc = EINVAL;
goto end;
}
switch (key) {
case 'b':
errno = 0;
arguments->bits = strtoul(arg, NULL, 10);
if (errno != 0) {
rc = errno;
goto end;
}
break;
case 'f':
arguments->file = strdup(arg);
if (arguments->file == NULL) {
fprintf(stderr, "Error: Out of memory\n");
rc = ENOMEM;
goto end;
}
break;
case 'p':
arguments->passphrase = strdup(arg);
if (arguments->passphrase == NULL) {
fprintf(stderr, "Error: Out of memory\n");
rc = ENOMEM;
goto end;
}
break;
case 't':
if (!strcmp(arg, "rsa")) {
arguments->type = SSH_KEYTYPE_RSA;
}
else if (!strcmp(arg, "ecdsa")) {
arguments->type = SSH_KEYTYPE_ECDSA;
}
else if (!strcmp(arg, "ed25519")) {
arguments->type = SSH_KEYTYPE_ED25519;
}
else {
fprintf(stderr, "Error: Invalid key type\n");
argp_usage(state);
rc = EINVAL;
goto end;
}
break;
case 'l':
arguments->action_list = 1;
break;
case 'm':
arguments->format = strdup(arg);
break;
case ARGP_KEY_ARG:
if (state->arg_num > 0) {
/* Too many arguments. */
printf("Error: Too many arguments\n");
argp_usage(state);
}
break;
case ARGP_KEY_END:
break;
default:
return ARGP_ERR_UNKNOWN;
}
end:
return rc;
}
static int validate_args(struct arguments_st *args)
{
int rc = 0;
if (args == NULL) {
return EINVAL;
}
/* no other arguments needed for listing key fingerprints */
if (args->action_list) {
return 0;
}
switch (args->type) {
case SSH_KEYTYPE_RSA:
switch (args->bits) {
case 0:
/* If not provided, use default value */
args->bits = 3072;
break;
case 1024:
case 2048:
case 3072:
case 4096:
case 8192:
break;
default:
fprintf(stderr, "Error: Invalid bits parameter provided\n");
rc = EINVAL;
break;
}
if (args->file == NULL) {
args->file = strdup("id_rsa");
if (args->file == NULL) {
rc = ENOMEM;
break;
}
}
break;
case SSH_KEYTYPE_ECDSA:
switch (args->bits) {
case 0:
/* If not provided, use default value */
args->bits = 256;
break;
case 256:
case 384:
case 521:
break;
default:
fprintf(stderr, "Error: Invalid bits parameter provided\n");
rc = EINVAL;
break;
}
if (args->file == NULL) {
args->file = strdup("id_ecdsa");
if (args->file == NULL) {
rc = ENOMEM;
break;
}
}
break;
case SSH_KEYTYPE_ED25519:
/* Ignore value and overwrite with a zero */
args->bits = 0;
if (args->file == NULL) {
args->file = strdup("id_ed25519");
if (args->file == NULL) {
rc = ENOMEM;
break;
}
}
break;
default:
fprintf(stderr, "Error: unknown key type\n");
rc = EINVAL;
break;
}
return rc;
}
/* Program documentation. */
static char doc[] = "Generate an SSH key pair. "
"The \"--type\" (short: \"-t\") option is required.";
/* Our argp parser */
static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL};
static void
list_fingerprint(char *file)
{
ssh_key key = NULL;
unsigned char *hash = NULL;
size_t hlen = 0;
int rc;
rc = ssh_pki_import_privkey_file(file, NULL, NULL, NULL, &key);
if (rc != SSH_OK) {
fprintf(stderr, "Failed to import private key %s\n", file);
return;
}
rc = ssh_get_publickey_hash(key, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen);
if (rc != SSH_OK) {
fprintf(stderr, "Failed to get key fingerprint\n");
ssh_key_free(key);
return;
}
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
ssh_clean_pubkey_hash(&hash);
ssh_key_free(key);
}
int main(int argc, char *argv[])
{
ssh_key key = NULL;
int rc = 0;
char overwrite[1024] = "";
char *pubkey_file = NULL;
struct arguments_st arguments = {
.type = SSH_KEYTYPE_UNKNOWN,
.bits = 0,
.file = NULL,
.passphrase = NULL,
.action_list = 0,
};
if (argc < 2) {
argp_help(&argp, stdout, ARGP_HELP_DOC | ARGP_HELP_USAGE, argv[0]);
goto end;
}
rc = argp_parse(&argp, argc, argv, 0, 0, &arguments);
if (rc != 0) {
goto end;
}
rc = validate_args(&arguments);
if (rc != 0) {
goto end;
}
if (arguments.file == NULL) {
fprintf(stderr, "Error: Missing argument file\n");
goto end;
}
if (arguments.action_list) {
list_fingerprint(arguments.file);
goto end;
}
errno = 0;
rc = open(arguments.file, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
if (rc < 0) {
if (errno == EEXIST) {
printf("File \"%s\" exists. Overwrite it? (y|n) ", arguments.file);
rc = scanf("%1023s", overwrite);
if (rc > 0 && tolower(overwrite[0]) == 'y') {
rc = open(arguments.file, O_WRONLY);
if (rc > 0) {
close(rc);
errno = 0;
rc = chmod(arguments.file, S_IRUSR | S_IWUSR);
if (rc != 0) {
fprintf(stderr,
"Error(%d): Could not set file permissions\n",
errno);
goto end;
}
} else {
fprintf(stderr,
"Error: Could not create private key file\n");
goto end;
}
} else {
goto end;
}
} else {
fprintf(stderr, "Error opening \"%s\" file\n", arguments.file);
goto end;
}
} else {
close(rc);
}
/* Generate a new private key */
rc = ssh_pki_generate(arguments.type, arguments.bits, &key);
if (rc != SSH_OK) {
fprintf(stderr, "Error: Failed to generate keys");
goto end;
}
/* Write the private key */
if (arguments.format != NULL) {
if (strcasecmp(arguments.format, "PEM") == 0) {
rc = ssh_pki_export_privkey_file_format(key,
arguments.passphrase,
NULL,
NULL,
arguments.file,
SSH_FILE_FORMAT_PEM);
} else if (strcasecmp(arguments.format, "OpenSSH") == 0) {
rc = ssh_pki_export_privkey_file_format(key,
arguments.passphrase,
NULL,
NULL,
arguments.file,
SSH_FILE_FORMAT_OPENSSH);
} else {
rc = ssh_pki_export_privkey_file_format(key,
arguments.passphrase,
NULL,
NULL,
arguments.file,
SSH_FILE_FORMAT_DEFAULT);
}
} else {
rc = ssh_pki_export_privkey_file(key,
arguments.passphrase,
NULL,
NULL,
arguments.file);
}
if (rc != SSH_OK) {
fprintf(stderr, "Error: Failed to write private key file");
goto end;
}
/* If a passphrase was provided, overwrite and free it as it is not needed
* anymore */
if (arguments.passphrase != NULL) {
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(arguments.passphrase, strlen(arguments.passphrase));
#else
bzero(arguments.passphrase, strlen(arguments.passphrase));
#endif
free(arguments.passphrase);
arguments.passphrase = NULL;
}
pubkey_file = (char *)malloc(strlen(arguments.file) + 5);
if (pubkey_file == NULL) {
rc = ENOMEM;
goto end;
}
sprintf(pubkey_file, "%s.pub", arguments.file);
errno = 0;
rc = open(pubkey_file,
O_CREAT | O_EXCL | O_WRONLY,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (rc < 0) {
if (errno == EEXIST) {
printf("File \"%s\" exists. Overwrite it? (y|n) ", pubkey_file);
rc = scanf("%1023s", overwrite);
if (rc > 0 && tolower(overwrite[0]) == 'y') {
rc = open(pubkey_file, O_WRONLY);
if (rc > 0) {
close(rc);
errno = 0;
rc = chmod(pubkey_file,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (rc != 0) {
fprintf(stderr,
"Error(%d): Could not set file permissions\n",
errno);
goto end;
}
} else {
fprintf(stderr,
"Error: Could not create public key file\n");
goto end;
}
} else {
goto end;
}
} else {
fprintf(stderr, "Error opening \"%s\" file\n", pubkey_file);
goto end;
}
} else {
close(rc);
}
/* Write the public key */
rc = ssh_pki_export_pubkey_file(key, pubkey_file);
if (rc != SSH_OK) {
fprintf(stderr, "Error: Failed to write public key file");
goto end;
}
end:
if (key != NULL) {
ssh_key_free(key);
}
if (arguments.file != NULL) {
free(arguments.file);
}
if (arguments.passphrase != NULL) {
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(arguments.passphrase, strlen(arguments.passphrase));
#else
bzero(arguments.passphrase, strlen(arguments.passphrase));
#endif
free(arguments.passphrase);
}
if (pubkey_file != NULL) {
free(pubkey_file);
}
return rc;
}

View File

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

View File

@@ -22,13 +22,9 @@ program.
#include <libssh/libssh.h>
#include "examples_common.h"
#ifndef BUF_SIZE
#define BUF_SIZE 16384
#endif
static char **sources = NULL;
static char **sources;
static int nsources;
static char *destination = NULL;
static char *destination;
static int verbosity = 0;
struct location {
@@ -109,19 +105,18 @@ static void location_free(struct location *loc)
free(loc->user);
}
loc->user = NULL;
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
}
free(loc);
}
}
static struct location *parse_location(char *loc)
{
struct location *location = NULL;
char *ptr = NULL;
if (loc == NULL) {
return NULL;
}
static struct location *parse_location(char *loc) {
struct location *location;
char *ptr;
location = malloc(sizeof(struct location));
if (location == NULL) {
@@ -234,11 +229,11 @@ static int open_location(struct location *loc, int flag) {
return -1;
}
return 0;
} else if (loc->path != NULL) {
} else {
loc->file = fopen(loc->path, flag == READ ? "r":"w");
if (!loc->file) {
if (errno == EISDIR) {
if (chdir(loc->path)) {
if (loc->path != NULL && chdir(loc->path)) {
fprintf(stderr,
"Error changing directory to %s: %s\n",
loc->path, strerror(errno));
@@ -266,7 +261,7 @@ static int do_copy(struct location *src, struct location *dest, int recursive) {
socket_t fd;
struct stat s;
int w, r;
char buffer[BUF_SIZE];
char buffer[16384];
size_t total = 0;
mode_t mode;
char *filename = NULL;
@@ -409,11 +404,10 @@ int main(int argc, char **argv) {
int i;
int r;
if (opts(argc, argv) < 0) {
return EXIT_FAILURE;
r = EXIT_FAILURE;
goto end;
}
ssh_init();
dest = parse_location(destination);
if (dest == NULL) {
r = EXIT_FAILURE;
@@ -455,7 +449,5 @@ close_dest:
close_location(dest);
location_free(dest);
end:
ssh_finalize();
free(sources);
return r;
}

View File

@@ -25,18 +25,14 @@ clients must be made or how a client should react.
#include <string.h>
#include <stdio.h>
#ifndef BUF_SIZE
#define BUF_SIZE 2048
#endif
#define USER "myuser"
#define PASSWORD "mypassword"
static int authenticated=0;
static int tries = 0;
static int error = 0;
static ssh_channel chan = NULL;
static char *username = NULL;
static ssh_channel chan=NULL;
static char *username;
static ssh_gssapi_creds client_creds = NULL;
static int auth_password(ssh_session session, const char *user,
@@ -142,12 +138,20 @@ static struct argp_option options[] = {
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa host key (deprecated alias to 'k').",
.doc = "Set the rsa key.",
.group = 0
},
{
@@ -172,11 +176,15 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'r':
/* deprecated */
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
@@ -204,12 +212,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};
#endif /* HAVE_ARGP_H */
int main(int argc, char **argv)
{
ssh_session session = NULL;
ssh_bind sshbind = NULL;
ssh_event mainloop = NULL;
ssh_session client_session = NULL;
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_event mainloop;
ssh_session client_session;
struct ssh_server_callbacks_struct cb = {
.userdata = NULL,
@@ -218,15 +225,15 @@ int main(int argc, char **argv)
.channel_open_request_session_function = new_session_channel
};
char buf[BUF_SIZE];
char buf[2048];
char host[128]="";
char *ptr = NULL;
char *ptr;
int i,r, rc;
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, "sshd_rsa");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, "sshd_rsa");
#ifdef HAVE_ARGP_H
/*
@@ -284,7 +291,7 @@ int main(int argc, char **argv)
snprintf(buf,sizeof(buf), "Hello %s, welcome to the Sample SSH proxy.\r\nPlease select your destination: ", username);
ssh_channel_write(chan, buf, strlen(buf));
do{
i=ssh_channel_read(chan,buf, sizeof(buf), 0);
i=ssh_channel_read(chan,buf, 2048, 0);
if(i>0) {
ssh_channel_write(chan, buf, i);
if(strlen(host) + i < sizeof(host)){
@@ -337,3 +344,4 @@ int main(int argc, char **argv)
ssh_finalize();
return 0;
}

View File

@@ -1,515 +0,0 @@
/* This is a sample implementation of a libssh based SSH server */
/*
Copyright 2014 Audrius Butkevicius
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
The goal is to show the API in action.
*/
#include "config.h"
#include <libssh/callbacks.h>
#include <libssh/server.h>
#include <libssh/sftp.h>
#include <libssh/sftpserver.h>
#include <poll.h>
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#include <fcntl.h>
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#include <signal.h>
#include <stdlib.h>
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdbool.h>
/* below are for sftp */
#include <sys/statvfs.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <time.h>
#include <inttypes.h>
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#define USER "myuser"
#define PASS "mypassword"
#define BUF_SIZE 1048576
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
static void set_default_keys(ssh_bind sshbind,
int rsa_already_set,
int ecdsa_already_set)
{
if (!rsa_already_set)
{
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
KEYS_FOLDER "ssh_host_rsa_key");
}
if (!ecdsa_already_set)
{
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
KEYS_FOLDER "ssh_host_ecdsa_key");
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
KEYS_FOLDER "ssh_host_ed25519_key");
}
#define DEF_STR_SIZE 1024
char authorizedkeys[DEF_STR_SIZE] = {0};
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh sftp server example " SSH_STRINGIFY(LIBSSH_VERSION);
const char *argp_program_bug_address = "<libssh@libssh.org>";
/* Program documentation. */
static char doc[] = "Sftp server implemented with libssh -- a Secure Shell protocol implementation";
/* A description of the arguments we accept. */
static char args_doc[] = "BINDADDR";
/* The options we understand. */
static struct argp_option options[] = {
{.name = "port",
.key = 'p',
.arg = "PORT",
.flags = 0,
.doc = "Set the port to bind.",
.group = 0},
{.name = "hostkey",
.key = 'k',
.arg = "FILE",
.flags = 0,
.doc = "Set a host key. Can be used multiple times. "
"Implies no default keys.",
.group = 0},
{.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key.",
.group = 0},
{.name = "ecdsakey",
.key = 'e',
.arg = "FILE",
.flags = 0,
.doc = "Set the ecdsa key.",
.group = 0},
{.name = "authorizedkeys",
.key = 'a',
.arg = "FILE",
.flags = 0,
.doc = "Set the authorized keys file.",
.group = 0},
{.name = "no-default-keys",
.key = 'n',
.arg = NULL,
.flags = 0,
.doc = "Do not set default key locations.",
.group = 0},
{.name = "verbose",
.key = 'v',
.arg = NULL,
.flags = 0,
.doc = "Get verbose output.",
.group = 0},
{NULL, 0, NULL, 0, NULL, 0}};
/* Parse a single option. */
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure. */
ssh_bind sshbind = state->input;
static int no_default_keys = 0;
static int rsa_already_set = 0, ecdsa_already_set = 0;
switch (key)
{
case 'n':
no_default_keys = 1;
break;
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
/* We can't track the types of keys being added with this
option, so let's ensure we keep the keys we're adding
by just not setting the default keys */
no_default_keys = 1;
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
rsa_already_set = 1;
break;
case 'e':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
ecdsa_already_set = 1;
break;
case 'a':
strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
"3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1)
{
/* Too many arguments. */
argp_usage(state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1)
{
/* Not enough arguments. */
argp_usage(state);
}
if (!no_default_keys)
{
set_default_keys(sshbind,
rsa_already_set,
ecdsa_already_set);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */
/* A userdata struct for channel. */
struct channel_data_struct
{
/* Event which is used to poll the above descriptors. */
ssh_event event;
sftp_session sftp;
};
/* A userdata struct for session. */
struct session_data_struct
{
/* Pointer to the channel the session will allocate. */
ssh_channel channel;
int auth_attempts;
int authenticated;
};
static int auth_password(ssh_session session, const char *user,
const char *pass, void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
(void)session;
if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0)
{
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
sdata->auth_attempts++;
return SSH_AUTH_DENIED;
}
static int auth_publickey(ssh_session session,
const char *user,
struct ssh_key_struct *pubkey,
char signature_state,
void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
(void)session;
(void)user;
if (signature_state == SSH_PUBLICKEY_STATE_NONE)
{
return SSH_AUTH_SUCCESS;
}
if (signature_state != SSH_PUBLICKEY_STATE_VALID)
{
return SSH_AUTH_DENIED;
}
// valid so far. Now look through authorized keys for a match
if (authorizedkeys[0])
{
ssh_key key = NULL;
int result;
struct stat buf;
if (stat(authorizedkeys, &buf) == 0)
{
result = ssh_pki_import_pubkey_file(authorizedkeys, &key);
if ((result != SSH_OK) || (key == NULL))
{
fprintf(stderr,
"Unable to import public key file %s\n",
authorizedkeys);
}
else
{
result = ssh_key_cmp(key, pubkey, SSH_KEY_CMP_PUBLIC);
ssh_key_free(key);
if (result == 0)
{
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
}
}
}
// no matches
sdata->authenticated = 0;
return SSH_AUTH_DENIED;
}
static ssh_channel channel_open(ssh_session session, void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
sdata->channel = ssh_channel_new(session);
return sdata->channel;
}
static void handle_session(ssh_event event, ssh_session session)
{
int n;
/* Our struct holding information about the channel. */
struct channel_data_struct cdata = {
.sftp = NULL,
};
/* Our struct holding information about the session. */
struct session_data_struct sdata = {
.channel = NULL,
.auth_attempts = 0,
.authenticated = 0,
};
struct ssh_channel_callbacks_struct channel_cb = {
.userdata = &(cdata.sftp),
.channel_data_function = sftp_channel_default_data_callback,
.channel_subsystem_request_function = sftp_channel_default_subsystem_request,
};
struct ssh_server_callbacks_struct server_cb = {
.userdata = &sdata,
.auth_password_function = auth_password,
.channel_open_request_session_function = channel_open,
};
if (authorizedkeys[0])
{
server_cb.auth_pubkey_function = auth_publickey;
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_PUBLICKEY);
}
else
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
ssh_callbacks_init(&server_cb);
ssh_callbacks_init(&channel_cb);
ssh_set_server_callbacks(session, &server_cb);
if (ssh_handle_key_exchange(session) != SSH_OK)
{
fprintf(stderr, "%s\n", ssh_get_error(session));
return;
}
ssh_event_add_session(event, session);
n = 0;
while (sdata.authenticated == 0 || sdata.channel == NULL) {
/* If the user has used up all attempts, or if he hasn't been able to
* authenticate in 10 seconds (n * 100ms), disconnect. */
if (sdata.auth_attempts >= 3 || n >= 100) {
return;
}
if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
fprintf(stderr, "%s\n", ssh_get_error(session));
return;
}
n++;
}
ssh_set_channel_callbacks(sdata.channel, &channel_cb);
do {
/* Poll the main event which takes care of the session, the channel and
* even our child process's stdout/stderr (once it's started). */
if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
ssh_channel_close(sdata.channel);
}
/* If child process's stdout/stderr has been registered with the event,
* or the child process hasn't started yet, continue. */
if (cdata.event != NULL) {
continue;
}
/* FIXME The server keeps hanging in the poll above when the client
* closes the channel */
} while (ssh_channel_is_open(sdata.channel));
ssh_channel_send_eof(sdata.channel);
ssh_channel_close(sdata.channel);
/* Wait up to 5 seconds for the client to terminate the session. */
for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
ssh_event_dopoll(event, 100);
}
}
/* SIGCHLD handler for cleaning up dead children. */
static void sigchld_handler(int signo)
{
(void)signo;
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}
int main(int argc, char **argv)
{
ssh_bind sshbind = NULL;
ssh_session session = NULL;
ssh_event event = NULL;
struct sigaction sa;
int rc;
/* Set up SIGCHLD handler. */
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sa, NULL) != 0)
{
fprintf(stderr, "Failed to register SIGCHLD handler\n");
return 1;
}
rc = ssh_init();
if (rc < 0)
{
fprintf(stderr, "ssh_init failed\n");
goto exit;
}
sshbind = ssh_bind_new();
if (sshbind == NULL)
{
fprintf(stderr, "ssh_bind_new failed\n");
goto exit;
}
#ifdef HAVE_ARGP_H
argp_parse(&argp, argc, argv, 0, 0, sshbind);
#else
(void)argc;
(void)argv;
set_default_keys(sshbind, 0, 0);
#endif /* HAVE_ARGP_H */
if (ssh_bind_listen(sshbind) < 0)
{
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
goto exit;
}
while (1)
{
session = ssh_new();
if (session == NULL)
{
fprintf(stderr, "Failed to allocate session\n");
continue;
}
/* Blocks until there is a new incoming connection. */
if (ssh_bind_accept(sshbind, session) != SSH_ERROR)
{
switch (fork())
{
case 0:
/* Remove the SIGCHLD handler inherited from parent. */
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
/* Remove socket binding, which allows us to restart the
* parent process, without terminating existing sessions. */
ssh_bind_free(sshbind);
event = ssh_event_new();
if (event != NULL)
{
/* Blocks until the SSH session ends by either
* child process exiting, or client disconnecting. */
handle_session(event, session);
ssh_event_free(event);
}
else
{
fprintf(stderr, "Could not create polling context\n");
}
ssh_disconnect(session);
ssh_free(session);
exit(0);
case -1:
fprintf(stderr, "Failed to fork\n");
}
}
else
{
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
}
/* Since the session has been passed to a child fork, do some cleaning
* up at the parent process. */
ssh_disconnect(session);
ssh_free(session);
}
exit:
ssh_bind_free(sshbind);
ssh_finalize();
return 0;
}

View File

@@ -29,9 +29,10 @@ clients must be made or how a client should react.
#include "examples_common.h"
#ifdef WITH_SFTP
#ifndef BUF_SIZE
#define BUF_SIZE 65536
#endif
static int verbosity;
static char *destination;
#define DATALEN 65536
static void do_sftp(ssh_session session) {
sftp_session sftp = sftp_new(session);
@@ -39,12 +40,12 @@ static void do_sftp(ssh_session session) {
sftp_attributes file;
sftp_statvfs_t sftpstatvfs;
struct statvfs sysstatvfs;
sftp_file source;
sftp_file fichier;
sftp_file to;
int len = 1;
unsigned int i;
char data[BUF_SIZE] = {0};
char *lnk = NULL;
char data[DATALEN] = {0};
char *lnk;
unsigned int count;
@@ -83,7 +84,6 @@ static void do_sftp(ssh_session session) {
goto end;
}
printf("readlink /tmp/sftp_symlink_test: %s\n", lnk);
ssh_string_free_char(lnk);
sftp_unlink(sftp, "/tmp/sftp_symlink_test");
@@ -171,7 +171,7 @@ static void do_sftp(ssh_session session) {
sftp_attributes_free(file);
}
/* when file = NULL, an error has occurred OR the directory listing is end of
/* when file = NULL, an error has occured OR the directory listing is end of
* file */
if (!sftp_dir_eof(dir)) {
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
@@ -186,8 +186,8 @@ static void do_sftp(ssh_session session) {
/* the small buffer size was intended to stress the library. of course, you
* can use a buffer till 20kbytes without problem */
source = sftp_open(sftp, "/usr/bin/ssh", O_RDONLY, 0);
if (!source) {
fichier = sftp_open(sftp, "/usr/bin/ssh", O_RDONLY, 0);
if (!fichier) {
fprintf(stderr, "Error opening /usr/bin/ssh: %s\n",
ssh_get_error(session));
goto end;
@@ -198,16 +198,16 @@ static void do_sftp(ssh_session session) {
if (!to) {
fprintf(stderr, "Error opening ssh-copy for writing: %s\n",
ssh_get_error(session));
sftp_close(source);
sftp_close(fichier);
goto end;
}
while ((len = sftp_read(source, data, 4096)) > 0) {
while ((len = sftp_read(fichier, data, 4096)) > 0) {
if (sftp_write(to, data, len) != len) {
fprintf(stderr, "Error writing %d bytes: %s\n",
len, ssh_get_error(session));
sftp_close(to);
sftp_close(source);
sftp_close(fichier);
goto end;
}
}
@@ -217,15 +217,15 @@ static void do_sftp(ssh_session session) {
fprintf(stderr, "Error reading file: %s\n", ssh_get_error(session));
}
sftp_close(source);
sftp_close(fichier);
sftp_close(to);
printf("file closed\n");
to = sftp_open(sftp, "/tmp/large_file", O_WRONLY|O_CREAT, 0644);
printf("fichiers ferm\n");
to = sftp_open(sftp, "/tmp/grosfichier", O_WRONLY|O_CREAT, 0644);
for (i = 0; i < 1000; ++i) {
len = sftp_write(to, data, sizeof(data));
len = sftp_write(to, data, DATALEN);
printf("wrote %d bytes\n", len);
if (len != sizeof(data)) {
if (len != DATALEN) {
printf("chunk %d : %d (%s)\n", i, len, ssh_get_error(session));
}
}
@@ -241,63 +241,50 @@ static void usage(const char *argv0) {
fprintf(stderr, "Usage : %s [-v] remotehost\n"
"sample sftp test client - libssh-%s\n"
"Options :\n"
" -l user : log in as user\n"
" -p port : connect to port\n"
" -v : increase log verbosity\n",
argv0,
ssh_version(0));
exit(0);
}
int main(int argc, char **argv)
{
ssh_session session = NULL;
char *destination = NULL;
int auth = 0;
int state;
static int opts(int argc, char **argv) {
int i;
ssh_init();
session = ssh_new();
while ((i = getopt(argc, argv, "v")) != -1) {
switch(i) {
case 'v':
verbosity++;
break;
default:
fprintf(stderr, "unknown option %c\n", optopt);
usage(argv[0]);
return -1;
}
}
if (ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr,
"Error parsing command line: %s\n",
ssh_get_error(session));
ssh_free(session);
ssh_finalize();
destination = argv[optind];
if (destination == NULL) {
usage(argv[0]);
return -1;
}
return 0;
}
int main(int argc, char **argv) {
ssh_session session;
if (opts(argc, argv) < 0) {
return EXIT_FAILURE;
}
if (argc < 1) {
usage(argv[0]);
session = connect_ssh(destination, NULL, verbosity);
if (session == NULL) {
return EXIT_FAILURE;
}
destination = argv[1];
if (ssh_options_set(session, SSH_OPTIONS_HOST, destination) < 0) {
return -1;
}
if (ssh_connect(session)) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
return -1;
}
state = verify_knownhost(session);
if (state != 0) {
return -1;
}
auth = authenticate_console(session);
if (auth != SSH_AUTH_SUCCESS) {
return -1;
}
do_sftp(session);
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
return 0;
}

View File

@@ -25,14 +25,6 @@ clients must be made or how a client should react.
#include <string.h>
#include <stdio.h>
#ifdef _WIN32
#include <io.h>
#endif
#ifndef BUF_SIZE
#define BUF_SIZE 2049
#endif
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
@@ -49,27 +41,6 @@ static int tries = 0;
static int error = 0;
static ssh_channel chan=NULL;
static int auth_none(ssh_session session,
const char *user,
void *userdata)
{
ssh_string banner = NULL;
(void)user; /* unused */
(void)userdata; /* unused */
ssh_set_auth_methods(session,
SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC);
banner = ssh_string_from_char("Banner Example\n");
if (banner != NULL) {
ssh_send_issue_banner(session, banner);
}
ssh_string_free(banner);
return SSH_AUTH_DENIED;
}
static int auth_password(ssh_session session, const char *user,
const char *password, void *userdata){
(void)userdata;
@@ -89,7 +60,6 @@ static int auth_password(ssh_session session, const char *user,
return SSH_AUTH_DENIED;
}
#ifdef WITH_GSSAPI
static int auth_gssapi_mic(ssh_session session, const char *user, const char *principal, void *userdata){
ssh_gssapi_creds creds = ssh_gssapi_get_creds(session);
(void)userdata;
@@ -102,7 +72,6 @@ static int auth_gssapi_mic(ssh_session session, const char *user, const char *pr
authenticated = 1;
return SSH_AUTH_SUCCESS;
}
#endif
static int pty_request(ssh_session session, ssh_channel channel, const char *term,
int x,int y, int px, int py, void *userdata){
@@ -172,12 +141,20 @@ static struct argp_option options[] = {
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key (deprecated alias for 'k').",
.doc = "Set the rsa key.",
.group = 0
},
{
@@ -188,14 +165,6 @@ static struct argp_option options[] = {
.doc = "Get verbose output.",
.group = 0
},
{
.name = "config",
.key = 'f',
.arg = "FILE",
.flags = 0,
.doc = "Configuration file to use.",
.group = 0
},
{NULL, 0, NULL, 0, NULL, 0}
};
@@ -210,16 +179,18 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'r':
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
case 'f':
ssh_bind_options_parse_config(sshbind, arg);
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
@@ -244,29 +215,26 @@ 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};
#endif /* HAVE_ARGP_H */
int main(int argc, char **argv)
{
ssh_session session = NULL;
ssh_bind sshbind = NULL;
ssh_event mainloop = NULL;
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_event mainloop;
struct ssh_server_callbacks_struct cb = {
.userdata = NULL,
.auth_none_function = auth_none,
.auth_password_function = auth_password,
#ifdef WITH_GSSAPI
.auth_gssapi_mic_function = auth_gssapi_mic,
#endif
.channel_open_request_session_function = new_session_channel
};
char buf[BUF_SIZE];
char buf[2048];
int i;
int r;
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, KEYS_FOLDER "ssh_host_rsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
@@ -314,24 +282,19 @@ int main(int argc, char **argv)
} else
printf("Authenticated and got a channel\n");
do{
i=ssh_channel_read(chan, buf, sizeof(buf) - 1, 0);
i=ssh_channel_read(chan,buf, 2048, 0);
if(i>0) {
if (ssh_channel_write(chan, buf, i) == SSH_ERROR) {
printf("error writing to channel\n");
ssh_channel_write(chan, buf, i);
if (write(1,buf,i) < 0) {
printf("error writing to buffer\n");
return 1;
}
buf[i] = '\0';
printf("%s", buf);
fflush(stdout);
if (buf[0] == '\x0d') {
if (ssh_channel_write(chan, "\n", 1) == SSH_ERROR) {
printf("error writing to channel\n");
if (write(1, "\n", 1) < 0) {
printf("error writing to buffer\n");
return 1;
}
printf("\n");
ssh_channel_write(chan, "\n", 1);
}
}
} while (i>0);
@@ -340,3 +303,4 @@ int main(int argc, char **argv)
ssh_finalize();
return 0;
}

View File

@@ -25,10 +25,6 @@ clients must be made or how a client should react.
#include <stdio.h>
#include <stdbool.h>
#ifndef BUF_SIZE
#define BUF_SIZE 2048
#endif
#define SSHD_USER "libssh"
#define SSHD_PASSWORD "libssh"
@@ -112,12 +108,20 @@ static struct argp_option options[] = {
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key (deprecated alias for 'k').",
.doc = "Set the rsa key.",
.group = 0
},
{
@@ -143,10 +147,15 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
port = atoi(arg);
break;
case 'r':
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
@@ -174,8 +183,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};
#endif /* HAVE_ARGP_H */
static const char *name = NULL;
static const char *instruction = NULL;
static const char *name;
static const char *instruction;
static const char *prompts[2];
static char echo[] = { 1, 0 };
@@ -279,13 +288,12 @@ static int authenticate(ssh_session session) {
return 0;
}
int main(int argc, char **argv)
{
ssh_session session = NULL;
ssh_bind sshbind = NULL;
ssh_message message = NULL;
ssh_channel chan = NULL;
char buf[BUF_SIZE];
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_message message;
ssh_channel chan=0;
char buf[2048];
int auth=0;
int shell=0;
int i;
@@ -294,8 +302,10 @@ int main(int argc, char **argv)
sshbind=ssh_bind_new();
session=ssh_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
KEYS_FOLDER "ssh_host_rsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*
@@ -355,9 +365,9 @@ int main(int argc, char **argv)
}
} while(!chan);
if (!chan) {
printf("Error: client did not ask for a channel session (%s)\n",
ssh_get_error(session));
if(!chan) {
printf("Error: cleint did not ask for a channel session (%s)\n",
ssh_get_error(session));
ssh_finalize();
return 1;
}
@@ -389,7 +399,7 @@ int main(int argc, char **argv)
printf("it works !\n");
do{
i=ssh_channel_read(chan,buf, sizeof(buf), 0);
i=ssh_channel_read(chan,buf, 2048, 0);
if(i>0) {
if(*buf == '' || *buf == '')
break;
@@ -412,3 +422,4 @@ int main(int argc, char **argv)
ssh_finalize();
return 0;
}

View File

@@ -22,173 +22,157 @@ program.
#include <libssh/libssh.h>
#include "examples_common.h"
#ifndef BUF_SIZE
#define BUF_SIZE 16384
#endif
static int verbosity = 0;
static const char *createcommand =
"rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && "
"cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
static char *host = NULL;
static void usage(const char *argv0)
{
fprintf(stderr,
"Usage : %s [options] host\n"
"sample tiny scp downloader client - libssh-%s\n"
"This program will create files in /tmp and try to fetch them\n",
argv0,
ssh_version(0));
exit(0);
static void usage(const char *argv0){
fprintf(stderr,"Usage : %s [options] host\n"
"sample tiny scp downloader client - libssh-%s\n"
"This program will create files in /tmp and try to fetch them\n",
// "Options :\n",
// " -r : use RSA to verify host public key\n",
argv0,
ssh_version(0));
exit(0);
}
static int opts(int argc, char **argv)
{
int i;
while ((i = getopt(argc, argv, "v")) != -1) {
switch (i) {
case 'v':
verbosity++;
break;
default:
fprintf(stderr, "unknown option %c\n", optopt);
usage(argv[0]);
return -1;
}
}
host = argv[optind];
if (host == NULL)
static int opts(int argc, char **argv){
int i;
while((i=getopt(argc,argv,"v"))!=-1){
switch(i){
case 'v':
verbosity++;
break;
default:
fprintf(stderr,"unknown option %c\n",optopt);
usage(argv[0]);
return 0;
}
static void create_files(ssh_session session)
{
ssh_channel channel = ssh_channel_new(session);
char buffer[1];
int rc;
if (channel == NULL) {
fprintf(stderr, "Error creating channel: %s\n", ssh_get_error(session));
exit(EXIT_FAILURE);
}
if (ssh_channel_open_session(channel) != SSH_OK) {
fprintf(stderr, "Error creating channel: %s\n", ssh_get_error(session));
ssh_channel_free(channel);
exit(EXIT_FAILURE);
}
if (ssh_channel_request_exec(channel, createcommand) != SSH_OK) {
fprintf(stderr,
"Error executing command: %s\n",
ssh_get_error(session));
ssh_channel_close(channel);
ssh_channel_free(channel);
exit(EXIT_FAILURE);
}
while (!ssh_channel_is_eof(channel)) {
rc = ssh_channel_read(channel, buffer, 1, 1);
if (rc != 1) {
fprintf(stderr, "Error reading from channel\n");
ssh_channel_close(channel);
ssh_channel_free(channel);
return;
}
rc = write(1, buffer, 1);
if (rc < 0) {
fprintf(stderr, "Error writing to buffer\n");
ssh_channel_close(channel);
ssh_channel_free(channel);
return;
}
}
ssh_channel_close(channel);
ssh_channel_free(channel);
}
static int fetch_files(ssh_session session)
{
int size;
char buffer[BUF_SIZE];
int mode;
char *filename = NULL;
int r;
ssh_scp scp = ssh_scp_new(session,
SSH_SCP_READ | SSH_SCP_RECURSIVE,
"/tmp/libssh_tests/*");
if (ssh_scp_init(scp) != SSH_OK) {
fprintf(stderr, "error initializing scp: %s\n", ssh_get_error(session));
ssh_scp_free(scp);
return -1;
}
printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n");
do {
r = ssh_scp_pull_request(scp);
switch (r) {
case SSH_SCP_REQUEST_NEWFILE:
size = ssh_scp_request_get_size(scp);
filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp);
printf("downloading file %s, size %d, perms 0%o\n",
filename,
size,
mode);
free(filename);
ssh_scp_accept_request(scp);
r = ssh_scp_read(scp, buffer, sizeof(buffer));
if (r == SSH_ERROR) {
fprintf(stderr,
"Error reading scp: %s\n",
ssh_get_error(session));
ssh_scp_close(scp);
ssh_scp_free(scp);
return -1;
}
printf("done\n");
break;
case SSH_ERROR:
fprintf(stderr, "Error: %s\n", ssh_get_error(session));
ssh_scp_close(scp);
ssh_scp_free(scp);
return -1;
case SSH_SCP_REQUEST_WARNING:
fprintf(stderr, "Warning: %s\n", ssh_scp_request_get_warning(scp));
break;
case SSH_SCP_REQUEST_NEWDIR:
filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp);
printf("downloading directory %s, perms 0%o\n", filename, mode);
free(filename);
ssh_scp_accept_request(scp);
break;
case SSH_SCP_REQUEST_ENDDIR:
printf("End of directory\n");
break;
case SSH_SCP_REQUEST_EOF:
printf("End of requests\n");
goto end;
}
} while (1);
end:
ssh_scp_close(scp);
ssh_scp_free(scp);
return 0;
}
host = argv[optind];
if(host == NULL)
usage(argv[0]);
return 0;
}
int main(int argc, char **argv)
{
ssh_session session = NULL;
if (opts(argc, argv) < 0)
return EXIT_FAILURE;
session = connect_ssh(host, NULL, verbosity);
if (session == NULL)
return EXIT_FAILURE;
create_files(session);
fetch_files(session);
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
return 0;
static void create_files(ssh_session session){
ssh_channel channel=ssh_channel_new(session);
char buffer[1];
int rc;
if(channel == NULL){
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
exit(EXIT_FAILURE);
}
if(ssh_channel_open_session(channel) != SSH_OK){
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
ssh_channel_free(channel);
exit(EXIT_FAILURE);
}
if(ssh_channel_request_exec(channel,createcommand) != SSH_OK){
fprintf(stderr,"Error executing command: %s\n",ssh_get_error(session));
ssh_channel_close(channel);
ssh_channel_free(channel);
exit(EXIT_FAILURE);
}
while(!ssh_channel_is_eof(channel)){
rc = ssh_channel_read(channel,buffer,1,1);
if (rc != 1) {
fprintf(stderr, "Error reading from channel\n");
ssh_channel_close(channel);
ssh_channel_free(channel);
return;
}
rc = write(1, buffer, 1);
if (rc < 0) {
fprintf(stderr, "Error writing to buffer\n");
ssh_channel_close(channel);
ssh_channel_free(channel);
return;
}
}
ssh_channel_close(channel);
ssh_channel_free(channel);
}
static int fetch_files(ssh_session session){
int size;
char buffer[16384];
int mode;
char *filename;
int r;
ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*");
if(ssh_scp_init(scp) != SSH_OK){
fprintf(stderr,"error initializing scp: %s\n",ssh_get_error(session));
ssh_scp_free(scp);
return -1;
}
printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n");
do {
r=ssh_scp_pull_request(scp);
switch(r){
case SSH_SCP_REQUEST_NEWFILE:
size=ssh_scp_request_get_size(scp);
filename=strdup(ssh_scp_request_get_filename(scp));
mode=ssh_scp_request_get_permissions(scp);
printf("downloading file %s, size %d, perms 0%o\n",filename,size,mode);
free(filename);
ssh_scp_accept_request(scp);
r=ssh_scp_read(scp,buffer,sizeof(buffer));
if(r==SSH_ERROR){
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(session));
ssh_scp_close(scp);
ssh_scp_free(scp);
return -1;
}
printf("done\n");
break;
case SSH_ERROR:
fprintf(stderr,"Error: %s\n",ssh_get_error(session));
ssh_scp_close(scp);
ssh_scp_free(scp);
return -1;
case SSH_SCP_REQUEST_WARNING:
fprintf(stderr,"Warning: %s\n",ssh_scp_request_get_warning(scp));
break;
case SSH_SCP_REQUEST_NEWDIR:
filename=strdup(ssh_scp_request_get_filename(scp));
mode=ssh_scp_request_get_permissions(scp);
printf("downloading directory %s, perms 0%o\n",filename,mode);
free(filename);
ssh_scp_accept_request(scp);
break;
case SSH_SCP_REQUEST_ENDDIR:
printf("End of directory\n");
break;
case SSH_SCP_REQUEST_EOF:
printf("End of requests\n");
goto end;
}
} while (1);
end:
ssh_scp_close(scp);
ssh_scp_free(scp);
return 0;
}
int main(int argc, char **argv){
ssh_session session;
if(opts(argc,argv)<0)
return EXIT_FAILURE;
session=connect_ssh(host,NULL,verbosity);
if(session == NULL)
return EXIT_FAILURE;
create_files(session);
fetch_files(session);
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
return 0;
}

View File

@@ -5,60 +5,60 @@
#define LIMIT 0x100000000UL
int main(void)
{
ssh_session session = NULL;
ssh_channel channel = NULL;
char buffer[1024 * 1024] = {0};
int rc;
uint64_t total = 0;
uint64_t lastshown = 4096;
session = connect_ssh("localhost", NULL, 0);
if (session == NULL) {
return 1;
}
channel = ssh_channel_new(session);
if (channel == NULL) {
ssh_disconnect(session);
return 1;
}
rc = ssh_channel_open_session(channel);
if (rc < 0) {
ssh_channel_close(channel);
ssh_disconnect(session);
return 1;
}
rc = ssh_channel_request_exec(channel, "cat > /dev/null");
if (rc < 0) {
ssh_channel_close(channel);
ssh_disconnect(session);
return 1;
}
while ((rc = ssh_channel_write(channel, buffer, sizeof(buffer))) > 0) {
total += rc;
if (total / 2 >= lastshown) {
printf("written %llx\n", (long long unsigned int)total);
lastshown = total;
}
if (total > LIMIT)
break;
}
if (rc < 0) {
printf("error : %s\n", ssh_get_error(session));
ssh_channel_close(channel);
ssh_disconnect(session);
return 1;
}
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
int main(void) {
ssh_session session;
ssh_channel channel;
char buffer[1024*1024];
int rc;
uint64_t total=0;
uint64_t lastshown=4096;
session = connect_ssh("localhost", NULL, 0);
if (session == NULL) {
return 1;
}
channel = ssh_channel_new(session);;
if (channel == NULL) {
ssh_disconnect(session);
return 1;
}
return 0;
rc = ssh_channel_open_session(channel);
if (rc < 0) {
ssh_channel_close(channel);
ssh_disconnect(session);
return 1;
}
rc = ssh_channel_request_exec(channel, "cat > /dev/null");
if (rc < 0) {
ssh_channel_close(channel);
ssh_disconnect(session);
return 1;
}
while ((rc = ssh_channel_write(channel, buffer, sizeof(buffer))) > 0) {
total += rc;
if(total/2 >= lastshown){
printf("written %llx\n", (long long unsigned int) total);
lastshown=total;
}
if(total > LIMIT)
break;
}
if (rc < 0) {
printf("error : %s\n",ssh_get_error(session));
ssh_channel_close(channel);
ssh_disconnect(session);
return 1;
}
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_disconnect(session);
return 0;
}

View File

@@ -1,951 +0,0 @@
/*
* ssh.c - Simple example of SSH X11 client using libssh
*
* Copyright (C) 2022 Marco Fortina
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*
*
* ssh_X11_client
* ==============
*
* AUTHOR URL
* https://gitlab.com/marco.fortina/libssh-x11-client/
*
* This is a simple example of SSH X11 client using libssh.
*
* Features:
*
* - support local display (e.g. :0)
* - support remote display (e.g. localhost:10.0)
* - using callbacks and event polling to significantly reduce CPU utilization
* - use X11 forwarding with authentication spoofing (like openssh)
*
* Note:
*
* - part of this code was inspired by openssh's one.
*
* Dependencies:
*
* - gcc >= 7.5.0
* - libssh >= 0.8.0
* - libssh-dev >= 0.8.0
*
* To Build:
* gcc -o ssh_X11_client ssh_X11_client.c -lssh -g
*
* Donations:
*
* If you liked this work and wish to support the developer please donate to:
* Bitcoin: 1N2rQimKbeUQA8N2LU5vGopYQJmZsBM2d6
*
*/
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <poll.h>
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <time.h>
#include <libssh/libssh.h>
#include <libssh/callbacks.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
/*
* Data Structures and Macros
*/
#define _PATH_UNIX_X "/tmp/.X11-unix/X%d"
#define _XAUTH_CMD "/usr/bin/xauth list %s 2>/dev/null"
typedef struct item {
ssh_channel channel;
int fd_in;
int fd_out;
int protected;
struct item *next;
} node_t;
node_t *node = NULL;
/*
* Mutex
*/
pthread_mutex_t mutex;
/*
* Function declarations
*/
/* Linked nodes to manage channel/fd tuples */
static int insert_item(ssh_channel channel, int fd_in, int fd_out,
int protected);
static void delete_item(ssh_channel channel);
static node_t * search_item(ssh_channel channel);
/* X11 Display */
const char * ssh_gai_strerror(int gaierr);
static int x11_get_proto(const char *display, char **_proto, char **_data);
static void set_nodelay(int fd);
static int connect_local_xsocket_path(const char *pathname);
static int connect_local_xsocket(int display_number);
static int x11_connect_display(void);
/* Send data to channel */
static int copy_fd_to_channel_callback(int fd, int revents, void *userdata);
/* Read data from channel */
static int copy_channel_to_fd_callback(ssh_session session, ssh_channel channel,
void *data, uint32_t len, int is_stderr,
void *userdata);
/* EOF&Close channel */
static void channel_close_callback(ssh_session session, ssh_channel channel,
void *userdata);
/* X11 Request */
static ssh_channel x11_open_request_callback(ssh_session session,
const char *shost, int sport,
void *userdata);
/* Main loop */
static int main_loop(ssh_channel channel);
/* Internals */
int64_t _current_timestamp(void);
/* Global variables */
const char *hostname = NULL;
int enableX11 = 1;
/*
* Callbacks Data Structures
*/
/* SSH Channel Callbacks */
struct ssh_channel_callbacks_struct channel_cb =
{
.channel_data_function = copy_channel_to_fd_callback,
.channel_eof_function = channel_close_callback,
.channel_close_function = channel_close_callback,
.userdata = NULL
};
/* SSH Callbacks */
struct ssh_callbacks_struct cb =
{
.channel_open_request_x11_function = x11_open_request_callback,
.userdata = NULL
};
/*
* SSH Event Context
*/
short events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
ssh_event event;
/*
* Internal data structures
*/
struct termios _saved_tio;
/*
* Internal functions
*/
int64_t _current_timestamp(void)
{
struct timeval tv;
int64_t milliseconds;
gettimeofday(&tv, NULL);
milliseconds = (int64_t)(tv.tv_sec) * 1000 + (tv.tv_usec / 1000);
return milliseconds;
}
static void _logging_callback(int priority, const char *function,
const char *buffer, void *userdata)
{
FILE *fp = NULL;
char buf[100];
int64_t milliseconds;
time_t now = time(0);
(void)userdata;
strftime(buf, 100, "%Y-%m-%d %H:%M:%S", localtime(&now));
fp = fopen("debug.log","a");
if (fp == NULL) {
printf("Error!");
exit(-11);
}
milliseconds = _current_timestamp();
fprintf(fp, "[%s.%" PRId64 ", %d] %s: %s\n", buf, milliseconds, priority,
function, buffer);
fclose(fp);
}
static int _enter_term_raw_mode(void)
{
struct termios tio;
int ret = tcgetattr(fileno(stdin), &tio);
if (ret != -1) {
_saved_tio = tio;
tio.c_iflag |= IGNPAR;
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
#ifdef IUCLC
tio.c_iflag &= ~IUCLC;
#endif
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
#ifdef IEXTEN
tio.c_lflag &= ~IEXTEN;
#endif
tio.c_oflag &= ~OPOST;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
ret = tcsetattr(fileno(stdin), TCSADRAIN, &tio);
}
return ret;
}
static int _leave_term_raw_mode(void)
{
int ret = tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio);
return ret;
}
/*
* Functions
*/
static int insert_item(ssh_channel channel, int fd_in, int fd_out,
int protected)
{
node_t *node_iterator = NULL, *new = NULL;
pthread_mutex_lock(&mutex);
if (node == NULL) {
/* Calloc ensure that node is full of 0 */
node = (node_t *) calloc(1, sizeof(node_t));
if (node == NULL) {
pthread_mutex_unlock(&mutex);
return -1;
}
node->channel = channel;
node->fd_in = fd_in;
node->fd_out = fd_out;
node->protected = protected;
node->next = NULL;
} else {
node_iterator = node;
while (node_iterator->next != NULL) {
node_iterator = node_iterator->next;
}
/* Create the new node */
new = (node_t *) malloc(sizeof(node_t));
if (new == NULL) {
pthread_mutex_unlock(&mutex);
return -1;
}
new->channel = channel;
new->fd_in = fd_in;
new->fd_out = fd_out;
new->protected = protected;
new->next = NULL;
node_iterator->next = new;
}
pthread_mutex_unlock(&mutex);
return 0;
}
static void delete_item(ssh_channel channel)
{
node_t *current = NULL, *previous = NULL;
pthread_mutex_lock(&mutex);
for (current = node; current; previous = current, current = current->next) {
if (current->channel != channel) {
continue;
}
if (previous == NULL) {
node = current->next;
} else {
previous->next = current->next;
}
free(current);
pthread_mutex_unlock(&mutex);
return;
}
pthread_mutex_unlock(&mutex);
}
static node_t *search_item(ssh_channel channel)
{
node_t *current = NULL;
pthread_mutex_lock(&mutex);
current = node;
while (current != NULL) {
if (current->channel == channel) {
pthread_mutex_unlock(&mutex);
return current;
} else {
current = current->next;
}
}
pthread_mutex_unlock(&mutex);
return NULL;
}
static void set_nodelay(int fd)
{
int opt, rc;
socklen_t optlen;
optlen = sizeof(opt);
rc = getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen);
if (rc == -1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "getsockopt TCP_NODELAY: %.100s",
strerror(errno));
return;
}
if (opt == 1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fd %d is TCP_NODELAY", fd);
return;
}
opt = 1;
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fd %d setting TCP_NODELAY", fd);
rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
if (rc == -1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "setsockopt TCP_NODELAY: %.100s",
strerror(errno));
}
}
const char *ssh_gai_strerror(int gaierr)
{
if (gaierr == EAI_SYSTEM && errno != 0) {
return strerror(errno);
}
return gai_strerror(gaierr);
}
static int x11_get_proto(const char *display, char **_proto, char **_cookie)
{
char cmd[1024], line[512], xdisplay[512];
static char proto[512], cookie[512];
FILE *f = NULL;
int ret = 0;
*_proto = proto;
*_cookie = cookie;
proto[0] = cookie[0] = '\0';
if (strncmp(display, "localhost:", 10) == 0) {
ret = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", display + 10);
if (ret < 0 || (size_t)ret >= sizeof(xdisplay)) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"display name too long. display: %s", display);
return -1;
}
display = xdisplay;
}
snprintf(cmd, sizeof(cmd), _XAUTH_CMD, display);
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "xauth cmd: %s", cmd);
f = popen(cmd, "r");
if (f && fgets(line, sizeof(line), f) &&
sscanf(line, "%*s %511s %511s", proto, cookie) == 2) {
ret = 0;
} else {
ret = 1;
}
if (f) {
pclose(f);
}
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "proto: %s - cookie: %s - ret: %d",
proto, cookie, ret);
return ret;
}
static int connect_local_xsocket_path(const char *pathname)
{
int sock, rc;
struct sockaddr_un addr;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "socket: %.100s",
strerror(errno));
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
addr.sun_path[0] = '\0';
/* pathname is guaranteed to be initialized and larger than addr.sun_path[108] */
memcpy(addr.sun_path + 1, pathname, sizeof(addr.sun_path) - 1);
rc = connect(sock, (struct sockaddr *)&addr,
offsetof(struct sockaddr_un, sun_path) + 1 + strlen(pathname));
if (rc == 0) {
return sock;
}
close(sock);
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "connect %.100s: %.100s",
addr.sun_path, strerror(errno));
return -1;
}
static int connect_local_xsocket(int display_number)
{
char buf[1024] = {0};
snprintf(buf, sizeof(buf), _PATH_UNIX_X, display_number);
return connect_local_xsocket_path(buf);
}
static int x11_connect_display(void)
{
int display_number;
const char *display = NULL;
char buf[1024], *cp = NULL;
struct addrinfo hints, *ai = NULL, *aitop = NULL;
char strport[NI_MAXSERV];
int gaierr = 0, sock = 0;
/* Try to open a socket for the local X server. */
display = getenv("DISPLAY");
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display: %s", display);
if (display == 0) {
return -1;
}
/* Check if it is a unix domain socket. */
if (strncmp(display, "unix:", 5) == 0 || display[0] == ':') {
/* Connect to the unix domain socket. */
if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"Could not parse display number from DISPLAY: %.100s",
display);
return -1;
}
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display_number: %d",
display_number);
/* Create a socket. */
sock = connect_local_xsocket(display_number);
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "socket: %d", sock);
if (sock < 0) {
return -1;
}
/* OK, we now have a connection to the display. */
return sock;
}
/* Connect to an inet socket. */
strncpy(buf, display, sizeof(buf) - 1);
cp = strchr(buf, ':');
if (cp == 0) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"Could not find ':' in DISPLAY: %.100s", display);
return -1;
}
*cp = 0;
if (sscanf(cp + 1, "%d", &display_number) != 1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"Could not parse display number from DISPLAY: %.100s",
display);
return -1;
}
/* Look up the host address */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof(strport), "%u", 6000 + display_number);
gaierr = getaddrinfo(buf, strport, &hints, &aitop);
if (gaierr != 0) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "%.100s: unknown host. (%s)",
buf, ssh_gai_strerror(gaierr));
return -1;
}
for (ai = aitop; ai; ai = ai->ai_next) {
/* Create a socket. */
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock == -1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "socket: %.100s",
strerror(errno));
continue;
}
/* Connect it to the display. */
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"connect %.100s port %u: %.100s", buf,
6000 + display_number, strerror(errno));
close(sock);
continue;
}
/* Success */
break;
}
freeaddrinfo(aitop);
if (ai == 0) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "connect %.100s port %u: %.100s",
buf, 6000 + display_number, strerror(errno));
return -1;
}
set_nodelay(sock);
return sock;
}
static int copy_fd_to_channel_callback(int fd, int revents, void *userdata)
{
ssh_channel channel = (ssh_channel)userdata;
char buf[2097152];
int sz = 0, ret = 0;
node_t *temp_node = search_item(channel);
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "event: %d - fd: %d", revents, fd);
if (channel == NULL) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "channel does not exist.");
if (temp_node->protected == 0) {
close(fd);
}
return -1;
}
if (fcntl(fd, F_GETFD) == -1) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fcntl error. fd: %d", fd);
ssh_channel_close(channel);
return -1;
}
if ((revents & POLLIN) || (revents & POLLPRI)) {
sz = read(fd, buf, sizeof(buf));
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "sz: %d", sz);
if (sz > 0) {
ret = ssh_channel_write(channel, buf, sz);
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "channel_write ret: %d", ret);
} else if (sz < 0) {
ssh_channel_close(channel);
return -1;
} else {
/* sz = 0. Why the hell I'm here? */
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"Why the hell am I here?: sz: %d", sz);
if (temp_node->protected == 0) {
close(fd);
}
return -1;
}
}
if ((revents & POLLHUP) || (revents & POLLNVAL) || (revents & POLLERR)) {
ssh_channel_close(channel);
return -1;
}
return sz;
}
static int copy_channel_to_fd_callback(ssh_session session, ssh_channel channel,
void *data, uint32_t len, int is_stderr,
void *userdata)
{
node_t *temp_node = NULL;
int fd, sz;
(void)session;
(void)is_stderr;
(void)userdata;
temp_node = search_item(channel);
fd = temp_node->fd_out;
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "len: %d - fd: %d - is_stderr: %d",
len, fd, is_stderr);
sz = write(fd, data, len);
return sz;
}
static void channel_close_callback(ssh_session session, ssh_channel channel,
void *userdata)
{
node_t *temp_node = NULL;
(void)session;
(void)userdata;
temp_node = search_item(channel);
if (temp_node != NULL) {
int fd = temp_node->fd_in;
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "fd: %d", fd);
delete_item(channel);
ssh_event_remove_fd(event, fd);
if (temp_node->protected == 0) {
close(fd);
}
}
}
static ssh_channel x11_open_request_callback(ssh_session session,
const char *shost, int sport,
void *userdata)
{
ssh_channel channel = NULL;
int sock, rv;
(void)shost;
(void)sport;
(void)userdata;
channel = ssh_channel_new(session);
sock = x11_connect_display();
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "sock: %d", sock);
rv = insert_item(channel, sock, sock, 0);
if (rv != 0) {
ssh_channel_free(channel);
return NULL;
}
ssh_event_add_fd(event, sock, events, copy_fd_to_channel_callback, channel);
ssh_event_add_session(event, session);
ssh_add_channel_callbacks(channel, &channel_cb);
return channel;
}
/*
* MAIN LOOP
*/
static int main_loop(ssh_channel channel)
{
ssh_session session = ssh_channel_get_session(channel);
int rv;
rv = insert_item(channel, fileno(stdin), fileno(stdout), 1);
if (rv != 0) {
return -1;
}
ssh_callbacks_init(&channel_cb);
ssh_set_channel_callbacks(channel, &channel_cb);
event = ssh_event_new();
if (event == NULL) {
printf("Couldn't get a event\n");
return -1;
}
rv = ssh_event_add_fd(event, fileno(stdin), events,
copy_fd_to_channel_callback, channel);
if (rv != SSH_OK) {
printf("Couldn't add an fd to the event\n");
return -1;
}
rv = ssh_event_add_session(event, session);
if (rv != SSH_OK) {
printf("Couldn't add the session to the event\n");
return -1;
}
do {
if (ssh_event_dopoll(event, 1000) == SSH_ERROR) {
printf("Error : %s\n", ssh_get_error(session));
/* fall through */
}
} while (!ssh_channel_is_closed(channel));
delete_item(channel);
ssh_event_remove_fd(event, fileno(stdin));
ssh_event_remove_session(event, session);
ssh_event_free(event);
return 0;
}
/*
* USAGE
*/
static void usage(void)
{
fprintf(stderr,
"Usage : ssh-X11-client [options] [login@]hostname\n"
"sample X11 client - libssh-%s\n"
"Options :\n"
" -l user : Specifies the user to log in as on the remote "
"machine.\n"
" -p port : Port to connect to on the remote host.\n"
" -v : Verbose mode. Multiple -v options increase the "
"verbosity. The maximum is 5.\n"
" -C : Requests compression of all data.\n"
" -x : Disables X11 forwarding.\n"
"\n",
ssh_version(0));
exit(0);
}
static int opts(int argc, char **argv)
{
int i;
while ((i = getopt(argc,argv,"x")) != -1) {
switch (i) {
case 'x':
enableX11 = 0;
break;
default:
fprintf(stderr, "Unknown option %c\n", optopt);
return -1;
}
}
if (optind < argc) {
hostname = argv[optind++];
}
if (hostname == NULL) {
return -1;
}
return 0;
}
/*
* MAIN
*/
int main(int argc, char **argv)
{
char *password = NULL;
ssh_session session = NULL;
ssh_channel channel = NULL;
int ret;
const char *display = NULL;
char *proto = NULL, *cookie = NULL;
ssh_set_log_callback(_logging_callback);
ret = ssh_init();
if (ret != SSH_OK) {
return ret;
}
session = ssh_new();
if (session == NULL) {
exit(-1);
}
if (ssh_options_getopt(session, &argc, argv) || opts(argc, argv)) {
fprintf(stderr, "Error parsing command line: %s\n",
ssh_get_error(session));
ssh_free(session);
ssh_finalize();
usage();
}
if (ssh_options_set(session, SSH_OPTIONS_HOST, hostname) < 0) {
return -1;
}
ret = ssh_connect(session);
if (ret != SSH_OK) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
exit(-1);
}
password = getpass("Password: ");
ret = ssh_userauth_password(session, NULL, password);
if (ret != SSH_AUTH_SUCCESS) {
fprintf(stderr, "Error authenticating with password: %s\n",
ssh_get_error(session));
exit(-1);
}
channel = ssh_channel_new(session);
if (channel == NULL) {
return SSH_ERROR;
}
ret = ssh_channel_open_session(channel);
if (ret != SSH_OK) {
return ret;
}
ret = ssh_channel_request_pty(channel);
if (ret != SSH_OK) {
return ret;
}
ret = ssh_channel_change_pty_size(channel, 80, 24);
if (ret != SSH_OK) {
return ret;
}
if (enableX11 == 1) {
display = getenv("DISPLAY");
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "display: %s", display);
if (display) {
ssh_callbacks_init(&cb);
ret = ssh_set_callbacks(session, &cb);
if (ret != SSH_OK) {
return ret;
}
ret = x11_get_proto(display, &proto, &cookie);
if (ret != 0) {
_ssh_log(SSH_LOG_FUNCTIONS, __func__,
"Using fake authentication data for X11 forwarding");
proto = NULL;
cookie = NULL;
}
_ssh_log(SSH_LOG_FUNCTIONS, __func__, "proto: %s - cookie: %s",
proto, cookie);
/* See https://gitlab.com/libssh/libssh-mirror/-/blob/master/src/channels.c#L2062 for details. */
ret = ssh_channel_request_x11(channel, 0, proto, cookie, 0);
if (ret != SSH_OK) {
return ret;
}
}
}
ret = _enter_term_raw_mode();
if (ret != 0) {
exit(-1);
}
ret = ssh_channel_request_shell(channel);
if (ret != SSH_OK) {
return ret;
}
ret = main_loop(channel);
if (ret != SSH_OK) {
return ret;
}
_leave_term_raw_mode();
ssh_channel_close(channel);
ssh_channel_free(channel);
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
}

View File

@@ -17,7 +17,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/select.h>
#include <sys/time.h>
@@ -45,15 +44,14 @@
#include "examples_common.h"
#define MAXCMD 10
static char *host = NULL;
static char *user = NULL;
static char *host;
static char *user;
static char *cmds[MAXCMD];
static char *config_file = NULL;
static struct termios terminal;
static char *pcap_file = NULL;
static char *proxycommand = NULL;
static char *proxycommand;
static int auth_callback(const char *prompt,
char *buf,
@@ -83,7 +81,7 @@ static void add_cmd(char *cmd)
return;
}
cmds[n] = cmd;
cmds[n] = strdup(cmd);
}
static void usage(void)
@@ -94,8 +92,8 @@ static void usage(void)
"Options :\n"
" -l user : log in as user\n"
" -p port : connect to port\n"
" -d : use DSS to verify host public key\n"
" -r : use RSA to verify host public key\n"
" -F file : parse configuration file instead of default one\n"
#ifdef WITH_PCAP
" -P file : create a pcap debugging file\n"
#endif
@@ -112,14 +110,11 @@ static int opts(int argc, char **argv)
{
int i;
while((i = getopt(argc,argv,"T:P:F:")) != -1) {
while((i = getopt(argc,argv,"T:P:")) != -1) {
switch(i){
case 'P':
pcap_file = optarg;
break;
case 'F':
config_file = optarg;
break;
#ifndef _WIN32
case 'T':
proxycommand = optarg;
@@ -127,7 +122,7 @@ static int opts(int argc, char **argv)
#endif
default:
fprintf(stderr, "Unknown option %c\n", optopt);
return -1;
usage();
}
}
if (optind < argc) {
@@ -139,7 +134,7 @@ static int opts(int argc, char **argv)
}
if (host == NULL) {
return -1;
usage();
}
return 0;
@@ -174,25 +169,22 @@ static void do_exit(int i)
exit(0);
}
static ssh_channel chan;
static int signal_delayed = 0;
#ifdef SIGWINCH
static void sigwindowchanged(int i)
{
(void) i;
signal_delayed = 1;
}
#endif
static void setsignal(void)
{
#ifdef SIGWINCH
signal(SIGWINCH, sigwindowchanged);
#endif
signal_delayed = 0;
}
static void sizechanged(ssh_channel chan)
static void sizechanged(void)
{
struct winsize win = {
.ws_row = 0,
@@ -230,7 +222,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
while (ssh_channel_is_open(channel)) {
if (signal_delayed) {
sizechanged(channel);
sizechanged();
}
rc = ssh_event_dopoll(event, 60000);
if (rc == SSH_ERROR) {
@@ -251,7 +243,7 @@ static void select_loop(ssh_session session,ssh_channel channel)
static void shell(ssh_session session)
{
ssh_channel channel = NULL;
ssh_channel channel;
struct termios terminal_local;
int interactive=isatty(0);
@@ -270,9 +262,10 @@ static void shell(ssh_session session)
ssh_channel_free(channel);
return;
}
chan = channel;
if (interactive) {
ssh_channel_request_pty(channel);
sizechanged(channel);
sizechanged();
}
if (ssh_channel_request_shell(channel)) {
@@ -297,41 +290,27 @@ static void shell(ssh_session session)
static void batch_shell(ssh_session session)
{
ssh_channel channel;
char *buffer = NULL;
size_t i, s, n;
char buffer[1024];
size_t i;
int s = 0;
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
free(cmds[i]);
cmds[i] = NULL;
}
channel = ssh_channel_new(session);
if (channel == NULL) {
return;
}
n = 0;
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
/* Including space after cmds[i] */
n += strlen(cmds[i]) + 1;
}
/* Trailing \0 */
n += 1;
buffer = malloc(n);
if (buffer == NULL) {
ssh_channel_free(channel);
return;
}
s = 0;
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
s += snprintf(buffer + s, n - s, "%s ", cmds[i]);
}
ssh_channel_open_session(channel);
if (ssh_channel_request_exec(channel, buffer)) {
printf("Error executing '%s' : %s\n", buffer, ssh_get_error(session));
free(buffer);
ssh_channel_free(channel);
return;
}
free(buffer);
select_loop(session, channel);
ssh_channel_free(channel);
}
@@ -339,7 +318,7 @@ static void batch_shell(ssh_session session)
static int client(ssh_session session)
{
int auth = 0;
char *banner = NULL;
char *banner;
int state;
if (user) {
@@ -347,7 +326,7 @@ static int client(ssh_session session)
return -1;
}
}
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0) {
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0) {
return -1;
}
if (proxycommand != NULL) {
@@ -355,13 +334,7 @@ static int client(ssh_session session)
return -1;
}
}
/* Parse configuration file if specified: The command-line options will
* overwrite items loaded from configuration file */
if (config_file != NULL) {
ssh_options_parse_config(session, config_file);
} else {
ssh_options_parse_config(session, NULL);
}
ssh_options_parse_config(session, NULL);
if (ssh_connect(session)) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
@@ -423,22 +396,20 @@ static void cleanup_pcap(void)
int main(int argc, char **argv)
{
ssh_session session = NULL;
ssh_session session;
ssh_init();
session = ssh_new();
ssh_callbacks_init(&cb);
ssh_set_callbacks(session,&cb);
if (ssh_options_getopt(session, &argc, argv) || opts(argc, argv)) {
if (ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr,
"Error parsing command line: %s\n",
ssh_get_error(session));
ssh_free(session);
ssh_finalize();
usage();
}
opts(argc, argv);
signal(SIGTERM, do_exit);
set_pcap(session);

View File

@@ -24,7 +24,6 @@ The goal is to show the API in action.
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#include <pthread.h>
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
@@ -41,18 +40,41 @@ The goal is to show the API in action.
#include <sys/stat.h>
#include <stdio.h>
#ifndef BUF_SIZE
#define BUF_SIZE 1048576
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#define USER "myuser"
#define PASS "mypassword"
#define BUF_SIZE 1048576
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
#define AUTH_KEYS_MAX_LINE_SIZE 2048
static void set_default_keys(ssh_bind sshbind,
int rsa_already_set,
int dsa_already_set,
int ecdsa_already_set) {
if (!rsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
KEYS_FOLDER "ssh_host_rsa_key");
}
if (!dsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
KEYS_FOLDER "ssh_host_dsa_key");
}
if (!ecdsa_already_set) {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
KEYS_FOLDER "ssh_host_ecdsa_key");
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
KEYS_FOLDER "ssh_host_ed25519_key");
}
#define DEF_STR_SIZE 1024
char authorizedkeys[DEF_STR_SIZE] = {0};
char username[128] = "myuser";
char password[128] = "mypassword";
#ifdef HAVE_ARGP_H
const char *argp_program_version = "libssh server example "
SSH_STRINGIFY(LIBSSH_VERSION);
@@ -83,12 +105,20 @@ static struct argp_option options[] = {
"Implies no default keys.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key (deprecated alias for 'k').",
.doc = "Set the rsa key.",
.group = 0
},
{
@@ -96,7 +126,7 @@ static struct argp_option options[] = {
.key = 'e',
.arg = "FILE",
.flags = 0,
.doc = "Set the ecdsa key (deprecated alias for 'k').",
.doc = "Set the ecdsa key.",
.group = 0
},
{
@@ -108,19 +138,11 @@ static struct argp_option options[] = {
.group = 0
},
{
.name = "user",
.key = 'u',
.arg = "USERNAME",
.name = "no-default-keys",
.key = 'n',
.arg = NULL,
.flags = 0,
.doc = "Set expected username.",
.group = 0
},
{
.name = "pass",
.key = 'P',
.arg = "PASSWORD",
.flags = 0,
.doc = "Set expected password.",
.doc = "Do not set default key locations.",
.group = 0
},
{
@@ -135,120 +157,75 @@ static struct argp_option options[] = {
};
/* Parse a single option. */
static error_t
parse_opt(int key, char *arg, struct argp_state *state)
{
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
/* Get the input argument from argp_parse, which we
* know is a pointer to our arguments structure. */
ssh_bind sshbind = state->input;
static int no_default_keys = 0;
static int rsa_already_set = 0, dsa_already_set = 0, ecdsa_already_set = 0;
switch (key) {
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'e':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'a':
strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1);
break;
case 'u':
strncpy(username, arg, sizeof(username) - 1);
break;
case 'P':
strncpy(password, arg, sizeof(password) - 1);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage(state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage(state);
}
break;
default:
return ARGP_ERR_UNKNOWN;
case 'n':
no_default_keys = 1;
break;
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
dsa_already_set = 1;
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
/* We can't track the types of keys being added with this
option, so let's ensure we keep the keys we're adding
by just not setting the default keys */
no_default_keys = 1;
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
rsa_already_set = 1;
break;
case 'e':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
ecdsa_already_set = 1;
break;
case 'a':
strncpy(authorizedkeys, arg, DEF_STR_SIZE-1);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
"3");
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1) {
/* Too many arguments. */
argp_usage (state);
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
break;
case ARGP_KEY_END:
if (state->arg_num < 1) {
/* Not enough arguments. */
argp_usage (state);
}
if (!no_default_keys) {
set_default_keys(sshbind,
rsa_already_set,
dsa_already_set,
ecdsa_already_set);
}
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#else
static int
parse_opt(int argc, char **argv, ssh_bind sshbind)
{
int key;
while((key = getopt(argc, argv, "a:e:k:p:P:r:u:v")) != -1) {
if (key == 'p') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, optarg);
} else if (key == 'k') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
} else if (key == 'r') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
} else if (key == 'e') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
} else if (key == 'a') {
strncpy(authorizedkeys, optarg, DEF_STR_SIZE-1);
} else if (key == 'u') {
strncpy(username, optarg, sizeof(username) - 1);
} else if (key == 'P') {
strncpy(password, optarg, sizeof(password) - 1);
} else if (key == 'v') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
"3");
} else {
break;
}
}
if (key != -1) {
printf("Usage: %s [OPTION...] BINDADDR\n"
"libssh %s -- a Secure Shell protocol implementation\n"
"\n"
" -a, --authorizedkeys=FILE Set the authorized keys file.\n"
" -e, --ecdsakey=FILE Set the ecdsa key (deprecated alias for 'k').\n"
" -k, --hostkey=FILE Set a host key. Can be used multiple times.\n"
" Implies no default keys.\n"
" -p, --port=PORT Set the port to bind.\n"
" -P, --pass=PASSWORD Set expected password.\n"
" -r, --rsakey=FILE Set the rsa key (deprecated alias for 'k').\n"
" -u, --user=USERNAME Set expected username.\n"
" -v, --verbose Get verbose output.\n"
" -?, --help Give this help list\n"
"\n"
"Mandatory or optional arguments to long options are also mandatory or optional\n"
"for any corresponding short options.\n"
"\n"
"Report bugs to <libssh@libssh.org>.\n",
argv[0], SSH_STRINGIFY(LIBSSH_VERSION));
return -1;
}
if (optind != argc - 1) {
printf("Usage: %s [OPTION...] BINDADDR\n", argv[0]);
return -1;
}
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, argv[optind]);
return 0;
}
#endif /* HAVE_ARGP_H */
/* A userdata struct for channel. */
@@ -277,74 +254,49 @@ struct session_data_struct {
int authenticated;
};
static int
data_function(ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata)
{
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
static int data_function(ssh_session session, ssh_channel channel, void *data,
uint32_t len, int is_stderr, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void)session;
(void)channel;
(void)is_stderr;
(void) session;
(void) channel;
(void) is_stderr;
if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) {
return 0;
}
return write(cdata->child_stdin, (char *)data, len);
return write(cdata->child_stdin, (char *) data, len);
}
static int
pty_request(ssh_session session,
ssh_channel channel,
const char *term,
int cols,
int rows,
int py,
int px,
void *userdata)
{
static int pty_request(ssh_session session, ssh_channel channel,
const char *term, int cols, int rows, int py, int px,
void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
int rc;
(void)session;
(void)channel;
(void)term;
(void) session;
(void) channel;
(void) term;
cdata->winsize->ws_row = rows;
cdata->winsize->ws_col = cols;
cdata->winsize->ws_xpixel = px;
cdata->winsize->ws_ypixel = py;
rc = openpty(&cdata->pty_master,
&cdata->pty_slave,
NULL,
NULL,
cdata->winsize);
if (rc != 0) {
if (openpty(&cdata->pty_master, &cdata->pty_slave, NULL, NULL,
cdata->winsize) != 0) {
fprintf(stderr, "Failed to open pty\n");
return SSH_ERROR;
}
return SSH_OK;
}
static int
pty_resize(ssh_session session,
ssh_channel channel,
int cols,
int rows,
int py,
int px,
void *userdata)
{
static int pty_resize(ssh_session session, ssh_channel channel, int cols,
int rows, int py, int px, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
(void)session;
(void)channel;
(void) session;
(void) channel;
cdata->winsize->ws_row = rows;
cdata->winsize->ws_col = cols;
@@ -358,36 +310,30 @@ pty_resize(ssh_session session,
return SSH_ERROR;
}
static int
exec_pty(const char *mode,
const char *command,
struct channel_data_struct *cdata)
{
cdata->pid = fork();
switch (cdata->pid) {
case -1:
close(cdata->pty_master);
close(cdata->pty_slave);
fprintf(stderr, "Failed to fork\n");
return SSH_ERROR;
case 0:
close(cdata->pty_master);
if (login_tty(cdata->pty_slave) != 0) {
exit(1);
}
execl("/bin/sh", "sh", mode, command, NULL);
exit(0);
default:
close(cdata->pty_slave);
/* pty fd is bi-directional */
cdata->child_stdout = cdata->child_stdin = cdata->pty_master;
static int exec_pty(const char *mode, const char *command,
struct channel_data_struct *cdata) {
switch(cdata->pid = fork()) {
case -1:
close(cdata->pty_master);
close(cdata->pty_slave);
fprintf(stderr, "Failed to fork\n");
return SSH_ERROR;
case 0:
close(cdata->pty_master);
if (login_tty(cdata->pty_slave) != 0) {
exit(1);
}
execl("/bin/sh", "sh", mode, command, NULL);
exit(0);
default:
close(cdata->pty_slave);
/* pty fd is bi-directional */
cdata->child_stdout = cdata->child_stdin = cdata->pty_master;
}
return SSH_OK;
}
static int
exec_nopty(const char *command, struct channel_data_struct *cdata)
{
static int exec_nopty(const char *command, struct channel_data_struct *cdata) {
int in[2], out[2], err[2];
/* Do the plumbing to be able to talk with the child process. */
@@ -401,24 +347,23 @@ exec_nopty(const char *command, struct channel_data_struct *cdata)
goto stderr_failed;
}
cdata->pid = fork();
switch (cdata->pid) {
case -1:
goto fork_failed;
case 0:
/* Finish the plumbing in the child process. */
close(in[1]);
close(out[0]);
close(err[0]);
dup2(in[0], STDIN_FILENO);
dup2(out[1], STDOUT_FILENO);
dup2(err[1], STDERR_FILENO);
close(in[0]);
close(out[1]);
close(err[1]);
/* exec the requested command. */
execl("/bin/sh", "sh", "-c", command, NULL);
exit(0);
switch(cdata->pid = fork()) {
case -1:
goto fork_failed;
case 0:
/* Finish the plumbing in the child process. */
close(in[1]);
close(out[0]);
close(err[0]);
dup2(in[0], STDIN_FILENO);
dup2(out[1], STDOUT_FILENO);
dup2(err[1], STDERR_FILENO);
close(in[0]);
close(out[1]);
close(err[1]);
/* exec the requested command. */
execl("/bin/sh", "sh", "-c", command, NULL);
exit(0);
}
close(in[0]);
@@ -444,18 +389,15 @@ stdin_failed:
return SSH_ERROR;
}
static int
exec_request(ssh_session session,
ssh_channel channel,
const char *command,
void *userdata)
{
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
static int exec_request(ssh_session session, ssh_channel channel,
const char *command, void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void)session;
(void)channel;
if (cdata->pid > 0) {
(void) session;
(void) channel;
if(cdata->pid > 0) {
return SSH_ERROR;
}
@@ -465,15 +407,14 @@ exec_request(ssh_session session,
return exec_nopty(command, cdata);
}
static int
shell_request(ssh_session session, ssh_channel channel, void *userdata)
{
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
static int shell_request(ssh_session session, ssh_channel channel,
void *userdata) {
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
(void)session;
(void)channel;
(void) session;
(void) channel;
if (cdata->pid > 0) {
if(cdata->pid > 0) {
return SSH_ERROR;
}
@@ -484,30 +425,22 @@ shell_request(ssh_session session, ssh_channel channel, void *userdata)
return SSH_OK;
}
static int
subsystem_request(ssh_session session,
ssh_channel channel,
const char *subsystem,
void *userdata)
{
/* subsystem requests behave similarly to exec requests. */
static int subsystem_request(ssh_session session, ssh_channel channel,
const char *subsystem, void *userdata) {
/* subsystem requests behave simillarly to exec requests. */
if (strcmp(subsystem, "sftp") == 0) {
return exec_request(session, channel, SFTP_SERVER_PATH, userdata);
}
return SSH_ERROR;
}
static int
auth_password(ssh_session session,
const char *user,
const char *pass,
void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
static int auth_password(ssh_session session, const char *user,
const char *pass, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
(void)session;
(void) session;
if (strcmp(user, username) == 0 && strcmp(pass, password) == 0) {
if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0) {
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
@@ -516,26 +449,16 @@ auth_password(ssh_session session,
return SSH_AUTH_DENIED;
}
static int
auth_publickey(ssh_session session,
const char *user,
struct ssh_key_struct *pubkey,
char signature_state,
void *userdata)
static int auth_publickey(ssh_session session,
const char *user,
struct ssh_key_struct *pubkey,
char signature_state,
void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
ssh_key key = NULL;
FILE *fp = NULL;
char line[AUTH_KEYS_MAX_LINE_SIZE] = {0};
char *p = NULL;
const char *q = NULL;
unsigned int lineno = 0;
int result;
int i;
enum ssh_keytypes_e type;
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
(void)user;
(void)session;
(void) user;
(void) session;
if (signature_state == SSH_PUBLICKEY_STATE_NONE) {
return SSH_AUTH_SUCCESS;
@@ -545,107 +468,45 @@ auth_publickey(ssh_session session,
return SSH_AUTH_DENIED;
}
fp = fopen(authorizedkeys, "r");
if (fp == NULL) {
fprintf(stderr, "Error: opening authorized keys file %s failed, reason: %s\n",
authorizedkeys, strerror(errno));
return SSH_AUTH_DENIED;
}
// valid so far. Now look through authorized keys for a match
if (authorizedkeys[0]) {
ssh_key key = NULL;
int result;
struct stat buf;
while (fgets(line, sizeof(line), fp)) {
lineno++;
/* Skip leading whitespace and ignore comments */
p = line;
for (i = 0; i < AUTH_KEYS_MAX_LINE_SIZE; i++) {
if (!isspace((int)p[i])) {
break;
if (stat(authorizedkeys, &buf) == 0) {
result = ssh_pki_import_pubkey_file( authorizedkeys, &key );
if ((result != SSH_OK) || (key==NULL)) {
fprintf(stderr,
"Unable to import public key file %s\n",
authorizedkeys);
} else {
result = ssh_key_cmp( key, pubkey, SSH_KEY_CMP_PUBLIC );
ssh_key_free(key);
if (result == 0) {
sdata->authenticated = 1;
return SSH_AUTH_SUCCESS;
}
}
}
if (i >= AUTH_KEYS_MAX_LINE_SIZE) {
fprintf(stderr,
"warning: The line %d in %s too long! Skipping.\n",
lineno,
authorizedkeys);
continue;
}
if (p[i] == '#' || p[i] == '\0' || p[i] == '\n') {
continue;
}
q = &p[i];
for (; i < AUTH_KEYS_MAX_LINE_SIZE; i++) {
if (isspace((int)p[i])) {
p[i] = '\0';
break;
}
}
type = ssh_key_type_from_name(q);
i++;
if (i >= AUTH_KEYS_MAX_LINE_SIZE) {
fprintf(stderr,
"warning: The line %d in %s too long! Skipping.\n",
lineno,
authorizedkeys);
continue;
}
q = &p[i];
for (; i < AUTH_KEYS_MAX_LINE_SIZE; i++) {
if (isspace((int)p[i])) {
p[i] = '\0';
break;
}
}
result = ssh_pki_import_pubkey_base64(q, type, &key);
if (result != SSH_OK) {
fprintf(stderr,
"Warning: Cannot import key on line no. %d in authorized keys file: %s\n",
lineno,
authorizedkeys);
continue;
}
result = ssh_key_cmp(key, pubkey, SSH_KEY_CMP_PUBLIC);
ssh_key_free(key);
if (result == 0) {
sdata->authenticated = 1;
fclose(fp);
return SSH_AUTH_SUCCESS;
}
}
if (ferror(fp) != 0) {
fprintf(stderr,
"Error: Reading from authorized keys file %s failed, reason: %s\n",
authorizedkeys, strerror(errno));
}
fclose(fp);
/* no matches */
// no matches
sdata->authenticated = 0;
return SSH_AUTH_DENIED;
}
static ssh_channel
channel_open(ssh_session session, void *userdata)
{
struct session_data_struct *sdata = (struct session_data_struct *)userdata;
static ssh_channel channel_open(ssh_session session, void *userdata) {
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
sdata->channel = ssh_channel_new(session);
return sdata->channel;
}
static int
process_stdout(socket_t fd, int revents, void *userdata)
{
static int process_stdout(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel)userdata;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
@@ -657,12 +518,10 @@ process_stdout(socket_t fd, int revents, void *userdata)
return n;
}
static int
process_stderr(socket_t fd, int revents, void *userdata)
{
static int process_stderr(socket_t fd, int revents, void *userdata) {
char buf[BUF_SIZE];
int n = -1;
ssh_channel channel = (ssh_channel)userdata;
ssh_channel channel = (ssh_channel) userdata;
if (channel != NULL && (revents & POLLIN) != 0) {
n = read(fd, buf, BUF_SIZE);
@@ -674,9 +533,7 @@ process_stderr(socket_t fd, int revents, void *userdata)
return n;
}
static void
handle_session(ssh_event event, ssh_session session)
{
static void handle_session(ssh_event event, ssh_session session) {
int n;
int rc = 0;
@@ -789,8 +646,8 @@ handle_session(ssh_event event, ssh_session session)
ssh_channel_close(sdata.channel);
}
}
} while (ssh_channel_is_open(sdata.channel) &&
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
} while(ssh_channel_is_open(sdata.channel) &&
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
close(cdata.pty_master);
close(cdata.child_stdin);
@@ -821,41 +678,18 @@ handle_session(ssh_event event, ssh_session session)
}
}
#ifdef WITH_FORK
/* SIGCHLD handler for cleaning up dead children. */
static void sigchld_handler(int signo)
{
(void)signo;
static void sigchld_handler(int signo) {
(void) signo;
while (waitpid(-1, NULL, WNOHANG) > 0);
}
#else
static void *session_thread(void *arg)
{
ssh_session session = arg;
int main(int argc, char **argv) {
ssh_bind sshbind;
ssh_session session;
ssh_event event;
event = ssh_event_new();
if (event != NULL) {
/* Blocks until the SSH session ends by either
* child thread exiting, or client disconnecting. */
handle_session(event, session);
ssh_event_free(event);
} else {
fprintf(stderr, "Could not create polling context\n");
}
ssh_disconnect(session);
ssh_free(session);
return NULL;
}
#endif
int main(int argc, char **argv)
{
ssh_bind sshbind = NULL;
ssh_session session = NULL;
int rc;
#ifdef WITH_FORK
struct sigaction sa;
int rc;
/* Set up SIGCHLD handler. */
sa.sa_handler = sigchld_handler;
@@ -865,7 +699,6 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to register SIGCHLD handler\n");
return 1;
}
#endif
rc = ssh_init();
if (rc < 0) {
@@ -876,25 +709,20 @@ int main(int argc, char **argv)
sshbind = ssh_bind_new();
if (sshbind == NULL) {
fprintf(stderr, "ssh_bind_new failed\n");
ssh_finalize();
return 1;
}
#ifdef HAVE_ARGP_H
argp_parse(&argp, argc, argv, 0, 0, sshbind);
#else
if (parse_opt(argc, argv, sshbind) < 0) {
ssh_bind_free(sshbind);
ssh_finalize();
return 1;
}
(void) argc;
(void) argv;
set_default_keys(sshbind, 0, 0, 0);
#endif /* HAVE_ARGP_H */
rc = ssh_bind_listen(sshbind);
if (rc < 0) {
if(ssh_bind_listen(sshbind) < 0) {
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
ssh_bind_free(sshbind);
ssh_finalize();
return 1;
}
@@ -906,47 +734,32 @@ int main(int argc, char **argv)
}
/* Blocks until there is a new incoming connection. */
rc = ssh_bind_accept(sshbind, session);
if (rc != SSH_ERROR) {
#ifdef WITH_FORK
ssh_event event;
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
switch(fork()) {
case 0:
/* Remove the SIGCHLD handler inherited from parent. */
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
/* Remove socket binding, which allows us to restart the
* parent process, without terminating existing sessions. */
ssh_bind_free(sshbind);
pid_t pid = fork();
switch (pid) {
case 0:
/* Remove the SIGCHLD handler inherited from parent. */
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
/* Remove socket binding, which allows us to restart the
* parent process, without terminating existing sessions. */
ssh_bind_free(sshbind);
event = ssh_event_new();
if (event != NULL) {
/* Blocks until the SSH session ends by either
* child process exiting, or client disconnecting. */
handle_session(event, session);
ssh_event_free(event);
} else {
fprintf(stderr, "Could not create polling context\n");
}
ssh_disconnect(session);
ssh_free(session);
event = ssh_event_new();
if (event != NULL) {
/* Blocks until the SSH session ends by either
* child process exiting, or client disconnecting. */
handle_session(event, session);
ssh_event_free(event);
} else {
fprintf(stderr, "Could not create polling context\n");
}
ssh_disconnect(session);
ssh_free(session);
exit(0);
case -1:
fprintf(stderr, "Failed to fork\n");
exit(0);
case -1:
fprintf(stderr, "Failed to fork\n");
}
#else
pthread_t tid;
rc = pthread_create(&tid, NULL, session_thread, session);
if (rc == 0) {
pthread_detach(tid);
continue;
}
fprintf(stderr, "Failed to pthread_create\n");
#endif
} else {
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
}

View File

@@ -15,7 +15,7 @@ clients must be made or how a client should react.
/*
Example:
./sshd_direct-tcpip -v -p 2022 -r serverkey.rsa 127.0.0.1
./sshd_direct-tcpip -v -p 2022 -d serverkey.dsa -r serverkey.rsa 127.0.0.1
*/
#include "config.h"
@@ -27,9 +27,6 @@ clients must be made or how a client should react.
#ifdef HAVE_ARGP_H
#include <argp.h>
#endif
#ifndef _WIN32
#include <netinet/in.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <stdbool.h>
@@ -38,10 +35,6 @@ clients must be made or how a client should react.
#include <stdio.h>
#include <poll.h>
#ifndef BUF_SIZE
#define BUF_SIZE 16384
#endif
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
#ifndef __unused__
@@ -94,11 +87,8 @@ cleanup_push(struct cleanup_node_struct** head_ref,
{
// Allocate memory for node
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
if (new_node == NULL) {
return;
}
if (*head_ref != NULL) {
if (head_ref != NULL) {
new_node->next = *head_ref;
} else {
new_node->next = NULL;
@@ -203,7 +193,7 @@ subsystem_request(UNUSED_PARAM(ssh_session session),
UNUSED_PARAM(void *userdata))
{
_ssh_log(SSH_LOG_PROTOCOL,
"=== subsystem_request", "Channel subsystem request: %s",
"=== subsystem_request", "Channel subsystem reqeuest: %s",
subsystem);
return 0;
}
@@ -299,7 +289,7 @@ my_channel_eof_function(ssh_session session,
_ssh_log(SSH_LOG_PROTOCOL,
"=== my_channel_eof_function",
"Got EOF on channel. Shutting down write on socket (fd = %d).",
"Got EOF on channel. Shuting down write on socket (fd = %d).",
*event_fd_data->p_fd);
stack_socket_close(session, event_fd_data);
@@ -361,9 +351,9 @@ my_fd_data_function(UNUSED_PARAM(socket_t fd),
{
struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata;
ssh_channel channel = event_fd_data->channel;
ssh_session session = NULL;
ssh_session session;
int len, i, wr;
char buf[BUF_SIZE];
char buf[16384];
int blocking;
if (channel == NULL) {
@@ -428,7 +418,7 @@ my_fd_data_function(UNUSED_PARAM(socket_t fd),
break;
}
wr += i;
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "ssh_channel_write (%d from %d)", wr, len);
_ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel_write (%d from %d)", wr, len);
} while (i > 0 && wr < len);
}
else {
@@ -455,8 +445,8 @@ open_tcp_socket(ssh_message msg)
{
struct sockaddr_in sin;
int forwardsock = -1;
struct hostent *host = NULL;
const char *dest_hostname = NULL;
struct hostent *host;
const char *dest_hostname;
int dest_port;
forwardsock = socket(AF_INET, SOCK_STREAM, 0);
@@ -499,8 +489,8 @@ message_callback(UNUSED_PARAM(ssh_session session),
UNUSED_PARAM(void *userdata))
{
ssh_channel channel;
int socket_fd, *pFd = NULL;
struct ssh_channel_callbacks_struct *cb_chan = NULL;
int socket_fd, *pFd;
struct ssh_channel_callbacks_struct *cb_chan;
struct event_fd_data_struct *event_fd_data;
_ssh_log(SSH_LOG_PACKET, "=== message_callback", "Message type: %d",
@@ -526,13 +516,12 @@ message_callback(UNUSED_PARAM(ssh_session session),
}
pFd = malloc(sizeof *pFd);
cb_chan = calloc(1, sizeof *cb_chan);
cb_chan = malloc(sizeof *cb_chan);
event_fd_data = malloc(sizeof *event_fd_data);
if (pFd == NULL || cb_chan == NULL || event_fd_data == NULL) {
SAFE_FREE(pFd);
SAFE_FREE(cb_chan);
SAFE_FREE(event_fd_data);
close(socket_fd);
return 1;
}
@@ -589,12 +578,20 @@ static struct argp_option options[] = {
.doc = "Set the host key.",
.group = 0
},
{
.name = "dsakey",
.key = 'd',
.arg = "FILE",
.flags = 0,
.doc = "Set the dsa key.",
.group = 0
},
{
.name = "rsakey",
.key = 'r',
.arg = "FILE",
.flags = 0,
.doc = "Set the rsa key (deprecated alias for 'k').",
.doc = "Set the rsa key.",
.group = 0
},
{
@@ -621,10 +618,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'p':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
break;
case 'r':
case 'd':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
break;
case 'k':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
break;
case 'r':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
break;
case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "1");
break;
@@ -655,8 +657,8 @@ static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
int
main(int argc, char **argv)
{
ssh_session session = NULL;
ssh_bind sshbind = NULL;
ssh_session session;
ssh_bind sshbind;
struct ssh_server_callbacks_struct cb = {
.userdata = NULL,
.auth_password_function = auth_password,
@@ -675,7 +677,8 @@ main(int argc, char **argv)
session = ssh_new();
mainloop = ssh_event_new();
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, KEYS_FOLDER "ssh_host_rsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
#ifdef HAVE_ARGP_H
/*

View File

@@ -34,242 +34,223 @@ clients must be made or how a client should react.
#include <fcntl.h>
#include "examples_common.h"
#ifndef BUF_SIZE
#define BUF_SIZE 4096
#endif
char *host = NULL;
const char *desthost = "localhost";
const char *port = "22";
char *host;
const char *desthost="localhost";
const char *port="22";
#ifdef WITH_PCAP
#include <libssh/pcap.h>
char *pcap_file = NULL;
char *pcap_file=NULL;
#endif
static void usage(void)
{
fprintf(stderr,
"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
exit(1);
fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
exit(1);
}
static int opts(int argc, char **argv)
{
static int opts(int argc, char **argv){
int i;
while ((i = getopt(argc, argv, "P:")) != -1) {
switch (i) {
while((i=getopt(argc,argv,"P:"))!=-1){
switch(i){
#ifdef WITH_PCAP
case 'P':
pcap_file = optarg;
break;
case 'P':
pcap_file=optarg;
break;
#endif
default:
fprintf(stderr, "unknown option %c\n", optopt);
usage();
default:
fprintf(stderr,"unknown option %c\n",optopt);
usage();
}
}
if (optind < argc)
host = argv[optind++];
if (optind < argc)
desthost = argv[optind++];
if (optind < argc)
port = argv[optind++];
if (host == NULL)
if(optind < argc)
host=argv[optind++];
if(optind < argc)
desthost=argv[optind++];
if(optind < argc)
port=argv[optind++];
if(host==NULL)
usage();
return 0;
}
static void select_loop(ssh_session session, ssh_channel channel)
{
fd_set fds;
struct timeval timeout;
char buffer[BUF_SIZE];
/* channels will be set to the channels to poll.
* outchannels will contain the result of the poll
*/
ssh_channel channels[2], outchannels[2];
int lus;
int eof = 0;
int maxfd;
int ret;
while (channel) {
do {
static void select_loop(ssh_session session,ssh_channel channel){
fd_set fds;
struct timeval timeout;
char buffer[4096];
/* channels will be set to the channels to poll.
* outchannels will contain the result of the poll
*/
ssh_channel channels[2], outchannels[2];
int lus;
int eof=0;
int maxfd;
int ret;
while(channel){
do{
int fd;
ZERO_STRUCT(fds);
FD_ZERO(&fds);
if (!eof)
FD_SET(0, &fds);
timeout.tv_sec = 30;
timeout.tv_usec = 0;
FD_ZERO(&fds);
if(!eof)
FD_SET(0,&fds);
timeout.tv_sec=30;
timeout.tv_usec=0;
fd = ssh_get_fd(session);
if (fd == -1) {
fprintf(stderr,
"Error getting the session file descriptor: %s\n",
ssh_get_error(session));
fprintf(stderr, "Error getting the session file descriptor: %s\n",
ssh_get_error(session));
return;
}
FD_SET(fd, &fds);
maxfd = fd + 1;
channels[0] = channel; // set the first channel we want to read from
channels[1] = NULL;
ret = ssh_select(channels, outchannels, maxfd, &fds, &timeout);
if (ret == EINTR)
continue;
if (FD_ISSET(0, &fds)) {
lus = read(0, buffer, sizeof(buffer));
if (lus)
ssh_channel_write(channel, buffer, lus);
else {
eof = 1;
ssh_channel_send_eof(channel);
}
}
if (channel && ssh_channel_is_closed(channel)) {
ssh_channel_free(channel);
channel = NULL;
channels[0] = NULL;
}
if (outchannels[0]) {
while (channel && ssh_channel_is_open(channel) &&
ssh_channel_poll(channel, 0)) {
lus = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
if (lus == -1) {
fprintf(stderr,
"Error reading channel: %s\n",
ssh_get_error(session));
return;
channels[0]=channel; // set the first channel we want to read from
channels[1]=NULL;
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
if(ret==EINTR)
continue;
if(FD_ISSET(0,&fds)){
lus=read(0,buffer,sizeof(buffer));
if(lus)
ssh_channel_write(channel,buffer,lus);
else {
eof=1;
ssh_channel_send_eof(channel);
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
channels[0]=NULL;
}
if(outchannels[0]){
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)){
lus = ssh_channel_read(channel,buffer,sizeof(buffer),0);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else {
ret = write(1, buffer, lus);
if (ret < 0) {
fprintf(stderr, "Error writing to stdin: %s",
strerror(errno));
return;
}
}
}
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)){ /* stderr */
lus = ssh_channel_read(channel, buffer, sizeof(buffer), 1);
if(lus==-1){
fprintf(stderr, "Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if(lus==0){
ssh_channel_free(channel);
channel=channels[0]=NULL;
} else {
ret = write(2, buffer, lus);
if (ret < 0) {
fprintf(stderr, "Error writing to stderr: %s",
strerror(errno));
return;
}
}
if (lus == 0) {
ssh_channel_free(channel);
channel = channels[0] = NULL;
} else {
ret = write(1, buffer, lus);
if (ret < 0) {
fprintf(stderr,
"Error writing to stdin: %s",
strerror(errno));
return;
}
}
}
while (channel && ssh_channel_is_open(channel) &&
ssh_channel_poll(channel, 1)) { /* stderr */
lus = ssh_channel_read(channel, buffer, sizeof(buffer), 1);
if (lus == -1) {
fprintf(stderr,
"Error reading channel: %s\n",
ssh_get_error(session));
return;
}
if (lus == 0) {
ssh_channel_free(channel);
channel = channels[0] = NULL;
} else {
ret = write(2, buffer, lus);
if (ret < 0) {
fprintf(stderr,
"Error writing to stderr: %s",
strerror(errno));
return;
}
}
}
}
if (channel && ssh_channel_is_closed(channel)) {
ssh_channel_free(channel);
channel = NULL;
}
} while (ret == EINTR || ret == SSH_EINTR);
}
}
}
if(channel && ssh_channel_is_closed(channel)){
ssh_channel_free(channel);
channel=NULL;
}
} while (ret==EINTR || ret==SSH_EINTR);
}
}
static void forwarding(ssh_session session)
{
static void forwarding(ssh_session session){
ssh_channel channel;
int r;
channel = ssh_channel_new(session);
r = ssh_channel_open_forward(channel, desthost, atoi(port), "localhost", 22);
if (r < 0) {
printf("error forwarding port : %s\n", ssh_get_error(session));
if(r<0) {
printf("error forwarding port : %s\n",ssh_get_error(session));
return;
}
select_loop(session, channel);
select_loop(session,channel);
}
static int client(ssh_session session)
{
int auth = 0;
char *banner = NULL;
int state;
static int client(ssh_session session){
int auth=0;
char *banner;
int state;
if (ssh_options_set(session, SSH_OPTIONS_HOST, host) < 0)
return -1;
ssh_options_parse_config(session, NULL);
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
return -1;
ssh_options_parse_config(session, NULL);
if (ssh_connect(session)) {
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
return -1;
}
state = verify_knownhost(session);
if (state != 0)
return -1;
ssh_userauth_none(session, NULL);
banner = ssh_get_issue_banner(session);
if (banner) {
printf("%s\n", banner);
free(banner);
}
auth = authenticate_console(session);
if (auth != SSH_AUTH_SUCCESS) {
return -1;
}
forwarding(session);
return 0;
if(ssh_connect(session)){
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
return -1;
}
state=verify_knownhost(session);
if (state != 0)
return -1;
ssh_userauth_none(session, NULL);
banner=ssh_get_issue_banner(session);
if(banner){
printf("%s\n",banner);
free(banner);
}
auth=authenticate_console(session);
if(auth != SSH_AUTH_SUCCESS){
return -1;
}
forwarding(session);
return 0;
}
#ifdef WITH_PCAP
ssh_pcap_file pcap;
void set_pcap(ssh_session session);
void set_pcap(ssh_session session)
{
if (!pcap_file)
return;
pcap = ssh_pcap_file_new();
if (ssh_pcap_file_open(pcap, pcap_file) == SSH_ERROR) {
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap = NULL;
return;
}
ssh_set_pcap_file(session, pcap);
void set_pcap(ssh_session session){
if(!pcap_file)
return;
pcap=ssh_pcap_file_new();
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
printf("Error opening pcap file\n");
ssh_pcap_file_free(pcap);
pcap=NULL;
return;
}
ssh_set_pcap_file(session,pcap);
}
void cleanup_pcap(void);
void cleanup_pcap(void)
{
ssh_pcap_file_free(pcap);
pcap = NULL;
ssh_pcap_file_free(pcap);
pcap = NULL;
}
#endif
int main(int argc, char **argv)
{
ssh_session session = NULL;
int main(int argc, char **argv){
ssh_session session;
session = ssh_new();
if (ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr,
"error parsing command line :%s\n",
ssh_get_error(session));
usage();
if(ssh_options_getopt(session, &argc, argv)) {
fprintf(stderr, "error parsing command line :%s\n",
ssh_get_error(session));
usage();
}
opts(argc, argv);
opts(argc,argv);
#ifdef WITH_PCAP
set_pcap(session);
#endif

View File

@@ -20,13 +20,6 @@ if (WITH_SERVER)
${libssh_HDRS}
server.h
)
if (WITH_SFTP)
set(libssh_HDRS
${libssh_HDRS}
sftpserver.h
)
endif (WITH_SFTP)
endif (WITH_SERVER)
install(

View File

@@ -70,10 +70,6 @@
#define SSH_AGENT_RSA_SHA2_256 0x02
#define SSH_AGENT_RSA_SHA2_512 0x04
#ifdef __cplusplus
extern "C" {
#endif
struct ssh_agent_struct {
struct ssh_socket_struct *sock;
ssh_buffer ident;
@@ -81,6 +77,7 @@ struct ssh_agent_struct {
ssh_channel channel;
};
#ifndef _WIN32
/* agent.c */
/**
* @brief Create a new ssh agent structure.
@@ -118,9 +115,6 @@ ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
ssh_string ssh_agent_sign_data(ssh_session session,
const ssh_key pubkey,
struct ssh_buffer_struct *data);
#ifdef __cplusplus
}
#endif
#endif /* __AGENT_H */

View File

@@ -23,10 +23,6 @@
#include "config.h"
#include "libssh/callbacks.h"
#ifdef __cplusplus
extern "C" {
#endif
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner);
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure);
SSH_PACKET_CALLBACK(ssh_packet_userauth_success);
@@ -104,8 +100,4 @@ enum ssh_auth_service_state_e {
SSH_AUTH_SERVICE_DENIED,
};
#ifdef __cplusplus
}
#endif
#endif /* AUTH_H_ */

View File

@@ -25,17 +25,9 @@
#include "libssh/libgcrypt.h"
#include "libssh/libmbedcrypto.h"
#ifdef __cplusplus
extern "C" {
#endif
bignum ssh_make_string_bn(ssh_string string);
ssh_string ssh_make_bignum_string(bignum num);
ssh_string ssh_make_padded_bignum_string(bignum num, size_t pad_len);
void ssh_print_bignum(const char *which, const_bignum num);
#ifdef __cplusplus
}
#endif
#endif /* BIGNUM_H_ */

View File

@@ -25,10 +25,6 @@
#include "libssh/kex.h"
#include "libssh/session.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ssh_bind_struct {
struct ssh_common_struct common; /* stuff common to ssh_bind and ssh_session */
struct ssh_bind_callbacks_struct *bind_callbacks;
@@ -39,9 +35,11 @@ struct ssh_bind_struct {
char *wanted_methods[SSH_KEX_METHODS];
char *banner;
char *ecdsakey;
char *dsakey;
char *rsakey;
char *ed25519key;
ssh_key ecdsa;
ssh_key dsa;
ssh_key rsa;
ssh_key ed25519;
char *bindaddr;
@@ -52,15 +50,10 @@ struct ssh_bind_struct {
bool config_processed;
char *config_dir;
char *pubkey_accepted_key_types;
char* moduli_file;
int rsa_min_size;
};
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
*sshbind);
#ifdef __cplusplus
}
#endif
#endif /* BIND_H_ */

View File

@@ -28,10 +28,6 @@
#include "libssh/server.h"
#ifdef __cplusplus
extern "C" {
#endif
enum ssh_bind_config_opcode_e {
/* Known but not allowed in Match block */
BIND_CFG_NOT_ALLOWED_IN_MATCH = -4,
@@ -65,18 +61,4 @@ enum ssh_bind_config_opcode_e {
*/
int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename);
/* @brief Parse configuration string and set the options to the given bind session
*
* @params[in] bind The ssh bind session
* @params[in] input Null terminated string containing the configuration
*
* @returns SSH_OK on successful parsing the configuration string,
* SSH_ERROR on error
*/
int ssh_bind_config_parse_string(ssh_bind bind, const char *input);
#ifdef __cplusplus
}
#endif
#endif /* BIND_CONFIG_H_ */

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: blf.h,v 1.8 2021/11/29 01:04:45 djm Exp $ */
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
/*
* Blowfish - a fast block cipher designed by Bruce Schneier
*
@@ -13,7 +13,10 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
@@ -46,10 +49,6 @@
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
#ifdef __cplusplus
extern "C" {
#endif
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
@@ -85,9 +84,4 @@ void ssh_blf_cbc_decrypt(ssh_blf_ctx *, uint8_t *, uint8_t *, uint32_t);
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t , uint16_t *);
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
#ifdef __cplusplus
}
#endif
#endif /* _BLF_H */

View File

@@ -27,10 +27,6 @@
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
#ifdef __cplusplus
extern "C" {
#endif
void ssh_buffer_set_secure(ssh_buffer buffer);
int ssh_buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
int ssh_buffer_add_u8(ssh_buffer buffer, uint8_t data);
@@ -42,6 +38,10 @@ int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len);
void *ssh_buffer_allocate(struct ssh_buffer_struct *buffer, uint32_t len);
int ssh_buffer_allocate_size(struct ssh_buffer_struct *buffer, uint32_t len);
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
va_list ap);
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer,
const char *format,
size_t argc,
@@ -63,9 +63,9 @@ int ssh_buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
int ssh_buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
uint32_t ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data);
uint32_t ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data);
uint32_t ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
int ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data);
int ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data);
int ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
/* ssh_buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
@@ -74,8 +74,4 @@ ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
uint32_t ssh_buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
uint32_t ssh_buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif /* BUFFER_H_ */

View File

@@ -27,7 +27,6 @@
#include <libssh/libssh.h>
#include <string.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@@ -57,7 +56,7 @@ typedef void (*ssh_callback_int) (int code, void *user);
* @returns number of bytes processed by the callee. The remaining bytes will
* be sent in the next callback message, when more data is available.
*/
typedef size_t (*ssh_callback_data) (const void *data, size_t len, void *user);
typedef int (*ssh_callback_data) (const void *data, size_t len, void *user);
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
@@ -82,9 +81,9 @@ typedef void (*ssh_log_callback) (ssh_session session, int priority,
*
* @param priority Priority of the log, the smaller being the more important.
*
* @param function The function name calling the logging functions.
* @param function The function name calling the the logging fucntions.
*
* @param buffer The actual message
* @param message The actual message
*
* @param userdata Userdata to be passed to the callback function.
*/
@@ -113,24 +112,11 @@ typedef void (*ssh_status_callback) (ssh_session session, float status,
typedef void (*ssh_global_request_callback) (ssh_session session,
ssh_message message, void *userdata);
/**
* @brief SSH connect status callback. These are functions that report the
* status of the connection i,e. a function indicating the completed percentage
* of the connection
* steps.
* @param userdata Userdata to be passed to the callback function.
* @param status Percentage of connection status, going from 0.0 to 1.0
* once connection is done.
*/
typedef void (*ssh_connect_status_callback)(void *userdata, float status);
/**
* @brief Handles an SSH new channel open X11 request. This happens when the server
* sends back an X11 connection attempt. This is a client-side API
* @param session current session handler
* @param userdata Userdata to be passed to the callback function.
* @param originator_address IP address of the machine who sent the request
* @param originator_port port number of the machine who sent the request
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the application.
@@ -150,26 +136,6 @@ typedef ssh_channel (*ssh_channel_open_request_x11_callback) (ssh_session sessio
typedef ssh_channel (*ssh_channel_open_request_auth_agent_callback) (ssh_session session,
void *userdata);
/**
* @brief Handles an SSH new channel open "forwarded-tcpip" request. This
* happens when the server forwards an incoming TCP connection on a port it was
* previously requested to listen on. This is a client-side API
* @param session current session handler
* @param destination_address the address that the TCP connection connected to
* @param destination_port the port that the TCP connection connected to
* @param originator_address the originator IP address
* @param originator_port the originator port
* @param userdata Userdata to be passed to the callback function.
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the
* application.
*/
typedef ssh_channel (*ssh_channel_open_request_forwarded_tcpip_callback) (ssh_session session,
const char *destination_address, int destination_port,
const char *originator_address, int originator_port,
void *userdata);
/**
* The structure to replace libssh functions with appropriate callbacks.
*/
@@ -192,7 +158,7 @@ struct ssh_callbacks_struct {
* This function gets called during connection time to indicate the
* percentage of connection steps completed.
*/
ssh_connect_status_callback connect_status_function;
void (*connect_status_function)(void *userdata, float status);
/**
* This function will be called each time a global request is received.
*/
@@ -203,11 +169,6 @@ struct ssh_callbacks_struct {
/** This function will be called when an incoming "auth-agent" request is received.
*/
ssh_channel_open_request_auth_agent_callback channel_open_request_auth_agent_function;
/**
* This function will be called when an incoming "forwarded-tcpip"
* request is received.
*/
ssh_channel_open_request_forwarded_tcpip_callback channel_open_request_forwarded_tcpip_function;
};
typedef struct ssh_callbacks_struct *ssh_callbacks;
@@ -260,8 +221,8 @@ typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *us
* @param user User that wants to authenticate
* @param pubkey public key used for authentication
* @param signature_state SSH_PUBLICKEY_STATE_NONE if the key is not signed (simple public key probe),
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
* replied with a SSH_AUTH_DENIED.
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
* replied with a SSH_AUTH_DENIED.
* @param userdata Userdata to be passed to the callback function.
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
@@ -294,7 +255,6 @@ typedef ssh_channel (*ssh_channel_open_request_session_callback) (ssh_session se
/*
* @brief handle the beginning of a GSSAPI authentication, server side.
* Callback should select the oid and also acquire the server credential.
* @param session current session handler
* @param user the username of the client
* @param n_oid number of available oids
@@ -308,11 +268,11 @@ typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const
int n_oid, ssh_string *oids, void *userdata);
/*
* @brief handle the negotiation of a security context, server side.
* @brief handle the negociation of a security context, server side.
* @param session current session handler
* @param[in] input_token input token provided by client
* @param[out] output_token output of the gssapi accept_sec_context method,
* NULL after completion.
* NULL after completion.
* @returns SSH_OK if the token was generated correctly or accept_sec_context
* returned GSS_S_COMPLETE
* @returns SSH_ERROR in case of error
@@ -336,28 +296,6 @@ typedef int (*ssh_gssapi_accept_sec_ctx_callback) (ssh_session session,
typedef int (*ssh_gssapi_verify_mic_callback) (ssh_session session,
ssh_string mic, void *mic_buffer, size_t mic_buffer_size, void *userdata);
/**
* @brief Handles an SSH new channel open "direct-tcpip" request. This
* happens when the client forwards an incoming TCP connection on a port it
* wants to forward to the destination. This is a server-side API
* @param session current session handler
* @param destination_address the address that the TCP connection connected to
* @param destination_port the port that the TCP connection connected to
* @param originator_address the originator IP address
* @param originator_port the originator port
* @param userdata Userdata to be passed to the callback function.
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the
* application.
*/
typedef ssh_channel (*ssh_channel_open_request_direct_tcpip_callback)(
ssh_session session,
const char *destination_address,
int destination_port,
const char *originator_address,
int originator_port,
void *userdata);
/**
* This structure can be used to implement a libssh server, with appropriate callbacks.
@@ -399,7 +337,6 @@ struct ssh_server_callbacks_struct {
*/
ssh_channel_open_request_session_callback channel_open_request_session_function;
/** This function will be called when a new gssapi authentication is attempted.
* This should select the oid and acquire credential for the server.
*/
ssh_gssapi_select_oid_callback gssapi_select_oid_function;
/** This function will be called when a gssapi token comes in.
@@ -408,12 +345,6 @@ struct ssh_server_callbacks_struct {
/* This function will be called when a MIC needs to be verified.
*/
ssh_gssapi_verify_mic_callback gssapi_verify_mic_function;
/**
* This function will be called when an incoming "direct-tcpip"
* request is received.
*/
ssh_channel_open_request_direct_tcpip_callback
channel_open_request_direct_tcpip_function;
};
typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
@@ -423,9 +354,6 @@ typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
* This functions sets the callback structure to use your own callback
* functions for user authentication, new channels and requests.
*
* Note, that the structure is not copied to the session structure so it needs
* to be valid for the whole session lifetime.
*
* @code
* struct ssh_server_callbacks_struct cb = {
* .userdata = data,
@@ -466,7 +394,7 @@ struct ssh_socket_callbacks_struct {
*/
ssh_callback_int_int exception;
/** This function is called when the ssh_socket_connect was used on the socket
* on nonblocking state, and the connection succeeded.
* on nonblocking state, and the connection successed.
*/
ssh_callback_int_int connected;
};
@@ -620,9 +548,6 @@ typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
* This functions sets the callback structure to use your own callback
* functions for auth, logging and status.
*
* Note, that the callback structure is not copied into the session so it needs
* to be valid for the whole session lifetime.
*
* @code
* struct ssh_callbacks_struct cb = {
* .userdata = data,
@@ -694,7 +619,6 @@ typedef void (*ssh_channel_signal_callback) (ssh_session session,
* @brief SSH channel exit status callback. Called when a channel has received an exit status
* @param session Current session handler
* @param channel the actual channel
* @param exit_status Exit status of the ran command
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
@@ -707,7 +631,7 @@ typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
* @param session Current session handler
* @param channel the actual channel
* @param signal the signal name (without the SIG prefix)
* @param core a boolean telling whether a core has been dumped or not
* @param core a boolean telling wether a core has been dumped or not
* @param errmsg the description of the exception
* @param lang the language of the description (format: RFC 3066)
* @param userdata Userdata to be passed to the callback function.
@@ -722,13 +646,12 @@ typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
/**
* @brief SSH channel PTY request from a client.
* @param session the session
* @param channel the channel
* @param term The type of terminal emulation
* @param width width of the terminal, in characters
* @param height height of the terminal, in characters
* @param pxwidth width of the terminal, in pixels
* @param pwheight height of the terminal, in pixels
* @param pxheight height of the terminal, in pixels
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the pty request is accepted
* @returns -1 if the request is denied
@@ -742,7 +665,6 @@ typedef int (*ssh_channel_pty_request_callback) (ssh_session session,
/**
* @brief SSH channel Shell request from a client.
* @param session the session
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the shell request is accepted
@@ -755,7 +677,6 @@ typedef int (*ssh_channel_shell_request_callback) (ssh_session session,
* @brief SSH auth-agent-request from the client. This request is
* sent by a client when agent forwarding is available.
* Server is free to ignore this callback, no answer is expected.
* @param session the session
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
*/
@@ -767,12 +688,7 @@ typedef void (*ssh_channel_auth_agent_req_callback) (ssh_session session,
* @brief SSH X11 request from the client. This request is
* sent by a client when X11 forwarding is requested(and available).
* Server is free to ignore this callback, no answer is expected.
* @param session the session
* @param channel the channel
* @param single_connection If true, only one channel should be forwarded
* @param auth_protocol The X11 authentication method to be used
* @param auth_cookie Authentication cookie encoded hexadecimal
* @param screen_number Screen number
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
@@ -784,12 +700,11 @@ typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
void *userdata);
/**
* @brief SSH channel PTY windows change (terminal size) from a client.
* @param session the session
* @param channel the channel
* @param width width of the terminal, in characters
* @param height height of the terminal, in characters
* @param pxwidth width of the terminal, in pixels
* @param pwheight height of the terminal, in pixels
* @param pxheight height of the terminal, in pixels
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the pty request is accepted
* @returns -1 if the request is denied
@@ -802,7 +717,6 @@ typedef int (*ssh_channel_pty_window_change_callback) (ssh_session session,
/**
* @brief SSH channel Exec request from a client.
* @param session the session
* @param channel the channel
* @param command the shell command to be executed
* @param userdata Userdata to be passed to the callback function.
@@ -816,7 +730,6 @@ typedef int (*ssh_channel_exec_request_callback) (ssh_session session,
/**
* @brief SSH channel environment request from a client.
* @param session the session
* @param channel the channel
* @param env_name name of the environment value to be set
* @param env_value value of the environment value to be set
@@ -833,7 +746,6 @@ typedef int (*ssh_channel_env_request_callback) (ssh_session session,
void *userdata);
/**
* @brief SSH channel subsystem request from a client.
* @param session the session
* @param channel the channel
* @param subsystem the subsystem required
* @param userdata Userdata to be passed to the callback function.
@@ -848,8 +760,6 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
/**
* @brief SSH channel write will not block (flow control).
*
* @param session the session
*
* @param channel the channel
*
* @param[in] bytes size of the remote window in bytes. Writing as much data
@@ -861,31 +771,9 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
*/
typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
ssh_channel channel,
uint32_t bytes,
size_t bytes,
void *userdata);
/**
* @brief SSH channel open callback. Called when a channel open succeeds or fails.
* @param session Current session handler
* @param channel the actual channel
* @param is_success is 1 when the open succeeds, and 0 otherwise.
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_open_resp_callback) (ssh_session session,
ssh_channel channel,
bool is_success,
void *userdata);
/**
* @brief SSH channel request response callback. Called when a response to the pending request is received.
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_request_resp_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
struct ssh_channel_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
@@ -953,14 +841,6 @@ struct ssh_channel_callbacks_struct {
* not to block.
*/
ssh_channel_write_wontblock_callback channel_write_wontblock_function;
/**
* This functions will be called when the channel has received a channel open confirmation or failure.
*/
ssh_channel_open_resp_callback channel_open_response_function;
/**
* This functions will be called when the channel has received the response to the pending request.
*/
ssh_channel_request_resp_callback channel_request_response_function;
};
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
@@ -969,11 +849,7 @@ typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
* @brief Set the channel callback functions.
*
* This functions sets the callback structure to use your own callback
* functions for channel data and exceptions.
*
* Note, that the structure is not copied to the channel structure so it needs
* to be valid as for the whole life of the channel or until it is removed with
* ssh_remove_channel_callbacks().
* functions for channel data and exceptions
*
* @code
* struct ssh_channel_callbacks_struct cb = {
@@ -1031,7 +907,7 @@ LIBSSH_API int ssh_remove_channel_callbacks(ssh_channel channel,
/** @} */
/** @addtogroup libssh_threads
/** @group libssh_threads
* @{
*/
@@ -1097,14 +973,13 @@ LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
* @see ssh_threads_set_callbacks
*/
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void);
/** @} */
/**
* @brief Set the logging callback function.
*
* @param[in] cb The callback to set.
*
* @return 0 on success, < 0 on error.
* @return 0 on success, < 0 on errror.
*/
LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
@@ -1115,45 +990,7 @@ LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
*/
LIBSSH_API ssh_logging_callback ssh_get_log_callback(void);
/**
* @brief SSH proxyjump before connection callback. Called before calling
* ssh_connect()
* @param session Jump session handler
* @param userdata Userdata to be passed to the callback function.
*
* @return 0 on success, < 0 on error.
*/
typedef int (*ssh_jump_before_connection_callback)(ssh_session session,
void *userdata);
/**
* @brief SSH proxyjump verify knownhost callback. Verify the host.
* If not specified default function will be used.
* @param session Jump session handler
* @param userdata Userdata to be passed to the callback function.
*
* @return 0 on success, < 0 on error.
*/
typedef int (*ssh_jump_verify_knownhost_callback)(ssh_session session,
void *userdata);
/**
* @brief SSH proxyjump user authentication callback. Authenticate the user.
* @param session Jump session handler
* @param userdata Userdata to be passed to the callback function.
*
* @return 0 on success, < 0 on error.
*/
typedef int (*ssh_jump_authenticate_callback)(ssh_session session,
void *userdata);
struct ssh_jump_callbacks_struct {
void *userdata;
ssh_jump_before_connection_callback before_connection;
ssh_jump_verify_knownhost_callback verify_knownhost;
ssh_jump_authenticate_callback authenticate;
};
/** @} */
#ifdef __cplusplus
}
#endif

View File

@@ -17,10 +17,7 @@ struct chacha_ctx {
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#ifdef __cplusplus
extern "C" {
#endif
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
@@ -41,8 +38,4 @@ void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m,
#endif
;
#ifdef __cplusplus
}
#endif
#endif /* CHACHA_H */

View File

@@ -1,54 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2020 Red Hat, Inc.
*
* Author: Jakub Jelen <jjelen@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* chacha20-poly1305.h file
* This file includes definitions needed for Chacha20-poly1305 AEAD cipher
* using different crypto backends.
*/
#ifndef CHACHA20_POLY1305_H
#define CHACHA20_POLY1305_H
#define CHACHA20_BLOCKSIZE 64
#define CHACHA20_KEYLEN 32
#define POLY1305_TAGLEN 16
/* size of the keys k1 and k2 as defined in specs */
#define POLY1305_KEYLEN 32
#ifdef _MSC_VER
#pragma pack(push, 1)
#endif
struct ssh_packet_header {
uint32_t length;
uint8_t payload[];
}
#if defined(__GNUC__)
__attribute__ ((packed))
#endif
#ifdef _MSC_VER
#pragma pack(pop)
#endif
;
#endif /* CHACHA20_POLY1305_H */

View File

@@ -22,10 +22,6 @@
#define CHANNELS_H_
#include "libssh/priv.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @internal
* Describes the different possible states in a
* outgoing (client) channel request
@@ -39,7 +35,7 @@ enum ssh_channel_request_state_e {
SSH_CHANNEL_REQ_STATE_ACCEPTED,
/** A request has been replied and refused */
SSH_CHANNEL_REQ_STATE_DENIED,
/** A request has been replied and an error happened */
/** A request has been replied and an error happend */
SSH_CHANNEL_REQ_STATE_ERROR
};
@@ -80,12 +76,7 @@ struct ssh_channel_struct {
ssh_buffer stdout_buffer;
ssh_buffer stderr_buffer;
void *userarg;
struct {
bool status;
uint32_t code;
char *signal;
bool core_dumped;
} exit;
int exit_status;
enum ssh_channel_request_state_e request_state;
struct ssh_list *callbacks; /* list of ssh_channel_callbacks */
@@ -107,7 +98,7 @@ SSH_PACKET_CALLBACK(channel_rcv_request);
SSH_PACKET_CALLBACK(channel_rcv_data);
int channel_default_bufferize(ssh_channel channel,
void *data, uint32_t len,
void *data, size_t len,
bool is_stderr);
int ssh_channel_flush(ssh_channel channel);
uint32_t ssh_channel_new_id(ssh_session session);
@@ -118,8 +109,4 @@ int ssh_global_request(ssh_session session,
ssh_buffer buffer,
int reply);
#ifdef __cplusplus
}
#endif
#endif /* CHANNELS_H_ */

View File

@@ -42,6 +42,7 @@ enum ssh_config_opcode_e {
SOC_MACS,
SOC_COMPRESSION,
SOC_TIMEOUT,
SOC_PROTOCOL,
SOC_STRICTHOSTKEYCHECK,
SOC_KNOWNHOSTS,
SOC_PROXYCOMMAND,
@@ -59,13 +60,8 @@ enum ssh_config_opcode_e {
SOC_KBDINTERACTIVEAUTHENTICATION,
SOC_PASSWORDAUTHENTICATION,
SOC_PUBKEYAUTHENTICATION,
SOC_PUBKEYACCEPTEDKEYTYPES,
SOC_PUBKEYACCEPTEDTYPES,
SOC_REKEYLIMIT,
SOC_IDENTITYAGENT,
SOC_IDENTITIESONLY,
SOC_CONTROLMASTER,
SOC_CONTROLPATH,
SOC_CERTIFICATE,
SOC_MAX /* Keep this one last in the list */
};

View File

@@ -26,13 +26,6 @@
#ifndef CONFIG_PARSER_H_
#define CONFIG_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "libssh/libssh.h"
#include <stdbool.h>
char *ssh_config_get_cmd(char **str);
char *ssh_config_get_token(char **str);
@@ -52,35 +45,13 @@ int ssh_config_get_yesno(char **str, int notfound);
* be stored or NULL if we do not care about the result.
* @param[out] port Pointer to the location, where the new port will
* be stored or NULL if we do not care about the result.
* @param[in] ignore_port Set to true if we should not attempt to parse
* port number.
*
* @returns SSH_OK if the provided string is in format of SSH URI,
* SSH_ERROR on failure
*/
int ssh_config_parse_uri(const char *tok,
char **username,
char **hostname,
char **port,
bool ignore_port);
/**
* @brief: Parse the ProxyJump configuration line and if parsing,
* stores the result in the configuration option
*
* @param[in] session The ssh session
* @param[in] s The string to be parsed.
* @param[in] do_parsing Whether to parse or not.
*
* @returns SSH_OK if the provided string is formatted and parsed correctly
* SSH_ERROR on failure
*/
int ssh_config_parse_proxy_jump(ssh_session session,
const char *s,
bool do_parsing);
#ifdef __cplusplus
}
#endif
char **username,
char **hostname,
char **port);
#endif /* LIBSSH_CONFIG_H_ */

View File

@@ -45,11 +45,10 @@
#ifdef HAVE_OPENSSL_ECDH_H
#include <openssl/ecdh.h>
#endif
#include "libssh/curve25519.h"
#include "libssh/dh.h"
#include "libssh/ecdh.h"
#include "libssh/kex.h"
#include "libssh/sntrup761.h"
#include "libssh/curve25519.h"
#define DIGEST_MAX_LEN 64
@@ -57,41 +56,39 @@
#define AES_GCM_IVLEN 12
enum ssh_key_exchange_e {
/* diffie-hellman-group1-sha1 */
SSH_KEX_DH_GROUP1_SHA1 = 1,
/* diffie-hellman-group14-sha1 */
SSH_KEX_DH_GROUP14_SHA1,
/* diffie-hellman-group1-sha1 */
SSH_KEX_DH_GROUP1_SHA1=1,
/* diffie-hellman-group14-sha1 */
SSH_KEX_DH_GROUP14_SHA1,
#ifdef WITH_GEX
/* diffie-hellman-group-exchange-sha1 */
SSH_KEX_DH_GEX_SHA1,
/* diffie-hellman-group-exchange-sha256 */
SSH_KEX_DH_GEX_SHA256,
/* diffie-hellman-group-exchange-sha1 */
SSH_KEX_DH_GEX_SHA1,
/* diffie-hellman-group-exchange-sha256 */
SSH_KEX_DH_GEX_SHA256,
#endif /* WITH_GEX */
/* ecdh-sha2-nistp256 */
SSH_KEX_ECDH_SHA2_NISTP256,
/* ecdh-sha2-nistp384 */
SSH_KEX_ECDH_SHA2_NISTP384,
/* ecdh-sha2-nistp521 */
SSH_KEX_ECDH_SHA2_NISTP521,
/* curve25519-sha256@libssh.org */
SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG,
/* curve25519-sha256 */
SSH_KEX_CURVE25519_SHA256,
/* diffie-hellman-group16-sha512 */
SSH_KEX_DH_GROUP16_SHA512,
/* diffie-hellman-group18-sha512 */
SSH_KEX_DH_GROUP18_SHA512,
/* diffie-hellman-group14-sha256 */
SSH_KEX_DH_GROUP14_SHA256,
/* sntrup761x25519-sha512@openssh.com */
SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM,
/* ecdh-sha2-nistp256 */
SSH_KEX_ECDH_SHA2_NISTP256,
/* ecdh-sha2-nistp384 */
SSH_KEX_ECDH_SHA2_NISTP384,
/* ecdh-sha2-nistp521 */
SSH_KEX_ECDH_SHA2_NISTP521,
/* curve25519-sha256@libssh.org */
SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG,
/* curve25519-sha256 */
SSH_KEX_CURVE25519_SHA256,
/* diffie-hellman-group16-sha512 */
SSH_KEX_DH_GROUP16_SHA512,
/* diffie-hellman-group18-sha512 */
SSH_KEX_DH_GROUP18_SHA512,
/* diffie-hellman-group14-sha256 */
SSH_KEX_DH_GROUP14_SHA256,
};
enum ssh_cipher_e {
SSH_NO_CIPHER=0,
#ifdef HAVE_BLOWFISH
#ifdef WITH_BLOWFISH_CIPHER
SSH_BLOWFISH_CBC,
#endif /* HAVE_BLOWFISH */
#endif /* WITH_BLOWFISH_CIPHER */
SSH_3DES_CBC,
SSH_AES128_CBC,
SSH_AES192_CBC,
@@ -114,11 +111,7 @@ struct ssh_crypto_struct {
#endif /* WITH_GEX */
#ifdef HAVE_ECDH
#ifdef HAVE_OPENSSL_ECC
#if OPENSSL_VERSION_NUMBER < 0x30000000L
EC_KEY *ecdh_privkey;
#else
EVP_PKEY *ecdh_privkey;
#endif /* OPENSSL_VERSION_NUMBER */
#elif defined HAVE_GCRYPT_ECC
gcry_sexp_t ecdh_privkey;
#elif defined HAVE_LIBMBEDCRYPTO
@@ -128,20 +121,9 @@ struct ssh_crypto_struct {
ssh_string ecdh_server_pubkey;
#endif
#ifdef HAVE_CURVE25519
#ifdef HAVE_LIBCRYPTO
EVP_PKEY *curve25519_privkey;
#elif defined(HAVE_GCRYPT_CURVE25519)
gcry_sexp_t curve25519_privkey;
#else
ssh_curve25519_privkey curve25519_privkey;
#endif
ssh_curve25519_pubkey curve25519_client_pubkey;
ssh_curve25519_pubkey curve25519_server_pubkey;
#endif
#ifdef HAVE_SNTRUP761
ssh_sntrup761_privkey sntrup761_privkey;
ssh_sntrup761_pubkey sntrup761_client_pubkey;
ssh_sntrup761_ciphertext sntrup761_ciphertext;
#endif
ssh_string dh_server_signature; /* information used by dh_handshake. */
size_t session_id_len;
@@ -226,22 +208,10 @@ struct ssh_cipher_struct {
void (*cleanup)(struct ssh_cipher_struct *cipher);
};
#ifdef __cplusplus
extern "C" {
#endif
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void);
int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
unsigned char *key, size_t key_len,
uint8_t key_type, unsigned char *output,
int key_type, unsigned char *output,
size_t requested_len);
int secure_memcmp(const void *s1, const void *s2, size_t n);
void compress_cleanup(struct ssh_crypto_struct *crypto);
#ifdef __cplusplus
}
#endif
#endif /* _CRYPTO_H_ */

View File

@@ -33,10 +33,6 @@
#define crypto_scalarmult crypto_scalarmult_curve25519
#else
#ifdef __cplusplus
extern "C" {
#endif
#define CURVE25519_PUBKEY_SIZE 32
#define CURVE25519_PRIVKEY_SIZE 32
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
@@ -50,9 +46,6 @@ int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned c
typedef unsigned char ssh_curve25519_pubkey[CURVE25519_PUBKEY_SIZE];
typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
int ssh_curve25519_init(ssh_session session);
int curve25519_do_create_k(ssh_session session, ssh_curve25519_pubkey k);
int ssh_curve25519_create_k(ssh_session session, ssh_curve25519_pubkey k);
int ssh_client_curve25519_init(ssh_session session);
void ssh_client_curve25519_remove_callbacks(ssh_session session);
@@ -61,8 +54,4 @@ void ssh_client_curve25519_remove_callbacks(ssh_session session);
void ssh_server_curve25519_init(ssh_session session);
#endif /* WITH_SERVER */
#ifdef __cplusplus
}
#endif
#endif /* CURVE25519_H_ */

View File

@@ -23,10 +23,6 @@
#ifndef SRC_DH_GEX_H_
#define SRC_DH_GEX_H_
#ifdef __cplusplus
extern "C" {
#endif
int ssh_client_dhgex_init(ssh_session session);
void ssh_client_dhgex_remove_callbacks(ssh_session session);
@@ -34,8 +30,4 @@ void ssh_client_dhgex_remove_callbacks(ssh_session session);
void ssh_server_dhgex_init(ssh_session session);
#endif /* WITH_SERVER */
#ifdef __cplusplus
}
#endif
#endif /* SRC_DH_GEX_H_ */

View File

@@ -30,34 +30,20 @@ struct dh_ctx;
#define DH_CLIENT_KEYPAIR 0
#define DH_SERVER_KEYPAIR 1
#ifdef __cplusplus
extern "C" {
#endif
/* functions implemented by crypto backends */
int ssh_dh_init_common(struct ssh_crypto_struct *crypto);
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto);
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
int ssh_dh_get_parameters(struct dh_ctx *ctx,
const_bignum *modulus, const_bignum *generator);
#else
int ssh_dh_get_parameters(struct dh_ctx *ctx,
bignum *modulus, bignum *generator);
#endif /* OPENSSL_VERSION_NUMBER */
int ssh_dh_set_parameters(struct dh_ctx *ctx,
const bignum modulus, const bignum generator);
int ssh_dh_keypair_gen_keys(struct dh_ctx *ctx, int peer);
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
const_bignum *priv, const_bignum *pub);
#else
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
bignum *priv, bignum *pub);
#endif /* OPENSSL_VERSION_NUMBER */
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
bignum priv, bignum pub);
const bignum priv, const bignum pub);
int ssh_dh_compute_shared_secret(struct dh_ctx *ctx, int local, int remote,
bignum *dest);
@@ -88,8 +74,4 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet);
int ssh_fallback_group(uint32_t pmax, bignum *p, bignum *g);
bool ssh_dh_is_known_group(bignum modulus, bignum generator);
#ifdef __cplusplus
}
#endif
#endif /* DH_H_ */

View File

@@ -42,10 +42,6 @@
#define HAVE_ECDH 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks;
/* Backend-specific functions. */
int ssh_client_ecdh_init(ssh_session session);
@@ -58,8 +54,4 @@ void ssh_server_ecdh_init(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init);
#endif /* WITH_SERVER */
#ifdef __cplusplus
}
#endif
#endif /* ECDH_H_ */

View File

@@ -24,10 +24,10 @@
/**
* @defgroup ed25519 ed25519 API
* @internal
* @brief API for DJB's ed25519
*
* @{
*/
* @{ */
#define ED25519_PK_LEN 32
#define ED25519_SK_LEN 64
@@ -37,10 +37,6 @@ typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
#ifdef __cplusplus
extern "C" {
#endif
/** @internal
* @brief generate an ed25519 key pair
* @param[out] pk generated public key
@@ -80,8 +76,4 @@ int crypto_sign_ed25519_open(
const ed25519_pubkey pk);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* ED25519_H_ */

View File

@@ -33,10 +33,6 @@ typedef struct {
uint32_t v[32];
} fe25519;
#ifdef __cplusplus
extern "C" {
#endif
void fe25519_freeze(fe25519 *r);
void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
@@ -69,8 +65,4 @@ void fe25519_invert(fe25519 *r, const fe25519 *x);
void fe25519_pow2523(fe25519 *r, const fe25519 *x);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -28,10 +28,6 @@ typedef struct
fe25519 t;
} ge25519;
#ifdef __cplusplus
extern "C" {
#endif
extern const ge25519 ge25519_base;
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
@@ -44,8 +40,4 @@ void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25
void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -22,45 +22,13 @@
#define GSSAPI_H_
#include "config.h"
#ifdef WITH_GSSAPI
#include "session.h"
#include <gssapi/gssapi.h>
/* all OID begin with the tag identifier + length */
#define SSH_OID_TAG 06
typedef struct ssh_gssapi_struct *ssh_gssapi;
#ifdef __cplusplus
extern "C" {
#endif
/** current state of an GSSAPI authentication */
enum ssh_gssapi_state_e {
SSH_GSSAPI_STATE_NONE, /* no status */
SSH_GSSAPI_STATE_RCV_TOKEN, /* Expecting a token */
SSH_GSSAPI_STATE_RCV_MIC, /* Expecting a MIC */
};
struct ssh_gssapi_struct{
enum ssh_gssapi_state_e state; /* current state */
struct gss_OID_desc_struct mech; /* mechanism being elected for auth */
gss_cred_id_t server_creds; /* credentials of server */
gss_cred_id_t client_creds; /* creds delegated by the client */
gss_ctx_id_t ctx; /* the authentication context */
gss_name_t client_name; /* Identity of the client */
char *user; /* username of client */
char *canonic_user; /* canonic form of the client's username */
char *service; /* name of the service */
struct {
gss_name_t server_name; /* identity of server */
OM_uint32 flags; /* flags used for init context */
gss_OID oid; /* mech being used for authentication */
gss_cred_id_t creds; /* creds used to initialize context */
gss_cred_id_t client_deleg_creds; /* delegated creds (const, not freeable) */
} client;
};
#ifdef WITH_SERVER
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids);
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server);
@@ -72,15 +40,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client);
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response);
int ssh_gssapi_init(ssh_session session);
void ssh_gssapi_log_error(int verb, const char *msg_a, int maj_stat, int min_stat);
int ssh_gssapi_auth_mic(ssh_session session);
void ssh_gssapi_free(ssh_session session);
char *ssh_gssapi_name_to_char(gss_name_t name);
#ifdef __cplusplus
}
#endif
#endif /* WITH_GSSAPI */
#endif /* GSSAPI_H */

View File

@@ -31,10 +31,6 @@ struct ssh_kex_struct {
char *methods[SSH_KEX_METHODS];
};
#ifdef __cplusplus
extern "C" {
#endif
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
int ssh_send_kex(ssh_session session);
@@ -45,17 +41,13 @@ int ssh_kex_select_methods(ssh_session session);
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list);
char *ssh_add_to_default_algos(enum ssh_kex_types_e algo, const char *list);
char *ssh_remove_from_default_algos(enum ssh_kex_types_e algo,
const char *list);
char *ssh_prefix_default_algos(enum ssh_kex_types_e algo, const char *list);
char **ssh_space_tokenize(const char *chain);
int ssh_get_kex1(ssh_session session);
char *ssh_find_matching(const char *in_d, const char *what_d);
const char *ssh_kex_get_supported_method(enum ssh_kex_types_e type);
const char *ssh_kex_get_default_methods(enum ssh_kex_types_e type);
const char *ssh_kex_get_fips_methods(enum ssh_kex_types_e type);
const char *ssh_kex_get_description(enum ssh_kex_types_e type);
const char *ssh_kex_get_supported_method(uint32_t algo);
const char *ssh_kex_get_default_methods(uint32_t algo);
const char *ssh_kex_get_fips_methods(uint32_t algo);
const char *ssh_kex_get_description(uint32_t algo);
char *ssh_client_select_hostkeys(ssh_session session);
int ssh_send_rekex(ssh_session session);
int server_set_kex(ssh_session session);
@@ -65,8 +57,4 @@ int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int ssh_hashbufout_add_cookie(ssh_session session);
int ssh_generate_session_keys(ssh_session session);
#ifdef __cplusplus
}
#endif
#endif /* KEX_H_ */

View File

@@ -29,36 +29,34 @@ struct ssh_public_key_struct {
int type;
const char *type_c; /* Don't free it ! it is static */
#if defined(HAVE_LIBGCRYPT)
gcry_sexp_t dsa_pub;
gcry_sexp_t rsa_pub;
#elif defined(HAVE_LIBCRYPTO)
EVP_PKEY *key_pub;
DSA *dsa_pub;
RSA *rsa_pub;
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa_pub;
void *dsa_pub;
#endif
};
struct ssh_private_key_struct {
int type;
#if defined(HAVE_LIBGCRYPT)
gcry_sexp_t dsa_priv;
gcry_sexp_t rsa_priv;
#elif defined(HAVE_LIBCRYPTO)
EVP_PKEY *key_priv;
DSA *dsa_priv;
RSA *rsa_priv;
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa_priv;
void *dsa_priv;
#endif
};
#ifdef __cplusplus
extern "C" {
#endif
const char *ssh_type_to_char(int type);
int ssh_type_from_name(const char *name);
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s);
#ifdef __cplusplus
}
#endif
#endif /* KEYS_H_ */

View File

@@ -22,10 +22,6 @@
#ifndef SSH_KNOWNHOSTS_H_
#define SSH_KNOWNHOSTS_H_
#ifdef __cplusplus
extern "C" {
#endif
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
char *ssh_known_hosts_get_algorithms_names(ssh_session session);
enum ssh_known_hosts_e
@@ -33,8 +29,4 @@ ssh_session_get_known_hosts_entry_file(ssh_session session,
const char *filename,
struct ssh_knownhosts_entry **pentry);
#ifdef __cplusplus
}
#endif
#endif /* SSH_KNOWNHOSTS_H_ */

View File

@@ -31,10 +31,6 @@
typedef struct ssh_private_key_struct* ssh_private_key;
typedef struct ssh_public_key_struct* ssh_public_key;
#ifdef __cplusplus
extern "C" {
#endif
LIBSSH_API int ssh_auth_list(ssh_session session);
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
@@ -92,19 +88,19 @@ SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
SSH_DEPRECATED LIBSSH_API void privatekey_free(ssh_private_key prv);
SSH_DEPRECATED LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
LIBSSH_API void privatekey_free(ssh_private_key prv);
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
int type, const char *passphrase);
SSH_DEPRECATED LIBSSH_API void publickey_free(ssh_public_key key);
SSH_DEPRECATED LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
LIBSSH_API void publickey_free(ssh_public_key key);
LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
ssh_string pubkey, int type);
SSH_DEPRECATED LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
int *type);
SSH_DEPRECATED LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
SSH_DEPRECATED LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
SSH_DEPRECATED LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
ssh_string *publickey, int *type);
SSH_DEPRECATED LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
@@ -121,8 +117,4 @@ SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
#ifdef __cplusplus
}
#endif
#endif /* LEGACY_H_ */

View File

@@ -25,21 +25,20 @@
#ifdef HAVE_LIBCRYPTO
#include "libssh/libssh.h"
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
typedef EVP_MD_CTX* SHACTX;
typedef EVP_MD_CTX* SHA256CTX;
typedef EVP_MD_CTX* SHA384CTX;
typedef EVP_MD_CTX* SHA512CTX;
typedef EVP_MD_CTX* MD5CTX;
typedef EVP_MD_CTX* HMACCTX;
typedef HMAC_CTX* HMACCTX;
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
@@ -54,15 +53,12 @@ typedef EVP_MD_CTX* HMACCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
#endif
/* Use ssh_crypto_free() to release memory allocated by bignum_bn2dec(),
bignum_bn2hex() and other functions that use crypto-library functions that
are documented to allocate memory that needs to be de-allocate with
OPENSSL_free. */
#define ssh_crypto_free(x) OPENSSL_free(x)
#include <openssl/bn.h>
#include <openssl/opensslv.h>
#define OPENSSL_0_9_7b 0x0090702fL
#if (OPENSSL_VERSION_NUMBER <= OPENSSL_0_9_7b)
#define BROKEN_AES_CTR
#endif
typedef BIGNUM* bignum;
typedef const BIGNUM* const_bignum;
typedef BN_CTX* bignum_CTX;
@@ -113,23 +109,10 @@ typedef BN_CTX* bignum_CTX;
/* Returns true if the OpenSSL is operating in FIPS mode */
#ifdef HAVE_OPENSSL_FIPS_MODE
#define ssh_fips_mode() (FIPS_mode() != 0)
#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
#define ssh_fips_mode() EVP_default_properties_is_fips_enabled(NULL)
#else
#define ssh_fips_mode() false
#endif
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);
#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 /* LIBCRYPTO_H_ */

View File

@@ -48,8 +48,6 @@ typedef gcry_md_hd_t HMACCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
#define ssh_crypto_free(x) gcry_free(x)
typedef gcry_mpi_t bignum;
typedef const struct gcry_mpi *const_bignum;
typedef void* bignum_CTX;
@@ -105,10 +103,6 @@ int ssh_gcry_rand_range(bignum rnd, bignum max);
} while(0)
/* Helper functions for data conversions. */
#ifdef __cplusplus
extern "C" {
#endif
/* Extract an MPI from the given s-expression SEXP named NAME which is
encoded using INFORMAT and store it in a newly allocated ssh_string
encoded using OUTFORMAT. */
@@ -119,10 +113,6 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
#define ssh_fips_mode() false
#ifdef __cplusplus
}
#endif
#endif /* HAVE_LIBGCRYPT */
#endif /* LIBGCRYPT_H_ */

View File

@@ -34,7 +34,6 @@
#include <mbedtls/cipher.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/platform.h>
typedef mbedtls_md_context_t *SHACTX;
typedef mbedtls_md_context_t *SHA256CTX;
@@ -59,8 +58,6 @@ typedef mbedtls_md_context_t *HMACCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
#define ssh_crypto_free(x) mbedtls_free(x)
typedef mbedtls_mpi *bignum;
typedef const mbedtls_mpi *const_bignum;
typedef void* bignum_CTX;
@@ -75,13 +72,9 @@ struct mbedtls_ecdsa_sig {
bignum s;
};
#ifdef __cplusplus
extern "C" {
#endif
bignum ssh_mbedcry_bn_new(void);
void ssh_mbedcry_bn_free(bignum num);
char *ssh_mbedcry_bn2num(const_bignum num, int radix);
unsigned char *ssh_mbedcry_bn2num(const_bignum num, int radix);
int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom);
int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
int ssh_mbedcry_rand_range(bignum dest, bignum max);
@@ -107,7 +100,7 @@ int ssh_mbedcry_hex2bn(bignum *dest, char *data);
} while(0)
#define bignum_bn2dec(num) ssh_mbedcry_bn2num(num, 10)
#define bignum_dec2bn(data, bn) mbedtls_mpi_read_string(bn, 10, data)
#define bignum_bn2hex(num, dest) (*dest)=(unsigned char *)ssh_mbedcry_bn2num(num, 16)
#define bignum_bn2hex(num, dest) (*dest)=ssh_mbedcry_bn2num(num, 16)
#define bignum_hex2bn(data, dest) ssh_mbedcry_hex2bn(dest, data)
#define bignum_rand(rnd, bits) ssh_mbedcry_rand((rnd), (bits), 0, 1)
#define bignum_rand_range(rnd, max) ssh_mbedcry_rand_range(rnd, max)
@@ -129,7 +122,7 @@ int ssh_mbedcry_hex2bn(bignum *dest, char *data);
*(dest) = bignum_new(); \
} \
if (*(dest) != NULL) { \
mbedtls_mpi_copy(*(dest), orig); \
mbedtls_mpi_copy(orig, *(dest)); \
} \
} while(0)
@@ -142,9 +135,5 @@ ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
#define ssh_fips_mode() false
#ifdef __cplusplus
}
#endif
#endif /* HAVE_LIBMBEDCRYPTO */
#endif /* LIBMBEDCRYPTO_H_ */

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