Compare commits

...

89 Commits

Author SHA1 Message Date
Andreas Schneider
6e0dee7845 poll: Fix compilation with struct ssh_timestamp
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e0a73d3dbe)
2015-05-06 10:07:38 +02:00
Andreas Schneider
9e99408dba Bump version to 0.6.5
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-29 12:24:33 +02:00
Andreas Schneider
6b49863bb0 Update Changelog
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-29 12:23:50 +02:00
Aris Adamantiadis
e9d16bd343 buffers: Fix a possible null pointer dereference
This is an addition to CVE-2015-3146 to fix the null pointer
dereference. The patch is not required to fix the CVE but prevents
issues in future.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3091025472)
2015-04-23 10:34:13 +02:00
Aris Adamantiadis
94f6955fba CVE-2015-3146: Fix state validation in packet handlers
The state validation in the packet handlers for SSH_MSG_NEWKEYS and
SSH_MSG_KEXDH_REPLY had a bug which did not raise an error.

The issue has been found and reported by Mariusz Ziule.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bf0c7ae0ae)
2015-04-23 10:34:12 +02:00
Kevin Fan
d2a990a68e Fix leak of sftp->ext when sftp_new() fails
Signed-off-by: Kevin Fan <kevinfan@google.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b5dc8197f7)
2015-04-14 20:57:17 +02:00
Andreas Schneider
584ab49b7b cmake: Detect network function correctly on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 195f25cfbd)
2015-04-10 14:32:53 +02:00
Andreas Schneider
dc30183d8a cmake: Detect __func__ and __FUNCTION__ during configure step
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 13:42:12 +02:00
Andreas Schneider
396f5e2110 include: We should use __func__ which is C99
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-04-02 10:57:18 +02:00
Seb Boving
6b18f0b4b0 Locally restart ssh_poll() upon EINTR.
BUG: https://red.libssh.org/issues/186

Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
Signed-off-by: Sebastien Boving <seb@google.com>
2015-02-23 22:06:34 +01:00
xjoaalm
8f2eee6509 Sending EOF on Socket that received a Broken Pipe makes call to poll to hang
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
Signed-off-by: Joao Pedro Almeida Pereira <joao.almeida@blue-tc.com>
2015-02-23 22:02:35 +01:00
Aris Adamantiadis
4bd704295c examples: cast arguments of connect(2)
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2015-02-14 22:20:45 +01:00
Aris Adamantiadis
be2f5399dd torture: fix includes for freebsd10 2015-02-14 22:13:58 +01:00
Aris Adamantiadis
a672b3e7bb tests: torture-misc: check for NULL return codes
Use the LOGNAME environment variable if USER is not set, as it sometimes
happens in cron jobs.
2015-02-12 11:39:53 +01:00
Aris Adamantiadis
ddc3f987a7 tests: workaround for compiling with older cmocka 2015-02-12 11:39:45 +01:00
Aris Adamantiadis
e9ad0c3c69 sftp: fix endianess issue 2015-02-11 21:35:02 +01:00
Andreas Schneider
2ccab05cba connect: Fix mingw build.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a198193723)
2015-01-26 17:10:19 +01:00
Andreas Schneider
58348fcc57 sftp: Fix sftp_get_new_id().
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-21 08:44:34 +01:00
Léo Peltier
0579b7d8b2 cmake: Add libsshpp.hpp to the distributed headers list.
BUG: https://red.libssh.org/issues/163

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8db4520d89)
2015-01-20 19:33:16 +01:00
Andreas Schneider
915d28ffa5 pki: Make sure sig is not used unintialized.
BUG: https://red.libssh.org/issues/167

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9a7d450098)
2015-01-20 19:31:29 +01:00
Andreas Schneider
884bff5bdc sftp: Fix sftp endianess bugs.
BUG: https://red.libssh.org/issues/179

This is a backport of 6019cf1bed.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-01-20 19:17:02 +01:00
Andreas Schneider
08c33d6aeb threads: Fix building with POSIX threads in MinGW.
BUG: https://red.libssh.org/issues/181

Originally written by Patrick von Reth <vonreth () kde ! org>.

This patch is part of the larger patch:
https://projects.kde.org/projects/kdesupport/emerge/repository/revisions/master/changes/portage/win32libs/libssh/0002-add-a-way-to-test-ssh-connections-on-windows.patch

MinGW (in particular, the MinGW-w64 fork) can use either posix threads
or win32 threads. This patch fixes the MinGW build when using posix
threads.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 433f8fd550)
2015-01-20 19:03:08 +01:00
Yanis Kurganov
fa4740bdf5 channels1: Fix pty request state
Signed-off-by: Yanis Kurganov <YKurganov@ptsecurity.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c6590bd189)
2015-01-20 18:59:01 +01:00
Andreas Schneider
da91ca43c0 connect: Fix a memory leak.
CID: #1238618

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
(cherry picked from commit 06a0d8ff1c)
2015-01-14 15:21:41 +01:00
Andreas Schneider
4de6a708ad sftp: Fix a possible integer overflow.
CID: #1238630

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
(cherry picked from commit af0dd3fb02)
2015-01-14 15:21:40 +01:00
Andreas Schneider
fd3b1f63a1 sftp: Use a declared variable for data len.
CID: #1238632

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
(cherry picked from commit ce02f6576a)
2015-01-14 15:21:36 +01:00
Andreas Schneider
914f8abde8 cmake: Fix ntohll and htonll macro detection.
BUG: https://red.libssh.org/issues/164

Thanks to Ryan Schmidt!

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8536cd9808)
2015-01-13 08:55:07 +01:00
Aris Adamantiadis
3880a8ed80 Fix the dh.c build with libgcrypt
Fixes bug reported by gentoo at https://bugs.gentoo.org/show_bug.cgi?id=533424
The function was only used by EDCSA backend which are not supported by the libgcrypt code anyway.
2014-12-29 16:06:33 +01:00
Andreas Schneider
0e969e0316 connect: Check that errno is 0 to fix Windows build.
Thanks to Viktor Butskih.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e051135a05)
2014-12-25 12:35:24 +01:00
Andreas Schneider
a45dd8e000 options: Fix setting the port.
Make sure we correctly read the port from the config file.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bb18442fe8)
2014-12-25 12:35:21 +01:00
Andreas Schneider
319129399d Bump version to 0.6.4. 2014-12-17 19:45:23 +01:00
Jon Simons
87ae95eb3c CVE-2014-8132: Fixup error path in ssh_packet_kexinit()
Before this change, dangling pointers can be unintentionally left in the
respective next_crypto kex methods slots.  Ensure to set all slots to
NULL in the error-out path.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2ced24ddd67a261dc364ad4d8958c068c1671ae7)
2014-12-17 19:45:23 +01:00
Andreas Schneider
055f102601 libcrypto: Fix Windows build with ssh_reseed().
gettimeofday() is not available on Windows and we need it only in case
of forking.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b7b535816d)
2014-12-17 19:40:57 +01:00
Andreas Schneider
2d6862ddb9 cmake: Fix the build on Windows.
(cherry picked from commit a738507ad2)
2014-12-17 19:31:32 +01:00
Andreas Schneider
22aa60d506 cmake: Fix config variable names.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d8e691b58a)
2014-12-17 10:40:31 +01:00
Andreas Schneider
4b02bbbd32 cmake: Fix libssh cmake-config files.
(cherry picked from commit 142b2e4ede)
2014-12-17 10:40:25 +01:00
William Orr
31ded2070e config: Also tokenize on equal sign.
The ssh config specifies it as a valid separator.

BUG: https://red.libssh.org/issues/166

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 52968b1a11)
2014-12-17 10:35:17 +01:00
Davide \"FunkyAss\" Del Zompo
df3d53e561 doc: clarify tutorial error section
Signed-off-by: Davide "FunkyAss" Del Zompo <davide.delzompo@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bb197de75d)
2014-12-05 11:09:34 +01:00
Hani Benhabiles
f28c3099da Set the correct error in ssh_options_set().
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 03095f1516)
2014-12-05 11:04:35 +01:00
Andreas Schneider
32a106c70d messages: Fix a possible double free.
Thanks to Ramana Gampa.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2014-12-05 10:59:41 +01:00
Jon Simons
5d75090d9f pki_crypto.c: plug ecdsa_sig->[r,s] bignum leaks
Per ecdsa(3ssl), ECDSA_SIG_new does allocate its 'r' and 's' bignum fields.
Fix a bug where the initial 'r' and 's' bignums were being overwritten with
newly-allocated bignums, resulting in a memory leak.

BUG: https://red.libssh.org/issues/175

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>

(cherry picked from commit 4745d652b5)
2014-12-05 10:46:31 +01:00
Andreas Schneider
32a3cfe661 connect: Do not fail if the connect is in progress.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a48711ae7e)
2014-10-28 10:33:47 +01:00
Stef Walter
1c59844dfe gssapi: ssh_gssapi_set_creds() is a client side function
It should not be guarded by the WITH_SERVER #ifdef

Signed-off-by: Stef Walter <stefw@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cd2dc3770a)
2014-10-12 15:47:13 +02:00
William Orr
f071954a76 Check return code of connect(2).
Signed-off-by: William Orr <will@worrbase.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 250f506487)
2014-10-12 15:47:12 +02:00
Artyom V. Poptsov
a033b93c61 pki_gcrypt: Initialize 'type_c' in 'pki_do_sign_sessionid'
Add missing initialization of 'type_c' field of a SSH signature in
'pki_do_sign_sessionid' procedure.

If libssh is compiled with GCrypt, 'dh_handshake_server' fails with
"Could not sign the session id" error.  The change fixes that.

Signed-off-by: Artyom V. Poptsov <poptsov.artyom@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aaae6cd97d)
2014-10-02 08:30:30 +02:00
Jon Simons
b7856780a9 crypto: check malloc return in ssh_mac_ctx_init
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit af25c5e668)
2014-10-02 08:26:08 +02:00
Jon Simons
8b3425865a wrapper: fix z_stream leak
Ensure to free the z_stream structures as allocated from
the gzip.c initcompress, initdecompress functions.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 092fe0b727)
2014-10-02 08:25:27 +02:00
Andreas Schneider
a30e234c03 string: Correctly burn the string buffer.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
(cherry picked from commit 1ddb99c46f)
2014-09-15 20:46:06 +02:00
Jon Simons
bbf172a79c session: fix ssh_session->srv.ecdsa_key leak
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-28 10:24:01 +02:00
Andreas Schneider
f28748578d pki: Fix build without ECC support.
Signed-off-by: Andreas Schneider <asn@samba.org>
2014-05-09 08:56:10 +02:00
Andreas Schneider
36f7d1a614 pki: Add missing semi-colon. 2014-05-07 09:36:11 +02:00
Andreas Schneider
71241ca68c pki: Move ssh_pki_key_ecdsa_name() to the correct file. 2014-05-07 09:35:49 +02:00
Andreas Schneider
bfbf9283d0 cmake: Fix doxygen. 2014-05-07 09:35:34 +02:00
Andreas Schneider
d75573e665 cmake: Update doxygen module. 2014-05-07 09:35:34 +02:00
Jon Simons
8fe36e3d07 pki crypto: expose new ssh_pki_key_ecdsa_name API
Enable retrieving the "ecdsa-sha2-nistpNNN" name of ECDSA keys with a
new 'ssh_pki_key_ecdsa_name' API.  This gives more information than the
'ssh_key_type_to_char' API, which yields "ssh-ecdsa" for ECDSA keys.
The motivation is that this info is useful to have in a server context.

The torture_pki unit test is updated to include the new API, and a few
more passes are added to additionally test 384 and 521-bit keys.

Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-07 09:35:06 +02:00
Alan Dunn
f2e9ce68e7 messages: Add missing ntohl on X11 request screen number
BUG: https://red.libssh.org/issues/160

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-05-06 08:56:55 +02:00
Andreas Schneider
cfb4d27c47 pki: Correctly update the ECDSA keytype.
(cherry picked from commit 2884bbf5b1)
2014-05-06 08:54:11 +02:00
Andreas Schneider
d366e289f3 pki: Move ssh_pki_key_ecdsa_name() to the correct file.
(cherry picked from commit f48a99b97c)
2014-05-06 08:54:06 +02:00
Andreas Schneider
2fc8347504 pki: Make pki_key_ecdsa_nid_to_name() a shared function.
(cherry picked from commit 11cfb2903e)
2014-05-06 08:54:00 +02:00
Andreas Schneider
2691ed595e cmake: Install cmake config files to the correct directory.
(cherry picked from commit 291312c5e4)
2014-04-22 09:10:05 +02:00
Andreas Schneider
7b133cf9f5 doc: Improve docs for ssh_channel_get_exit_status().
BUG: https://red.libssh.org/issues/154
(cherry picked from commit adf23533e0)
2014-04-22 09:09:57 +02:00
Andreas Schneider
9b59f1a222 channels: Fix exit-signal request.
BUG: https://red.libssh.org/issues/153
(cherry picked from commit 927cd90dc1)
2014-04-22 09:09:56 +02:00
Andreas Schneider
8f21f879d3 session: Fix a memory leak with custom banner.
BUG: https://red.libssh.org/issues/152
(cherry picked from commit b5efbe75cd)
2014-04-22 09:09:39 +02:00
Andreas Schneider
67752dabfc cmake: Enable creation of the compile command database by default.
(cherry picked from commit 437a39c798)
2014-04-22 09:09:28 +02:00
Jon Simons
34ac4e4248 packet: elide two buffer_prepend calls into one
In packet_send2, rather than issue two separate buffer_prepend_data calls
(each of which may entail realloc + memmove + memcpy), elide the prepend
work into a single buffer_prepend_data: the header information is computed
locally, and a single 5 byte prepend operation is now done instead of
prepending 1, then 4 bytes.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit aa05248ca8)

Conflicts:
	src/packet.c
2014-03-27 11:25:15 +01:00
Andreas Schneider
1928fb6a85 doc: Fix ssh_userauth_none() function signature.
Thanks to David Tibbe!

BUG: https://red.libssh.org/issues/151
(cherry picked from commit 04543c9dbc)
2014-03-27 11:16:23 +01:00
Alan Dunn
5b1678f197 doc: Improve and consolidate ssh_bind_options_set docs
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 47bd0b6d1f)
2014-03-27 11:15:39 +01:00
Petar Koretic
8aff91dfcb libssh: libhpp: overload read function to support timeout parameter
Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8e2590b535)
2014-03-27 11:15:39 +01:00
Petar Koretic
c0cc12d582 libssh: libhpp: avoid unnecessary call to ssh_channel_read
ssh_channel_read is a wrapper for ssh_channel_read_timeout with timeout
-1 (infinite) so we call that directly.

Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c51f42a566)
2014-03-27 11:15:39 +01:00
Petar Koretic
a162071f9a libssh: libhpp: fix multiple definitions for acceptForward function
Defining a non inlined class function in a header will cause multiple
definitions when header is included in more that one file since for each
file function will get defined.

Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 00d4fbe753)

