Compare commits

...

20 Commits

Author SHA1 Message Date
Aris Adamantiadis
48f0bfc703 security: fix for vulnerability CVE-2014-0017
When accepting a new connection, a forking server based on libssh forks
and the child process handles the request. The RAND_bytes() function of
openssl doesn't reset its state after the fork, but simply adds the
current process id (getpid) to the PRNG state, which is not guaranteed
to be unique.
This can cause several children to end up with same PRNG state which is
a security issue.

Conflicts:
	src/bind.c
2014-03-04 09:54:25 +01:00
Andreas Schneider
87549f7bb6 tests: Add a sftp_read blocking test. 2013-10-23 15:54:12 +02:00
Johannes Krude
d7ab3d7b3d socket: Call data handler as long as handler takes data.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-10-06 17:48:40 +02:00
Andreas Schneider
f17788adc2 Update ChangeLog. 2013-07-26 08:42:26 +02:00
Andreas Schneider
23e0053a41 BUG 103: Disable proxy command if set to 'none'.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2013-07-26 08:42:26 +02:00
Andreas Schneider
b6788f369e client: Fix possible NULL pointer dereference. 2013-07-26 08:42:26 +02:00
Andreas Schneider
4cc4236182 kex: Fix a double free. 2013-07-26 08:42:26 +02:00
milo
21a1c51eef Check for NULL pointers in channels.c 2013-07-26 08:42:26 +02:00
Andreas Schneider
d796de288e cmake: Set application version as package version. 2013-07-26 08:42:26 +02:00
Andreas Schneider
7ba381116d BUG 103: Fix ProxyCommand parsing. 2013-06-02 19:33:57 +02:00
Andreas Schneider
6f59c0534d config: Rename ssh_config_get_str(). 2013-06-02 19:33:57 +02:00
Andreas Schneider
494fb26b01 opts: Fix segfault in option parser. 2013-06-02 19:33:57 +02:00
Andreas Schneider
d0f9320602 cmake: Fix setting -D_FORTIFY_SOURCE=2. 2013-06-02 19:33:56 +02:00
Aris Adamantiadis
5826cb6ab2 poll: return error on poll() when pollset is empty
(cherry picked from commit 222a0d78ca)
2013-02-27 08:07:44 +01:00
Andreas Schneider
bbdef245a1 Update version number to 0.5.5. 2013-02-12 14:30:22 +01:00
Laurent Bigonville
a0d894dd2a server: Fix typo in dh_handshake_server().
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2013-02-05 21:16:04 +01:00
Andreas Schneider
05d8421290 Update to version 0.5.4. 2013-01-22 11:52:36 +01:00
Andreas Schneider
55b09f4264 CVE-2013-0176: Fix a remote DoS if the client doesn't send a matching kex.
Thanks to Yong Chuan Koh, X-Force Research <kohyc@sg.ibm.com>
2013-01-14 14:38:55 +01:00
Andreas Schneider
f128338132 options: Fix a free crash bug if we parse unknown options.
Thanks to Yong Chuan Koh, X-Force Research <kohyc@sg.ibm.com>
2013-01-11 08:52:27 +01:00
Andreas Schneider
ba231d0844 channels1: Fix severa possible null pointer dereferences.
(cherry picked from commit b811b89f57)
2013-01-10 13:55:12 +01:00
21 changed files with 318 additions and 56 deletions

View File

@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
set(APPLICATION_VERSION_MAJOR "0")
set(APPLICATION_VERSION_MINOR "5")
set(APPLICATION_VERSION_PATCH "3")
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.2.3")
set(LIBRARY_VERSION "4.2.5")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked

View File

@@ -11,9 +11,9 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
### versions
set(CPACK_PACKAGE_VERSION_MAJOR "0")
set(CPACK_PACKAGE_VERSION_MINOR "5")
set(CPACK_PACKAGE_VERSION_PATCH "3")
set(CPACK_PACKAGE_VERSION_MAJOR "${APPLICATION_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${APPLICATION_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${APPLICATION_VERSION_PATCH}")
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")

View File

