Compare commits

..

197 Commits

Author SHA1 Message Date
Jakub Jelen
479eca13aa Bump version to 0.10.5
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 13:37:20 +02:00
Norbert Pocs
994acfe2c5 torture_options: Add tests for incorrect number parsing options
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:53:10 +02:00
Norbert Pocs
968e09aae0 options: Fail if no number was parsed
strtoul returns 0 if no valid character was parsed, which
can unwantedly misconfigure the options.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:53:10 +02:00
Norbert Pocs
a006d34372 buffer.c: Fix null pointer dereference error
This issue was discovered by covscan tool.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:53:10 +02:00
Norbert Pocs
a669408201 Add missing return value check
This issue was detected by covscan

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:53:10 +02:00
Norbert Pocs
c68a58575b 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:52 +02:00
Norbert Pocs
e8dfbb85a2 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:46 +02:00
Jakub Jelen
dc1254d53e CVE-2023-1667: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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:23 +02:00
Jakub Jelen
d08f1b2377 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:22 +02:00
Jakub Jelen
70565ac438 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:20 +02:00
Jakub Jelen
fc1a8bb455 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:18 +02:00
Jakub Jelen
b759ae557d 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:17 +02:00
Jakub Jelen
6df2daea04 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:15 +02:00
Jakub Jelen
99760776d4 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:13 +02:00
Jakub Jelen
247a4a761c 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:12 +02:00
Jakub Jelen
a30339d7b1 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: Andreas Schneider <asn@cryptomilk.org>
2023-05-04 11:52:06 +02:00
Jakub Jelen
8dde4e1924 token: Add missing whitespace
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:54 +02:00
Jakub Jelen
b1d9bff6ee kex: Reformat ssh_kex_select_methods
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:52 +02:00
Jakub Jelen
a0f10b9860 client: Reformat ssh_client_connection_callback
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:50 +02:00
Jakub Jelen
7e40f13125 wrapper: Reformat crypto_new
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:47 +02:00
Jakub Jelen
36273e708a Reformat struct ssh_session_struct
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:44 +02:00
Jakub Jelen
41c63fa88d server: Reformat ssh_server_connection_callback
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:42 +02:00
Jakub Jelen
d726eca7d2 Reformat ssh_packet_kexinit()
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:40 +02:00
Jakub Jelen
ad2797613e kex: Reformat ssh_send_kex
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:37 +02:00
Jakub Jelen
653e5ee117 packet: Reformat callback handling functions
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:34 +02:00
Jakub Jelen
d8b1b5e0cc server: Reformat callback_receive_banner
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:31 +02:00
Jakub Jelen
7341615e2f server: Reformat ssh_handle_key_exchange
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:29 +02:00
Jakub Jelen
f8ba2b0148 packet: Fix indentation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:26 +02:00
Jakub Jelen
d26cc63dd5 kex: Clarify the comment
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:18 +02:00
Jakub Jelen
e41dacbf10 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:16 +02:00
Jakub Jelen
e786bacb92 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:13 +02:00
Jakub Jelen
19e2521242 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:09 +02:00
Jakub Jelen
429d0422dc 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:06 +02:00
Jakub Jelen
559ebc9ccb 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:03 +02:00
Jakub Jelen
d7f18c468e 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:36:00 +02:00
Jakub Jelen
f73dac8eed 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:35:58 +02:00
Jakub Jelen
3c381565c9 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:35:55 +02:00
Jakub Jelen
833c3d3330 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:35:52 +02:00
Jakub Jelen
6d073f2746 fuzz: Avoid the server fuzzer to proceed to the authentication and further
Thanks Phil Turnbull from GitHub

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:35:49 +02:00
Jakub Jelen
fe83733a7c 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: Andreas Schneider <asn@cryptomilk.org>
2023-04-28 11:35:45 +02:00
Ran Park
d3d7eeab75 Add tests for run ssh_execute_command
Signed-off-by: Ran Park <bagayonghuming@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d109b5bd5f)
2023-04-28 11:06:16 +02:00
Ran Park
8a037e9afe solve incorrect parsing of the ProxyCommand configuration option
Signed-off-by: Ran Park <bagayonghuming@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9cd23fecac)
2023-04-28 11:06:13 +02:00
Jakub Jelen
dd0aaec67e cmake: Return back the DEFAULT_C_COMPILE_FLAGS
Accidentally removed in 1689b83d0f.

Reported in #185 by Peter Kästle

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 3058549bf7)
2023-04-17 13:46:41 +02:00
Jakub Jelen
8b3b041096 ci: Add CentOS 8 as there are no other OpenSSL 1.1.1 platforms
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 7f40974802)
2023-04-17 13:46:41 +02:00
Jakub Jelen
e9e9190079 ci: Suse is already on OpenSSL 3.0
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit f6f1bfaa4e)
2023-04-17 13:46:41 +02:00
Jakub Jelen
bc4afc1067 ci: Actually build the package with x86 cross-compiler
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 91279e0aac)
2023-04-17 13:46:41 +02:00
Jakub Jelen
6a187990c1 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)
2023-04-17 13:46:41 +02:00
khalid
ec5bd83e50 Remove zlib from the default compression methods and fips methods
Signed-off-by: Khalid Mamdouh <khalidmamdou7@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f9147a3cf4)
2023-04-17 13:46:41 +02:00
khalid
e818700734 Disabled preauth compression (zlib) by default
Removed it from the wanted methods list in the ssh_options_set function. Now users have to set the compression value to 'zlib' explicitly to enable it.
Updated unit tests to reflect removing zlib compression algo from the defaults compression algorithms.

Signed-off-by: Khalid Mamdouh <khalidmamdou7@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit cb19677d2e)
2023-04-17 13:46:41 +02:00
Andreas Schneider
9e20e180e6 gitlab-ci: We have cmake in Windows runners in the default path now
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0c6995b149)
2023-04-17 13:46:41 +02:00
Norbert Pocs
e426664623 doc: Fix doxygen errors when QUIET=yes EXTRACT_ALL=yes
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Sahana Prasad <sahana@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7b12876f04)
2023-03-20 13:41:04 +01:00
Andreas Schneider
921efbeea1 gitlab-ci: Don't install CMake
The choco server is somtimes ratelimited. Avoid running into issues
and use cmake already installed on the runner.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0b826c986c)
2023-03-20 13:41:04 +01:00
Ahsen Kamal
03f8fcae84 fix null dereference of error
The Coverity scan CID 1506418 found the null pointer dereferencing

Signed-off-by: Ahsen Kamal <itsahsenkamal@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6d3e7e1c44)
2023-03-20 13:41:04 +01:00
Andreas Schneider
ea639b0258 poll: Rename lock to lock_cnt and make it unsigned
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2ed0525f40)
2023-03-20 13:41:04 +01:00
Jakub Jelen
bb5bdac321 poll: Change the lock to block only POLLIN events
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 30b5a2e33b)
2023-03-20 13:41:04 +01:00
Jakub Jelen
554fe06aeb socket: Reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e15f493d4a)
2023-03-20 13:41:04 +01:00
Jakub Jelen
298155da71 Reformat ssh_packet_socket_callback
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 19c4de7350)
2023-03-20 13:41:04 +01:00
Jakub Jelen
44ceeb4d53 Reformat ssh_connector_fd_out_cb
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 832b94a660)
2023-03-20 13:41:04 +01:00
Jakub Jelen
0c725d7602 config: Fix indentation
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5506aadf05)
2023-03-20 13:41:04 +01:00
Jakub Jelen
2461027f72 bignum: Avoid bogus newline in the log
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 258560da16)
2023-03-20 13:41:04 +01:00
Ahsen Kamal
967082c207 free memory of peer_discon_msg
Signed-off-by: Ahsen Kamal <itsahsenkamal@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e364b1e793)
2023-03-20 13:41:04 +01:00
Ahsen Kamal
1f7995ccea test for peer_discon_msg
Signed-off-by: Ahsen Kamal <itsahsenkamal@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 49b34987d6)
2023-03-20 13:41:04 +01:00
Ahsen Kamal
662fe00c15 assign peer_discon_msg
Signed-off-by: Ahsen Kamal <itsahsenkamal@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4a7a7e3186)
2023-03-20 13:41:04 +01:00
Ahsen Kamal
0d86688da2 rename discon_msg to peer_discon_msg
Signed-off-by: Ahsen Kamal <itsahsenkamal@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e2b89dec9d)
2023-03-20 13:41:04 +01:00
Andreas Schneider
02f39b5e60 gitlab-ci: Use CentOS9 for Coverity builds
The Fedora 34 container is not available anymore. And we need gcc 11
as scan.coverity.com is on version 2022.6 supporting only gcc 11.

See
https://dev.sig-docs.synopsys.com/polaris/topics/r_coverity-compatible-platforms_2022.6.html

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e7b8de1363)
2023-03-01 14:41:24 +01:00
Norbert Pocs
1bf87909e7 src/options.c: Add documentation for default LogLevel
Libssh defaults to QUIET or SSH_LOG_NONE regarding of loglevel. Have it
documented to not confuse the users.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 486df37a84)
2023-02-02 10:45:16 +01:00
Norbert Pocs
096416d306 server: Add documentation to some functions
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9931f158e0)
2023-02-02 10:45:01 +01:00
Norbert Pocs
019040f693 documentation: Fix Missing param doxygen warnings
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b7c1f792cc)
2023-02-02 10:44:56 +01:00
Jakub Jelen
f1c5888553 ci: Update OpenSSL versions in the CI target names
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 6d34718f89)
2023-02-02 10:44:12 +01:00
Jakub Jelen
8a5bdc3a21 ci: Drop fedora/fips combination as it looks broken
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 31073780d1)
2023-02-02 10:44:02 +01:00
Jakub Jelen
3a77bb2992 tests: Use temporary variable to set test environment
avoids also long lines and code duplication

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 10296dbc76)
2023-02-02 10:43:09 +01:00
Jakub Jelen
b2ca8b07ec Clean up usage of HAVE_ECC and HAVE_ECDH
they might be turned off and on independenty and each of them affects different
part of libssh, authentication and key exchange respectively. But only HAVE_ECC
is defined by the cmake.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 492f5d82b8)
2023-02-02 10:42:58 +01:00
Jakub Jelen
1bc9b20b1a pki: Initialize pointers and avoid double-free with OSSL 3.0
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit dac62e7439)
2023-02-02 10:42:53 +01:00
Jakub Jelen
b9a6fac062 Do not build the PKCS#11 when disabled
This prevents building the pkcs11-related functions and printing pkcs11-related
log messages when the libssh is built without PKCS#11 support.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit ab24110ae0)
2023-02-02 10:42:48 +01:00
Jakub Jelen
2eee844025 tests: Reproducer for delayed compression rekey
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit c52f40bcb2)
2023-02-02 10:42:34 +01:00
Jakub Jelen
be2084f9e2 wrapper: Correctly handle rekey with delayed compression
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 98b81ebcad)
2023-02-02 10:42:29 +01:00
Jakub Jelen
cfa95d9ead wrapper: Reformat compression algorithms handling
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 342b69246c)
2023-02-02 10:42:27 +01:00
Jakub Jelen
1685c14024 Reformat gzip.c
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit c784bf345c)
2023-02-02 10:42:25 +01:00
Jakub Jelen
7f12c572d3 packet: Log at least names of unknown extensions
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 834603c96b)
2023-02-02 10:42:07 +01:00
Jakub Jelen
2177c9e567 cmake: Check for Argp also on Linux to fix alpine build
This adjusts also usage of ARGP_LIBRARY to use ARGP_LIBRARIES which is defined
by the FindArgp module, unlike the former one in case it is provided by libc
directly.

Fixes: #167

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 8f237bde15)
2023-02-02 10:41:53 +01:00
Jakub Jelen
96bc6af2b3 cmake: Document the consequences of enabling benchmarks
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit d54d45871a)
2023-02-02 10:41:48 +01:00
Jakub Jelen
ec33973319 include: Document the need to free the returned buffer
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit a5631280a9)
2023-02-02 10:41:42 +01:00
Jakub Jelen
512ac7620b examples: Avoid memory leak from sftp
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit 8c1b159a3a)
2023-02-02 10:41:35 +01:00
Norbert Pocs
d190053660 Add support for sk-keys through configuration
To be able to enable sk-ecdsa, sk-edd25519 key usage from the config file
the algorithms are needed to be listed in the algorithm lists.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 96ad1b380d)
2023-02-02 10:41:26 +01:00
Andreas Schneider
253658dce8 Happy new year 2023!
And happy anniversary libssh (20 years).

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit edcce095e0)
2023-02-02 10:41:10 +01:00
Norbert Pocs
8ac8b19017 torture_options.c: Add test for ssh_options_apply
Test that ssh_options_apply can be called multiple times without expanding
escape characters more than once. If the options are updated after calling
ssh_options_apply keep the last options.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(backported from commit df48ddd895)
2023-02-02 10:40:01 +01:00
Norbert Pocs
e8838f419b torture_options.c: Add identity test for ssh_options_copy
Test if the ssh_options_apply is called on session before ssh_options_copy,
then `opts.identity` ssh_list will be copied

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c0c063f94c)
2023-02-02 10:38:47 +01:00
Norbert Pocs
2b45e61f74 Add flags for escape expand operation
Calling `ssh_options_apply` more times can result in an unwanted behaviour of
expanding the escape characters more times. Adding flags to check if the
expansion was already done on the current string variables.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1bd499febb)
2023-02-02 10:38:43 +01:00
Norbert Pocs
54bcce5aa2 tests: Use opts.identites_non_exp not opts.identities
The configuration of identities are first saved to `opts.identities_non_exp`,
then moved to `opts.identities` after calling ssh_options_apply and expanding
the identity strings. These tests are testing against the proper configuration

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(backported from commit 87d694d5ad)
2023-02-02 10:38:24 +01:00
Norbert Pocs
1fb95070f2 Add a placehohlder for non-expanded identities
Expanding a string twice could lead to unwanted behaviour.
This solution creates a ssh_list (`opts.identites_non_exp`) to store the strings
before expansion and by using ssh_apply it moves the string to the
`opts.identities`. This way the expanded strings are separated.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 1ff893c914)
2023-02-02 10:36:55 +01:00
Norbert Pocs
438cc6df52 misc.c: Fix typo in docstring
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 435f1549f1)
2022-11-29 15:01:11 +01:00
Norbert Pocs
4aeb685b04 Fix memory leaks of bignums when openssl >= 3.0
The openssl 3.0 support has introduced some memory leaks at key build as
OSSL_PARAM_BLD_push_BN duplicates the bignum and does not save the pointer
itself.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4cd58350a8)
2022-11-29 15:01:08 +01:00
Andreas Schneider
54a3da64ad tests: Fix test with ssh as proxy command
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c8373e652c)
2022-11-25 15:41:31 +01:00
Andreas Schneider
e21ceae755 Add missing includes for fprintf()
src/init.c:118:9: warning: incompatible implicit declaration of built-in
function 'fprintf' [enabled by default]
         fprintf(stderr, "Error in auto_init()\n");
         ^

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
(cherry picked from commit da357b1cb4)
2022-11-25 15:41:29 +01:00
Andreas Schneider
905049d1e1 dh: Add missing include for fprintf()
src/dh.c:824:5: warning: incompatible implicit declaration of built-in
function 'fprintf' [enabled by default]
     fprintf(stderr, "%s\n", fingerprint);
     ^

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9941e89f30)
2022-11-25 15:41:28 +01:00
Norbert Pocs
2c03f3bd0b libcrypto.c: Change function parameter name
"new" is a c++ keyword which will make the build fail.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 23cebfadea)
2022-11-18 16:21:20 +01:00
Norbert Pocs
e218745d0e pki_ed25519_common.c: Change function parameter name
"new" is a c++ keyword which will make the build fail.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9d429eda93)
2022-11-18 16:21:20 +01:00
Norbert Pocs
24c44e2c7a misc.c/h: Change function parameter name
"template" is a c++ keyword which will make the build fail.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 34baecf49a)
2022-11-18 16:20:03 +01:00
Norbert Pocs
7fd953ef42 Add external c declaration for c++
To make sure c++ name mangling works correctly c code should be noted "extern"

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d1947b55ec)
2022-11-18 16:19:56 +01:00
David GUGLIELMI
80c994ef72 examples: fix htons implicit declaration in sshd_direct-tcpip
Signed-off-by: David GUGLIELMI <david.guglielmi@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5e81eec4ec)
2022-11-18 16:19:52 +01:00
Jakub Jelen
5c5811bf7c bind: Set socket connected after accepting connection
Also factor out the operation to the single place. Original patch drafted by
Zekun Ni in the following issue:

https://gitlab.com/libssh/libssh-mirror/-/issues/155

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 06a0a957c9)
2022-11-18 16:19:49 +01:00
Jakub Jelen
27f3e955e8 Reformat and initialize pointers
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8f7c179bed)
2022-11-18 16:19:48 +01:00
Norbert Pocs
54a0eb6846 setup-softhsm-tokens.sh: Fix shellcheck errors
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3c272d00fb)
2022-11-18 16:19:23 +01:00
Norbert Pocs
8c17a79797 Fix libsofthsm.so path detection
libsofthsm detection is broken in i686 architecture. The approach is to export
the path found by cmake to `tests_config.h` and the script
setup-softhsm-tokens.sh gets that value through cli parameters.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 50713d8ab1)
2022-11-18 16:19:21 +01:00
Jakub Jelen
13363975d8 sftp: Add comment about limitation of sftp_setstat
Fixes: #138

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 367be19990)
2022-11-18 16:18:57 +01:00
Jakub Jelen
e8dccfe1dd ci: Introduce spellchecker
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 769cb46ac8)
2022-11-18 16:18:50 +01:00
Jakub Jelen
bff436695b Fix various spelling issues reported by codespell
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 97c9ac2f58)
2022-11-18 16:18:44 +01:00
Jakub Jelen
e3d0f60281 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)
2022-11-18 16:18:39 +01:00
Jeroen Ooms
92eedd8f19 Support SSH_SUPPRESS_DEPRECATED
Signed-off-by: Jeroen Ooms <jeroenooms@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 78978dc6ce)
2022-11-18 16:18:33 +01:00
Norbert Pocs
a29f98be26 .gitlab-ci.yml: Run pkcs11 tests on c9s
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e29ffd78b3)
2022-11-18 16:18:19 +01:00
Norbert Pocs
53bc265987 .gitlab-ci.yml: Add c9s fips runner
Let's check tests in fips mode with an up to date system too as we already
found some issues running the tests there.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7757ebf7a5)
2022-11-18 16:18:17 +01:00
Carlos Martín Nieto
d993088553 packet: do not enqueue outgoing packets after sending SSH2_MSG_NEWKEYS
When we decide we need to rekey, we enqueue any further packets until we've sent
our SSH2_MSG_NEWKEYS message, after which we dequeue these packets and send them
to the other side. This enqueueing is done based on ssh_packet_in_rekey checking
the session flags and whether DH handshake state is marked as finished.

However, the handshake state is not reset to DH_STATE_FINISHED until the other
side has sent us their new keys. This leaves a gap between sending our new keys
and receiving the other side's new keys where we would still decide to enqueue a
packet.

These enqueued packets will not be dequeued as we've already sent our new keys.
Once we've received the other side's new keys, we'll go back to a finished
handshake and we will send out our caller's new data, skipping however much data
we've enqueued.

Fix this by changing ssh_packet_in_rekey to return false once we've sent our new
keys.

Signed-off-by: Carlos Martín Nieto <carlosmn@github.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 346e6db318)
2022-11-18 16:17:58 +01:00
Carlo Bramini
5d26b0967d Libssh-0.10.4 cannot be compiled anymore on CYGWIN
Commit 8cf9c816 "Do not force GNU_SOURCE during build to fix #141" has broken support for CYGWIN.
The build hangs with this error message:

libssh-0.10.4/src/config.c: In function ‘local_parse_glob’:
libssh-0.10.4/src/config.c:252:25: error: ‘GLOB_TILDE’ undeclared (first use in this function)
  252 |     rt = glob(fileglob, GLOB_TILDE, NULL, &globbuf);
      |                         ^~~~~~~~~~

I think that it would be better to re-add it, by using target_compile_definitions() rather than target_compile_options(), which is more appropriate in my opinion.

Signed-off-by: Carlo Bramini carlo_bramini@users.sourceforge.net
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 37deed27d6)
2022-11-18 16:17:45 +01:00
Norbert Pocs
0d52be0f5b torture_packet.c: Add fips check for deprecated cipher
FIPS 140-3 puts big limitations on using TDEA and it is
already disabled in rhel9.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 76d375064b)
2022-11-18 16:17:30 +01:00
Norbert Pocs
fc66be08a1 threads.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 38765d82fc)
2022-11-18 16:17:29 +01:00
Norbert Pocs
13a2aa3a97 session.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 80e77802ab)
2022-11-18 16:17:27 +01:00
Norbert Pocs
4a36e52bc4 server.c: Add missing function documentation
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4070784029)
2022-11-18 16:17:25 +01:00
Norbert Pocs
01a92b5838 poll.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 3d740c09da)
2022-11-18 16:17:23 +01:00
Norbert Pocs
e5f72468b8 pki.c: Add missing function documentation
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 27e223ba22)
2022-11-18 16:17:21 +01:00
Norbert Pocs
1761db6f97 misc.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 954f9c86ce)
2022-11-18 16:17:19 +01:00
Norbert Pocs
73ea9a8922 messages.c: Add missing function documentation
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 99bad9006e)
2022-11-18 16:17:17 +01:00
Norbert Pocs
78e79fbc35 log.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit c17b8f1fb2)
2022-11-18 16:17:14 +01:00
Norbert Pocs
990db53ee6 getrandom_crypto.c: Add function to the documentation
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d57a383d43)
2022-11-18 16:17:12 +01:00
Norbert Pocs
18b46a6e17 error.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 5ef99fcaa5)
2022-11-18 16:17:09 +01:00
Norbert Pocs
096996501b client.c: Add documentation
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 85f73a9bf6)
2022-11-18 16:17:05 +01:00
Norbert Pocs
569164740d buffer.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6d67d3ca5d)
2022-11-18 16:17:02 +01:00
Norbert Pocs
0da3fe245b auth.c: Remove dot from documentation group definition
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d3f0aabe7f)
2022-11-18 16:17:00 +01:00
Norbert Pocs
b448c3ad98 agent.c: Add missing docu to libssh_auth group
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f8ba12f0a6)
2022-11-18 16:16:53 +01:00
Biswapriyo Nath
02e0eaa104 cmake: Fix pkgconfig path relocation in mingw
This fixes patch relocation of the output of pkgconfig by adding
missing keywords like prefix, exec_prefix, libdir and includedir.
The pkgconfig output changes are like following:

* Before:
$ pkg-config -libs libssh
-lssh

* After:
$ pkg-config -libs libssh
-LF:/msys64/ucrt64/lib -lssh