Conflicts:
	include/libssh/libsshpp.hpp
2014-03-27 11:15:19 +01:00
Jon Simons
2091dab273 channel: check for closed state in waitwindow loops
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dee8e5688b)
2014-03-27 11:14:25 +01:00
Jon Simons
7f18ec4620 kex: enable more ECDSA hostkey algos
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 40d81bb7ca)
2014-03-27 11:14:25 +01:00
Jon Simons
8e698382db pki_crypto: guard against NULL pubkey->rsa in signature extraction
Signed-off-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 10bc5ac203)
2014-03-27 11:14:25 +01:00
Luka Perkov
ce10d40325 session: fix comment typo
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 8ba9402282)
2014-03-27 11:14:25 +01:00
Luka Perkov
3fed9a5aff messages: use predefined macro for clearing sensitive data
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a2fe341da5)
2014-03-27 11:14:25 +01:00
Luka Perkov
da0c77fdb1 client: fix corner case when sockets are manually created
If the sockets are created manually and passed to libssh the internal session
state is set to SSH_SESSION_STATE_SOCKET_CONNECTED. Result of this fix can be
verified by running torture_connect test (torture_connect_socket) with -vvvv
flags.

Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dbb2de272b)
2014-03-27 11:14:25 +01:00
Luka Perkov
818c80baed tests: torture_connect: add test for user provided socket
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9423a3a065)
2014-03-27 11:14:25 +01:00
Luka Perkov
bb55bb2daf tests: torture_connect: fix coding style
Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0c5d4954a7)
2014-03-27 11:14:25 +01:00
Petar Koretic
fdced9d544 pki_crypto: Replace deprecated RSA_generate_key() with RSA_generate_key_ex()
On Mar 16, 09:41, Aris Adamantiadis wrote:
> Hi Petar,
> I agree with the principle, but I don't think this code can work...
> RSA_generate_key takes an RSA* as parameter and in our code we probably
> have key->rsa==NULL. (if we don't then the old code had a memory leak).
>
> Does the test case work ?
>
> Aris
>

Yes, you are right. This works, tested with tests/unittests/torture_pki

Signed-off-by: Petar Koretic <petar.koretic@sartura.hr>
(cherry picked from commit 0b8d24f800)
2014-03-27 11:14:25 +01:00
Luka Perkov
96db44ff17 update gitignore file
The libssh library by default does not allow in-source build (with cmake
MacroEnsureOutOfSourceBuild macro). The INSTALL file (implicitly) suggests
creating a build directory. So lets add build to list of git ignore files to
avoid complaints from git.

Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 48354f56ec)
2014-03-27 11:14:25 +01:00
Alan Dunn
70dbbfa320 doc: Add ECDSA keys to docs, make key docs consistent
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f6276fe739)
2014-03-27 11:13:15 +01:00
Alan Dunn
1118fc2adf options: Allow use of host ECDSA key
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2a1089d607)
2014-03-27 11:13:15 +01:00
Andreas Schneider
257449a0b6 tests: Check the the ecdsa_nid is the same.
(cherry picked from commit fbf73ede1e)
2014-03-27 11:13:15 +01:00
Alan Dunn
8752460df4 tests: Add test case for bug #147
Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 577840d7f7)
2014-03-27 11:13:15 +01:00
Alan Dunn
6f089a098b pki_crypto: Always copy ecdsa_nid into duplicated ECDSA keys
BUG: https://red.libssh.org/issues/147

Signed-off-by: Alan Dunn <amdunn@gmail.com>
2014-03-12 14:16:43 +01:00
Alan Dunn
8b3be050c9 pki: Use SHA-2 for session ID signing with ECDSA keys
Previously, SHA-1 was used always.

BUG: https://red.libssh.org/issues/148

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:35 +01:00
Luka Perkov
ade33474be server: silence build warning
The commit fixes this build warning:

====
src/server.c:223:8: warning: ‘privkey’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     rc = ssh_pki_export_privkey_to_pubkey(*privkey, &pubkey);
        ^
src/server.c:243:11: note: ‘privkey’ was declared here
   ssh_key privkey;
====

Signed-off-by: Luka Perkov <luka.perkov@sartura.hr>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:33 +01:00
Jon Simons
dbf7749696 packet: log disconnect code in host byte order
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:30 +01:00
Jon Simons
2db45dd547 bind: only set bindfd after successful listen
In 'ssh_bind_listen', move setting of 'sshbind->bindfd' to only happen after
the listen call: otherwise 'bindfd' can be set to a bogus descriptor for the
case that listen fails.

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2014-03-12 14:16:28 +01:00
53 changed files with 935 additions and 1993 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@
build build
cscope.* cscope.*
tags tags
build

View File

@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
set(APPLICATION_VERSION_MAJOR "0") set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "6") set(APPLICATION_VERSION_MINOR "6")
set(APPLICATION_VERSION_PATCH "3") set(APPLICATION_VERSION_PATCH "5")
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}") set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
@@ -19,7 +19,7 @@ set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINO
# Increment AGE. Set REVISION to 0 # Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes: # If the source code was changed, but there were no interface changes:
# Increment REVISION. # Increment REVISION.
set(LIBRARY_VERSION "4.4.1") set(LIBRARY_VERSION "4.5.1")
set(LIBRARY_SOVERSION "4") set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
@@ -97,18 +97,22 @@ install(
) )
# cmake config files # cmake config files
configure_file(libssh-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake @ONLY) set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
configure_file(libssh-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake @ONLY) set(LIBSSH_THREADS_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)
install( install(
FILES FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
DESTINATION DESTINATION
${CMAKE_INSTALL_DIR} ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
COMPONENT COMPONENT
devel devel
) )
# in tree build settings # in tree build settings
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY) configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)

View File

@@ -1,6 +1,32 @@
ChangeLog ChangeLog
========== ==========
version 0.6.5 (released 2015-04-29)
* Fixed CVE-2015-3146
* Fixed port handling in config file
* Fixed the build with libgcrypt
* Fixed SFTP endian issues (rlo #179)
* Fixed uninitilized sig variable (rlo #167)
* Fixed polling issues which could result in a hang
* Fixed handling of EINTR in ssh_poll() (rlo #186)
* Fixed C99 issues with __func__
* Fixed some memory leaks
* Improved macro detection on Windows
version 0.6.4 (released 2014-12-19)
* Fixed CVE-2014-8132.
* Added SHA-2 for session ID signing with ECDSA keys.
* Added support for ECDSA host keys.
* Added support for more ECDSA hostkey algorithms.
* Added ssh_pki_key_ecdsa_name() API.
* Fixed setting the bindfd only after successful listen.
* Fixed issues with user created sockets.
* Fixed several issues in libssh C++ wrapper.
* Fixed several documentation issues.
* Fixed channel exit-signal request.
* Fixed X11 request screen number in messages.
* Fixed several memory leaks.
version 0.6.3 (released 2014-03-04) version 0.6.3 (released 2014-03-04)
* Fixed CVE-2014-0017. * Fixed CVE-2014-0017.
* Fixed memory leak with ecdsa signatures. * Fixed memory leak with ecdsa signatures.

View File

@@ -51,6 +51,7 @@ check_include_file(pty.h HAVE_PTY_H)
check_include_file(termios.h HAVE_TERMIOS_H) check_include_file(termios.h HAVE_TERMIOS_H)
check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(util.h HAVE_UTIL_H) check_include_file(util.h HAVE_UTIL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
if (WIN32) if (WIN32)
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H) check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
@@ -98,11 +99,6 @@ check_function_exists(isblank HAVE_ISBLANK)
check_function_exists(strncpy HAVE_STRNCPY) check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(vsnprintf HAVE_VSNPRINTF) check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF) check_function_exists(snprintf HAVE_SNPRINTF)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_function_exists(ntohll HAVE_NTOHLL)
check_function_exists(htonll HAVE_HTONLL)
if (WIN32) if (WIN32)
check_function_exists(_strtoui64 HAVE__STRTOUI64) check_function_exists(_strtoui64 HAVE__STRTOUI64)
@@ -113,17 +109,28 @@ if (WIN32)
check_function_exists(_snprintf_s HAVE__SNPRINTF_S) check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H) if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_GETADDRINFO TRUE) check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL)
set(HAVE_GETHOSTBYNAME TRUE) check_symbol_exists(htonll winsock2.h HAVE_HTONLL)
if (MSVC)
set(HAVE_NTOHLL TRUE) set(CMAKE_REQUIRED_LIBRARIES ws2_32)
set(HAVE_HTONLL TRUE) check_symbol_exists(select "winsock2.h;ws2tcpip.h" HAVE_SELECT)
endif (MSVC) check_symbol_exists(poll "winsock2.h;ws2tcpip.h" HAVE_SELECT)
# The getaddrinfo function is defined to the WspiapiGetAddrInfo inline function
check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" HAVE_GETADDRINFO)
set(CMAKE_REQUIRED_LIBRARIES)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H) endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_SELECT TRUE) set(HAVE_SELECT TRUE)
else (WIN32)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_symbol_exists(ntohll arpa/inet.h HAVE_NTOHLL)
check_symbol_exists(htonll arpa/inet.h HAVE_HTONLL)
endif (WIN32) endif (WIN32)
if (UNIX) if (UNIX)
if (NOT LINUX) if (NOT LINUX)
# libsocket (Solaris) # libsocket (Solaris)
@@ -200,6 +207,20 @@ int main(void)
return 0; return 0;
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION) }" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __func__);
return 0;
}" HAVE_COMPILER__FUNC__)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __FUNCTION__);
return 0;
}" HAVE_COMPILER__FUNCTION__)
if (WITH_DEBUG_CRYPTO) if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1) set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO) endif (WITH_DEBUG_CRYPTO)

View File

@@ -25,3 +25,6 @@ if (NOT CMAKE_BUILD_TYPE)
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
) )
endif (NOT CMAKE_BUILD_TYPE) endif (NOT CMAKE_BUILD_TYPE)
# Create the compile command database for clang by default
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

View File

@@ -2,10 +2,18 @@
# #
# Adds a doxygen target that runs doxygen to generate the html # Adds a doxygen target that runs doxygen to generate the html
# and optionally the LaTeX API documentation. # and optionally the LaTeX API documentation.
# The doxygen target is added to the doc target as dependency. # The doxygen target is added to the doc target as a dependency.
# i.e.: the API documentation is built with: # i.e.: the API documentation is built with:
# make doc # make doc
# #
# USAGE: GLOBAL INSTALL
#
# Install it with:
# cmake ./ && sudo make install
# Add the following to the CMakeLists.txt of your project:
# include(UseDoxygen OPTIONAL)
# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it.
#
# USAGE: INCLUDE IN PROJECT # USAGE: INCLUDE IN PROJECT
# #
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) # set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
@@ -13,88 +21,120 @@
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory. # Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
# #
# #
# CONFIGURATION
#
# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake.
# Variables you may define are: # Variables you may define are:
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. Defaults to "doc". # DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are.
# # Defaults to the current source directory.
# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is stored. Defaults to "latex". # DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan.
# # The Paths should be in double quotes and separated by space. e.g.:
# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is stored. Defaults to "html". # "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/"
#
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored.
# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc".
#
# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation
# to be built.
# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
# the Doxygen LaTeX output is stored. Defaults to "latex".
#
# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
# the Doxygen html output is stored. Defaults to "html".
# #
# #
# Copyright (c) 2009-2010 Tobias Rautenkranz <tobias@rautenkranz.ch> # Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz <tobias@rautenkranz.ch>
# Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.org>
# #
# Redistribution and use is allowed according to the terms of the New # Redistribution and use is allowed according to the terms of the New
# BSD license. # BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# #
macro(usedoxygen_set_default name value) macro(usedoxygen_set_default name value type docstring)
if(NOT DEFINED "${name}") if(NOT DEFINED "${name}")
set("${name}" "${value}") set("${name}" "${value}" CACHE "${type}" "${docstring}")
endif() endif()
endmacro() endmacro()
find_package(Doxygen) find_package(Doxygen)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
find_file(DOXYFILE_IN find_file(DOXYFILE_IN "Doxyfile.in"
NAMES PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/"
doxy.config.in NO_DEFAULT_PATH
PATHS DOC "Path to the doxygen configuration template file")
${CMAKE_CURRENT_SOURCE_DIR} set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
${CMAKE_ROOT}/Modules/ include(FindPackageHandleStandardArgs)
NO_DEFAULT_PATH) find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
endif() endif()
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND) if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config) usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc"
PATH "Doxygen output directory")
usedoxygen_set_default(DOXYFILE_HTML_DIR "html"
STRING "Doxygen HTML output directory")
usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
PATH "Input files source directory")
usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS ""
STRING "Additional source files/directories separated by space")
set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}")
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF)
usedoxygen_set_default(DOXYFILE_HTML_DIR "html") usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory")
set_property(DIRECTORY APPEND PROPERTY mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR
ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}") DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN)
set(DOXYFILE_LATEX FALSE)
set(DOXYFILE_PDFLATEX FALSE)
set(DOXYFILE_DOT FALSE)
#find_package(LATEX) set_property(DIRECTORY
#if(LATEX_COMPILER AND MAKEINDEX_COMPILER) APPEND PROPERTY
# set(DOXYFILE_LATEX TRUE) ADDITIONAL_MAKE_CLEAN_FILES
# usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex") "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
#
# set_property(DIRECTORY APPEND PROPERTY
# ADDITIONAL_MAKE_CLEAN_FILES
# "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
#
# if(PDFLATEX_COMPILER)
# set(DOXYFILE_PDFLATEX TRUE)
# endif()
# if(DOXYGEN_DOT_EXECUTABLE)
# set(DOXYFILE_DOT TRUE)
# endif()
#
# add_custom_command(TARGET doxygen
# POST_BUILD
# COMMAND ${CMAKE_MAKE_PROGRAM}
# WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
#endif()
configure_file(${DOXYFILE_IN} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config ESCAPE_QUOTES IMMEDIATE @ONLY) add_custom_target(doxygen
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in) COMMAND "${DOXYGEN_EXECUTABLE}"
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac ESCAPE_QUOTES IMMEDIATE @ONLY) "${DOXYFILE}"
add_custom_target(doxygen-trac ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac) COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..."
endif() WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
get_target_property(DOC_TARGET doc TYPE) set(DOXYFILE_DOT "NO")
if(NOT DOC_TARGET) if(DOXYGEN_DOT_EXECUTABLE)
add_custom_target(doc) set(DOXYFILE_DOT "YES")
endif() endif()
add_dependencies(doc doxygen) ## LaTeX
set(DOXYFILE_PDFLATEX "NO")
set_property(DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
if(DOXYFILE_LATEX STREQUAL "ON")
set(DOXYFILE_GENERATE_LATEX "YES")
find_package(LATEX)
find_program(DOXYFILE_MAKE make)
mark_as_advanced(DOXYFILE_MAKE)
if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE)
if(PDFLATEX_COMPILER)
set(DOXYFILE_PDFLATEX "YES")
endif()
add_custom_command(TARGET doxygen
POST_BUILD
COMMAND "${DOXYFILE_MAKE}"
COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..."
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
else()
set(DOXYGEN_LATEX "NO")
endif()
else()
set(DOXYFILE_GENERATE_LATEX "NO")
endif()
configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY)
add_custom_target(doc)
add_dependencies(doc doxygen)
endif() endif()

