Compare commits

...

107 Commits

Author SHA1 Message Date
Andreas Schneider
04685a74df Bump version to 0.8.9
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
2020-04-09 09:35:55 +02:00
Andreas Schneider
ec853bb86a CVE-2020-1730: Fix a possible segfault when zeroing AES-CTR key
Fixes T213

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
(cherry picked from commit b36272eac1)
2020-04-09 09:35:40 +02:00
Andreas Schneider
7850307210 Bump version to 0.8.8
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-12-09 19:28:54 +01:00
Andreas Schneider
30c0f0c0e3 cpack: Ignore patch files and other stuff
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ecc78ec154)
2019-12-09 19:28:48 +01:00
Anderson Toshiyuki Sasaki
b0edec4e8d CVE-2019-14889: scp: Quote location to be used on shell
Single quote file paths to be used on commands to be executed on remote
shell.

Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3830c7ae6e)
2019-12-09 17:34:30 +01:00
Andreas Schneider
391c78de9d CVE-2019-14889: scp: Don't allow file path longer than 32kb
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0b5ee39726)
2019-12-09 17:34:28 +01:00
Anderson Toshiyuki Sasaki
2ba1dea549 CVE-2019-14889: misc: Add function to quote file names
The added function quote file names strings to be used in a shell.
Special cases are treated for the charactes '\'' and '!'.

Fixes T181

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

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

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

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 42c727d0c1)
2019-12-09 17:33:35 +01:00
Andreas Schneider
2fbeb2ac88 gitlab-ci: Mips is dead
Debian removed the cross compiling toolchain. So lets drop it.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit d02c06268e)
2019-11-04 09:50:56 +01:00
Andreas Schneider
e981113ee1 doc: Add a note about OpenSSL linking
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 144e551614)
2019-03-13 10:36:42 +01:00
Andreas Schneider
3736a0367b libcrypto: Add missing includes for modes.h
This defines block128_f.

Fixes T133.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 65bc24d8a4)
2019-03-13 10:33:08 +01:00
Andreas Schneider
be73335f8e sftp: Document how to free memory retruned by sftp_canonicalize_path()
Fixes T129

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7c444c09d7)
2019-02-27 08:34:36 +01:00
Andreas Schneider
52986115b8 Bump version to 0.8.7
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-02-25 10:00:04 +01:00
Andreas Schneider
7a49ee5ffc cmake: Bump API version to 4.7.4
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a1559505a5)
2019-02-22 18:21:25 +01:00
Dirkjan Bussink
c842bc2e8b Remove SHA384 HMAC
This is not supported by OpenSSH and not recommended to be implemented
either.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 369051a5b4)
2019-02-22 18:21:25 +01:00
Dirkjan Bussink
8892577296 Use constant time comparison function for HMAC comparison
Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 46d15b3161)
2019-02-22 18:21:25 +01:00
Andreas Schneider
ac7c64a769 pki_gcrypt: Include missing stdbool.h
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8a73e48184)
2019-02-22 11:42:26 +01:00
Andreas Schneider
47014eb273 pki: Fix size type for len in privatekey_string_to_buffer()
src/pki_gcrypt.c:485:10: error: assuming signed overflow does not occur
when simplifying conditional to constant [-Werror=strict-overflow]

Fixes T132

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7a8ed6d02b)
2019-02-22 11:42:26 +01:00
Andreas Schneider
2223106113 connect: Fix size type for i an j in ssh_select()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 58113d489e)
2019-02-22 11:42:26 +01:00
David Wedderwille
4af77362b0 connector: Fallback on the socket output callback
Fixes T124

Signed-off-by: David Wedderwille <davidwe@posteo.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b73ffb3f91)
2019-02-22 11:42:26 +01:00
Till Wimmer
f4a0fcc85e connector: Don't NULL connector (in|out) channels on event remove
Signed-off-by: Till Wimmer <g4-lisz@tonarchiv.ch>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 16a52a8362)
2019-02-22 11:42:26 +01:00
Till Wimmer
fa150ef8d2 options: Removed outdated param annotations of ssh_options_set()
Signed-off-by: Till Wimmer <g4-lisz@tonarchiv.ch>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d27b817acc)
2019-02-22 11:42:26 +01:00
Jakub Jelen
810dbd3db1 config: Avoid buffer overflow
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1af10fcdb3)
2019-02-22 11:42:26 +01:00
Jon Simons
fa6aa125a2 tests/pkd: repro rsa-sha2-{256,512} negotiation bug
Add four passes to the pkd tests to exercise codepaths where an
OpenSSH client requests these HostKeyAlgorithms combinations:

 * rsa-sha2-256
 * rsa-sha2-512
 * rsa-sha2-256,rsa-sha2-512
 * rsa-sha2-512,rsa-sha2-256

The tests demonstrate that the third combination currently fails:
libssh ends up choosing `rsa-sha2-512` instead of `rsa-sha2-256`,
and the initial exchange fails on the client side citing a signature
failure.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c2077ab775)
2019-02-07 14:22:58 +01:00
Jon Simons
a4948f6212 kex: honor client preference for rsa-sha2-{256,512} host key algorithms
Ensure to honor the client preference ordering when enabling one of
the RFC8332 RSA signature extensions (`rsa-sha2-{256,512}`).

Before this change, libssh unconditionally selects the `rsa-sha2-512`
algorithm for clients which may have offered "rsa-sha2-256,rsa-sha2-512".

The change can be observed before-and-after with the pkd tests:

    ./pkd_hello -t torture_pkd_openssh_rsa_rsa_sha2_256_512

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5d279a7ad7)
2019-02-07 14:22:30 +01:00
Jon Simons
e05e4ae971 pki_crypto: plug pki_signature_from_blob leaks
In 3341f49a49, some direct assignments
to OpenSSL structures was replaced with usage of getter and setter
macros.  Ensure to `bignum_safe_free` a couple of intermediate values
in error paths for `pki_signature_from_blob` DSS and ECDSA cases.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c0102e6a59)
2019-02-07 14:22:26 +01:00
Jon Simons
b6d275537e pki: NULL check pki_signature_from_rsa_blob result
Check for a potential NULL result from `pki_signature_from_rsa_blob`
in `pki_signature_from_blob`.  Otherwise the following `sig->type_c`
will result in a segfault.

Introduced in 7f83a1efae.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ccd73db90c)
2019-02-07 14:22:23 +01:00
Jakub Jelen
e69fb89e98 pki_container_openssh: Add padding to be compatible with OpenSSH
OpenSSH has a block size of 8 so we need to always add padding.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 128015bb17)
2019-02-07 13:53:03 +01:00
Andreas Schneider
f9beb3c690 gitlab-ci: Disable debian cross mips runner
This runner always times out.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fae1ed7ded)
2019-01-09 17:23:51 +01:00
Jakub Jelen
bfc39d578d kex: List also the SHA2 extension when ordering hostkey algorithms
By default, the list of already stored known host types is preferred,
but this selection so far ignored the SHA2 extension and excluded these
keys in the KEXINIT list leading to not using this extension if not
explicitly enabled from configuration.

This commit extends the default list with the SHA2 signatures algoritms
and compares only base types so they can be listed in the KEXINIT list.

This adjust the tests to expect the full list of algorithms to pass.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 531b80a60b)
2019-01-09 17:22:50 +01:00
Jakub Jelen
0acfd81f85 server: Correctly handle extensions
If the server had an RSA host key, it provided unconditionally SHA2
signatures without consulting the client proposed list of supported host
keys.

This commit implements more fine-grained detection of the extension
to provide the client with valid signatures according to RFC 8332
Section 3.1.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 27fe60954c)
2019-01-09 17:22:48 +01:00
Jakub Jelen
d028b2495d dh: Make sure we do not access uninitialized memory
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ca62632170)
2019-01-09 17:22:45 +01:00
Andreas Schneider
68fc17caac Bump version to 0.8.6
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-24 07:59:04 +01:00
Andreas Schneider
d327712739 Bump SO version to 4.7.3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-12-24 07:59:02 +01:00
Andreas Schneider
fded1fb9eb channels: Don't call ssh_channel_close() twice
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6cd8d4a24a)
2018-12-13 21:30:35 +01:00
Anderson Toshiyuki Sasaki
a6e055c42b packet: Allow SSH2_MSG_EXT_INFO when authenticated
When the server requests rekey, it can send the SSH2_MSG_EXT_INFO.  This
message was being filtered out by the packet filtering.  This includes a
test to enforce the filtering rules for this packet type.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fe309ba43f)
2018-12-10 17:50:27 +01:00
Andreas Schneider
32221ea9fb channels: Send close if we received a remote close
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c3067f8e73)
2018-12-10 17:50:22 +01:00
Andreas Schneider
917ba07478 channels: Reformat ssh_channel_free()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1d5b222cc4)
2018-12-10 17:50:19 +01:00
Andreas Schneider
bcdbc11732 channel: Add SSH_CHANNEL_FLAG_CLOSED_LOCAL
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 13b9d268d4)
2018-12-10 17:50:17 +01:00
Andreas Schneider
79289dc506 channel: Reformat ssh_channel_close()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0ba10870d1)
2018-12-10 17:50:14 +01:00
Andreas Schneider
45172a70fa sftp: Do not overwrite errors set by channel functions
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3784226fd8)
2018-11-30 18:57:39 +01:00
Anderson Toshiyuki Sasaki
7b0c80b475 tests: Test calling ssh_init() after ssh_finalize()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c413834764)
2018-11-30 18:57:39 +01:00
Anderson Toshiyuki Sasaki
d5bc9a1ace libcrypto: Fix access violation in ssh_init()
This fixes an access violation when ssh_init() was called after
ssh_finalize() in Windows when using OpenSSL 1.0.2 and libssh statically
linked.

Fixes T120

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 41b0d263d6)
2018-11-30 18:57:39 +01:00
Jakub Jelen
80d3e10b47 tests: Verify that signatures are sane and can not be verified by non-matching key
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 130256c348)
2018-11-30 18:57:39 +01:00
Jakub Jelen
455d495c74 pki: Sanitize input to verification
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b72c9eead6)
2018-11-30 18:57:39 +01:00
Jakub Jelen
b1bae1d90f pki: Return default RSA key type for DIGEST_AUTO
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c7628fbfea)
2018-11-30 18:57:39 +01:00
Jakub Jelen
ad4f1dbea0 pki: Verify the provided public key has expected type
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 783e5fd206)
2018-11-30 18:57:39 +01:00
Jakub Jelen
5ffe695c3c pki: Sanity-check signature matches base key type
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c79c33e224)
2018-11-30 18:57:39 +01:00
Jakub Jelen
230a437288 tests: Do not require base RSA type for SHA2 extension whitelist
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 968fdf4e18)
2018-11-30 18:57:38 +01:00
Jakub Jelen
1df272c3cc packet_cb: Properly verify the signature type
Issue reported by Tilo Eckert <tilo.eckert@flam.de>

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bc91fa98ea)
2018-11-30 18:57:38 +01:00
Jakub Jelen
c3a57fe2dc pki: Separate signature extraction and verification
Initial solution proposed by Tilo Eckert <tilo.eckert@flam.de>

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d2434c69c0)
2018-11-30 18:57:38 +01:00
Jakub Jelen
a238df2436 pki: Set correct type for imported signatures
Issue reported by Tilo Eckert <tilo.eckert@flam.de>

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7f83a1efae)
2018-11-30 18:57:38 +01:00
Jakub Jelen
f5e8fa5c5f pki: Use self-explanatory variable names
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7b725e6bc7)
2018-11-30 18:57:38 +01:00
Jakub Jelen
0a07266d9c The largest ECDSA key has 521 bits
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 46d8840f7e)
2018-11-30 18:57:38 +01:00
Jakub Jelen
953eae880f pki_gcrypt: Do not abort on bad signature
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c1fdb56d23)
2018-11-30 18:57:38 +01:00
Jakub Jelen
1d5215a5af server: Do not send SSH_MSG_EXT_INFO after rekey
This should not be a problem for well-behaving clients that do not
append the ext-info-c to the rekey, but if they do, we should not
send it either.

Resolves: T121

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:31:53 +01:00
Jakub Jelen
2d06a83b82 kex: Do not negotiate extensions during rekey
The RFC 8308 clearly says, that the additional  ext-info-c  should
be added only to the first SSH_MSG_KEXINIT.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:31:51 +01:00
Jakub Jelen
fd844cac6d tests: Verify setting NULL knownhosts does not crash
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:31:29 +01:00
Jakub Jelen
a106a00e0d options: Do not crash when setting knownhosts to NULL (T108)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-11-23 17:31:26 +01:00
Aris Adamantiadis
d8372c3063 gcrypt: Bugfix for very slow ecdh
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9546b20dec)
2018-11-21 16:55:19 +01:00
Tilo Eckert
946210534e socket: Add missing braces
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b227c12ad2)
2018-11-21 12:27:01 +01:00
Tilo Eckert
fe0331cf40 socket: Remove redundant code
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f369d02932)
2018-11-20 08:46:46 +01:00
Tilo Eckert
709c48eab6 socket: Fix potential buffer overrun
If nread is < 0 and no exception callback is set,
the following code block would cause a buffer overrun.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0b9e07fbdc)
2018-11-20 08:46:44 +01:00
Tilo Eckert
3d56bdae37 pki: Fix typos in documentation
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c47cdc0f97)
2018-11-20 08:46:43 +01:00
Tilo Eckert
8b4de1c477 packet: Fix timeout on hostkey type mismatch instead of proper error
If the hostkey type was not in the list of acceptable hostkey
types, the function failed to set the error state. Due to the
fact that the calling function ssh_packet_process() does not
handle the SSH_ERROR return code, the newkeys packet from the
server was silently ignored, stalling the connection until a
timeout occurred.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4b6eb05023)
2018-11-20 08:46:41 +01:00
Nicolas Viennot
906f63ba97 packets: Fix ssh_send_keepalive()
ssh_send_keepalive() should use global_request() to properly configure
the state machine for packet filtering.

Signed-off-by: Nicolas Viennot <nicolas@viennot.biz>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 59ada799d7)
2018-11-20 07:55:43 +01:00
Andreas Schneider
26ea4f059a COPYING: Reformat the last paragraph
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bb5d46c190)
2018-11-20 07:55:42 +01:00
Andreas Schneider
3b46198c42 tests: Fix chroot_wrapper location
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aa56b8ca53)
2018-11-15 16:36:21 +01:00
Sanne Raymaekers
3de34944ad tests: Ensure the ssh session fd is read-/writeable in torture_proxycommand
Signed-off-by: Sanne Raymaekers <sraymaek@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 03c30e9c8a)
2018-11-15 16:35:43 +01:00
Sanne Raymaekers
69cb3c5835 knownhosts: Take StrictHostKeyChecking option into account
Signed-off-by: Sanne Raymaekers <sraymaek@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 67f418218b)
2018-11-08 20:12:47 +01:00
Rosen Penev
5102b16cf1 crypto: Fix compilation for OpenSSL without deprecated APIs
Added missing bn.h include.

