Compare commits

...

11 Commits

Author SHA1 Message Date
Andreas Schneider
0588cbf9d4 Bump version to 0.7.5
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2017-04-13 16:33:04 +02:00
Andreas Schneider
a7cce77550 buffer: Validate the length before before memory allocation
Check if the size the other party sent is a valid size in the
transmitted buffer.

Thanks to Alex Gaynor for finding and reporting the issue.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 68b7ca6e92)
2017-04-13 16:28:18 +02:00
Andreas Schneider
5e63b40cde buffer: Create ssh_buffer_validate_length()
This functions allows if a given length can be obtained from the buffer.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c165c396de)
2017-04-13 16:27:33 +02:00
Alex Hermann
7b8b5eb4ea config: Only use first occurence of each parameter
ssh_config's manpage says:
"For each parameter, the first obtained value will be used."

Make libssh adhere to this rule.

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

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 5f202d7ffa)
2017-04-13 16:10:10 +02:00
Alex Hermann
8dc3d883b8 config: Don't expand Host variable
Tokens are not allowed (according to the manpage).
Expansion was introduced by a wrong fix for #127.

This commit reverts part of 6eea08a9ef

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c3a8b5009f)
2017-04-13 16:10:09 +02:00
Alex Hermann
24a3f7020c config: Support expansion in the HostName variable
BUG: https://red.libssh.org/issues/127

The original "fix" for 127 was expanding the wrong variable: Host instead
of HostName.

Signed-off-by: Alex Hermann <alex@hexla.nl>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 9ef7e90821)
2017-04-13 16:10:07 +02:00
Yanis Kurganov
f74d5d5df4 session: Add SSH1 support in ssh_send_debug()
Signed-off-by: Yanis Kurganov <ykurganov@ptsecurity.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 38cb19268a)
2017-04-11 17:40:58 +02:00
Yanis Kurganov
7a21187fb9 session: Add SSH1 support in ssh_send_ignore()
Signed-off-by: Yanis Kurganov <ykurganov@ptsecurity.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 72fdb4867e)
2017-04-11 17:40:57 +02:00
Max Bachmann
439d3039e3 messages: Utilize the message queue for SSH_REQUEST_GLOBAL.
Signed-off-by: Max Bachmann <mabahltm@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3ec8babfaf)
2017-04-11 09:55:46 +02:00
Andreas Schneider
61cbf160a0 cmake: Fix GCRYPT_ROOT_DIR and check correct paths
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 462c7726c3)
2017-04-11 09:55:05 +02:00
Andreas Schneider
ce029c0735 pki: Use byte mode for fopen()
BUG: https://red.libssh.org/issues/251

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit de369b46b1)
2017-02-03 13:19:24 +01:00
10 changed files with 110 additions and 30 deletions

View File

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

View File

@@ -1,5 +1,12 @@
ChangeLog
==========
version 0.7.5 (released 2017-04-13)
* Fixed a memory allocation issue with buffers
* Fixed PKI on Windows
* Fixed some SSHv1 functions
* Fixed config hostname expansion
version 0.7.4 (released 2017-02-03)
* Added id_ed25519 to the default identity list
* Fixed sftp EOF packet handling

View File