View File

@@ -23,6 +23,9 @@
/* Define to 1 if you have the <util.h> header file. */ /* Define to 1 if you have the <util.h> header file. */
#cmakedefine HAVE_UTIL_H 1 #cmakedefine HAVE_UTIL_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <termios.h> header file. */ /* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H 1 #cmakedefine HAVE_TERMIOS_H 1
@@ -136,6 +139,9 @@
#cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1 #cmakedefine HAVE_GCC_VOLATILE_MEMORY_PROTECTION 1
#cmakedefine HAVE_COMPILER__FUNC__ 1
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
/* Define to 1 if you want to enable GSSAPI */ /* Define to 1 if you want to enable GSSAPI */
#cmakedefine WITH_GSSAPI 1 #cmakedefine WITH_GSSAPI 1

View File

@@ -285,7 +285,7 @@ int authenticate_kbdint(ssh_session session)
{ {
int rc; int rc;
rc = ssh_userauth_none(session, NULL, NULL); rc = ssh_userauth_none(session, NULL);
return rc; return rc;
} }
@endcode @endcode
@@ -304,7 +304,7 @@ int test_several_auth_methods(ssh_session session)
{ {
int method, rc; int method, rc;
rc = ssh_userauth_none(session, NULL, NULL); rc = ssh_userauth_none(session, NULL);
if (rc != SSH_AUTH_SUCCESS) { if (rc != SSH_AUTH_SUCCESS) {
return rc; return rc;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -443,11 +443,10 @@ 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. (generaly the ssh_request_xxx ones) may fail because of server denying request.
In these cases, SSH_REQUEST_DENIED is returned. In these cases, SSH_REQUEST_DENIED is returned.
ssh_get_error() and ssh_get_error_code() take a ssh_session as a parameter. For thread safety, errors are bound to ssh_session objects.
That's for thread safety, error messages that can be attached to a session As long as your ssh_session object is not NULL, you can retrieve the last error
aren't static anymore. Any error that happens during ssh_options_xxx() message and error code from the ssh_session using ssh_get_error() and
or ssh_connect() (i.e., outside of any session) can be retrieved by ssh_get_error_code() respectively.
giving NULL as argument.
The SFTP subsystem has its own error codes, in addition to libssh ones. The SFTP subsystem has its own error codes, in addition to libssh ones.

View File

@@ -5,6 +5,7 @@ set(libssh_HDRS
libssh.h libssh.h
ssh2.h ssh2.h
legacy.h legacy.h
libsshpp.hpp
) )
if (WITH_SFTP) if (WITH_SFTP)

View File

@@ -49,7 +49,9 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int hashbufout_add_cookie(ssh_session session); int hashbufout_add_cookie(ssh_session session);
int generate_session_keys(ssh_session session); int generate_session_keys(ssh_session session);
bignum make_string_bn(ssh_string string); bignum make_string_bn(ssh_string string);
#ifdef HAVE_LIBCRYPTO
void make_string_bn_inplace(ssh_string string, bignum bnout);
#endif /* HAVE_LIBCRYPTO */
ssh_string make_bignum_string(bignum num); ssh_string make_bignum_string(bignum num);
#endif /* DH_H_ */ #endif /* DH_H_ */

View File

@@ -78,7 +78,7 @@
/* libssh version */ /* libssh version */
#define LIBSSH_VERSION_MAJOR 0 #define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 6 #define LIBSSH_VERSION_MINOR 6
#define LIBSSH_VERSION_MICRO 3 #define LIBSSH_VERSION_MICRO 5
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \ #define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \ LIBSSH_VERSION_MINOR, \
@@ -534,6 +534,8 @@ LIBSSH_API int ssh_pki_export_pubkey_base64(const ssh_key key,
LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key, LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
const char *filename); const char *filename);
LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key);
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len); LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data); LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display); LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);

View File

@@ -361,8 +361,8 @@ public:
* @see ssh_channel_forward_accept * @see ssh_channel_forward_accept
* @see Session::listenForward * @see Session::listenForward
*/ */
Channel *acceptForward(int timeout_ms); inline Channel *acceptForward(int timeout_ms);
/* acceptForward is implemented later in this file */ /* implemented outside the class due Channel references */
void_throwable cancelForward(const char *address, int port){ void_throwable cancelForward(const char *address, int port){
int err=ssh_forward_cancel(c_session, address, port); int err=ssh_forward_cancel(c_session, address, port);
@@ -480,12 +480,30 @@ public:
ssh_throw(err); ssh_throw(err);
return err; return err;
} }
int read(void *dest, size_t count, bool is_stderr=false){ int read(void *dest, size_t count, bool is_stderr){
int err; int err;
/* handle int overflow */ /* handle int overflow */
if(count > 0x7fffffff) if(count > 0x7fffffff)
count = 0x7fffffff; count = 0x7fffffff;
err=ssh_channel_read(channel,dest,count,is_stderr); err=ssh_channel_read_timeout(channel,dest,count,is_stderr,-1);
ssh_throw(err);
return err;
}
int read(void *dest, size_t count, int timeout){
int err;
/* handle int overflow */
if(count > 0x7fffffff)
count = 0x7fffffff;
err=ssh_channel_read_timeout(channel,dest,count,false,timeout);
ssh_throw(err);
return err;
}
int read(void *dest, size_t count, bool is_stderr=false, int timeout=-1){
int err;
/* handle int overflow */
if(count > 0x7fffffff)
count = 0x7fffffff;
err=ssh_channel_read_timeout(channel,dest,count,is_stderr,timeout);
ssh_throw(err); ssh_throw(err);
return err; return err;
} }

View File

@@ -29,11 +29,12 @@
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----" #define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
#define ssh_pki_log(...) \ #define ssh_pki_log(...) \
_ssh_pki_log(__FUNCTION__, __VA_ARGS__) _ssh_log(SSH_LOG_FUNCTIONS, __func__, __VA_ARGS__)
void _ssh_pki_log(const char *function, void _ssh_pki_log(const char *function,
const char *format, ...) PRINTF_ATTRIBUTE(2, 3); const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
int pki_key_ecdsa_nid_from_name(const char *name); int pki_key_ecdsa_nid_from_name(const char *name);
const char *pki_key_ecdsa_nid_to_name(int nid);
/* SSH Key Functions */ /* SSH Key Functions */
ssh_key pki_key_dup(const ssh_key key, int demote); ssh_key pki_key_dup(const ssh_key key, int demote);

View File

@@ -139,10 +139,12 @@ int gettimeofday(struct timeval *__p, void *__t);
#define MAX_BUF_SIZE 4096 #define MAX_BUF_SIZE 4096
#endif #endif
#ifndef __FUNCTION__ #ifndef HAVE_COMPILER__FUNC__
#if defined(__SUNPRO_C) # ifdef HAVE_COMPILER__FUNCTION__
#define __FUNCTION__ __func__ # define __func__ __FUNCTION__
#endif # else
# error "Your system must provide a __func__ macro"
# endif
#endif #endif
#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
@@ -179,7 +181,7 @@ void ssh_log_function(int verbosity,
const char *function, const char *function,
const char *buffer); const char *buffer);
#define SSH_LOG(priority, ...) \ #define SSH_LOG(priority, ...) \
_ssh_log(priority, __FUNCTION__, __VA_ARGS__) _ssh_log(priority, __func__, __VA_ARGS__)
/* LEGACY */ /* LEGACY */
void ssh_log_common(struct ssh_common_struct *common, void ssh_log_common(struct ssh_common_struct *common,
@@ -197,18 +199,18 @@ struct error_struct {
}; };
#define ssh_set_error(error, code, ...) \ #define ssh_set_error(error, code, ...) \
_ssh_set_error(error, code, __FUNCTION__, __VA_ARGS__) _ssh_set_error(error, code, __func__, __VA_ARGS__)
void _ssh_set_error(void *error, void _ssh_set_error(void *error,
int code, int code,
const char *function, const char *function,
const char *descr, ...) PRINTF_ATTRIBUTE(4, 5); const char *descr, ...) PRINTF_ATTRIBUTE(4, 5);
#define ssh_set_error_oom(error) \ #define ssh_set_error_oom(error) \
_ssh_set_error_oom(error, __FUNCTION__) _ssh_set_error_oom(error, __func__)
void _ssh_set_error_oom(void *error, const char *function); void _ssh_set_error_oom(void *error, const char *function);
#define ssh_set_error_invalid(error) \ #define ssh_set_error_invalid(error) \
_ssh_set_error_invalid(error, __FUNCTION__) _ssh_set_error_invalid(error, __func__)
void _ssh_set_error_invalid(void *error, const char *function); void _ssh_set_error_invalid(void *error, const char *function);

View File

@@ -44,7 +44,8 @@ enum ssh_bind_options_e {
SSH_BIND_OPTIONS_RSAKEY, SSH_BIND_OPTIONS_RSAKEY,
SSH_BIND_OPTIONS_BANNER, SSH_BIND_OPTIONS_BANNER,
SSH_BIND_OPTIONS_LOG_VERBOSITY, SSH_BIND_OPTIONS_LOG_VERBOSITY,
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
SSH_BIND_OPTIONS_ECDSAKEY
}; };
typedef struct ssh_bind_struct* ssh_bind; typedef struct ssh_bind_struct* ssh_bind;
@@ -80,69 +81,6 @@ typedef struct ssh_bind_callbacks_struct *ssh_bind_callbacks;
*/ */
LIBSSH_API ssh_bind ssh_bind_new(void); LIBSSH_API ssh_bind ssh_bind_new(void);
/**
* @brief Set the options for the current SSH server bind.
*
* @param sshbind The ssh server bind to configure.
*
* @param type The option type to set. This could be one of the
* following:
*
* - SSH_BIND_OPTIONS_BINDADDR
* The ip address to bind (const char *).
*
* - SSH_BIND_OPTIONS_BINDPORT
* The port to bind (unsigned int).
*
* - SSH_BIND_OPTIONS_BINDPORT_STR
* The port to bind (const char *).
*
* - SSH_BIND_OPTIONS_HOSTKEY
* This specifies the file containing the private host key used
* by SSHv1. (const char *).
*
* - SSH_BIND_OPTIONS_DSAKEY
* This specifies the file containing the private host dsa key
* used by SSHv2. (const char *).
*
* - SSH_BIND_OPTIONS_RSAKEY
* This specifies the file containing the private host dsa key
* used by SSHv2. (const char *).
*
* - SSH_BIND_OPTIONS_BANNER
* That the server banner (version string) for SSH.
* (const char *).
*
* - SSH_BIND_OPTIONS_LOG_VERBOSITY
* Set the session logging verbosity (int).\n
* \n
* The verbosity of the messages. Every log smaller or
* equal to verbosity will be shown.
* - SSH_LOG_NOLOG: No logging
* - SSH_LOG_RARE: Rare conditions or warnings
* - SSH_LOG_ENTRY: API-accessible entrypoints
* - SSH_LOG_PACKET: Packet id and size
* - SSH_LOG_FUNCTIONS: Function entering and leaving
*
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR
* Set the session logging verbosity (const char *).\n
* \n
* The verbosity of the messages. Every log smaller or
* equal to verbosity will be shown.
* - SSH_LOG_NOLOG: No logging
* - SSH_LOG_RARE: Rare conditions or warnings
* - SSH_LOG_ENTRY: API-accessible entrypoints
* - SSH_LOG_PACKET: Packet id and size
* - SSH_LOG_FUNCTIONS: Function entering and leaving
* \n
* See the corresponding numbers in libssh.h.
*
* @param value The value to set. This is a generic pointer and the
* datatype which is used should be set according to the
* type set.
*
* @returns SSH_OK on success, SSH_ERROR on invalid option or parameter.
*/
LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind, LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind,
enum ssh_bind_options_e type, const void *value); enum ssh_bind_options_e type, const void *value);

View File

@@ -7,5 +7,7 @@ else()
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@) set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
endif() endif()
set(LIBSSH_LIRBARY @LIB_INSTALL_DIR@/libssh.so) set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
set(LIBSSH_LIRBARIES @LIB_INSTALL_DIR@/libssh.so) set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@)

View File

@@ -1907,7 +1907,7 @@ int ssh_userauth_kbdint(ssh_session session, const char *user,
* This should not happen * This should not happen
*/ */
rc = SSH_AUTH_ERROR; rc = SSH_AUTH_ERROR;
ssh_set_error(session,SSH_FATAL,"Invalid state in %s", __FUNCTION__); ssh_set_error(session, SSH_FATAL, "Invalid state in %s", __func__);
} }
return rc; return rc;
} }

View File

@@ -254,7 +254,6 @@ int ssh_bind_listen(ssh_bind sshbind) {
sshbind->rsa = NULL; sshbind->rsa = NULL;
return -1; return -1;
} }
sshbind->bindfd = fd;
if (listen(fd, 10) < 0) { if (listen(fd, 10) < 0) {
ssh_set_error(sshbind, SSH_FATAL, ssh_set_error(sshbind, SSH_FATAL,
@@ -267,6 +266,8 @@ int ssh_bind_listen(ssh_bind sshbind) {
sshbind->rsa = NULL; sshbind->rsa = NULL;
return -1; return -1;
} }
sshbind->bindfd = fd;
} else { } else {
SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket"); SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket");
} }

