Compare commits

...

72 Commits

Author SHA1 Message Date
Andreas Schneider
8a2deeb3cc Bump version to 0.7.4 2017-02-03 09:47:18 +01:00
Andreas Schneider
40164c348e Update ChangeLog 2017-02-03 09:47:09 +01:00
Tilo Eckert
9d7f873fd3 session: Add missing ifdef that prevented Windows builds
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4f392ebc7e)
2016-11-25 13:11:37 +01:00
Andreas Schneider
c5d320811b sftpserver: Fix SSH_FXP_FSTAT arguments
Thanks to Игорь Коваленко <igor.a.kovalenko@gmail.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 47d21b6420)
2016-11-07 19:56:10 +01:00
Andreas Schneider
410f722ae5 misc: Use simpler macros for htonll and ntohll
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 52efbc3a23)
2016-11-07 09:43:09 +01:00
Andreas Schneider
8155b3c0a0 cmake: Always check for strtoull
This fixes building with different compilers on Windows

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

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fab85b495e)
2016-11-06 11:42:04 +01:00
Andreas Schneider
6836ffa103 options: Fix log level documentation
BUG: https://red.libssh.org/issues/210

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 801bc29494)
2016-11-05 17:16:14 +01:00
Andreas Schneider
b62b822100 cmake: Correctly check for *snprintf functions on Windows
BUG: https://red.libssh.org/issues/205

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1bf6c965e4)
2016-11-05 16:41:50 +01:00
Andreas Schneider
849f5db5d1 config: Fix build warning
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2016-11-05 16:33:29 +01:00
Pino Toscano
a6493efcae sftp: Fix memory leak in sftp_fstat
When parsing the result of a successful fstat call, make sure to free
the resulting reply message.

Signed-off-by: Pino Toscano <ptoscano@redhat.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit bc78383fac)
2016-10-22 16:04:00 +02:00
Andreas Schneider
1b0bf852be sftp: Correctly check for EOF else keep spinning if there is no data
This fixes an issue introduced with
dbf72ffba2

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f561e6bcb3)
2016-10-07 13:37:48 +02:00
Andreas Schneider
2b3185ec29 gssapi: Use correct return code in ssh_gssapi_auth_mic()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 83421c0e8c)
2016-10-06 19:39:06 +02:00
Andreas Schneider
d63547b18a gssapi: Print minor stat in error logging function
This also releases the memory allocated for the messages.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 095733ed9c)
2016-10-06 19:39:01 +02:00
Jeremy Cross
6697f85b50 sftp: ensure sftp_packet_read recognizes channel EOF to avoid infinite loop
Signed-off-by: Jeremy Cross <jcross@bomgar.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dbf72ffba2)
2016-09-09 11:40:07 +02:00
Travers Carter
67fe6f56ea Make "Host" pattern list handling consistent with OpenSSH
https://red.libssh.org/issues/187

Signed-off-by: Travers Carter <tcarter@noggin.com.au>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit bc2db86d1c)
2016-05-03 17:57:45 +02:00
Andreas Schneider
b5ce15eefa priv: Fix client banner specification for libssh
BUG: https://red.libssh.org/issues/231

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 4f7be0dbb2)
2016-05-03 10:58:47 +02:00
Andreas Schneider
a3688ada1a client: If SSHv1 is disabled send the banner immediately
This saves a round-trip with SSHv2 connecting to the server. See RFC
4253 section 5.2 (New Client, Old Server).

Thanks to Yang Yubo <yang@yangyubo.com> for the suggestion.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1da5c94b44)
2016-05-03 10:58:36 +02:00
Andreas Schneider
219d0bba42 client: Fix ssh_send_banner() to confirm with RFC 4253
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3d1edffe77)
2016-05-03 10:58:27 +02:00
Andreas Schneider
bf3d8f3ad4 client: Fix maximum banner length
According to RFC 4253 the max banner length is 255.

Thanks to Saju Panikulam <spanikulam@ipswitch.com> for the report.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cb52ed7b12)
2016-05-03 10:58:18 +02:00
Andreas Schneider
04a5d5bd74 client: Reformat callback_receive_banner()
The function is hard to read as the indentation is not correctly
applied.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 22799b107d)
2016-05-03 10:58:06 +02:00
Ken Reister
2957aaf9f0 client: Receive the banner correctly
Comply with RFC 4253 compliance section 4.2.

Allow data other than "SSH-" to be sent across prior to the actual
version striong.

Signed-off-by: Ken Reister <reister.kenneth@CIMCOR.COM>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c3ce3d5cc3)
2016-05-03 10:57:50 +02:00
Kohei Suzuki
8360139506 Add id_ed25519 to the default identity list
Signed-off-by: Kohei Suzuki <eagletmt@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c092101e01)
2016-05-02 15:34:32 +02:00
David Kedves
0bf78b0b8b channels: Bugfix for a possible invalid pointer usage (channel->session) in various places
BUG: https://red.libssh.org/issues/230

Signed-off-by: David Kedves <kedazo@severalnines.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d7df4429eb)
2016-05-02 15:32:16 +02:00
Stef Walter
faca78f547 auth: Cleanup memory leak when using SSH agent
In Cockpit we've seen this memory leak:

at 0x4C2A9C7: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5B76B03: ssh_userauth_agent (auth.c:778)
by 0x40DD5A: cockpit_ssh_authenticate (cockpitsshtransport.c:327)

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

Signed-off-by: Stef Walter <stefw@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ffe8b98cc2)
2016-05-02 15:29:01 +02:00
Andreas Schneider
7da587ba6c auth1: Fix non-blocking SSHv1 auth
BUG: https://red.libssh.org/issues/232

Thanks to Fengyu Gao.

TODO: Add SSHv1 tests to our testsuite.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 33ecaaac01)
2016-05-02 12:31:53 +02:00
Andreas Schneider
c7aa51240d Update the README
(cherry picked from commit e8b28f978e)
2016-05-02 12:11:02 +02:00
Andreas Schneider
cdf7690e03 Bump version to 0.7.3
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2016-02-23 08:23:31 +01:00
Andreas Schneider
7b19719022 Update ChangeLog 2016-02-23 08:22:09 +01:00
Aris Adamantiadis
f8d0026c65 dh: Fix CVE-2016-0739
Due to a byte/bit confusion, the DH secret was too short. This file was
completely reworked and will be commited in a future version.

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2016-02-23 08:17:43 +01:00
Hani Benhabiles
6b608e70ee options: Fix documentation typo
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit f8bde7156f)
2016-02-23 08:15:26 +01:00
Younes Serraj
a69a1af568 pki: Fixed documentation about return value.
Documentation now is congruent with the code:
- SSH_OK is returned on success,
- SSH_ERROR is returned on error.

Signed-off-by: Younes Serraj <younes.serraj@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 66c6ae1a55)
2016-02-23 08:15:24 +01:00
pouete
32b72555ee cmake: use check_symbol for (v)snprintf
Updated how snprintf and vsnprintf are discovered by cmake. Visual studio
2015 now include it in the file stdio.h.
More information here :
https://msdn.microsoft.com/en-us/library/bb531344.aspx

Reviewed-By: Aris Adamantiadis <aris@0xbadc0de.be>
2015-12-30 19:51:26 +01:00
Sebastián Peyrott
32af6a2390 CMake: include CheckIncludeFiles for calls to check_include_files. 2015-12-24 13:01:56 +01:00
Fabiano Fidêncio
b470dd943f Fix a bunch of -Wmaybe-uninitialized
Reviewed-By: Aris Adamantiadis <aris@0xbadc0de.be>
2015-12-17 15:02:01 +01:00
Dirk Neukirchen
69ca977aed headers: fix missing mode_t (2nd)
Reviewed-By: Aris Adamantiadis <aris@0xbadc0de.be>
2015-11-10 18:39:59 +01:00
Aris Adamantiadis
728a6349b7 Revert "headers: fix missing mode_t"
I commited a patch file *headdesk*
This reverts commit 378fcccc0a.
2015-11-10 18:39:52 +01:00
Dirk Neukirchen
ec32174abc headers: fix missing mode_t
Signed-off-by: Dirk Neukirchen <dirkneukirchen@web.de>
Reviewed-by: Aris Adamantiadis <aris@0xbadc0de.be>
2015-11-10 18:28:45 +01:00
Andreas Schneider
2172cd234a Ignore all build and obj* directories
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-10-28 09:28:42 +01:00
Andreas Schneider
0425ac9ad0 agent: Fix agent auth on big endian machines
BUG: https://red.libssh.org/issues/204

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-10-20 17:17:17 +02:00
Aris Adamantiadis
367558bb21 crypto: fix potential memory leak in ECDH 2015-09-21 15:03:08 +02:00
Andreas Schneider
186e7b5ca4 kex: Fix zlib compression
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 747e7d05db)
2015-09-16 08:34:58 +02:00
Andreas Schneider
2197704693 Bump version to 0.7.2 2015-09-15 15:17:35 +02:00
Andreas Schneider
229eb8715d cmake: Use tar.xz source package generator
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1f3a9105ff)
2015-09-15 15:17:35 +02:00
Andreas Schneider
1b18a06f8c kex: Prefer sha2 over sha1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b0f22fde62)
2015-09-15 15:09:21 +02:00
Andreas Schneider
91b513798e cmake: Handle libssh threas library correctly
This should fix the build on Windows and would not install pkg files.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5b586fdfec)
2015-09-08 17:32:57 +02:00
Michael Wilder
25234e510a bignum: Fix OpenSSL crash in SAFE_FREE
Signed-off-by: Michael Wilder <wilder.michael@cimcor.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 2f193b5cbb)
2015-09-08 17:32:40 +02:00
Andreas Schneider
d16eac5704 server: Fix return code check of ssh_buffer_pack()
Thanks to Andreas Gutschick <andreas.gutschick@mitel.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 36d9b62f1f)
2015-08-18 09:12:47 +02:00
Andreas Schneider
46bff47975 doc: Fix typos in sftp tutorial
Thanks to Anthony Baker <AnthonyBaker@fico.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit da4bebbe1e)
2015-08-18 09:05:45 +02:00
Andreas Schneider
f718b50b3f tests: Add checks for ssh_key_is_private()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit d54a1ab798)
2015-08-10 13:58:51 +02:00
Andreas Schneider
58b7d0f5d2 pki: Fix return values of ssh_key_is_(public|private)
Thanks to Kevin Haake <khaake@red-cocoa.com>

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e1081796af)
2015-08-10 13:58:50 +02:00
Tilo Eckert
30d4581be5 sftp: Fix incorrect handling of received length fields
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
2015-08-01 10:52:48 +03:00
Peter Volpe
83387f957f auth: Fix return status for ssh_userauth_agent()
BUG: https://red.libssh.org/issues/201