See https://people.freedesktop.org/~dbn/pkg-config-guide.html for
further documentation.

Signed-off-by: Biswapriyo Nath <nathbappai@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 425353d986)
2022-11-18 16:16:47 +01:00
Thomas Baag
82e76a15d1 config: Escape brackets in ProxyCommand build from ProxyJump
Missing escaping results in syntax errors in Zsh shell because of square
brackets getting interpreted as being a pattern for globbing.

Signed-off-by: Thomas Baag <libssh-git@spam.b2ag.de>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bccb8513fa)
2022-11-18 16:16:40 +01:00
Norbert Pocs
bddbe2a76d dh_crypto.c: Add missing rv check
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bcc541f467)
2022-11-18 16:16:25 +01:00
Andreas Schneider
e8322817a9 Bump version to 0.10.4
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2022-09-07 15:30:40 +02:00
Andreas Schneider
e0c2f2809b kdf: Avoid endianess issues
The key_type is only a letter, if we use and `int` and then cast it to
(const char *) we will end up with a 0 value on big endian.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2022-09-07 15:29:03 +02:00
Andreas Schneider
9bb91df20f tests: Set OPENSSL_ENABLE_SHA1_SIGNATURES=1 for all tests
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2022-09-07 15:29:01 +02:00
Andreas Schneider
783f2b97a8 Bump version to 0.10.3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2022-09-05 14:27:29 +02:00
Andreas Schneider
8d05810255 tests: Add test with dss known_hosts file
We should not end up with an infinite loop here.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit accbc91a86)
2022-09-05 14:25:24 +02:00
Andreas Schneider
1d29d4b627 knownhosts: Fix and infinite loop when iterating known host entries
Fixes #145

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 3e4c2205c5)
2022-09-05 14:25:22 +02:00
Andreas Schneider
787711a271 knownhosts: Give better warnings about unsupported key types
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit 2d79c7a9d5)
2022-09-05 14:25:21 +02:00
Andreas Schneider
ddea657ba7 Bump version to 0.10.2
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2022-09-02 10:00:11 +02:00
Andreas Schneider
9ae46bc364 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)
2022-09-02 09:56:54 +02:00
Jakub Jelen
fd1563575f config: Expand tilde when handling include directives
Related: #93

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d69026d7a4)
2022-09-02 09:56:52 +02:00
Andreas Schneider
1f973320a8 tests: Use weak attribute for torture_run_tests() if available
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 7787dad9bd)
2022-09-02 09:56:50 +02:00
Andreas Schneider
4fc7ab4399 cmake: Check for weak attribute
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 23546e354c)
2022-09-02 09:56:48 +02:00
Jakub Jelen
87bac425a0 ci: Add apline linux target
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e5af9524e3)
2022-09-02 09:56:43 +02:00
Andreas Schneider
0e637e3327 src: Add ABI symbols for 4.9.1 2022-08-30 16:28:00 +02:00
Andreas Schneider
9b1f4e9bf6 Bump version to 0.10.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
2022-08-30 15:46:13 +02:00
Jakub Jelen
630f335415 libcrypto: Avoid unused variable warning
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f86727e06a)
2022-08-30 13:26:08 +02:00
Jakub Jelen
b7934ab370 socket: Remove needless typedef
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a69424d4c5)
2022-08-30 13:26:06 +02:00
Jakub Jelen
0aaad9eb25 wrapper: Avoid size_t to uint8 cast
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8aade7ce6f)
2022-08-30 13:26:05 +02:00
Jakub Jelen
8fe4cabb26 misc: Refactor ssh_strerror to check return values
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 41f2ee92c6)
2022-08-30 13:26:04 +02:00
Jakub Jelen
1689b83d0f Do not force GNU_SOURCE during build to fix #141
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8cf9c8162f)
2022-08-30 13:26:02 +02:00
Andreas Schneider
7c6105882b options: Use exec for the proxy command
This wont create a new process but replace the shell.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit bd2db30174)
2022-08-30 10:01:48 +02:00
Andreas Schneider
bb6d1b78dc socket: Add a comment about shells
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d642b20d9c)
2022-08-30 10:01:46 +02:00
Andreas Schneider
5a884b8c5a socket: Add error message if execv fails
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2546b62242)
2022-08-30 10:01:36 +02:00
Andreas Schneider
90128929e7 tests: Use ncat instead of nc
The ncat tool from nmap is available on all unix platforms. The nc
binary might link to ncat or something else. Settle on one we know
also the options can be used if needed.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6268417ac6)
2022-08-30 10:01:30 +02:00
Andreas Schneider
a7d509ca50 tests: Add test for expanding port numbers
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8c0be750db)
2022-08-30 10:00:54 +02:00
Andreas Schneider
d26f7253a9 session: Initialize the port with the standard port (22)
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit f306aafdc6)
2022-08-30 10:00:48 +02:00
Andreas Schneider
3ad2a21d13 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)
2022-08-30 10:00:38 +02:00
Andreas Schneider
7f6b3fab4e 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)
2022-08-26 14:10:39 +02:00
Jakub Jelen
cd7ccf93f0 Update changelog
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2022-08-26 11:34:08 +02:00
Jakub Jelen
5944124428 examples: Fix dereference after NULL check (CID 1461477)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8164e1ff9c)
2022-08-25 17:45:43 +02:00
renmingshuai
8c40b2491d session->socket_callbacks.data will be set to ssh_packet_socket_callback
in ssh_packet_register_socket_callback. Here is redundant.

Signed-off-by: renmingshuai <renmingshuai@huawei.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0799775185)
2022-08-25 17:36:45 +02:00
Timo Rothenpieler
3331b794bc misc: rename gettimeofday symbol
mingw does have this function, even though it appears to be deprecated.
So the symbol has to have a different name, or linking becomes
impossible.

Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 17aec429f5)
2022-08-25 17:36:42 +02:00
Jakub Jelen
02f1873b9e CMake: Do not build PKCS#11 URI support with OpenSSL <1.1.1
The old version is missing the EVP_PKEY_up_ref(), which is needed to keep track
of the EVP_PKEY references.

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 6e2648af6b)
2022-08-25 17:36:38 +02:00
Jakub Jelen
5da93db25a pki: Rework handling of EVP_PKEYs in OpenSSL backend
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 a81e78aff4)
2022-08-25 17:36:36 +02:00
Jakub Jelen
b18495b56b Initialize pkcs11 engine only once
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 0800618f32)
2022-08-25 17:36:30 +02:00
Jakub Jelen
a96763b195 libcrypto: Skip unneccessary call to ENGINE_cleanup in OSSL>1.1
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 f721ee847b)
2022-08-25 17:36:26 +02:00
Jakub Jelen
540257b421 pki: Factor out the backend-specifics from cleaning the key structure
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 382ff38caa)
2022-08-25 17:36:22 +02:00
Jakub Jelen
b657eeb65e tests: Prevent memory leaks from test
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 bc0c027ac0)
2022-08-25 17:36:16 +02:00
renmingshuai
4a87515026 tests: Ensure the mode of the created file is ...
what we set in open funtion by the argument mode. The mode of the created file
is (mode & ~umask), So we set umask to typical default value(octal 022).

Signed-off-by: renmingshuai <renmingshuai@huawei.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1286a70e13)
2022-08-08 10:17:05 +02:00
Jakub Jelen
886ed379d8 session: Avoid memory leak of agent_socket from configuration file
Thanks oss-fuzz

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

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aa1e136ea3)
2022-08-08 10:17:00 +02:00
Norbert Pocs
9b9197d86b gitlab-ci: Enable environment variable in centos9
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4d96c667bc)
2022-08-03 19:43:48 +02:00
Norbert Pocs
64e89affeb torture.c Add environment variable to server fork
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 2e8e666b1d)
2022-08-03 19:43:48 +02:00
Jakub Jelen
2c1ad3262a tests: Refactor and provide plain PKCS8 PEM format
This also allows testing mbedtls with the PKCS8 PEM files

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 66be590657)
2022-08-03 10:49:24 +02:00
Jakub Jelen
14ff31490f examples: Update keygen2 example to show fingerprints
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f193e6840d)
2022-08-03 10:49:22 +02:00
Jakub Jelen
3db3511467 curve25519: Do not check for openssl functions when other crypto backend is used
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0982715bb5)
2022-08-03 10:49:18 +02:00
Jakub Jelen
4c5da86f91 pki: Do not check for DSA headers when DSA is not built in
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ebeee7631d)
2022-08-03 10:49:17 +02:00
Jakub Jelen
2564246024 mbedcrypto: Refactor PEM parsing
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aca482a5a5)
2022-08-03 10:49:15 +02:00
Jakub Jelen
146d1a620d session: Initialize pointers
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 355e29d881)
2022-08-03 10:49:14 +02:00
Anderson Toshiyuki Sasaki
19c43ff6b7 init: Free global init mutex in the destructor on Windows
Fixes: #57 (T238)

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 163951d869)
2022-08-02 16:03:06 +02:00
Norbert Pocs
58a2943d42 .gitlab-ci: Add centos9 image
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 84df28ee31)
2022-08-02 16:03:05 +02:00
Norbert Pocs
54c5472b53 .gitlab-ci: Remove remaining rawhide lines
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 224298a4d0)
2022-08-02 16:03:03 +02:00
Jakub Jelen
17e9cd70a5 Move digest functions into separate file
The external ed25519 requires also the sha512 functions to work.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c09b02c573)
2022-08-02 16:01:42 +02:00
Jakub Jelen
cee5c9f404 Build external override library with all symbols
The curve25519 depends on ssh_get_random, which is normally built into libssh.
For the external override tests to build, we need to have them in separate
source file that can be included for this test.

For some reason, this did not happen on CI builds, but it did happen in koji
during RPM builds.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0da54f2908)
2022-08-02 16:01:35 +02:00
Andreas Schneider
43fb1d7c8d packet: Check hmac return codes in ssh_packet_hmac_verify()
CID #1490530

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit b42e9a19a3)
2022-07-14 15:03:58 +02:00
Andreas Schneider
5c629f22f6 packet: Use consistent return codes in ssh_packet_hmac_verify()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit e27ee9d0a4)
2022-07-14 15:03:57 +02:00
Andreas Schneider
46e0703c6e packet: Reformat ssh_packet_hmac_verify()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 4a7791b784)
2022-07-14 15:03:55 +02:00
Norbert Pocs
cffa103378 Make it work with openssl3.0
The KDF was changed in the new API, fetching the algorithm first
then creating the context using it.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 9a4c5203af)
2022-07-13 15:36:07 +02:00
Norbert Pocs
ea6558b3a6 Change cmake files for new openssl API
The new API does not provide EVP_KDF_CTX_new_id function, insted
it works with EVP_KDF_CTX_new and fetching the algorithm.
Adding a check for both to make it work with the new API too.

Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 8343a43edc)
2022-07-13 15:36:04 +02:00
Norbert Pocs
33e12317c3 torture_options: Add test for '@' in login name
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 964df4dc29)
2022-07-12 10:45:35 +02:00
Norbert Pocs
d17c635617 options: Parse hostname by last '@'
The login name can have '@' char in it

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 bb5f7e2707)
2022-07-12 10:45:34 +02:00
Norbert Pocs
dde5fd8d38 bind.c: Add missing size constant to err_msg
Signed-off-by: Norbert Pocs <npocs@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e53a2711d3)
2022-07-12 10:43:25 +02:00
Andreas Schneider
46e78aaa3a gitlab-ci: Drop the rawhide runner
Fedora 36 is using OpenSSL 3.0 now.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit a0c0efaf2e)
2022-07-11 11:02:20 +02:00
Andreas Schneider
3107133d10 tests: Setup Leak Sanitizer suppressions for OpenSSL
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 21ef488121)
2022-07-11 11:02:18 +02:00
Andreas Schneider
b9ccaf6e23 cmake: Build curve25519_ref.c if we build with libgcrypt
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0128ed0d2c)
2022-07-11 11:02:17 +02:00
Andreas Schneider
38b17e6e6e pki: Fix building pki_ed25519.c with libgcrypt
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 6a25f07777)
2022-07-11 11:02:16 +02:00
Andreas Schneider
db0a1d6811 src: Fix building curve25519 with libgcrypt
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit cc0939df73)
2022-07-11 11:02:14 +02:00
275 changed files with 12639 additions and 34733 deletions

View File

@@ -1,28 +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']

2
.gitignore vendored
View File

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

View File