View File

@@ -188,6 +188,10 @@ int buffer_reinit(struct ssh_buffer_struct *buffer) {
int buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len) { int buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len) {
buffer_verify(buffer); buffer_verify(buffer);
if (data == NULL) {
return -1;
}
if (buffer->used + len < len) { if (buffer->used + len < len) {
return -1; return -1;
} }
@@ -221,6 +225,10 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
struct ssh_string_struct *string) { struct ssh_string_struct *string) {
uint32_t len = 0; uint32_t len = 0;
if (string == NULL) {
return -1;
}
len = ssh_string_len(string); len = ssh_string_len(string);
if (buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) { if (buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
return -1; return -1;

View File

@@ -1238,7 +1238,8 @@ error:
static int ssh_channel_waitwindow_termination(void *c){ static int ssh_channel_waitwindow_termination(void *c){
ssh_channel channel = (ssh_channel) c; ssh_channel channel = (ssh_channel) c;
if (channel->remote_window > 0 || if (channel->remote_window > 0 ||
channel->session->session_state == SSH_SESSION_STATE_ERROR) channel->session->session_state == SSH_SESSION_STATE_ERROR ||
channel->state == SSH_CHANNEL_STATE_CLOSED)
return 1; return 1;
else else
return 0; return 0;
@@ -1345,7 +1346,8 @@ int channel_write_common(ssh_channel channel, const void *data,
ssh_channel_waitwindow_termination,channel); ssh_channel_waitwindow_termination,channel);
if (rc == SSH_ERROR || if (rc == SSH_ERROR ||
!ssh_channel_waitwindow_termination(channel) || !ssh_channel_waitwindow_termination(channel) ||
channel->session->session_state == SSH_SESSION_STATE_ERROR) channel->session->session_state == SSH_SESSION_STATE_ERROR ||
channel->state == SSH_CHANNEL_STATE_CLOSED)
goto out; goto out;
continue; continue;
} }
@@ -3022,6 +3024,11 @@ static int ssh_channel_exit_status_termination(void *c){
* (yet). * (yet).
* @warning This function may block until a timeout (or never) * @warning This function may block until a timeout (or never)
* if the other side is not willing to close the channel. * if the other side is not willing to close the channel.
*
* If you're looking for an async handling of this register a callback for the
* exit status.
*
* @see ssh_channel_exit_status_callback
*/ */
int ssh_channel_get_exit_status(ssh_channel channel) { int ssh_channel_get_exit_status(ssh_channel channel) {
int rc; int rc;
@@ -3460,9 +3467,9 @@ error:
} }
/** /**
* @brief Send an exit signal to remote process (as described in RFC 4254, section 6.10). * @brief Send an exit signal to remote process (RFC 4254, section 6.10).
* *
* Sends a signal 'sig' to the remote process. * This sends the exit status of the remote process.
* Note, that remote system may not support signals concept. * Note, that remote system may not support signals concept.
* In such a case this request will be silently ignored. * In such a case this request will be silently ignored.
* Only SSH-v2 is supported (I'm not sure about SSH-v1). * Only SSH-v2 is supported (I'm not sure about SSH-v1).
@@ -3540,7 +3547,7 @@ int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
goto error; goto error;
} }
rc = channel_request(channel, "signal", buffer, 0); rc = channel_request(channel, "exit-signal", buffer, 0);
error: error:
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
if(tmp) if(tmp)

View File

@@ -101,7 +101,8 @@ int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col
} }
session = channel->session; session = channel->session;
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){ if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE &&
channel->request_state != SSH_CHANNEL_REQ_STATE_ACCEPTED){
ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state"); ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
return SSH_ERROR; return SSH_ERROR;
} }

View File

@@ -60,12 +60,15 @@
static void socket_callback_connected(int code, int errno_code, void *user){ static void socket_callback_connected(int code, int errno_code, void *user){
ssh_session session=(ssh_session)user; ssh_session session=(ssh_session)user;
if(session->session_state != SSH_SESSION_STATE_CONNECTING){ if (session->session_state != SSH_SESSION_STATE_CONNECTING &&
session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED)
{
ssh_set_error(session,SSH_FATAL, "Wrong state in socket_callback_connected : %d", ssh_set_error(session,SSH_FATAL, "Wrong state in socket_callback_connected : %d",
session->session_state); session->session_state);
return; return;
} }
SSH_LOG(SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno_code); SSH_LOG(SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno_code);
if(code == SSH_SOCKET_CONNECTED_OK) if(code == SSH_SOCKET_CONNECTED_OK)
session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED; session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED;
@@ -523,7 +526,7 @@ int ssh_connect(ssh_session session) {
} else { } else {
ret=ssh_socket_connect(session->socket, ret=ssh_socket_connect(session->socket,
session->opts.host, session->opts.host,
session->opts.port, session->opts.port > 0 ? session->opts.port : 22,
session->opts.bindaddr); session->opts.bindaddr);
} }
if (ret == SSH_ERROR) { if (ret == SSH_ERROR) {

View File

@@ -128,7 +128,7 @@ static char *ssh_config_get_token(char **str) {
c = ssh_config_get_cmd(str); c = ssh_config_get_cmd(str);
for (r = c; *c; c++) { for (r = c; *c; c++) {
if (isblank(*c)) { if (isblank(*c) || *c == '=') {
*c = '\0'; *c = '\0';
goto out; goto out;
} }
@@ -245,7 +245,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
} }
break; break;
case SOC_PORT: case SOC_PORT:
if (session->opts.port == 22) { if (session->opts.port == 0) {
p = ssh_config_get_str_tok(&s, NULL); p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) { if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_PORT_STR, p); ssh_options_set(session, SSH_OPTIONS_PORT_STR, p);

View File

@@ -64,6 +64,10 @@
#include <wspiapi.h> #include <wspiapi.h>
#endif #endif
#ifndef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif
#else /* _WIN32 */ #else /* _WIN32 */
#include <netdb.h> #include <netdb.h>
@@ -285,6 +289,7 @@ socket_t ssh_connect_host(ssh_session session, const char *host,
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr, socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
timeout, usec, s); timeout, usec, s);
freeaddrinfo(ai);
return ret; return ret;
} }
@@ -382,7 +387,16 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
continue; continue;
} }
connect(s, itr->ai_addr, itr->ai_addrlen); errno = 0;
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
ssh_set_error(session, SSH_FATAL,
"Failed to connect: %s", strerror(errno));
ssh_connect_socket_close(s);
s = -1;
continue;
}
break; break;
} }

View File

@@ -407,6 +407,18 @@ bignum make_string_bn(ssh_string string){
return bn; return bn;
} }
#ifdef HAVE_LIBCRYPTO
/** @internal
* @brief converts the content of a SSH string in an already allocated bignum
* @warning only available with OpenSSL builds
*/
void make_string_bn_inplace(ssh_string string, bignum bnout) {
unsigned int len = ssh_string_len(string);
bignum_bin2bn(string->data, len, bnout);
}
#endif /* HAVE_LIBCRYPTO */
ssh_string dh_get_e(ssh_session session) { ssh_string dh_get_e(ssh_session session) {
return make_bignum_string(session->next_crypto->e); return make_bignum_string(session->next_crypto->e);
} }

View File