Return SSH_AUTH_DENIED instead of SSH_AUTH_ERROR when the provided agent
offers no public keys.

Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit dc9c4d22ab)
2015-07-30 10:52:11 +02:00
Andreas Schneider
f3620bbbad cmake: Fix zlib include directory
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 728c2fbd01)
2015-07-03 12:36:53 +02:00
Andreas Schneider
b45933d30d cmake: Fix OpenSSL detection in non-standard path
This should fix the detection on Windows.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 613b71b385)
2015-07-03 11:40:04 +02:00
Andreas Schneider
1613ed556d cmake: Fail if can't find OpenSSL aes and des headers
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 70cc11618a)
2015-07-03 10:52:56 +02:00
Andreas Schneider
8f5b7b65eb include: Add stdarg.h so we can check for va_copy macro
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-06-30 09:59:21 +02:00
Andreas Schneider
053f72c671 Bump version to 0.7.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2015-06-30 09:34:28 +02:00
Tilo Eckert
63a8f333b8 SSH_AUTH_PARTIAL is now correctly passed to the caller of ssh_userauth_publickey_auto().
Implicitly fixed unsafe return code handling that could result in use-after-free.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 0423057424)
2015-06-29 11:11:26 +02:00
Tilo Eckert
57fd8e3187 available auth_methods must be reset on partial authentication
Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cc25d747d4)
2015-06-29 11:11:25 +02:00
Peter Volpe
03972b16c9 channels: Fix exit-signal data unpacking
Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7637351065)
2015-06-29 09:50:28 +02:00
Peter Volpe
ac7ed82585 agent: Add ssh_set_agent_socket
Allow callers to specify their own socket
for an ssh agent.

Signed-off-by: Peter Volpe <pvolpe@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 7aeba71a92)
2015-06-29 09:47:35 +02:00
Seb Boving
196c2e9c1f Don't allocate a new identity list in the new session's options.
The previous list is not freed. Since the new session just got
created, an identity list is already allocated and empty.

Signed-off-by: Sebastien Boving <seb@google.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e020dd8d59)
2015-06-24 18:36:10 +02:00
Douglas Heriot
1accbcb98b cmake: Do not use CMAKE_(SOURCE|BINARY)_DIR
(cherry picked from commit a65af1b3b8)
2015-06-24 18:36:08 +02:00
Tiamo Laitakari
342ae10f08 pki: Fix allocation of ed25519 public keys
Signed-off-by: Tiamo Laitakari <tiamo.laitakari@cs.helsinki.fi>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5478de1a64)
2015-06-24 18:36:08 +02:00
Jordy Moos
eb98a780ed Documentation fix where unsigned is used where signed is expected
Signed-off-by: Jordy Moos <jordymoos@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit fa9fbb1d67)
2015-06-24 18:36:08 +02:00
Andreas Schneider
64233fa3bb misc: Correctly guard the sys/time.h include
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ef751a26d0)
2015-06-24 18:36:08 +02:00
Andreas Schneider
cbf5cf4ac3 include: Add support for older MSVC versions
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 30a7229fc5)
2015-06-24 16:24:12 +02:00
Andreas Schneider
a3f3f9cb76 kex: Add comments to #if clauses
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1d69e073af)
2015-06-24 16:24:08 +02:00
Aris Adamantiadis
5aeae08be0 channels: fix exit-status not correctly set 2015-06-03 16:41:19 +02:00
Mike DePaulo
64a658acaa Comment that ssh_forward_cancel() is deprecated.
Signed-off-by: Aris Adamantiadis <aris@badcode.be>
2015-05-29 11:30:32 +02:00
Mike DePaulo
361940a5d7 Reintroduce ssh_forward_listen() (Fixes: #194)
Signed-off-by: Aris Adamantiadis <aris@badcode.be>
2015-05-29 11:24:27 +02:00
Andreas Schneider
2721cbc8ee ChangeLog: Set release date for 0.7.0 2015-05-11 10:42:08 +02:00
42 changed files with 633 additions and 409 deletions

4
.gitignore vendored
View File

@@ -3,7 +3,7 @@
.* .*
*.swp *.swp
*~$ *~$
obj
cscope.* cscope.*
tags tags
build /build
/obj*

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 "7") set(APPLICATION_VERSION_MINOR "7")
set(APPLICATION_VERSION_PATCH "0") set(APPLICATION_VERSION_PATCH "4")
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,12 +19,12 @@ 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.0") set(LIBRARY_VERSION "4.4.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
set(CMAKE_MODULE_PATH set(CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake/Modules ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules
) )
# add definitions # add definitions
@@ -84,8 +84,8 @@ add_subdirectory(include)
add_subdirectory(src) add_subdirectory(src)
# pkg-config file # pkg-config file
if (UNIX)
configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc) configure_file(libssh.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc)
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
install( install(
FILES FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc ${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
@@ -96,6 +96,20 @@ install(
pkgconfig pkgconfig
) )
if (LIBSSH_THREADS)
configure_file(libssh_threads.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/libssh.pc
${CMAKE_CURRENT_BINARY_DIR}/libssh_threads.pc
DESTINATION
${LIB_INSTALL_DIR}/pkgconfig
COMPONENT
pkgconfig
)
endif (LIBSSH_THREADS)
endif (UNIX)
# cmake config files # cmake config files
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX}) set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
set(LIBSSH_THREADS_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX}) set(LIBSSH_THREADS_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})

View File

@@ -4,10 +4,10 @@
### general settings ### general settings
set(CPACK_PACKAGE_NAME ${APPLICATION_NAME}) set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH library") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The SSH library")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team") set(CPACK_PACKAGE_VENDOR "The SSH Library Development Team")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
### versions ### versions
@@ -18,8 +18,8 @@ set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSIO
### source generator ### source generator
set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_GENERATOR "TXZ")
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;/obj/;tags;cscope.*") set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;/obj*/;tags;cscope.*")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
if (WIN32) if (WIN32)

View File

@@ -1,7 +1,32 @@
ChangeLog ChangeLog
========== ==========
version 0.7.4 (released 2017-02-03)
* Added id_ed25519 to the default identity list
* Fixed sftp EOF packet handling
* Fixed ssh_send_banner() to confirm with RFC 4253
* Fixed some memory leaks
version 0.7.0 (released 2015-05-xx) version 0.7.3 (released 2016-01-23)
* Fixed CVE-2016-0739
* Fixed ssh-agent on big endian
* Fixed some documentation issues
version 0.7.2 (released 2015-09-15)
* Fixed OpenSSL detection on Windows
* Fixed return status for ssh_userauth_agent()
* Fixed KEX to prefer hmac-sha2-256
* Fixed sftp packet handling
* Fixed return values of ssh_key_is_(public|private)
* Fixed bug in global success reply
version 0.7.1 (released 2015-06-30)
* Fixed SSH_AUTH_PARTIAL auth with auto public key
* Fixed memory leak in session options
* Fixed allocation of ed25519 public keys
* Fixed channel exit-status and exit-signal
* Reintroduce ssh_forward_listen()
version 0.7.0 (released 2015-05-11)
* Added support for ed25519 keys * Added support for ed25519 keys
* Added SHA2 algorithms for HMAC * Added SHA2 algorithms for HMAC
* Added improved and more secure buffer handling code * Added improved and more secure buffer handling code

View File

@@ -1,4 +1,5 @@
include(CheckIncludeFile) include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists) include(CheckSymbolExists)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckLibraryExists) include(CheckLibraryExists)
@@ -56,6 +57,7 @@ check_include_file(libutil.h HAVE_LIBUTIL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/param.h HAVE_SYS_PARAM_H) check_include_file(sys/param.h HAVE_SYS_PARAM_H)
check_include_file(arpa/inet.h HAVE_ARPA_INET_H) check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(byteswap.h HAVE_BYTESWAP_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)
@@ -65,23 +67,31 @@ if (WIN32)
check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H) check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H)
endif (WIN32) endif (WIN32)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS}) if (OPENSSL_FOUND)
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
if (NOT HAVE_OPENSSL_DES_H)
message(FATAL_ERROR "Could not detect openssl/des.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H) check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
if (NOT HAVE_OPENSSL_AES_H)
message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H) check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H) check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H) check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H) check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
endif()
if (CMAKE_HAVE_PTHREAD_H) if (CMAKE_HAVE_PTHREAD_H)
set(HAVE_PTHREAD_H 1) set(HAVE_PTHREAD_H 1)
@@ -101,16 +111,21 @@ endif (NOT WITH_GCRYPT)
check_function_exists(isblank HAVE_ISBLANK) 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(strtoull HAVE_STRTOULL)
check_function_exists(snprintf HAVE_SNPRINTF)
if (NOT WIN32)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
endif (NOT WIN32)
if (WIN32) if (WIN32)
check_function_exists(_strtoui64 HAVE__STRTOUI64) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S) check_symbol_exists(_vsnprintf_s "stdio.h" HAVE__VSNPRINTF_S)
check_function_exists(_vsnprintf HAVE__VSNPRINTF) check_symbol_exists(_vsnprintf "stdio.h" HAVE__VSNPRINTF)
check_function_exists(_snprintf HAVE__SNPRINTF) check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
check_function_exists(_snprintf_s HAVE__SNPRINTF_S) check_symbol_exists(_snprintf_s "stdio.h" HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H) if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL) check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL)
@@ -124,6 +139,8 @@ if (WIN32)
set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_LIBRARIES)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H) endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
set(HAVE_SELECT TRUE) set(HAVE_SELECT TRUE)
else (WIN32) else (WIN32)
check_function_exists(poll HAVE_POLL) check_function_exists(poll HAVE_POLL)
@@ -161,7 +178,6 @@ if (UNIX)
check_library_exists(util forkpty "" HAVE_LIBUTIL) check_library_exists(util forkpty "" HAVE_LIBUTIL)
check_function_exists(cfmakeraw HAVE_CFMAKERAW) check_function_exists(cfmakeraw HAVE_CFMAKERAW)
check_function_exists(strtoull HAVE_STRTOULL)
check_function_exists(__strtoull HAVE___STRTOULL) check_function_exists(__strtoull HAVE___STRTOULL)
endif (UNIX) endif (UNIX)

125
README
View File