@@ -35,6 +35,8 @@ find_path(GCRYPT_INCLUDE_DIR
gcrypt.h
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
include
)
find_library(GCRYPT_LIBRARY
@@ -44,6 +46,8 @@ find_library(GCRYPT_LIBRARY
libgcrypt-11
HINTS
${_GCRYPT_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES
lib
)
set(GCRYPT_LIBRARIES ${GCRYPT_LIBRARY})

View File

@@ -53,6 +53,8 @@ int buffer_add_u32(ssh_buffer buffer, uint32_t data);
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len);
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format,
int argc,

View File

@@ -79,7 +79,7 @@
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 7
#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

@@ -563,12 +563,15 @@ uint32_t buffer_pass_bytes_end(struct ssh_buffer_struct *buffer, uint32_t len){
* @returns 0 if there is not enough data in buffer, len otherwise.
*/
uint32_t buffer_get_data(struct ssh_buffer_struct *buffer, void *data, uint32_t len){
int rc;
/*
* Check for a integer overflow first, then check if not enough data is in
* the buffer.
*/
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
return 0;
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
return 0;
}
memcpy(data,buffer->data+buffer->pos,len);
buffer->pos+=len;
@@ -617,6 +620,24 @@ int buffer_get_u64(struct ssh_buffer_struct *buffer, uint64_t *data){
return buffer_get_data(buffer,data,sizeof(uint64_t));
}
/**
* @brief Valdiates that the given length can be obtained from the buffer.
*
* @param[in] buffer The buffer to read from.
*
* @param[in] len The length to be checked.
*
* @return SSH_OK if the length is valid, SSH_ERROR otherwise.
*/
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len)
{
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
return SSH_ERROR;
}
return SSH_OK;
}
/**
* @internal
*
@@ -630,13 +651,15 @@ struct ssh_string_struct *buffer_get_ssh_string(struct ssh_buffer_struct *buffer
uint32_t stringlen;
uint32_t hostlen;
struct ssh_string_struct *str = NULL;
int rc;
if (buffer_get_u32(buffer, &stringlen) == 0) {
return NULL;
}
hostlen = ntohl(stringlen);
/* verify if there is enough space in buffer to get it */
if (buffer->pos + hostlen < hostlen || buffer->pos + hostlen > buffer->used) {
rc = ssh_buffer_validate_length(buffer, hostlen);
if (rc != SSH_OK) {
return NULL; /* it is indeed */
}
str = ssh_string_new(hostlen);
@@ -867,11 +890,13 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
char **cstring;
void **data;
} o;
size_t len, rlen;
size_t len, rlen, max_len;
uint32_t u32len;
va_list ap_copy;
int count;
max_len = ssh_buffer_get_len(buffer);
/* copy the argument list in case a rollback is needed */
va_copy(ap_copy, ap);
@@ -921,10 +946,16 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
break;
}
len = ntohl(u32len);
if (len > UINT_MAX - 1){
if (len > max_len - 1) {
rc = SSH_ERROR;
break;
}
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
break;
}
*o.cstring = malloc(len + 1);
if (*o.cstring == NULL){
rc = SSH_ERROR;
@@ -942,6 +973,15 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
break;
case 'P':
len = va_arg(ap, size_t);
if (len > max_len - 1) {
rc = SSH_ERROR;
break;
}
rc = ssh_buffer_validate_length(buffer, len);
if (rc != SSH_OK) {
break;
}
o.data = va_arg(ap, void **);
count++;

View File

@@ -50,6 +50,8 @@ enum ssh_config_opcode_e {
SOC_GSSAPISERVERIDENTITY,
SOC_GSSAPICLIENTIDENTITY,
SOC_GSSAPIDELEGATECREDENTIALS,
SOC_END /* Keep this one last in the list */
};
struct ssh_config_keyword_table_s {
@@ -185,7 +187,7 @@ static int ssh_config_get_yesno(char **str, int notfound) {
}
static int ssh_config_parse_line(ssh_session session, const char *line,
unsigned int count, int *parsing) {
unsigned int count, int *parsing, int seen[]) {
enum ssh_config_opcode_e opcode;
const char *p;
char *s, *x;
@@ -216,6 +218,12 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
}
opcode = ssh_config_get_opcode(keyword);
if (*parsing == 1 && opcode != SOC_HOST) {
if (seen[opcode] == 0) {
return 0;
}
seen[opcode] = 1;
}
switch (opcode) {
case SOC_HOST: {
@@ -227,18 +235,12 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
p != NULL && p[0] != '\0';
p = ssh_config_get_str_tok(&s, NULL)) {
if (ok >= 0) {
char *z = ssh_path_expand_escape(session, p);
if (z == NULL) {
z = strdup(p);
}
ok = match_hostname(lowerhost, z, strlen(z));
ok = match_hostname(lowerhost, p, strlen(p));
if (ok < 0) {
*parsing = 0;
} else if (ok > 0) {
*parsing = 1;
}
free(z);
}
}
SAFE_FREE(lowerhost);
@@ -247,7 +249,12 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
case SOC_HOSTNAME:
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
ssh_options_set(session, SSH_OPTIONS_HOST, p);
char *z = ssh_path_expand_escape(session, p);
if (z == NULL) {
z = strdup(p);
}
ssh_options_set(session, SSH_OPTIONS_HOST, z);
free(z);
}
break;
case SOC_PORT:
@@ -384,6 +391,7 @@ int ssh_config_parse_file(ssh_session session, const char *filename) {
unsigned int count = 0;
FILE *f;
int parsing;
int seen[SOC_END - SOC_UNSUPPORTED] = {0};
if ((f = fopen(filename, "r")) == NULL) {
return 0;
@@ -394,7 +402,7 @@ int ssh_config_parse_file(ssh_session session, const char *filename) {
parsing = 1;
while (fgets(line, sizeof(line), f)) {
count++;
if (ssh_config_parse_line(session, line, count, &parsing) < 0) {
if (ssh_config_parse_line(session, line, count, &parsing, seen) < 0) {
fclose(f);
return -1;
}

View File

@@ -1355,7 +1355,8 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){
msg->global_request.bind_port);
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
} else {
ssh_message_reply_default(msg);
ssh_message_queue(session, msg);
return rc;
}
} else if (strcmp(request, "cancel-tcpip-forward") == 0) {
r = ssh_buffer_unpack(packet, "sd",
@@ -1374,7 +1375,8 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){
if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) {
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
} else {
ssh_message_reply_default(msg);
ssh_message_queue(session, msg);
return rc;
}
} else {
SSH_LOG(SSH_LOG_PROTOCOL, "UNKNOWN SSH_MSG_GLOBAL_REQUEST %s %d", request, want_reply);

View File

@@ -955,7 +955,7 @@ int ssh_pki_import_pubkey_file(const char *filename, ssh_key *pkey)
return SSH_ERROR;
}
file = fopen(filename, "r");
file = fopen(filename, "rb");
if (file == NULL) {
ssh_pki_log("Error opening %s: %s",
filename, strerror(errno));
@@ -1233,7 +1233,7 @@ int ssh_pki_export_pubkey_file(const ssh_key key,
return SSH_ERROR;
}
fp = fopen(filename, "w+");
fp = fopen(filename, "wb+");
if (fp == NULL) {
return SSH_ERROR;
}

View File

@@ -31,6 +31,9 @@
#include "libssh/crypto.h"
#include "libssh/server.h"
#include "libssh/socket.h"
#ifdef WITH_SSH1
#include "libssh/ssh1.h"
#endif /* WITH_SSH1 */
#include "libssh/ssh2.h"
#include "libssh/agent.h"
#include "libssh/packet.h"
@@ -830,13 +833,17 @@ void ssh_socket_exception_callback(int code, int errno_code, void *user){
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
int ssh_send_ignore (ssh_session session, const char *data) {
#ifdef WITH_SSH1
const int type = session->version == 1 ? SSH_MSG_IGNORE : SSH2_MSG_IGNORE;
#else /* WITH_SSH1 */
const int type = SSH2_MSG_IGNORE;
#endif /* WITH_SSH1 */
int rc;
if (ssh_socket_is_open(session->socket)) {
rc = ssh_buffer_pack(session->out_buffer,
"bs",
SSH2_MSG_IGNORE,
type,
data);
if (rc != SSH_OK){
ssh_set_error_oom(session);
@@ -868,12 +875,22 @@ int ssh_send_debug (ssh_session session, const char *message, int always_display
int rc;
if (ssh_socket_is_open(session->socket)) {
rc = ssh_buffer_pack(session->out_buffer,
"bbsd",
SSH2_MSG_DEBUG,
always_display != 0 ? 1 : 0,
message,
0); /* empty language tag */
#ifdef WITH_SSH1
if (session->version == 1) {
rc = ssh_buffer_pack(session->out_buffer,
"bs",
SSH_MSG_DEBUG,
message);
} else
#endif /* WITH_SSH1 */
{
rc = ssh_buffer_pack(session->out_buffer,
"bbsd",
SSH2_MSG_DEBUG,
always_display != 0 ? 1 : 0,
message,
0); /* empty language tag */
}
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;