Compare commits

...

29 Commits

Author SHA1 Message Date
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
29 changed files with 204 additions and 92 deletions

View File

@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "6")
set(APPLICATION_VERSION_PATCH "4")
set(APPLICATION_VERSION_PATCH "5")
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
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.5.0")
set(LIBRARY_VERSION "4.5.1")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked

View File

@@ -1,6 +1,18 @@
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.

View File

@@ -99,11 +99,6 @@ check_function_exists(isblank HAVE_ISBLANK)
check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
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)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
@@ -114,17 +109,28 @@ if (WIN32)
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
set(HAVE_GETADDRINFO TRUE)
set(HAVE_GETHOSTBYNAME TRUE)
if (MSVC)
set(HAVE_NTOHLL TRUE)
set(HAVE_HTONLL TRUE)
endif (MSVC)
check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL)
check_symbol_exists(htonll winsock2.h HAVE_HTONLL)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
check_symbol_exists(select "winsock2.h;ws2tcpip.h" HAVE_SELECT)
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)
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)
if (UNIX)
if (NOT LINUX)
# libsocket (Solaris)
@@ -201,6 +207,20 @@ int main(void)
return 0;
}" 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)
set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO)

View File

@@ -139,6 +139,9 @@
#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 */
#cmakedefine WITH_GSSAPI 1

View File

@@ -5,6 +5,7 @@ set(libssh_HDRS
libssh.h
ssh2.h
legacy.h
libsshpp.hpp
)
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 generate_session_keys(ssh_session session);
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);
#endif /* DH_H_ */

View File

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

View File

@@ -29,7 +29,7 @@
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
#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,
const char *format, ...) PRINTF_ATTRIBUTE(2, 3);

View File

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

View File

@@ -1907,7 +1907,7 @@ int ssh_userauth_kbdint(ssh_session session, const char *user,
* This should not happen
*/
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;
}

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

View File

@@ -101,7 +101,8 @@ int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col
}
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");
return SSH_ERROR;
}

View File