@@ -33,130 +33,11 @@ If you ask yourself how to compile libssh, please read INSTALL before anything.
http://www.libssh.org http://www.libssh.org
4* API Changes ! 4* Contributing
-_-_-_-_-_-_-_-_-_ -_-_-_-_-_-_-_-_-_
Changes between 0.4 and 0.5 Please read the file 'SubmittingPatches' next to this README file. It explains
--------------------------- our copyright policy and how you should send patches for upstream inclusion.
We use the ssh_ prefix as namespace for every function now. There is a legacy.h
which could be used to get the old function names.
Changes between 0.3 and 0.4
---------------------------
We changed libssh to be typesafe now:
SSH_SESSION *session -> ssh_session session
SFTP_SESSION *sftp -> sftp_session sftp
CHANNEL *channel -> ssh_channel channel
STRING *string -> ssh_string string
...
The options structure has been removed and there is a new function. This
function can set all available options now. You can find the enum in the
header file and it is documented. Example:
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
5* Copyright policy
-_-_-_-_-_-_-_-_-_-_
libssh is a project with distributed copyright ownership, which means we prefer
the copyright on parts of libssh to be held by individuals rather than
corporations if possible. There are historical legal reasons for this, but one
of the best ways to explain it is that its much easier to work with
individuals who have ownership than corporate legal departments if we ever need
to make reasonable compromises with people using and working with libssh.
We track the ownership of every part of libssh via git, our source code control
system, so we know the provenance of every piece of code that is committed to
libssh.
So if possible, if youre doing libssh changes on behalf of a company who
normally owns all the work you do please get them to assign personal copyright
ownership of your changes to you as an individual, that makes things very easy
for us to work with and avoids bringing corporate legal departments into the
picture.
If you cant do this we can still accept patches from you owned by your
employer under a standard employment contract with corporate copyright
ownership. It just requires a simple set-up process first.
We use a process very similar to the way things are done in the Linux Kernel
community, so it should be very easy to get a sign off from your corporate
legal department. The only changes weve made are to accommodate the license we
use, which is LGPLv2 (or later) whereas the Linux kernel uses GPLv2.
The process is called signing.
How to sign your work
----------------------
Once you have permission to contribute to libssh from your employer, simply
email a copy of the following text from your corporate email address to:
contributing@libssh.org
--------------------------------------------------------------------------
libssh Developer's Certificate of Origin. Version 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the appropriate
version of the GNU General Public License; or
(b) The contribution is based upon previous work that, to the best of
my knowledge, is covered under an appropriate open source license
and I have the right under that license to submit that work with
modifications, whether created in whole or in part by me, under
the GNU General Public License, in the appropriate version; or
(c) The contribution was provided directly to me by some other
person who certified (a) or (b) and I have not modified it.
(d) I understand and agree that this project and the contribution are
public and that a record of the contribution (including all
metadata and personal information I submit with it, including my
sign-off) is maintained indefinitely and may be redistributed
consistent with the libssh Team's policies and the requirements of
the GNU GPL where they are relevant.
(e) I am granting this work to this project under the terms of the
GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of
the License, or (at the option of the project) any later version.
http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------
We will maintain a copy of that email as a record that you have the rights to
contribute code to libssh under the required licenses whilst working for the
company where the email came from.
Then when sending in a patch via the normal mechanisms described above, add a
line that states:
Signed-off-by: Random J Developer <random@developer.example.org>
using your real name and the email address you sent the original email you used
to send the libssh Developers Certificate of Origin to us (sorry, no
pseudonyms or anonymous contributions.)
Thats it! Such code can then quite happily contain changes that have copyright
messages such as:
(c) Example Corporation.
and can be merged into the libssh codebase in the same way as patches from any
other individual. You dont need to send in a copy of the libssh Developers
Certificate of Origin for each patch, or inside each patch. Just the sign-off
message is all that is required once weve received the initial email.
Have fun and happy libssh hacking! Have fun and happy libssh hacking!

View File

@@ -56,7 +56,7 @@ If an error has been encountered, it returns a negative value:
@code @code
char buffer[256]; char buffer[256];
unsigned int nbytes; int nbytes;
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) while (nbytes > 0)

View File

@@ -367,7 +367,7 @@ int show_remote_processes(ssh_session session)
ssh_channel channel; ssh_channel channel;
int rc; int rc;
char buffer[256]; char buffer[256];
unsigned int nbytes; int nbytes;
channel = ssh_channel_new(session); channel = ssh_channel_new(session);
if (channel == NULL) if (channel == NULL)
@@ -391,7 +391,7 @@ int show_remote_processes(ssh_session session)
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) while (nbytes > 0)
{ {
if (write(1, buffer, nbytes) != nbytes) if (write(1, buffer, nbytes) != (unsigned int) nbytes)
{ {
ssh_channel_close(channel); ssh_channel_close(channel);
ssh_channel_free(channel); ssh_channel_free(channel);

View File

@@ -253,7 +253,7 @@ int sftp_read_sync(ssh_session session, sftp_session sftp)
return SSH_ERROR; return SSH_ERROR;
} }
nwritten = write(fd, buf, nbytes); nwritten = write(fd, buffer, nbytes);
if (nwritten != nbytes) { if (nwritten != nbytes) {
fprintf(stderr, "Error writing: %s\n", fprintf(stderr, "Error writing: %s\n",
strerror(errno)); strerror(errno));
@@ -282,7 +282,7 @@ sftp_async_read() waits for the data to come. To open a file in nonblocking mode
call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode. call sftp_file_set_nonblocking() right after you opened it. Default is blocking mode.
The example below reads a very big file in asynchronous, nonblocking, mode. Each The example below reads a very big file in asynchronous, nonblocking, mode. Each
time the data are not ready yet, a counter is incrementer. time the data is not ready yet, a counter is incremented.
@code @code
// Good chunk size // Good chunk size

View File

@@ -1,3 +1,3 @@
project(headers C) project(libssh-headers-x C)
add_subdirectory(libssh) add_subdirectory(libssh)

View File

@@ -58,6 +58,7 @@
#else /* _MSC_VER */ #else /* _MSC_VER */
#include <unistd.h> #include <unistd.h>
#include <inttypes.h> #include <inttypes.h>
#include <sys/types.h>
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#ifdef _WIN32 #ifdef _WIN32
@@ -78,7 +79,7 @@
/* libssh version */ /* libssh version */
#define LIBSSH_VERSION_MAJOR 0 #define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 7 #define LIBSSH_VERSION_MINOR 7
#define LIBSSH_VERSION_MICRO 0 #define LIBSSH_VERSION_MICRO 4
#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, \
@@ -588,6 +589,7 @@ LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socke
fd_set *readfds, struct timeval *timeout); fd_set *readfds, struct timeval *timeout);
LIBSSH_API int ssh_service_request(ssh_session session, const char *service); LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
LIBSSH_API int ssh_set_agent_channel(ssh_session session, ssh_channel channel); LIBSSH_API int ssh_set_agent_channel(ssh_session session, ssh_channel channel);
LIBSSH_API int ssh_set_agent_socket(ssh_session session, socket_t fd);
LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking); LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking);
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter, LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
ssh_counter rcounter); ssh_counter rcounter);

View File