@@ -1,9 +1,9 @@
---
variables:
BUILD_IMAGES_PROJECT: libssh/build-images
CENTOS7_BUILD: buildenv-centos7
CENTOS8_BUILD: buildenv-c8s
CENTOS9_BUILD: buildenv-c9s
CENTOS10_BUILD: buildenv-c10s
FEDORA_BUILD: buildenv-fedora
MINGW_BUILD: buildenv-mingw
TUMBLEWEED_BUILD: buildenv-tumbleweed
@@ -16,23 +16,12 @@ stages:
- test
- analysis
# This is some black magic to select between branch pipelines and
# merge request pipelines to avoid running same pipelines in twice
workflow:
rules:
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"'
when: never
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH'
.build:
stage: build
variables:
CMAKE_DEFAULT_OPTIONS: "-DCMAKE_BUILD_TYPE=RelWithDebInfo -DPICKY_DEVELOPER=ON"
CMAKE_BUILD_OPTIONS: "-DWITH_BLOWFISH_CIPHER=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON"
CMAKE_TEST_OPTIONS: "-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DGSSAPI_TESTING=ON -DWITH_BENCHMARKS=ON -DFUZZ_TESTING=ON"
CMAKE_BUILD_OPTIONS: "-DWITH_BLOWFISH_CIPHER=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON -DWITH_DSA=ON"
CMAKE_TEST_OPTIONS: "-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DWITH_BENCHMARKS=ON"
CMAKE_OPTIONS: $CMAKE_DEFAULT_OPTIONS $CMAKE_BUILD_OPTIONS $CMAKE_TEST_OPTIONS
before_script: &build
- uname -a
@@ -48,11 +37,7 @@ workflow:
make -j$(nproc) install
# Do not use after_script as it does not make the targets fail
tags:
- saas-linux-small-amd64
only:
- merge_requests
- branches
- shared
except:
- tags
artifacts:
@@ -75,6 +60,8 @@ workflow:
.fedora:
extends: .tests
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
.tumbleweed:
extends: .tests
@@ -83,7 +70,8 @@ workflow:
.fips:
extends: .tests
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
# DSA is turned off in fips mode
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_DSA=OFF
before_script:
- *build
- echo "# userspace fips" > /etc/system-fips
@@ -96,54 +84,20 @@ workflow:
- update-crypto-policies --set FIPS
- update-crypto-policies --show
###############################################################################
# Review #
###############################################################################
review:
variables:
GIT_DEPTH: 100
stage: review
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- ERROR=0
codespell --ignore-words-list=keypair,sorce,ned,nd,ue,pendin || ERROR=1;
./.gitlab-ci/clang-format-check.sh || ERROR=1;
./.gitlab-ci/git-check-signoff-trailer.sh ${CI_MERGE_REQUEST_DIFF_BASE_SHA} || ERROR=1;
./.gitlab-ci/shellcheck.sh || ERROR=1;
exit $ERROR
# the format is not always matching our intentions
allow_failure: true
tags:
- saas-linux-small-amd64
only:
- merge_requests
###############################################################################
# CentOS builds #
###############################################################################
centos10s/openssl_3.5.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS10_BUILD
# pkd tests fail on CentOS7 docker images, so we don't use -DSERVER_TESTING=ON
centos7/openssl_1.0.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD
extends: .tests
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
script:
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
- cmake3 $CMAKE_OPTIONS .. &&
make -j$(nproc) &&
ctest --output-on-failure
centos10s/openssl_3.5.x/x86_64/fips:
extends: .fips
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS10_BUILD
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
script:
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
make -j$(nproc) &&
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
centos9s/openssl_3.5.x/x86_64:
centos9s/openssl_3.0.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
extends: .tests
variables:
@@ -154,13 +108,7 @@ centos9s/openssl_3.5.x/x86_64:
make -j$(nproc) &&
ctest --output-on-failure
centos9s/mbedtls_2.x/x86_64:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
extends: .tests
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_BLOWFISH_CIPHER=OFF"
centos9s/openssl_3.5.x/x86_64/fips:
centos9s/openssl_3.0.x/x86_64/fips:
extends: .fips
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
script:
@@ -198,82 +146,32 @@ fedora/docs:
extends: .build
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- cmake .. && make docs_coverage && make docs
coverage: '/^Documentation coverage is \d+.\d+%/'
- cmake .. && make docs
fedora/ninja:
extends: .fedora
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- cmake -G Ninja $CMAKE_OPTIONS ../ && ninja && CTEST_OUTPUT_ON_FAILURE=1 ninja test
fedora/coverage:
extends: .fedora
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug -DWITH_COVERAGE=ON"
script:
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
make -j$(nproc) &&
make coverage_xml
coverage: /^\s*lines:\s*\d+.\d+\%/
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
expire_in: 1 week
reports:
coverage_report:
coverage_format: cobertura
path: obj/coverage_xml.xml
- cmake -G Ninja $CMAKE_OPTIONS ../ && ninja && ninja test
fedora/openssl_3.0.x/x86_64:
extends: .fedora
fedora/openssl_3.0.x/x86_64/pkcs11-provider:
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON -DWITH_PKCS11_PROVIDER=ON
extends: .fedora
fedora/openssl_3.0.x/x86_64/minimal:
extends: .fedora
variables:
script:
- cmake $CMAKE_DEFAULT_OPTIONS
-DWITH_EXEC=OFF
-DWITH_SFTP=OFF
-DWITH_SERVER=OFF
-DWITH_ZLIB=OFF
-DWITH_PCAP=OFF
-DWITH_DSA=OFF
-DUNIT_TESTING=ON
-DCLIENT_TESTING=ON
-DWITH_GEX=OFF .. &&
make -j$(nproc)
.valgrind:
extends: .fedora
stage: analysis
script:
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
make -j$(nproc) &&
make test_memcheck
- cat Testing/Temporary/MemoryChecker.*.log | wc -l | grep "^0$"
# The PKCS#11 support is turned off as it brings dozens of memory issues from
# engine_pkcs11 or openssl itself
fedora/valgrind/openssl:
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=OFF
extends: .valgrind
fedora/valgrind/mbedtls:
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_MBEDTLS=ON
extends: .valgrind
fedora/valgrind/libgcrypt:
variables:
CMAKE_ADDITIONAL_OPTIONS: -DWITH_GCRYPT=ON
extends: .valgrind
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
# so, this is only enabled for unit tests right now.
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
@@ -329,10 +227,10 @@ fedora/libgcrypt/x86_64:
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_GCRYPT=ON -DWITH_DEBUG_CRYPTO=ON"
fedora/mbedtls_2.x/x86_64:
fedora/mbedtls/x86_64:
extends: .fedora
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON "
CMAKE_ADDITIONAL_OPTIONS: "-DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_DSA=OFF"
# Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW
@@ -349,7 +247,7 @@ fedora/mingw64:
-DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure -E torture_rand
ctest --output-on-failure
# Unit testing only, no client and pkd testing, because cwrap is not available
# for MinGW
@@ -366,7 +264,7 @@ fedora/mingw32:
-DWITH_PCAP=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure -E torture_rand
ctest --output-on-failure
###############################################################################
@@ -379,11 +277,6 @@ fedora/mingw32:
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
before_script:
- |
# for merge requests
if [[ -n "$CI_MERGE_REQUEST_DIFF_BASE_SHA" ]]; then
export CI_COMMIT_BEFORE_SHA="$CI_MERGE_REQUEST_DIFF_BASE_SHA"
fi
# for branches run
if [[ -z "$CI_COMMIT_BEFORE_SHA" ]]; then
export CI_COMMIT_BEFORE_SHA=$(git rev-parse "${CI_COMMIT_SHA}~20")
fi
@@ -394,11 +287,9 @@ fedora/mingw32:
export CI_COMMIT_RANGE="$CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA"
tags:
- saas-linux-small-amd64
- shared
except:
- tags
only:
- merge_requests
artifacts:
expire_in: 1 week
when: on_failure
@@ -410,7 +301,7 @@ fedora/csbuild/openssl_3.0.x:
script:
- csbuild
--build-dir=obj-csbuild
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON @SRCDIR@ && make clean && make -j$(nproc)"
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_DSA=ON @SRCDIR@ && make clean && make -j$(nproc)"
--git-commit-range $CI_COMMIT_RANGE
--color
--print-current --print-fixed
@@ -420,7 +311,7 @@ fedora/csbuild/libgcrypt:
script:
- csbuild
--build-dir=obj-csbuild
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_GCRYPT=ON @SRCDIR@ && make clean && make -j$(nproc)"
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_GCRYPT=ON -DWITH_DSA=ON @SRCDIR@ && make clean && make -j$(nproc)"
--git-commit-range $CI_COMMIT_RANGE
--color
--print-current --print-fixed
@@ -466,6 +357,8 @@ alpine/openssl_3.0.x/musl:
###############################################################################
tumbleweed/openssl_3.0.x/x86_64/gcc:
extends: .tumbleweed
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config"
tumbleweed/openssl_3.0.x/x86/gcc:
extends: .tumbleweed
@@ -477,13 +370,14 @@ tumbleweed/openssl_3.0.x/x86/gcc:
-DWITH_SERVER=ON
-DWITH_ZLIB=ON
-DWITH_PCAP=ON
-DWITH_DSA=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc)
tumbleweed/openssl_3.0.x/x86_64/gcc7:
extends: .tumbleweed
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7"
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7 -DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config"
tumbleweed/openssl_3.0.x/x86/gcc7:
extends: .tumbleweed
@@ -493,6 +387,7 @@ tumbleweed/openssl_3.0.x/x86/gcc7:
-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
$CMAKE_DEFAULT_OPTIONS
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
-DWITH_DSA=ON
-DUNIT_TESTING=ON .. &&
make -j$(nproc) &&
ctest --output-on-failure
@@ -500,12 +395,7 @@ tumbleweed/openssl_3.0.x/x86/gcc7:
tumbleweed/openssl_3.0.x/x86_64/clang:
extends: .tumbleweed
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++"
tumbleweed/mbedtls-3.6.x/x86_64/gcc:
extends: .tumbleweed
variables:
CMAKE_ADDITIONAL_OPTIONS: "-DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config -DWITH_MBEDTLS=ON -DWITH_DEBUG_CRYPTO=ON -DWITH_BLOWFISH_CIPHER=OFF "
CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DKRB5_CONFIG=/usr/lib/mit/bin/krb5-config"
tumbleweed/static-analysis:
extends: .tests
@@ -565,12 +455,8 @@ freebsd/openssl_1.1.1/x86_64:
###############################################################################
# Visual Studio builds #
###############################################################################
# 2024-05-13: These jobs run out of the stages as they take extremely long and
# usually timeout with the update to Gitlab 17.0
.vs:
stage: analysis
needs: []
allow_failure: true
stage: test
cache:
key: vcpkg.${CI_JOB_NAME}
paths:
@@ -581,10 +467,8 @@ freebsd/openssl_1.1.1/x86_64:
- cmake --build .
- ctest --output-on-failure
tags:
- saas-windows-medium-amd64
only:
- merge_requests
- branches
- windows
- shared-windows
except:
- tags
artifacts:
@@ -648,7 +532,7 @@ coverity:
--form description="CI build"
https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
tags:
- saas-linux-small-amd64
- shared
only:
refs:
- master
@@ -662,3 +546,14 @@ coverity:
when: on_failure
paths:
- obj/cov-int/*.txt
###############################################################################
# Codespell #
###############################################################################
codespell:
stage: review
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
script:
- codespell --ignore-words-list=keypair,sorce,ned,nd,ue
tags:
- shared

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,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/*''',
]

119
CHANGELOG
View File

@@ -1,122 +1,6 @@
CHANGELOG
=========
version 0.11.3 (released 2025-09-09)
* Security:
* CVE-2025-8114: Fix NULL pointer dereference after allocation failure
* CVE-2025-8277: Fix memory leak of ephemeral key pair during repeated wrong KEX
* Potential UAF when send() fails during key exchange
* Fix possible timeout during KEX if client sends authentication too early (#311)
* Cleanup OpenSSL PKCS#11 provider when loaded
* Zeroize buffers containing private key blobs during export
version 0.11.2 (released 2025-06-24)
* Security:
* CVE-2025-4877 - Write beyond bounds in binary to base64 conversion
* CVE-2025-4878 - Use of uninitialized variable in privatekey_from_file()
* CVE-2025-5318 - Likely read beyond bounds in sftp server handle management
* CVE-2025-5351 - Double free in functions exporting keys
* CVE-2025-5372 - ssh_kdf() returns a success code on certain failures
* CVE-2025-5449 - Likely read beyond bounds in sftp server message decoding
* CVE-2025-5987 - Invalid return code for chacha20 poly1305 with OpenSSL
* Compatibility
* Fixed compatibility with CPM.cmake
* Compatibility with OpenSSH 10.0
* Tests compatibility with new Dropbear releases
* Removed p11-kit remoting from the pkcs11 testsuite
* Bugfixes
* Implement missing packet filter for DH GEX
* Properly process the SSH2_MSG_DEBUG message
* Allow escaping quotes in quoted arguments to ssh configuration
* Do not fail with unknown match keywords in ssh configuration
* Process packets before selecting signature algorithm during authentication
* Do not fail hard when the SFTP status message is not sent by noncompliant
servers
version 0.11.1 (released 2024-08-30)
* Fixed default TTY modes that are set when stdin is not connected to tty (#270)
* Fixed zlib cleanup procedure, which could crash on i386
* Various test fixes improving their stability
* Fixed cygwin build
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)
* 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
@@ -184,6 +68,9 @@ version 0.10.0 (released 2022-08-26)
* Deprecated old pubkey, privatekey API
* Avoided some needless large stack buffers to minimize memory footprint
* Removed support for OpenSSL < 1.0.1
* Fixed parsing username@host in login name
* Free global init mutex in the destructor on Windows
* Fixed PEM parsing in mbedtls to support both legacy and new PKCS8 formats
version 0.9.6 (released 2021-08-26)
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with

View File

@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.14.0)
cmake_minimum_required(VERSION 3.3.0)
cmake_policy(SET CMP0048 NEW)
# Specify search path for CMake modules to be loaded by include()
# and find_package()
@@ -9,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.11.3 LANGUAGES C)
project(libssh VERSION 0.10.5 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.3")
set(LIBRARY_VERSION "4.9.5")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
@@ -48,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 1.0.1)
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,6 +89,13 @@ if (WITH_GSSAPI)
find_package(GSSAPI)
endif (WITH_GSSAPI)
if (WITH_PKCS11_URI)
find_package(softhsm)
if (NOT SOFTHSM_FOUND)
message(SEND_ERROR "Could not find softhsm module!")
endif (NOT SOFTHSM_FOUND)
endif (WITH_PKCS11_URI)
if (WITH_NACL)
find_package(NaCl)
if (NOT NACL_FOUND)
@@ -75,6 +103,8 @@ if (WITH_NACL)
endif (NOT NACL_FOUND)
endif (WITH_NACL)
find_package(Argp)
# Disable symbol versioning in non UNIX platforms
if (UNIX)
find_package(ABIMap 0.3.1)
@@ -86,10 +116,6 @@ 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)
@@ -188,36 +214,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}")
@@ -227,14 +233,13 @@ 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 "Blowfish cipher support: ${WITH_BLOWFISH_CIPHER}")
message(STATUS "PKCS #11 URI support: ${WITH_PKCS11_URI}")
message(STATUS "With PKCS #11 provider support: ${WITH_PKCS11_PROVIDER}")
message(STATUS "DSA support: ${WITH_DSA}")
set(_SERVER_TESTING OFF)
if (WITH_SERVER)
set(_SERVER_TESTING ${SERVER_TESTING})

View File

@@ -478,45 +478,6 @@ 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;
}
Have fun and happy libssh hacking!

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

@@ -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)
@@ -92,12 +86,9 @@ if (UNIX)
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()
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()

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,32 +75,78 @@ 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_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
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)
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)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_function_exists(EVP_chacha20 HAVE_OPENSSL_EVP_CHACHA20)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
check_symbol_exists(EVP_PKEY_POLY1305 "openssl/evp.h" HAVE_OPENSSL_EVP_POLY1305)
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)
endif()
@@ -127,6 +170,12 @@ if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS)
endif ()
if (WITH_DSA)
if (NOT WITH_MBEDTLS)
set(HAVE_DSA 1)
endif (NOT WITH_MBEDTLS)
endif()
# FUNCTIONS
check_function_exists(isblank HAVE_ISBLANK)
@@ -236,10 +285,6 @@ if (MBEDTLS_FOUND)
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 (WITH_BLOWFISH_CIPHER)
check_include_file(blowfish.h HAVE_BLOWFISH)
endif()
unset(CMAKE_REQUIRED_INCLUDES)
endif (MBEDTLS_FOUND)
@@ -444,22 +489,22 @@ 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)
endif()
if (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()
if (HAVE_OPENSSL AND NOT OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.1")
message(FATAL_ERROR "PKCS #11 requires at least OpenSSL 1.1.1")
set(WITH_PKCS11_URI 0)
endif()
endif()
if (WITH_MBEDTLS)
if (WITH_DSA)
message(FATAL_ERROR "DSA is not supported with mbedTLS crypto")
set(HAVE_DSA 0)
endif()
endif()
# ENDIAN

View File

@@ -5,18 +5,17 @@ option(WITH_SERVER "Build with SSH server support" ON)
option(WITH_DEBUG_CRYPTO "Build with crypto 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_DSA "Build with DSA" 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_EXAMPLES "Build examples" ON)
option(WITH_NACL "Build with libnacl (curve25519)" ON)
@@ -24,7 +23,6 @@ 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(PICKY_DEVELOPER "Build with picky developer flags" OFF)
@@ -39,7 +37,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()
@@ -62,7 +60,3 @@ endif (NOT GLOBAL_CLIENT_CONFIG)
if (FUZZ_TESTING)
set(WITH_INSECURE_NONE ON)
endif (FUZZ_TESTING)
if (WIN32)
set(WITH_EXEC 0)
endif(WIN32)

11
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) >= 3.3.0
- [openssl](https://www.openssl.org) >= 1.0.1
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.

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

@@ -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

@@ -64,7 +64,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

@@ -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
@@ -73,14 +73,6 @@ set(MBEDTLS_LIBRARIES ${MBEDTLS_SSL_LIBRARY} ${MBEDTLS_CRYPTO_LIBRARY}
${MBEDTLS_X509_LIBRARY})
if (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
# mbedtls 2.8
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]+).*"
"\\1" MBEDTLS_VERSION "${_mbedtls_version_str}")
elseif (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
# mbedtls 3.6
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]+\"")
@@ -101,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)
@@ -110,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

@@ -58,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
@@ -91,9 +91,21 @@
/* Define to 1 if you have elliptic 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 OpenSSL with Ed25519 support */
#cmakedefine HAVE_OPENSSL_ED25519 1
/* Define to 1 if you have OpenSSL with X25519 support */
#cmakedefine HAVE_OPENSSL_X25519 1
/* Define to 1 if you have OpenSSL with Poly1305 support */
#cmakedefine HAVE_OPENSSL_EVP_POLY1305 1
/* Define to 1 if you have gcrypt with ChaCha20/Poly1305 support */
#cmakedefine HAVE_GCRYPT_CHACHA_POLY 1
@@ -108,6 +120,15 @@
/* 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
@@ -180,9 +201,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). */
@@ -234,14 +252,9 @@
/* 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 */
/* Define to 1 if you want to enable 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
@@ -263,9 +276,6 @@
/* 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,7 +14,6 @@ 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
@@ -36,44 +35,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 +45,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

@@ -105,7 +105,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 +218,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 +231,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 +251,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 +354,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);

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,7 +100,7 @@ used to retrieve google's home page from the remote SSH server.
@code
int direct_forwarding(ssh_session session)
{
ssh_channel forwarding_channel = NULL;
ssh_channel forwarding_channel;
int rc = SSH_ERROR;
char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n";
int nbytes, nwritten;
@@ -161,7 +161,7 @@ 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;

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

@@ -20,7 +20,7 @@ the interesting functions as you go.
The libssh library provides:
- <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
- <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
- <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
@@ -33,7 +33,7 @@ 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
@@ -213,15 +213,15 @@ It was later modified and expanded by the following RFCs.
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

@@ -9,11 +9,11 @@ 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):
Pre-requisites:
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.
OpenSSL 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 engine.
To build and use libssh with PKCS #11 support:
1. Enable the cmake option: $ cmake -DWITH_PKCS11_URI=ON
@@ -21,23 +21,6 @@ To build and use libssh with PKCS #11 support:
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
@@ -48,7 +31,7 @@ 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
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:
@@ -81,6 +64,4 @@ We recommend the users to provide a specific PKCS #11 URI so that it matches onl
If the engine discovers multiple slots that could potentially contain the private keys referenced
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().

View File

@@ -29,12 +29,6 @@ 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})

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);
@@ -143,7 +143,7 @@ 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);

View File

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

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;

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

@@ -38,7 +38,6 @@ struct arguments_st {
unsigned long bits;
char *file;
char *passphrase;
char *format;
int action_list;
};
@@ -53,6 +52,7 @@ static struct argp_option options[] = {
"Accepted values are: "
"1024, 2048, 3072 (default), 4096, and 8192 for TYPE=\"rsa\"; "
"256 (default), 384, and 521 for TYPE=\"ecdsa\"; "
"1024 (default) and 2048 for TYPE=\"dsa\"; "
"can be omitted for TYPE=\"ed25519\" "
"(it will be ignored if provided).\n",
.group = 0
@@ -86,7 +86,7 @@ static struct argp_option options[] = {
.flags = 0,
.doc = "The type of the key to be generated. "
"Accepted values are: "
"\"rsa\", \"ecdsa\", and \"ed25519\".\n",
"\"rsa\", \"ecdsa\", \"ed25519\", and \"dsa\".\n",
.group = 0
},
{
@@ -97,16 +97,6 @@ static struct argp_option options[] = {
.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
@@ -163,6 +153,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
if (!strcmp(arg, "rsa")) {
arguments->type = SSH_KEYTYPE_RSA;
}
else if (!strcmp(arg, "dsa")) {
arguments->type = SSH_KEYTYPE_DSS;
}
else if (!strcmp(arg, "ecdsa")) {
arguments->type = SSH_KEYTYPE_ECDSA;
}
@@ -179,9 +172,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
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. */
@@ -263,6 +253,29 @@ static int validate_args(struct arguments_st *args)
}
}
break;
case SSH_KEYTYPE_DSS:
switch (args->bits) {
case 0:
/* If not provided, use default value */
args->bits = 1024;
break;
case 1024:
case 2048:
break;
default:
fprintf(stderr, "Error: Invalid bits parameter provided\n");
rc = EINVAL;
break;
}
if (args->file == NULL) {
args->file = strdup("id_dsa");
if (args->file == NULL) {
rc = ENOMEM;
break;
}
}
break;
case SSH_KEYTYPE_ED25519:
/* Ignore value and overwrite with a zero */
@@ -310,7 +323,6 @@ list_fingerprint(char *file)
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);
@@ -397,36 +409,8 @@ int main(int argc, char *argv[])
}
/* 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);
}
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;

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

@@ -26,9 +26,9 @@ program.
#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 {
@@ -114,10 +114,9 @@ static void location_free(struct location *loc)
}
}
static struct location *parse_location(char *loc)
{
struct location *location = NULL;
char *ptr = NULL;
static struct location *parse_location(char *loc) {
struct location *location;
char *ptr;
location = malloc(sizeof(struct location));
if (location == NULL) {
@@ -230,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));

View File

@@ -35,8 +35,8 @@ clients must be made or how a client should react.
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 +142,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 +180,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 +216,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,
@@ -220,13 +231,13 @@ int main(int argc, char **argv)
char buf[BUF_SIZE];
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
/*
@@ -337,3 +348,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

@@ -33,13 +33,16 @@ clients must be made or how a client should react.
#define BUF_SIZE 65536
#endif
static int verbosity;
static char *destination;
static void do_sftp(ssh_session session) {
sftp_session sftp = sftp_new(session);
sftp_dir dir;
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;
@@ -186,8 +189,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 +201,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,10 +220,10 @@ 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));
@@ -241,63 +244,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

@@ -172,12 +172,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
},
{
@@ -210,10 +218,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':
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;
@@ -244,11 +257,10 @@ 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,
@@ -266,7 +278,8 @@ 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
/*
@@ -340,3 +353,4 @@ int main(int argc, char **argv)
ssh_finalize();
return 0;
}

View File

@@ -112,12 +112,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 +151,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 +187,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,12 +292,11 @@ 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;
int main(int argc, char **argv){
ssh_session session;
ssh_bind sshbind;
ssh_message message;
ssh_channel chan=0;
char buf[BUF_SIZE];
int auth=0;
int shell=0;
@@ -294,8 +306,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
/*
@@ -412,3 +426,4 @@ int main(int argc, char **argv)
ssh_finalize();
return 0;
}

View File

@@ -108,7 +108,7 @@ static int fetch_files(ssh_session session){
int size;
char buffer[BUF_SIZE];
int mode;
char *filename = NULL;
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){
@@ -167,7 +167,7 @@ static int fetch_files(ssh_session session){
}
int main(int argc, char **argv){
ssh_session session = NULL;
ssh_session session;
if(opts(argc,argv)<0)
return EXIT_FAILURE;
session=connect_ssh(host,NULL,verbosity);

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,7 @@ 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,
@@ -94,6 +94,7 @@ 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
@@ -251,7 +252,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);
@@ -297,41 +298,25 @@ 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[PATH_MAX];
size_t i;
int s = 0;
for (i = 0; i < MAXCMD && cmds[i]; ++i) {
s += snprintf(buffer + s, sizeof(buffer) - s, "%s ", cmds[i]);
}
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 +324,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) {
@@ -423,7 +408,7 @@ static void cleanup_pcap(void)
int main(int argc, char **argv)
{
ssh_session session = NULL;
ssh_session session;
ssh_init();
session = ssh_new();

View File

@@ -45,10 +45,36 @@ The goal is to show the API in action.
#define BUF_SIZE 1048576
#endif
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "/etc/ssh/"
#endif
#endif
#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";
@@ -83,12 +109,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 +130,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
},
{
@@ -123,6 +157,14 @@ static struct argp_option options[] = {
.doc = "Set expected password.",
.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',
@@ -135,53 +177,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 '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);
}
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;
}
@@ -189,17 +253,21 @@ parse_opt(int key, char *arg, struct argp_state *state)
/* 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)
{
static int parse_opt(int argc, char **argv, ssh_bind sshbind) {
int no_default_keys = 0;
int rsa_already_set = 0;
int dsa_already_set = 0;
int ecdsa_already_set = 0;
int key;
while((key = getopt(argc, argv, "a:e:k:p:P:r:u:v")) != -1) {
if (key == 'p') {
while((key = getopt(argc, argv, "a:d:e:k:np:P:r:u:v")) != -1) {
if (key == 'n') {
no_default_keys = 1;
} else if (key == 'p') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, optarg);
} else if (key == 'd') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, optarg);
dsa_already_set = 1;
} else if (key == 'k') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
/* We can't track the types of keys being added with this
@@ -207,10 +275,10 @@ parse_opt(int argc, char **argv, ssh_bind sshbind)
by just not setting the default keys */
no_default_keys = 1;
} else if (key == 'r') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, optarg);
rsa_already_set = 1;
} else if (key == 'e') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, optarg);
ecdsa_already_set = 1;
} else if (key == 'a') {
strncpy(authorizedkeys, optarg, DEF_STR_SIZE-1);
@@ -231,12 +299,14 @@ parse_opt(int argc, char **argv, ssh_bind sshbind)
"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"
" -d, --dsakey=FILE Set the dsa key.\n"
" -e, --ecdsakey=FILE Set the ecdsa key.\n"
" -k, --hostkey=FILE Set a host key. Can be used multiple times.\n"
" Implies no default keys.\n"
" -n, --no-default-keys Do not set default key locations.\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"
" -r, --rsakey=FILE Set the rsa key.\n"
" -u, --user=USERNAME Set expected username.\n"
" -v, --verbose Get verbose output.\n"
" -?, --help Give this help list\n"
@@ -259,6 +329,7 @@ parse_opt(int argc, char **argv, ssh_bind sshbind)
if (!no_default_keys) {
set_default_keys(sshbind,
rsa_already_set,
dsa_already_set,
ecdsa_already_set);
}
@@ -292,74 +363,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;
@@ -373,36 +419,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. */
@@ -416,24 +456,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]);
@@ -459,18 +498,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;
}
@@ -480,15 +516,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;
}
@@ -499,28 +534,20 @@ 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) {
sdata->authenticated = 1;
@@ -531,26 +558,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;
@@ -560,107 +577,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);
@@ -672,12 +627,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);
@@ -689,9 +642,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;
@@ -804,8 +755,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);
@@ -838,14 +789,12 @@ 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)
{
static void *session_thread(void *arg) {
ssh_session session = arg;
ssh_event event;
@@ -864,10 +813,9 @@ static void *session_thread(void *arg)
}
#endif
int main(int argc, char **argv)
{
ssh_bind sshbind = NULL;
ssh_session session = NULL;
int main(int argc, char **argv) {
ssh_bind sshbind;
ssh_session session;
int rc;
#ifdef WITH_FORK
struct sigaction sa;
@@ -905,8 +853,7 @@ int main(int argc, char **argv)
}
#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();
@@ -921,36 +868,34 @@ int main(int argc, char **argv)
}
/* Blocks until there is a new incoming connection. */
rc = ssh_bind_accept(sshbind, session);
if (rc != SSH_ERROR) {
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
#ifdef WITH_FORK
ssh_event event;
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);
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);
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;

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"
@@ -94,9 +94,6 @@ 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) {
new_node->next = *head_ref;
@@ -361,7 +358,7 @@ 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];
int blocking;
@@ -455,8 +452,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 +496,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,7 +523,7 @@ 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);
@@ -589,12 +586,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 +626,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 +665,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 +685,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

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

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

@@ -39,9 +39,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;

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

View File

@@ -42,6 +42,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,

View File

@@ -27,7 +27,6 @@
#include <libssh/libssh.h>
#include <string.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@@ -139,26 +138,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,11 +171,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;
@@ -283,7 +257,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
@@ -366,7 +339,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.
@@ -825,28 +797,6 @@ typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
uint32_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;
@@ -914,14 +864,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;
@@ -1058,7 +1000,6 @@ 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.
@@ -1076,45 +1017,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

@@ -80,12 +80,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 */

View File

@@ -62,10 +62,6 @@ enum ssh_config_opcode_e {
SOC_PUBKEYACCEPTEDKEYTYPES,
SOC_REKEYLIMIT,
SOC_IDENTITYAGENT,
SOC_IDENTITIESONLY,
SOC_CONTROLMASTER,
SOC_CONTROLPATH,
SOC_CERTIFICATE,
SOC_MAX /* Keep this one last in the list */
};

View File

@@ -30,9 +30,6 @@
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,32 +49,14 @@ 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);
char **username,
char **hostname,
char **port);
#ifdef __cplusplus
}

View File

@@ -86,9 +86,9 @@ enum ssh_key_exchange_e {
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,
@@ -111,7 +111,11 @@ struct ssh_crypto_struct {
#endif /* WITH_GEX */
#ifdef HAVE_ECDH
#ifdef HAVE_OPENSSL_ECC
#if OPENSSL_VERSION_NUMBER < 0x30000000L
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
* https://github.com/openssl/openssl/pull/16624
* #if OPENSSL_VERSION_NUMBER < 0x30000000L
*/
#if 1
EC_KEY *ecdh_privkey;
#else
EVP_PKEY *ecdh_privkey;
@@ -223,8 +227,9 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
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 HAVE_LIBCRYPTO
ENGINE *pki_get_engine(void);
#endif /* HAVE_LIBCRYPTO */
#ifdef __cplusplus
}

View File

@@ -22,9 +22,7 @@
#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
@@ -35,32 +33,6 @@ typedef struct ssh_gssapi_struct *ssh_gssapi;
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 +44,10 @@ 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

@@ -40,15 +40,10 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit);
int ssh_send_kex(ssh_session session);
void ssh_list_kex(struct ssh_kex_struct *kex);
int ssh_set_client_kex(ssh_session session);
int ssh_kex_append_extensions(ssh_session session, struct ssh_kex_struct *pkex);
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);

View File

@@ -29,22 +29,36 @@ 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)
#if OPENSSL_VERSION_NUMBER < 0x30000000L
DSA *dsa_pub;
RSA *rsa_pub;
#else /* OPENSSL_VERSION_NUMBER */
EVP_PKEY *key_pub;
#endif
#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)
#if OPENSSL_VERSION_NUMBER < 0x30000000L
DSA *dsa_priv;
RSA *rsa_priv;
#else
EVP_PKEY *key_priv;
#endif /* OPENSSL_VERSION_NUMBER */
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa_priv;
void *dsa_priv;
#endif
};

View File