@@ -526,7 +526,7 @@ int ssh_connect(ssh_session session) {
} else {
ret=ssh_socket_connect(session->socket,
session->opts.host,
session->opts.port,
session->opts.port > 0 ? session->opts.port : 22,
session->opts.bindaddr);
}
if (ret == SSH_ERROR) {

View File

@@ -245,7 +245,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
}
break;
case SOC_PORT:
if (session->opts.port == 22) {
if (session->opts.port == 0) {
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_PORT_STR, p);

View File

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

View File

@@ -407,14 +407,17 @@ bignum make_string_bn(ssh_string string){
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);
#ifdef HAVE_LIBGCRYPT
#error "unsupported"
#elif defined HAVE_LIBCRYPTO
bignum_bin2bn(string->data, len, bnout);
#endif
}
#endif /* HAVE_LIBCRYPTO */
ssh_string dh_get_e(ssh_session session) {
return make_bignum_string(session->next_crypto->e);

View File

@@ -435,7 +435,7 @@ int ssh_is_server_known(ssh_session session) {
return SSH_SERVER_ERROR;
}
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) {
ssh_set_error_oom(session);
SAFE_FREE(host);
@@ -542,7 +542,7 @@ int ssh_write_knownhost(ssh_session session) {
host = ssh_lowercase(session->opts.host);
/* 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);
SAFE_FREE(host);
if (hostport == NULL) {
@@ -682,7 +682,7 @@ char **ssh_knownhosts_algorithms(ssh_session session) {
}
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);
if (host == NULL || hostport == NULL || array == NULL) {

View File

@@ -871,11 +871,14 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
if (session == NULL) {
return -1;
}
if (!session->opts.port) {
ssh_set_error_invalid(session);
return -1;
if (session->opts.port == 0) {
*port_target = 22;
return 0;
}
*port_target = session->opts.port;
return 0;
}

View File

@@ -94,7 +94,7 @@ SSH_PACKET_CALLBACK(ssh_packet_dh_reply){
(void)type;
(void)user;
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){
ssh_set_error(session,SSH_FATAL,"ssh_packet_dh_reply called in wrong state : %d:%d",
session->session_state,session->dh_handshake_state);
@@ -135,12 +135,16 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
(void)user;
(void)type;
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){
ssh_set_error(session,SSH_FATAL,"ssh_packet_newkeys called in wrong state : %d:%d",
session->session_state,session->dh_handshake_state);
goto error;
if (session->session_state != SSH_SESSION_STATE_DH ||
session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) {
ssh_set_error(session,
SSH_FATAL,
"ssh_packet_newkeys called in wrong state : %d:%d",
session->session_state,session->dh_handshake_state);
goto error;
}
if(session->server){
/* server things are done in server.c */
session->dh_handshake_state=DH_STATE_FINISHED;

View File

@@ -1365,7 +1365,7 @@ ssh_string ssh_pki_do_sign(ssh_session session,
struct ssh_crypto_struct *crypto =
session->current_crypto ? session->current_crypto :
session->next_crypto;
ssh_signature sig;
ssh_signature sig = NULL;
ssh_string sig_blob;
ssh_string session_id;
int rc;

View File

@@ -597,11 +597,17 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) {
ssh_poll_handle p;
socket_t fd;
int revents;
struct ssh_timestamp ts;
if (!ctx->polls_used)
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)
return SSH_ERROR;
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){
int rc;
int rc = SSH_ERROR;
(void)type;
(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");
rc = SSH_ERROR;
}
if (rc == SSH_ERROR)
error:
if (rc == SSH_ERROR) {
session->session_state = SSH_SESSION_STATE_ERROR;
error:
}
return SSH_PACKET_USED;
}

View File

@@ -100,7 +100,7 @@ ssh_session ssh_new(void) {
/* OPTIONS */
session->opts.StrictHostKeyChecking = 1;
session->opts.port = 22;
session->opts.port = 0;
session->opts.fd = -1;
session->opts.ssh2 = 1;
session->opts.compressionlevel=7;

View File

@@ -126,6 +126,7 @@ sftp_session sftp_new(ssh_session session){
sftp->session = session;
sftp->channel = ssh_channel_new(session);
if (sftp->channel == NULL) {
sftp_ext_free(sftp->ext);
SAFE_FREE(sftp);
return NULL;
@@ -133,6 +134,7 @@ sftp_session sftp_new(ssh_session session){
if (ssh_channel_open_session(sftp->channel)) {
ssh_channel_free(sftp->channel);
sftp_ext_free(sftp->ext);
SAFE_FREE(sftp);
return NULL;
@@ -340,7 +342,6 @@ sftp_packet sftp_packet_read(sftp_session sftp) {
return NULL;
}
size = ntohl(size);
r=ssh_channel_read(sftp->channel, buffer, 1, 0);
if (r <= 0) {
/* 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_get_u8(packet->payload, &packet->type);
size=size-1;
size = ntohl(size);
if (size == 0) {
return packet;
}
size--;
while (size>0){
r=ssh_channel_read(sftp->channel,buffer,
sizeof(buffer)>size ? size:sizeof(buffer),0);
@@ -445,6 +451,7 @@ static sftp_message sftp_get_message(sftp_packet packet) {
sftp_message_free(msg);
return NULL;
}
msg->id = ntohl(msg->id);
SSH_LOG(SSH_LOG_PACKET,
"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);
if (buffer_add_u32(payload, id) < 0 ||
if (buffer_add_u32(payload, htonl(id)) < 0 ||
buffer_add_ssh_string(payload, path_s) < 0) {
ssh_set_error_oom(sftp->session);
ssh_buffer_free(payload);
@@ -1433,7 +1440,7 @@ sftp_attributes sftp_readdir(sftp_session sftp, sftp_dir dir) {
}
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) {
ssh_set_error_oom(sftp->session);
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);
if (buffer_add_u32(buffer, id) < 0 ||
if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, handle) < 0) {
ssh_set_error_oom(sftp->session);
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;
SSH_LOG(SSH_LOG_PACKET,"Opening file %s with sftp flags %x",file,sftp_flags);
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) {
ssh_set_error_oom(sftp->session);
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_status_message status;
ssh_string datastring;
size_t datalen;
ssh_buffer buffer;
int id;
@@ -1762,7 +1770,7 @@ ssize_t sftp_read(sftp_file handle, void *buf, size_t count) {
return -1;
}
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_u64(buffer, htonll(handle->offset)) < 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;
}
if (ssh_string_len(datastring) > count) {
datalen = ssh_string_len(datastring);
if (datalen > count) {
ssh_set_error(sftp->session, SSH_FATAL,
"Received a too big DATA packet from sftp server: "
"%" PRIdS " and asked for %" PRIdS,
ssh_string_len(datastring), count);
datalen, count);
ssh_string_free(datastring);
return -1;
}
count = ssh_string_len(datastring);
handle->offset += count;
memcpy(buf, ssh_string_data(datastring), count);
handle->offset += (uint64_t)datalen;
memcpy(buf, ssh_string_data(datastring), datalen);
ssh_string_free(datastring);
return count;
return datalen;
default:
ssh_set_error(sftp->session, SSH_FATAL,
"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);
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_u64(buffer, htonll(file->offset)) < 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);
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_u64(buffer, htonll(file->offset)) < 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);
if (buffer_add_u32(buffer, id) < 0 ||
if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, filename) < 0) {
ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer);
@@ -2178,7 +2186,7 @@ int sftp_rmdir(sftp_session sftp, const char *directory) {
}
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) {
ssh_set_error_oom(sftp->session);
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;
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_attributes(buffer, &attr) < 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);
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, newpath) < 0 ||
/* 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);
if (buffer_add_u32(buffer, id) < 0 ||
if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, path) < 0 ||
buffer_add_attributes(buffer, attr) < 0) {
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);
if (buffer_add_u32(buffer, id) < 0) {
if (buffer_add_u32(buffer, htonl(id)) < 0) {
ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer);
ssh_string_free(dest_s);
@@ -2682,7 +2690,7 @@ char *sftp_readlink(sftp_session sftp, const char *path) {
}
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) {
ssh_set_error_oom(sftp->session);
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);
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, pathstr) < 0) {
ssh_set_error_oom(sftp->session);
@@ -2948,7 +2956,7 @@ sftp_statvfs_t sftp_fstatvfs(sftp_file file) {
}
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, file->handle) < 0) {
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);
if (buffer_add_u32(buffer, id) < 0 ||
if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, pathstr) < 0) {
ssh_set_error_oom(sftp->session);
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);
if (buffer_add_u32(buffer, id) < 0 ||
if (buffer_add_u32(buffer, htonl(id)) < 0 ||
buffer_add_ssh_string(buffer, pathstr) < 0) {
ssh_set_error_oom(sftp->session);
ssh_buffer_free(buffer);
@@ -3182,7 +3190,7 @@ sftp_attributes sftp_fstat(sftp_file file) {
}
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) {
ssh_set_error_oom(file->sftp->session);
ssh_buffer_free(buffer);

View File

@@ -630,10 +630,15 @@ int ssh_socket_nonblocking_flush(ssh_socket s) {
if (!ssh_socket_is_open(s)) {
session->alive = 0;
/* FIXME use ssh_socket_get_errno */
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;
}
@@ -650,12 +655,16 @@ int ssh_socket_nonblocking_flush(ssh_socket s) {
if (w < 0) {
session->alive = 0;
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;
}
buffer_pass_bytes(s->out_buffer, w);

View File

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

View File

@@ -25,7 +25,9 @@
#include <libssh/libssh.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define HOST "localhost"
/* Should work until Apnic decides to assign it :) */
#define BLACKHOLE "1.1.1.1"
@@ -128,7 +130,7 @@ static void torture_connect_socket(void **state) {
server_addr.sin_port = htons(22);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
rc = connect(sock_fd, &server_addr, sizeof(server_addr));
rc = connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
assert_true(rc == 0);
ssh_options_set(session, SSH_OPTIONS_FD, &sock_fd);

View File

@@ -39,6 +39,12 @@
#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. */
struct argument_s {
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) {
char h[256];
char *d;
char *user;
char *home;
(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");
assert_non_null(d);
assert_string_equal(d, h);
free(d);
d = ssh_path_expand_tilde("/guru/meditation");
assert_non_null(d);
assert_string_equal(d, "/guru/meditation");
free(d);
snprintf(h, 256 - 1, "~%s/.ssh", getenv("USER"));
snprintf(h, 256 - 1, "~%s/.ssh", user);
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);
free(d);
}
@@ -146,6 +158,7 @@ static void torture_path_expand_escape(void **state) {
session->opts.username = strdup("root");
e = ssh_path_expand_escape(session, s);
assert_non_null(e);
assert_string_equal(e, "guru/meditation/by/root");
free(e);
}
@@ -157,6 +170,7 @@ static void torture_path_expand_known_hosts(void **state) {
session->opts.sshdir = strdup("/home/guru/.ssh");
tmp = ssh_path_expand_escape(session, "%d/known_hosts");
assert_non_null(tmp);
assert_string_equal(tmp, "/home/guru/.ssh/known_hosts");
free(tmp);
}