@@ -33,15 +33,6 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2);
int ssh_is_ipaddr_v4(const char *str); int ssh_is_ipaddr_v4(const char *str);
int ssh_is_ipaddr(const char *str); int ssh_is_ipaddr(const char *str);
#ifndef HAVE_NTOHLL
/* macro for byte ordering */
uint64_t ntohll(uint64_t);
#endif
#ifndef HAVE_HTONLL
#define htonll(x) ntohll((x))
#endif
/* list processing */ /* list processing */
struct ssh_list { struct ssh_list {

View File

@@ -43,6 +43,16 @@
# endif # endif
#endif /* !defined(HAVE_STRTOULL) */ #endif /* !defined(HAVE_STRTOULL) */
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#endif
#ifndef bswap_32
#define bswap_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#endif
#ifdef _WIN32 #ifdef _WIN32
/* Imitate define of inttypes.h */ /* Imitate define of inttypes.h */
@@ -60,11 +70,16 @@
# ifdef _MSC_VER # ifdef _MSC_VER
# include <stdio.h> # include <stdio.h>
# include <stdarg.h> /* va_copy define check */
/* On Microsoft compilers define inline to __inline on all others use inline */ /* On Microsoft compilers define inline to __inline on all others use inline */
# undef inline # undef inline
# define inline __inline # define inline __inline
# ifndef va_copy
# define va_copy(dest, src) (dest = src)
# endif
# define strcasecmp _stricmp # define strcasecmp _stricmp
# define strncasecmp _strnicmp # define strncasecmp _strnicmp
# if ! defined(HAVE_ISBLANK) # if ! defined(HAVE_ISBLANK)
@@ -131,10 +146,10 @@ int gettimeofday(struct timeval *__p, void *__t);
#define ERROR_BUFFERLEN 1024 #define ERROR_BUFFERLEN 1024
#endif #endif
#ifndef CLIENTBANNER1 #ifndef CLIENTBANNER1
#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION) #define CLIENTBANNER1 "SSH-1.5-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
#endif #endif
#ifndef CLIENTBANNER2 #ifndef CLIENTBANNER2
#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION) #define CLIENTBANNER2 "SSH-2.0-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
#endif #endif
#ifndef KBDINT_MAX_PROMPT #ifndef KBDINT_MAX_PROMPT
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */ #define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
@@ -346,5 +361,25 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
#define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0) #define CLOSE_SOCKET(s) do { if ((s) != SSH_INVALID_SOCKET) { _XCLOSESOCKET(s); (s) = SSH_INVALID_SOCKET;} } while(0)
#ifndef HAVE_HTONLL
# ifdef WORDS_BIGENDIAN
# define htonll(x) (x)
# else
# define htonll(x) \
(((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# endif
#endif
#ifndef HAVE_NTOHLL
# ifdef WORDS_BIGENDIAN
# define ntohll(x) (x)
# else
# define ntohll(x) \
(((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
# endif
#endif
void ssh_agent_state_free(void *data);
#endif /* _LIBSSH_PRIV_H */ #endif /* _LIBSSH_PRIV_H */
/* vim: set ts=4 sw=4 et cindent: */ /* vim: set ts=4 sw=4 et cindent: */

View File

@@ -1,12 +1,12 @@
project(libssh-library C) project(libssh-library C)
set(LIBSSH_PUBLIC_INCLUDE_DIRS set(LIBSSH_PUBLIC_INCLUDE_DIRS
${CMAKE_SOURCE_DIR}/include ${libssh_SOURCE_DIR}/include
CACHE INTERNAL "libssh public include directories" CACHE INTERNAL "libssh public include directories"
) )
set(LIBSSH_PRIVATE_INCLUDE_DIRS set(LIBSSH_PRIVATE_INCLUDE_DIRS
${CMAKE_BINARY_DIR} ${libssh_BINARY_DIR}
) )
set(LIBSSH_LINK_LIBRARIES set(LIBSSH_LINK_LIBRARIES
@@ -54,7 +54,7 @@ endif (GCRYPT_LIBRARY)
if (WITH_ZLIB) if (WITH_ZLIB)
set(LIBSSH_PRIVATE_INCLUDE_DIRS set(LIBSSH_PRIVATE_INCLUDE_DIRS
${LIBSSH_PRIVATE_INCLUDE_DIRS} ${LIBSSH_PRIVATE_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
) )
set(LIBSSH_LINK_LIBRARIES set(LIBSSH_LINK_LIBRARIES
@@ -300,6 +300,7 @@ if (WITH_STATIC_LIB)
) )
endif (WITH_STATIC_LIB) endif (WITH_STATIC_LIB)
message(STATUS "Threads_FOUND=${Threads_FOUND}")
if (Threads_FOUND) if (Threads_FOUND)
add_subdirectory(threads) add_subdirectory(threads)
endif (Threads_FOUND) endif (Threads_FOUND)

View File

@@ -185,15 +185,32 @@ int ssh_set_agent_channel(ssh_session session, ssh_channel channel){
return SSH_OK; return SSH_OK;
} }
/** @brief sets the SSH agent socket.
* The SSH agent will be used to authenticate this client using
* the given socket to communicate with the ssh-agent. The caller
* is responsible for connecting to the socket prior to calling
* this function.
* @returns SSH_OK in case of success
* SSH_ERROR in case of an error
*/
int ssh_set_agent_socket(ssh_session session, socket_t fd){
if (!session)
return SSH_ERROR;
if (!session->agent){
ssh_set_error(session, SSH_REQUEST_DENIED, "Session has no active agent");
return SSH_ERROR;
}
ssh_socket_set_fd(session->agent->sock, fd);
return SSH_OK;
}
void agent_close(struct ssh_agent_struct *agent) { void agent_close(struct ssh_agent_struct *agent) {
if (agent == NULL) { if (agent == NULL) {
return; return;
} }
if (getenv("SSH_AUTH_SOCK")) { ssh_socket_close(agent->sock);
ssh_socket_close(agent->sock);
}
} }
void agent_free(ssh_agent agent) { void agent_free(ssh_agent agent) {
@@ -365,6 +382,9 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
ssh_buffer_free(reply); ssh_buffer_free(reply);
return -1; return -1;
} }
#ifdef WORDS_BIGENDIAN
type = bswap_32(type);
#endif
SSH_LOG(SSH_LOG_WARN, SSH_LOG(SSH_LOG_WARN,
"Answer type: %d, expected answer: %d", "Answer type: %d, expected answer: %d",
@@ -375,7 +395,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
return 0; return 0;
} else if (type != c2) { } else if (type != c2) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Bad authentication reply message type: %d", type); "Bad authentication reply message type: %u", type);
ssh_buffer_free(reply); ssh_buffer_free(reply);
return -1; return -1;
} }
@@ -490,8 +510,8 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer reply; ssh_buffer reply;
ssh_string key_blob; ssh_string key_blob;
ssh_string sig_blob; ssh_string sig_blob;
int type = SSH2_AGENT_FAILURE; unsigned int type = 0;
int flags = 0; unsigned int flags = 0;
uint32_t dlen; uint32_t dlen;
int rc; int rc;
@@ -555,13 +575,19 @@ ssh_string ssh_agent_sign_data(ssh_session session,
ssh_buffer_free(reply); ssh_buffer_free(reply);
return NULL; return NULL;
} }
#ifdef WORDS_BIGENDIAN
type = bswap_32(type);
#endif
if (agent_failed(type)) { if (agent_failed(type)) {
SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key"); SSH_LOG(SSH_LOG_WARN, "Agent reports failure in signing the key");
ssh_buffer_free(reply); ssh_buffer_free(reply);
return NULL; return NULL;
} else if (type != SSH2_AGENT_SIGN_RESPONSE) { } else if (type != SSH2_AGENT_SIGN_RESPONSE) {
ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type); ssh_set_error(session,
SSH_FATAL,
"Bad authentication response: %u",
type);
ssh_buffer_free(reply); ssh_buffer_free(reply);
return NULL; return NULL;
} }

49
src/auth.c Normal file → Executable file
View File

@@ -209,8 +209,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){
"Access denied. Authentication that can continue: %s", "Access denied. Authentication that can continue: %s",
auth_methods); auth_methods);
session->auth_methods = 0;
} }
session->auth_methods = 0;
if (strstr(auth_methods, "password") != NULL) { if (strstr(auth_methods, "password") != NULL) {
session->auth_methods |= SSH_AUTH_METHOD_PASSWORD; session->auth_methods |= SSH_AUTH_METHOD_PASSWORD;
} }
@@ -740,6 +740,15 @@ struct ssh_agent_state_struct {
char *comment; char *comment;
}; };
/* Internal function */
void ssh_agent_state_free(void *data) {
struct ssh_agent_state_struct *state = data;
if (state) {
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
free (state);
}
}
/** /**
* @brief Try to do public key authentication with ssh agent. * @brief Try to do public key authentication with ssh agent.
@@ -786,6 +795,11 @@ int ssh_userauth_agent(ssh_session session,
state = session->agent_state; state = session->agent_state;
if (state->pubkey == NULL) if (state->pubkey == NULL)
state->pubkey = ssh_agent_get_first_ident(session, &state->comment); state->pubkey = ssh_agent_get_first_ident(session, &state->comment);
if (state->pubkey == NULL) {
return SSH_AUTH_DENIED;
}
while (state->pubkey != NULL) { while (state->pubkey != NULL) {
if(state->state == SSH_AGENT_STATE_NONE){ if(state->state == SSH_AGENT_STATE_NONE){
SSH_LOG(SSH_LOG_DEBUG, SSH_LOG(SSH_LOG_DEBUG,
@@ -795,9 +809,8 @@ int ssh_userauth_agent(ssh_session session,
state->state == SSH_AGENT_STATE_PUBKEY){ state->state == SSH_AGENT_STATE_PUBKEY){
rc = ssh_userauth_try_publickey(session, username, state->pubkey); rc = ssh_userauth_try_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_ERROR) { if (rc == SSH_AUTH_ERROR) {
ssh_string_free_char(state->comment); ssh_agent_state_free (state);
ssh_key_free(state->pubkey); session->agent_state = NULL;
SAFE_FREE(session->agent_state);
return rc; return rc;
} else if (rc == SSH_AUTH_AGAIN) { } else if (rc == SSH_AUTH_AGAIN) {
state->state = SSH_AGENT_STATE_PUBKEY; state->state = SSH_AGENT_STATE_PUBKEY;
@@ -806,6 +819,7 @@ int ssh_userauth_agent(ssh_session session,
SSH_LOG(SSH_LOG_DEBUG, SSH_LOG(SSH_LOG_DEBUG,
"Public key of %s refused by server", state->comment); "Public key of %s refused by server", state->comment);
ssh_string_free_char(state->comment); ssh_string_free_char(state->comment);
state->comment = NULL;
ssh_key_free(state->pubkey); ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment); state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE; state->state = SSH_AGENT_STATE_NONE;
@@ -821,23 +835,27 @@ int ssh_userauth_agent(ssh_session session,
if (rc == SSH_AUTH_AGAIN) if (rc == SSH_AUTH_AGAIN)
return rc; return rc;
ssh_string_free_char(state->comment); ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey); state->comment = NULL;
if (rc == SSH_AUTH_ERROR) { if (rc == SSH_AUTH_ERROR) {
SAFE_FREE(session->agent_state); ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return rc; return rc;
} else if (rc != SSH_AUTH_SUCCESS) { } else if (rc != SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO, SSH_LOG(SSH_LOG_INFO,
"Server accepted public key but refused the signature"); "Server accepted public key but refused the signature");
ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment); state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE; state->state = SSH_AGENT_STATE_NONE;
continue; continue;
} }
SAFE_FREE(session->agent_state); ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
} }
} }
SAFE_FREE(session->agent_state); ssh_agent_state_free (session->agent_state);
session->agent_state = NULL;
return rc; return rc;
} }
#endif #endif
@@ -1045,15 +1063,14 @@ int ssh_userauth_publickey_auto(ssh_session session,
ssh_key_free(state->privkey); ssh_key_free(state->privkey);
ssh_key_free(state->pubkey); ssh_key_free(state->pubkey);
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth_auto_state);
if (rc == SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO,
"Successfully authenticated using %s",
privkey_file);
}
return rc;
} }
if (rc == SSH_AUTH_ERROR) { if (rc == SSH_AUTH_AGAIN){
return rc;
} else if (rc == SSH_AUTH_SUCCESS) {
SSH_LOG(SSH_LOG_INFO,
"Successfully authenticated using %s",
privkey_file);
return rc;
} else if (rc == SSH_AUTH_AGAIN){
return rc; return rc;
} }

View File

@@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include <errno.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@@ -117,6 +118,7 @@ static int send_username(ssh_session session, const char *username) {
if (packet_send(session) == SSH_ERROR) { if (packet_send(session) == SSH_ERROR) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
return SSH_AUTH_AGAIN;
pending: pending:
rc = wait_auth1_status(session); rc = wait_auth1_status(session);
switch (rc){ switch (rc){
@@ -161,12 +163,14 @@ int ssh_userauth1_password(ssh_session session, const char *username,
ssh_string pwd = NULL; ssh_string pwd = NULL;
int rc; int rc;
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD) {
goto pending;
}
rc = send_username(session, username); rc = send_username(session, username);
if (rc != SSH_AUTH_DENIED) { if (rc != SSH_AUTH_DENIED) {
return rc; return rc;
} }
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD)
goto pending;
/* we trick a bit here. A known flaw in SSH1 protocol is that it's /* we trick a bit here. A known flaw in SSH1 protocol is that it's
* easy to guess password sizes. * easy to guess password sizes.
* not that sure ... * not that sure ...
@@ -219,8 +223,11 @@ int ssh_userauth1_password(ssh_session session, const char *username,
} }
pending: pending:
rc = wait_auth1_status(session); rc = wait_auth1_status(session);
if (rc != SSH_AUTH_AGAIN) if (rc == SSH_AUTH_ERROR && errno == EAGAIN) {
session->pending_call_state = SSH_PENDING_CALL_NONE; /* Nothing to do */
} else if (rc != SSH_AUTH_AGAIN) {
session->pending_call_state = SSH_PENDING_CALL_NONE;
}
return rc; return rc;
} }

View File

@@ -103,5 +103,9 @@ void ssh_print_bignum(const char *which, bignum num) {
#endif #endif
fprintf(stderr, "%s value: ", which); fprintf(stderr, "%s value: ", which);
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex); fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
#ifdef HAVE_LIBGCRYPT
SAFE_FREE(hex); SAFE_FREE(hex);
#elif defined HAVE_LIBCRYPTO
OPENSSL_free(hex);
#endif
} }

View File