@@ -539,8 +539,12 @@ ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session){
return (ssh_gssapi_creds)session->gssapi->client_creds; return (ssh_gssapi_creds)session->gssapi->client_creds;
} }
#endif /* SERVER */
/** /**
* @brief Set the forwadable ticket to be given to the server for authentication. * @brief Set the forwadable ticket to be given to the server for authentication.
* Unlike ssh_gssapi_get_creds() this is called on the client side of an ssh
* connection.
* *
* @param[in] creds gssapi credentials handle. * @param[in] creds gssapi credentials handle.
*/ */
@@ -559,8 +563,6 @@ void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds)
session->gssapi->client.client_deleg_creds = (gss_cred_id_t)creds; session->gssapi->client.client_deleg_creds = (gss_cred_id_t)creds;
} }
#endif /* SERVER */
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){ static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
ssh_string str; ssh_string str;
int rc; int rc;

View File

@@ -73,7 +73,7 @@
#ifdef HAVE_ECDH #ifdef HAVE_ECDH
#define ECDH "ecdh-sha2-nistp256," #define ECDH "ecdh-sha2-nistp256,"
#define HOSTKEYS "ecdsa-sha2-nistp256,ssh-rsa,ssh-dss" #define HOSTKEYS "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
#else #else
#define HOSTKEYS "ssh-rsa,ssh-dss" #define HOSTKEYS "ssh-rsa,ssh-dss"
#define ECDH "" #define ECDH ""
@@ -315,7 +315,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
for (i = 0; i < KEX_METHODS_SIZE; i++) { for (i = 0; i < KEX_METHODS_SIZE; i++) {
str = buffer_get_ssh_string(packet); str = buffer_get_ssh_string(packet);
if (str == NULL) { if (str == NULL) {
break; goto error;
} }
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) { if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
@@ -350,6 +350,11 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
error: error:
ssh_string_free(str); ssh_string_free(str);
for (i = 0; i < SSH_KEX_METHODS; i++) { for (i = 0; i < SSH_KEX_METHODS; i++) {
if (server_kex) {
session->next_crypto->client_kex.methods[i] = NULL;
} else { /* client */
session->next_crypto->server_kex.methods[i] = NULL;
}
SAFE_FREE(strings[i]); SAFE_FREE(strings[i]);
} }

View File

@@ -435,7 +435,7 @@ int ssh_is_server_known(ssh_session session) {
return SSH_SERVER_ERROR; return SSH_SERVER_ERROR;
} }
host = ssh_lowercase(session->opts.host); host = ssh_lowercase(session->opts.host);
hostport = ssh_hostport(host, session->opts.port); hostport = ssh_hostport(host, session->opts.port > 0 ? session->opts.port : 22);
if (host == NULL || hostport == NULL) { if (host == NULL || hostport == NULL) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
SAFE_FREE(host); SAFE_FREE(host);
@@ -542,7 +542,7 @@ int ssh_write_knownhost(ssh_session session) {
host = ssh_lowercase(session->opts.host); host = ssh_lowercase(session->opts.host);
/* If using a nonstandard port, save the host in the [host]:port format */ /* If using a nonstandard port, save the host in the [host]:port format */
if(session->opts.port != 22) { if (session->opts.port > 0 && session->opts.port != 22) {
hostport = ssh_hostport(host, session->opts.port); hostport = ssh_hostport(host, session->opts.port);
SAFE_FREE(host); SAFE_FREE(host);
if (hostport == NULL) { if (hostport == NULL) {
@@ -682,7 +682,7 @@ char **ssh_knownhosts_algorithms(ssh_session session) {
} }
host = ssh_lowercase(session->opts.host); host = ssh_lowercase(session->opts.host);
hostport = ssh_hostport(host, session->opts.port); hostport = ssh_hostport(host, session->opts.port > 0 ? session->opts.port : 22);
array = malloc(sizeof(char *) * KNOWNHOSTS_MAXTYPES); array = malloc(sizeof(char *) * KNOWNHOSTS_MAXTYPES);
if (host == NULL || hostport == NULL || array == NULL) { if (host == NULL || hostport == NULL || array == NULL) {

View File

@@ -19,11 +19,14 @@
* MA 02111-1307, USA. * MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/session.h" #include "libssh/session.h"
@@ -78,9 +81,11 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
} }
void ssh_reseed(void){ void ssh_reseed(void){
#ifndef _WIN32
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
RAND_add(&tv, sizeof(tv), 0.0); RAND_add(&tv, sizeof(tv), 0.0);
#endif
} }
SHACTX sha1_init(void) { SHACTX sha1_init(void) {
@@ -202,7 +207,11 @@ void md5_final(unsigned char *md, MD5CTX c) {
} }
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){ ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
ssh_mac_ctx ctx=malloc(sizeof(struct ssh_mac_ctx_struct)); ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct));
if (ctx == NULL) {
return NULL;
}
ctx->mac_type=type; ctx->mac_type=type;
switch(type){ switch(type){
case SSH_MAC_SHA1: case SSH_MAC_SHA1:

View File

@@ -91,7 +91,11 @@ void md5_final(unsigned char *md, MD5CTX c) {
} }
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){ ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
ssh_mac_ctx ctx=malloc(sizeof(struct ssh_mac_ctx_struct)); ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct));
if (ctx == NULL) {
return NULL;
}
ctx->mac_type=type; ctx->mac_type=type;
switch(type){ switch(type){
case SSH_MAC_SHA1: case SSH_MAC_SHA1:

View File

@@ -508,8 +508,7 @@ void ssh_message_free(ssh_message msg){
case SSH_REQUEST_AUTH: case SSH_REQUEST_AUTH:
SAFE_FREE(msg->auth_request.username); SAFE_FREE(msg->auth_request.username);
if (msg->auth_request.password) { if (msg->auth_request.password) {
memset(msg->auth_request.password, 0, BURN_STRING(msg->auth_request.password);
strlen(msg->auth_request.password));
SAFE_FREE(msg->auth_request.password); SAFE_FREE(msg->auth_request.password);
} }
ssh_key_free(msg->auth_request.pubkey); ssh_key_free(msg->auth_request.pubkey);
@@ -1372,6 +1371,7 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight); msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
msg->channel_request.modes = buffer_get_ssh_string(packet); msg->channel_request.modes = buffer_get_ssh_string(packet);
if (msg->channel_request.modes == NULL) { if (msg->channel_request.modes == NULL) {
msg->channel_request.TERM = NULL;
SAFE_FREE(term_c); SAFE_FREE(term_c);
goto error; goto error;
} }
@@ -1470,6 +1470,7 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
if (strcmp(request, "x11-req") == 0) { if (strcmp(request, "x11-req") == 0) {
ssh_string auth_protocol = NULL; ssh_string auth_protocol = NULL;
ssh_string auth_cookie = NULL; ssh_string auth_cookie = NULL;
uint32_t screen_number;
buffer_get_u8(packet, &msg->channel_request.x11_single_connection); buffer_get_u8(packet, &msg->channel_request.x11_single_connection);
@@ -1497,7 +1498,8 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
ssh_string_free(auth_protocol); ssh_string_free(auth_protocol);
ssh_string_free(auth_cookie); ssh_string_free(auth_cookie);
buffer_get_u32(packet, &msg->channel_request.x11_screen_number); buffer_get_u32(packet, &screen_number);
msg->channel_request.x11_screen_number = ntohl(screen_number);
goto end; goto end;
} }

View File

@@ -512,7 +512,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
} }
session->opts.username = q; session->opts.username = q;
} else if (v[0] == '\0') { } else if (v[0] == '\0') {
ssh_set_error_oom(session); ssh_set_error_invalid(session);
return -1; return -1;
} else { /* username provided */ } else { /* username provided */
session->opts.username = strdup(value); session->opts.username = strdup(value);
@@ -531,7 +531,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
return -1; return -1;
} }
} else if (v[0] == '\0') { } else if (v[0] == '\0') {
ssh_set_error_oom(session); ssh_set_error_invalid(session);
return -1; return -1;
} else { } else {
session->opts.sshdir = ssh_path_expand_tilde(v); session->opts.sshdir = ssh_path_expand_tilde(v);
@@ -871,11 +871,14 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
if (session == NULL) { if (session == NULL) {
return -1; return -1;
} }
if (!session->opts.port) {
ssh_set_error_invalid(session); if (session->opts.port == 0) {
return -1; *port_target = 22;
return 0;
} }
*port_target = session->opts.port; *port_target = session->opts.port;
return 0; return 0;
} }
@@ -1303,65 +1306,89 @@ static int ssh_bind_options_set_algo(ssh_bind sshbind, int algo,
return 0; return 0;
} }
static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
const void *value) {
if (value == NULL) {
ssh_set_error_invalid(sshbind);
return -1;
} else {
SAFE_FREE(*key_loc);
*key_loc = strdup(value);
if (*key_loc == NULL) {
ssh_set_error_oom(sshbind);
return -1;
}
}
return 0;
}
/** /**
* @brief This function can set all possible ssh bind options. * @brief Set options for an SSH server bind.
* *
* @param sshbind An allocated ssh bind structure. * @param sshbind The ssh server bind to configure.
* *
* @param type The option type to set. This could be one of the * @param type The option type to set. This should be one of the
* following: * following:
* *
* SSH_BIND_OPTIONS_LOG_VERBOSITY: * - SSH_BIND_OPTIONS_HOSTKEY:
* Set the session logging verbosity (integer).
*
* The verbosity of the messages. Every log smaller or
* equal to verbosity will be shown.
* SSH_LOG_NOLOG: No logging
* SSH_LOG_RARE: Rare conditions or warnings
* SSH_LOG_ENTRY: API-accessible entrypoints
* SSH_LOG_PACKET: Packet id and size
* SSH_LOG_FUNCTIONS: Function entering and leaving
*
* SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
* Set the session logging verbosity (integer).
*
* The verbosity of the messages. Every log smaller or
* equal to verbosity will be shown.
* SSH_LOG_NOLOG: No logging
* SSH_LOG_RARE: Rare conditions or warnings
* SSH_LOG_ENTRY: API-accessible entrypoints
* SSH_LOG_PACKET: Packet id and size
* SSH_LOG_FUNCTIONS: Function entering and leaving
*
* SSH_BIND_OPTIONS_BINDADDR:
* Set the bind address.
*
* SSH_BIND_OPTIONS_BINDPORT:
* Set the bind port, default is 22.
*
* SSH_BIND_OPTIONS_HOSTKEY:
* Set the server public key type: ssh-rsa or ssh-dss * Set the server public key type: ssh-rsa or ssh-dss
* (string). * (const char *).
* *
* SSH_BIND_OPTIONS_DSAKEY: * - SSH_BIND_OPTIONS_BINDADDR:
* Set the path to the dsa ssh host key (string). * Set the IP address to bind (const char *).
* *
* SSH_BIND_OPTIONS_RSAKEY: * - SSH_BIND_OPTIONS_BINDPORT:
* Set the path to the ssh host rsa key (string). * Set the port to bind (unsigned int *).
* *
* SSH_BIND_OPTIONS_BANNER: * - SSH_BIND_OPTIONS_BINDPORT_STR:
* Set the server banner sent to clients (string). * Set the port to bind (const char *).
*
* - SSH_BIND_OPTIONS_LOG_VERBOSITY:
* Set the session logging verbosity (int *).
* The logging verbosity should have one of the
* following values, which are listed in order
* of increasing verbosity. Every log message
* with verbosity less than or equal to the
* logging verbosity will be shown.
* - SSH_LOG_NOLOG: No logging
* - SSH_LOG_RARE: Rare conditions or warnings
* - SSH_LOG_ENTRY: API-accessible entrypoints
* - SSH_LOG_PACKET: Packet id and size
* - SSH_LOG_FUNCTIONS: Function entering and leaving
*
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
* Set the session logging verbosity via a
* string that will be converted to a numerical
* value (e.g. "3") and interpreted according
* to the values of
* SSH_BIND_OPTIONS_LOG_VERBOSITY above (const
* char *).
*
* - SSH_BIND_OPTIONS_DSAKEY:
* Set the path to the ssh host dsa key, SSHv2
* only (const char *).
*
* - SSH_BIND_OPTIONS_RSAKEY:
* Set the path to the ssh host rsa key, SSHv2
* only (const char *).
*
* - SSH_BIND_OPTIONS_ECDSAKEY:
* Set the path to the ssh host ecdsa key,
* SSHv2 only (const char *).
*
* - SSH_BIND_OPTIONS_BANNER:
* Set the server banner sent to clients (const char *).
* *
* @param value The value to set. This is a generic pointer and the * @param value The value to set. This is a generic pointer and the
* datatype which is used should be set according to the * datatype which should be used is described at the
* type set. * corresponding value of type above.
* *
* @return 0 on success, < 0 on error. * @return 0 on success, < 0 on error, invalid option, or parameter.
*/ */
int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type, int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
const void *value) { const void *value) {
char *p, *q; char *p, *q;
int i; int i, rc;
if (sshbind == NULL) { if (sshbind == NULL) {
return -1; return -1;
@@ -1445,31 +1472,23 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
} }
break; break;
case SSH_BIND_OPTIONS_DSAKEY: case SSH_BIND_OPTIONS_DSAKEY:
if (value == NULL) { rc = ssh_bind_set_key(sshbind, &sshbind->dsakey, value);
ssh_set_error_invalid(sshbind); if (rc < 0) {
return -1; return -1;
} else {
SAFE_FREE(sshbind->dsakey);
sshbind->dsakey = strdup(value);
if (sshbind->dsakey == NULL) {
ssh_set_error_oom(sshbind);
return -1;
} }
} break;
break;
case SSH_BIND_OPTIONS_RSAKEY: case SSH_BIND_OPTIONS_RSAKEY:
if (value == NULL) { rc = ssh_bind_set_key(sshbind, &sshbind->rsakey, value);
ssh_set_error_invalid(sshbind); if (rc < 0) {
return -1; return -1;
} else {
SAFE_FREE(sshbind->rsakey);
sshbind->rsakey = strdup(value);
if (sshbind->rsakey == NULL) {
ssh_set_error_oom(sshbind);
return -1;
} }
} break;
break; case SSH_BIND_OPTIONS_ECDSAKEY:
rc = ssh_bind_set_key(sshbind, &sshbind->ecdsakey, value);
if (rc < 0) {
return -1;
}
break;
case SSH_BIND_OPTIONS_BANNER: case SSH_BIND_OPTIONS_BANNER:
if (value == NULL) { if (value == NULL) {
ssh_set_error_invalid(sshbind); ssh_set_error_invalid(sshbind);

View File

@@ -504,11 +504,13 @@ static int packet_send2(ssh_session session) {
session->current_crypto->out_cipher->blocksize : 8); session->current_crypto->out_cipher->blocksize : 8);
uint32_t currentlen = buffer_get_rest_len(session->out_buffer); uint32_t currentlen = buffer_get_rest_len(session->out_buffer);
unsigned char *hmac = NULL; unsigned char *hmac = NULL;
char padstring[32] = {0}; char padstring[32] = { 0 };
int rc = SSH_ERROR; int rc = SSH_ERROR;
uint32_t finallen,payloadsize,compsize; uint32_t finallen,payloadsize,compsize;
uint8_t padding; uint8_t padding;
uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 };
payloadsize = currentlen; payloadsize = currentlen;
#ifdef WITH_ZLIB #ifdef WITH_ZLIB
if (session->current_crypto if (session->current_crypto
@@ -528,19 +530,18 @@ static int packet_send2(ssh_session session) {
if (session->current_crypto) { if (session->current_crypto) {
ssh_get_random(padstring, padding, 0); ssh_get_random(padstring, padding, 0);
} else {
memset(padstring,0,padding);
} }
finallen = htonl(currentlen + padding + 1); finallen = htonl(currentlen + padding + 1);
if (buffer_prepend_data(session->out_buffer, &padding, sizeof(uint8_t)) < 0) { memcpy(&header[0], &finallen, sizeof(finallen));
header[sizeof(finallen)] = padding;
rc = buffer_prepend_data(session->out_buffer, &header, sizeof(header));
if (rc < 0) {
goto error; goto error;
} }
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) { rc = buffer_add_data(session->out_buffer, padstring, padding);
goto error; if (rc < 0) {
}
if (buffer_add_data(session->out_buffer, padstring, padding) < 0) {
goto error; goto error;
} }
#ifdef WITH_PCAP #ifdef WITH_PCAP

View File

@@ -43,29 +43,35 @@
* @brief Handle a SSH_DISCONNECT packet. * @brief Handle a SSH_DISCONNECT packet.
*/ */
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback){ SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback){
uint32_t code; int rc;
char *error=NULL; uint32_t code = 0;
ssh_string error_s; char *error = NULL;
(void)user; ssh_string error_s;
(void)type; (void)user;
buffer_get_u32(packet, &code); (void)type;
rc = buffer_get_u32(packet, &code);
if (rc != 0) {
code = ntohl(code);
}
error_s = buffer_get_ssh_string(packet); error_s = buffer_get_ssh_string(packet);
if (error_s != NULL) { if (error_s != NULL) {
error = ssh_string_to_char(error_s); error = ssh_string_to_char(error_s);
ssh_string_free(error_s); ssh_string_free(error_s);
} }
SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s",code, SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s",
error != NULL ? error : "no error"); code, error != NULL ? error : "no error");
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Received SSH_MSG_DISCONNECT: %d:%s",code, "Received SSH_MSG_DISCONNECT: %d:%s",
error != NULL ? error : "no error"); code, error != NULL ? error : "no error");
SAFE_FREE(error); SAFE_FREE(error);
ssh_socket_close(session->socket); ssh_socket_close(session->socket);
session->alive = 0; session->alive = 0;
session->session_state= SSH_SESSION_STATE_ERROR; session->session_state = SSH_SESSION_STATE_ERROR;
/* TODO: handle a graceful disconnect */ /* TODO: handle a graceful disconnect */
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
/** /**
@@ -88,7 +94,7 @@ SSH_PACKET_CALLBACK(ssh_packet_dh_reply){
(void)type; (void)type;
(void)user; (void)user;
SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_KEXDH_REPLY"); SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_KEXDH_REPLY");
if(session->session_state!= SSH_SESSION_STATE_DH && if (session->session_state != SSH_SESSION_STATE_DH ||
session->dh_handshake_state != DH_STATE_INIT_SENT){ session->dh_handshake_state != DH_STATE_INIT_SENT){
ssh_set_error(session,SSH_FATAL,"ssh_packet_dh_reply called in wrong state : %d:%d", ssh_set_error(session,SSH_FATAL,"ssh_packet_dh_reply called in wrong state : %d:%d",
session->session_state,session->dh_handshake_state); session->session_state,session->dh_handshake_state);
@@ -129,12 +135,16 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
(void)user; (void)user;
(void)type; (void)type;
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_NEWKEYS"); SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_NEWKEYS");
if(session->session_state!= SSH_SESSION_STATE_DH &&
session->dh_handshake_state != DH_STATE_NEWKEYS_SENT){ if (session->session_state != SSH_SESSION_STATE_DH ||
ssh_set_error(session,SSH_FATAL,"ssh_packet_newkeys called in wrong state : %d:%d", session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) {
session->session_state,session->dh_handshake_state); ssh_set_error(session,
goto error; SSH_FATAL,
"ssh_packet_newkeys called in wrong state : %d:%d",
session->session_state,session->dh_handshake_state);
goto error;
} }
if(session->server){ if(session->server){
/* server things are done in server.c */ /* server things are done in server.c */
session->dh_handshake_state=DH_STATE_FINISHED; session->dh_handshake_state=DH_STATE_FINISHED;

View File