@@ -1,6 +1,18 @@
ChangeLog
==========
version 0.5.5 (released 2013-07-26)
* BUG 103: Fix ProxyCommand parsing.
* Fix setting -D_FORTIFY_SOURCE=2.
* Fix pollset error return if emtpy.
* Fix NULL pointer checks in channel functions.
* Several bugfixes.
version 0.5.4 (released 2013-01-22)
* CVE-2013-0176 - NULL dereference leads to denial of service
* Fixed several NULL pointer dereferences in SSHv1.
* Fixed a free crash bug in options parsing.
version 0.5.3 (released 2012-11-20)
* CVE-2012-4559 Fixed multiple double free() flaws.
* CVE-2012-4560 Fixed multiple buffer overflow flaws.

View File

@@ -25,10 +25,15 @@ if (UNIX AND NOT WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
endif (WITH_STACK_PROTECTOR)
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
if (WITH_FORTIFY_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2")
endif (WITH_FORTIFY_SOURCE)
if (CMAKE_BUILD_TYPE)
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (NOT CMAKE_BUILD_TYPE_LOWER MATCHES debug)
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
if (WITH_FORTIFY_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FORTIFY_SOURCE=2")
endif (WITH_FORTIFY_SOURCE)
endif()
endif()
endif (${CMAKE_C_COMPILER_ID} MATCHES GNU)
#

View File

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

View File

@@ -44,5 +44,6 @@ int crypt_set_algorithms_server(ssh_session session);
struct ssh_crypto_struct *crypto_new(void);
void crypto_free(struct ssh_crypto_struct *crypto);
void ssh_reseed(void);
#endif /* WRAPPER_H_ */

View File

@@ -374,7 +374,8 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
ssh_socket_get_poll_handle_out(session->socket);
session->dsa_key = dsa;
session->rsa_key = rsa;
/* force PRNG to change state in case we fork after ssh_bind_accept */
ssh_reseed();
return SSH_OK;
}

View File

@@ -79,6 +79,10 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet);
ssh_channel ssh_channel_new(ssh_session session) {
ssh_channel channel = NULL;
if(session == NULL) {
return NULL;
}
channel = malloc(sizeof(struct ssh_channel_struct));
if (channel == NULL) {
ssh_set_error_oom(session);
@@ -887,6 +891,10 @@ int channel_default_bufferize(ssh_channel channel, void *data, int len,
* @see channel_request_exec()
*/
int ssh_channel_open_session(ssh_channel channel) {
if(channel == NULL) {
return SSH_ERROR;
}
#ifdef WITH_SSH1
if (channel->session->version == 1) {
return channel_open_session1(channel);
@@ -934,7 +942,6 @@ int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
}
session = channel->session;
enter_function();
if(remotehost == NULL || sourcehost == NULL) {
@@ -1036,9 +1043,14 @@ void ssh_channel_free(ssh_channel channel) {
* @see channel_free()
*/
int ssh_channel_send_eof(ssh_channel channel){
ssh_session session = channel->session;
ssh_session session;
int rc = SSH_ERROR;
if(channel == NULL) {
return rc;
}
session = channel->session;
enter_function();
if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_EOF) < 0) {
@@ -1080,9 +1092,14 @@ error:
* @see channel_eof()
*/
int ssh_channel_close(ssh_channel channel){
ssh_session session = channel->session;
ssh_session session;
int rc = 0;
if(channel == NULL) {
return SSH_ERROR;
}
session = channel->session;
enter_function();
if (channel->local_eof == 0) {
@@ -1143,6 +1160,10 @@ int channel_write_common(ssh_channel channel, const void *data,
return SSH_ERROR;
}
if(channel == NULL || data == NULL) {
return -1;
}
session = channel->session;
enter_function();
if(ssh_is_blocking(session))
timeout = -2;
@@ -2823,11 +2844,17 @@ int ssh_channel_write_stderr(ssh_channel channel, const void *data, uint32_t len
*/
int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport) {
ssh_session session = channel->session;
ssh_session session;
ssh_buffer payload = NULL;
ssh_string str = NULL;
int rc = SSH_ERROR;
if(channel == NULL) {
return rc;
}
session = channel->session;
enter_function();
payload = ssh_buffer_new();
@@ -2891,6 +2918,10 @@ int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) {
ssh_buffer buffer = NULL;
int rc = SSH_ERROR;
if(channel == NULL) {
return SSH_ERROR;
}
#ifdef WITH_SSH1
if (channel->version == 1) {
return SSH_ERROR; // TODO: Add support for SSH-v1 if possible.
@@ -2933,7 +2964,8 @@ error:
* @return SSH_OK on success, SSH_ERROR if an error occured
* (including attempts to send signal via SSH-v1 session).
*/
int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig, int core, const char *errmsg, const char *lang) {
int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
int core, const char *errmsg, const char *lang) {
ssh_buffer buffer = NULL;
ssh_string tmp = NULL;
int rc = SSH_ERROR;

View File

@@ -50,11 +50,17 @@
*/
int channel_open_session1(ssh_channel chan) {
ssh_session session;
if (chan == NULL) {
return -1;
}
session = chan->session;
/*
* We guess we are requesting an *exec* channel. It can only have one exec
* channel. So we abort with an error if we need more than one.
*/
ssh_session session = chan->session;
if (session->exec_channel_opened) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"SSH1 supports only one execution channel. "
@@ -85,8 +91,14 @@ int channel_open_session1(ssh_channel chan) {
int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col,
int row) {
ssh_session session = channel->session;
ssh_session session;
ssh_string str = NULL;
if (channel == NULL) {
return SSH_ERROR;
}
session = channel->session;
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
return SSH_ERROR;
@@ -139,7 +151,13 @@ int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col
}
int channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
ssh_session session = channel->session;
ssh_session session;
if (channel == NULL) {
return SSH_ERROR;
}
session = channel->session;
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
return SSH_ERROR;
@@ -182,7 +200,12 @@ int channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
}
int channel_request_shell1(ssh_channel channel) {
ssh_session session = channel->session;
ssh_session session;
if (channel == NULL) {
return -1;
}
session = channel->session;
if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) {
return -1;
@@ -198,9 +221,14 @@ int channel_request_shell1(ssh_channel channel) {
}
int channel_request_exec1(ssh_channel channel, const char *cmd) {
ssh_session session = channel->session;
ssh_session session;
ssh_string command = NULL;
if (channel == NULL) {
return -1;
}
session = channel->session;
command = ssh_string_from_char(cmd);
if (command == NULL) {
return -1;
@@ -227,6 +255,11 @@ SSH_PACKET_CALLBACK(ssh_packet_data1){
ssh_string str = NULL;
int is_stderr=(type==SSH_SMSG_STDOUT_DATA ? 0 : 1);
(void)user;
if (channel == NULL) {
return SSH_PACKET_NOT_USED;
}
str = buffer_get_ssh_string(packet);
if (str == NULL) {
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n");
@@ -254,6 +287,10 @@ SSH_PACKET_CALLBACK(ssh_packet_close1){
(void)type;
(void)user;
if (channel == NULL) {
return SSH_PACKET_NOT_USED;
}
buffer_get_u32(packet, &status);
/*
* It's much more than a channel closing. spec says it's the last
@@ -275,6 +312,11 @@ SSH_PACKET_CALLBACK(ssh_packet_exist_status1){
uint32_t status;
(void)type;
(void)user;
if (channel == NULL) {
return SSH_PACKET_NOT_USED;
}
buffer_get_u32(packet, &status);
channel->state = SSH_CHANNEL_STATE_CLOSED;
channel->remote_eof = 1;
@@ -285,10 +327,16 @@ SSH_PACKET_CALLBACK(ssh_packet_exist_status1){
int channel_write1(ssh_channel channel, const void *data, int len) {
ssh_session session = channel->session;
ssh_session session;
int origlen = len;
int effectivelen;
const unsigned char *ptr=data;
if (channel == NULL) {
return -1;
}
session = channel->session;
while (len > 0) {
if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) {
return -1;
@@ -314,6 +362,11 @@ int channel_write1(ssh_channel channel, const void *data, int len) {
ssh_channel ssh_get_channel1(ssh_session session){
struct ssh_iterator *it;
if (session == NULL) {
return NULL;
}
/* With SSH1, the channel is always the first one */
if(session->channels != NULL){
it = ssh_list_get_iterator(session->channels);

View File

@@ -765,7 +765,7 @@ void ssh_disconnect(ssh_session session) {
enter_function();
if (ssh_socket_is_open(session->socket)) {
if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
goto error;
}
@@ -790,7 +790,7 @@ void ssh_disconnect(ssh_session session) {
}
error:
session->alive = 0;
if(session->socket){
if (session->socket != NULL){
ssh_socket_reset(session->socket);
}
session->fd = SSH_INVALID_SOCKET;

View File

@@ -78,7 +78,7 @@ static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) {
return SOC_UNSUPPORTED;
}
static char *ssh_config_get_token(char **str) {
static char *ssh_config_get_cmd(char **str) {
register char *c;
char *r;
@@ -98,6 +98,25 @@ static char *ssh_config_get_token(char **str) {
}
}
for (r = c; *c; c++) {
if (*c == '\n') {
*c = '\0';
goto out;
}
}
out:
*str = c + 1;
return r;
}
static char *ssh_config_get_token(char **str) {
register char *c;
char *r;
c = ssh_config_get_cmd(str);
for (r = c; *c; c++) {
if (isblank(*c)) {
*c = '\0';
@@ -127,7 +146,7 @@ static int ssh_config_get_int(char **str, int notfound) {
return notfound;
}
static const char *ssh_config_get_str(char **str, const char *def) {
static const char *ssh_config_get_str_tok(char **str, const char *def) {
char *p;
p = ssh_config_get_token(str);
@@ -141,7 +160,7 @@ static const char *ssh_config_get_str(char **str, const char *def) {
static int ssh_config_get_yesno(char **str, int notfound) {
const char *p;
p = ssh_config_get_str(str, NULL);
p = ssh_config_get_str_tok(str, NULL);
if (p == NULL) {
return notfound;
}
@@ -192,8 +211,8 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
case SOC_HOST:
*parsing = 0;
lowerhost = (session->host) ? ssh_lowercase(session->host) : NULL;
for (p = ssh_config_get_str(&s, NULL); p && *p;
p = ssh_config_get_str(&s, NULL)) {
for (p = ssh_config_get_str_tok(&s, NULL); p && *p;
p = ssh_config_get_str_tok(&s, NULL)) {
if (match_hostname(lowerhost, p, strlen(p))) {
*parsing = 1;
}
@@ -201,14 +220,14 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
SAFE_FREE(lowerhost);
break;
case SOC_HOSTNAME:
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_HOST, p);
}
break;
case SOC_PORT:
if (session->port == 22) {
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_PORT_STR, p);
}
@@ -216,20 +235,20 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
break;
case SOC_USERNAME:
if (session->username == NULL) {
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_USER, p);
}
}
break;
case SOC_IDENTITY:
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_ADD_IDENTITY, p);
}
break;
case SOC_CIPHERS:
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, p);
ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, p);
@@ -246,7 +265,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
}
break;
case SOC_PROTOCOL:
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
char *a, *b;
b = strdup(p);
@@ -289,13 +308,13 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
}
break;
case SOC_KNOWNHOSTS:
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, p);
}
break;
case SOC_PROXYCOMMAND:
p = ssh_config_get_str(&s, NULL);
p = ssh_config_get_cmd(&s);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, p);
}

View File

@@ -432,6 +432,7 @@ int ssh_send_kex(ssh_session session, int server_kex) {
goto error;
}
ssh_string_free(str);
str = NULL;
}
if (buffer_add_u8(session->out_buffer, 0) < 0) {

View File

@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "libssh/priv.h"
#include "libssh/session.h"
@@ -38,6 +39,8 @@
#include <openssl/rsa.h>
#include <openssl/hmac.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
#ifdef HAVE_OPENSSL_AES_H
#define HAS_AES
#include <openssl/aes.h>
@@ -66,6 +69,12 @@ static int alloc_key(struct crypto_struct *cipher) {
return 0;
}
void ssh_reseed(void){
struct timeval tv;
gettimeofday(&tv, NULL);
RAND_add(&tv, sizeof(tv), 0.0);
}
SHACTX sha1_init(void) {
SHACTX c = malloc(sizeof(*c));
if (c == NULL) {

View File

@@ -41,6 +41,9 @@ static int alloc_key(struct crypto_struct *cipher) {
return 0;
}
void ssh_reseed(void){
}
SHACTX sha1_init(void) {
SHACTX ctx = NULL;
gcry_md_open(&ctx, GCRY_MD_SHA1, 0);

View File

@@ -655,11 +655,15 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
return -1;
} else {
SAFE_FREE(session->ProxyCommand);
q = strdup(value);
if (q == NULL) {
return -1;
/* Setting the command to 'none' disables this option. */
rc = strcasecmp(value, "none");
if (rc != 0) {
q = strdup(value);
if (q == NULL) {
return -1;
}
session->ProxyCommand = q;
}
session->ProxyCommand = q;
}
break;
default:
@@ -698,7 +702,7 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
char *cipher = NULL;
char *identity = NULL;
char *port = NULL;
char **save = NULL;
char **save = NULL, **tmp;
int i = 0;
int argc = *argcptr;
int debuglevel = 0;
@@ -720,12 +724,6 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
int saveoptind = optind; /* need to save 'em */
int saveopterr = opterr;
save = malloc(argc * sizeof(char *));
if (save == NULL) {
ssh_set_error_oom(session);
return -1;
}
opterr = 0; /* shut up getopt */
while(cont && ((i = getopt(argc, argv, "c:i:Cl:p:vb:rd12")) != -1)) {
switch(i) {
@@ -765,6 +763,13 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
{
char opt[3]="- ";
opt[1] = optopt;
tmp = realloc(save, (current + 1) * sizeof(char*));
if (tmp == NULL) {
SAFE_FREE(save);
ssh_set_error_oom(session);
return -1;
}
save = tmp;
save[current] = strdup(opt);
if (save[current] == NULL) {
SAFE_FREE(save);
@@ -780,7 +785,16 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
} /* while */
opterr = saveopterr;
while (optind < argc) {
save[current++] = argv[optind++];
tmp = realloc(save, (current + 1) * sizeof(char*));
if (tmp == NULL) {
SAFE_FREE(save);
ssh_set_error_oom(session);
return -1;
}
save = tmp;
save[current] = argv[optind];
current++;
optind++;
}
if (usersa && usedss) {

View File

@@ -581,7 +581,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) {
int revents;
if (!ctx->polls_used)
return 0;
return SSH_ERROR;
rc = ssh_poll(ctx->pollfds, ctx->polls_used, timeout);
if(rc < 0)

View File

@@ -184,7 +184,11 @@ static int dh_handshake_server(ssh_session session) {
prv = session->rsa_key;
break;
default:
prv = NULL;
ssh_set_error(session,
SSH_FATAL,
"Could not determine the specified hostkey");
ssh_string_free(f);
return -1;
}
pub = publickey_from_privatekey(prv);
@@ -270,6 +274,8 @@ static int dh_handshake_server(ssh_session session) {
*/
static void ssh_server_connection_callback(ssh_session session){
int ssh1,ssh2;
int rc;
enter_function();
switch(session->session_state){
case SSH_SESSION_STATE_NONE:
@@ -338,7 +344,10 @@ static void ssh_server_connection_callback(ssh_session session){
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
set_status(session,0.6f);
ssh_list_kex(session, &session->client_kex); // log client kex
crypt_set_algorithms_server(session);
rc = crypt_set_algorithms_server(session);
if (rc == SSH_ERROR) {
goto error;
}
if (set_kex(session) < 0) {
goto error;
}

View File

@@ -280,10 +280,12 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int r
/* Bufferize the data and then call the callback */
buffer_add_data(s->in_buffer,buffer,r);
if(s->callbacks && s->callbacks->data){
r= s->callbacks->data(buffer_get_rest(s->in_buffer),
buffer_get_rest_len(s->in_buffer),
s->callbacks->userdata);
buffer_pass_bytes(s->in_buffer,r);
do {
r= s->callbacks->data(buffer_get_rest(s->in_buffer),
buffer_get_rest_len(s->in_buffer),
s->callbacks->userdata);
buffer_pass_bytes(s->in_buffer,r);
} while (r > 0);
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;

View File

@@ -8,4 +8,5 @@ add_cmockery_test(torture_proxycommand torture_proxycommand.c ${TORTURE_LIBRARY}
if (WITH_SFTP)
add_cmockery_test(torture_sftp_static torture_sftp_static.c ${TORTURE_LIBRARY})
add_cmockery_test(torture_sftp_dir torture_sftp_dir.c ${TORTURE_LIBRARY})
add_cmockery_test(torture_sftp_read torture_sftp_read.c ${TORTURE_LIBRARY})
endif (WITH_SFTP)

View File

@@ -0,0 +1,82 @@
#define LIBSSH_STATIC
#include "torture.h"
#include "sftp.c"
#define MAX_XFER_BUF_SIZE 16384
static void setup(void **state) {
ssh_session session;
struct torture_sftp *t;
const char *host;
const char *user;
const char *password;
host = getenv("TORTURE_HOST");
if (host == NULL) {
host = "localhost";
}
user = getenv("TORTURE_USER");
password = getenv("TORTURE_PASSWORD");
session = torture_ssh_session(host, user, password);
assert_false(session == NULL);
t = torture_sftp_session(session);
assert_false(t == NULL);
*state = t;
}
static void teardown(void **state) {
struct torture_sftp *t = *state;
assert_false(t == NULL);
torture_rmdirs(t->testdir);
torture_sftp_close(t);
}
static void torture_sftp_read_blocking(void **state) {
struct torture_sftp *t = *state;
char libssh_tmp_file[] = "/tmp/libssh_sftp_test_XXXXXX";
char buf[MAX_XFER_BUF_SIZE];
ssize_t bytesread;
ssize_t byteswritten;
int fd;
sftp_file file;
file = sftp_open(t->sftp, "/usr/bin/ssh", O_RDONLY, 0);
fd = mkstemp(libssh_tmp_file);
unlink(libssh_tmp_file);
for (;;) {
bytesread = sftp_read(file, buf, MAX_XFER_BUF_SIZE);
if (bytesread == 0) {
break; /* EOF */
}
assert_false(bytesread < 0);
byteswritten = write(fd, buf, bytesread);
assert_int_equal(byteswritten, bytesread);
}
close(fd);
sftp_close(file);
}
int torture_run_tests(void) {
int rc;
const UnitTest tests[] = {
unit_test_setup_teardown(torture_sftp_read_blocking, setup, teardown)
};
ssh_init();
rc = run_tests(tests);
ssh_finalize();
return rc;
}

View File

@@ -119,6 +119,23 @@ static void torture_options_set_identity(void **state) {
assert_string_equal(session->identity->root->next->data, "identity1");
}
static void torture_options_proxycommand(void **state) {
ssh_session session = *state;
int rc;
/* Enable ProxyCommand */
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "ssh -q -A -X -W %h:%p JUMPHOST");
assert_int_equal(rc, 0);
assert_string_equal(session->ProxyCommand, "ssh -q -A -X -W %h:%p JUMPHOST");
/* Disable ProxyCommand */
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "none");
assert_int_equal(rc, 0);
assert_true(session->ProxyCommand == NULL);
}
int torture_run_tests(void) {
int rc;
const UnitTest tests[] = {
@@ -127,6 +144,7 @@ int torture_run_tests(void) {
unit_test_setup_teardown(torture_options_set_fd, setup, teardown),
unit_test_setup_teardown(torture_options_set_user, setup, teardown),
unit_test_setup_teardown(torture_options_set_identity, setup, teardown),
unit_test_setup_teardown(torture_options_proxycommand, setup, teardown),
};
ssh_init();