@@ -664,11 +664,9 @@ SSH_PACKET_CALLBACK(channel_rcv_request) {
} }
if (strcmp(request,"exit-status") == 0) { if (strcmp(request,"exit-status") == 0) {
uint32_t exit_status = 0; SAFE_FREE(request);
rc = ssh_buffer_unpack(packet, "d", &channel->exit_status);
SAFE_FREE(request); SSH_LOG(SSH_LOG_PACKET, "received exit-status %d", channel->exit_status);
rc = ssh_buffer_unpack(packet, "d", &exit_status);
SSH_LOG(SSH_LOG_PACKET, "received exit-status %d", channel->exit_status);
if(ssh_callbacks_exists(channel->callbacks, channel_exit_status_function)) { if(ssh_callbacks_exists(channel->callbacks, channel_exit_status_function)) {
channel->callbacks->channel_exit_status_function(channel->session, channel->callbacks->channel_exit_status_function(channel->session,
@@ -714,7 +712,7 @@ SSH_PACKET_CALLBACK(channel_rcv_request) {
SAFE_FREE(request); SAFE_FREE(request);
rc = ssh_buffer_unpack(packet, "sbs", rc = ssh_buffer_unpack(packet, "sbss",
&sig, /* signal name */ &sig, /* signal name */
&core_dumped, /* core dumped */ &core_dumped, /* core dumped */
&errmsg, /* error message */ &errmsg, /* error message */
@@ -1247,7 +1245,7 @@ static int channel_write_common(ssh_channel channel,
return -1; return -1;
} }
if (channel->session->session_state == SSH_SESSION_STATE_ERROR) { if (session->session_state == SSH_SESSION_STATE_ERROR) {
return SSH_ERROR; return SSH_ERROR;
} }
#ifdef WITH_SSH1 #ifdef WITH_SSH1
@@ -1278,7 +1276,7 @@ static int channel_write_common(ssh_channel channel,
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 || session->session_state == SSH_SESSION_STATE_ERROR ||
channel->state == SSH_CHANNEL_STATE_CLOSED) channel->state == SSH_CHANNEL_STATE_CLOSED)
goto out; goto out;
continue; continue;
@@ -2205,6 +2203,11 @@ error:
return rc; return rc;
} }
/* DEPRECATED */
int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port) {
return ssh_channel_listen_forward(session, address, port, bound_port);
}
/* DEPRECATED */ /* DEPRECATED */
ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms) { ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms) {
return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, NULL); return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, NULL);
@@ -2272,6 +2275,7 @@ error:
return rc; return rc;
} }
/* DEPRECATED */
int ssh_forward_cancel(ssh_session session, const char *address, int port) { int ssh_forward_cancel(ssh_session session, const char *address, int port) {
return ssh_channel_cancel_forward(session, address, port); return ssh_channel_cancel_forward(session, address, port);
} }
@@ -2685,7 +2689,7 @@ int ssh_channel_read_timeout(ssh_channel channel,
if (rc == SSH_ERROR){ if (rc == SSH_ERROR){
return rc; return rc;
} }
if (channel->session->session_state == SSH_SESSION_STATE_ERROR){ if (session->session_state == SSH_SESSION_STATE_ERROR){
return SSH_ERROR; return SSH_ERROR;
} }
if (channel->remote_eof && buffer_get_rest_len(stdbuf) == 0) { if (channel->remote_eof && buffer_get_rest_len(stdbuf) == 0) {
@@ -2750,7 +2754,7 @@ int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count
to_read = ssh_channel_poll(channel, is_stderr); to_read = ssh_channel_poll(channel, is_stderr);
if (to_read <= 0) { if (to_read <= 0) {
if (channel->session->session_state == SSH_SESSION_STATE_ERROR){ if (session->session_state == SSH_SESSION_STATE_ERROR){
return SSH_ERROR; return SSH_ERROR;
} }

View File

@@ -90,52 +90,74 @@ static void socket_callback_connected(int code, int errno_code, void *user){
* @param user is a pointer to session * @param user is a pointer to session
* @returns Number of bytes processed, or zero if the banner is not complete. * @returns Number of bytes processed, or zero if the banner is not complete.
*/ */
static int callback_receive_banner(const void *data, size_t len, void *user) { static int callback_receive_banner(const void *data, size_t len, void *user)
char *buffer = (char *)data; {
ssh_session session=(ssh_session) user; char *buffer = (char *)data;
char *str = NULL; ssh_session session=(ssh_session) user;
size_t i; char *str = NULL;
int ret=0; size_t i;
int ret=0;
if(session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED){ if (session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED) {
ssh_set_error(session,SSH_FATAL,"Wrong state in callback_receive_banner : %d",session->session_state); ssh_set_error(session,SSH_FATAL,
"Wrong state in callback_receive_banner : %d",
session->session_state);
return SSH_ERROR; return SSH_ERROR;
}
for(i=0;i<len;++i){
#ifdef WITH_PCAP
if(session->pcap_ctx && buffer[i] == '\n'){
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1);
}
#endif
if(buffer[i]=='\r') {
buffer[i]='\0';
} }
if (buffer[i]=='\n') { for (i = 0; i < len; ++i) {
buffer[i] = '\0'; #ifdef WITH_PCAP
str = strdup(buffer); if (session->pcap_ctx && buffer[i] == '\n') {
if (str == NULL) { ssh_pcap_context_write(session->pcap_ctx,
return SSH_ERROR; SSH_PCAP_DIR_IN,
buffer,i+1,
i+1);
} }
/* number of bytes read */ #endif
ret = i + 1; if (buffer[i] == '\r') {
session->serverbanner = str; buffer[i] = '\0';
session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED; }
SSH_LOG(SSH_LOG_PACKET,"Received banner: %s",str); if (buffer[i] == '\n') {
session->ssh_connection_callback(session); int cmp;
return ret; buffer[i] = '\0';
}
if(i>127){
/* Too big banner */
session->session_state=SSH_SESSION_STATE_ERROR;
ssh_set_error(session,SSH_FATAL,"Receiving banner: too large banner");
return 0; /* The server MAY send other lines of data... */
} cmp = strncmp(buffer, "SSH-", 4);
} if (cmp == 0) {
str = strdup(buffer);
if (str == NULL) {
return SSH_ERROR;
}
/* number of bytes read */
ret = i + 1;
session->serverbanner = str;
session->session_state = SSH_SESSION_STATE_BANNER_RECEIVED;
SSH_LOG(SSH_LOG_PACKET, "Received banner: %s", str);
session->ssh_connection_callback(session);
return ret; return ret;
} else {
SSH_LOG(SSH_LOG_DEBUG,
"ssh_protocol_version_exchange: %s",
buffer);
ret = i + 1;
break;
}
}
/* According to RFC 4253 the max banner length is 255 */
if (i > 255) {
/* Too big banner */
session->session_state=SSH_SESSION_STATE_ERROR;
ssh_set_error(session,
SSH_FATAL,
"Receiving banner: too large banner");
return 0;
}
}
return ret;
} }
/** @internal /** @internal
@@ -147,46 +169,75 @@ static int callback_receive_banner(const void *data, size_t len, void *user) {
* *
* @return 0 on success, < 0 on error. * @return 0 on success, < 0 on error.
*/ */
int ssh_send_banner(ssh_session session, int server) { int ssh_send_banner(ssh_session session, int server)
const char *banner = NULL; {
char buffer[128] = {0}; const char *banner = NULL;
int err=SSH_ERROR; const char *terminator = NULL;
/* The maximum banner length is 255 for SSH2 */
char buffer[256] = {0};
size_t len;
int rc = SSH_ERROR;
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2; banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
terminator = session->version == 1 ? "\n" : "\r\n";
if (server) { if (server == 1) {
if(session->opts.custombanner == NULL){ if (session->opts.custombanner == NULL){
session->serverbanner = strdup(banner); len = strlen(banner);
session->serverbanner = strdup(banner);
if (session->serverbanner == NULL) {
goto end;
}
} else {
len = strlen(session->opts.custombanner);
session->serverbanner = malloc(len + 8 + 1);
if(session->serverbanner == NULL) {
goto end;
}
snprintf(session->serverbanner,
len + 8 + 1,
"SSH-2.0-%s",
session->opts.custombanner);
}
snprintf(buffer,
sizeof(buffer),
"%s%s",
session->serverbanner,
terminator);
} else { } else {
session->serverbanner = malloc(strlen(session->opts.custombanner) + 9); session->clientbanner = strdup(banner);
if(!session->serverbanner) if (session->clientbanner == NULL) {
goto end; goto end;
strcpy(session->serverbanner, "SSH-2.0-"); }
strcat(session->serverbanner, session->opts.custombanner);
}
if (session->serverbanner == NULL) {
goto end;
}
snprintf(buffer, 128, "%s\n", session->serverbanner);
} else {
session->clientbanner = strdup(banner);
if (session->clientbanner == NULL) {
goto end;
}
snprintf(buffer, 128, "%s\n", session->clientbanner);
}
if (ssh_socket_write(session->socket, buffer, strlen(buffer)) == SSH_ERROR) { /* SSH version 1 has a banner length of 128 only */
goto end; len = session->version == 1 ? 128 : 0;
}
snprintf(buffer,
sizeof(buffer) - len,
"%s%s",
session->clientbanner,
terminator);
}
rc = ssh_socket_write(session->socket, buffer, strlen(buffer));
if (rc == SSH_ERROR) {
goto end;
}
#ifdef WITH_PCAP #ifdef WITH_PCAP
if(session->pcap_ctx) if (session->pcap_ctx != NULL) {
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,buffer,strlen(buffer),strlen(buffer)); ssh_pcap_context_write(session->pcap_ctx,
SSH_PCAP_DIR_OUT,
buffer,
strlen(buffer),
strlen(buffer));
}
#endif #endif
err=SSH_OK;
end:
return err; rc = SSH_OK;
end:
return rc;
} }
/** @internal /** @internal
@@ -335,7 +386,13 @@ static void ssh_client_connection_callback(ssh_session session){
switch(session->session_state){ switch(session->session_state){
case SSH_SESSION_STATE_NONE: case SSH_SESSION_STATE_NONE:
case SSH_SESSION_STATE_CONNECTING: case SSH_SESSION_STATE_CONNECTING:
break;
case SSH_SESSION_STATE_SOCKET_CONNECTED: case SSH_SESSION_STATE_SOCKET_CONNECTED:
/* If SSHv1 is disabled, we can send the banner immedietly */
if (session->opts.ssh1 == 0) {
ssh_set_fd_towrite(session);
ssh_send_banner(session, 0);
}
break; break;
case SSH_SESSION_STATE_BANNER_RECEIVED: case SSH_SESSION_STATE_BANNER_RECEIVED:
if (session->serverbanner == NULL) { if (session->serverbanner == NULL) {
@@ -381,7 +438,9 @@ static void ssh_client_connection_callback(ssh_session session){
#endif #endif
ssh_packet_set_default_callbacks(session); ssh_packet_set_default_callbacks(session);
session->session_state=SSH_SESSION_STATE_INITIAL_KEX; session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
ssh_send_banner(session, 0); if (session->opts.ssh1 == 1) {
ssh_send_banner(session, 0);
}
set_status(session, 0.5f); set_status(session, 0.5f);
break; break;
case SSH_SESSION_STATE_INITIAL_KEX: case SSH_SESSION_STATE_INITIAL_KEX:

View File

@@ -218,26 +218,32 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
opcode = ssh_config_get_opcode(keyword); opcode = ssh_config_get_opcode(keyword);
switch (opcode) { switch (opcode) {
case SOC_HOST: case SOC_HOST: {
int ok = 0;
*parsing = 0; *parsing = 0;
lowerhost = (session->opts.host) ? ssh_lowercase(session->opts.host) : NULL; lowerhost = (session->opts.host) ? ssh_lowercase(session->opts.host) : NULL;
for (p = ssh_config_get_str_tok(&s, NULL); for (p = ssh_config_get_str_tok(&s, NULL);
p != NULL && p[0] != '\0'; p != NULL && p[0] != '\0';
p = ssh_config_get_str_tok(&s, NULL)) { p = ssh_config_get_str_tok(&s, NULL)) {
char *z = ssh_path_expand_escape(session, p); if (ok >= 0) {
int ok; char *z = ssh_path_expand_escape(session, p);
if (z == NULL) { if (z == NULL) {
z = strdup(p); z = strdup(p);
}
ok = match_hostname(lowerhost, z, strlen(z));
if (ok < 0) {
*parsing = 0;
} else if (ok > 0) {
*parsing = 1;
}
free(z);
} }
ok = match_hostname(lowerhost, z, strlen(z));
if (ok) {
*parsing = 1;
}
free(z);
} }
SAFE_FREE(lowerhost); SAFE_FREE(lowerhost);
break; break;
}
case SOC_HOSTNAME: case SOC_HOSTNAME:
p = ssh_config_get_str_tok(&s, NULL); p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) { if (p && *parsing) {

View File

@@ -227,15 +227,21 @@ void ssh_crypto_finalize(void) {
} }
int dh_generate_x(ssh_session session) { int dh_generate_x(ssh_session session) {
int keysize;
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
keysize = 1023;
} else {
keysize = 2047;
}
session->next_crypto->x = bignum_new(); session->next_crypto->x = bignum_new();
if (session->next_crypto->x == NULL) { if (session->next_crypto->x == NULL) {
return -1; return -1;
} }
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->x, 128); bignum_rand(session->next_crypto->x, keysize);
#elif defined HAVE_LIBCRYPTO #elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->x, 128, 0, -1); bignum_rand(session->next_crypto->x, keysize, -1, 0);
#endif #endif
/* not harder than this */ /* not harder than this */
@@ -248,15 +254,21 @@ int dh_generate_x(ssh_session session) {
/* used by server */ /* used by server */
int dh_generate_y(ssh_session session) { int dh_generate_y(ssh_session session) {
session->next_crypto->y = bignum_new(); int keysize;
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
keysize = 1023;
} else {
keysize = 2047;
}
session->next_crypto->y = bignum_new();
if (session->next_crypto->y == NULL) { if (session->next_crypto->y == NULL) {
return -1; return -1;
} }
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
bignum_rand(session->next_crypto->y, 128); bignum_rand(session->next_crypto->y, keysize);
#elif defined HAVE_LIBCRYPTO #elif defined HAVE_LIBCRYPTO
bignum_rand(session->next_crypto->y, 128, 0, -1); bignum_rand(session->next_crypto->y, keysize, -1, 0);
#endif #endif
/* not harder than this */ /* not harder than this */

View File

@@ -129,11 +129,53 @@ static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
#endif /* WITH_SERVER */ #endif /* WITH_SERVER */
static void ssh_gssapi_log_error(int verb, const char *msg, int maj_stat){ static void ssh_gssapi_log_error(int verb,
gss_buffer_desc buffer; const char *msg,
OM_uint32 dummy, message_context; int maj_stat,
gss_display_status(&dummy,maj_stat,GSS_C_GSS_CODE, GSS_C_NO_OID, &message_context, &buffer); int min_stat)
SSH_LOG(verb, "GSSAPI(%s): %s", msg, (const char *)buffer.value); {
gss_buffer_desc msg_maj = {
.length = 0,
};
gss_buffer_desc msg_min = {
.length = 0,
};
OM_uint32 dummy_maj, dummy_min;
OM_uint32 message_context = 0;
dummy_maj = gss_display_status(&dummy_min,
maj_stat,
GSS_C_GSS_CODE,
GSS_C_NO_OID,
&message_context,
&msg_maj);
if (dummy_maj != 0) {
goto out;
}
dummy_maj = gss_display_status(&dummy_min,
min_stat,
GSS_C_MECH_CODE,
GSS_C_NO_OID,
&message_context,
&msg_min);
if (dummy_maj != 0) {
goto out;
}
SSH_LOG(verb,
"GSSAPI(%s): %s - %s",
msg,
(const char *)msg_maj.value,
(const char *)msg_min.value);
out:
if (msg_maj.value) {
dummy_maj = gss_release_buffer(&dummy_min, &msg_maj);
}
if (msg_min.value) {
dummy_maj = gss_release_buffer(&dummy_min, &msg_min);
}
} }
#ifdef WITH_SERVER #ifdef WITH_SERVER
@@ -212,7 +254,10 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
(gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name); (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
if (maj_stat != GSS_S_COMPLETE) { if (maj_stat != GSS_S_COMPLETE) {
SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat); SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat); ssh_gssapi_log_error(SSH_LOG_WARNING,
"importing name",
maj_stat,
min_stat);
return -1; return -1;
} }
@@ -224,7 +269,10 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
if (maj_stat != GSS_S_COMPLETE) { if (maj_stat != GSS_S_COMPLETE) {
SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat); SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "acquiring creds", maj_stat); ssh_gssapi_log_error(SSH_LOG_WARNING,
"acquiring creds",
maj_stat,
min_stat);
ssh_auth_reply_default(session,0); ssh_auth_reply_default(session,0);
return SSH_ERROR; return SSH_ERROR;
} }
@@ -266,7 +314,10 @@ static char *ssh_gssapi_name_to_char(gss_name_t name){
OM_uint32 maj_stat, min_stat; OM_uint32 maj_stat, min_stat;
char *ptr; char *ptr;
maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); maj_stat = gss_display_name(&min_stat, name, &buffer, NULL);
ssh_gssapi_log_error(SSH_LOG_WARNING, "converting name", maj_stat); ssh_gssapi_log_error(SSH_LOG_WARNING,
"converting name",
maj_stat,
min_stat);
ptr=malloc(buffer.length + 1); ptr=malloc(buffer.length + 1);
memcpy(ptr, buffer.value, buffer.length); memcpy(ptr, buffer.value, buffer.length);
ptr[buffer.length] = '\0'; ptr[buffer.length] = '\0';
@@ -335,14 +386,20 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
maj_stat = gss_accept_sec_context(&min_stat, &session->gssapi->ctx, session->gssapi->server_creds, maj_stat = gss_accept_sec_context(&min_stat, &session->gssapi->ctx, session->gssapi->server_creds,
&input_token, input_bindings, &client_name, NULL /*mech_oid*/, &output_token, &ret_flags, &input_token, input_bindings, &client_name, NULL /*mech_oid*/, &output_token, &ret_flags,
NULL /*time*/, &session->gssapi->client_creds); NULL /*time*/, &session->gssapi->client_creds);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat); ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"accepting token",
maj_stat,
min_stat);
ssh_string_free(token); ssh_string_free(token);
if (client_name != GSS_C_NO_NAME){ if (client_name != GSS_C_NO_NAME){
session->gssapi->client_name = client_name; session->gssapi->client_name = client_name;
session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name); session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name);
} }
if (GSS_ERROR(maj_stat)){ if (GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_WARNING, "Gssapi error", maj_stat); ssh_gssapi_log_error(SSH_LOG_WARNING,
"Gssapi error",
maj_stat,
min_stat);
ssh_auth_reply_default(session,0); ssh_auth_reply_default(session,0);
ssh_gssapi_free(session); ssh_gssapi_free(session);
session->gssapi=NULL; session->gssapi=NULL;
@@ -439,8 +496,10 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic)
mic_token_buf.value = ssh_string_data(mic_token); mic_token_buf.value = ssh_string_data(mic_token);
maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL); maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC", maj_stat); ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC (min stat)", min_stat); "verifying MIC",
maj_stat,
min_stat);
if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat)) { if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat)) {
goto error; goto error;
} }
@@ -653,8 +712,11 @@ int ssh_gssapi_auth_mic(ssh_session session){
&session->gssapi->client.server_name); &session->gssapi->client.server_name);
if (maj_stat != GSS_S_COMPLETE) { if (maj_stat != GSS_S_COMPLETE) {
SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat); SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat); ssh_gssapi_log_error(SSH_LOG_WARNING,
return SSH_PACKET_USED; "importing name",
maj_stat,
min_stat);
return SSH_AUTH_DENIED;
} }
/* copy username */ /* copy username */
@@ -759,7 +821,10 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
0, NULL, &input_token, NULL, 0, NULL, &input_token, NULL,
&output_token, NULL, NULL); &output_token, NULL, NULL);
if(GSS_ERROR(maj_stat)){ if(GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_WARNING, "Initializing gssapi context", maj_stat); ssh_gssapi_log_error(SSH_LOG_WARNING,
"Initializing gssapi context",
maj_stat,
min_stat);
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
if (output_token.length != 0){ if (output_token.length != 0){
@@ -797,7 +862,10 @@ static int ssh_gssapi_send_mic(ssh_session session){
maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT, &mic_buf, &mic_token_buf); maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT, &mic_buf, &mic_token_buf);
if (GSS_ERROR(maj_stat)){ if (GSS_ERROR(maj_stat)){
ssh_buffer_free(mic_buffer); ssh_buffer_free(mic_buffer);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "generating MIC", maj_stat); ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"generating MIC",
maj_stat,
min_stat);
return SSH_ERROR; return SSH_ERROR;
} }
@@ -848,10 +916,16 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
0, NULL, &input_token, NULL, 0, NULL, &input_token, NULL,
&output_token, NULL, NULL); &output_token, NULL, NULL);
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat); ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"accepting token",
maj_stat,
min_stat);
ssh_string_free(token); ssh_string_free(token);
if (GSS_ERROR(maj_stat)){ if (GSS_ERROR(maj_stat)){
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "Gssapi error", maj_stat); ssh_gssapi_log_error(SSH_LOG_PROTOCOL,
"Gssapi error",
maj_stat,
min_stat);
ssh_gssapi_free(session); ssh_gssapi_free(session);
session->gssapi=NULL; session->gssapi=NULL;
return SSH_PACKET_USED; return SSH_PACKET_USED;

View File

@@ -42,24 +42,28 @@
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc," # define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
# define DES "3des-cbc" # define DES "3des-cbc"
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1" # define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
#elif defined(HAVE_LIBCRYPTO) #elif defined(HAVE_LIBCRYPTO)
# ifdef HAVE_OPENSSL_BLOWFISH_H # ifdef HAVE_OPENSSL_BLOWFISH_H
# define BLOWFISH "blowfish-cbc," # define BLOWFISH "blowfish-cbc,"
# else # else /* HAVE_OPENSSL_BLOWFISH_H */
# define BLOWFISH "" # define BLOWFISH ""
# endif # endif /* HAVE_OPENSSL_BLOWFISH_H */
# ifdef HAVE_OPENSSL_AES_H # ifdef HAVE_OPENSSL_AES_H
# ifdef BROKEN_AES_CTR # ifdef BROKEN_AES_CTR
# define AES "aes256-cbc,aes192-cbc,aes128-cbc," # define AES "aes256-cbc,aes192-cbc,aes128-cbc,"
# else # else /* BROKEN_AES_CTR */
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc," # define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
# endif /* BROKEN_AES_CTR */ # endif /* BROKEN_AES_CTR */
# else # else /* HAVE_OPENSSL_AES_H */
# define AES "" # define AES ""
# endif # endif /* HAVE_OPENSSL_AES_H */
# define DES "3des-cbc" # define DES "3des-cbc"
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1" # define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
#endif #endif /* HAVE_LIBCRYPTO */
#ifdef WITH_ZLIB #ifdef WITH_ZLIB
#define ZLIB "none,zlib,zlib@openssh.com" #define ZLIB "none,zlib,zlib@openssh.com"
@@ -90,8 +94,8 @@ static const char *default_methods[] = {
HOSTKEYS, HOSTKEYS,
AES BLOWFISH DES, AES BLOWFISH DES,
AES BLOWFISH DES, AES BLOWFISH DES,
"hmac-sha1,hmac-sha2-256,hmac-sha2-512", "hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha1,hmac-sha2-256,hmac-sha2-512", "hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"none", "none",
"none", "none",
"", "",
@@ -105,8 +109,8 @@ static const char *supported_methods[] = {
HOSTKEYS, HOSTKEYS,
AES BLOWFISH DES_SUPPORTED, AES BLOWFISH DES_SUPPORTED,
AES BLOWFISH DES_SUPPORTED, AES BLOWFISH DES_SUPPORTED,
"hmac-sha1,hmac-sha2-256,hmac-sha2-512", "hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha1,hmac-sha2-256,hmac-sha2-512", "hmac-sha2-256,hmac-sha2-512,hmac-sha1",
ZLIB, ZLIB,
ZLIB, ZLIB,
"", "",

View File

@@ -181,7 +181,7 @@ void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len) {
} }
void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) { void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
size_t len; size_t len = 0;
switch(ctx->mac_type){ switch(ctx->mac_type){
case SSH_MAC_SHA1: case SSH_MAC_SHA1:
len=SHA_DIGEST_LEN; len=SHA_DIGEST_LEN;

View File

@@ -33,9 +33,10 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#ifndef HAVE_CLOCK_GETTIME #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif /* HAVE_CLOCK_GETTIME */ #endif /* HAVE_SYS_TIME_H */
#endif /* _WIN32 */ #endif /* _WIN32 */
#include <limits.h> #include <limits.h>
@@ -289,23 +290,6 @@ int ssh_is_ipaddr(const char *str) {
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifndef HAVE_NTOHLL
uint64_t ntohll(uint64_t a) {
#ifdef WORDS_BIGENDIAN
return a;
#else /* WORDS_BIGENDIAN */
return (((uint64_t)(a) << 56) | \
(((uint64_t)(a) << 40) & 0xff000000000000ULL) | \
(((uint64_t)(a) << 24) & 0xff0000000000ULL) | \
(((uint64_t)(a) << 8) & 0xff00000000ULL) | \
(((uint64_t)(a) >> 8) & 0xff000000ULL) | \
(((uint64_t)(a) >> 24) & 0xff0000ULL) | \
(((uint64_t)(a) >> 40) & 0xff00ULL) | \
((uint64_t)(a) >> 56));
#endif /* WORDS_BIGENDIAN */
}
#endif /* HAVE_NTOHLL */
char *ssh_lowercase(const char* str) { char *ssh_lowercase(const char* str) {
char *new, *p; char *new, *p;

View File

@@ -93,12 +93,6 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
if (src->opts.identity) { if (src->opts.identity) {
struct ssh_iterator *it; struct ssh_iterator *it;
new->opts.identity = ssh_list_new();
if (new->opts.identity == NULL) {
ssh_free(new);
return -1;
}
it = ssh_list_get_iterator(src->opts.identity); it = ssh_list_get_iterator(src->opts.identity);
while (it) { while (it) {
char *id; char *id;
@@ -338,7 +332,7 @@ int ssh_options_set_algo(ssh_session session, int algo,
* - SSH_OPTIONS_HOSTKEYS: * - SSH_OPTIONS_HOSTKEYS:
* Set the preferred server host key types (const char *, * Set the preferred server host key types (const char *,
* comma-separated list). ex: * comma-separated list). ex:
* "ssh-rsa,ssh-dsa,ecdh-sha2-nistp256" * "ssh-rsa,ssh-dss,ecdh-sha2-nistp256"
* *
* - SSH_OPTIONS_COMPRESSION_C_S: * - SSH_OPTIONS_COMPRESSION_C_S:
* Set the compression to use for client to server * Set the compression to use for client to server
@@ -1356,10 +1350,10 @@ static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
* with verbosity less than or equal to the * with verbosity less than or equal to the
* logging verbosity will be shown. * logging verbosity will be shown.
* - SSH_LOG_NOLOG: No logging * - SSH_LOG_NOLOG: No logging
* - SSH_LOG_RARE: Rare conditions or warnings * - SSH_LOG_WARNING: Only warnings
* - SSH_LOG_ENTRY: API-accessible entrypoints * - SSH_LOG_PROTOCOL: High level protocol information
* - SSH_LOG_PACKET: Packet id and size * - SSH_LOG_PACKET: Lower level protocol infomations, packet level
* - SSH_LOG_FUNCTIONS: Function entering and leaving * - SSH_LOG_FUNCTIONS: Every function path
* *
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR: * - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
* Set the session logging verbosity via a * Set the session logging verbosity via a

View File

@@ -271,7 +271,7 @@ int ssh_key_is_public(const ssh_key k) {
return 0; return 0;
} }
return (k->flags & SSH_KEY_FLAG_PUBLIC); return (k->flags & SSH_KEY_FLAG_PUBLIC) == SSH_KEY_FLAG_PUBLIC;
} }
/** /**
@@ -286,7 +286,7 @@ int ssh_key_is_private(const ssh_key k) {
return 0; return 0;
} }
return (k->flags & SSH_KEY_FLAG_PRIVATE); return (k->flags & SSH_KEY_FLAG_PRIVATE) == SSH_KEY_FLAG_PRIVATE;
} }
/** /**
@@ -1094,7 +1094,7 @@ error:
* @param[out] pkey A pointer to store the newly allocated public key. You * @param[out] pkey A pointer to store the newly allocated public key. You
* NEED to free the key. * NEED to free the key.
* *
* @return A public key, NULL on error. * @return SSH_OK on success, SSH_ERROR on error.
* *
* @see ssh_key_free() * @see ssh_key_free()
*/ */
@@ -1584,7 +1584,7 @@ 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;
ssh_signature sig; ssh_signature sig = NULL;
ssh_string sig_blob; ssh_string sig_blob;
int rc; int rc;

View File

@@ -35,8 +35,8 @@ int pki_key_generate_ed25519(ssh_key key)
goto error; goto error;
} }
key->ed25519_pubkey = malloc(sizeof (ed25519_privkey)); key->ed25519_pubkey = malloc(sizeof (ed25519_pubkey));
if (key->ed25519_privkey == NULL) { if (key->ed25519_pubkey == NULL) {
goto error; goto error;
} }

View File

@@ -737,7 +737,7 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
ssh_key pki_key_dup(const ssh_key key, int demote) ssh_key pki_key_dup(const ssh_key key, int demote)
{ {
ssh_key new; ssh_key new;
gcry_sexp_t sexp; gcry_sexp_t sexp = NULL;
gcry_error_t err; gcry_error_t err;
const char *tmp = NULL; const char *tmp = NULL;
size_t size; size_t size;

View File

@@ -116,7 +116,11 @@ static poll_fn ssh_poll_emu;
#else /* _WIN32 */ #else /* _WIN32 */
#include <sys/select.h> #include <sys/select.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h>
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# endif
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H

View File

@@ -746,7 +746,7 @@ int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_por
if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD
&& msg->global_request.bind_port == 0) { && msg->global_request.bind_port == 0) {
rc = ssh_buffer_pack(msg->session->out_buffer, "d", bound_port); rc = ssh_buffer_pack(msg->session->out_buffer, "d", bound_port);
if (rc != SSH_ERROR) { if (rc != SSH_OK) {
ssh_set_error_oom(msg->session); ssh_set_error_oom(msg->session);
goto error; goto error;
} }

View File

@@ -115,6 +115,15 @@ ssh_session ssh_new(void) {
goto err; goto err;
} }
id = strdup("%d/id_ed25519");
if (id == NULL) {
goto err;
}
rc = ssh_list_append(session->opts.identity, id);
if (rc == SSH_ERROR) {
goto err;
}
#ifdef HAVE_ECC #ifdef HAVE_ECC
id = strdup("%d/id_ecdsa"); id = strdup("%d/id_ecdsa");
if (id == NULL) { if (id == NULL) {
@@ -261,6 +270,11 @@ void ssh_free(ssh_session session) {
ssh_list_free(session->opts.identity); ssh_list_free(session->opts.identity);
} }
#ifndef _WIN32
ssh_agent_state_free (session->agent_state);
#endif
session->agent_state = NULL;
SAFE_FREE(session->auth_auto_state); SAFE_FREE(session->auth_auto_state);
SAFE_FREE(session->serverbanner); SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner); SAFE_FREE(session->clientbanner);

View File

@@ -315,7 +315,7 @@ sftp_packet sftp_packet_read(sftp_session sftp) {
sftp_packet packet = NULL; sftp_packet packet = NULL;
uint32_t tmp; uint32_t tmp;
size_t size; size_t size;
int r; int r, s;
packet = malloc(sizeof(struct sftp_packet_struct)); packet = malloc(sizeof(struct sftp_packet_struct));
if (packet == NULL) { if (packet == NULL) {
@@ -330,26 +330,33 @@ sftp_packet sftp_packet_read(sftp_session sftp) {
return NULL; return NULL;
} }
r=ssh_channel_read(sftp->channel, buffer, 4, 0); r=0;
if (r < 0) { do {
ssh_buffer_free(packet->payload); // read from channel until 4 bytes have been read or an error occurs
SAFE_FREE(packet); s=ssh_channel_read(sftp->channel, buffer+r, 4-r, 0);
return NULL; if (s < 0) {
} goto error;
} else if (s == 0) {
int is_eof;
is_eof = ssh_channel_is_eof(sftp->channel);
if (is_eof) {
goto error;
}
} else {
r += s;
}
} while (r<4);
ssh_buffer_add_data(packet->payload, buffer, r); ssh_buffer_add_data(packet->payload, buffer, r);
if (buffer_get_u32(packet->payload, &tmp) != sizeof(uint32_t)) { if (buffer_get_u32(packet->payload, &tmp) != sizeof(uint32_t)) {
ssh_set_error(sftp->session, SSH_FATAL, "Short sftp packet!"); ssh_set_error(sftp->session, SSH_FATAL, "Short sftp packet!");
ssh_buffer_free(packet->payload); goto error;
SAFE_FREE(packet);
return NULL;
} }
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 */
ssh_buffer_free(packet->payload); goto error;
SAFE_FREE(packet);
return NULL;
} }
ssh_buffer_add_data(packet->payload, buffer, r); ssh_buffer_add_data(packet->payload, buffer, r);
buffer_get_u8(packet->payload, &packet->type); buffer_get_u8(packet->payload, &packet->type);
@@ -366,20 +373,20 @@ sftp_packet sftp_packet_read(sftp_session sftp) {
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 */
ssh_buffer_free(packet->payload); goto error;
SAFE_FREE(packet);
return NULL;
} }
if (ssh_buffer_add_data(packet->payload, buffer, r) == SSH_ERROR) { if (ssh_buffer_add_data(packet->payload, buffer, r) == SSH_ERROR) {
ssh_buffer_free(packet->payload);
SAFE_FREE(packet);
ssh_set_error_oom(sftp->session); ssh_set_error_oom(sftp->session);
return NULL; goto error;
} }
size -= r; size -= r;
} }
return packet; return packet;
error:
ssh_buffer_free(packet->payload);
SAFE_FREE(packet);
return NULL;
} }
static void sftp_set_error(sftp_session sftp, int errnum) { static void sftp_set_error(sftp_session sftp, int errnum) {
@@ -3070,7 +3077,10 @@ sftp_attributes sftp_fstat(sftp_file file) {
} }
if (msg->packet_type == SSH_FXP_ATTRS){ if (msg->packet_type == SSH_FXP_ATTRS){
return sftp_parse_attr(file->sftp, msg->payload, 0); sftp_attributes attr = sftp_parse_attr(file->sftp, msg->payload, 0);
sftp_message_free(msg);
return attr;
} else if (msg->packet_type == SSH_FXP_STATUS) { } else if (msg->packet_type == SSH_FXP_STATUS) {
status = parse_status_msg(msg); status = parse_status_msg(msg);
sftp_message_free(msg); sftp_message_free(msg);

View File

@@ -194,9 +194,8 @@ sftp_client_message sftp_get_client_message(sftp_session sftp) {
break; break;
case SSH_FXP_FSTAT: case SSH_FXP_FSTAT:
rc = ssh_buffer_unpack(payload, rc = ssh_buffer_unpack(payload,
"Sd", "S",
&msg->handle, &msg->handle);
&msg->flags);
if (rc != SSH_OK) { if (rc != SSH_OK) {
ssh_set_error_oom(session); ssh_set_error_oom(session);
sftp_client_message_free(msg); sftp_client_message_free(msg);

View File

@@ -27,8 +27,9 @@ set(LIBSSH_THREADS_LINK_LIBRARIES
${LIBSSH_SHARED_LIBRARY} ${LIBSSH_SHARED_LIBRARY}
) )
set(libssh_threads_SRCS message(STATUS "threads library: Threads_FOUND=${Threads_FOUND}")
)
set(libssh_threads_SRCS) # empty SRC
# build and link pthread # build and link pthread
if (CMAKE_USE_PTHREADS_INIT) if (CMAKE_USE_PTHREADS_INIT)
@@ -41,6 +42,8 @@ if (CMAKE_USE_PTHREADS_INIT)
${LIBSSH_THREADS_LINK_LIBRARIES} ${LIBSSH_THREADS_LINK_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
) )
message(STATUS "libssh_threads_SRCS=${libssh_threads_SRCS}")
endif (CMAKE_USE_PTHREADS_INIT) endif (CMAKE_USE_PTHREADS_INIT)
set(LIBSSH_THREADS_LINK_LIBRARIES set(LIBSSH_THREADS_LINK_LIBRARIES
@@ -54,6 +57,8 @@ include_directories(
) )
if (libssh_threads_SRCS) if (libssh_threads_SRCS)
set(LIBSSH_THREADS ON CACHE "libssh threads lib" INTERNAL)
add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${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})

View File

@@ -160,6 +160,10 @@ void crypto_free(struct ssh_crypto_struct *crypto){
#ifdef HAVE_ECDH #ifdef HAVE_ECDH
SAFE_FREE(crypto->ecdh_client_pubkey); SAFE_FREE(crypto->ecdh_client_pubkey);
SAFE_FREE(crypto->ecdh_server_pubkey); SAFE_FREE(crypto->ecdh_server_pubkey);
if(crypto->ecdh_privkey != NULL){
EC_KEY_free(crypto->ecdh_privkey);
crypto->ecdh_privkey = NULL;
}
#endif #endif
if(crypto->session_id != NULL){ if(crypto->session_id != NULL){
memset(crypto->session_id, '\0', crypto->digest_len); memset(crypto->session_id, '\0', crypto->digest_len);

View File

@@ -1,4 +1,4 @@
project(tests C) project(libssh-tests C)
if (BSD OR SOLARIS OR OSX) if (BSD OR SOLARIS OR OSX)
find_package(Argp) find_package(Argp)
@@ -9,9 +9,9 @@ set(TORTURE_LIBRARY torture)
include_directories( include_directories(
${LIBSSH_PUBLIC_INCLUDE_DIRS} ${LIBSSH_PUBLIC_INCLUDE_DIRS}
${CMOCKA_INCLUDE_DIR} ${CMOCKA_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR}
${GCRYPT_INCLUDE_DIRS} ${GCRYPT_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
@@ -22,12 +22,12 @@ set(TORTURE_LINK_LIBRARIES
${LIBSSH_STATIC_LIBRARY} ${LIBSSH_STATIC_LIBRARY}
${LIBSSH_LINK_LIBRARIES}) ${LIBSSH_LINK_LIBRARIES})
if (Threads_FOUND) if (LIBSSH_THREADS)
set(TORTURE_LINK_LIBRARIES set(TORTURE_LINK_LIBRARIES
${TORTURE_LINK_LIBRARIES} ${TORTURE_LINK_LIBRARIES}
${LIBSSH_THREADS_STATIC_LIBRARY} ${LIBSSH_THREADS_STATIC_LIBRARY}
${LIBSSH_THREADS_LINK_LIBRARIES}) ${LIBSSH_THREADS_LINK_LIBRARIES})
endif () endif (LIBSSH_THREADS)
# create test library # create test library
add_library(${TORTURE_LIBRARY} STATIC cmdline.c torture.c) add_library(${TORTURE_LIBRARY} STATIC cmdline.c torture.c)

View File

@@ -45,7 +45,7 @@ int benchmarks_sync_sftp_up (ssh_session session, struct argument_s *args,
float ms=0.0; float ms=0.0;
unsigned long total=0; unsigned long total=0;
sftp_session sftp; sftp_session sftp;
sftp_file file; sftp_file file = NULL;
bytes = args->datasize * 1024 * 1024; bytes = args->datasize * 1024 * 1024;
sftp = sftp_new(session); sftp = sftp_new(session);
@@ -101,7 +101,7 @@ int benchmarks_sync_sftp_down (ssh_session session, struct argument_s *args,
float ms=0.0; float ms=0.0;
unsigned long total=0; unsigned long total=0;
sftp_session sftp; sftp_session sftp;
sftp_file file; sftp_file file = NULL;
int r; int r;
bytes = args->datasize * 1024 * 1024; bytes = args->datasize * 1024 * 1024;
@@ -163,7 +163,7 @@ int benchmarks_async_sftp_down (ssh_session session, struct argument_s *args,
float ms=0.0; float ms=0.0;
unsigned long total=0; unsigned long total=0;
sftp_session sftp; sftp_session sftp;
sftp_file file; sftp_file file = NULL;
int r,i; int r,i;
int warned = 0; int warned = 0;
unsigned long toread; unsigned long toread;

View File

@@ -5,9 +5,9 @@ if (WITH_SERVER AND UNIX AND NOT WIN32)
include_directories( include_directories(
${LIBSSH_PUBLIC_INCLUDE_DIRS} ${LIBSSH_PUBLIC_INCLUDE_DIRS}
${CMOCKA_INCLUDE_DIR} ${CMOCKA_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR}
${GCRYPT_INCLUDE_DIRS} ${GCRYPT_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}

View File

@@ -14,11 +14,13 @@ if (UNIX AND NOT WIN32)
# requires ssh-keygen # requires ssh-keygen
add_cmocka_test(torture_keyfiles torture_keyfiles.c ${TORTURE_LIBRARY}) add_cmocka_test(torture_keyfiles torture_keyfiles.c ${TORTURE_LIBRARY})
add_cmocka_test(torture_pki torture_pki.c ${TORTURE_LIBRARY}) add_cmocka_test(torture_pki torture_pki.c ${TORTURE_LIBRARY})
# requires pthread
add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY})
# requires /dev/null # requires /dev/null
add_cmocka_test(torture_channel torture_channel.c ${TORTURE_LIBRARY}) add_cmocka_test(torture_channel torture_channel.c ${TORTURE_LIBRARY})
if (WITH_SERVER AND Threads_FOUND) # requires pthread
add_cmocka_test(torture_server_x11 torture_server_x11.c ${TORTURE_LIBRARY}) if (LIBSSH_THREADS)
endif (WITH_SERVER AND Threads_FOUND) add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY})
if (WITH_SERVER)
add_cmocka_test(torture_server_x11 torture_server_x11.c ${TORTURE_LIBRARY})
endif (WITH_SERVER)
endif (LIBSSH_THREADS)
endif (UNIX AND NOT WIN32) endif (UNIX AND NOT WIN32)

View File

@@ -212,6 +212,9 @@ static void torture_pki_import_privkey_base64_RSA(void **state) {
type = ssh_key_type(key); type = ssh_key_type(key);
assert_true(type == SSH_KEYTYPE_RSA); assert_true(type == SSH_KEYTYPE_RSA);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
rc = ssh_key_is_public(key); rc = ssh_key_is_public(key);
assert_true(rc == 1); assert_true(rc == 1);
@@ -281,6 +284,9 @@ static void torture_pki_import_privkey_base64_ECDSA(void **state) {
rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key); rc = ssh_pki_import_privkey_base64(key_str, passphrase, NULL, NULL, &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
free(key_str); free(key_str);
ssh_key_free(key); ssh_key_free(key);
} }
@@ -300,6 +306,10 @@ static void torture_pki_import_privkey_base64_passphrase(void **state) {
NULL, NULL,
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key); ssh_key_free(key);
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
@@ -329,6 +339,10 @@ static void torture_pki_import_privkey_base64_passphrase(void **state) {
NULL, NULL,
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key); ssh_key_free(key);
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
@@ -358,6 +372,10 @@ static void torture_pki_import_privkey_base64_passphrase(void **state) {
NULL, NULL,
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key); ssh_key_free(key);
/* test if it returns -1 if passphrase is wrong */ /* test if it returns -1 if passphrase is wrong */
@@ -388,6 +406,9 @@ static void torture_pki_import_privkey_base64_ed25519(void **state){
type = ssh_key_type(key); type = ssh_key_type(key);
assert_true(type == SSH_KEYTYPE_ED25519); assert_true(type == SSH_KEYTYPE_ED25519);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
rc = ssh_key_is_public(key); rc = ssh_key_is_public(key);
assert_true(rc == 1); assert_true(rc == 1);
@@ -411,6 +432,9 @@ static void torture_pki_pki_publickey_from_privatekey_RSA(void **state) {
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
@@ -433,6 +457,9 @@ static void torture_pki_pki_publickey_from_privatekey_DSA(void **state) {
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);
@@ -455,6 +482,9 @@ static void torture_pki_pki_publickey_from_privatekey_ed25519(void **state){
&key); &key);
assert_true(rc == 0); assert_true(rc == 0);
rc = ssh_key_is_private(key);
assert_true(rc == 1);
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK); assert_true(rc == SSH_OK);