@@ -98,6 +98,25 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) {
return SSH_KEYTYPE_UNKNOWN; return SSH_KEYTYPE_UNKNOWN;
} }
/**
* @brief returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
*
* @param[in] key the ssh_key whose ECDSA name to get
*
* @returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
*
* @returns "unknown" if the ECDSA key name is not known
*/
const char *ssh_pki_key_ecdsa_name(const ssh_key key)
{
#ifdef HAVE_OPENSSL_ECC /* FIXME Better ECC check needed */
return pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
#else
(void) key; /* unused */
return NULL;
#endif
}
/** /**
* @brief creates a new empty SSH key * @brief creates a new empty SSH key
* @returns an empty ssh_key handle, or NULL on error. * @returns an empty ssh_key handle, or NULL on error.
@@ -724,6 +743,9 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer,
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
} }
/* Update key type */
key->type_c = ssh_pki_key_ecdsa_name(key);
} }
break; break;
#endif #endif
@@ -980,8 +1002,12 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC #ifdef HAVE_ECC
rc = pki_key_generate_ecdsa(key, parameter); rc = pki_key_generate_ecdsa(key, parameter);
if(rc == SSH_ERROR) if (rc == SSH_ERROR) {
goto error; goto error;
}
/* Update key type */
key->type_c = ssh_pki_key_ecdsa_name(key);
break; break;
#endif #endif
case SSH_KEYTYPE_UNKNOWN: case SSH_KEYTYPE_UNKNOWN:
@@ -1299,6 +1325,11 @@ int ssh_pki_signature_verify_blob(ssh_session session,
evp(key->ecdsa_nid, digest, dlen, ehash, &elen); evp(key->ecdsa_nid, digest, dlen, ehash, &elen);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Hash to be verified with ecdsa",
ehash, elen);
#endif
rc = pki_signature_verify(session, rc = pki_signature_verify(session,
sig, sig,
key, key,
@@ -1334,7 +1365,7 @@ ssh_string ssh_pki_do_sign(ssh_session session,
struct ssh_crypto_struct *crypto = struct ssh_crypto_struct *crypto =
session->current_crypto ? session->current_crypto : session->current_crypto ? session->current_crypto :
session->next_crypto; session->next_crypto;
ssh_signature sig; ssh_signature sig = NULL;
ssh_string sig_blob; ssh_string sig_blob;
ssh_string session_id; ssh_string session_id;
int rc; int rc;
@@ -1365,6 +1396,10 @@ ssh_string ssh_pki_do_sign(ssh_session session,
evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
evp_final(ctx, ehash, &elen); evp_final(ctx, ehash, &elen);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Hash being signed", ehash, elen);
#endif
sig = pki_do_sign(privkey, ehash, elen); sig = pki_do_sign(privkey, ehash, elen);
#endif #endif
} else { } else {
@@ -1458,10 +1493,8 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
const ssh_key privkey) const ssh_key privkey)
{ {
struct ssh_crypto_struct *crypto; struct ssh_crypto_struct *crypto;
unsigned char hash[SHA_DIGEST_LEN] = {0};
ssh_signature sig; ssh_signature sig;
ssh_string sig_blob; ssh_string sig_blob;
SHACTX ctx;
int rc; int rc;
if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) { if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) {
@@ -1470,24 +1503,47 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
crypto = session->next_crypto ? session->next_crypto : crypto = session->next_crypto ? session->next_crypto :
session->current_crypto; session->current_crypto;
ctx = sha1_init();
if (ctx == NULL) {
return NULL;
}
if (crypto->secret_hash == NULL){ if (crypto->secret_hash == NULL){
ssh_set_error(session,SSH_FATAL,"Missing secret_hash"); ssh_set_error(session,SSH_FATAL,"Missing secret_hash");
return NULL; return NULL;
} }
sha1_update(ctx, crypto->secret_hash, crypto->digest_len);
sha1_final(hash, ctx); if (privkey->type == SSH_KEYTYPE_ECDSA) {
#ifdef HAVE_ECC
unsigned char ehash[EVP_DIGEST_LEN] = {0};
uint32_t elen;
evp(privkey->ecdsa_nid, crypto->secret_hash, crypto->digest_len,
ehash, &elen);
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); ssh_print_hexa("Hash being signed", ehash, elen);
#endif #endif
sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN); sig = pki_do_sign_sessionid(privkey, ehash, elen);
if (sig == NULL) { if (sig == NULL) {
return NULL; return NULL;
}
#endif
} else {
unsigned char hash[SHA_DIGEST_LEN] = {0};
SHACTX ctx;
ctx = sha1_init();
if (ctx == NULL) {
return NULL;
}
sha1_update(ctx, crypto->secret_hash, crypto->digest_len);
sha1_final(hash, ctx);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
#endif
sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN);
if (sig == NULL) {
return NULL;
}
} }
rc = ssh_pki_export_signature_blob(sig, &sig_blob); rc = ssh_pki_export_signature_blob(sig, &sig_blob);

View File

@@ -89,7 +89,7 @@ static int pki_key_ecdsa_to_nid(EC_KEY *k)
return -1; return -1;
} }
static const char *pki_key_ecdsa_nid_to_name(int nid) const char *pki_key_ecdsa_nid_to_name(int nid)
{ {
switch (nid) { switch (nid) {
case NID_X9_62_prime256v1: case NID_X9_62_prime256v1:
@@ -345,13 +345,13 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
break; break;
case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_OPENSSL_ECC #ifdef HAVE_OPENSSL_ECC
new->ecdsa_nid = key->ecdsa_nid;
/* privkey -> pubkey */ /* privkey -> pubkey */
if (demote && ssh_key_is_private(key)) { if (demote && ssh_key_is_private(key)) {
const EC_POINT *p; const EC_POINT *p;
int ok; int ok;
new->ecdsa_nid = key->ecdsa_nid;
new->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid); new->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
if (new->ecdsa == NULL) { if (new->ecdsa == NULL) {
goto fail; goto fail;
@@ -383,10 +383,20 @@ fail:
} }
int pki_key_generate_rsa(ssh_key key, int parameter){ int pki_key_generate_rsa(ssh_key key, int parameter){
key->rsa = RSA_generate_key(parameter, 65537, NULL, NULL); BIGNUM *e;
if(key->rsa == NULL) int rc;
return SSH_ERROR;
return SSH_OK; e = BN_new();
key->rsa = RSA_new();
BN_set_word(e, 65537);
rc = RSA_generate_key_ex(key->rsa, parameter, e, NULL);
BN_free(e);
if (rc == -1 || key->rsa == NULL)
return SSH_ERROR;
return SSH_OK;
} }
int pki_key_generate_dss(ssh_key key, int parameter){ int pki_key_generate_dss(ssh_key key, int parameter){
@@ -1223,9 +1233,15 @@ static ssh_signature pki_signature_from_rsa_blob(const ssh_key pubkey,
char *blob_padded_data; char *blob_padded_data;
ssh_string sig_blob_padded; ssh_string sig_blob_padded;
size_t rsalen = 0;
size_t len = ssh_string_len(sig_blob); size_t len = ssh_string_len(sig_blob);
size_t rsalen= RSA_size(pubkey->rsa);
if (pubkey->rsa == NULL) {
ssh_pki_log("Pubkey RSA field NULL");
goto errout;
}
rsalen = RSA_size(pubkey->rsa);
if (len > rsalen) { if (len > rsalen) {
ssh_pki_log("Signature is too big: %lu > %lu", ssh_pki_log("Signature is too big: %lu > %lu",
(unsigned long)len, (unsigned long)rsalen); (unsigned long)len, (unsigned long)rsalen);
@@ -1381,7 +1397,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r)); ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r));
#endif #endif
sig->ecdsa_sig->r = make_string_bn(r); make_string_bn_inplace(r, sig->ecdsa_sig->r);
ssh_string_burn(r); ssh_string_burn(r);
ssh_string_free(r); ssh_string_free(r);
if (sig->ecdsa_sig->r == NULL) { if (sig->ecdsa_sig->r == NULL) {
@@ -1402,7 +1418,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s)); ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s));
#endif #endif
sig->ecdsa_sig->s = make_string_bn(s); make_string_bn_inplace(s, sig->ecdsa_sig->s);
ssh_string_burn(s); ssh_string_burn(s);
ssh_string_free(s); ssh_string_free(s);
if (sig->ecdsa_sig->s == NULL) { if (sig->ecdsa_sig->s == NULL) {

View File

@@ -1657,6 +1657,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
return NULL; return NULL;
} }
sig->type = key->type; sig->type = key->type;
sig->type_c = key->type_c;
switch(key->type) { switch(key->type) {
case SSH_KEYTYPE_DSS: case SSH_KEYTYPE_DSS:

View File

@@ -35,9 +35,9 @@
#include "libssh/poll.h" #include "libssh/poll.h"
#include "libssh/socket.h" #include "libssh/socket.h"
#include "libssh/session.h" #include "libssh/session.h"
#include "libssh/misc.h"
#ifdef WITH_SERVER #ifdef WITH_SERVER
#include "libssh/server.h" #include "libssh/server.h"
#include "libssh/misc.h"
#endif #endif
@@ -597,11 +597,17 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) {
ssh_poll_handle p; ssh_poll_handle p;
socket_t fd; socket_t fd;
int revents; int revents;
struct ssh_timestamp ts;
if (!ctx->polls_used) if (!ctx->polls_used)
return SSH_ERROR; return SSH_ERROR;
rc = ssh_poll(ctx->pollfds, ctx->polls_used, timeout); ssh_timestamp_init(&ts);
do {
int tm = ssh_timeout_update(&ts, timeout);
rc = ssh_poll(ctx->pollfds, ctx->polls_used, tm);
} while (rc == -1 && errno == EINTR);
if(rc < 0) if(rc < 0)
return SSH_ERROR; return SSH_ERROR;
if (rc == 0) if (rc == 0)

View File

@@ -165,7 +165,7 @@ static int ssh_server_kexdh_init(ssh_session session, ssh_buffer packet){
} }
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
int rc; int rc = SSH_ERROR;
(void)type; (void)type;
(void)user; (void)user;
@@ -193,9 +193,11 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_kexdh_init"); ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_kexdh_init");
rc = SSH_ERROR; rc = SSH_ERROR;
} }
if (rc == SSH_ERROR)
error:
if (rc == SSH_ERROR) {
session->session_state = SSH_SESSION_STATE_ERROR; session->session_state = SSH_SESSION_STATE_ERROR;
error: }
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
@@ -217,6 +219,7 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){
*privkey = session->srv.ecdsa_key; *privkey = session->srv.ecdsa_key;
break; break;
case SSH_KEYTYPE_UNKNOWN: case SSH_KEYTYPE_UNKNOWN:
default:
*privkey = NULL; *privkey = NULL;
} }

View File

@@ -100,7 +100,7 @@ ssh_session ssh_new(void) {
/* OPTIONS */ /* OPTIONS */
session->opts.StrictHostKeyChecking = 1; session->opts.StrictHostKeyChecking = 1;
session->opts.port = 22; session->opts.port = 0;
session->opts.fd = -1; session->opts.fd = -1;
session->opts.ssh2 = 1; session->opts.ssh2 = 1;
session->opts.compressionlevel=7; session->opts.compressionlevel=7;
@@ -226,7 +226,11 @@ void ssh_free(ssh_session session) {
#endif /* _WIN32 */ #endif /* _WIN32 */
ssh_key_free(session->srv.dsa_key); ssh_key_free(session->srv.dsa_key);
session->srv.dsa_key = NULL;
ssh_key_free(session->srv.rsa_key); ssh_key_free(session->srv.rsa_key);
session->srv.rsa_key = NULL;
ssh_key_free(session->srv.ecdsa_key);
session->srv.ecdsa_key = NULL;
if (session->ssh_message_list) { if (session->ssh_message_list) {
ssh_message msg; ssh_message msg;
@@ -261,6 +265,7 @@ void ssh_free(ssh_session session) {
SAFE_FREE(session->banner); SAFE_FREE(session->banner);
SAFE_FREE(session->opts.bindaddr); SAFE_FREE(session->opts.bindaddr);
SAFE_FREE(session->opts.custombanner);
SAFE_FREE(session->opts.username); SAFE_FREE(session->opts.username);
SAFE_FREE(session->opts.host); SAFE_FREE(session->opts.host);
SAFE_FREE(session->opts.sshdir); SAFE_FREE(session->opts.sshdir);
@@ -275,7 +280,7 @@ void ssh_free(ssh_session session) {
} }
} }
/* burn connection, it could hang sensitive datas */ /* burn connection, it could contain sensitive data */
BURN_BUFFER(session, sizeof(struct ssh_session_struct)); BURN_BUFFER(session, sizeof(struct ssh_session_struct));
SAFE_FREE(session); SAFE_FREE(session);
} }

View File

