mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 20:30:38 +09:00
Compare commits
29 Commits
libssh-0.6
...
libssh-0.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e99408dba | ||
|
|
6b49863bb0 | ||
|
|
e9d16bd343 | ||
|
|
94f6955fba | ||
|
|
d2a990a68e | ||
|
|
584ab49b7b | ||
|
|
dc30183d8a | ||
|
|
396f5e2110 | ||
|
|
6b18f0b4b0 | ||
|
|
8f2eee6509 | ||
|
|
4bd704295c | ||
|
|
be2f5399dd | ||
|
|
a672b3e7bb | ||
|
|
ddc3f987a7 | ||
|
|
e9ad0c3c69 | ||
|
|
2ccab05cba | ||
|
|
58348fcc57 | ||
|
|
0579b7d8b2 | ||
|
|
915d28ffa5 | ||
|
|
884bff5bdc | ||
|
|
08c33d6aeb | ||
|
|
fa4740bdf5 | ||
|
|
da91ca43c0 | ||
|
|
4de6a708ad | ||
|
|
fd3b1f63a1 | ||
|
|
914f8abde8 | ||
|
|
3880a8ed80 | ||
|
|
0e969e0316 | ||
|
|
a45dd8e000 |
@@ -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
|
||||
|
||||
12
ChangeLog
12
ChangeLog
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ set(libssh_HDRS
|
||||
libssh.h
|
||||
ssh2.h
|
||||
legacy.h
|
||||
libsshpp.hpp
|
||||
)
|
||||
|
||||
if (WITH_SFTP)
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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, \
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
src/dh.c
11
src/dh.c
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
62
src/sftp.c
62
src/sftp.c
@@ -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);
|
||||
|
||||
27
src/socket.c
27
src/socket.c
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user