@@ -25,14 +25,13 @@
#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;
@@ -40,6 +39,11 @@ typedef EVP_MD_CTX* SHA384CTX;
typedef EVP_MD_CTX* SHA512CTX;
typedef EVP_MD_CTX* MD5CTX;
typedef EVP_MD_CTX* HMACCTX;
#ifdef HAVE_ECC
typedef EVP_MD_CTX *EVPCTX;
#else
typedef void *EVPCTX;
#endif
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
@@ -54,15 +58,8 @@ 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>
typedef BIGNUM* bignum;
typedef const BIGNUM* const_bignum;
typedef BN_CTX* bignum_CTX;
@@ -119,17 +116,6 @@ typedef BN_CTX* bignum_CTX;
#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

@@ -32,6 +32,7 @@ typedef gcry_md_hd_t SHA384CTX;
typedef gcry_md_hd_t SHA512CTX;
typedef gcry_md_hd_t MD5CTX;
typedef gcry_md_hd_t HMACCTX;
typedef gcry_md_hd_t EVPCTX;
#define SHA_DIGEST_LENGTH 20
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define MD5_DIGEST_LEN 16
@@ -48,8 +49,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;

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;
@@ -42,6 +41,7 @@ typedef mbedtls_md_context_t *SHA384CTX;
typedef mbedtls_md_context_t *SHA512CTX;
typedef mbedtls_md_context_t *MD5CTX;
typedef mbedtls_md_context_t *HMACCTX;
typedef mbedtls_md_context_t *EVPCTX;
#define SHA_DIGEST_LENGTH 20
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
@@ -59,8 +59,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;
@@ -81,7 +79,7 @@ extern "C" {
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 +105,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 +127,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)

View File