@@ -126,6 +126,7 @@ sftp_session sftp_new(ssh_session session){
sftp->session = session; sftp->session = session;
sftp->channel = ssh_channel_new(session); sftp->channel = ssh_channel_new(session);
if (sftp->channel == NULL) { if (sftp->channel == NULL) {
sftp_ext_free(sftp->ext);
SAFE_FREE(sftp); SAFE_FREE(sftp);
return NULL; return NULL;
@@ -133,6 +134,7 @@ sftp_session sftp_new(ssh_session session){
if (ssh_channel_open_session(sftp->channel)) { if (ssh_channel_open_session(sftp->channel)) {
ssh_channel_free(sftp->channel); ssh_channel_free(sftp->channel);
sftp_ext_free(sftp->ext);
SAFE_FREE(sftp); SAFE_FREE(sftp);
return NULL; return NULL;
@@ -340,7 +342,6 @@ sftp_packet sftp_packet_read(sftp_session sftp) {
return NULL; return NULL;
} }
size = ntohl(size);
r=ssh_channel_read(sftp->channel, buffer, 1, 0); r=ssh_channel_read(sftp->channel, buffer, 1, 0);
if (r <= 0) { if (r <= 0) {
/* TODO: check if there are cases where an error needs to be set here */ /* TODO: check if there are cases where an error needs to be set here */
@@ -350,7 +351,12 @@ sftp_packet sftp_packet_read(sftp_session sftp) {
} }
buffer_add_data(packet->payload, buffer, r); buffer_add_data(packet->payload, buffer, r);
buffer_get_u8(packet->payload, &packet->type); buffer_get_u8(packet->payload, &packet->type);
size=size-1;
size = ntohl(size);
if (size == 0) {
return packet;
}
size--;
while (size>0){ while (size>0){
r=ssh_channel_read(sftp->channel,buffer, r=ssh_channel_read(sftp->channel,buffer,
sizeof(buffer)>size ? size:sizeof(buffer),0); sizeof(buffer)>size ? size:sizeof(buffer),0);
@@ -445,6 +451,7 @@ static sftp_message sftp_get_message(sftp_packet packet) {
sftp_message_free(msg); sftp_message_free(msg);
return NULL; return NULL;
} }
msg->id = ntohl(msg->id);
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"Packet with id %d type %d", "Packet with id %d type %d",
@@ -886,7 +893,7 @@ sftp_dir sftp_opendir(sftp_session sftp, const char *path){
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(payload, id) < 0 || if (buffer_add_u32(payload, htonl(id)) < 0 ||
buffer_add_ssh_string(payload, path_s) < 0) { buffer_add_ssh_string(payload, path_s) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(payload); ssh_buffer_free(payload);
@@ -1433,7 +1440,7 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(payload, id) < 0 || if (buffer_add_u32(payload, htonl(id)) < 0 ||
buffer_add_ssh_string(payload, dir->handle) < 0) { buffer_add_ssh_string(payload, dir->handle) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(payload); ssh_buffer_free(payload);
@@ -1557,7 +1564,7 @@ static int sftp_handle_close(sftp_session sftp, ssh_string handle) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, handle) < 0) { buffer_add_ssh_string(buffer, handle) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -1681,7 +1688,7 @@ sftp_file sftp_open(sftp_session sftp, const char *file, int flags,
sftp_flags |= SSH_FXF_EXCL; sftp_flags |= SSH_FXF_EXCL;
SSH_LOG(SSH_LOG_PACKET,"Opening file %s with sftp flags %x",file,sftp_flags); SSH_LOG(SSH_LOG_PACKET,"Opening file %s with sftp flags %x",file,sftp_flags);
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, filename) < 0) { buffer_add_ssh_string(buffer, filename) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -1749,6 +1756,7 @@ ssize_t sftp_read(sftp_file handle, void *buf, size_t count) {
sftp_message msg = NULL; sftp_message msg = NULL;
sftp_status_message status; sftp_status_message status;
ssh_string datastring; ssh_string datastring;
size_t datalen;
ssh_buffer buffer; ssh_buffer buffer;
int id; int id;
@@ -1762,7 +1770,7 @@ ssize_t sftp_read(sftp_file handle, void *buf, size_t count) {
return -1; return -1;
} }
id = sftp_get_new_id(handle->sftp); id = sftp_get_new_id(handle->sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, handle->handle) < 0 || buffer_add_ssh_string(buffer, handle->handle) < 0 ||
buffer_add_u64(buffer, htonll(handle->offset)) < 0 || buffer_add_u64(buffer, htonll(handle->offset)) < 0 ||
buffer_add_u32(buffer,htonl(count)) < 0) { buffer_add_u32(buffer,htonl(count)) < 0) {
@@ -1819,19 +1827,19 @@ ssize_t sftp_read(sftp_file handle, void *buf, size_t count) {
return -1; return -1;
} }
if (ssh_string_len(datastring) > count) { datalen = ssh_string_len(datastring);
if (datalen > count) {
ssh_set_error(sftp->session, SSH_FATAL, ssh_set_error(sftp->session, SSH_FATAL,
"Received a too big DATA packet from sftp server: " "Received a too big DATA packet from sftp server: "
"%" PRIdS " and asked for %" PRIdS, "%" PRIdS " and asked for %" PRIdS,
ssh_string_len(datastring), count); datalen, count);
ssh_string_free(datastring); ssh_string_free(datastring);
return -1; return -1;
} }
count = ssh_string_len(datastring); handle->offset += (uint64_t)datalen;
handle->offset += count; memcpy(buf, ssh_string_data(datastring), datalen);
memcpy(buf, ssh_string_data(datastring), count);
ssh_string_free(datastring); ssh_string_free(datastring);
return count; return datalen;
default: default:
ssh_set_error(sftp->session, SSH_FATAL, ssh_set_error(sftp->session, SSH_FATAL,
"Received message %d during read!", msg->packet_type); "Received message %d during read!", msg->packet_type);
@@ -1855,7 +1863,7 @@ int sftp_async_read_begin(sftp_file file, uint32_t len){
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, file->handle) < 0 || buffer_add_ssh_string(buffer, file->handle) < 0 ||
buffer_add_u64(buffer, htonll(file->offset)) < 0 || buffer_add_u64(buffer, htonll(file->offset)) < 0 ||
buffer_add_u32(buffer, htonl(len)) < 0) { buffer_add_u32(buffer, htonl(len)) < 0) {
@@ -1982,7 +1990,7 @@ ssize_t sftp_write(sftp_file file, const void *buf, size_t count) {
ssh_string_fill(datastring, buf, count); ssh_string_fill(datastring, buf, count);
id = sftp_get_new_id(file->sftp); id = sftp_get_new_id(file->sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, file->handle) < 0 || buffer_add_ssh_string(buffer, file->handle) < 0 ||
buffer_add_u64(buffer, htonll(file->offset)) < 0 || buffer_add_u64(buffer, htonll(file->offset)) < 0 ||
buffer_add_ssh_string(buffer, datastring) < 0) { buffer_add_ssh_string(buffer, datastring) < 0) {
@@ -2101,7 +2109,7 @@ int sftp_unlink(sftp_session sftp, const char *file) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, filename) < 0) { buffer_add_ssh_string(buffer, filename) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -2178,7 +2186,7 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, filename) < 0) { buffer_add_ssh_string(buffer, filename) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -2258,7 +2266,7 @@ int sftp_mkdir(sftp_session sftp, const char *directory, mode_t mode) {
attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS; attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS;
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, path) < 0 || buffer_add_ssh_string(buffer, path) < 0 ||
buffer_add_attributes(buffer, &attr) < 0 || buffer_add_attributes(buffer, &attr) < 0 ||
sftp_packet_write(sftp, SSH_FXP_MKDIR, buffer) < 0) { sftp_packet_write(sftp, SSH_FXP_MKDIR, buffer) < 0) {
@@ -2353,7 +2361,7 @@ int sftp_rename(sftp_session sftp, const char *original, const char *newname) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, oldpath) < 0 || buffer_add_ssh_string(buffer, oldpath) < 0 ||
buffer_add_ssh_string(buffer, newpath) < 0 || buffer_add_ssh_string(buffer, newpath) < 0 ||
/* POSIX rename atomically replaces newpath, we should do the same /* POSIX rename atomically replaces newpath, we should do the same
@@ -2438,7 +2446,7 @@ int sftp_setstat(sftp_session sftp, const char *file, sftp_attributes attr) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, path) < 0 || buffer_add_ssh_string(buffer, path) < 0 ||
buffer_add_attributes(buffer, attr) < 0) { buffer_add_attributes(buffer, attr) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
@@ -2571,7 +2579,7 @@ int sftp_symlink(sftp_session sftp, const char *target, const char *dest) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0) { if (buffer_add_u32(buffer, htonl(id)) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
ssh_string_free(dest_s); ssh_string_free(dest_s);
@@ -2682,7 +2690,7 @@ char *sftp_readlink(sftp_session sftp, const char *path) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, path_s) < 0) { buffer_add_ssh_string(buffer, path_s) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -2869,7 +2877,7 @@ sftp_statvfs_t sftp_statvfs(sftp_session sftp, const char *path) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, ext) < 0 || buffer_add_ssh_string(buffer, ext) < 0 ||
buffer_add_ssh_string(buffer, pathstr) < 0) { buffer_add_ssh_string(buffer, pathstr) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
@@ -2948,7 +2956,7 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, ext) < 0 || buffer_add_ssh_string(buffer, ext) < 0 ||
buffer_add_ssh_string(buffer, file->handle) < 0) { buffer_add_ssh_string(buffer, file->handle) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
@@ -3037,7 +3045,7 @@ char *sftp_canonicalize_path(sftp_session sftp, const char *path) {
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, pathstr) < 0) { buffer_add_ssh_string(buffer, pathstr) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -3115,7 +3123,7 @@ static sftp_attributes sftp_xstat(sftp_session sftp, const char *path,
} }
id = sftp_get_new_id(sftp); id = sftp_get_new_id(sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, pathstr) < 0) { buffer_add_ssh_string(buffer, pathstr) < 0) {
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);
@@ -3182,7 +3190,7 @@ sftp_attributes sftp_fstat(sftp_file file) {
} }
id = sftp_get_new_id(file->sftp); id = sftp_get_new_id(file->sftp);
if (buffer_add_u32(buffer, id) < 0 || if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, file->handle) < 0) { buffer_add_ssh_string(buffer, file->handle) < 0) {
ssh_set_error_oom(file->sftp->session); ssh_set_error_oom(file->sftp->session);
ssh_buffer_free(buffer); ssh_buffer_free(buffer);

View File

@@ -630,10 +630,15 @@ int ssh_socket_nonblocking_flush(ssh_socket s) {
if (!ssh_socket_is_open(s)) { if (!ssh_socket_is_open(s)) {
session->alive = 0; session->alive = 0;
/* FIXME use ssh_socket_get_errno */ if(s->callbacks && s->callbacks->exception){
ssh_set_error(session, SSH_FATAL, s->callbacks->exception(
"Writing packet: error on socket (or connection closed): %s", SSH_SOCKET_EXCEPTION_ERROR,
strerror(s->last_errno)); s->last_errno,s->callbacks->userdata);
}else{
ssh_set_error(session, SSH_FATAL,
"Writing packet: error on socket (or connection closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR; return SSH_ERROR;
} }
@@ -650,12 +655,16 @@ int ssh_socket_nonblocking_flush(ssh_socket s) {
if (w < 0) { if (w < 0) {
session->alive = 0; session->alive = 0;
ssh_socket_close(s); ssh_socket_close(s);
/* FIXME use ssh_socket_get_errno() */
/* FIXME use callback for errors */
ssh_set_error(session, SSH_FATAL,
"Writing packet: error on socket (or connection closed): %s",
strerror(s->last_errno));
if(s->callbacks && s->callbacks->exception){
s->callbacks->exception(
SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,s->callbacks->userdata);
}else{
ssh_set_error(session, SSH_FATAL,
"Writing packet: error on socket (or connection closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR; return SSH_ERROR;
} }
buffer_pass_bytes(s->out_buffer, w); buffer_pass_bytes(s->out_buffer, w);

View File

@@ -235,10 +235,11 @@ struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) {
* @param[in] s The string to burn. * @param[in] s The string to burn.
*/ */
void ssh_string_burn(struct ssh_string_struct *s) { void ssh_string_burn(struct ssh_string_struct *s) {
if (s == NULL) { if (s == NULL || s->size == 0) {
return; return;
} }
memset(s->data, 'X', ssh_string_len(s));
BURN_BUFFER(s->data, ssh_string_len(s));
} }
/** /**

View File

@@ -53,73 +53,75 @@ include_directories(
${LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS} ${LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS}
) )
add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${libssh_threads_SRCS}) if (libssh_threads_SRCS)
add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${libssh_threads_SRCS})
target_link_libraries(${LIBSSH_THREADS_SHARED_LIBRARY} ${LIBSSH_THREADS_LINK_LIBRARIES}) target_link_libraries(${LIBSSH_THREADS_SHARED_LIBRARY} ${LIBSSH_THREADS_LINK_LIBRARIES})
set_target_properties(
${LIBSSH_THREADS_SHARED_LIBRARY}
PROPERTIES
VERSION
${LIBRARY_VERSION}
SOVERSION
${LIBRARY_SOVERSION}
OUTPUT_NAME
ssh_threads
DEFINE_SYMBOL
LIBSSH_EXPORTS
)
if (WITH_VISIBILITY_HIDDEN)
set_target_properties(${LIBSSH_THREADS_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
endif (WITH_VISIBILITY_HIDDEN)
install(
TARGETS
${LIBSSH_THREADS_SHARED_LIBRARY}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
COMPONENT libraries
)
if (WITH_STATIC_LIB)
add_library(${LIBSSH_THREADS_STATIC_LIBRARY} STATIC ${libssh_threads_SRCS})
if (MSVC)
set(OUTPUT_SUFFIX static)
else (MSVC)
set(OUTPUT_SUFFIX )
endif (MSVC)
set_target_properties(
${LIBSSH_THREADS_STATIC_LIBRARY}
PROPERTIES
VERSION
${LIBRARY_VERSION}
SOVERSION
${LIBRARY_SOVERSION}
OUTPUT_NAME
ssh_threads
ARCHIVE_OUTPUT_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX}
)
if (WIN32)
set_target_properties( set_target_properties(
${LIBSSH_THREADS_STATIC_LIBRARY} ${LIBSSH_THREADS_SHARED_LIBRARY}
PROPERTIES PROPERTIES
COMPILE_FLAGS VERSION
"-DLIBSSH_STATIC" ${LIBRARY_VERSION}
) SOVERSION
endif (WIN32) ${LIBRARY_SOVERSION}
OUTPUT_NAME
ssh_threads
DEFINE_SYMBOL
LIBSSH_EXPORTS
)
install( if (WITH_VISIBILITY_HIDDEN)
TARGETS set_target_properties(${LIBSSH_THREADS_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
${LIBSSH_THREADS_STATIC_LIBRARY} endif (WITH_VISIBILITY_HIDDEN)
DESTINATION
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX} install(
COMPONENT TARGETS
libraries ${LIBSSH_THREADS_SHARED_LIBRARY}
) RUNTIME DESTINATION ${BIN_INSTALL_DIR}
endif (WITH_STATIC_LIB) LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
COMPONENT libraries
)
if (WITH_STATIC_LIB)
add_library(${LIBSSH_THREADS_STATIC_LIBRARY} STATIC ${libssh_threads_SRCS})
if (MSVC)
set(OUTPUT_SUFFIX static)
else (MSVC)
set(OUTPUT_SUFFIX )
endif (MSVC)
set_target_properties(
${LIBSSH_THREADS_STATIC_LIBRARY}
PROPERTIES
VERSION
${LIBRARY_VERSION}
SOVERSION
${LIBRARY_SOVERSION}
OUTPUT_NAME
ssh_threads
ARCHIVE_OUTPUT_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX}
)
if (WIN32)
set_target_properties(
${LIBSSH_THREADS_STATIC_LIBRARY}
PROPERTIES
COMPILE_FLAGS
"-DLIBSSH_STATIC"
)
endif (WIN32)
install(
TARGETS
${LIBSSH_THREADS_STATIC_LIBRARY}
DESTINATION
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
COMPONENT
libraries
)
endif (WITH_STATIC_LIB)
endif (libssh_threads_SRCS)

View File

@@ -75,7 +75,7 @@ static int ssh_pthread_mutex_unlock (void **lock){
} }
static unsigned long ssh_pthread_thread_id (void){ static unsigned long ssh_pthread_thread_id (void){
#if _WIN32 #if defined(_WIN32) && !defined(__WINPTHREADS_VERSION)
return (unsigned long) pthread_self().p; return (unsigned long) pthread_self().p;
#else #else
return (unsigned long) pthread_self(); return (unsigned long) pthread_self();

View File

@@ -130,10 +130,13 @@ void crypto_free(struct ssh_crypto_struct *crypto){
(deflateEnd(crypto->compress_out_ctx) != 0)) { (deflateEnd(crypto->compress_out_ctx) != 0)) {
inflateEnd(crypto->compress_out_ctx); inflateEnd(crypto->compress_out_ctx);
} }
SAFE_FREE(crypto->compress_out_ctx);
if (crypto->compress_in_ctx && if (crypto->compress_in_ctx &&
(deflateEnd(crypto->compress_in_ctx) != 0)) { (deflateEnd(crypto->compress_in_ctx) != 0)) {
inflateEnd(crypto->compress_in_ctx); inflateEnd(crypto->compress_in_ctx);
} }
SAFE_FREE(crypto->compress_in_ctx);
#endif /* WITH_ZLIB */ #endif /* WITH_ZLIB */
if(crypto->encryptIV) if(crypto->encryptIV)
SAFE_FREE(crypto->encryptIV); SAFE_FREE(crypto->encryptIV);

View File

@@ -24,7 +24,10 @@
#include "torture.h" #include "torture.h"
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <sys/time.h> #include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define HOST "localhost" #define HOST "localhost"
/* Should work until Apnic decides to assign it :) */ /* Should work until Apnic decides to assign it :) */
#define BLACKHOLE "1.1.1.1" #define BLACKHOLE "1.1.1.1"
@@ -54,12 +57,11 @@ static void torture_connect_nonblocking(void **state) {
ssh_set_blocking(session,0); ssh_set_blocking(session,0);
do { do {
rc = ssh_connect(session); rc = ssh_connect(session);
assert_true(rc != SSH_ERROR); assert_true(rc != SSH_ERROR);
} while(rc == SSH_AGAIN); } while(rc == SSH_AGAIN);
assert_true(rc==SSH_OK); assert_true(rc == SSH_OK);
} }
static void torture_connect_timeout(void **state) { static void torture_connect_timeout(void **state) {
@@ -84,9 +86,9 @@ static void torture_connect_timeout(void **state) {
sec = after.tv_sec - before.tv_sec; sec = after.tv_sec - before.tv_sec;
usec = after.tv_usec - before.tv_usec; usec = after.tv_usec - before.tv_usec;
/* Borrow a second for the missing usecs, but don't bother calculating */ /* Borrow a second for the missing usecs, but don't bother calculating */
if(usec < 0) if (usec < 0)
sec--; sec--;
assert_in_range(sec,1,3); assert_in_range(sec, 1, 3);
} }
static void torture_connect_double(void **state) { static void torture_connect_double(void **state) {
@@ -102,10 +104,9 @@ static void torture_connect_double(void **state) {
rc = ssh_connect(session); rc = ssh_connect(session);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
} }
static void torture_connect_failure(void **state){ static void torture_connect_failure(void **state) {
/* /*
* The intent of this test is to check that a fresh * The intent of this test is to check that a fresh
* ssh_new/ssh_disconnect/ssh_free sequence doesn't crash/leak * ssh_new/ssh_disconnect/ssh_free sequence doesn't crash/leak
@@ -114,6 +115,30 @@ static void torture_connect_failure(void **state){
ssh_session session = *state; ssh_session session = *state;
ssh_disconnect(session); ssh_disconnect(session);
} }
static void torture_connect_socket(void **state) {
ssh_session session = *state;
int rc;
int sock_fd = 0;
struct sockaddr_in server_addr;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
assert_true(sock_fd > 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(22);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
rc = connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
assert_true(rc == 0);
ssh_options_set(session, SSH_OPTIONS_FD, &sock_fd);
rc = ssh_connect(session);
assert_true(rc == SSH_OK);
}
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
const UnitTest tests[] = { const UnitTest tests[] = {
@@ -121,6 +146,7 @@ int torture_run_tests(void) {
unit_test_setup_teardown(torture_connect_double, setup, teardown), unit_test_setup_teardown(torture_connect_double, setup, teardown),
unit_test_setup_teardown(torture_connect_failure, setup, teardown), unit_test_setup_teardown(torture_connect_failure, setup, teardown),
unit_test_setup_teardown(torture_connect_timeout, setup, teardown), unit_test_setup_teardown(torture_connect_timeout, setup, teardown),
unit_test_setup_teardown(torture_connect_socket, setup, teardown),
}; };
ssh_init(); ssh_init();

View File

@@ -39,6 +39,12 @@
#include <cmocka.h> #include <cmocka.h>
#ifndef assert_return_code
/* hack for older versions of cmocka */
#define assert_return_code(code, errno) \
assert_true(code >= 0)
#endif /* assert_return_code */
/* Used by main to communicate with parse_opt. */ /* Used by main to communicate with parse_opt. */
struct argument_s { struct argument_s {
char *args[2]; char *args[2];

View File

@@ -113,23 +113,35 @@ static void torture_path_expand_tilde_win(void **state) {
static void torture_path_expand_tilde_unix(void **state) { static void torture_path_expand_tilde_unix(void **state) {
char h[256]; char h[256];
char *d; char *d;
char *user;
char *home;
(void) state; (void) state;
snprintf(h, 256 - 1, "%s/.ssh", getenv("HOME")); user = getenv("USER");
if (user == NULL){
user = getenv("LOGNAME");
}
assert_non_null(user);
home = getenv("HOME");
assert_non_null(home);
snprintf(h, 256 - 1, "%s/.ssh", home);
d = ssh_path_expand_tilde("~/.ssh"); d = ssh_path_expand_tilde("~/.ssh");
assert_non_null(d);
assert_string_equal(d, h); assert_string_equal(d, h);
free(d); free(d);
d = ssh_path_expand_tilde("/guru/meditation"); d = ssh_path_expand_tilde("/guru/meditation");
assert_non_null(d);
assert_string_equal(d, "/guru/meditation"); assert_string_equal(d, "/guru/meditation");
free(d); free(d);
snprintf(h, 256 - 1, "~%s/.ssh", getenv("USER")); snprintf(h, 256 - 1, "~%s/.ssh", user);
d = ssh_path_expand_tilde(h); d = ssh_path_expand_tilde(h);
assert_non_null(d);
snprintf(h, 256 - 1, "%s/.ssh", getenv("HOME")); snprintf(h, 256 - 1, "%s/.ssh", home);
assert_string_equal(d, h); assert_string_equal(d, h);
free(d); free(d);
} }
@@ -146,6 +158,7 @@ static void torture_path_expand_escape(void **state) {
session->opts.username = strdup("root"); session->opts.username = strdup("root");
e = ssh_path_expand_escape(session, s); e = ssh_path_expand_escape(session, s);
assert_non_null(e);
assert_string_equal(e, "guru/meditation/by/root"); assert_string_equal(e, "guru/meditation/by/root");
free(e); free(e);
} }
@@ -157,6 +170,7 @@ static void torture_path_expand_known_hosts(void **state) {
session->opts.sshdir = strdup("/home/guru/.ssh"); session->opts.sshdir = strdup("/home/guru/.ssh");
tmp = ssh_path_expand_escape(session, "%d/known_hosts"); tmp = ssh_path_expand_escape(session, "%d/known_hosts");
assert_non_null(tmp);
assert_string_equal(tmp, "/home/guru/.ssh/known_hosts"); assert_string_equal(tmp, "/home/guru/.ssh/known_hosts");
free(tmp); free(tmp);
} }

View File

@@ -36,17 +36,36 @@ static void setup_dsa_key(void **state) {
} }
#ifdef HAVE_OPENSSL_ECC #ifdef HAVE_OPENSSL_ECC
static void setup_ecdsa_key(void **state) { static void setup_ecdsa_key(void **state, int ecdsa_bits) {
int rc; int rc = -1;
(void) state; /* unused */ (void) state; /* unused */
unlink(LIBSSH_ECDSA_TESTKEY); unlink(LIBSSH_ECDSA_TESTKEY);
unlink(LIBSSH_ECDSA_TESTKEY ".pub"); unlink(LIBSSH_ECDSA_TESTKEY ".pub");
rc = system("ssh-keygen -t ecdsa -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY); if (ecdsa_bits == 256) {
rc = system("ssh-keygen -t ecdsa -b 256 -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
} else if (ecdsa_bits == 384) {
rc = system("ssh-keygen -t ecdsa -b 384 -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
} else if (ecdsa_bits == 521) {
rc = system("ssh-keygen -t ecdsa -b 521 -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
}
assert_true(rc == 0); assert_true(rc == 0);
} }
static void setup_ecdsa_key_521(void **state) {
setup_ecdsa_key(state, 521);
}
static void setup_ecdsa_key_384(void **state) {
setup_ecdsa_key(state, 384);
}
static void setup_ecdsa_key_256(void **state) {
setup_ecdsa_key(state, 256);
}
#endif #endif
static void setup_both_keys(void **state) { static void setup_both_keys(void **state) {
@@ -766,6 +785,39 @@ static void torture_pki_duplicate_key_ecdsa(void **state)
ssh_string_free_char(b64_key); ssh_string_free_char(b64_key);
ssh_string_free_char(b64_key_gen); ssh_string_free_char(b64_key_gen);
} }
/* Test case for bug #147: Private ECDSA key duplication did not carry
* over parts of the key that then caused subsequent key demotion to
* fail.
*/
static void torture_pki_ecdsa_duplicate_then_demote(void **state)
{
ssh_key pubkey;
ssh_key privkey;
ssh_key privkey_dup;
int rc;
(void) state;
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY,
NULL,
NULL,
NULL,
&privkey);
assert_true(rc == 0);
privkey_dup = ssh_key_dup(privkey);
assert_true(privkey_dup != NULL);
assert_int_equal(privkey->ecdsa_nid, privkey_dup->ecdsa_nid);
rc = ssh_pki_export_privkey_to_pubkey(privkey_dup, &pubkey);
assert_true(rc == 0);
assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid);
ssh_key_free(pubkey);
ssh_key_free(privkey);
ssh_key_free(privkey_dup);
}
#endif #endif
static void torture_pki_generate_key_rsa(void **state) static void torture_pki_generate_key_rsa(void **state)
@@ -906,6 +958,9 @@ static void torture_pki_generate_key_ecdsa(void **state)
int rc; int rc;
ssh_key key; ssh_key key;
ssh_signature sign; ssh_signature sign;
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
const char *type_char = NULL;
const char *etype_char = NULL;
ssh_session session=ssh_new(); ssh_session session=ssh_new();
(void) state; (void) state;
@@ -916,6 +971,13 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(sign != NULL); assert_true(sign != NULL);
rc = pki_signature_verify(session,sign,key,HASH,20); rc = pki_signature_verify(session,sign,key,HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
type = ssh_key_type(key);
assert_true(type == SSH_KEYTYPE_ECDSA);
type_char = ssh_key_type_to_char(type);
assert_true(strcmp(type_char, "ssh-ecdsa") == 0);
etype_char = ssh_pki_key_ecdsa_name(key);
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); ssh_key_free(key);
key=NULL; key=NULL;
@@ -927,6 +989,13 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(sign != NULL); assert_true(sign != NULL);
rc = pki_signature_verify(session,sign,key,HASH,20); rc = pki_signature_verify(session,sign,key,HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
type = ssh_key_type(key);
assert_true(type == SSH_KEYTYPE_ECDSA);
type_char = ssh_key_type_to_char(type);
assert_true(strcmp(type_char, "ssh-ecdsa") == 0);
etype_char =ssh_pki_key_ecdsa_name(key);
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); ssh_key_free(key);
key=NULL; key=NULL;
@@ -938,6 +1007,13 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(sign != NULL); assert_true(sign != NULL);
rc = pki_signature_verify(session,sign,key,HASH,20); rc = pki_signature_verify(session,sign,key,HASH,20);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
type = ssh_key_type(key);
assert_true(type == SSH_KEYTYPE_ECDSA);
type_char = ssh_key_type_to_char(type);
assert_true(strcmp(type_char, "ssh-ecdsa") == 0);
etype_char =ssh_pki_key_ecdsa_name(key);
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0);
ssh_signature_free(sign); ssh_signature_free(sign);
ssh_key_free(key); ssh_key_free(key);
key=NULL; key=NULL;
@@ -1070,6 +1146,42 @@ static void torture_pki_write_privkey_ecdsa(void **state)
#endif #endif
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
#ifdef HAVE_ECC
static void torture_pki_ecdsa_name(void **state, const char *expected_name)
{
int rc;
ssh_key key;
const char *etype_char = NULL;
(void) state; /* unused */
ssh_set_log_level(5);
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, NULL, NULL, NULL, &key);
assert_true(rc == 0);
etype_char =ssh_pki_key_ecdsa_name(key);
assert_true(strcmp(etype_char, expected_name) == 0);
ssh_key_free(key);
}
static void torture_pki_ecdsa_name256(void **state)
{
torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp256");
}
static void torture_pki_ecdsa_name384(void **state)
{
torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp384");
}
static void torture_pki_ecdsa_name521(void **state)
{
torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp521");
}
#endif
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
const UnitTest tests[] = { const UnitTest tests[] = {
@@ -1092,7 +1204,13 @@ int torture_run_tests(void) {
teardown), teardown),
#ifdef HAVE_ECC #ifdef HAVE_ECC
unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA, unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA,
setup_ecdsa_key, setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA,
setup_ecdsa_key_521,
teardown), teardown),
#endif #endif
unit_test_setup_teardown(torture_pki_import_privkey_base64_passphrase, unit_test_setup_teardown(torture_pki_import_privkey_base64_passphrase,
@@ -1107,7 +1225,22 @@ int torture_run_tests(void) {
teardown), teardown),
#ifdef HAVE_ECC #ifdef HAVE_ECC
unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA, unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA,
setup_ecdsa_key, setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA,
setup_ecdsa_key_521,
teardown),
unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote,
setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote,
setup_ecdsa_key_521,
teardown), teardown),
#endif #endif
/* public key */ /* public key */
@@ -1119,7 +1252,13 @@ int torture_run_tests(void) {
teardown), teardown),
#ifdef HAVE_ECC #ifdef HAVE_ECC
unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64, unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64,
setup_ecdsa_key, setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64,
setup_ecdsa_key_521,
teardown), teardown),
#endif #endif
@@ -1131,7 +1270,13 @@ int torture_run_tests(void) {
teardown), teardown),
#ifdef HAVE_ECC #ifdef HAVE_ECC
unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa, unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa,
setup_ecdsa_key, setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa,
setup_ecdsa_key_521,
teardown), teardown),
#endif #endif
@@ -1143,7 +1288,13 @@ int torture_run_tests(void) {
teardown), teardown),
#ifdef HAVE_ECC #ifdef HAVE_ECC
unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa, unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa,
setup_ecdsa_key, setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa,
setup_ecdsa_key_521,
teardown), teardown),
#endif #endif
unit_test(torture_pki_generate_key_rsa), unit_test(torture_pki_generate_key_rsa),
@@ -1161,10 +1312,27 @@ int torture_run_tests(void) {
teardown), teardown),
#ifdef HAVE_ECC #ifdef HAVE_ECC
unit_test_setup_teardown(torture_pki_write_privkey_ecdsa, unit_test_setup_teardown(torture_pki_write_privkey_ecdsa,
setup_ecdsa_key, setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_write_privkey_ecdsa,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_write_privkey_ecdsa,
setup_ecdsa_key_521,
teardown), teardown),
#endif #endif
#endif /* HAVE_LIBCRYPTO */ #endif /* HAVE_LIBCRYPTO */
#ifdef HAVE_ECC
unit_test_setup_teardown(torture_pki_ecdsa_name256,
setup_ecdsa_key_256,
teardown),
unit_test_setup_teardown(torture_pki_ecdsa_name384,
setup_ecdsa_key_384,
teardown),
unit_test_setup_teardown(torture_pki_ecdsa_name521,
setup_ecdsa_key_521,
teardown),
#endif
}; };
(void)setup_both_keys; (void)setup_both_keys;