Made engine.h include conditional, otherwise it would fail.

DSA_generate_parameters was deprecated long before 1.1.0.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
(cherry picked from commit 61cac32288)
2018-11-08 09:32:42 +01:00
Christophe Giboudeaux
dc071dc6cf cmake: Refresh the CMake Config files
This commit fixes a couple issues in the CMake configuration files and uses
native features from CMake:

* libssh-build-tree-settings.cmake is deleted. There was a typo that made
this file unusable, anyway.
* use the macros available in CMakePackageConfigHelpers.cmake to generate
the version file and check that the files exist
* Remove the LIBSSH_THREADS_LIBRARY variable, it used the non-existent
  LIBSSH_THREADS_LIBRARY_NAME variable.
* Fix the in tree build. libssh can be used uninstalled again.

Test plan:
The values were tested after installing the new files and also without running
'make install'.

Signed-off-by: Christophe Giboudeaux <christophe@krop.fr>
(cherry picked from commit aa899f8ec0)
2018-11-06 14:02:33 +01:00
Jakub Jelen
a8d4fbaccb tests: Improve error reporting in auth test
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7e44ce1556)
2018-11-02 11:43:17 +01:00
Jakub Jelen
56b7d2da4d tests: Typo -- the flags should be checked according to the comment
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5fc4d5b22a)
2018-11-02 11:43:09 +01:00
Jakub Jelen
a4b99eedf2 knownhosts: Make sure we have both knownhosts files ready
If either one is missing at this point, fill it with default vaules in
ssh_options_apply().

Previously, when setting up only knownhosts, global_knownhosts file
was left pointing to NULL and the ssh_known_hosts_read_entries()
was trying to open NULL file which is invalid.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5159cd96e8)
2018-11-02 11:43:04 +01:00
Jakub Jelen
8a8498b586 client: Reformat comment
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 35c417312c)
2018-11-02 11:42:52 +01:00
Jakub Jelen
44b32e940e tests/pkd: Properly clean up memory
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e1a8b359c1)
2018-11-02 11:42:50 +01:00
Jakub Jelen
059079581a session: Drop unused structure member (SSHv1)
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c8519c435e)
2018-11-02 11:42:48 +01:00
Jakub Jelen
f11be32e11 misc: Properly check for errors returned from getpwuid_r()
Resolves: T118

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d85bc347d3)
2018-11-02 11:42:42 +01:00
Jakub Jelen
a9be4ab73e misc: Reformat ssh_get_user_home_dir and ssh_file_readaccess_ok
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9c4baa7fd5)
2018-11-02 11:42:39 +01:00
Andreas Schneider
273fb4cfc6 Bump version to 0.8.5
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-29 10:50:51 +01:00
Andreas Schneider
56f7c27852 Bump SO version to 4.7.2
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a4342b97d6)
2018-10-29 09:34:09 +01:00
Mike Frysinger
1285b37b60 doc: fix up various typos and trailing whitespace
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 963c3077a4)
2018-10-28 14:31:12 +01:00
Andreas Schneider
b7de358cdc libcrypto: Fix memory leak in evp_final()
Fixes T116

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

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

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

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

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

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

Resolves: T105

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

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

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

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

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

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

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

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fe618a35dc)
2018-10-19 14:05:05 +02:00
Andreas Schneider
4b886ac656 src: Fix typos
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 795389ae1b)
2018-10-19 14:05:02 +02:00
93 changed files with 4546 additions and 1146 deletions

View File

@@ -4,7 +4,6 @@ variables:
CENTOS7_BUILD: buildenv-centos7
TUMBLEWEED_BUILD: buildenv-tumbleweed
MINGW_BUILD: buildenv-mingw
DEBIAN_CROSS_BUILD: buildenv-debian-cross
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
centos7/openssl_1.0.x/x86-64:
@@ -333,29 +332,3 @@ mingw32:
when: on_failure
paths:
- obj/
.Debian.cross.template: &Debian_cross_template
stage: test
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_CROSS_BUILD
script:
- build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE)
- host="${CI_JOB_NAME#*.cross.}"
- mkdir -p obj && cd obj && cmake
-DCMAKE_C_COMPILER="$(which $host-gcc)"
-DCMAKE_CXX_COMPILER="$(which $host-g++)"
-DCMAKE_BUILD_TYPE=Debug
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
-DWITH_PCAP=ON .. && make -j$(nproc)
- ctest --output-on-failure -j$(nproc)
tags:
- shared
except:
- tags
artifacts:
expire_in: 1 week
when: on_failure
paths:
- obj/
Debian.cross.mips-linux-gnu:
<<: *Debian_cross_template

View File