@@ -1,7 +1,7 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2003-2025 by Aris Adamantiadis and the libssh team
* Copyright (c) 2003-2023 by Aris Adamantiadis and the libssh team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -50,13 +50,18 @@
#endif
#include <stdarg.h>
#include <stdint.h>
#include <inttypes.h>
#ifdef _MSC_VER
/* Visual Studio hasn't inttypes.h so it doesn't know uint32_t */
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef unsigned long long uint64_t;
typedef int mode_t;
#else /* _MSC_VER */
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#endif /* _MSC_VER */
@@ -191,8 +196,7 @@ enum ssh_global_requests_e {
SSH_GLOBAL_REQUEST_UNKNOWN=0,
SSH_GLOBAL_REQUEST_TCPIP_FORWARD,
SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD,
SSH_GLOBAL_REQUEST_KEEPALIVE,
SSH_GLOBAL_REQUEST_NO_MORE_SESSIONS
SSH_GLOBAL_REQUEST_KEEPALIVE
};
enum ssh_publickey_state_e {
@@ -273,12 +277,12 @@ enum ssh_error_types_e {
/* some types for keys */
enum ssh_keytypes_e{
SSH_KEYTYPE_UNKNOWN=0,
SSH_KEYTYPE_DSS=1, /* deprecated */
SSH_KEYTYPE_DSS=1,
SSH_KEYTYPE_RSA,
SSH_KEYTYPE_RSA1,
SSH_KEYTYPE_ECDSA, /* deprecated */
SSH_KEYTYPE_ED25519,
SSH_KEYTYPE_DSS_CERT01, /* deprecated */
SSH_KEYTYPE_DSS_CERT01,
SSH_KEYTYPE_RSA_CERT01,
SSH_KEYTYPE_ECDSA_P256,
SSH_KEYTYPE_ECDSA_P384,
@@ -295,8 +299,7 @@ enum ssh_keytypes_e{
enum ssh_keycmp_e {
SSH_KEY_CMP_PUBLIC = 0,
SSH_KEY_CMP_PRIVATE = 1,
SSH_KEY_CMP_CERTIFICATE = 2,
SSH_KEY_CMP_PRIVATE
};
#define SSH_ADDRSTRLEN 46
@@ -325,16 +328,16 @@ enum {
/** No logging at all
*/
SSH_LOG_NOLOG=0,
/** Only unrecoverable errors
/** Only warnings
*/
SSH_LOG_WARNING,
/** Information for the users
/** High level protocol information
*/
SSH_LOG_PROTOCOL,
/** Debug information, to see what is going on
/** Lower level protocol infomations, packet level
*/
SSH_LOG_PACKET,
/** Trace information and recoverable error messages
/** Every function path
*/
SSH_LOG_FUNCTIONS
};
@@ -350,7 +353,7 @@ enum {
/** No logging at all */
#define SSH_LOG_NONE 0
/** Show only fatal warnings */
/** Show only warnings */
#define SSH_LOG_WARN 1
/** Get some information what's going on */
#define SSH_LOG_INFO 2
@@ -361,64 +364,50 @@ enum {
/** @} */
enum ssh_control_master_options_e {
SSH_CONTROL_MASTER_NO,
SSH_CONTROL_MASTER_AUTO,
SSH_CONTROL_MASTER_YES,
SSH_CONTROL_MASTER_ASK,
SSH_CONTROL_MASTER_AUTOASK
};
enum ssh_options_e {
SSH_OPTIONS_HOST,
SSH_OPTIONS_PORT,
SSH_OPTIONS_PORT_STR,
SSH_OPTIONS_FD,
SSH_OPTIONS_USER,
SSH_OPTIONS_SSH_DIR,
SSH_OPTIONS_IDENTITY,
SSH_OPTIONS_ADD_IDENTITY,
SSH_OPTIONS_KNOWNHOSTS,
SSH_OPTIONS_TIMEOUT,
SSH_OPTIONS_TIMEOUT_USEC,
SSH_OPTIONS_SSH1,
SSH_OPTIONS_SSH2,
SSH_OPTIONS_LOG_VERBOSITY,
SSH_OPTIONS_LOG_VERBOSITY_STR,
SSH_OPTIONS_CIPHERS_C_S,
SSH_OPTIONS_CIPHERS_S_C,
SSH_OPTIONS_COMPRESSION_C_S,
SSH_OPTIONS_COMPRESSION_S_C,
SSH_OPTIONS_PROXYCOMMAND,
SSH_OPTIONS_BINDADDR,
SSH_OPTIONS_STRICTHOSTKEYCHECK,
SSH_OPTIONS_COMPRESSION,
SSH_OPTIONS_COMPRESSION_LEVEL,
SSH_OPTIONS_KEY_EXCHANGE,
SSH_OPTIONS_HOSTKEYS,
SSH_OPTIONS_GSSAPI_SERVER_IDENTITY,
SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY,
SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS,
SSH_OPTIONS_HMAC_C_S,
SSH_OPTIONS_HMAC_S_C,
SSH_OPTIONS_PASSWORD_AUTH,
SSH_OPTIONS_PUBKEY_AUTH,
SSH_OPTIONS_KBDINT_AUTH,
SSH_OPTIONS_GSSAPI_AUTH,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
SSH_OPTIONS_NODELAY,
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
SSH_OPTIONS_PROCESS_CONFIG,
SSH_OPTIONS_REKEY_DATA,
SSH_OPTIONS_REKEY_TIME,
SSH_OPTIONS_RSA_MIN_SIZE,
SSH_OPTIONS_IDENTITY_AGENT,
SSH_OPTIONS_IDENTITIES_ONLY,
SSH_OPTIONS_CONTROL_MASTER,
SSH_OPTIONS_CONTROL_PATH,
SSH_OPTIONS_CERTIFICATE,
SSH_OPTIONS_PROXYJUMP,
SSH_OPTIONS_PROXYJUMP_CB_LIST_APPEND,
SSH_OPTIONS_HOST,
SSH_OPTIONS_PORT,
SSH_OPTIONS_PORT_STR,
SSH_OPTIONS_FD,
SSH_OPTIONS_USER,
SSH_OPTIONS_SSH_DIR,
SSH_OPTIONS_IDENTITY,
SSH_OPTIONS_ADD_IDENTITY,
SSH_OPTIONS_KNOWNHOSTS,
SSH_OPTIONS_TIMEOUT,
SSH_OPTIONS_TIMEOUT_USEC,
SSH_OPTIONS_SSH1,
SSH_OPTIONS_SSH2,
SSH_OPTIONS_LOG_VERBOSITY,
SSH_OPTIONS_LOG_VERBOSITY_STR,
SSH_OPTIONS_CIPHERS_C_S,
SSH_OPTIONS_CIPHERS_S_C,
SSH_OPTIONS_COMPRESSION_C_S,
SSH_OPTIONS_COMPRESSION_S_C,
SSH_OPTIONS_PROXYCOMMAND,
SSH_OPTIONS_BINDADDR,
SSH_OPTIONS_STRICTHOSTKEYCHECK,
SSH_OPTIONS_COMPRESSION,
SSH_OPTIONS_COMPRESSION_LEVEL,
SSH_OPTIONS_KEY_EXCHANGE,
SSH_OPTIONS_HOSTKEYS,
SSH_OPTIONS_GSSAPI_SERVER_IDENTITY,
SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY,
SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS,
SSH_OPTIONS_HMAC_C_S,
SSH_OPTIONS_HMAC_S_C,
SSH_OPTIONS_PASSWORD_AUTH,
SSH_OPTIONS_PUBKEY_AUTH,
SSH_OPTIONS_KBDINT_AUTH,
SSH_OPTIONS_GSSAPI_AUTH,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
SSH_OPTIONS_NODELAY,
SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
SSH_OPTIONS_PROCESS_CONFIG,
SSH_OPTIONS_REKEY_DATA,
SSH_OPTIONS_REKEY_TIME,
SSH_OPTIONS_RSA_MIN_SIZE,
SSH_OPTIONS_IDENTITY_AGENT,
};
enum {
@@ -456,19 +445,8 @@ LIBSSH_API int ssh_blocking_flush(ssh_session session, int timeout);
LIBSSH_API ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms);
LIBSSH_API int ssh_channel_change_pty_size(ssh_channel channel,int cols,int rows);
LIBSSH_API int ssh_channel_close(ssh_channel channel);
#define SSH_CHANNEL_FREE(x) \
do { \
if ((x) != NULL) { \
ssh_channel_free(x); \
(x) = NULL; \
} \
} while (0)
LIBSSH_API void ssh_channel_free(ssh_channel channel);
LIBSSH_API int ssh_channel_get_exit_state(ssh_channel channel,
uint32_t *pexit_code,
char **pexit_signal,
int *pcore_dumped);
SSH_DEPRECATED LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
LIBSSH_API ssh_session ssh_channel_get_session(ssh_channel channel);
LIBSSH_API int ssh_channel_is_closed(ssh_channel channel);
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
@@ -492,8 +470,6 @@ LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd);
LIBSSH_API int ssh_channel_request_pty(ssh_channel channel);
LIBSSH_API int ssh_channel_request_pty_size(ssh_channel channel, const char *term,
int cols, int rows);
LIBSSH_API int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *term,
int cols, int rows, const unsigned char* modes, size_t modes_len);
LIBSSH_API int ssh_channel_request_shell(ssh_channel channel);
LIBSSH_API int ssh_channel_request_send_signal(ssh_channel channel, const char *signum);
LIBSSH_API int ssh_channel_request_send_break(ssh_channel channel, uint32_t length);
@@ -557,7 +533,6 @@ LIBSSH_API socket_t ssh_get_fd(ssh_session session);
LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len);
LIBSSH_API char *ssh_get_issue_banner(ssh_session session);
LIBSSH_API int ssh_get_openssh_version(ssh_session session);
LIBSSH_API int ssh_request_no_more_sessions(ssh_session session);
LIBSSH_API int ssh_get_server_publickey(ssh_session session, ssh_key *key);
@@ -701,12 +676,6 @@ typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
/** @} */
enum ssh_file_format_e {
SSH_FILE_FORMAT_DEFAULT = 0,
SSH_FILE_FORMAT_OPENSSH,
SSH_FILE_FORMAT_PEM,
};
LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
@@ -733,13 +702,6 @@ LIBSSH_API int ssh_pki_export_privkey_base64(const ssh_key privkey,
ssh_auth_callback auth_fn,
void *auth_data,
char **b64_key);
LIBSSH_API int
ssh_pki_export_privkey_base64_format(const ssh_key privkey,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
char **b64_key,
enum ssh_file_format_e format);
LIBSSH_API int ssh_pki_import_privkey_file(const char *filename,
const char *passphrase,
ssh_auth_callback auth_fn,
@@ -750,13 +712,6 @@ LIBSSH_API int ssh_pki_export_privkey_file(const ssh_key privkey,
ssh_auth_callback auth_fn,
void *auth_data,
const char *filename);
LIBSSH_API int
ssh_pki_export_privkey_file_format(const ssh_key privkey,
const char *passphrase,
ssh_auth_callback auth_fn,
void *auth_data,
const char *filename,
enum ssh_file_format_e format);
LIBSSH_API int ssh_pki_copy_cert_to_privkey(const ssh_key cert_key,
ssh_key privkey);
@@ -812,8 +767,10 @@ LIBSSH_API int ssh_userauth_try_publickey(ssh_session session,
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
const char *username,
const ssh_key privkey);
#ifndef _WIN32
LIBSSH_API int ssh_userauth_agent(ssh_session session,
const char *username);
#endif
LIBSSH_API int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
char** value);
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,

View File

@@ -498,22 +498,8 @@ public:
return_throwable;
}
/*
* @deprecated Please use getExitState()
*/
int getExitStatus() {
uint32_t exit_status = (uint32_t)-1;
ssh_channel_get_exit_state(channel, &exit_status, NULL, NULL);
return exit_status;
}
void_throwable getExitState(uint32_t & pexit_code,
char **pexit_signal,
int & pcore_dumped) {
ssh_throw(ssh_channel_get_exit_state(channel,
&pexit_code,
pexit_signal,
&pcore_dumped));
return_throwable;
int getExitStatus(){
return ssh_channel_get_exit_status(channel);
}
Session &getSession(){
return *session;
@@ -601,12 +587,9 @@ public:
ssh_throw(err);
return_throwable;
}
void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0,
const unsigned char* modes=NULL, size_t modes_len=0){
void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0){
int err;
if(term != NULL && cols != 0 && rows != 0 && modes != NULL)
err=ssh_channel_request_pty_size_modes(channel,term,cols,rows,modes,modes_len);
else if(term != NULL && cols != 0 && rows != 0)
if(term != NULL && cols != 0 && rows != 0)
err=ssh_channel_request_pty_size(channel,term,cols,rows);
else
err=ssh_channel_request_pty(channel);

View File

@@ -21,22 +21,6 @@
#ifndef MISC_H_
#define MISC_H_
#ifdef _WIN32
# ifdef _MSC_VER
# ifndef _SSIZE_T_DEFINED
# undef ssize_t
# include <BaseTsd.h>
typedef _W64 SSIZE_T ssize_t;
# define _SSIZE_T_DEFINED
# endif /* _SSIZE_T_DEFINED */
# endif /* _MSC_VER */
#else
#include <sys/types.h>
#include <stdbool.h>
#endif /* _WIN32 */
#ifdef __cplusplus
extern "C" {
#endif
@@ -66,12 +50,6 @@ struct ssh_iterator {
const void *data;
};
struct ssh_jump_info_struct {
char *hostname;
char *username;
int port;
};
struct ssh_timestamp {
long seconds;
long useconds;
@@ -107,14 +85,13 @@ const void *_ssh_list_pop_head(struct ssh_list *list);
#define ssh_list_pop_head(type, ssh_list)\
((type)_ssh_list_pop_head(ssh_list))
#define SSH_LIST_FREE(x) \
do { if ((x) != NULL) { ssh_list_free(x); (x) = NULL; } } while(0)
int ssh_make_milliseconds(unsigned long sec, unsigned long usec);
void ssh_timestamp_init(struct ssh_timestamp *ts);
int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout);
int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
int ssh_match_group(const char *group, const char *object);
void uint64_inc(unsigned char *counter);
void ssh_log_hexdump(const char *descr, const unsigned char *what, size_t len);
@@ -126,16 +103,6 @@ int ssh_newline_vis(const char *string, char *buf, size_t buf_len);
int ssh_tmpname(char *name);
char *ssh_strreplace(const char *src, const char *pattern, const char *repl);
ssize_t ssh_readn(int fd, void *buf, size_t nbytes);
ssize_t ssh_writen(int fd, const void *buf, size_t nbytes);
int ssh_check_hostname_syntax(const char *hostname);
int ssh_check_username_syntax(const char *username);
void ssh_proxyjumps_free(struct ssh_list *proxy_jump_list);
bool ssh_libssh_proxy_jumps(void);
#ifdef __cplusplus
}
#endif

View File

@@ -29,12 +29,9 @@ int ssh_config_parse_file(ssh_session session, const char *filename);
int ssh_config_parse_string(ssh_session session, const char *input);
int ssh_options_set_algo(ssh_session session,
enum ssh_kex_types_e algo,
const char *list,
char **place);
const char *list);
int ssh_options_apply(ssh_session session);
char *ssh_options_get_algo(ssh_session session, enum ssh_kex_types_e algo);
#ifdef __cplusplus
}
#endif

View File

@@ -58,7 +58,6 @@ extern "C" {
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
SSH_PACKET_CALLBACK(ssh_packet_debug_callback);
SSH_PACKET_CALLBACK(ssh_packet_dh_reply);
SSH_PACKET_CALLBACK(ssh_packet_newkeys);
SSH_PACKET_CALLBACK(ssh_packet_service_accept);
@@ -68,7 +67,6 @@ SSH_PACKET_CALLBACK(ssh_packet_ext_info);
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
#endif
int ssh_packet_send_newkeys(ssh_session session);
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum);
int ssh_packet_parse_type(ssh_session session);
//int packet_flush(ssh_session session, int enforce_blocking);

View File

@@ -33,7 +33,7 @@
#include <openssl/evp.h>
#endif
#include "libssh/crypto.h"
#ifdef HAVE_LIBCRYPTO
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
/* If using OpenSSL implementation, define the signature length which would be
* defined in libssh/ed25519.h otherwise */
#define ED25519_SIG_LEN 64
@@ -57,24 +57,40 @@ struct ssh_key_struct {
const char *type_c; /* Don't free it ! it is static */
int ecdsa_nid;
#if defined(HAVE_LIBGCRYPT)
gcry_sexp_t dsa;
gcry_sexp_t rsa;
gcry_sexp_t ecdsa;
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *pk;
mbedtls_pk_context *rsa;
mbedtls_ecdsa_context *ecdsa;
void *dsa;
#elif defined(HAVE_LIBCRYPTO)
#if OPENSSL_VERSION_NUMBER < 0x30000000L
DSA *dsa;
RSA *rsa;
#endif /* OPENSSL_VERSION_NUMBER */
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
* https://github.com/openssl/openssl/pull/16624
* Move into the #if above
*/
# if defined(HAVE_OPENSSL_ECC)
EC_KEY *ecdsa;
# else
void *ecdsa;
# endif /* HAVE_OPENSSL_EC_H */
/* This holds either ENGINE key for PKCS#11 support or just key in
* high-level format */
* high-level format required by OpenSSL 3.0 */
EVP_PKEY *key;
#endif /* HAVE_LIBGCRYPT */
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
uint8_t *ed25519_pubkey;
uint8_t *ed25519_privkey;
#endif /* HAVE_LIBGCRYPT */
#ifndef HAVE_LIBCRYPTO
#else
ed25519_pubkey *ed25519_pubkey;
ed25519_privkey *ed25519_privkey;
#endif /* HAVE_LIBCRYPTO */
#endif
ssh_string sk_application;
ssh_buffer cert;
void *cert;
enum ssh_keytypes_e cert_type;
};
@@ -83,15 +99,16 @@ struct ssh_signature_struct {
enum ssh_digest_e hash_type;
const char *type_c;
#if defined(HAVE_LIBGCRYPT)
gcry_sexp_t dsa_sig;
gcry_sexp_t rsa_sig;
gcry_sexp_t ecdsa_sig;
#elif defined(HAVE_LIBMBEDCRYPTO)
ssh_string rsa_sig;
struct mbedtls_ecdsa_sig ecdsa_sig;
#endif /* HAVE_LIBGCRYPT */
#ifndef HAVE_LIBCRYPTO
#if !defined(HAVE_LIBCRYPTO) || !defined(HAVE_OPENSSL_ED25519)
ed25519_signature *ed25519_sig;
#endif /* HAVE_LIBGCRYPT */
#endif
ssh_string raw_sig;
/* Security Key specific additions */
@@ -121,11 +138,12 @@ enum ssh_digest_e ssh_key_hash_from_name(const char *name);
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
#define is_cert_type(kt)\
((kt) == SSH_KEYTYPE_RSA_CERT01 ||\
(kt) == SSH_KEYTYPE_SK_ECDSA_CERT01 ||\
(kt) == SSH_KEYTYPE_SK_ED25519_CERT01 ||\
((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
(kt) <= SSH_KEYTYPE_ED25519_CERT01))
((kt) == SSH_KEYTYPE_DSS_CERT01 ||\
(kt) == SSH_KEYTYPE_RSA_CERT01 ||\
(kt) == SSH_KEYTYPE_SK_ECDSA_CERT01 ||\
(kt) == SSH_KEYTYPE_SK_ED25519_CERT01 ||\
((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
(kt) <= SSH_KEYTYPE_ED25519_CERT01))
/* SSH Signature Functions */
ssh_signature ssh_signature_new(void);
@@ -153,10 +171,6 @@ int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
int ssh_pki_import_cert_blob(const ssh_string cert_blob,
ssh_key *pkey);
/* SSH Private Key Functions */
int ssh_pki_export_privkey_blob(const ssh_key key,
ssh_string *pblob);
/* SSH Signing Functions */
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,

View File

@@ -38,6 +38,8 @@ int bcrypt_pbkdf(const char *pass,
#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
#define ECDSA_HEADER_BEGIN "-----BEGIN EC PRIVATE KEY-----"
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
@@ -63,6 +65,7 @@ enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
/* SSH Key Functions */
ssh_key pki_key_dup(const ssh_key key, int demote);
int pki_key_generate_rsa(ssh_key key, int parameter);
int pki_key_generate_dss(ssh_key key, int parameter);
int pki_key_generate_ecdsa(ssh_key key, int parameter);
int pki_key_generate_ed25519(ssh_key key);
@@ -88,13 +91,24 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type,
ssh_key *pkey);
/* SSH Public Key Functions */
int pki_pubkey_build_dss(ssh_key key,
ssh_string p,
ssh_string q,
ssh_string g,
ssh_string pubkey);
int pki_pubkey_build_rsa(ssh_key key,
ssh_string e,
ssh_string n);
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e);
ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type);
ssh_string pki_publickey_to_blob(const ssh_key key);
/* SSH Private Key Functions */
int pki_privkey_build_dss(ssh_key key,
ssh_string p,
ssh_string q,
ssh_string g,
ssh_string pubkey,
ssh_string privkey);
int pki_privkey_build_rsa(ssh_key key,
ssh_string n,
ssh_string e,
@@ -106,6 +120,7 @@ int pki_privkey_build_ecdsa(ssh_key key,
int nid,
ssh_string e,
ssh_string exp);
ssh_string pki_publickey_to_blob(const ssh_key key);
/* SSH Signature Functions */
ssh_signature pki_sign_data(const ssh_key privkey,
@@ -131,18 +146,15 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
const unsigned char *hash,
size_t hlen,
enum ssh_digest_e hash_type);
#ifndef HAVE_LIBCRYPTO
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
#endif /* HAVE_LIBCRYPTO */
int pki_ed25519_key_cmp(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
int pki_ed25519_key_dup(ssh_key new_key, const ssh_key key);
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
int pki_ed25519_private_key_to_blob(ssh_buffer buffer, const ssh_key privkey);
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig);
int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob);
int pki_privkey_build_ed25519(ssh_key key,

View File

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

View File

@@ -47,10 +47,6 @@
# endif
#endif /* !defined(HAVE_STRTOULL) */
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -166,20 +162,6 @@ int ssh_gettimeofday(struct timeval *__p, void *__t);
#define _XCLOSESOCKET closesocket
# ifdef HAVE_IO_H
# include <io.h>
# undef open
# define open _open
# undef close
# define close _close
# undef read
# define read _read
# undef write
# define write _write
# undef unlink
# define unlink _unlink
# endif /* HAVE_IO_H */
#else /* _WIN32 */
#include <unistd.h>
@@ -274,10 +256,6 @@ void ssh_log_common(struct ssh_common_struct *common,
const char *function,
const char *format, ...) PRINTF_ATTRIBUTE(4, 5);
void _ssh_remove_legacy_log_cb(void);
/* log.c */
void _ssh_reset_log_cb(void);
/* ERROR HANDLING */
@@ -312,7 +290,6 @@ int ssh_auth_reply_success(ssh_session session, int partial);
/* client.c */
int ssh_send_banner(ssh_session session, int is_server);
void ssh_session_socket_close(ssh_session session);
/* connect.c */
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
@@ -330,12 +307,6 @@ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen);
int match_pattern_list(const char *string, const char *pattern,
size_t len, int dolower);
int match_hostname(const char *host, const char *pattern, unsigned int len);
#ifndef _WIN32
int match_cidr_address_list(const char *address,
const char *addrlist,
int sa_family);
#endif
int match_group(const char *group, const char *object);
/* connector.c */
int ssh_connector_set_event(ssh_connector connector, ssh_event event);
@@ -384,7 +355,6 @@ void explicit_bzero(void *s, size_t n);
*/
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
#ifndef __VA_NARG__
/**
* Get the argument count of variadic arguments
*/
@@ -416,7 +386,6 @@ void explicit_bzero(void *s, size_t n);
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#endif
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
@@ -469,10 +438,6 @@ bool is_ssh_initialized(void);
#define SSH_ERRNO_MSG_MAX 1024
char *ssh_strerror(int err_num, char *buf, size_t buflen);
/** 55 defined options (5 bytes each) + terminator */
#define SSH_TTY_MODES_MAX_BUFSIZE (55 * 5 + 1)
int encode_current_tty_opts(unsigned char *buf, size_t buflen);
#ifdef __cplusplus
}
#endif

View File

@@ -36,29 +36,28 @@ extern "C" {
#endif
enum ssh_bind_options_e {
SSH_BIND_OPTIONS_BINDADDR,
SSH_BIND_OPTIONS_BINDPORT,
SSH_BIND_OPTIONS_BINDPORT_STR,
SSH_BIND_OPTIONS_HOSTKEY,
SSH_BIND_OPTIONS_DSAKEY, /* deprecated */
SSH_BIND_OPTIONS_RSAKEY, /* deprecated */
SSH_BIND_OPTIONS_BANNER,
SSH_BIND_OPTIONS_LOG_VERBOSITY,
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
SSH_BIND_OPTIONS_ECDSAKEY, /* deprecated */
SSH_BIND_OPTIONS_IMPORT_KEY,
SSH_BIND_OPTIONS_KEY_EXCHANGE,
SSH_BIND_OPTIONS_CIPHERS_C_S,
SSH_BIND_OPTIONS_CIPHERS_S_C,
SSH_BIND_OPTIONS_HMAC_C_S,
SSH_BIND_OPTIONS_HMAC_S_C,
SSH_BIND_OPTIONS_CONFIG_DIR,
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES,
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS,
SSH_BIND_OPTIONS_PROCESS_CONFIG,
SSH_BIND_OPTIONS_MODULI,
SSH_BIND_OPTIONS_RSA_MIN_SIZE,
SSH_BIND_OPTIONS_IMPORT_KEY_STR,
SSH_BIND_OPTIONS_BINDADDR,
SSH_BIND_OPTIONS_BINDPORT,
SSH_BIND_OPTIONS_BINDPORT_STR,
SSH_BIND_OPTIONS_HOSTKEY,
SSH_BIND_OPTIONS_DSAKEY,
SSH_BIND_OPTIONS_RSAKEY,
SSH_BIND_OPTIONS_BANNER,
SSH_BIND_OPTIONS_LOG_VERBOSITY,
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
SSH_BIND_OPTIONS_ECDSAKEY,
SSH_BIND_OPTIONS_IMPORT_KEY,
SSH_BIND_OPTIONS_KEY_EXCHANGE,
SSH_BIND_OPTIONS_CIPHERS_C_S,
SSH_BIND_OPTIONS_CIPHERS_S_C,
SSH_BIND_OPTIONS_HMAC_C_S,
SSH_BIND_OPTIONS_HMAC_S_C,
SSH_BIND_OPTIONS_CONFIG_DIR,
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES,
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS,
SSH_BIND_OPTIONS_PROCESS_CONFIG,
SSH_BIND_OPTIONS_MODULI,
SSH_BIND_OPTIONS_RSA_MIN_SIZE,
};
typedef struct ssh_bind_struct* ssh_bind;
@@ -223,9 +222,6 @@ LIBSSH_API int ssh_server_init_kex(ssh_session session);
/**
* @brief Free a ssh servers bind.
*
* Note that this will also free options that have been set on the bind,
* including keys set with SSH_BIND_OPTIONS_IMPORT_KEY.
*
* @param ssh_bind_o The ssh server bind to free.
*/
LIBSSH_API void ssh_bind_free(ssh_bind ssh_bind_o);
@@ -296,7 +292,7 @@ LIBSSH_API const char *ssh_message_auth_user(ssh_message msg);
*
* @param[in] msg The message to get the password from.
*
* @return The password or NULL if an error occurred.
* @return The username or NULL if an error occurred.
*
* @see ssh_message_get()
* @see ssh_message_type()

View File

@@ -71,24 +71,15 @@ enum ssh_pending_call_e {
};
/* libssh calls may block an undefined amount of time */
#define SSH_SESSION_FLAG_BLOCKING 0x0001
#define SSH_SESSION_FLAG_BLOCKING 1
/* Client successfully authenticated */
#define SSH_SESSION_FLAG_AUTHENTICATED 0x0002
/* Do not accept new session channels (no-more-sessions@openssh.com) */
#define SSH_SESSION_FLAG_NO_MORE_SESSIONS 0x0004
#define SSH_SESSION_FLAG_AUTHENTICATED 2
/* The KEXINIT message can be sent first by either of the parties so this flag
* indicates that the message was already sent to make sure it is sent and avoid
* sending it twice during key exchange to simplify the state machine. */
#define SSH_SESSION_FLAG_KEXINIT_SENT 0x0008
/* The current SSH2 session implements the "strict KEX" feature and should behave
* differently on SSH2_MSG_NEWKEYS. */
#define SSH_SESSION_FLAG_KEX_STRICT 0x0010
/* Unexpected packets have been sent while the session was still unencrypted */
#define SSH_SESSION_FLAG_KEX_TAINTED 0x0020
#define SSH_SESSION_FLAG_KEXINIT_SENT 4
/* codes to use with ssh_handle_packets*() */
/* Infinite timeout */
@@ -112,7 +103,6 @@ enum ssh_pending_call_e {
#define SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS 0x2
#define SSH_OPT_EXP_FLAG_PROXYCOMMAND 0x4
#define SSH_OPT_EXP_FLAG_IDENTITY 0x8
#define SSH_OPT_EXP_FLAG_CONTROL_PATH 0x10
/* extensions flags */
/* negotiation enabled */
@@ -140,7 +130,6 @@ struct ssh_session_struct {
uint32_t send_seq;
uint32_t recv_seq;
struct ssh_timestamp last_rekey_time;
bool proxy_root;
int connected;
/* !=0 when the user got a session handle */
@@ -213,6 +202,7 @@ struct ssh_session_struct {
/* server host keys */
struct {
ssh_key rsa_key;
ssh_key dsa_key;
ssh_key ecdsa_key;
ssh_key ed25519_key;
/* The type of host key wanted by client */
@@ -238,10 +228,6 @@ struct ssh_session_struct {
struct {
struct ssh_list *identity;
struct ssh_list *identity_non_exp;
struct ssh_list *certificate;
struct ssh_list *certificate_non_exp;
struct ssh_list *proxy_jumps;
struct ssh_list *proxy_jumps_user_cb;
char *username;
char *host;
char *bindaddr; /* bind the client to an ip addr */
@@ -251,6 +237,8 @@ struct ssh_session_struct {
char *wanted_methods[SSH_KEX_METHODS];
char *pubkey_accepted_types;
char *ProxyCommand;
char *custombanner;
char *moduli_file;
char *agent_socket;
unsigned long timeout; /* seconds */
unsigned long timeout_usec;
@@ -269,17 +257,7 @@ struct ssh_session_struct {
uint64_t rekey_data;
uint32_t rekey_time;
int rsa_min_size;
bool identities_only;
int control_master;
char *control_path;
} opts;
/* server options */
struct {
char *custombanner;
char *moduli_file;
} server_opts;
/* counters */
ssh_counter socket_counter;
ssh_counter raw_counter;

View File

@@ -77,8 +77,6 @@ typedef struct sftp_request_queue_struct* sftp_request_queue;
typedef struct sftp_session_struct* sftp_session;
typedef struct sftp_status_message_struct* sftp_status_message;
typedef struct sftp_statvfs_struct* sftp_statvfs_t;
typedef struct sftp_limits_struct* sftp_limits_t;
typedef struct sftp_aio_struct* sftp_aio;
struct sftp_session_struct {
ssh_session session;
@@ -92,7 +90,6 @@ struct sftp_session_struct {
void **handles;
sftp_ext ext;
sftp_packet read_packet;
sftp_limits_t limits;
};
struct sftp_packet_struct {
@@ -203,16 +200,6 @@ struct sftp_statvfs_struct {
uint64_t f_namemax; /** maximum filename length */
};
/**
* @brief SFTP limits structure.
*/
struct sftp_limits_struct {
uint64_t max_packet_length; /** maximum number of bytes in a single sftp packet */
uint64_t max_read_length; /** maximum length in a SSH_FXP_READ packet */
uint64_t max_write_length; /** maximum length in a SSH_FXP_WRITE packet */
uint64_t max_open_handles; /** maximum number of active handles allowed by server */
};
/**
* @brief Creates a new sftp session.
*
@@ -489,18 +476,13 @@ LIBSSH_API void sftp_file_set_blocking(sftp_file handle);
/**
* @brief Read from a file using an opened sftp file handle.
*
* This function caps the length a user is allowed to read from an sftp file.
*
* The value used for the cap is same as the value of the max_read_length
* field of the sftp_limits_t returned by sftp_limits().
*
* @param file The opened sftp file handle to be read from.
*
* @param buf Pointer to buffer to receive read data.
*
* @param count Size of the buffer in bytes.
*
* @return Number of bytes read, < 0 on error with ssh and sftp
* @return Number of bytes written, < 0 on error with ssh and sftp
* error set.
*
* @see sftp_get_error()
@@ -538,8 +520,7 @@ LIBSSH_API ssize_t sftp_read(sftp_file file, void *buf, size_t count);
* @see sftp_async_read()
* @see sftp_open()
*/
SSH_DEPRECATED LIBSSH_API int sftp_async_read_begin(sftp_file file,
uint32_t len);
LIBSSH_API int sftp_async_read_begin(sftp_file file, uint32_t len);
/**
* @brief Wait for an asynchronous read to complete and save the data.
@@ -564,19 +545,11 @@ SSH_DEPRECATED LIBSSH_API int sftp_async_read_begin(sftp_file file,
*
* @see sftp_async_read_begin()
*/
SSH_DEPRECATED LIBSSH_API int sftp_async_read(sftp_file file,
void *data,
uint32_t len,
uint32_t id);
LIBSSH_API int sftp_async_read(sftp_file file, void *data, uint32_t len, uint32_t id);
/**
* @brief Write to a file using an opened sftp file handle.
*
* This function caps the length a user is allowed to write to an sftp file.
*
* The value used for the cap is same as the value of the max_write_length
* field of the sftp_limits_t returned by sftp_limits().
*
* @param file Open sftp file handle to write to.
*
* @param buf Pointer to buffer to write data.
@@ -592,229 +565,6 @@ SSH_DEPRECATED LIBSSH_API int sftp_async_read(sftp_file file,
*/
LIBSSH_API ssize_t sftp_write(sftp_file file, const void *buf, size_t count);
/**
* @brief Deallocate memory corresponding to a sftp aio handle.
*
* This function deallocates memory corresponding to the aio handle returned
* by the sftp_aio_begin_*() functions. Users can use this function to free
* memory corresponding to an aio handle for an outstanding async i/o request
* on encountering some error.
*
* @param aio sftp aio handle corresponding to which memory has
* to be deallocated.
*
* @see sftp_aio_begin_read()
* @see sftp_aio_wait_read()
* @see sftp_aio_begin_write()
* @see sftp_aio_wait_write()
*/
LIBSSH_API void sftp_aio_free(sftp_aio aio);
#define SFTP_AIO_FREE(x) \
do { if(x != NULL) {sftp_aio_free(x); x = NULL;} } while(0)
/**
* @brief Start an asynchronous read from a file using an opened sftp
* file handle.
*
* Its goal is to avoid the slowdowns related to the request/response pattern
* of a synchronous read. To do so, you must call 2 functions :
*
* sftp_aio_begin_read() and sftp_aio_wait_read().
*
* - The first step is to call sftp_aio_begin_read(). This function sends a
* read request to the sftp server, dynamically allocates memory to store
* information about the sent request and provides the caller an sftp aio
* handle to that memory.
*
* - The second step is to call sftp_aio_wait_read() and pass it the address
* of a location storing the sftp aio handle provided by
* sftp_aio_begin_read().
*
* These two functions do not close the open sftp file handle passed to
* sftp_aio_begin_read() irrespective of whether they fail or not.
*
* It is the responsibility of the caller to ensure that the open sftp file
* handle passed to sftp_aio_begin_read() must not be closed before the
* corresponding call to sftp_aio_wait_read(). After sftp_aio_wait_read()
* returns, it is caller's decision whether to immediately close the file by
* calling sftp_close() or to keep it open and perform some more operations
* on it.
*
* This function caps the length a user is allowed to read from an sftp file,
* the value of len parameter after capping is returned on success.
*
* The value used for the cap is same as the value of the max_read_length
* field of the sftp_limits_t returned by sftp_limits().
*
* @param file The opened sftp file handle to be read from.
*
* @param len Number of bytes to read.
*
* @param aio Pointer to a location where the sftp aio handle
* (corresponding to the sent request) should be stored.
*
* @returns On success, the number of bytes the server is
* requested to read (value of len parameter after
* capping). On error, SSH_ERROR with sftp and ssh
* errors set.
*
* @warning When calling this function, the internal file offset is
* updated corresponding to the number of bytes requested
* to read.
*
* @warning A call to sftp_aio_begin_read() sends a request to
* the server. When the server answers, libssh allocates
* memory to store it until sftp_aio_wait_read() is called.
* Not calling sftp_aio_wait_read() will lead to memory
* leaks.
*
* @see sftp_aio_wait_read()
* @see sftp_aio_free()
* @see sftp_open()
* @see sftp_close()
* @see sftp_get_error()
* @see ssh_get_error()
*/
LIBSSH_API ssize_t sftp_aio_begin_read(sftp_file file,
size_t len,
sftp_aio *aio);
/**
* @brief Wait for an asynchronous read to complete and store the read data
* in the supplied buffer.
*
* A pointer to an sftp aio handle should be passed while calling
* this function. Except when the return value is SSH_AGAIN,
* this function releases the memory corresponding to the supplied
* aio handle and assigns NULL to that aio handle using the passed
* pointer to that handle.
*
* If the file is opened in non-blocking mode and the request hasn't been
* executed yet, this function returns SSH_AGAIN and must be called again
* using the same sftp aio handle.
*
* @param aio Pointer to the sftp aio handle returned by
* sftp_aio_begin_read().
*
* @param buf Pointer to the buffer in which read data will be stored.
*
* @param buf_size Size of the buffer in bytes. It should be bigger or
* equal to the length parameter of the
* sftp_aio_begin_read() call.
*
* @return Number of bytes read, 0 on EOF, SSH_ERROR if an error
* occurred, SSH_AGAIN if the file is opened in nonblocking
* mode and the request hasn't been executed yet.
*
* @warning A call to this function with an invalid sftp aio handle
* may never return.
*
* @see sftp_aio_begin_read()
* @see sftp_aio_free()
*/
LIBSSH_API ssize_t sftp_aio_wait_read(sftp_aio *aio,
void *buf,
size_t buf_size);
/**
* @brief Start an asynchronous write to a file using an opened sftp
* file handle.
*
* Its goal is to avoid the slowdowns related to the request/response pattern
* of a synchronous write. To do so, you must call 2 functions :
*
* sftp_aio_begin_write() and sftp_aio_wait_write().
*
* - The first step is to call sftp_aio_begin_write(). This function sends a
* write request to the sftp server, dynamically allocates memory to store
* information about the sent request and provides the caller an sftp aio
* handle to that memory.
*
* - The second step is to call sftp_aio_wait_write() and pass it the address
* of a location storing the sftp aio handle provided by
* sftp_aio_begin_write().
*
* These two functions do not close the open sftp file handle passed to
* sftp_aio_begin_write() irrespective of whether they fail or not.
*
* It is the responsibility of the caller to ensure that the open sftp file
* handle passed to sftp_aio_begin_write() must not be closed before the
* corresponding call to sftp_aio_wait_write(). After sftp_aio_wait_write()
* returns, it is caller's decision whether to immediately close the file by
* calling sftp_close() or to keep it open and perform some more operations
* on it.
*
* This function caps the length a user is allowed to write to an sftp file,
* the value of len parameter after capping is returned on success.
*
* The value used for the cap is same as the value of the max_write_length
* field of the sftp_limits_t returned by sftp_limits().
*
* @param file The opened sftp file handle to write to.
*
* @param buf Pointer to the buffer containing data to write.
*
* @param len Number of bytes to write.
*
* @param aio Pointer to a location where the sftp aio handle
* (corresponding to the sent request) should be stored.
*
* @returns On success, the number of bytes the server is
* requested to write (value of len parameter after
* capping). On error, SSH_ERROR with sftp and ssh errors
* set.
*
* @warning When calling this function, the internal file offset is
* updated corresponding to the number of bytes requested
* to write.
*
* @warning A call to sftp_aio_begin_write() sends a request to
* the server. When the server answers, libssh allocates
* memory to store it until sftp_aio_wait_write() is
* called. Not calling sftp_aio_wait_write() will lead to
* memory leaks.
*
* @see sftp_aio_wait_write()
* @see sftp_aio_free()
* @see sftp_open()
* @see sftp_close()
* @see sftp_get_error()
* @see ssh_get_error()
*/
LIBSSH_API ssize_t sftp_aio_begin_write(sftp_file file,
const void *buf,
size_t len,
sftp_aio *aio);
/**
* @brief Wait for an asynchronous write to complete.
*
* A pointer to an sftp aio handle should be passed while calling
* this function. Except when the return value is SSH_AGAIN,
* this function releases the memory corresponding to the supplied
* aio handle and assigns NULL to that aio handle using the passed
* pointer to that handle.
*
* If the file is opened in non-blocking mode and the request hasn't
* been executed yet, this function returns SSH_AGAIN and must be called
* again using the same sftp aio handle.
*
* @param aio Pointer to the sftp aio handle returned by
* sftp_aio_begin_write().
*
* @return Number of bytes written on success, SSH_ERROR
* if an error occurred, SSH_AGAIN if the file is
* opened in nonblocking mode and the request hasn't
* been executed yet.
*
* @warning A call to this function with an invalid sftp aio handle
* may never return.
*
* @see sftp_aio_begin_write()
* @see sftp_aio_free()
*/
LIBSSH_API ssize_t sftp_aio_wait_write(sftp_aio *aio);
/**
* @brief Seek to a specific location in a file.
*
@@ -855,7 +605,8 @@ LIBSSH_API unsigned long sftp_tell(sftp_file file);
* @param file Open sftp file handle.
*
* @return The offset of the current byte relative to the beginning
* of the file associated with the file descriptor.
* of the file associated with the file descriptor. < 0 on
* error.
*/
LIBSSH_API uint64_t sftp_tell64(sftp_file file);
@@ -948,29 +699,6 @@ LIBSSH_API int sftp_rename(sftp_session sftp, const char *original, const char
*/
LIBSSH_API int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr);
/**
* @brief This request is like setstat (excluding mode and size) but sets file
* attributes on symlinks themselves.
*
* Note, that this function can only set time values using 32 bit values due to
* the restrictions in the SFTP protocol version 3 implemented by libssh.
* The support for 64 bit time values was introduced in SFTP version 5, which is
* not implemented by libssh nor any major SFTP servers.
*
* @param sftp The sftp session handle.
*
* @param file The symbolic link which attributes should be changed.
*
* @param attr The file attributes structure with the attributes set
* which should be changed.
*
* @return 0 on success, < 0 on error with ssh and sftp error set.
*
* @see sftp_get_error()
*/
LIBSSH_API int
sftp_lsetstat(sftp_session sftp, const char *file, sftp_attributes attr);
/**
* @brief Change the file owner and group
*
@@ -1051,22 +779,6 @@ LIBSSH_API int sftp_symlink(sftp_session sftp, const char *target, const char *d
*/
LIBSSH_API char *sftp_readlink(sftp_session sftp, const char *path);
/**
* @brief Create a hard link.
*
* @param sftp The sftp session handle.
*
* @param oldpath Specifies the pathname of the file for
* which the new hardlink is to be created.
*
* @param newpath Specifies the pathname of the hardlink to be created.
*
* @return 0 on success, -1 on error with ssh and sftp error set.
*
* @see sftp_get_error()
*/
LIBSSH_API int sftp_hardlink(sftp_session sftp, const char *oldpath, const char *newpath);
/**
* @brief Get information about a mounted file system.
*
@@ -1114,24 +826,6 @@ LIBSSH_API void sftp_statvfs_free(sftp_statvfs_t statvfs_o);
*/
LIBSSH_API int sftp_fsync(sftp_file file);
/**
* @brief Get information about the various limits the server might impose.
*
* @param sftp The sftp session handle.
*
* @return A limits structure or NULL on error.
*
* @see sftp_get_error()
*/
LIBSSH_API sftp_limits_t sftp_limits(sftp_session sftp);
/**
* @brief Free the memory of an allocated limits.
*
* @param limits The limits to free.
*/
LIBSSH_API void sftp_limits_free(sftp_limits_t limits);
/**
* @brief Canonicalize a sftp path.
*
@@ -1154,40 +848,6 @@ LIBSSH_API char *sftp_canonicalize_path(sftp_session sftp, const char *path);
*/
LIBSSH_API int sftp_server_version(sftp_session sftp);
/**
* @brief Canonicalize path using expand-path@openssh.com extension
*
* @param sftp The sftp session handle.
*
* @param path The path to be canonicalized.
*
* @return A pointer to the newly allocated canonicalized path,
* NULL on error. The caller needs to free the memory
* using ssh_string_free_char().
*/
LIBSSH_API char *sftp_expand_path(sftp_session sftp, const char *path);
/**
* @brief Get the specified user's home directory
*
* This calls the "home-directory" extension. You should check if the extension
* is supported using:
*
* @code
* int supported = sftp_extension_supported(sftp, "home-directory", "1");
* @endcode
*
* @param sftp The sftp session handle.
*
* @param username username of the user whose home directory is requested.
*
* @return On success, a newly allocated string containing the
* absolute real-path of the home directory of the user.
* NULL on error. The caller needs to free the memory
* using ssh_string_free_char().
*/
LIBSSH_API char *sftp_home_directory(sftp_session sftp, const char *username);
#ifdef WITH_SERVER
/**
* @brief Create a new sftp server session.
@@ -1207,7 +867,7 @@ LIBSSH_API sftp_session sftp_server_new(ssh_session session, ssh_channel chan);
*
* @return 0 on success, < 0 on error.
*/
SSH_DEPRECATED LIBSSH_API int sftp_server_init(sftp_session sftp);
LIBSSH_API int sftp_server_init(sftp_session sftp);
/**
* @brief Close and deallocate a sftp server session.

View File

@@ -32,49 +32,6 @@ int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr);
sftp_attributes sftp_parse_attr(sftp_session session,
ssh_buffer buf,
int expectname);
/**
* @brief Reply to the SSH_FXP_INIT message with the SSH_FXP_VERSION message
*
* @param client_msg The pointer to client message.
*
* @return 0 on success, < 0 on error with ssh and sftp error set.
*
* @see sftp_get_error()
*/
int sftp_reply_version(sftp_client_message client_msg);
/**
* @brief Decode the data from channel buffer into sftp read_packet.
*
* @param sftp The sftp session handle.
*
* @param data The pointer to the data buffer of channel.
* @param len The data buffer length
*
* @return Length of data decoded.
*/
int sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len);
void sftp_set_error(sftp_session sftp, int errnum);
void sftp_message_free(sftp_message msg);
int sftp_read_and_dispatch(sftp_session sftp);
sftp_message sftp_dequeue(sftp_session sftp, uint32_t id);
/*
* Assigns a new SFTP ID for new requests and assures there is no collision
* between them.
* Returns a new ID ready to use in a request
*/
static inline uint32_t sftp_get_new_id(sftp_session session)
{
return ++session->id_counter;
}
sftp_status_message parse_status_msg(sftp_message msg);
void status_msg_free(sftp_status_message status);
#ifdef __cplusplus
}

View File

@@ -1,77 +0,0 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2022 Zeyu Sheng <shengzeyu19_98@163.com>
* Copyright (c) 2023 Red Hat, Inc.
*
* Authors: 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
*/
#ifndef SFTP_SERVER_H
#define SFTP_SERVER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "libssh/libssh.h"
#include "libssh/sftp.h"
/**
* @defgroup libssh_sftp_server The libssh SFTP server API
*
* @brief SFTP server handling functions
*
* TODO
*
* @{
*/
#define SSH_SFTP_CALLBACK(name) \
static int name(sftp_client_message message)
typedef int (*sftp_server_message_callback)(sftp_client_message message);
struct sftp_message_handler
{
const char *name;
const char *extended_name;
uint8_t type;
sftp_server_message_callback cb;
};
LIBSSH_API int sftp_channel_default_subsystem_request(ssh_session session,
ssh_channel channel,
const char *subsystem,
void *userdata);
LIBSSH_API int sftp_channel_default_data_callback(ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* SFTP_SERVER_H */

View File

@@ -37,11 +37,10 @@ void ssh_socket_set_fd(ssh_socket s, socket_t fd);
socket_t ssh_socket_get_fd(ssh_socket s);
void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p);
int ssh_socket_unix(ssh_socket s, const char *path);
#if WITH_EXEC
void ssh_execute_command(const char *command, socket_t in, socket_t out);
#ifndef _WIN32
int ssh_socket_connect_proxycommand(ssh_socket s, const char *command);
#endif
int ssh_socket_connect_proxyjump(ssh_socket s);
void ssh_socket_close(ssh_socket s);
int ssh_socket_write(ssh_socket s,const void *buffer, uint32_t len);
int ssh_socket_is_open(ssh_socket s);

View File

@@ -49,11 +49,6 @@ char *ssh_remove_duplicates(const char *list);
char *ssh_append_without_duplicates(const char *list,
const char *appended_list);
char *ssh_prefix_without_duplicates(const char *list,
const char *prefixed_list);
char *ssh_remove_all_matching(const char *list,
const char *remove_list);
#ifdef __cplusplus
}
#endif

View File

@@ -72,33 +72,33 @@ struct ssh_crypto_struct;
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void);
void md5_ctx_free(MD5CTX);
int md5_update(MD5CTX c, const void *data, size_t len);
int md5_final(unsigned char *md, MD5CTX c);
void md5_update(MD5CTX c, const void *data, size_t len);
void md5_final(unsigned char *md,MD5CTX c);
SHACTX sha1_init(void);
void sha1_ctx_free(SHACTX);
int sha1_update(SHACTX c, const void *data, size_t len);
int sha1_final(unsigned char *md,SHACTX c);
int sha1(const unsigned char *digest,size_t len, unsigned char *hash);
void sha1_update(SHACTX c, const void *data, size_t len);
void sha1_final(unsigned char *md,SHACTX c);
void sha1(const unsigned char *digest,size_t len,unsigned char *hash);
SHA256CTX sha256_init(void);
void sha256_ctx_free(SHA256CTX);
int sha256_update(SHA256CTX c, const void *data, size_t len);
int sha256_final(unsigned char *md,SHA256CTX c);
int sha256(const unsigned char *digest, size_t len, unsigned char *hash);
void sha256_update(SHA256CTX c, const void *data, size_t len);
void sha256_final(unsigned char *md,SHA256CTX c);
void sha256(const unsigned char *digest, size_t len, unsigned char *hash);
SHA384CTX sha384_init(void);
void sha384_ctx_free(SHA384CTX);
int sha384_update(SHA384CTX c, const void *data, size_t len);
int sha384_final(unsigned char *md,SHA384CTX c);
int sha384(const unsigned char *digest, size_t len, unsigned char *hash);
void sha384_update(SHA384CTX c, const void *data, size_t len);
void sha384_final(unsigned char *md,SHA384CTX c);
void sha384(const unsigned char *digest, size_t len, unsigned char *hash);
SHA512CTX sha512_init(void);
void sha512_ctx_free(SHA512CTX);
int sha512_update(SHA512CTX c, const void *data, size_t len);
int sha512_final(unsigned char *md,SHA512CTX c);
int sha512(const unsigned char *digest, size_t len, unsigned char *hash);
void sha512_update(SHA512CTX c, const void *data, size_t len);
void sha512_final(unsigned char *md,SHA512CTX c);
void sha512(const unsigned char *digest, size_t len, unsigned char *hash);
void evp(int nid, unsigned char *digest, size_t len, unsigned char *hash, unsigned int *hlen);
EVPCTX evp_init(int nid);
void evp_update(EVPCTX ctx, const void *data, size_t len);
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
HMACCTX hmac_init(const void *key,size_t len, enum ssh_hmac_e type);
int hmac_update(HMACCTX c, const void *data, size_t len);

View File

@@ -1 +1 @@
4.10.3
4.9.5

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,20 +9,50 @@ set(LIBSSH_LINK_LIBRARIES
${LIBSSH_REQUIRED_LIBRARIES}
)
if (TARGET OpenSSL::Crypto)
list(APPEND LIBSSH_LINK_LIBRARIES OpenSSL::Crypto)
endif ()
if (OPENSSL_CRYPTO_LIBRARIES)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
)
if (TARGET MbedTLS::mbedcrypto)
list(APPEND LIBSSH_LINK_LIBRARIES MbedTLS::mbedcrypto)
endif ()
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARIES}
)
endif (OPENSSL_CRYPTO_LIBRARIES)
if (TARGET libgcrypt::libgcrypt)
list(APPEND LIBSSH_LINK_LIBRARIES ${GCRYPT_LIBRARIES})
endif ()
if (MBEDTLS_CRYPTO_LIBRARY)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${MBEDTLS_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${MBEDTLS_CRYPTO_LIBRARY}
)
endif (MBEDTLS_CRYPTO_LIBRARY)
if (GCRYPT_LIBRARIES)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${GCRYPT_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${GCRYPT_LIBRARIES})
endif()
if (WITH_ZLIB)
list(APPEND LIBSSH_LINK_LIBRARIES ZLIB::ZLIB)
set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
${ZLIB_LIBRARY}
)
endif (WITH_ZLIB)
if (WITH_GSSAPI AND GSSAPI_FOUND)
@@ -56,12 +86,11 @@ if (MINGW AND Threads_FOUND)
)
endif()
# The ws2_32 needs to be last for mingw to build
# This needs to be last for mingw to build
# https://gitlab.com/libssh/libssh-mirror/-/issues/84
if (WIN32)
set(LIBSSH_LINK_LIBRARIES
${LIBSSH_LINK_LIBRARIES}
iphlpapi
ws2_32
)
endif (WIN32)
@@ -91,7 +120,6 @@ set(libssh_SRCS
ecdh.c
error.c
getpass.c
gzip.c
init.c
kdf.c
kex.c
@@ -115,7 +143,6 @@ set(libssh_SRCS
socket.c
string.c
threads.c
ttyopts.c
wrapper.c
external/bcrypt_pbkdf.c
external/blowfish.c
@@ -211,22 +238,33 @@ else (WITH_GCRYPT)
libcrypto.c
dh_crypto.c
)
if (NOT HAVE_OPENSSL_EVP_CHACHA20)
if (NOT HAVE_OPENSSL_ED25519)
set(libssh_SRCS
${libssh_SRCS}
pki_ed25519.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
external/sc25519.c
)
endif (NOT HAVE_OPENSSL_ED25519)
if (NOT (HAVE_OPENSSL_EVP_CHACHA20 AND HAVE_OPENSSL_EVP_POLY1305))
set(libssh_SRCS
${libssh_SRCS}
external/chacha.c
external/poly1305.c
chachapoly.c
)
endif (NOT HAVE_OPENSSL_EVP_CHACHA20)
endif (NOT (HAVE_OPENSSL_EVP_CHACHA20 AND HAVE_OPENSSL_EVP_POLY1305))
if(OPENSSL_VERSION VERSION_LESS "1.1.0")
set(libssh_SRCS ${libssh_SRCS} libcrypto-compat.c)
endif()
endif (WITH_GCRYPT)
if (WITH_SFTP)
set(libssh_SRCS
${libssh_SRCS}
sftp.c
sftp_common.c
sftp_aio.c
)
if (WITH_SERVER)
@@ -253,6 +291,13 @@ if (WITH_GEX)
)
endif (WITH_GEX)
if (WITH_ZLIB)
set(libssh_SRCS
${libssh_SRCS}
gzip.c
)
endif(WITH_ZLIB)
if (WITH_GSSAPI AND GSSAPI_FOUND)
set(libssh_SRCS
${libssh_SRCS}
@@ -261,7 +306,7 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
endif (WITH_GSSAPI AND GSSAPI_FOUND)
if (NOT WITH_NACL)
if (NOT HAVE_LIBCRYPTO)
if (NOT HAVE_LIBCRYPTO OR NOT HAVE_OPENSSL_ED25519)
set(libssh_SRCS
${libssh_SRCS}
external/curve25519_ref.c
@@ -312,7 +357,6 @@ endif ()
target_include_directories(ssh
PUBLIC
$<BUILD_INTERFACE:${libssh_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${libssh_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${LIBSSH_PRIVATE_INCLUDE_DIRS})
@@ -336,8 +380,6 @@ endif (WITH_SYMBOL_VERSIONING AND HAVE_LD_VERSION_SCRIPT)
set_target_properties(ssh
PROPERTIES
C_STANDARD
99
VERSION
${LIBRARY_VERSION}
SOVERSION
@@ -354,10 +396,6 @@ if (MINGW)
target_link_libraries(ssh PRIVATE "-Wl,--enable-stdcall-fixup")
target_compile_definitions(ssh PRIVATE "_POSIX_SOURCE")
endif ()
if (WITH_COVERAGE)
include(CodeCoverage)
append_coverage_compiler_flags_to_target(ssh)
endif (WITH_COVERAGE)
install(TARGETS ssh
@@ -382,7 +420,6 @@ if (BUILD_STATIC_LIB)
target_include_directories(ssh-static
PUBLIC
$<BUILD_INTERFACE:${libssh_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${libssh_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${LIBSSH_PRIVATE_INCLUDE_DIRS})
target_link_libraries(ssh-static
@@ -410,9 +447,6 @@ if (BUILD_STATIC_LIB)
if (WIN32)
target_compile_definitions(ssh-static PUBLIC "LIBSSH_STATIC")
endif (WIN32)
if (WITH_COVERAGE)
append_coverage_compiler_flags_to_target(ssh-static)
endif (WITH_COVERAGE)
endif (BUILD_STATIC_LIB)
message(STATUS "Threads_FOUND=${Threads_FOUND}")

View File

@@ -275,19 +275,19 @@ static int agent_talk(struct ssh_session_struct *session,
char err_msg[SSH_ERRNO_MSG_MAX] = {0};
len = ssh_buffer_get_len(request);
SSH_LOG(SSH_LOG_TRACE, "Request length: %" PRIu32, len);
SSH_LOG(SSH_LOG_TRACE, "Request length: %u", len);
PUSH_BE_U32(payload, 0, len);
/* send length and then the request packet */
if (atomicio(session->agent, payload, 4, 0) == 4) {
if (atomicio(session->agent, ssh_buffer_get(request), len, 0)
!= len) {
SSH_LOG(SSH_LOG_TRACE, "atomicio sending request failed: %s",
strerror(errno));
SSH_LOG(SSH_LOG_WARN, "atomicio sending request failed: %s",
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
return -1;
}
} else {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"atomicio sending request length failed: %s",
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
return -1;
@@ -295,27 +295,27 @@ static int agent_talk(struct ssh_session_struct *session,
/* wait for response, read the length of the response packet */
if (atomicio(session->agent, payload, 4, 1) != 4) {
SSH_LOG(SSH_LOG_TRACE, "atomicio read response length failed: %s",
strerror(errno));
SSH_LOG(SSH_LOG_WARN, "atomicio read response length failed: %s",
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
return -1;
}
len = PULL_BE_U32(payload, 0);
if (len > 256 * 1024) {
ssh_set_error(session, SSH_FATAL,
"Authentication response too long: %" PRIu32, len);
"Authentication response too long: %u", len);
return -1;
}
SSH_LOG(SSH_LOG_TRACE, "Response length: %" PRIu32, len);
SSH_LOG(SSH_LOG_TRACE, "Response length: %u", len);
payload = ssh_buffer_allocate(reply, len);
if (payload == NULL) {
SSH_LOG(SSH_LOG_DEBUG, "Not enough space");
SSH_LOG(SSH_LOG_WARN, "Not enough space");
return -1;
}
if (atomicio(session->agent, payload, len, 1) != len) {
SSH_LOG(SSH_LOG_DEBUG,
SSH_LOG(SSH_LOG_WARN,
"Error reading response from authentication socket.");
/* Rollback the unused space */
ssh_buffer_pass_bytes_end(reply, len);
@@ -363,7 +363,7 @@ uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
rc = ssh_buffer_get_u8(reply, (uint8_t *) &type);
if (rc != sizeof(uint8_t)) {
ssh_set_error(session, SSH_FATAL,
"Bad authentication reply size: %" PRIu32, rc);
"Bad authentication reply size: %d", rc);
SSH_BUFFER_FREE(reply);
return 0;
}
@@ -371,7 +371,7 @@ uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
type = bswap_32(type);
#endif
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"Answer type: %d, expected answer: %d",
type, SSH2_AGENT_IDENTITIES_ANSWER);
@@ -404,7 +404,9 @@ uint32_t ssh_agent_get_ident_count(struct ssh_session_struct *session)
return 0;
}
ssh_buffer_free(session->agent->ident);
if (session->agent->ident) {
ssh_buffer_reinit(session->agent->ident);
}
session->agent->ident = reply;
return session->agent->count;
@@ -422,9 +424,8 @@ ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
/* caller has to free comment */
ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
char **comment)
{
struct ssh_key_struct *key = NULL;
char **comment) {
struct ssh_key_struct *key;
struct ssh_string_struct *blob = NULL;
struct ssh_string_struct *tmp = NULL;
int rc;
@@ -493,10 +494,10 @@ ssh_string ssh_agent_sign_data(ssh_session session,
const ssh_key pubkey,
struct ssh_buffer_struct *data)
{
ssh_buffer request = NULL;
ssh_buffer reply = NULL;
ssh_string key_blob = NULL;
ssh_string sig_blob = NULL;
ssh_buffer request;
ssh_buffer reply;
ssh_string key_blob;
ssh_string sig_blob;
unsigned int type = 0;
unsigned int flags = 0;
uint32_t dlen;
@@ -590,7 +591,7 @@ ssh_string ssh_agent_sign_data(ssh_session session,
#endif
if (agent_failed(type)) {
SSH_LOG(SSH_LOG_DEBUG, "Agent reports failure in signing the key");
SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key");
SSH_BUFFER_FREE(reply);
return NULL;
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {

View File

@@ -72,7 +72,7 @@ static int ssh_userauth_request_service(ssh_session session)
rc = ssh_service_request(session, "ssh-userauth");
if ((rc != SSH_OK) && (rc != SSH_AGAIN)) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"Failed to request \"ssh-userauth\" service");
}
@@ -195,15 +195,14 @@ static int ssh_userauth_get_response(ssh_session session)
*
* This banner should be shown to user prior to authentication
*/
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner)
{
ssh_string banner = NULL;
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner) {
ssh_string banner;
(void)type;
(void)user;
banner = ssh_buffer_get_ssh_string(packet);
if (banner == NULL) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"Invalid SSH_USERAUTH_BANNER packet");
} else {
SSH_LOG(SSH_LOG_DEBUG,
@@ -241,7 +240,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) {
if (partial) {
session->auth.state = SSH_AUTH_STATE_PARTIAL;
SSH_LOG(SSH_LOG_DEBUG,
SSH_LOG(SSH_LOG_INFO,
"Partial success for '%s'. Authentication that can continue: %s",
current_method,
auth_methods);
@@ -251,7 +250,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure) {
"Access denied for '%s'. Authentication that can continue: %s",
current_method,
auth_methods);
SSH_LOG(SSH_LOG_DEBUG,
SSH_LOG(SSH_LOG_INFO,
"%s",
ssh_get_error(session));
@@ -522,17 +521,6 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) {
@@ -556,13 +544,19 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_DENIED;
}
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* public key */
rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s);
if (rc < 0) {
goto fail;
}
SSH_LOG(SSH_LOG_TRACE, "Trying signature type %s", sig_type_c);
/* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
SSH2_MSG_USERAUTH_REQUEST,
@@ -657,17 +651,6 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
@@ -694,13 +677,19 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_DENIED;
}
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* get public key or cert */
rc = ssh_pki_export_pubkey_blob(privkey, &str);
if (rc < 0) {
goto fail;
}
SSH_LOG(SSH_LOG_TRACE, "Sending signature type %s", sig_type_c);
/* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
SSH2_MSG_USERAUTH_REQUEST,
@@ -765,23 +754,18 @@ static int ssh_userauth_agent_publickey(ssh_session session,
bool allowed;
int rc;
switch (session->pending_call_state) {
case SSH_PENDING_CALL_NONE:
break;
case SSH_PENDING_CALL_AUTH_AGENT:
goto pending;
default:
ssh_set_error(session,
SSH_FATAL,
"Bad call during pending SSH call in %s",
__func__);
return SSH_ERROR;
switch(session->pending_call_state) {
case SSH_PENDING_CALL_NONE:
break;
case SSH_PENDING_CALL_AUTH_AGENT:
goto pending;
default:
ssh_set_error(session,
SSH_FATAL,
"Bad call during pending SSH call in ssh_userauth_try_publickey");
return SSH_ERROR;
}
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
@@ -823,14 +807,14 @@ static int ssh_userauth_agent_publickey(ssh_session session,
/* request */
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"publickey",
1, /* private key */
sig_type_c, /* algo */
pubkey_s /* public key */
);
SSH2_MSG_USERAUTH_REQUEST,
username ? username : session->opts.username,
"ssh-connection",
"publickey",
1, /* private key */
sig_type_c, /* algo */
pubkey_s /* public key */
);
SSH_STRING_FREE(pubkey_s);
if (rc < 0) {
goto fail;
@@ -874,7 +858,6 @@ fail:
enum ssh_agent_state_e {
SSH_AGENT_STATE_NONE = 0,
SSH_AGENT_STATE_PUBKEY,
SSH_AGENT_STATE_CERT,
SSH_AGENT_STATE_AUTH
};
@@ -922,12 +905,7 @@ int ssh_userauth_agent(ssh_session session,
const char *username)
{
int rc = SSH_AUTH_ERROR;
struct ssh_agent_state_struct *state = NULL;
ssh_key *configKeys = NULL;
ssh_key *configCerts = NULL;
size_t configKeysCount = 0;
size_t configCertsCount = 0;
size_t i;
struct ssh_agent_state_struct *state;
if (session == NULL) {
return SSH_AUTH_ERROR;
@@ -944,7 +922,7 @@ int ssh_userauth_agent(ssh_session session,
return SSH_AUTH_ERROR;
}
ZERO_STRUCTP(session->agent_state);
session->agent_state->state = SSH_AGENT_STATE_NONE;
session->agent_state->state=SSH_AGENT_STATE_NONE;
}
state = session->agent_state;
@@ -956,230 +934,62 @@ int ssh_userauth_agent(ssh_session session,
return SSH_AUTH_DENIED;
}
if (session->opts.identities_only) {
/*
* Read keys mentioned in the config, so we can check if key from agent
* is in there.
*/
size_t identityLen = ssh_list_count(session->opts.identity);
size_t certsLen = ssh_list_count(session->opts.certificate);
struct ssh_iterator *it = ssh_list_get_iterator(session->opts.identity);
configKeys = malloc(identityLen * sizeof(ssh_key));
configCerts = malloc((certsLen + identityLen) * sizeof(ssh_key));
if (configKeys == NULL || configCerts == NULL) {
free(configKeys);
free(configCerts);
ssh_set_error_oom(session);
return SSH_AUTH_ERROR;
}
while (it != NULL && configKeysCount < identityLen) {
const char *privkeyFile = it->data;
size_t certPathLen;
char *certFile = NULL;
ssh_key pubkey = NULL;
ssh_key cert = NULL;
/*
* Read the private key file listed in the config, but we're only
* interested in the public key. Don't try to decrypt private key.
*/
rc = ssh_pki_import_pubkey_file(privkeyFile, &pubkey);
if (rc == SSH_OK) {
configKeys[configKeysCount++] = pubkey;
} else {
char *pubkeyFile = NULL;
size_t pubkeyPathLen = strlen(privkeyFile) + sizeof(".pub");
SSH_KEY_FREE(pubkey);
/*
* If we couldn't get the public key from the private key file,
* try a .pub file instead.
*/
pubkeyFile = malloc(pubkeyPathLen);
if (!pubkeyFile) {
ssh_set_error_oom(session);
rc = SSH_AUTH_ERROR;
goto done;
}
snprintf(pubkeyFile, pubkeyPathLen, "%s.pub", privkeyFile);
rc = ssh_pki_import_pubkey_file(pubkeyFile, &pubkey);
free(pubkeyFile);
if (rc == SSH_OK) {
configKeys[configKeysCount++] = pubkey;
} else if (pubkey) {
SSH_KEY_FREE(pubkey);
}
}
/* Now try to see if there is a certificate with default name
* do not merge it yet with the key as we need to try first the
* non-certified key */
certPathLen = strlen(privkeyFile) + sizeof("-cert.pub");
certFile = malloc(certPathLen);
if (!certFile) {
ssh_set_error_oom(session);
rc = SSH_AUTH_ERROR;
goto done;
}
snprintf(certFile, certPathLen, "%s-cert.pub", privkeyFile);
rc = ssh_pki_import_cert_file(certFile, &cert);
free(certFile);
if (rc == SSH_OK) {
configCerts[configCertsCount++] = cert;
} else if (cert) {
SSH_KEY_FREE(cert);
}
it = it->next;
}
/* And now load separately-listed certificates. */
it = ssh_list_get_iterator(session->opts.certificate);
while (it != NULL && configCertsCount < certsLen + identityLen) {
const char *certFile = it->data;
ssh_key cert = NULL;
rc = ssh_pki_import_cert_file(certFile, &cert);
if (rc == SSH_OK) {
configCerts[configCertsCount++] = cert;
} else if (cert) {
SSH_KEY_FREE(cert);
}
it = it->next;
}
}
while (state->pubkey != NULL) {
if (state->state == SSH_AGENT_STATE_NONE) {
SSH_LOG(SSH_LOG_DEBUG,
"Trying identity %s",
state->comment);
if (session->opts.identities_only) {
/* Check if this key is one of the keys listed in the config */
bool found_key = false;
for (i = 0; i < configKeysCount; i++) {
int cmp = ssh_key_cmp(state->pubkey,
configKeys[i],
SSH_KEY_CMP_PUBLIC);
if (cmp == 0) {
found_key = true;
break;
}
}
/* or in separate certificates */
for (i = 0; i < configCertsCount; i++) {
int cmp = ssh_key_cmp(state->pubkey,
configCerts[i],
SSH_KEY_CMP_PUBLIC);
if (cmp == 0) {
found_key = true;
break;
}
}
if (!found_key) {
SSH_LOG(SSH_LOG_DEBUG,
"Identities only is enabled and identity %s was "
"not listed in config, skipping",
state->comment);
SSH_STRING_FREE_CHAR(state->comment);
state->comment = NULL;
SSH_KEY_FREE(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(
session, &state->comment);
if (state->pubkey == NULL) {
rc = SSH_AUTH_DENIED;
}
continue;
}
}
"Trying identity %s", state->comment);
}
if (state->state == SSH_AGENT_STATE_NONE ||
state->state == SSH_AGENT_STATE_PUBKEY ||
state->state == SSH_AGENT_STATE_CERT) {
state->state == SSH_AGENT_STATE_PUBKEY) {
rc = ssh_userauth_try_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_ERROR) {
ssh_agent_state_free(state);
ssh_agent_state_free (state);
session->agent_state = NULL;
goto done;
return rc;
} else if (rc == SSH_AUTH_AGAIN) {
state->state = (state->state == SSH_AGENT_STATE_NONE ?
SSH_AGENT_STATE_PUBKEY : state->state);
goto done;
state->state = SSH_AGENT_STATE_PUBKEY;
return rc;
} else if (rc != SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_DEBUG,
"Public key of %s refused by server",
state->comment);
if (state->state == SSH_AGENT_STATE_PUBKEY) {
for (i = 0; i < configCertsCount; i++) {
int cmp = ssh_key_cmp(state->pubkey,
configCerts[i],
SSH_KEY_CMP_PUBLIC);
if (cmp == 0) {
SSH_LOG(SSH_LOG_DEBUG,
"Retry with matching certificate");
SSH_KEY_FREE(state->pubkey);
state->pubkey = ssh_key_dup(configCerts[i]);
state->state = SSH_AGENT_STATE_CERT;
continue;
}
}
}
"Public key of %s refused by server", state->comment);
SSH_STRING_FREE_CHAR(state->comment);
state->comment = NULL;
SSH_KEY_FREE(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session,
&state->comment);
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
continue;
}
SSH_LOG(SSH_LOG_DEBUG,
"Public key of %s accepted by server",
state->comment);
"Public key of %s accepted by server", state->comment);
state->state = SSH_AGENT_STATE_AUTH;
}
if (state->state == SSH_AGENT_STATE_AUTH) {
rc = ssh_userauth_agent_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_AGAIN) {
goto done;
}
if (rc == SSH_AUTH_AGAIN)
return rc;
SSH_STRING_FREE_CHAR(state->comment);
state->comment = NULL;
if (rc == SSH_AUTH_ERROR || rc == SSH_AUTH_PARTIAL) {
ssh_agent_state_free(session->agent_state);
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
goto done;
return rc;
} else if (rc != SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_DEBUG,
SSH_LOG(SSH_LOG_INFO,
"Server accepted public key but refused the signature");
SSH_KEY_FREE(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session,
&state->comment);
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
continue;
}
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
rc = SSH_AUTH_SUCCESS;
goto done;
return SSH_AUTH_SUCCESS;
}
}
ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
done:
for (i = 0; i < configKeysCount; i++) {
ssh_key_free(configKeys[i]);
}
free(configKeys);
for (i = 0; i < configCertsCount; i++) {
ssh_key_free(configCerts[i]);
}
free(configCerts);
return rc;
}
@@ -1187,8 +997,6 @@ enum ssh_auth_auto_state_e {
SSH_AUTH_AUTO_STATE_NONE = 0,
SSH_AUTH_AUTO_STATE_PUBKEY,
SSH_AUTH_AUTO_STATE_KEY_IMPORTED,
SSH_AUTH_AUTO_STATE_CERTIFICATE_FILE,
SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION,
SSH_AUTH_AUTO_STATE_PUBKEY_ACCEPTED
};
@@ -1197,8 +1005,6 @@ struct ssh_auth_auto_state_struct {
struct ssh_iterator *it;
ssh_key privkey;
ssh_key pubkey;
ssh_key cert;
struct ssh_iterator *cert_it;
};
/**
@@ -1233,8 +1039,7 @@ int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
return SSH_ERROR;
}
if (session->auth.auto_state != NULL &&
session->auth.auto_state->it != NULL) {
if (session->auth.auto_state != NULL && session->auth.auto_state->it != NULL) {
id = session->auth.auto_state->it->data;
}
@@ -1278,9 +1083,6 @@ int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
* @note Most server implementations do not permit changing the username during
* authentication. The username should only be set with ssh_options_set() only
* before you connect to the server.
*
* The OpenSSH iterates over the identities and first try the plain public key
* and then the certificate if it is in place.
*/
int ssh_userauth_publickey_auto(ssh_session session,
const char *username,
@@ -1288,7 +1090,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
{
ssh_auth_callback auth_fn = NULL;
void *auth_data = NULL;
struct ssh_auth_auto_state_struct *state = NULL;
struct ssh_auth_auto_state_struct *state;
int rc;
if (session == NULL) {
@@ -1319,7 +1121,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
rc = ssh_userauth_agent(session, username);
if (rc == SSH_AUTH_SUCCESS ||
rc == SSH_AUTH_PARTIAL ||
rc == SSH_AUTH_AGAIN) {
rc == SSH_AUTH_AGAIN ) {
return rc;
}
state->state = SSH_AUTH_AUTO_STATE_PUBKEY;
@@ -1334,9 +1136,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
if (state->state == SSH_AUTH_AUTO_STATE_PUBKEY) {
SSH_LOG(SSH_LOG_DEBUG,
"Trying to authenticate with %s",
privkey_file);
state->cert = NULL;
"Trying to authenticate with %s", privkey_file);
state->privkey = NULL;
state->pubkey = NULL;
@@ -1349,165 +1149,86 @@ int ssh_userauth_publickey_auto(ssh_session session,
if (pub_uri_from_priv == NULL) {
return SSH_ERROR;
} else {
snprintf(pubkey_file,
sizeof(pubkey_file),
"%s",
snprintf(pubkey_file, sizeof(pubkey_file), "%s",
pub_uri_from_priv);
SAFE_FREE(pub_uri_from_priv);
}
} else
#endif /* WITH_PKCS11_URI */
{
snprintf(pubkey_file,
sizeof(pubkey_file),
"%s.pub",
privkey_file);
snprintf(pubkey_file, sizeof(pubkey_file), "%s.pub", privkey_file);
}
rc = ssh_pki_import_pubkey_file(pubkey_file, &state->pubkey);
if (rc == SSH_ERROR) {
ssh_set_error(session,
SSH_FATAL,
"Failed to import public key: %s",
pubkey_file);
SSH_FATAL,
"Failed to import public key: %s",
pubkey_file);
SAFE_FREE(session->auth.auto_state);
return SSH_AUTH_ERROR;
} else if (rc == SSH_EOF) {
/* Read the private key and save the public key to file */
rc = ssh_pki_import_privkey_file(privkey_file,
passphrase,
auth_fn,
auth_data,
&state->privkey);
passphrase,
auth_fn,
auth_data,
&state->privkey);
if (rc == SSH_ERROR) {
ssh_set_error(session,
SSH_FATAL,
"Failed to read private key: %s",
privkey_file);
state->it = state->it->next;
SSH_FATAL,
"Failed to read private key: %s",
privkey_file);
state->it=state->it->next;
continue;
} else if (rc == SSH_EOF) {
/* If the file doesn't exist, continue */
SSH_LOG(SSH_LOG_DEBUG,
"Private key %s doesn't exist.",
privkey_file);
state->it = state->it->next;
state->it=state->it->next;
continue;
}
rc = ssh_pki_export_privkey_to_pubkey(state->privkey,
&state->pubkey);
rc = ssh_pki_export_privkey_to_pubkey(state->privkey, &state->pubkey);
if (rc == SSH_ERROR) {
SSH_KEY_FREE(state->privkey);
ssh_key_free(state->privkey);
SAFE_FREE(session->auth.auto_state);
return SSH_AUTH_ERROR;
}
rc = ssh_pki_export_pubkey_file(state->pubkey, pubkey_file);
if (rc == SSH_ERROR) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"Could not write public key to file: %s",
pubkey_file);
}
}
state->state = SSH_AUTH_AUTO_STATE_KEY_IMPORTED;
}
if (state->state == SSH_AUTH_AUTO_STATE_KEY_IMPORTED ||
state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_FILE ||
state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION) {
ssh_key k = state->pubkey;
if (state->state != SSH_AUTH_AUTO_STATE_KEY_IMPORTED) {
k = state->cert;
}
rc = ssh_userauth_try_publickey(session, username, k);
if (state->state == SSH_AUTH_AUTO_STATE_KEY_IMPORTED) {
rc = ssh_userauth_try_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_ERROR) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"Public key authentication error for %s",
privkey_file);
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->privkey);
SSH_KEY_FREE(state->pubkey);
ssh_key_free(state->privkey);
state->privkey = NULL;
ssh_key_free(state->pubkey);
state->pubkey = NULL;
SAFE_FREE(session->auth.auto_state);
return rc;
} else if (rc == SSH_AUTH_AGAIN) {
return rc;
} else if (rc != SSH_AUTH_SUCCESS) {
int r; /* do not reuse `rc` as it is used to return from here */
SSH_KEY_FREE(state->cert);
SSH_LOG(SSH_LOG_DEBUG,
"Public key for %s%s refused by server",
privkey_file,
(state->state != SSH_AUTH_AUTO_STATE_KEY_IMPORTED
? " (with certificate)" : ""));
/* Try certificate file by appending -cert.pub (if present) */
if (state->state == SSH_AUTH_AUTO_STATE_KEY_IMPORTED) {
char cert_file[PATH_MAX] = {0};
ssh_key cert = NULL;
snprintf(cert_file,
sizeof(cert_file),
"%s-cert.pub",
privkey_file);
SSH_LOG(SSH_LOG_TRACE,
"Trying to load the certificate %s (default path)",
cert_file);
r = ssh_pki_import_cert_file(cert_file, &cert);
if (r == SSH_OK) {
/* TODO check the pubkey and certs match */
SSH_LOG(SSH_LOG_TRACE,
"Certificate loaded %s. Retry the authentication.",
cert_file);
state->state = SSH_AUTH_AUTO_STATE_CERTIFICATE_FILE;
SSH_KEY_FREE(state->cert);
state->cert = cert;
/* try to authenticate with this certificate */
continue;
}
/* if the file does not exists, try configuration options */
state->state = SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION;
}
/* Try certificate files loaded through options */
if (state->state == SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION) {
SSH_KEY_FREE(state->cert);
if (state->cert_it == NULL) {
state->cert_it = ssh_list_get_iterator(session->opts.certificate);
}
while (state->cert_it != NULL) {
const char *cert_file = state->cert_it->data;
ssh_key cert = NULL;
SSH_LOG(SSH_LOG_TRACE,
"Trying to load the certificate %s (options)",
cert_file);
r = ssh_pki_import_cert_file(cert_file, &cert);
if (r == SSH_OK) {
int cmp = ssh_key_cmp(cert,
state->pubkey,
SSH_KEY_CMP_PUBLIC);
if (cmp != 0) {
state->cert_it = state->cert_it->next;
SSH_KEY_FREE(cert);
continue; /* with next cert */
}
SSH_LOG(SSH_LOG_TRACE,
"Found matching certificate %s in options. Retry the authentication.",
cert_file);
state->cert = cert;
cert = NULL;
state->state = SSH_AUTH_AUTO_STATE_CERTIFICATE_OPTION;
/* try to authenticate with this identity */
break; /* try this cert */
}
/* continue with next identity */
}
if (state->cert != NULL) {
continue; /* retry with the certificate */
}
}
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->privkey);
SSH_KEY_FREE(state->pubkey);
state->it = state->it->next;
"Public key for %s refused by server",
privkey_file);
ssh_key_free(state->privkey);
state->privkey = NULL;
ssh_key_free(state->pubkey);
state->pubkey = NULL;
state->it=state->it->next;
state->state = SSH_AUTH_AUTO_STATE_PUBKEY;
continue;
}
@@ -1517,25 +1238,25 @@ int ssh_userauth_publickey_auto(ssh_session session,
/* Public key has been accepted by the server */
if (state->privkey == NULL) {
rc = ssh_pki_import_privkey_file(privkey_file,
passphrase,
auth_fn,
auth_data,
&state->privkey);
passphrase,
auth_fn,
auth_data,
&state->privkey);
if (rc == SSH_ERROR) {
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->pubkey);
ssh_key_free(state->pubkey);
state->pubkey=NULL;
ssh_set_error(session,
SSH_FATAL,
"Failed to read private key: %s",
privkey_file);
state->it = state->it->next;
SSH_FATAL,
"Failed to read private key: %s",
privkey_file);
state->it=state->it->next;
state->state = SSH_AUTH_AUTO_STATE_PUBKEY;
continue;
} else if (rc == SSH_EOF) {
/* If the file doesn't exist, continue */
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->pubkey);
SSH_LOG(SSH_LOG_DEBUG,
ssh_key_free(state->pubkey);
state->pubkey = NULL;
SSH_LOG(SSH_LOG_INFO,
"Private key %s doesn't exist.",
privkey_file);
state->it = state->it->next;
@@ -1543,33 +1264,16 @@ int ssh_userauth_publickey_auto(ssh_session session,
continue;
}
}
if (state->cert != NULL && !is_cert_type(state->privkey->cert_type)) {
rc = ssh_pki_copy_cert_to_privkey(state->cert, state->privkey);
if (rc != SSH_OK) {
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->privkey);
SSH_KEY_FREE(state->pubkey);
ssh_set_error(session,
SSH_FATAL,
"Failed to copy cert to private key");
state->it = state->it->next;
state->state = SSH_AUTH_AUTO_STATE_PUBKEY;
continue;
}
}
rc = ssh_userauth_publickey(session, username, state->privkey);
if (rc != SSH_AUTH_AGAIN && rc != SSH_AUTH_DENIED) {
bool cert_used = (state->cert != NULL);
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->privkey);
SSH_KEY_FREE(state->pubkey);
ssh_key_free(state->privkey);
ssh_key_free(state->pubkey);
SAFE_FREE(session->auth.auto_state);
if (rc == SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_DEBUG,
"Successfully authenticated using %s%s",
privkey_file,
(cert_used ? " and certificate" : ""));
SSH_LOG(SSH_LOG_INFO,
"Successfully authenticated using %s",
privkey_file);
}
return rc;
}
@@ -1577,19 +1281,18 @@ int ssh_userauth_publickey_auto(ssh_session session,
return rc;
}
SSH_KEY_FREE(state->cert);
SSH_KEY_FREE(state->privkey);
SSH_KEY_FREE(state->pubkey);
ssh_key_free(state->privkey);
ssh_key_free(state->pubkey);
SSH_LOG(SSH_LOG_DEBUG,
SSH_LOG(SSH_LOG_WARN,
"The server accepted the public key but refused the signature");
state->it = state->it->next;
state->state = SSH_AUTH_AUTO_STATE_PUBKEY;
/* continue */
}
}
SSH_LOG(SSH_LOG_WARN,
"Access denied: Tried every public key, none matched");
SSH_LOG(SSH_LOG_INFO,
"Tried every public key, none matched");
SAFE_FREE(session->auth.auto_state);
return SSH_AUTH_DENIED;
}
@@ -1695,7 +1398,7 @@ int ssh_userauth_agent_pubkey(ssh_session session,
const char *username,
ssh_public_key publickey)
{
ssh_key key = NULL;
ssh_key key;
int rc;
key = ssh_key_new();
@@ -1706,23 +1409,21 @@ int ssh_userauth_agent_pubkey(ssh_session session,
key->type = publickey->type;
key->type_c = ssh_key_type_to_char(key->type);
key->flags = SSH_KEY_FLAG_PUBLIC;
#if defined(HAVE_LIBMBEDCRYPTO)
key->pk = publickey->rsa_pub;
#elif defined(HAVE_LIBCRYPTO)
key->key = publickey->key_pub;
#else
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
key->dsa = publickey->dsa_pub;
key->rsa = publickey->rsa_pub;
#endif /* HAVE_LIBCRYPTO */
#else
key->key = publickey->key_pub;
#endif /* OPENSSL_VERSION_NUMBER */
rc = ssh_userauth_agent_publickey(session, username, key);
#if defined(HAVE_LIBMBEDCRYPTO)
key->pk = NULL;
#elif defined(HAVE_LIBCRYPTO)
key->key = NULL;
#else
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
key->dsa = NULL;
key->rsa = NULL;
#endif /* HAVE_LIBCRYPTO */
#else
key->key = NULL;
#endif /* OPENSSL_VERSION_NUMBER */
ssh_key_free(key);
return rc;
@@ -1979,10 +1680,10 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
}
SSH_LOG(SSH_LOG_DEBUG,
"%" PRIu32 " keyboard-interactive prompts", nprompts);
"%d keyboard-interactive prompts", nprompts);
if (nprompts > KBDINT_MAX_PROMPT) {
ssh_set_error(session, SSH_FATAL,
"Too much prompts requested by the server: %" PRIu32 " (0x%.4" PRIx32 ")",
"Too much prompts requested by the server: %u (0x%.4x)",
nprompts, nprompts);
ssh_kbdint_free(session->kbdint);
session->kbdint = NULL;
@@ -2227,8 +1928,7 @@ int ssh_userauth_kbdint_getnanswers(ssh_session session)
*
* @param[in] i index The number of the ith answer.
*
* @return The answer string, or NULL if the answer is not
* available. Do not free the string.
* @return 0 on success, < 0 on error.
*/
const char *ssh_userauth_kbdint_getanswer(ssh_session session, unsigned int i)
{
@@ -2334,7 +2034,7 @@ int ssh_userauth_gssapi(ssh_session session)
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
SSH_LOG(SSH_LOG_DEBUG, "Authenticating with gssapi-with-mic");
SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi-with-mic");
session->auth.current_method = SSH_AUTH_METHOD_GSSAPI_MIC;
session->auth.state = SSH_AUTH_STATE_NONE;

View File

@@ -29,9 +29,6 @@
#include "libssh/priv.h"
#include "libssh/buffer.h"
/* Do not allow encoding more than 256MB of data */
#define BASE64_MAX_INPUT_LEN 256 * 1024 * 1024
static
const uint8_t alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
@@ -60,120 +57,119 @@ static int get_equals(char *string);
* @returns A buffer containing the decoded string, NULL if something went
* wrong (e.g. incorrect char).
*/
ssh_buffer base64_to_bin(const char *source)
{
ssh_buffer buffer = NULL;
unsigned char block[3];
char *base64 = NULL;
char *ptr = NULL;
size_t len;
int equals;
ssh_buffer base64_to_bin(const char *source) {
ssh_buffer buffer = NULL;
unsigned char block[3];
char *base64;
char *ptr;
size_t len;
int equals;
base64 = strdup(source);
if (base64 == NULL) {
return NULL;
base64 = strdup(source);
if (base64 == NULL) {
return NULL;
}
ptr = base64;
/* Get the number of equals signs, which mirrors the padding */
equals = get_equals(ptr);
if (equals > 2) {
SAFE_FREE(base64);
return NULL;
}
buffer = ssh_buffer_new();
if (buffer == NULL) {
SAFE_FREE(base64);
return NULL;
}
/*
* The base64 buffer often contains sensitive data. Make sure we don't leak
* sensitive data
*/
ssh_buffer_set_secure(buffer);
len = strlen(ptr);
while (len > 4) {
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
ptr = base64;
/* Get the number of equals signs, which mirrors the padding */
equals = get_equals(ptr);
if (equals > 2) {
SAFE_FREE(base64);
return NULL;
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
len -= 4;
ptr += 4;
}
buffer = ssh_buffer_new();
if (buffer == NULL) {
SAFE_FREE(base64);
return NULL;
}
/*
* The base64 buffer often contains sensitive data. Make sure we don't leak
* sensitive data
*/
ssh_buffer_set_secure(buffer);
len = strlen(ptr);
while (len > 4) {
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
len -= 4;
ptr += 4;
}
/*
* Depending on the number of bytes resting, there are 3 possibilities
* from the RFC.
*/
switch (len) {
/*
* Depending on the number of bytes resting, there are 3 possibilities
* from the RFC.
*/
switch (len) {
/*
* (1) The final quantum of encoding input is an integral multiple of
* 24 bits. Here, the final unit of encoded output will be an integral
* multiple of 4 characters with no "=" padding
*/
case 4:
if (equals != 0) {
goto error;
}
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
SAFE_FREE(base64);
if (equals != 0) {
goto error;
}
if (_base64_to_bin(block, ptr, 3) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
goto error;
}
SAFE_FREE(base64);
return buffer;
return buffer;
/*
* (2) The final quantum of encoding input is exactly 8 bits; here, the
* final unit of encoded output will be two characters followed by
* two "=" padding characters.
*/
case 2:
if (equals != 2) {
goto error;
}
if (equals != 2){
goto error;
}
if (_base64_to_bin(block, ptr, 1) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 1) < 0) {
goto error;
}
SAFE_FREE(base64);
if (_base64_to_bin(block, ptr, 1) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 1) < 0) {
goto error;
}
SAFE_FREE(base64);
return buffer;
return buffer;
/*
* The final quantum of encoding input is exactly 16 bits. Here, the final
* unit of encoded output will be three characters followed by one "="
* padding character.
*/
case 3:
if (equals != 1) {
goto error;
}
if (_base64_to_bin(block, ptr, 2) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer, block, 2) < 0) {
goto error;
}
SAFE_FREE(base64);
return buffer;
default:
/* 4,3,2 are the only padding size allowed */
if (equals != 1) {
goto error;
}
}
if (_base64_to_bin(block, ptr, 2) < 0) {
goto error;
}
if (ssh_buffer_add_data(buffer,block,2) < 0) {
goto error;
}
SAFE_FREE(base64);
return buffer;
default:
/* 4,3,2 are the only padding size allowed */
goto error;
}
error:
SAFE_FREE(base64);
SSH_BUFFER_FREE(buffer);
return NULL;
SAFE_FREE(base64);
SSH_BUFFER_FREE(buffer);
return NULL;
}
#define BLOCK(letter, n) do {ptr = strchr((const char *)alphabet, source[n]); \
@@ -183,62 +179,59 @@ error:
} while(0)
/* Returns 0 if ok, -1 if not (ie invalid char into the stuff) */
static int to_block4(unsigned long *block, const char *source, int num)
{
const char *ptr = NULL;
unsigned int i;
*block = 0;
if (num < 1) {
return 0;
}
BLOCK(A, 0); /* 6 bit */
BLOCK(B, 1); /* 12 bit */
if (num < 2) {
return 0;
}
BLOCK(C, 2); /* 18 bit */
if (num < 3) {
return 0;
}
BLOCK(D, 3); /* 24 bit */
static int to_block4(unsigned long *block, const char *source, int num) {
const char *ptr = NULL;
unsigned int i;
*block = 0;
if (num < 1) {
return 0;
}
BLOCK(A, 0); /* 6 bit */
BLOCK(B,1); /* 12 bit */
if (num < 2) {
return 0;
}
BLOCK(C, 2); /* 18 bit */
if (num < 3) {
return 0;
}
BLOCK(D, 3); /* 24 bit */
return 0;
}
/* num = numbers of final bytes to be decoded */
static int _base64_to_bin(unsigned char dest[3], const char *source, int num)
{
unsigned long block;
static int _base64_to_bin(unsigned char dest[3], const char *source, int num) {
unsigned long block;
if (to_block4(&block, source, num) < 0) {
return -1;
}
dest[0] = GET_A(block);
dest[1] = GET_B(block);
dest[2] = GET_C(block);
if (to_block4(&block, source, num) < 0) {
return -1;
}
dest[0] = GET_A(block);
dest[1] = GET_B(block);
dest[2] = GET_C(block);
return 0;
return 0;
}
/* Count the number of "=" signs and replace them by zeroes */
static int get_equals(char *string)
{
char *ptr = string;
int num = 0;
static int get_equals(char *string) {
char *ptr = string;
int num = 0;
while ((ptr = strchr(ptr, '=')) != NULL) {
num++;
*ptr = '\0';
ptr++;
}
while ((ptr=strchr(ptr,'=')) != NULL) {
num++;
*ptr = '\0';
ptr++;
}
return num;
return num;
}
/* thanks sysk for debugging my mess :) */
@@ -281,15 +274,7 @@ uint8_t *bin_to_base64(const uint8_t *source, size_t len)
{
uint8_t *base64 = NULL;
uint8_t *ptr = NULL;
size_t flen = 0;
/* Set the artificial upper limit for the input. Otherwise on 32b arch, the
* following line could overflow for sizes larger than SIZE_MAX / 4 */
if (len > BASE64_MAX_INPUT_LEN) {
return NULL;
}
flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
size_t flen = len + (3 - (len % 3)); /* round to upper 3 multiple */
flen = (4 * flen) / 3 + 1;
base64 = malloc(flen);
@@ -298,7 +283,7 @@ uint8_t *bin_to_base64(const uint8_t *source, size_t len)
}
ptr = base64;
while (len > 0) {
while(len > 0){
_bin_to_base64(ptr, source, len > 3 ? 3 : len);
ptr += 4;
if (len < 3) {

View File

@@ -70,7 +70,7 @@ bignum ssh_make_string_bn(ssh_string string)
#ifdef DEBUG_CRYPTO
SSH_LOG(SSH_LOG_TRACE,
"Importing a %zu bits, %zu bytes object ...",
"Importing a %zu bits, %zu bytes object ...\n",
len * 8, len);
#endif /* DEBUG_CRYPTO */
@@ -88,5 +88,11 @@ void ssh_print_bignum(const char *name, const_bignum num)
}
SSH_LOG(SSH_LOG_DEBUG, "%s value: %s", name,
(hex == NULL) ? "(null)" : (char *)hex);
ssh_crypto_free(hex);
#ifdef HAVE_LIBGCRYPT
SAFE_FREE(hex);
#elif defined HAVE_LIBCRYPTO
OPENSSL_free(hex);
#elif defined HAVE_LIBMBEDCRYPTO
SAFE_FREE(hex);
#endif
}

View File

@@ -74,7 +74,7 @@
static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
int port) {
char port_c[6];
struct addrinfo *ai = NULL;
struct addrinfo *ai;
struct addrinfo hints;
int opt = 1;
socket_t s;
@@ -132,9 +132,8 @@ static socket_t bind_socket(ssh_bind sshbind, const char *hostname,
return s;
}
ssh_bind ssh_bind_new(void)
{
ssh_bind ptr = NULL;
ssh_bind ssh_bind_new(void) {
ssh_bind ptr;
ptr = calloc(1, sizeof(struct ssh_bind_struct));
if (ptr == NULL) {
@@ -150,6 +149,15 @@ ssh_bind ssh_bind_new(void)
static int ssh_bind_import_keys(ssh_bind sshbind) {
int rc;
if (sshbind->ecdsakey == NULL &&
sshbind->dsakey == NULL &&
sshbind->rsakey == NULL &&
sshbind->ed25519key == NULL) {
ssh_set_error(sshbind, SSH_FATAL,
"ECDSA, ED25519, DSA, or RSA host key file must be set");
return SSH_ERROR;
}
#ifdef HAVE_ECC
if (sshbind->ecdsa == NULL && sshbind->ecdsakey != NULL) {
rc = ssh_pki_import_privkey_file(sshbind->ecdsakey,
@@ -173,6 +181,30 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
}
#endif
#ifdef HAVE_DSA
if (sshbind->dsa == NULL && sshbind->dsakey != NULL) {
rc = ssh_pki_import_privkey_file(sshbind->dsakey,
NULL,
NULL,
NULL,
&sshbind->dsa);
if (rc == SSH_ERROR || rc == SSH_EOF) {
ssh_set_error(sshbind, SSH_FATAL,
"Failed to import private DSA host key");
return SSH_ERROR;
}
if (ssh_key_type(sshbind->dsa) != SSH_KEYTYPE_DSS) {
ssh_set_error(sshbind, SSH_FATAL,
"The DSA host key has the wrong type: %d",
ssh_key_type(sshbind->dsa));
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
return SSH_ERROR;
}
}
#endif
if (sshbind->rsa == NULL && sshbind->rsakey != NULL) {
rc = ssh_pki_import_privkey_file(sshbind->rsakey,
NULL,
@@ -218,105 +250,95 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
return SSH_OK;
}
int ssh_bind_listen(ssh_bind sshbind)
{
const char *host = NULL;
socket_t fd;
int rc;
int ssh_bind_listen(ssh_bind sshbind) {
const char *host;
socket_t fd;
int rc;
/* Apply global bind configurations, if it hasn't been applied before */
rc = ssh_bind_options_parse_config(sshbind, NULL);
if (rc != 0) {
ssh_set_error(sshbind, SSH_FATAL, "Could not parse global config");
return SSH_ERROR;
}
if (sshbind->rsa == NULL &&
sshbind->dsa == NULL &&
sshbind->ecdsa == NULL &&
sshbind->ed25519 == NULL) {
rc = ssh_bind_import_keys(sshbind);
if (rc != SSH_OK) {
return SSH_ERROR;
}
}
/* Set default hostkey paths if no hostkey was found before */
if (sshbind->ecdsakey == NULL &&
sshbind->rsakey == NULL &&
sshbind->ed25519key == NULL) {
if (sshbind->bindfd == SSH_INVALID_SOCKET) {
host = sshbind->bindaddr;
if (host == NULL) {
host = "0.0.0.0";
}
sshbind->ecdsakey = strdup("/etc/ssh/ssh_host_ecdsa_key");
sshbind->rsakey = strdup("/etc/ssh/ssh_host_rsa_key");
sshbind->ed25519key = strdup("/etc/ssh/ssh_host_ed25519_key");
}
fd = bind_socket(sshbind, host, sshbind->bindport);
if (fd == SSH_INVALID_SOCKET) {
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
ssh_key_free(sshbind->rsa);
sshbind->rsa = NULL;
/* XXX should this clear also other structures that were allocated */
return -1;
}
if (sshbind->rsa == NULL &&
sshbind->ecdsa == NULL &&
sshbind->ed25519 == NULL) {
rc = ssh_bind_import_keys(sshbind);
if (rc != SSH_OK) {
return SSH_ERROR;
}
}
if (listen(fd, 10) < 0) {
char err_msg[SSH_ERRNO_MSG_MAX] = {0};
ssh_set_error(sshbind, SSH_FATAL,
"Listening to socket %d: %s",
fd, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
CLOSE_SOCKET(fd);
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
ssh_key_free(sshbind->rsa);
sshbind->rsa = NULL;
/* XXX should this clear also other structures that were allocated */
return -1;
}
if (sshbind->bindfd == SSH_INVALID_SOCKET) {
host = sshbind->bindaddr;
if (host == NULL) {
host = "0.0.0.0";
}
fd = bind_socket(sshbind, host, sshbind->bindport);
if (fd == SSH_INVALID_SOCKET) {
return SSH_ERROR;
}
if (listen(fd, 10) < 0) {
char err_msg[SSH_ERRNO_MSG_MAX] = {0};
ssh_set_error(sshbind,
SSH_FATAL,
"Listening to socket %d: %s",
fd,
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
CLOSE_SOCKET(fd);
return SSH_ERROR;
}
sshbind->bindfd = fd;
} else {
SSH_LOG(SSH_LOG_DEBUG, "Using app-provided bind socket");
}
return 0;
sshbind->bindfd = fd;
} else {
SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket");
}
return 0;
}
int ssh_bind_set_callbacks(ssh_bind sshbind, ssh_bind_callbacks callbacks, void *userdata)
{
if (sshbind == NULL) {
return SSH_ERROR;
}
if (callbacks == NULL) {
ssh_set_error_invalid(sshbind);
return SSH_ERROR;
}
if (callbacks->size <= 0 || callbacks->size > 1024 * sizeof(void *)) {
ssh_set_error(sshbind,
SSH_FATAL,
"Invalid callback passed in (badly initialized)");
return SSH_ERROR;
}
sshbind->bind_callbacks = callbacks;
sshbind->bind_callbacks_userdata = userdata;
return 0;
int ssh_bind_set_callbacks(ssh_bind sshbind, ssh_bind_callbacks callbacks,
void *userdata){
if (sshbind == NULL) {
return SSH_ERROR;
}
if (callbacks == NULL) {
ssh_set_error_invalid(sshbind);
return SSH_ERROR;
}
if(callbacks->size <= 0 || callbacks->size > 1024 * sizeof(void *)){
ssh_set_error(sshbind,SSH_FATAL,
"Invalid callback passed in (badly initialized)");
return SSH_ERROR;
}
sshbind->bind_callbacks = callbacks;
sshbind->bind_callbacks_userdata=userdata;
return 0;
}
/** @internal
* @brief callback being called by poll when an event happens
*
*/
static int ssh_bind_poll_callback(ssh_poll_handle sshpoll, socket_t fd, int revents, void *user)
{
ssh_bind sshbind = (ssh_bind)user;
(void)sshpoll;
(void)fd;
static int ssh_bind_poll_callback(ssh_poll_handle sshpoll,
socket_t fd, int revents, void *user){
ssh_bind sshbind=(ssh_bind)user;
(void)sshpoll;
(void)fd;
if (revents & POLLIN) {
/* new incoming connection */
if (ssh_callbacks_exists(sshbind->bind_callbacks, incoming_connection)) {
sshbind->bind_callbacks->incoming_connection(sshbind,
sshbind->bind_callbacks_userdata);
}
if(revents & POLLIN){
/* new incoming connection */
if(ssh_callbacks_exists(sshbind->bind_callbacks,incoming_connection)){
sshbind->bind_callbacks->incoming_connection(sshbind,
sshbind->bind_callbacks_userdata);
}
return 0;
}
return 0;
}
/** @internal
@@ -344,24 +366,20 @@ ssh_poll_handle ssh_bind_get_poll(ssh_bind sshbind)
return sshbind->poll;
}
void ssh_bind_set_blocking(ssh_bind sshbind, int blocking)
{
sshbind->blocking = blocking ? 1 : 0;
void ssh_bind_set_blocking(ssh_bind sshbind, int blocking) {
sshbind->blocking = blocking ? 1 : 0;
}
socket_t ssh_bind_get_fd(ssh_bind sshbind)
{
return sshbind->bindfd;
socket_t ssh_bind_get_fd(ssh_bind sshbind) {
return sshbind->bindfd;
}
void ssh_bind_set_fd(ssh_bind sshbind, socket_t fd)
{
sshbind->bindfd = fd;
void ssh_bind_set_fd(ssh_bind sshbind, socket_t fd) {
sshbind->bindfd = fd;
}
void ssh_bind_fd_toaccept(ssh_bind sshbind)
{
sshbind->toaccept = 1;
void ssh_bind_fd_toaccept(ssh_bind sshbind) {
sshbind->toaccept = 1;
}
void ssh_bind_free(ssh_bind sshbind){
@@ -383,10 +401,13 @@ void ssh_bind_free(ssh_bind sshbind){
SAFE_FREE(sshbind->config_dir);
SAFE_FREE(sshbind->pubkey_accepted_key_types);
SAFE_FREE(sshbind->dsakey);
SAFE_FREE(sshbind->rsakey);
SAFE_FREE(sshbind->ecdsakey);
SAFE_FREE(sshbind->ed25519key);
ssh_key_free(sshbind->dsa);
sshbind->dsa = NULL;
ssh_key_free(sshbind->rsa);
sshbind->rsa = NULL;
ssh_key_free(sshbind->ecdsa);
@@ -417,6 +438,13 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
return SSH_ERROR;
}
/* Apply global bind configurations, if it hasn't been applied before */
rc = ssh_bind_options_parse_config(sshbind, NULL);
if (rc != 0) {
ssh_set_error(sshbind, SSH_FATAL,"Could not parse global config");
return SSH_ERROR;
}
session->server = 1;
/* Copy options from bind to session */
@@ -447,7 +475,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
return SSH_ERROR;
}
} else {
char *p = NULL;
char *p;
/* If something was set to the session prior to calling this
* function, keep only what is allowed by the options set in
* sshbind */
@@ -465,16 +493,16 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
session->common.log_verbosity = sshbind->common.log_verbosity;
if (sshbind->banner != NULL) {
session->server_opts.custombanner = strdup(sshbind->banner);
if (session->server_opts.custombanner == NULL) {
session->opts.custombanner = strdup(sshbind->banner);
if (session->opts.custombanner == NULL) {
ssh_set_error_oom(sshbind);
return SSH_ERROR;
}
}
if (sshbind->moduli_file != NULL) {
session->server_opts.moduli_file = strdup(sshbind->moduli_file);
if (session->server_opts.moduli_file == NULL) {
session->opts.moduli_file = strdup(sshbind->moduli_file);
if (session->opts.moduli_file == NULL) {
ssh_set_error_oom(sshbind);
return SSH_ERROR;
}
@@ -503,6 +531,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
* only using ssh_bind_accept_fd to manage sockets ourselves.
*/
if (sshbind->rsa == NULL &&
sshbind->dsa == NULL &&
sshbind->ecdsa == NULL &&
sshbind->ed25519 == NULL) {
rc = ssh_bind_import_keys(sshbind);
@@ -519,6 +548,15 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
return SSH_ERROR;
}
}
#endif
#ifdef HAVE_DSA
if (sshbind->dsa) {
session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
if (session->srv.dsa_key == NULL) {
ssh_set_error_oom(sshbind);
return SSH_ERROR;
}
}
#endif
if (sshbind->rsa) {
session->srv.rsa_key = ssh_key_dup(sshbind->rsa);

View File

@@ -200,7 +200,7 @@ local_parse_file(ssh_bind bind,
uint8_t *seen,
unsigned int depth)
{
FILE *f = NULL;
FILE *f;
char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0;
int rv;
@@ -363,7 +363,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HOSTKEY, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set Hostkey value '%s'",
count, p);
}
@@ -374,7 +374,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDADDR, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set ListenAddress value '%s'",
count, p);
}
@@ -385,7 +385,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BINDPORT_STR, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set Port value '%s'",
count, p);
}
@@ -396,7 +396,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_C_S, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set C->S Ciphers value '%s'",
count, p);
break;
@@ -404,7 +404,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_CIPHERS_S_C, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set S->C Ciphers value '%s'",
count, p);
}
@@ -415,7 +415,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_C_S, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set C->S MAC value '%s'",
count, p);
break;
@@ -423,7 +423,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_HMAC_S_C, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set S->C MAC value '%s'",
count, p);
}
@@ -437,10 +437,10 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (strcasecmp(p, "quiet") == 0) {
value = SSH_LOG_NONE;
} else if (strcasecmp(p, "fatal") == 0 ||
strcasecmp(p, "error")== 0) {
value = SSH_LOG_WARN;
} else if (strcasecmp(p, "verbose") == 0 ||
strcasecmp(p, "error")== 0 ||
strcasecmp(p, "info") == 0) {
value = SSH_LOG_WARN;
} else if (strcasecmp(p, "verbose") == 0) {
value = SSH_LOG_INFO;
} else if (strcasecmp(p, "DEBUG") == 0 ||
strcasecmp(p, "DEBUG1") == 0) {
@@ -453,7 +453,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY,
&value);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set LogLevel value '%s'",
count, p);
}
@@ -465,7 +465,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
if (p && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_KEY_EXCHANGE, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set KexAlgorithms value '%s'",
count, p);
}
@@ -540,13 +540,13 @@ ssh_bind_config_parse_line(ssh_bind bind,
/* Skip one argument */
p = ssh_config_get_str_tok(&s, NULL);
if (p == NULL || p[0] == '\0') {
SSH_LOG(SSH_LOG_TRACE, "line %d: Match keyword "
SSH_LOG(SSH_LOG_WARN, "line %d: Match keyword "
"'%s' requires argument\n", count, p2);
SAFE_FREE(x);
return -1;
}
args++;
SSH_LOG(SSH_LOG_DEBUG,
SSH_LOG(SSH_LOG_WARN,
"line %d: Unsupported Match keyword '%s', ignoring\n",
count,
p2);
@@ -576,7 +576,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
rc = ssh_bind_options_set(bind,
SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set PubKeyAcceptedKeyTypes value '%s'",
count, p);
}
@@ -588,26 +588,26 @@ ssh_bind_config_parse_line(ssh_bind bind,
rc = ssh_bind_options_set(bind,
SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS, p);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
SSH_LOG(SSH_LOG_WARN,
"line %d: Failed to set HostkeyAlgorithms value '%s'",
count, p);
}
}
break;
case BIND_CFG_NOT_ALLOWED_IN_MATCH:
SSH_LOG(SSH_LOG_DEBUG, "Option not allowed in Match block: %s, line: %d",
SSH_LOG(SSH_LOG_WARN, "Option not allowed in Match block: %s, line: %d",
keyword, count);
break;
case BIND_CFG_UNKNOWN:
SSH_LOG(SSH_LOG_TRACE, "Unknown option: %s, line: %d",
SSH_LOG(SSH_LOG_WARN, "Unknown option: %s, line: %d",
keyword, count);
break;
case BIND_CFG_UNSUPPORTED:
SSH_LOG(SSH_LOG_TRACE, "Unsupported option: %s, line: %d",
SSH_LOG(SSH_LOG_WARN, "Unsupported option: %s, line: %d",
keyword, count);
break;
case BIND_CFG_NA:
SSH_LOG(SSH_LOG_TRACE, "Option not applicable: %s, line: %d",
SSH_LOG(SSH_LOG_WARN, "Option not applicable: %s, line: %d",
keyword, count);
break;
default:
@@ -626,7 +626,7 @@ int ssh_bind_config_parse_file(ssh_bind bind, const char *filename)
{
char line[MAX_LINE_SIZE] = {0};
unsigned int count = 0;
FILE *f = NULL;
FILE *f;
uint32_t parser_flags;
int rv;

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