@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.8.4 LANGUAGES C)
project(libssh VERSION 0.8.9 LANGUAGES C)
# global needed variable
set(APPLICATION_NAME ${PROJECT_NAME})
@@ -22,7 +22,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.7.1")
set(LIBRARY_VERSION "4.7.6")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
@@ -39,6 +39,9 @@ include(CompilerChecks.cmake)
include(MacroEnsureOutOfSourceBuild)
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
# Copy library files to a lib sub-directory
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
# search for libraries
if (WITH_ZLIB)
find_package(ZLIB REQUIRED)
@@ -116,11 +119,22 @@ install(
)
endif (UNIX)
# cmake config files
# CMake config files
include(CMakePackageConfigHelpers)
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
# libssh-config-version.cmake
write_basic_package_version_file(libssh-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
# libssh-config.cmake
configure_package_config_file(${PROJECT_NAME}-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
@@ -131,10 +145,6 @@ install(
devel
)
# in tree build settings
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
if (WITH_EXAMPLES)
add_subdirectory(examples)
endif (WITH_EXAMPLES)

13
COPYING
View File

@@ -455,6 +455,15 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
Linking with OpenSSL
17. In addition, as a special exception, we give permission to link the code of its release of libssh with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Lesser General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
Linking with OpenSSL
17. In addition, as a special exception, we give permission to link the code
of its release of libssh with the OpenSSL project's "OpenSSL" library (or with
modified versions of it that use the same license as the "OpenSSL" library),
and distribute the linked executables. You must obey the GNU Lesser General
Public License in all respects for all of the code used other than "OpenSSL".
If you modify this file, you may extend this exception to your version of the
file, but you are not obligated to do so. If you do not wish to do so, delete
this exception statement from your version.
END OF TERMS AND CONDITIONS

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$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;/[.]clangd/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
### NSIS INSTALLER

View File

@@ -1,6 +1,41 @@
ChangeLog
==========
version 0.8.9 (released 2020-04-09)
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
AES-CTR keys with OpenSSL
version 0.8.8 (released 2019-12-10)
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
version 0.8.7 (released 2019-02-25)
* Fixed handling extension flags in the server implementation
* Fixed exporting ed25519 private keys
* Fixed corner cases for rsa-sha2 signatures
* Fixed some issues with connector
version 0.8.6 (released 2018-12-24)
* Fixed compilation issues with different OpenSSL versions
* Fixed StrictHostKeyChecking in new knownhosts API
* Fixed ssh_send_keepalive() with packet filter
* Fixed possible crash with knownhosts options
* Fixed issus with rekeying
* Fixed strong ECDSA keys
* Fixed some issues with rsa-sha2 extentions
* Fixed access violation in ssh_init() (static linking)
* Fixed ssh_channel_close() handling
version 0.8.5 (released 2018-10-29)
* Added support to get known_hosts locations with ssh_options_get()
* Fixed preferred algorithm for known hosts negotiations
* Fixed KEX with some server implementations (e.g. Cisco)
* Fixed issues with MSVC
* Fixed keyboard-interactive auth in server mode
(regression from CVE-2018-10933)
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
* Fixed socket fd handling with proxy command
* Fixed a memory leak with OpenSSL
version 0.8.4 (released 2018-10-16)
* Fixed CVE-2018-10933
* Fixed building without globbing support

View File

@@ -127,7 +127,7 @@ The keyboard-interactive method is, as its name tells, interactive. The
server will issue one or more challenges that the user has to answer,
until the server takes an authentication decision.
ssh_userauth_kbdint() is the the main keyboard-interactive function.
ssh_userauth_kbdint() is the the main keyboard-interactive function.
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
@@ -154,9 +154,9 @@ Here are a few remarks:
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
- The server can send an empty question set (this is the default behavior
on my system) after you have sent the answers to the first questions.
You must still parse the answer, it might contain some
You must still parse the answer, it might contain some
message from the server saying hello or such things. Just call
ssh_userauth_kbdint() until needed.
ssh_userauth_kbdint() until needed.
- The meaning of "name", "prompt", "instruction" may be a little
confusing. An explanation is given in the RFC section that follows.
@@ -187,7 +187,7 @@ keyboard-interactive authentication, coming from the RFC itself (rfc4256):
the name and prompts. If the server presents names or prompts longer than 30
characters, the client MAY truncate these fields to the length it can
display. If the client does truncate any fields, there MUST be an obvious
indication that such truncation has occured.
indication that such truncation has occurred.
The instruction field SHOULD NOT be truncated. Clients SHOULD use control
character filtering as discussed in [SSH-ARCH] to avoid attacks by

View File

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

View File

@@ -31,20 +31,20 @@ A SSH session goes through the following steps:
- Invoke your own subsystem. This is outside the scope of this document,
but can be done.
- When everything is finished, just close the channels, and then the connection.
- When everything is finished, just close the channels, and then the connection.
The sftp and scp subsystems use channels, but libssh hides them to
the programmer. If you want to use those subsystems, instead of a channel,
you'll usually open a "sftp session" or a "scp session".
@subsection setup Creating the session and setting options
The most important object in a SSH connection is the SSH session. In order
to allocate a new SSH session, you use ssh_new(). Don't forget to
always verify that the allocation successed.
always verify that the allocation succeeded.
@code
#include <libssh/libssh.h>
#include <libssh/libssh.h>
#include <stdlib.h>
int main()
@@ -69,12 +69,12 @@ The ssh_options_set() function sets the options of the session. The most importa
The complete list of options can be found in the documentation of ssh_options_set().
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
the local username of your account will be used.
the local username of your account will be used.
Here is a small example of how to use it:
@code
#include <libssh/libssh.h>
#include <libssh/libssh.h>
#include <stdlib.h>
int main()
@@ -122,7 +122,7 @@ Here's an example:
@code
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
int main()
{
@@ -285,9 +285,9 @@ int verify_knownhost(ssh_session session)
The authentication process is the way a service provider can identify a
user and verify his/her identity. The authorization process is about enabling
the authenticated user the access to ressources. In SSH, the two concepts
the authenticated user the access to resources. In SSH, the two concepts
are linked. After authentication, the server can grant the user access to
several ressources such as port forwarding, shell, sftp subsystem, and so on.
several resources such as port forwarding, shell, sftp subsystem, and so on.
libssh supports several methods of authentication:
- "none" method. This method allows to get the available authentications
@@ -313,7 +313,7 @@ The example below shows an authentication with password:
@code
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
int main()
{
@@ -338,7 +338,7 @@ int main()
}
// Verify the server's identity
// For the source code of verify_knowhost(), check previous example
// For the source code of verify_knownhost(), check previous example
if (verify_knownhost(my_ssh_session) < 0)
{
ssh_disconnect(my_ssh_session);
@@ -415,7 +415,7 @@ int show_remote_processes(ssh_session session)
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0)
{
ssh_channel_close(channel);
@@ -456,7 +456,7 @@ might be recoverable. SSH_FATAL means the connection has an important
problem and isn't probably recoverable.
Most of time, the error returned are SSH_FATAL, but some functions
(generaly the ssh_request_xxx ones) may fail because of server denying request.
(generally the ssh_request_xxx ones) may fail because of server denying request.
In these cases, SSH_REQUEST_DENIED is returned.
For thread safety, errors are bound to ssh_session objects.

View File

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

View File

@@ -27,4 +27,7 @@ the dllimport attribute.
#include <libssh/libssh.h>
@endcode
If you're are statically linking with OpenSSL, read the "Linking your
application" section in the NOTES.<OS> in the OpenSSL source tree!
*/

View File

@@ -23,7 +23,7 @@ The libssh library provides:
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256,ssh-dss
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512, hmac-md5, none
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5, none
- <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip

View File

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

View File

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

View File

@@ -209,7 +209,7 @@ int interactive_shell_session(ssh_channel channel)
Of course, this is a poor terminal emulator, since the echo from the keys
pressed should not be done locally, but should be done by the remote side.
Also, user's input should not be sent once "Enter" key is pressed, but
Also, user's input should not be sent once "Enter" key is pressed, but
immediately after each key is pressed. This can be accomplished
by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
cfmakeraw() is a standard function under Linux, on other systems you can
@@ -245,13 +245,13 @@ provide a more elegant way to wait for data coming from many sources.
The functions ssh_select() and ssh_channel_select() remind of the standard
UNIX select(2) function. The idea is to wait for "something" to happen:
incoming data to be read, outcoming data to block, or an exception to
incoming data to be read, outgoing data to block, or an exception to
occur. Both these functions do a "passive wait", i.e. you can safely use
them repeatedly in a loop, it will not consume exaggerate processor time
and make your computer unresponsive. It is quite common to use these
functions in your application's main loop.
The difference between ssh_select() and ssh_channel_select() is that
The difference between ssh_select() and ssh_channel_select() is that
ssh_channel_select() is simpler, but allows you only to watch SSH channels.
ssh_select() is more complete and enables watching regular file descriptors
as well, in the same function call.

View File

@@ -11,10 +11,10 @@ libssh may be used in multithreaded applications, but under several conditions :
- If libssh is statically linked, threading must be initialized by calling
ssh_init() before using any of libssh provided functions. This initialization
must be done outside of any threading context. Don't forget to call
ssh_finalize() to avoid memory leak
ssh_finalize() to avoid memory leak
- At all times, you may use different sessions inside threads, make parallel
connections, read/write on different sessions and so on. You *cannot* use a
single session (or channels for a single session) in several threads at the same
single session (or channels for a single session) in several threads at the same
time. This will most likely lead to internal state corruption. This limitation is
being worked out and will maybe disappear later.

View File

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

View File

@@ -48,11 +48,16 @@ enum ssh_channel_state_e {
};
/* The channel has been closed by the remote side */
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x1
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x0001
/* The channel has been closed locally */
#define SSH_CHANNEL_FLAG_CLOSED_LOCAL 0x0002
/* The channel has been freed by the calling program */
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x2
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x0004
/* the channel has not yet been bound to a remote one */
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x4
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x0008
struct ssh_channel_struct {
ssh_session session; /* SSH_SESSION pointer */
@@ -98,5 +103,9 @@ int ssh_channel_flush(ssh_channel channel);
uint32_t ssh_channel_new_id(ssh_session session);
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
void ssh_channel_do_free(ssh_channel channel);
int ssh_global_request(ssh_session session,
const char *request,
ssh_buffer buffer,
int reply);
#endif /* CHANNELS_H_ */

View File

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

View File

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

View File

@@ -79,7 +79,7 @@
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 8
#define LIBSSH_VERSION_MICRO 4
#define LIBSSH_VERSION_MICRO 8
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \

View File

@@ -50,6 +50,12 @@ struct ssh_timestamp {
long useconds;
};
enum ssh_quote_state_e {
NO_QUOTE,
SINGLE_QUOTE,
DOUBLE_QUOTE
};
struct ssh_list *ssh_list_new(void);
void ssh_list_free(struct ssh_list *list);
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
@@ -81,4 +87,6 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
int ssh_match_group(const char *group, const char *object);
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
#endif /* MISC_H_ */

View File

@@ -110,11 +110,11 @@ int ssh_pki_export_signature_blob(const ssh_signature sign,
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
const ssh_key pubkey,
ssh_signature *psig);
int ssh_pki_signature_verify_blob(ssh_session session,
ssh_string sig_blob,
const ssh_key key,
unsigned char *digest,
size_t dlen);
int ssh_pki_signature_verify(ssh_session session,
ssh_signature sig,
const ssh_key key,
unsigned char *digest,
size_t dlen);
/* SSH Public Key Functions */
int ssh_pki_export_pubkey_blob(const ssh_key key,

View File

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

View File

@@ -87,10 +87,11 @@ enum ssh_pending_call_e {
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
/* extensions flags */
/* negotiation enabled */
#define SSH_EXT_NEGOTIATION 0x01
/* server-sig-algs extension */
#define SSH_EXT_SIG_RSA_SHA256 0x01
#define SSH_EXT_SIG_RSA_SHA512 0x02
#define SSH_EXT_ALL SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512
#define SSH_EXT_SIG_RSA_SHA256 0x02
#define SSH_EXT_SIG_RSA_SHA512 0x04
/* members that are common to ssh_session and ssh_bind */
struct ssh_common_struct {
@@ -164,8 +165,6 @@ struct ssh_session_struct {
struct ssh_list *channels; /* linked list of channels */
int maxchannel;
int exec_channel_opened; /* version 1 only. more
info in channels1.c */
ssh_agent agent; /* ssh agent */
/* keyb interactive data */

View File

@@ -53,9 +53,14 @@ extern "C" {
typedef uint32_t gid_t;
#endif /* gid_t */
#ifdef _MSC_VER
#ifndef ssize_t
typedef _W64 SSIZE_T ssize_t;
#endif /* ssize_t */
# ifndef _SSIZE_T_DEFINED
# undef ssize_t
# include <BaseTsd.h>
typedef _W64 SSIZE_T ssize_t;
# define _SSIZE_T_DEFINED
# endif /* _SSIZE_T_DEFINED */
#endif /* _MSC_VER */
#endif /* _WIN32 */
@@ -813,7 +818,9 @@ LIBSSH_API int sftp_fsync(sftp_file file);
*
* @param path The path to be canonicalized.
*
* @return The canonicalize path, NULL on error.
* @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_canonicalize_path(sftp_session sftp, const char *path);

View File

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

View File

@@ -44,7 +44,6 @@ enum ssh_mac_e {
enum ssh_hmac_e {
SSH_HMAC_SHA1 = 1,
SSH_HMAC_SHA256,
SSH_HMAC_SHA384,
SSH_HMAC_SHA512,
SSH_HMAC_MD5,
SSH_HMAC_AEAD_POLY1305

View File

@@ -1 +0,0 @@
set(LIBSSH_INLUDE_DIR @PROJECT_SOURCE_DIR@/include)

View File

@@ -1,11 +0,0 @@
set(PACKAGE_VERSION @PROJECT_VERSION@)
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()

View File

@@ -1,15 +1,15 @@
get_filename_component(LIBSSH_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
@PACKAGE_INIT@
if (EXISTS "${LIBSSH_CMAKE_DIR}/CMakeCache.txt")
# In build tree
include(${LIBSSH_CMAKE_DIR}/libssh-build-tree-settings.cmake)
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/CMakeCache.txt")
# In tree build
set_and_check(LIBSSH_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
set_and_check(LIBSSH_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/@LIBSSH_LIBRARY_NAME@")
else()
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
set_and_check(LIBSSH_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(LIBSSH_LIBRARIES "@PACKAGE_LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@")
endif()
set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
# For backward compatibility
set(LIBSSH_LIBRARY ${LIBSSH_LIBRARIES})
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@)
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_INCLUDE_DIR)
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_LIBRARY LIBSSH_INCLUDE_DIR)

View File

@@ -1 +1 @@
4.7.1
4.7.6

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -28,6 +28,7 @@
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <stdbool.h>
#ifndef _WIN32
#include <netinet/in.h>
@@ -999,28 +1000,50 @@ error:
*
* @warning Any data unread on this channel will be lost.
*/
void ssh_channel_free(ssh_channel channel) {
ssh_session session;
void ssh_channel_free(ssh_channel channel)
{
ssh_session session;
if (channel == NULL) {
return;
}
if (channel == NULL) {
return;
}
session = channel->session;
if (session->alive && channel->state == SSH_CHANNEL_STATE_OPEN) {
ssh_channel_close(channel);
}
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
session = channel->session;
if (session->alive) {
bool send_close = false;
/* The idea behind the flags is the following : it is well possible
* that a client closes a channel that stills exists on the server side.
* We definitively close the channel when we receive a close message *and*
* the user closed it.
*/
if((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE)
|| (channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)){
ssh_channel_do_free(channel);
}
switch (channel->state) {
case SSH_CHANNEL_STATE_OPEN:
send_close = true;
break;
case SSH_CHANNEL_STATE_CLOSED:
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) {
send_close = true;
}
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
send_close = false;
}
break;
default:
send_close = false;
break;
}
if (send_close) {
ssh_channel_close(channel);
}
}
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
/* The idea behind the flags is the following : it is well possible
* that a client closes a channel that stills exists on the server side.
* We definitively close the channel when we receive a close message *and*
* the user closed it.
*/
if ((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) ||
(channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)) {
ssh_channel_do_free(channel);
}
}
/**
@@ -1128,52 +1151,60 @@ error:
* @see ssh_channel_free()
* @see ssh_channel_is_eof()
*/
int ssh_channel_close(ssh_channel channel){
ssh_session session;
int rc = 0;
int ssh_channel_close(ssh_channel channel)
{
ssh_session session;
int rc = 0;
if(channel == NULL) {
return SSH_ERROR;
}
if(channel == NULL) {
return SSH_ERROR;
}
session = channel->session;
/* If the channel close has already been sent we're done here. */
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
return SSH_OK;
}
if (channel->local_eof == 0) {
rc = ssh_channel_send_eof(channel);
}
session = channel->session;
if (channel->local_eof == 0) {
rc = ssh_channel_send_eof(channel);
}
if (rc != SSH_OK) {
return rc;
}
rc = ssh_buffer_pack(session->out_buffer,
"bd",
SSH2_MSG_CHANNEL_CLOSE,
channel->remote_channel);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET,
"Sent a close on client channel (%d:%d)",
channel->local_channel,
channel->remote_channel);
if (rc == SSH_OK) {
channel->state = SSH_CHANNEL_STATE_CLOSED;
channel->flags |= SSH_CHANNEL_FLAG_CLOSED_LOCAL;
}
rc = ssh_channel_flush(channel);
if(rc == SSH_ERROR) {
goto error;
}
if (rc != SSH_OK) {
return rc;
}
rc = ssh_buffer_pack(session->out_buffer,
"bd",
SSH2_MSG_CHANNEL_CLOSE,
channel->remote_channel);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
}
rc = ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET,
"Sent a close on client channel (%d:%d)",
channel->local_channel,
channel->remote_channel);
if(rc == SSH_OK) {
channel->state=SSH_CHANNEL_STATE_CLOSED;
}
rc = ssh_channel_flush(channel);
if(rc == SSH_ERROR)
goto error;
return rc;
error:
ssh_buffer_reinit(session->out_buffer);
ssh_buffer_reinit(session->out_buffer);
return rc;
return rc;
}
/* this termination function waits for a window growing condition */
@@ -2082,8 +2113,11 @@ static int ssh_global_request_termination(void *s){
* SSH_AGAIN if in nonblocking mode and call has
* to be done again.
*/
static int global_request(ssh_session session, const char *request,
ssh_buffer buffer, int reply) {
int ssh_global_request(ssh_session session,
const char *request,
ssh_buffer buffer,
int reply)
{
int rc;
switch (session->global_req_state) {
@@ -2214,7 +2248,7 @@ int ssh_channel_listen_forward(ssh_session session,
goto error;
}
pending:
rc = global_request(session, "tcpip-forward", buffer, 1);
rc = ssh_global_request(session, "tcpip-forward", buffer, 1);
/* TODO: FIXME no guarantee the last packet we received contains
* that info */
@@ -2294,7 +2328,7 @@ int ssh_channel_cancel_forward(ssh_session session,
goto error;
}
pending:
rc = global_request(session, "cancel-tcpip-forward", buffer, 1);
rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
error:
ssh_buffer_free(buffer);

View File

@@ -411,6 +411,14 @@ static void ssh_client_connection_callback(ssh_session session)
ssh_packet_set_default_callbacks(session);
session->session_state = SSH_SESSION_STATE_INITIAL_KEX;
rc = ssh_set_client_kex(session);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_send_kex(session, 0);
if (rc < 0) {
goto error;
}
set_status(session, 0.5f);
break;
@@ -420,14 +428,19 @@ static void ssh_client_connection_callback(ssh_session session)
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
set_status(session,0.6f);
ssh_list_kex(&session->next_crypto->server_kex);
if (ssh_set_client_kex(session) < 0) {
goto error;
if (session->next_crypto->client_kex.methods[0] == NULL) {
/* in rekeying state if next_crypto client_kex is empty */
rc = ssh_set_client_kex(session);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_send_kex(session, 0);
if (rc < 0) {
goto error;
}
}
if (ssh_kex_select_methods(session) == SSH_ERROR)
goto error;
if (ssh_send_kex(session, 0) < 0) {
goto error;
}
set_status(session,0.8f);
session->session_state=SSH_SESSION_STATE_DH;
if (dh_handshake(session) == SSH_ERROR) {
@@ -481,8 +494,8 @@ static int ssh_connect_termination(void *user){
* @param[in] session The ssh session to connect.
*
* @returns SSH_OK on success, SSH_ERROR on error.
* @returns SSH_AGAIN, if the session is in nonblocking mode,
* and call must be done again.
* @returns SSH_AGAIN, if the session is in nonblocking mode,
* and call must be done again.
*
* @see ssh_new()
* @see ssh_disconnect()

View File

@@ -210,6 +210,7 @@ static struct ssh_config_match_keyword_table_s ssh_config_match_keyword_table[]
{ "originalhost", MATCH_ORIGINALHOST },
{ "user", MATCH_USER },
{ "localuser", MATCH_LOCALUSER },
{ NULL, MATCH_UNKNOWN },
};
static int ssh_config_parse_line(ssh_session session, const char *line,

View File

@@ -476,7 +476,7 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout) {
fd_set origfds;
socket_t fd;
int i,j;
size_t i, j;
int rc;
int base_tm, tm;
struct ssh_timestamp ts;

View File

@@ -641,14 +641,12 @@ int ssh_connector_remove_event(ssh_connector connector) {
session = ssh_channel_get_session(connector->in_channel);
ssh_event_remove_session(connector->event, session);
connector->in_channel = NULL;
}
if (connector->out_channel != NULL) {
session = ssh_channel_get_session(connector->out_channel);
ssh_event_remove_session(connector->event, session);
connector->out_channel = NULL;
}
connector->event = NULL;

View File

@@ -1274,6 +1274,10 @@ int ssh_get_server_publickey(ssh_session session, ssh_key *key)
ssh_key ssh_dh_get_current_server_publickey(ssh_session session)
{
if (session->current_crypto == NULL) {
return NULL;
}
return session->current_crypto->server_pubkey;
}

View File

@@ -286,7 +286,7 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet) {
session->next_crypto->ecdh_client_pubkey = q_c_string;
/* Build server's keypair */
err = gcry_sexp_build(&param, NULL, "(genkey(ecdh(curve %s)))",
err = gcry_sexp_build(&param, NULL, "(genkey(ecdh(curve %s) (flags transient-key)))",
curve);
if (err) {
goto out;

View File

@@ -120,6 +120,7 @@ static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
ssh_set_error_oom(session);
return SSH_ERROR;
}
session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN;
ssh_packet_send(session);
SSH_LOG(SSH_LOG_PACKET,

126
src/kex.c
View File

@@ -26,6 +26,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "libssh/priv.h"
#include "libssh/buffer.h"
@@ -37,6 +38,7 @@
#include "libssh/curve25519.h"
#include "libssh/knownhosts.h"
#include "libssh/misc.h"
#include "libssh/pki.h"
#ifdef HAVE_LIBGCRYPT
# define BLOWFISH "blowfish-cbc,"
@@ -419,6 +421,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
int server_kex=session->server;
ssh_string str = NULL;
char *strings[KEX_METHODS_SIZE] = {0};
char *rsa_sig_ext = NULL;
int rc = SSH_ERROR;
uint8_t first_kex_packet_follows = 0;
@@ -525,13 +528,52 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
ok = ssh_match_group(session->next_crypto->client_kex.methods[SSH_KEX],
KEX_EXTENSION_CLIENT);
if (ok) {
const char *hostkeys = NULL;
/* The client supports extension negotiation */
session->extensions |= SSH_EXT_NEGOTIATION;
/*
* Enable all the supported extensions and when the time comes
* (after NEWKEYS) send them to the client.
* RFC 8332 Section 3.1: Use for Server Authentication
* Check what algorithms were provided in the SSH_HOSTKEYS list
* by the client and enable the respective extensions to provide
* correct signature in the next packet if RSA is negotiated
*/
hostkeys = session->next_crypto->client_kex.methods[SSH_HOSTKEYS];
ok = ssh_match_group(hostkeys, "rsa-sha2-512");
if (ok) {
session->extensions |= SSH_EXT_SIG_RSA_SHA512;
}
ok = ssh_match_group(hostkeys, "rsa-sha2-256");
if (ok) {
session->extensions |= SSH_EXT_SIG_RSA_SHA256;
}
/*
* Ensure that the client preference is honored for the case
* both signature types are enabled.
*/
if ((session->extensions & SSH_EXT_SIG_RSA_SHA256) &&
(session->extensions & SSH_EXT_SIG_RSA_SHA512)) {
session->extensions &= ~(SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512);
rsa_sig_ext = ssh_find_matching("rsa-sha2-512,rsa-sha2-256",
session->next_crypto->client_kex.methods[SSH_HOSTKEYS]);
if (rsa_sig_ext == NULL) {
goto error; /* should never happen */
} else if (strcmp(rsa_sig_ext, "rsa-sha2-512") == 0) {
session->extensions |= SSH_EXT_SIG_RSA_SHA512;
} else if (strcmp(rsa_sig_ext, "rsa-sha2-256") == 0) {
session->extensions |= SSH_EXT_SIG_RSA_SHA256;
} else {
SAFE_FREE(rsa_sig_ext);
goto error; /* should never happen */
}
SAFE_FREE(rsa_sig_ext);
}
SSH_LOG(SSH_LOG_DEBUG, "The client supports extension "
"negotiation: enabling all extensions");
session->extensions = SSH_EXT_ALL;
"negotiation. Enabled signature algorithms: %s%s",
session->extensions & SSH_EXT_SIG_RSA_SHA256 ? "SHA256" : "",
session->extensions & SSH_EXT_SIG_RSA_SHA512 ? " SHA512" : "");
}
/*
@@ -592,14 +634,18 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
* @returns a cstring containing a comma-separated list of hostkey methods.
* NULL if no method matches
*/
static char *ssh_client_select_hostkeys(ssh_session session)
char *ssh_client_select_hostkeys(ssh_session session)
{
char methods_buffer[128]={0};
char tail_buffer[128]={0};
char *new_hostkeys = NULL;
static const char *preferred_hostkeys[] = {
"ssh-ed25519",
"ecdsa-sha2-nistp521",
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp256",
"rsa-sha2-512",
"rsa-sha2-256",
"ssh-rsa",
#ifdef HAVE_DSA
"ssh-dss",
@@ -610,7 +656,7 @@ static char *ssh_client_select_hostkeys(ssh_session session)
struct ssh_iterator *it = NULL;
size_t algo_count;
int needcomma = 0;
int i;
size_t i, len;
algo_list = ssh_known_hosts_get_algorithms(session);
if (algo_list == NULL) {
@@ -624,30 +670,41 @@ static char *ssh_client_select_hostkeys(ssh_session session)
}
for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
bool found = false;
/* This is a signature type: We list also the SHA2 extensions */
enum ssh_keytypes_e base_preferred =
ssh_key_type_from_signature_name(preferred_hostkeys[i]);
for (it = ssh_list_get_iterator(algo_list);
it != NULL;
it = ssh_list_get_iterator(algo_list)) {
it = it->next) {
const char *algo = ssh_iterator_value(const char *, it);
int cmp;
int ok;
/* This is always key type so we do not have to care for the
* SHA2 extension */
enum ssh_keytypes_e base_algo = ssh_key_type_from_name(algo);
cmp = strcmp(preferred_hostkeys[i], algo);
if (cmp == 0) {
ok = ssh_verify_existing_algo(SSH_HOSTKEYS, algo);
if (ok) {
if (needcomma) {
strncat(methods_buffer,
",",
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
}
if (base_preferred == base_algo) {
/* Matching the keys already verified it is a known type */
if (needcomma) {
strncat(methods_buffer,
algo,
",",
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
needcomma = 1;
}
strncat(methods_buffer,
preferred_hostkeys[i],
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
needcomma = 1;
found = true;
}
ssh_list_remove(algo_list, it);
}
/* Collect the rest of the algorithms in other buffer, that will
* follow the preferred buffer. This will signalize all the algorithms
* we are willing to accept.
*/
if (!found) {
snprintf(tail_buffer + strlen(tail_buffer),
sizeof(tail_buffer) - strlen(tail_buffer),
",%s", preferred_hostkeys[i]);
}
}
ssh_list_free(algo_list);
@@ -658,11 +715,23 @@ static char *ssh_client_select_hostkeys(ssh_session session)
return NULL;
}
/* Append the supported list to the preferred.
* The length is maximum 128 + 128 + 1, which will not overflow
*/
len = strlen(methods_buffer) + strlen(tail_buffer) + 1;
new_hostkeys = malloc(len);
if (new_hostkeys == NULL) {
ssh_set_error_oom(session);
return NULL;
}
snprintf(new_hostkeys, len,
"%s%s", methods_buffer, tail_buffer);
SSH_LOG(SSH_LOG_DEBUG,
"Changing host key method to \"%s\"",
methods_buffer);
new_hostkeys);
return strdup(methods_buffer);
return new_hostkeys;
}
/**
@@ -687,10 +756,10 @@ int ssh_set_client_kex(ssh_session session)
memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
/* first check if we have specific host key methods */
if(session->opts.wanted_methods[SSH_HOSTKEYS] == NULL){
if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) {
/* Only if no override */
session->opts.wanted_methods[SSH_HOSTKEYS] =
ssh_client_select_hostkeys(session);
ssh_client_select_hostkeys(session);
}
for (i = 0; i < KEX_METHODS_SIZE; i++) {
@@ -704,6 +773,11 @@ int ssh_set_client_kex(ssh_session session)
}
}
/* For rekeying, skip the extension negotiation */
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED) {
return SSH_OK;
}
/* Here we append ext-info-c to the list of kex algorithms */
kex = client->methods[SSH_KEX];
len = strlen(kex);

View File

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

View File

@@ -10,9 +10,12 @@
#include "config.h"
#include <string.h>
#include <openssl/engine.h>
#include "libcrypto-compat.h"
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
static void *OPENSSL_zalloc(size_t num)
{
void *ret = OPENSSL_malloc(num);

View File

@@ -10,6 +10,7 @@
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);

View File

@@ -43,6 +43,7 @@
#include <openssl/hmac.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
#include "libcrypto-compat.h"
#ifdef HAVE_OPENSSL_AES_H
@@ -54,6 +55,10 @@
#include <openssl/des.h>
#endif
#ifdef HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT
#include <openssl/modes.h>
#endif
#if (OPENSSL_VERSION_NUMBER<0x00907000L)
#define OLD_CRYPTO
#endif
@@ -196,6 +201,7 @@ void evp_update(EVPCTX ctx, const void *data, unsigned long len)
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
{
EVP_DigestFinal(ctx, md, mdlen);
EVP_MD_CTX_free(ctx);
}
#endif
@@ -426,9 +432,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
case SSH_HMAC_SHA256:
HMAC_Init_ex(ctx, key, len, EVP_sha256(), NULL);
break;
case SSH_HMAC_SHA384:
HMAC_Init_ex(ctx, key, len, EVP_sha384(), NULL);
break;
case SSH_HMAC_SHA512:
HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
break;
@@ -638,8 +641,12 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou
}
static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
SAFE_FREE(cipher->aes_key);
if (cipher != NULL) {
if (cipher->aes_key != NULL) {
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
}
SAFE_FREE(cipher->aes_key);
}
}
#endif /* HAVE_OPENSSL_EVP_AES_CTR */

View File

@@ -282,9 +282,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
case SSH_HMAC_SHA256:
gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
break;
case SSH_HMAC_SHA384:
gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);
break;
case SSH_HMAC_SHA512:
gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
break;

View File

@@ -462,9 +462,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type)
case SSH_HMAC_SHA256:
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
break;
case SSH_HMAC_SHA384:
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
break;
case SSH_HMAC_SHA512:
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
break;

View File

@@ -702,8 +702,10 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
*/
SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
ssh_message msg = NULL;
ssh_signature sig = NULL;
char *service = NULL;
char *method = NULL;
int cmp;
int rc;
(void)user;
@@ -730,6 +732,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
service, method,
msg->auth_request.username);
cmp = strcmp(service, "ssh-connection");
if (cmp != 0) {
SSH_LOG(SSH_LOG_WARNING,
"Invalid service request: %s",
service);
goto end;
}
if (strcmp(method, "none") == 0) {
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
@@ -827,13 +836,19 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
goto error;
}
rc = ssh_pki_signature_verify_blob(session,
sig_blob,
rc = ssh_pki_import_signature_blob(sig_blob,
msg->auth_request.pubkey,
ssh_buffer_get(digest),
ssh_buffer_get_len(digest));
&sig);
if (rc == SSH_OK) {
rc = ssh_pki_signature_verify(session,
sig,
msg->auth_request.pubkey,
ssh_buffer_get(digest),
ssh_buffer_get_len(digest));
}
ssh_string_free(sig_blob);
ssh_buffer_free(digest);
ssh_signature_free(sig);
if (rc < 0) {
SSH_LOG(
SSH_LOG_PACKET,

View File

@@ -213,47 +213,50 @@ int ssh_is_ipaddr(const char *str) {
#define NSS_BUFLEN_PASSWD 4096
#endif /* NSS_BUFLEN_PASSWD */
char *ssh_get_user_home_dir(void) {
char *szPath = NULL;
struct passwd pwd;
struct passwd *pwdbuf;
char buf[NSS_BUFLEN_PASSWD] = {0};
int rc;
char *ssh_get_user_home_dir(void)
{
char *szPath = NULL;
struct passwd pwd;
struct passwd *pwdbuf = NULL;
char buf[NSS_BUFLEN_PASSWD] = {0};
int rc;
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
if (rc != 0) {
szPath = getenv("HOME");
if (szPath == NULL) {
return NULL;
}
snprintf(buf, sizeof(buf), "%s", szPath);
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
if (rc != 0 || pwdbuf == NULL ) {
szPath = getenv("HOME");
if (szPath == NULL) {
return NULL;
}
snprintf(buf, sizeof(buf), "%s", szPath);
return strdup(buf);
}
return strdup(buf);
}
szPath = strdup(pwd.pw_dir);
szPath = strdup(pwd.pw_dir);
return szPath;
return szPath;
}
/* we have read access on file */
int ssh_file_readaccess_ok(const char *file) {
if (access(file, R_OK) < 0) {
return 0;
}
int ssh_file_readaccess_ok(const char *file)
{
if (access(file, R_OK) < 0) {
return 0;
}
return 1;
return 1;
}
char *ssh_get_local_username(void) {
char *ssh_get_local_username(void)
{
struct passwd pwd;
struct passwd *pwdbuf;
struct passwd *pwdbuf = NULL;
char buf[NSS_BUFLEN_PASSWD];
char *name;
int rc;
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
if (rc != 0) {
if (rc != 0 || pwdbuf == NULL) {
return NULL;
}
@@ -1105,4 +1108,188 @@ char *strndup(const char *s, size_t n)
}
#endif /* ! HAVE_STRNDUP */
/**
* @internal
*
* @brief Quote file name to be used on shell.
*
* Try to put the given file name between single quotes. There are special
* cases:
*
* - When the '\'' char is found in the file name, it is double quoted
* - example:
* input: a'b
* output: 'a'"'"'b'
* - When the '!' char is found in the file name, it is replaced by an unquoted
* verbatim char "\!"
* - example:
* input: a!b
* output 'a'\!'b'
*
* @param[in] file_name File name string to be quoted before used on shell
* @param[out] buf Buffer to receive the final quoted file name. Must
* have room for the final quoted string. The maximum
* output length would be (3 * strlen(file_name) + 1)
* since in the worst case each character would be
* replaced by 3 characters, plus the terminating '\0'.
* @param[in] buf_len The size of the provided output buffer
*
* @returns SSH_ERROR on error; length of the resulting string not counting the
* string terminator '\0'
* */
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len)
{
const char *src = NULL;
char *dst = NULL;
size_t required_buf_len;
enum ssh_quote_state_e state = NO_QUOTE;
if (file_name == NULL || buf == NULL || buf_len == 0) {
SSH_LOG(SSH_LOG_WARNING, "Invalid parameter");
return SSH_ERROR;
}
/* Only allow file names smaller than 32kb. */
if (strlen(file_name) > 32 * 1024) {
SSH_LOG(SSH_LOG_WARNING, "File name too long");
return SSH_ERROR;
}
/* Paranoia check */
required_buf_len = (size_t)3 * strlen(file_name) + 1;
if (required_buf_len > buf_len) {
SSH_LOG(SSH_LOG_WARNING, "Buffer too small");
return SSH_ERROR;
}
src = file_name;
dst = buf;
while ((*src != '\0')) {
switch (*src) {
/* The '\'' char is double quoted */
case '\'':
switch (state) {
case NO_QUOTE:
/* Start a new double quoted string. The '\'' char will be
* copied to the beginning of it at the end of the loop. */
*dst++ = '"';
break;
case SINGLE_QUOTE:
/* Close the current single quoted string and start a new double
* quoted string. The '\'' char will be copied to the beginning
* of it at the end of the loop. */
*dst++ = '\'';
*dst++ = '"';
break;
case DOUBLE_QUOTE:
/* If already in the double quoted string, keep copying the
* sequence of chars. */
break;
default:
/* Should never be reached */
goto error;
}
/* When the '\'' char is found, the resulting state will be
* DOUBLE_QUOTE in any case*/
state = DOUBLE_QUOTE;
break;
/* The '!' char is replaced by unquoted "\!" */
case '!':
switch (state) {
case NO_QUOTE:
/* The '!' char is interpreted in some shells (e.g. CSH) even
* when is quoted with single quotes. Replace it with unquoted
* "\!" which is correctly interpreted as the '!' character. */
*dst++ = '\\';
break;
case SINGLE_QUOTE:
/* Close the current quoted string and replace '!' for unquoted
* "\!" */
*dst++ = '\'';
*dst++ = '\\';
break;
case DOUBLE_QUOTE:
/* Close current quoted string and replace "!" for unquoted
* "\!" */
*dst++ = '"';
*dst++ = '\\';
break;
default:
/* Should never be reached */
goto error;
}
/* When the '!' char is found, the resulting state will be NO_QUOTE
* in any case*/
state = NO_QUOTE;
break;
/* Ordinary chars are single quoted */
default:
switch (state) {
case NO_QUOTE:
/* Start a new single quoted string */
*dst++ = '\'';
break;
case SINGLE_QUOTE:
/* If already in the single quoted string, keep copying the
* sequence of chars. */
break;
case DOUBLE_QUOTE:
/* Close current double quoted string and start a new single
* quoted string. */
*dst++ = '"';
*dst++ = '\'';
break;
default:
/* Should never be reached */
goto error;
}
/* When an ordinary char is found, the resulting state will be
* SINGLE_QUOTE in any case*/
state = SINGLE_QUOTE;
break;
}
/* Copy the current char to output */
*dst++ = *src++;
}
/* Close the quoted string when necessary */
switch (state) {
case NO_QUOTE:
/* No open string */
break;
case SINGLE_QUOTE:
/* Close current single quoted string */
*dst++ = '\'';
break;
case DOUBLE_QUOTE:
/* Close current double quoted string */
*dst++ = '"';
break;
default:
/* Should never be reached */
goto error;
}
/* Put the string terminator */
*dst = '\0';
return dst - buf;
error:
return SSH_ERROR;
}
/** @} */

View File

@@ -302,37 +302,6 @@ int ssh_options_set_algo(ssh_session session,
* \n
* See the corresponding numbers in libssh.h.
*
* - SSH_OPTIONS_AUTH_CALLBACK:
* Set a callback to use your own authentication function
* (function pointer).
*
* - SSH_OPTIONS_AUTH_USERDATA:
* Set the user data passed to the authentication
* function (generic pointer).
*
* - SSH_OPTIONS_LOG_CALLBACK:
* Set a callback to use your own logging function
* (function pointer).
*
* - SSH_OPTIONS_LOG_USERDATA:
* Set the user data passed to the logging function
* (generic pointer).
*
* - SSH_OPTIONS_STATUS_CALLBACK:
* Set a callback to show connection status in realtime
* (function pointer).\n
* \n
* @code
* fn(void *arg, float status)
* @endcode
* \n
* During ssh_connect(), libssh will call the callback
* with status from 0.0 to 1.0.
*
* - SSH_OPTIONS_STATUS_ARG:
* Set the status argument which should be passed to the
* status callback (generic pointer).
*
* - SSH_OPTIONS_CIPHERS_C_S:
* Set the symmetric cipher client to server (const char *,
* comma-separated list).
@@ -605,12 +574,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
v = value;
SAFE_FREE(session->opts.knownhosts);
if (v == NULL) {
session->opts.knownhosts = ssh_path_expand_escape(session,
"%d/known_hosts");
if (session->opts.knownhosts == NULL) {
ssh_set_error_oom(session);
return -1;
}
/* The default value will be set by the ssh_options_apply() */
} else if (v[0] == '\0') {
ssh_set_error_invalid(session);
return -1;
@@ -1022,6 +986,12 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
* remote host. When not explicitly set, it will be read
* from the ~/.ssh/config file.
*
* - SSH_OPTIONS_GLOBAL_KNOWNHOSTS:
* Get the path to the global known_hosts file being used.
*
* - SSH_OPTIONS_KNOWNHOSTS:
* Get the path to the known_hosts file being used.
*
* @param value The value to get into. As a char**, space will be
* allocated by the function for the value, it is
* your responsibility to free the memory using
@@ -1064,6 +1034,14 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
src = session->opts.ProxyCommand;
break;
}
case SSH_OPTIONS_KNOWNHOSTS: {
src = session->opts.knownhosts;
break;
}
case SSH_OPTIONS_GLOBAL_KNOWNHOSTS: {
src = session->opts.global_knownhosts;
break;
}
default:
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
return SSH_ERROR;
@@ -1356,6 +1334,17 @@ int ssh_options_apply(ssh_session session) {
free(session->opts.knownhosts);
session->opts.knownhosts = tmp;
if (session->opts.global_knownhosts == NULL) {
tmp = strdup("/etc/ssh/ssh_known_hosts");
} else {
tmp = ssh_path_expand_escape(session, session->opts.global_knownhosts);
}
if (tmp == NULL) {
return -1;
}
free(session->opts.global_knownhosts);
session->opts.global_knownhosts = tmp;
if (session->opts.ProxyCommand != NULL) {
tmp = ssh_path_expand_escape(session, session->opts.ProxyCommand);
if (tmp == NULL) {

View File

@@ -263,13 +263,17 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* (re-exchange)
* - dh_handshake_state == DH_STATE_FINISHED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
@@ -308,6 +312,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
(session->dh_handshake_state != DH_STATE_FINISHED))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;

View File

@@ -138,6 +138,7 @@ error:
SSH_PACKET_CALLBACK(ssh_packet_newkeys){
ssh_string sig_blob = NULL;
ssh_signature sig = NULL;
int rc;
(void)packet;
(void)user;
@@ -185,30 +186,36 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
/* get the server public key */
server_key = ssh_dh_get_next_server_publickey(session);
if (server_key == NULL) {
return SSH_ERROR;
goto error;
}
/* check if public key from server matches user preferences */
rc = ssh_pki_import_signature_blob(sig_blob, server_key, &sig);
if (rc != SSH_OK) {
goto error;
}
/* Check if signature from server matches user preferences */
if (session->opts.wanted_methods[SSH_HOSTKEYS]) {
if(!ssh_match_group(session->opts.wanted_methods[SSH_HOSTKEYS],
server_key->type_c)) {
if (!ssh_match_group(session->opts.wanted_methods[SSH_HOSTKEYS],
sig->type_c)) {
ssh_set_error(session,
SSH_FATAL,
"Public key from server (%s) doesn't match user "
"preference (%s)",
server_key->type_c,
sig->type_c,
session->opts.wanted_methods[SSH_HOSTKEYS]);
return -1;
goto error;
}
}
rc = ssh_pki_signature_verify_blob(session,
sig_blob,
server_key,
session->next_crypto->secret_hash,
session->next_crypto->digest_len);
rc = ssh_pki_signature_verify(session,
sig,
server_key,
session->next_crypto->secret_hash,
session->next_crypto->digest_len);
ssh_string_burn(sig_blob);
ssh_string_free(sig_blob);
ssh_signature_free(sig);
sig_blob = NULL;
if (rc == SSH_ERROR) {
goto error;

View File

@@ -176,6 +176,17 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
return session->current_crypto->hmacbuf;
}
static int secure_memcmp(const void *s1, const void *s2, size_t n)
{
int rc = 0;
const unsigned char *p1 = s1;
const unsigned char *p2 = s2;
for (; n > 0; --n) {
rc |= *p1++ ^ *p2++;
}
return (rc != 0);
}
/**
* @internal
*
@@ -219,7 +230,7 @@ int ssh_packet_hmac_verify(ssh_session session,
ssh_print_hexa("Computed mac",hmacbuf,len);
ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t));
#endif
if (memcmp(mac, hmacbuf, len) == 0) {
if (secure_memcmp(mac, hmacbuf, len) == 0) {
return 0;
}

View File

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

View File

@@ -214,6 +214,7 @@ ssh_key_signature_to_char(enum ssh_keytypes_e type,
case SSH_DIGEST_SHA512:
return "rsa-sha2-512";
case SSH_DIGEST_SHA1:
case SSH_DIGEST_AUTO:
return "ssh-rsa";
default:
return NULL;
@@ -271,13 +272,14 @@ static enum ssh_digest_e ssh_key_hash_from_name(const char *name)
/* we do not care for others now */
return SSH_DIGEST_AUTO;
}
/**
* @brief Checks the given key against the configured allowed
* public key algorithm types
*
* @param[in] session The SSH session
* @parma[in] type The key algorithm to check
* @returns 1 if the key algorithm is allowed 0 otherwise
* @param[in] type The key algorithm to check
* @returns 1 if the key algorithm is allowed, 0 otherwise
*/
int ssh_key_algorithm_allowed(ssh_session session, const char *type)
{
@@ -1534,7 +1536,7 @@ int ssh_pki_import_cert_file(const char *filename, ssh_key *pkey)
* @param[in] parameter Parameter to the creation of key:
* rsa : length of the key in bits (e.g. 1024, 2048, 4096)
* dsa : length of the key in bits (e.g. 1024, 2048, 3072)
* ecdsa : bits of the key (e.g. 256, 384, 512)
* ecdsa : bits of the key (e.g. 256, 384, 521)
* @param[out] pkey A pointer to store the allocated private key. You need
* to free the memory.
*
@@ -1863,10 +1865,10 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
const ssh_key pubkey,
ssh_signature *psig)
{
ssh_signature sig;
ssh_signature sig = NULL;
enum ssh_keytypes_e type;
enum ssh_digest_e hash_type;
ssh_string str;
ssh_string algorithm = NULL, blob = NULL;
ssh_buffer buf;
const char *alg = NULL;
int rc;
@@ -1888,25 +1890,25 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
return SSH_ERROR;
}
str = ssh_buffer_get_ssh_string(buf);
if (str == NULL) {
algorithm = ssh_buffer_get_ssh_string(buf);
if (algorithm == NULL) {
ssh_buffer_free(buf);
return SSH_ERROR;
}
alg = ssh_string_get_char(str);
alg = ssh_string_get_char(algorithm);
type = ssh_key_type_from_signature_name(alg);
hash_type = ssh_key_hash_from_name(alg);
ssh_string_free(str);
ssh_string_free(algorithm);
str = ssh_buffer_get_ssh_string(buf);
blob = ssh_buffer_get_ssh_string(buf);
ssh_buffer_free(buf);
if (str == NULL) {
if (blob == NULL) {
return SSH_ERROR;
}
sig = pki_signature_from_blob(pubkey, str, type, hash_type);
ssh_string_free(str);
sig = pki_signature_from_blob(pubkey, blob, type, hash_type);
ssh_string_free(blob);
if (sig == NULL) {
return SSH_ERROR;
}
@@ -1915,24 +1917,24 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
return SSH_OK;
}
int ssh_pki_signature_verify_blob(ssh_session session,
ssh_string sig_blob,
const ssh_key key,
unsigned char *digest,
size_t dlen)
int ssh_pki_signature_verify(ssh_session session,
ssh_signature sig,
const ssh_key key,
unsigned char *digest,
size_t dlen)
{
ssh_signature sig;
int rc;
rc = ssh_pki_import_signature_blob(sig_blob, key, &sig);
if (rc < 0) {
return SSH_ERROR;
}
SSH_LOG(SSH_LOG_FUNCTIONS,
"Going to verify a %s type signature",
sig->type_c);
if (key->type != sig->type) {
SSH_LOG(SSH_LOG_WARN,
"Can not verify %s signature with %s key",
sig->type_c, key->type_c);
return SSH_ERROR;
}
if (key->type == SSH_KEYTYPE_ECDSA) {
#if HAVE_ECC
@@ -1996,8 +1998,6 @@ int ssh_pki_signature_verify_blob(ssh_session session,
hlen);
}
ssh_signature_free(sig);
return rc;
}

View File

@@ -409,7 +409,7 @@ static int pki_openssh_export_privkey_blob(const ssh_key privkey,
return SSH_ERROR;
}
if (privkey->ed25519_privkey == NULL ||
privkey->ed25519_pubkey == NULL){
privkey->ed25519_pubkey == NULL) {
return SSH_ERROR;
}
rc = ssh_buffer_pack(buffer,
@@ -442,7 +442,6 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
char passphrase_buffer[128];
int rc;
int i;
uint8_t padding = 1;
int cmp;
cmp = strcmp(ciphername, "none");
@@ -469,14 +468,6 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
SSH_LOG(SSH_LOG_WARN, "Unsupported KDF %s", kdfname);
return SSH_ERROR;
}
while (ssh_buffer_get_len(privkey_buffer) % cipher.blocksize != 0) {
rc = ssh_buffer_add_u8(privkey_buffer, padding);
if (rc < 0) {
return SSH_ERROR;
}
padding++;
}
/* We need material for key (keysize bits / 8) and IV (blocksize) */
key_material_len = cipher.keysize/8 + cipher.blocksize;
if (key_material_len > sizeof(key_material)){
@@ -553,6 +544,7 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
int to_encrypt=0;
unsigned char *b64;
uint32_t str_len, len;
uint8_t padding = 1;
int ok;
int rc;
@@ -603,6 +595,18 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
goto error;
}
/* Add padding regardless encryption because it is expected
* by OpenSSH tools.
* XXX Using 16 B as we use only AES cipher below anyway.
*/
while (ssh_buffer_get_len(privkey_buffer) % 16 != 0) {
rc = ssh_buffer_add_u8(privkey_buffer, padding);
if (rc < 0) {
goto error;
}
padding++;
}
if (to_encrypt){
ssh_buffer kdf_buf;

View File

@@ -516,7 +516,7 @@ int pki_key_generate_rsa(ssh_key key, int parameter){
int pki_key_generate_dss(ssh_key key, int parameter){
int rc;
#if OPENSSL_VERSION_NUMBER > 0x10100000L
#if OPENSSL_VERSION_NUMBER > 0x00908000L
key->dsa = DSA_new();
if (key->dsa == NULL) {
return SSH_ERROR;
@@ -558,7 +558,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
case 384:
nid = NID_secp384r1;
break;
case 512:
case 521:
nid = NID_secp521r1;
break;
case 256:
@@ -790,7 +790,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
case SSH_KEYTYPE_UNKNOWN:
default:
BIO_free(mem);
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", key->type);
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", key->type);
return NULL;
}
@@ -916,7 +916,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
case SSH_KEYTYPE_RSA_CERT01:
case SSH_KEYTYPE_UNKNOWN:
BIO_free(mem);
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
return NULL;
}
@@ -1600,6 +1600,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
int rc;
BIGNUM *pr = NULL, *ps = NULL;
if (type != pubkey->type) {
SSH_LOG(SSH_LOG_WARN,
"Incompatible public key provided (%d) expecting (%d)",
type,
pubkey->type);
return NULL;
}
sig = ssh_signature_new();
if (sig == NULL) {
return NULL;
@@ -1607,7 +1615,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
sig->type = type;
sig->hash_type = hash_type;
sig->type_c = ssh_key_signature_to_char(type, hash_type);
sig->type_c = pubkey->type_c; /* for all types but RSA */
len = ssh_string_len(sig_blob);
@@ -1649,6 +1657,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
s = ssh_string_new(20);
if (s == NULL) {
bignum_safe_free(pr);
ssh_signature_free(sig);
return NULL;
}
@@ -1657,6 +1666,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ps = ssh_make_string_bn(s);
ssh_string_free(s);
if (ps == NULL) {
bignum_safe_free(pr);
ssh_signature_free(sig);
return NULL;
}
@@ -1665,6 +1675,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
* object */
rc = DSA_SIG_set0(sig->dsa_sig, pr, ps);
if (rc == 0) {
bignum_safe_free(ps);
bignum_safe_free(pr);
ssh_signature_free(sig);
return NULL;
}
@@ -1673,6 +1685,10 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
if (sig == NULL) {
return NULL;
}
sig->type_c = ssh_key_signature_to_char(type, hash_type);
break;
case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_OPENSSL_ECC
@@ -1725,6 +1741,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
rlen = ssh_buffer_get_len(b);
ssh_buffer_free(b);
if (s == NULL) {
bignum_safe_free(pr);
ssh_signature_free(sig);
return NULL;
}
@@ -1737,6 +1754,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_string_burn(s);
ssh_string_free(s);
if (ps == NULL) {
bignum_safe_free(pr);
ssh_signature_free(sig);
return NULL;
}
@@ -1745,6 +1763,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
* ECDSA signature object */
rc = ECDSA_SIG_set0(sig->ecdsa_sig, pr, ps);
if (rc == 0) {
bignum_safe_free(ps);
bignum_safe_free(pr);
ssh_signature_free(sig);
return NULL;
}
@@ -1787,7 +1807,15 @@ int pki_signature_verify(ssh_session session,
int rc;
int nid;
switch(key->type) {
if (key->type != sig->type) {
SSH_LOG(SSH_LOG_WARN,
"Can not verify %s signature with %s key",
sig->type_c,
key->type_c);
return SSH_ERROR;
}
switch (key->type) {
case SSH_KEYTYPE_DSS:
rc = DSA_do_verify(hash,
hlen,

View File

@@ -28,6 +28,7 @@
#ifdef HAVE_LIBGCRYPT
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <gcrypt.h>
@@ -389,7 +390,7 @@ static int privatekey_dek_header(const char *header, unsigned int header_len,
while(p[len] == '\n' || p[len] == '\r') /* skip empty lines */ \
len++; \
if(p[len] == '\0') /* EOL */ \
len = -1; \
eol = true; \
else /* calculate length */ \
for(p += len, len = 0; p[len] && p[len] != '\n' \
&& p[len] != '\r'; len++); \
@@ -409,7 +410,8 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
unsigned int iv_len = 0;
int algo = 0;
int mode = 0;
int len;
bool eol = false;
size_t len;
buffer = ssh_buffer_new();
if (buffer == NULL) {
@@ -441,25 +443,38 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
len = 0;
get_next_line(p, len);
while(len > 0 && strncmp(p, header_begin, header_begin_size)) {
while(!eol && strncmp(p, header_begin, header_begin_size)) {
/* skip line */
get_next_line(p, len);
}
if(len < 0) {
/* no header found */
if (eol) {
ssh_buffer_free(buffer);
return NULL;
}
/* skip header line */
get_next_line(p, len);
if (eol) {
ssh_buffer_free(buffer);
return NULL;
}
if (len > 11 && strncmp("Proc-Type: 4,ENCRYPTED", p, 11) == 0) {
/* skip line */
get_next_line(p, len);
if (eol) {
ssh_buffer_free(buffer);
return NULL;
}
if (len > 10 && strncmp("DEK-Info: ", p, 10) == 0) {
p += 10;
len = 0;
get_next_line(p, len);
if (eol) {
ssh_buffer_free(buffer);
return NULL;
}
if (privatekey_dek_header(p, len, &algo, &mode, &key_len,
&iv, &iv_len) < 0) {
ssh_buffer_free(buffer);
@@ -482,7 +497,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
}
get_next_line(p, len);
while(len > 0 && strncmp(p, header_end, header_end_size) != 0) {
while(!eol && strncmp(p, header_end, header_end_size) != 0) {
if (ssh_buffer_add_data(buffer, p, len) < 0) {
ssh_buffer_free(buffer);
SAFE_FREE(iv);
@@ -491,7 +506,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
get_next_line(p, len);
}
if (len == -1 || strncmp(p, header_end, header_end_size) != 0) {
if (eol || strncmp(p, header_end, header_end_size) != 0) {
ssh_buffer_free(buffer);
SAFE_FREE(iv);
return NULL;
@@ -998,7 +1013,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
case SSH_KEYTYPE_RSA1:
case SSH_KEYTYPE_UNKNOWN:
default:
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
return NULL;
}
@@ -1348,7 +1363,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
case 384:
nid = NID_gcrypt_nistp384;
break;
case 512:
case 521:
nid = NID_gcrypt_nistp521;
break;
case 256:
@@ -1848,6 +1863,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
size_t rsalen;
int rc;
if (type != pubkey->type) {
SSH_LOG(SSH_LOG_WARN,
"Incompatible public key provided (%d) expecting (%d)",
type,
pubkey->type);
return NULL;
}
sig = ssh_signature_new();
if (sig == NULL) {
return NULL;
@@ -1855,7 +1878,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
sig->type = type;
sig->hash_type = hash_type;
sig->type_c = ssh_key_signature_to_char(type, hash_type);
sig->type_c = pubkey->type_c; /* for all types but RSA */
len = ssh_string_len(sig_blob);
@@ -1921,6 +1944,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_signature_free(sig);
return NULL;
}
sig->type_c = ssh_key_signature_to_char(type, hash_type);
break;
case SSH_KEYTYPE_ED25519:
rc = pki_ed25519_sig_from_blob(sig, sig_blob);
@@ -2025,6 +2049,14 @@ int pki_signature_verify(ssh_session session,
gcry_sexp_t sexp;
gcry_error_t err;
if (key->type != sig->type) {
SSH_LOG(SSH_LOG_WARN,
"Can not verify %s signature with %s key",
sig->type_c,
key->type_c);
return SSH_ERROR;
}
switch(key->type) {
case SSH_KEYTYPE_DSS:
/* That is to mark the number as positive */
@@ -2124,7 +2156,6 @@ int pki_signature_verify(ssh_session session,
gcry_sexp_release(sexp);
if (err) {
ssh_set_error(session, SSH_FATAL, "Invalid ECDSA signature");
abort();
if (gcry_err_code(err) != GPG_ERR_BAD_SIGNATURE) {
ssh_set_error(session,
SSH_FATAL,

View File

@@ -897,6 +897,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_signature sig = NULL;
int rc;
if (type != pubkey->type) {
SSH_LOG(SSH_LOG_WARN,
"Incompatible public key provided (%d) expecting (%d)",
type,
pubkey->type);
return NULL;
}
sig = ssh_signature_new();
if (sig == NULL) {
return NULL;
@@ -904,11 +912,15 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
sig->type = type;
sig->hash_type = hash_type;
sig->type_c = ssh_key_signature_to_char(type, hash_type);
sig->type_c = pubkey->type_c; /* for all types but RSA */
switch(type) {
case SSH_KEYTYPE_RSA:
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
if (sig == NULL) {
return NULL;
}
sig->type_c = ssh_key_signature_to_char(type, hash_type);
break;
case SSH_KEYTYPE_ECDSA: {
ssh_buffer b;
@@ -999,6 +1011,14 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
int rc;
mbedtls_md_type_t md = 0;
if (key->type != sig->type) {
SSH_LOG(SSH_LOG_WARN,
"Can not verify %s signature with %s key",
sig->type_c,
key->type_c);
return SSH_ERROR;
}
switch (key->type) {
case SSH_KEYTYPE_RSA:
switch (sig->hash_type) {
@@ -1439,7 +1459,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter)
case 384:
nid = NID_mbedtls_nistp384;
break;
case 512:
case 521:
nid = NID_mbedtls_nistp521;
break;
case 256:

View File

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

1201
src/scp.c

File diff suppressed because it is too large Load Diff

View File

@@ -453,6 +453,7 @@ static void ssh_server_connection_callback(ssh_session session){
/* from now, the packet layer is handling incoming packets */
session->socket_callbacks.data=ssh_packet_socket_callback;
ssh_packet_register_socket_callback(session, session->socket);
ssh_packet_set_default_callbacks(session);
set_status(session, 0.5f);
@@ -518,20 +519,22 @@ static void ssh_server_connection_callback(ssh_session session){
goto error;
}
/*
* If the client supports extension negotiation, we will send
* our supported extensions now. This is the first message after
* sending NEWKEYS message and after turning on crypto.
*/
if (session->extensions & SSH_EXT_NEGOTIATION &&
session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
ssh_server_send_extensions(session);
}
set_status(session,1.0f);
session->connected = 1;
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
/*
* If the client supports extension negotiation, we will send
* our supported extensions now. This is the first message after
* sending NEWKEYS message and after turning on crypto.
*/
if (session->extensions) {
ssh_server_send_extensions(session);
}
}
break;
case SSH_SESSION_STATE_AUTHENTICATING:
@@ -1039,6 +1042,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
msg->session->kbdint->prompts = NULL;
msg->session->kbdint->echo = NULL;
}
msg->session->auth.state = SSH_AUTH_STATE_INFO;
return rc;
}
@@ -1252,30 +1256,10 @@ int ssh_execute_message_callbacks(ssh_session session){
int ssh_send_keepalive(ssh_session session)
{
int rc;
/* Client denies the request, so the error code is not meaningful */
(void)ssh_global_request(session, "keepalive@openssh.com", NULL, 1);
rc = ssh_buffer_pack(session->out_buffer,
"bsb",
SSH2_MSG_GLOBAL_REQUEST,
"keepalive@openssh.com",
1);
if (rc != SSH_OK) {
goto err;
}
if (ssh_packet_send(session) == SSH_ERROR) {
goto err;
}
ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
return SSH_OK;
err:
ssh_set_error_oom(session);
ssh_buffer_reinit(session->out_buffer);
return SSH_ERROR;
return SSH_OK;
}
/** @} */

View File

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

View File

@@ -127,22 +127,26 @@ sftp_session sftp_new(ssh_session session)
sftp->ext = sftp_ext_new();
if (sftp->ext == NULL) {
ssh_set_error_oom(session);
goto error;
}
sftp->read_packet = calloc(1, sizeof(struct sftp_packet_struct));
if (sftp->read_packet == NULL) {
ssh_set_error_oom(session);
goto error;
}
sftp->read_packet->payload = ssh_buffer_new();
if (sftp->read_packet->payload == NULL) {
ssh_set_error_oom(session);
goto error;
}
sftp->session = session;
sftp->channel = ssh_channel_new(session);
if (sftp->channel == NULL) {
ssh_set_error_oom(session);
goto error;
}
@@ -156,7 +160,6 @@ sftp_session sftp_new(ssh_session session)
return sftp;
error:
ssh_set_error_oom(session);
if (sftp->ext != NULL) {
sftp_ext_free(sftp->ext);
}

View File

@@ -74,8 +74,7 @@ enum ssh_socket_states_e {
};
struct ssh_socket_struct {
socket_t fd_in;
socket_t fd_out;
socket_t fd;
int fd_is_socket;
int last_errno;
int read_wontblock; /* reading now on socket will
@@ -87,8 +86,7 @@ struct ssh_socket_struct {
ssh_buffer in_buffer;
ssh_session session;
ssh_socket_callbacks callbacks;
ssh_poll_handle poll_in;
ssh_poll_handle poll_out;
ssh_poll_handle poll_handle;
};
static int sockets_initialized = 0;
@@ -149,8 +147,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
ssh_set_error_oom(session);
return NULL;
}
s->fd_in = SSH_INVALID_SOCKET;
s->fd_out= SSH_INVALID_SOCKET;
s->fd = SSH_INVALID_SOCKET;
s->last_errno = -1;
s->fd_is_socket = 1;
s->session = session;
@@ -170,7 +167,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
s->read_wontblock = 0;
s->write_wontblock = 0;
s->data_except = 0;
s->poll_in=s->poll_out=NULL;
s->poll_handle = NULL;
s->state=SSH_SOCKET_NONE;
return s;
}
@@ -181,8 +178,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
* @param[in] s socket to rest
*/
void ssh_socket_reset(ssh_socket s){
s->fd_in = SSH_INVALID_SOCKET;
s->fd_out= SSH_INVALID_SOCKET;
s->fd = SSH_INVALID_SOCKET;
s->last_errno = -1;
s->fd_is_socket = 1;
ssh_buffer_reinit(s->in_buffer);
@@ -190,7 +186,7 @@ void ssh_socket_reset(ssh_socket s){
s->read_wontblock = 0;
s->write_wontblock = 0;
s->data_except = 0;
s->poll_in=s->poll_out=NULL;
s->poll_handle = NULL;
s->state=SSH_SOCKET_NONE;
}
@@ -240,7 +236,7 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
(revents & POLLOUT) ? "POLLOUT ":"",
(revents & POLLERR) ? "POLLERR":"",
ssh_buffer_get_len(s->out_buffer));
if (revents & POLLERR || revents & POLLHUP) {
if ((revents & POLLERR) || (revents & POLLHUP)) {
/* Check if we are in a connecting state */
if (s->state == SSH_SOCKET_CONNECTING) {
s->state = SSH_SOCKET_ERROR;
@@ -274,17 +270,10 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,
s->callbacks->userdata);
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;
return -2;
}
return -2;
}
if (nread == 0) {
if (p != NULL) {
ssh_poll_remove_events(p, POLLIN);
}
if (p != NULL) {
ssh_poll_remove_events(p, POLLIN);
}
@@ -292,12 +281,8 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF,
0,
s->callbacks->userdata);
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;
return -2;
}
return -2;
}
if (s->session->socket_counter != NULL) {
@@ -337,7 +322,7 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
ssh_poll_set_events(p, POLLOUT | POLLIN);
}
rc = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
rc = ssh_socket_set_blocking(ssh_socket_get_fd(s));
if (rc < 0) {
return -1;
}
@@ -370,8 +355,8 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
/* TODO: Find a way to put back POLLOUT when buffering occurs */
}
/* Return -1 if one of the poll handlers disappeared */
if (s->poll_in == NULL || s->poll_out == NULL) {
/* Return -1 if the poll handler disappeared */
if (s->poll_handle == NULL) {
return -1;
}
@@ -379,31 +364,17 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
}
/** @internal
* @brief returns the input poll handle corresponding to the socket,
* @brief returns the poll handle corresponding to the socket,
* creates it if it does not exist.
* @returns allocated and initialized ssh_poll_handle object
*/
ssh_poll_handle ssh_socket_get_poll_handle_in(ssh_socket s){
if(s->poll_in)
return s->poll_in;
s->poll_in=ssh_poll_new(s->fd_in,0,ssh_socket_pollcallback,s);
if(s->fd_in == s->fd_out && s->poll_out == NULL)
s->poll_out=s->poll_in;
return s->poll_in;
}
/** @internal
* @brief returns the output poll handle corresponding to the socket,
* creates it if it does not exist.
* @returns allocated and initialized ssh_poll_handle object
*/
ssh_poll_handle ssh_socket_get_poll_handle_out(ssh_socket s){
if(s->poll_out)
return s->poll_out;
s->poll_out=ssh_poll_new(s->fd_out,0,ssh_socket_pollcallback,s);
if(s->fd_in == s->fd_out && s->poll_in == NULL)
s->poll_in=s->poll_out;
return s->poll_out;
ssh_poll_handle ssh_socket_get_poll_handle(ssh_socket s)
{
if (s->poll_handle) {
return s->poll_handle;
}
s->poll_handle = ssh_poll_new(s->fd,0,ssh_socket_pollcallback,s);
return s->poll_handle;
}
/** \internal
@@ -460,27 +431,17 @@ int ssh_socket_unix(ssh_socket s, const char *path) {
void ssh_socket_close(ssh_socket s){
if (ssh_socket_is_open(s)) {
#ifdef _WIN32
CLOSE_SOCKET(s->fd_in);
/* fd_in = fd_out under win32 */
CLOSE_SOCKET(s->fd);
s->last_errno = WSAGetLastError();
#else
if (s->fd_out != s->fd_in && s->fd_out != -1) {
CLOSE_SOCKET(s->fd_out);
}
CLOSE_SOCKET(s->fd_in);
CLOSE_SOCKET(s->fd);
s->last_errno = errno;
#endif
}
if(s->poll_in != NULL){
if(s->poll_out == s->poll_in)
s->poll_out = NULL;
ssh_poll_free(s->poll_in);
s->poll_in=NULL;
}
if(s->poll_out != NULL){
ssh_poll_free(s->poll_out);
s->poll_out=NULL;
if(s->poll_handle != NULL){
ssh_poll_free(s->poll_handle);
s->poll_handle=NULL;
}
s->state = SSH_SOCKET_CLOSED;
@@ -495,59 +456,34 @@ void ssh_socket_close(ssh_socket s){
* file descriptors
*/
void ssh_socket_set_fd(ssh_socket s, socket_t fd) {
s->fd_in = s->fd_out = fd;
s->fd = fd;
if (s->poll_in) {
ssh_poll_set_fd(s->poll_in,fd);
if (s->poll_handle) {
ssh_poll_set_fd(s->poll_handle,fd);
} else {
s->state = SSH_SOCKET_CONNECTING;
/* POLLOUT is the event to wait for in a nonblocking connect */
ssh_poll_set_events(ssh_socket_get_poll_handle_in(s), POLLOUT);
ssh_poll_set_events(ssh_socket_get_poll_handle(s), POLLOUT);
#ifdef _WIN32
ssh_poll_add_events(ssh_socket_get_poll_handle_in(s), POLLWRNORM);
ssh_poll_add_events(ssh_socket_get_poll_handle(s), POLLWRNORM);
#endif
}
}
/**
* @internal
* @brief sets the input file descriptor of the socket.
* @param[out] s ssh_socket to update
* @param[in] fd file descriptor to set
*/
void ssh_socket_set_fd_in(ssh_socket s, socket_t fd) {
s->fd_in = fd;
if(s->poll_in)
ssh_poll_set_fd(s->poll_in,fd);
}
/**
* @internal
* @brief sets the output file descriptor of the socket.
* @param[out] s ssh_socket to update
* @param[in] fd file descriptor to set
*/
void ssh_socket_set_fd_out(ssh_socket s, socket_t fd) {
s->fd_out = fd;
if(s->poll_out)
ssh_poll_set_fd(s->poll_out,fd);
}
/** \internal
* \brief returns the input file descriptor of the socket
*/
socket_t ssh_socket_get_fd_in(ssh_socket s) {
return s->fd_in;
socket_t ssh_socket_get_fd(ssh_socket s)
{
return s->fd;
}
/** \internal
* \brief returns nonzero if the socket is open
*/
int ssh_socket_is_open(ssh_socket s) {
return s->fd_in != SSH_INVALID_SOCKET;
return s->fd != SSH_INVALID_SOCKET;
}
/** \internal
@@ -563,9 +499,9 @@ static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
return -1;
}
if (s->fd_is_socket) {
rc = recv(s->fd_in,buffer, len, 0);
rc = recv(s->fd,buffer, len, 0);
} else {
rc = read(s->fd_in,buffer, len);
rc = read(s->fd,buffer, len);
}
#ifdef _WIN32
s->last_errno = WSAGetLastError();
@@ -600,9 +536,9 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
}
if (s->fd_is_socket) {
w = send(s->fd_out, buffer, len, flags);
w = send(s->fd, buffer, len, flags);
} else {
w = write(s->fd_out, buffer, len);
w = write(s->fd, buffer, len);
}
#ifdef _WIN32
s->last_errno = WSAGetLastError();
@@ -611,9 +547,9 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
#endif
s->write_wontblock = 0;
/* Reactive the POLLOUT detector in the poll multiplexer system */
if (s->poll_out) {
if (s->poll_handle) {
SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
ssh_poll_set_events(s->poll_handle,ssh_poll_get_events(s->poll_handle) | POLLOUT);
}
if (w < 0) {
s->data_except = 1;
@@ -626,10 +562,10 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
* \brief returns nonzero if the current socket is in the fd_set
*/
int ssh_socket_fd_isset(ssh_socket s, fd_set *set) {
if(s->fd_in == SSH_INVALID_SOCKET) {
if(s->fd == SSH_INVALID_SOCKET) {
return 0;
}
return FD_ISSET(s->fd_in,set) || FD_ISSET(s->fd_out,set);
return FD_ISSET(s->fd,set);
}
/** \internal
@@ -637,22 +573,16 @@ int ssh_socket_fd_isset(ssh_socket s, fd_set *set) {
*/
void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd) {
if (s->fd_in == SSH_INVALID_SOCKET) {
if (s->fd == SSH_INVALID_SOCKET) {
return;
}
FD_SET(s->fd_in,set);
FD_SET(s->fd_out,set);
FD_SET(s->fd,set);
if (s->fd_in >= 0 &&
s->fd_in >= *max_fd &&
s->fd_in != SSH_INVALID_SOCKET) {
*max_fd = s->fd_in + 1;
}
if (s->fd_out >= 0 &&
s->fd_out >= *max_fd &&
s->fd_out != SSH_INVALID_SOCKET) {
*max_fd = s->fd_out + 1;
if (s->fd >= 0 &&
s->fd >= *max_fd &&
s->fd != SSH_INVALID_SOCKET) {
*max_fd = s->fd + 1;
}
}
@@ -701,9 +631,9 @@ int ssh_socket_nonblocking_flush(ssh_socket s)
}
len = ssh_buffer_get_len(s->out_buffer);
if (!s->write_wontblock && s->poll_out && len > 0) {
if (!s->write_wontblock && s->poll_handle && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
ssh_poll_add_events(s->poll_handle, POLLOUT);
return SSH_AGAIN;
}
@@ -741,9 +671,9 @@ int ssh_socket_nonblocking_flush(ssh_socket s)
/* Is there some data pending? */
len = ssh_buffer_get_len(s->out_buffer);
if (s->poll_out && len > 0) {
if (s->poll_handle && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
ssh_poll_add_events(s->poll_handle, POLLOUT);
return SSH_AGAIN;
}
@@ -804,10 +734,10 @@ int ssh_socket_get_status(ssh_socket s) {
int ssh_socket_get_poll_flags(ssh_socket s) {
int r = 0;
if (s->poll_in != NULL && (ssh_poll_get_events (s->poll_in) & POLLIN) > 0) {
if (s->poll_handle != NULL && (ssh_poll_get_events (s->poll_handle) & POLLIN) > 0) {
r |= SSH_READ_PENDING;
}
if (s->poll_out != NULL && (ssh_poll_get_events (s->poll_out) & POLLOUT) > 0) {
if (s->poll_handle != NULL && (ssh_poll_get_events (s->poll_handle) & POLLOUT) > 0) {
r |= SSH_WRITE_PENDING;
}
return r;
@@ -897,19 +827,15 @@ void ssh_execute_command(const char *command, socket_t in, socket_t out){
*/
int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){
socket_t in_pipe[2];
socket_t out_pipe[2];
socket_t pair[2];
int pid;
int rc;
if(s->state != SSH_SOCKET_NONE)
if (s->state != SSH_SOCKET_NONE) {
return SSH_ERROR;
rc = pipe(in_pipe);
if (rc < 0) {
return SSH_ERROR;
}
rc = pipe(out_pipe);
rc = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
if (rc < 0) {
return SSH_ERROR;
}
@@ -917,20 +843,18 @@ int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){
SSH_LOG(SSH_LOG_PROTOCOL,"Executing proxycommand '%s'",command);
pid = fork();
if(pid == 0){
ssh_execute_command(command,out_pipe[0],in_pipe[1]);
ssh_execute_command(command,pair[0],pair[0]);
}
close(in_pipe[1]);
close(out_pipe[0]);
SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",in_pipe[0],out_pipe[1]);
ssh_socket_set_fd_in(s,in_pipe[0]);
ssh_socket_set_fd_out(s,out_pipe[1]);
close(pair[0]);
SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]);
ssh_socket_set_fd(s, pair[1]);
s->state=SSH_SOCKET_CONNECTED;
s->fd_is_socket=0;
/* POLLOUT is the event to wait for in a nonblocking connect */
ssh_poll_set_events(ssh_socket_get_poll_handle_in(s),POLLIN);
ssh_poll_set_events(ssh_socket_get_poll_handle_out(s),POLLOUT);
if(s->callbacks && s->callbacks->connected)
ssh_poll_set_events(ssh_socket_get_poll_handle(s), POLLIN | POLLOUT);
if(s->callbacks && s->callbacks->connected) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata);
}
return SSH_OK;
}

View File

@@ -116,6 +116,14 @@ void crypto_thread_finalize(void)
return;
}
#ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
CRYPTO_THREADID_set_callback(NULL);
#else
CRYPTO_set_id_callback(NULL);
#endif
CRYPTO_set_locking_callback(NULL);
for (i = 0; i < n; ++i) {
user_callbacks->mutex_destroy(&libcrypto_mutexes[i]);
}

View File

@@ -52,7 +52,6 @@
static struct ssh_hmac_struct ssh_hmac_tab[] = {
{ "hmac-sha1", SSH_HMAC_SHA1 },
{ "hmac-sha2-256", SSH_HMAC_SHA256 },
{ "hmac-sha2-384", SSH_HMAC_SHA384 },
{ "hmac-sha2-512", SSH_HMAC_SHA512 },
{ "hmac-md5", SSH_HMAC_MD5 },
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305 },
@@ -69,8 +68,6 @@ size_t hmac_digest_len(enum ssh_hmac_e type) {
return SHA_DIGEST_LEN;
case SSH_HMAC_SHA256:
return SHA256_DIGEST_LEN;
case SSH_HMAC_SHA384:
return SHA384_DIGEST_LEN;
case SSH_HMAC_SHA512:
return SHA512_DIGEST_LEN;
case SSH_HMAC_MD5:

View File

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

View File

@@ -232,7 +232,7 @@ static void torture_auth_none_nonblocking(void **state) {
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
ssh_set_blocking(session,0);
@@ -241,7 +241,7 @@ static void torture_auth_none_nonblocking(void **state) {
rc = ssh_userauth_none(session,NULL);
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_DENIED);
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
@@ -260,7 +260,7 @@ static void torture_auth_autopubkey(void **state) {
rc = ssh_userauth_none(session,NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
@@ -313,7 +313,7 @@ static void torture_auth_kbdint(void **state) {
rc = ssh_userauth_none(session,NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE);
@@ -352,7 +352,7 @@ static void torture_auth_kbdint_nonblocking(void **state) {
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE);
@@ -392,7 +392,7 @@ static void torture_auth_password(void **state) {
rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_AUTH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PASSWORD);
@@ -419,7 +419,7 @@ static void torture_auth_password_nonblocking(void **state) {
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_AUTH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
@@ -450,7 +450,7 @@ static void torture_auth_agent(void **state) {
rc = ssh_userauth_none(session,NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
@@ -477,7 +477,7 @@ static void torture_auth_agent_nonblocking(void **state) {
rc = ssh_userauth_none(session,NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
@@ -559,10 +559,10 @@ static void torture_auth_pubkey_types(void **state)
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
rc = ssh_userauth_none(session,NULL);
rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
@@ -596,10 +596,10 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
rc = ssh_userauth_none(session,NULL);
rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
@@ -622,6 +622,44 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
}
static void torture_auth_pubkey_types_ed25519(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_ssh_return_code(session, rc);
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
rc = ssh_userauth_none(session, NULL);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
/* Enable only DSA keys -- authentication should fail */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-dss");
assert_ssh_return_code(session, rc);
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
assert_int_equal(rc, SSH_AUTH_DENIED);
/* Verify we can use also ed25519 keys */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-ed25519");
assert_ssh_return_code(session, rc);
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
static void torture_auth_pubkey_types_nonblocking(void **state)
{
struct torture_state *s = *state;
@@ -634,7 +672,7 @@ static void torture_auth_pubkey_types_nonblocking(void **state)
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
ssh_set_blocking(session,0);
ssh_set_blocking(session, 0);
do {
rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
@@ -681,7 +719,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
ssh_set_blocking(session,0);
ssh_set_blocking(session, 0);
do {
rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
@@ -704,7 +742,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_DENIED);
/* Verify we can use also ECDSA keys with their various names */
/* Verify we can use also ECDSA key to authenticate */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ecdsa-sha2-nistp256");
assert_ssh_return_code(session, rc);
@@ -716,6 +754,52 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
}
static void torture_auth_pubkey_types_ed25519_nonblocking(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_ssh_return_code(session, rc);
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
ssh_set_blocking(session, 0);
do {
rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
/* This request should return a SSH_REQUEST_DENIED error */
if (rc == SSH_ERROR) {
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
}
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
/* Enable only DSA keys -- authentication should fail */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-dss");
assert_ssh_return_code(session, rc);
do {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_DENIED);
/* Verify we can use also ED25519 key to authenticate */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ssh-ed25519");
assert_ssh_return_code(session, rc);
do {
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
int torture_run_tests(void) {
int rc;
@@ -771,6 +855,12 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ecdsa_nonblocking,
pubkey_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519,
pubkey_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519_nonblocking,
pubkey_setup,
session_teardown),
};
ssh_init();

View File

@@ -163,7 +163,7 @@ static void torture_hostkey_ecdsa(void **state) {
static void torture_hostkey_rsa_sha256(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
char rsa[] = "rsa-sha2-256,ssh-rsa";
char rsa[] = "rsa-sha2-256";
int rc;
@@ -182,7 +182,7 @@ static void torture_hostkey_rsa_sha256(void **state) {
static void torture_hostkey_rsa_sha512(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
char rsa[] = "rsa-sha2-512,ssh-rsa";
char rsa[] = "rsa-sha2-512";
int rc;

View File

@@ -328,6 +328,41 @@ static void torture_knownhosts_conflict(void **state) {
/* session will be freed by session_teardown() */
}
static void torture_knownhosts_no_hostkeychecking(void **state)
{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
char known_hosts_file[1024] = {0};
enum ssh_known_hosts_e found;
int strict_host_key_checking = 0;
int rc;
snprintf(known_hosts_file,
sizeof(known_hosts_file),
"%s/%s",
s->socket_dir,
TORTURE_KNOWN_HOSTS_FILE);
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
assert_ssh_return_code(session, rc);
rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519");
assert_ssh_return_code(session, rc);
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
found = ssh_session_is_known_server(session);
assert_int_equal(found, SSH_KNOWN_HOSTS_UNKNOWN);
rc = ssh_options_set(session, SSH_OPTIONS_STRICTHOSTKEYCHECK, &strict_host_key_checking);
assert_ssh_return_code(session, rc);
found = ssh_session_is_known_server(session);
assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
}
int torture_run_tests(void) {
int rc;
struct CMUnitTest tests[] = {
@@ -346,6 +381,9 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_knownhosts_conflict,
session_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_knownhosts_no_hostkeychecking,
session_setup,
session_teardown),
};
ssh_init();

View File

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

View File

@@ -9,6 +9,7 @@
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
#include <fcntl.h>
static int sshd_setup(void **state)
{
@@ -61,11 +62,16 @@ static void torture_options_set_proxycommand(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
socket_t fd;
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "nc 127.0.0.10 22");
assert_int_equal(rc, 0);
rc = ssh_connect(session);
assert_ssh_return_code(session, rc);
fd = ssh_get_fd(session);
assert_true(fd != SSH_INVALID_SOCKET);
rc = fcntl(fd, F_GETFL);
assert_int_equal(rc & O_RDWR, O_RDWR);
}
static void torture_options_set_proxycommand_notexist(void **state) {

View File

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

8
tests/keys/id_ed25519 Normal file
View File

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

View File

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

View File

@@ -46,12 +46,12 @@
OPENSSH_PKACCEPTED_ECDSA \
OPENSSH_PKACCEPTED_DSA
#define OPENSSH_CMD_START \
#define OPENSSH_CMD_START(hostkey_algos) \
OPENSSH_BINARY " " \
"-o UserKnownHostsFile=/dev/null " \
"-o StrictHostKeyChecking=no " \
"-F /dev/null " \
OPENSSH_HOSTKEY_ALGOS " " \
hostkey_algos " " \
OPENSSH_PKACCEPTED_TYPES " " \
"-i " CLIENT_ID_FILE " " \
"1> %s.out " \
@@ -61,16 +61,19 @@
#define OPENSSH_CMD_END "-p 1234 localhost ls"
#define OPENSSH_CMD \
OPENSSH_CMD_START OPENSSH_CMD_END
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) OPENSSH_CMD_END
#define OPENSSH_KEX_CMD(kexalgo) \
OPENSSH_CMD_START "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END
#define OPENSSH_CIPHER_CMD(ciphers) \
OPENSSH_CMD_START "-c " ciphers " " OPENSSH_CMD_END
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-c " ciphers " " OPENSSH_CMD_END
#define OPENSSH_MAC_CMD(macs) \
OPENSSH_CMD_START "-o MACs=" macs " " OPENSSH_CMD_END
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-o MACs=" macs " " OPENSSH_CMD_END
#define OPENSSH_HOSTKEY_CMD(hostkeyalgo) \
OPENSSH_CMD_START("-o HostKeyAlgorithms=" hostkeyalgo " ") OPENSSH_CMD_END
/* Dropbear */

View File

@@ -35,7 +35,7 @@ struct pkd_daemon_args {
unsigned int iterations;
struct {
const char *mkdtemp_str;
char *mkdtemp_str;
} socket_wrapper;
} opts;
};

View File

@@ -478,6 +478,12 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ecdsa_521_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_ecdsa_521, teardown)
#endif
#define PKDTESTS_HOSTKEY_OPENSSHONLY(f, client, hkcmd) \
f(client, rsa_sha2_256, hkcmd("rsa-sha2-256"), setup_rsa, teardown) \
f(client, rsa_sha2_512, hkcmd("rsa-sha2-512"), setup_rsa, teardown) \
f(client, rsa_sha2_256_512, hkcmd("rsa-sha2-256,rsa-sha2-512"), setup_rsa, teardown) \
f(client, rsa_sha2_512_256, hkcmd("rsa-sha2-512,rsa-sha2-256"), setup_rsa, teardown)
static void torture_pkd_client_noop(void **state) {
struct pkd_state *pstate = (struct pkd_state *) (*state);
(void) pstate;
@@ -545,6 +551,7 @@ PKDTESTS_CIPHER(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD)
PKDTESTS_CIPHER_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD)
PKDTESTS_MAC(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD)
PKDTESTS_MAC_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD)
PKDTESTS_HOSTKEY_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_HOSTKEY_CMD)
#undef CLIENT_ID_FILE
#define CLIENT_ID_FILE OPENSSH_ECDSA256_TESTKEY
@@ -621,6 +628,7 @@ struct {
PKDTESTS_CIPHER_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_CIPHER_CMD)
PKDTESTS_MAC(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD)
PKDTESTS_MAC_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD)
PKDTESTS_HOSTKEY_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_HOSTKEY_CMD)
PKDTESTS_DEFAULT(emit_testmap, openssh_e256, OPENSSH_CMD)
PKDTESTS_DEFAULT_OPENSSHONLY(emit_testmap, openssh_e256, OPENSSH_CMD)
@@ -849,6 +857,8 @@ static int pkd_cleanup_socket_wrapper(void) {
goto errrmdir;
}
free(pkd_dargs.opts.socket_wrapper.mkdtemp_str);
goto out;
errrmdir:
errrmfiles:

View File

@@ -284,7 +284,7 @@ static void torture_config_auth_methods(void **state) {
assert_false(session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH);
/* no method should be left enabled */
assert_int_equal(session->opts.port, 0);
assert_int_equal(session->opts.flags, 0);
/* gradually enable them again */
ssh_options_set(session, SSH_OPTIONS_HOST, "gss");

View File

@@ -16,10 +16,27 @@ static void torture_ssh_init(void **state) {
assert_int_equal(rc, SSH_OK);
}
static void torture_ssh_init_after_finalize(void **state) {
int rc;
(void) state;
rc = ssh_init();
assert_int_equal(rc, SSH_OK);
rc = ssh_finalize();
assert_int_equal(rc, SSH_OK);
rc = ssh_init();
assert_int_equal(rc, SSH_OK);
rc = ssh_finalize();
assert_int_equal(rc, SSH_OK);
}
int torture_run_tests(void) {
int rc;
struct CMUnitTest tests[] = {
cmocka_unit_test(torture_ssh_init),
cmocka_unit_test(torture_ssh_init_after_finalize),
};
torture_filter_tests(tests);

View File

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

View File

@@ -12,6 +12,7 @@
#include <libssh/session.h>
#include <libssh/misc.h>
#include <libssh/pki_priv.h>
#include <libssh/options.h>
static int setup(void **state)
{
@@ -346,6 +347,86 @@ static void torture_options_get_identity(void **state) {
free(identity);
}
static void torture_options_set_global_knownhosts(void **state)
{
ssh_session session = *state;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
"/etc/libssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.global_knownhosts,
"/etc/libssh/known_hosts");
}
static void torture_options_get_global_knownhosts(void **state)
{
ssh_session session = *state;
char *str = NULL;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
"/etc/libssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.global_knownhosts,
"/etc/libssh/known_hosts");
rc = ssh_options_get(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, &str);
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.global_knownhosts,
"/etc/libssh/known_hosts");
SSH_STRING_FREE_CHAR(str);
}
static void torture_options_set_knownhosts(void **state)
{
ssh_session session = *state;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_KNOWNHOSTS,
"/home/libssh/.ssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.knownhosts,
"/home/libssh/.ssh/known_hosts");
/* The NULL value should not crash the libssh */
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, NULL);
assert_ssh_return_code(session, rc);
assert_null(session->opts.knownhosts);
/* ssh_options_apply() should set the path to correct value */
rc = ssh_options_apply(session);
assert_ssh_return_code(session, rc);
assert_true(session->opts.knownhosts != NULL);
}
static void torture_options_get_knownhosts(void **state)
{
ssh_session session = *state;
char *str = NULL;
int rc;
rc = ssh_options_set(session,
SSH_OPTIONS_KNOWNHOSTS,
"/home/libssh/.ssh/known_hosts");
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.knownhosts,
"/home/libssh/.ssh/known_hosts");
rc = ssh_options_get(session, SSH_OPTIONS_KNOWNHOSTS, &str);
assert_ssh_return_code(session, rc);
assert_string_equal(session->opts.knownhosts,
"/home/libssh/.ssh/known_hosts");
SSH_STRING_FREE_CHAR(str);
}
static void torture_options_proxycommand(void **state) {
ssh_session session = *state;
int rc;
@@ -581,7 +662,7 @@ static void torture_bind_options_import_key(void **state)
assert_int_equal(rc, 0);
#endif
/* set ecdsa key */
base64_key = torture_get_testkey(SSH_KEYTYPE_ECDSA, 512, 0);
base64_key = torture_get_testkey(SSH_KEYTYPE_ECDSA, 521, 0);
rc = ssh_pki_import_privkey_base64(base64_key, NULL, NULL, NULL, &key);
assert_int_equal(rc, SSH_OK);
assert_non_null(key);
@@ -604,6 +685,10 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_options_get_user, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_identity, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_get_identity, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_global_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_get_global_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_get_knownhosts, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_ciphers, setup, teardown),
cmocka_unit_test_setup_teardown(torture_options_set_key_exchange, setup, teardown),

View File

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

View File

@@ -462,6 +462,36 @@ static void torture_packet_filter_check_auth_success(void **state)
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_msg_ext_info(void **state)
{
int rc;
global_state accepted[] = {
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_DH_STATE),
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_DH_STATE),
.session = SSH_SESSION_STATE_AUTHENTICATED,
.dh = DH_STATE_FINISHED,
},
};
int accepted_count = 2;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_EXT_INFO);
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_channel_open(void **state)
{
int rc;
@@ -492,6 +522,7 @@ int torture_run_tests(void)
cmocka_unit_test(torture_packet_filter_check_auth_success),
cmocka_unit_test(torture_packet_filter_check_channel_open),
cmocka_unit_test(torture_packet_filter_check_unfiltered),
cmocka_unit_test(torture_packet_filter_check_msg_ext_info)
};
ssh_init();

View File

@@ -9,6 +9,10 @@
#include "torture_pki.h"
#include "pki.c"
const unsigned char HASH[] = "1234567890123456789012345678901234567890"
"123456789012345678901234";
static void torture_pki_keytype(void **state) {
enum ssh_keytypes_e type;
const char *type_c;
@@ -43,11 +47,227 @@ static void torture_pki_signature(void **state)
ssh_signature_free(sig);
}
/* Maps to enum ssh_keytypes_e */
const char *key_types[] = {
"", /* UNKNOWN */
"ssh-dss",
"ssh-rsa",
"",/* RSA1 */
"ecdsa-sha2-nistp521",
"ssh-ed25519",
};
/* Maps to enum ssh_keytypes_e */
const int key_sizes[] = {
0, /* UNKNOWN */
1024,
2048,
0, /* RSA1 */
521,
0,
};
/* Maps to enum ssh_keytypes_e */
const int sig_lengths[] = {
0, /* UNKNOWN */
20,
20,
0, /* RSA1 */
64,
33,
};
/* Maps to enum ssh_keytypes_e */
const char *signature_types[] = {
"", /* UNKNOWN */
"ssh-dss",
"ssh-rsa",
"",/* RSA1 */
"ecdsa-sha2-nistp521",
"ssh-ed25519",
};
/* Maps to enum ssh_digest_e */
const char *hash_signatures[] = {
"", /* Not used here */
"ssh-rsa",
"rsa-sha2-256",
"rsa-sha2-512",
};
/* Maps to enum ssh_digest_e */
int hash_lengths[] = {
0, /* Not used here */
20,
32,
64,
};
/* This tests all the base types and their signatures against each other */
static void torture_pki_verify_mismatch(void **state)
{
int rc;
int verbosity = torture_libssh_verbosity();
ssh_key key = NULL, verify_key = NULL;
ssh_signature sign = NULL, import_sig = NULL, new_sig = NULL;
ssh_string blob;
ssh_session session = ssh_new();
enum ssh_keytypes_e key_type, sig_type, first_key;
enum ssh_digest_e hash;
int hash_length;
(void) state;
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
#ifdef HAVE_DSA
first_key = SSH_KEYTYPE_DSS;
#else
first_key = SSH_KEYTYPE_RSA;
#endif /* HAVE_DSA */
for (sig_type = first_key;
sig_type <= SSH_KEYTYPE_ED25519;
sig_type++) {
if (sig_type == SSH_KEYTYPE_RSA1) {
continue;
}
rc = ssh_pki_generate(sig_type, key_sizes[sig_type], &key);
assert_true(rc == SSH_OK);
assert_true(key != NULL);
assert_int_equal(key->type, sig_type);
assert_string_equal(key->type_c, key_types[sig_type]);
for (hash = SSH_DIGEST_AUTO;
hash <= SSH_DIGEST_SHA512;
hash++) {
hash_length = ((hash == SSH_DIGEST_AUTO) ?
sig_lengths[sig_type] : hash_lengths[hash]);
SSH_LOG(SSH_LOG_TRACE, "Creating signature %d with hash %d",
sig_type, hash);
/* Create a valid signature using this key */
sign = pki_do_sign_hash(key, HASH, hash_length, hash);
assert_true(sign != NULL);
assert_int_equal(sign->type, key->type);
if (hash == SSH_DIGEST_AUTO) {
assert_string_equal(sign->type_c, key->type_c);
assert_string_equal(sign->type_c, signature_types[sig_type]);
} else {
assert_string_equal(sign->type_c, hash_signatures[hash]);
}
/* Create a signature blob that can be imported and verified */
blob = pki_signature_to_blob(sign);
assert_non_null(blob);
/* Import and verify with current key
* (this is not tested anywhere else yet) */
import_sig = pki_signature_from_blob(key,
blob,
sig_type,
hash);
assert_non_null(import_sig);
assert_int_equal(import_sig->type, key->type);
if (hash == SSH_DIGEST_AUTO) {
assert_string_equal(import_sig->type_c, key->type_c);
assert_string_equal(import_sig->type_c, signature_types[sig_type]);
} else {
assert_string_equal(import_sig->type_c, hash_signatures[hash]);
}
/* Internal API: Should work */
rc = pki_signature_verify(session,
import_sig,
key,
HASH,
hash_length);
assert_true(rc == SSH_OK);
/* XXX Test all the hash versions only with RSA.
* This also skips the cleanup for the last hash so we can use the
* created signatures later on
*/
if (sig_type != SSH_KEYTYPE_RSA || hash == SSH_DIGEST_SHA512) {
break;
}
ssh_string_free(blob);
ssh_signature_free(sign);
ssh_signature_free(import_sig);
}
for (key_type = first_key;
key_type <= SSH_KEYTYPE_ED25519;
key_type++) {
if (key_type == SSH_KEYTYPE_RSA1) {
continue;
}
SSH_LOG(SSH_LOG_TRACE, "Trying key %d with signature %d",
key_type, sig_type);
rc = ssh_pki_generate(key_type, key_sizes[key_type], &verify_key);
assert_true(rc == SSH_OK);
assert_true(verify_key != NULL);
/* Should gradefully fail, but not crash */
rc = pki_signature_verify(session,
sign,
verify_key,
HASH,
hash_length);
assert_true(rc != SSH_OK);
/* Try the same with the imported signature */
rc = pki_signature_verify(session,
import_sig,
verify_key,
HASH,
hash_length);
assert_true(rc != SSH_OK);
/* Try to import the signature blob with different key */
new_sig = pki_signature_from_blob(verify_key,
blob,
sig_type,
SSH_DIGEST_SHA1);
if (sig_type != key_type) {
assert_true(new_sig == NULL);
} else {
/* Importing with the same key type should work */
assert_true(new_sig != NULL);
assert_int_equal(new_sig->type, key->type);
assert_string_equal(new_sig->type_c, key->type_c);
assert_string_equal(new_sig->type_c, signature_types[sig_type]);
/* The verificaiton should not work */
rc = pki_signature_verify(session,
new_sig,
verify_key,
HASH,
hash_length);
assert_true(rc != SSH_OK);
ssh_signature_free(new_sig);
}
SSH_KEY_FREE(verify_key);
}
ssh_string_free(blob);
ssh_signature_free(sign);
ssh_signature_free(import_sig);
SSH_KEY_FREE(key);
key = NULL;
}
ssh_free(session);
}
int torture_run_tests(void) {
int rc;
struct CMUnitTest tests[] = {
cmocka_unit_test(torture_pki_keytype),
cmocka_unit_test(torture_pki_signature),
cmocka_unit_test(torture_pki_verify_mismatch),
};
ssh_init();

View File

@@ -392,7 +392,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
ssh_signature_free(sign);
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key);
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 521, &key);
assert_true(rc == SSH_OK);
assert_true(key != NULL);
sign = pki_do_sign(key, ECDSA_HASH, 20);