Patch from Daniel Stenberg
1 - #include <inttypes.h> and uses uint32_t (this is not very portable and need attention as I mentioned in my separate mail) 2 - changes libssh2_blocking_read() to return ssize_t and all code that uses this function explicitly checks its return code (better). 3 - I fixed a bunch of compiler warnings where functions got called with unsigned char * when they expect char *. I strongly suggest we patch away all warnings - now.
Этот коммит содержится в:
родитель
7058b7fc2a
Коммит
1baaa31792
77
src/packet.c
77
src/packet.c
@ -62,6 +62,8 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||||
*
|
*
|
||||||
* "All implementations MUST be able to process packets with
|
* "All implementations MUST be able to process packets with
|
||||||
@ -71,6 +73,9 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_SSH_PACKET_LEN 35000
|
#define MAX_SSH_PACKET_LEN 35000
|
||||||
|
|
||||||
|
inline int libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, unsigned long datalen);
|
||||||
|
inline int libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data, unsigned long datalen);
|
||||||
|
|
||||||
/* {{{ libssh2_packet_queue_listener
|
/* {{{ libssh2_packet_queue_listener
|
||||||
* Queue a connection request for a listener
|
* Queue a connection request for a listener
|
||||||
*/
|
*/
|
||||||
@ -78,14 +83,14 @@ inline int libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char
|
|||||||
{
|
{
|
||||||
/* Look for a matching listener */
|
/* Look for a matching listener */
|
||||||
unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
|
unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
|
||||||
|
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
||||||
unsigned long packet_len = 17 + (sizeof("Forward not requested") - 1);
|
unsigned long packet_len = 17 + (sizeof("Forward not requested") - 1);
|
||||||
unsigned char *p, packet[17 + (sizeof("Forward not requested") - 1)];
|
unsigned char *p, packet[17 + (sizeof("Forward not requested") - 1)];
|
||||||
/* packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
|
||||||
LIBSSH2_LISTENER *l = session->listeners;
|
LIBSSH2_LISTENER *l = session->listeners;
|
||||||
char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
|
char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
|
||||||
unsigned long sender_channel, initial_window_size, packet_size;
|
uint32_t sender_channel, initial_window_size, packet_size;
|
||||||
unsigned char *host, *shost;
|
unsigned char *host, *shost;
|
||||||
unsigned long port, sport, host_len, shost_len;
|
uint32_t port, sport, host_len, shost_len;
|
||||||
|
|
||||||
sender_channel = libssh2_ntohu32(s); s += 4;
|
sender_channel = libssh2_ntohu32(s); s += 4;
|
||||||
|
|
||||||
@ -292,8 +297,11 @@ inline int libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data
|
|||||||
channel->next = NULL;
|
channel->next = NULL;
|
||||||
session->channels.tail = channel;
|
session->channels.tail = channel;
|
||||||
|
|
||||||
/* Pass control to the callback, they may turn right around and free the channel, or actually use it */
|
/*
|
||||||
LIBSSH2_X11_OPEN(channel, shost, sport);
|
* Pass control to the callback, they may turn right around and
|
||||||
|
* free the channel, or actually use it
|
||||||
|
*/
|
||||||
|
LIBSSH2_X11_OPEN(channel, (char *)shost, sport);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -330,7 +338,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
#endif
|
#endif
|
||||||
if (macstate == LIBSSH2_MAC_INVALID) {
|
if (macstate == LIBSSH2_MAC_INVALID) {
|
||||||
if (session->macerror) {
|
if (session->macerror) {
|
||||||
if (LIBSSH2_MACERROR(session, data, datalen) == 0) {
|
if (LIBSSH2_MACERROR(session, (char *)data, datalen) == 0) {
|
||||||
/* Calling app has given the OK, Process it anyway */
|
/* Calling app has given the OK, Process it anyway */
|
||||||
macstate = LIBSSH2_MAC_CONFIRMED;
|
macstate = LIBSSH2_MAC_CONFIRMED;
|
||||||
} else {
|
} else {
|
||||||
@ -358,7 +366,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
|
|
||||||
reason = libssh2_ntohu32(data + 1);
|
reason = libssh2_ntohu32(data + 1);
|
||||||
message_len = libssh2_ntohu32(data + 5);
|
message_len = libssh2_ntohu32(data + 5);
|
||||||
message = data + 9; /* packet_type(1) + reason(4) + message_len(4) */
|
message = (char *)data + 9; /* packet_type(1) + reason(4) + message_len(4) */
|
||||||
language_len = libssh2_ntohu32(data + 9 + message_len);
|
language_len = libssh2_ntohu32(data + 9 + message_len);
|
||||||
/* This is where we hack on the data a little,
|
/* This is where we hack on the data a little,
|
||||||
* Use the MSB of language_len to to a terminating NULL (In all liklihood it is already)
|
* Use the MSB of language_len to to a terminating NULL (In all liklihood it is already)
|
||||||
@ -367,7 +375,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
* With the lengths passed this isn't *REALLY* necessary, but it's "kind"
|
* With the lengths passed this isn't *REALLY* necessary, but it's "kind"
|
||||||
*/
|
*/
|
||||||
message[message_len] = '\0';
|
message[message_len] = '\0';
|
||||||
language = data + 9 + message_len + 3;
|
language = (char *)data + 9 + message_len + 3;
|
||||||
if (language_len) {
|
if (language_len) {
|
||||||
memcpy(language, language + 1, language_len);
|
memcpy(language, language + 1, language_len);
|
||||||
}
|
}
|
||||||
@ -389,9 +397,9 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
memcpy(data + 4, data + 5, datalen - 5);
|
memcpy(data + 4, data + 5, datalen - 5);
|
||||||
data[datalen] = '\0';
|
data[datalen] = '\0';
|
||||||
if (session->ssh_msg_ignore) {
|
if (session->ssh_msg_ignore) {
|
||||||
LIBSSH2_IGNORE(session, data + 4, datalen - 5);
|
LIBSSH2_IGNORE(session, (char *)data + 4, datalen - 5);
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, (char *)data);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case SSH_MSG_DEBUG:
|
case SSH_MSG_DEBUG:
|
||||||
@ -401,7 +409,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
int message_len, language_len;
|
int message_len, language_len;
|
||||||
|
|
||||||
message_len = libssh2_ntohu32(data + 2);
|
message_len = libssh2_ntohu32(data + 2);
|
||||||
message = data + 6; /* packet_type(1) + display(1) + message_len(4) */
|
message = (char *)data + 6; /* packet_type(1) + display(1) + message_len(4) */
|
||||||
language_len = libssh2_ntohu32(data + 6 + message_len);
|
language_len = libssh2_ntohu32(data + 6 + message_len);
|
||||||
/* This is where we hack on the data a little,
|
/* This is where we hack on the data a little,
|
||||||
* Use the MSB of language_len to to a terminating NULL (In all liklihood it is already)
|
* Use the MSB of language_len to to a terminating NULL (In all liklihood it is already)
|
||||||
@ -410,7 +418,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
* With the lengths passed this isn't *REALLY* necessary, but it's "kind"
|
* With the lengths passed this isn't *REALLY* necessary, but it's "kind"
|
||||||
*/
|
*/
|
||||||
message[message_len] = '\0';
|
message[message_len] = '\0';
|
||||||
language = data + 6 + message_len + 3;
|
language = (char *)data + 6 + message_len + 3;
|
||||||
if (language_len) {
|
if (language_len) {
|
||||||
memcpy(language, language + 1, language_len);
|
memcpy(language, language + 1, language_len);
|
||||||
}
|
}
|
||||||
@ -621,7 +629,7 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
|
|||||||
/* {{{ libssh2_blocking_read
|
/* {{{ libssh2_blocking_read
|
||||||
* Force a blocking read, regardless of socket settings
|
* Force a blocking read, regardless of socket settings
|
||||||
*/
|
*/
|
||||||
static int libssh2_blocking_read(LIBSSH2_SESSION *session, unsigned char *buf, size_t count)
|
static ssize_t libssh2_blocking_read(LIBSSH2_SESSION *session, unsigned char *buf, size_t count)
|
||||||
{
|
{
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
#if !defined(HAVE_POLL) && !defined(HAVE_SELECT)
|
#if !defined(HAVE_POLL) && !defined(HAVE_SELECT)
|
||||||
@ -738,12 +746,13 @@ int libssh2_packet_read(LIBSSH2_SESSION *session, int should_block)
|
|||||||
* The largest blocksize (currently) is 32, the largest MAC (currently) is 20
|
* The largest blocksize (currently) is 32, the largest MAC (currently) is 20
|
||||||
*/
|
*/
|
||||||
unsigned char block[2 * 32], *payload, *s, tmp[6];
|
unsigned char block[2 * 32], *payload, *s, tmp[6];
|
||||||
long read_len;
|
ssize_t read_len;
|
||||||
unsigned long blocksize = session->remote.crypt->blocksize;
|
unsigned long blocksize = session->remote.crypt->blocksize;
|
||||||
unsigned long packet_len, payload_len;
|
unsigned long packet_len, payload_len;
|
||||||
int padding_len;
|
int padding_len;
|
||||||
int macstate;
|
int macstate;
|
||||||
int free_payload = 1;
|
int free_payload = 1;
|
||||||
|
|
||||||
/* Safely ignored in CUSTOM cipher mode */
|
/* Safely ignored in CUSTOM cipher mode */
|
||||||
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)session->remote.crypt_abstract;
|
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)session->remote.crypt_abstract;
|
||||||
|
|
||||||
@ -752,12 +761,19 @@ int libssh2_packet_read(LIBSSH2_SESSION *session, int should_block)
|
|||||||
*/
|
*/
|
||||||
if (should_block) {
|
if (should_block) {
|
||||||
read_len = libssh2_blocking_read(session, block, blocksize);
|
read_len = libssh2_blocking_read(session, block, blocksize);
|
||||||
|
if(read_len <= 0)
|
||||||
|
return read_len;
|
||||||
} else {
|
} else {
|
||||||
|
ssize_t nread;
|
||||||
read_len = recv(session->socket_fd, block, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
|
read_len = recv(session->socket_fd, block, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||||
if (read_len <= 0) {
|
if (read_len <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
read_len += libssh2_blocking_read(session, block + read_len, blocksize - read_len);
|
nread = libssh2_blocking_read(session, block + read_len, blocksize - read_len);
|
||||||
|
if(nread <= 0)
|
||||||
|
return nread;
|
||||||
|
|
||||||
|
read_len += nread;
|
||||||
}
|
}
|
||||||
if (read_len < blocksize) {
|
if (read_len < blocksize) {
|
||||||
return (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) ? 0 : -1;
|
return (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) ? 0 : -1;
|
||||||
@ -836,7 +852,7 @@ int libssh2_packet_read(LIBSSH2_SESSION *session, int should_block)
|
|||||||
/* Calculate MAC hash */
|
/* Calculate MAC hash */
|
||||||
session->remote.mac->hash(session, block + session->remote.mac->mac_len, session->remote.seqno, tmp, 5, payload, payload_len, &session->remote.mac_abstract);
|
session->remote.mac->hash(session, block + session->remote.mac->mac_len, session->remote.seqno, tmp, 5, payload, payload_len, &session->remote.mac_abstract);
|
||||||
|
|
||||||
macstate = (strncmp(block, block + session->remote.mac->mac_len, session->remote.mac->mac_len) == 0) ? LIBSSH2_MAC_CONFIRMED : LIBSSH2_MAC_INVALID;
|
macstate = (strncmp((char *)block, (char *)block + session->remote.mac->mac_len, session->remote.mac->mac_len) == 0) ? LIBSSH2_MAC_CONFIRMED : LIBSSH2_MAC_INVALID;
|
||||||
|
|
||||||
session->remote.seqno++;
|
session->remote.seqno++;
|
||||||
|
|
||||||
@ -889,18 +905,24 @@ int libssh2_packet_read(LIBSSH2_SESSION *session, int should_block)
|
|||||||
} else { /* No cipher active */
|
} else { /* No cipher active */
|
||||||
unsigned char *payload;
|
unsigned char *payload;
|
||||||
unsigned char buf[24];
|
unsigned char buf[24];
|
||||||
unsigned long buf_len, payload_len;
|
ssize_t buf_len;
|
||||||
unsigned long packet_length;
|
unsigned long payload_len;
|
||||||
|
uint32_t packet_length;
|
||||||
unsigned long padding_length;
|
unsigned long padding_length;
|
||||||
|
|
||||||
if (should_block) {
|
if (should_block) {
|
||||||
buf_len = libssh2_blocking_read(session, buf, 5);
|
buf_len = libssh2_blocking_read(session, buf, 5);
|
||||||
} else {
|
} else {
|
||||||
|
ssize_t nread;
|
||||||
buf_len = recv(session->socket_fd, buf, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
|
buf_len = recv(session->socket_fd, buf, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||||
if (buf_len <= 0) {
|
if (buf_len <= 0) {
|
||||||
return 0;
|
return buf_len;
|
||||||
}
|
}
|
||||||
buf_len += libssh2_blocking_read(session, buf, 5 - buf_len);
|
nread = libssh2_blocking_read(session, buf, 5 - buf_len);
|
||||||
|
if(nread <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buf_len += nread;
|
||||||
}
|
}
|
||||||
if (buf_len < 5) {
|
if (buf_len < 5) {
|
||||||
/* Something bad happened */
|
/* Something bad happened */
|
||||||
@ -1002,10 +1024,15 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
|
|||||||
/* {{{ libssh2_packet_askv
|
/* {{{ libssh2_packet_askv
|
||||||
* Scan for any of a list of packet types in the brigade, optionally poll the socket for a packet first
|
* Scan for any of a list of packet types in the brigade, optionally poll the socket for a packet first
|
||||||
*/
|
*/
|
||||||
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, unsigned char *packet_types, unsigned char **data, unsigned long *data_len,
|
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
|
||||||
unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket)
|
unsigned char *packet_types,
|
||||||
|
unsigned char **data,
|
||||||
|
unsigned long *data_len,
|
||||||
|
unsigned long match_ofs,
|
||||||
|
const unsigned char *match_buf,
|
||||||
|
unsigned long match_len, int poll_socket)
|
||||||
{
|
{
|
||||||
int i, packet_types_len = strlen(packet_types);
|
int i, packet_types_len = strlen((char *)packet_types);
|
||||||
|
|
||||||
for(i = 0; i < packet_types_len; i++) {
|
for(i = 0; i < packet_types_len; i++) {
|
||||||
if (0 == libssh2_packet_ask_ex(session, packet_types[i], data, data_len, match_ofs, match_buf, match_len, i ? 0 : poll_socket)) {
|
if (0 == libssh2_packet_ask_ex(session, packet_types[i], data, data_len, match_ofs, match_buf, match_len, i ? 0 : poll_socket)) {
|
||||||
@ -1058,7 +1085,7 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session)
|
|||||||
{
|
{
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
unsigned long data_len;
|
unsigned long data_len;
|
||||||
char all_packets[255];
|
unsigned char all_packets[255];
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < 256; i++) all_packets[i - 1] = i;
|
for(i = 1; i < 256; i++) all_packets[i - 1] = i;
|
||||||
|
|
||||||
@ -1114,7 +1141,7 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, unsigned char *packet_t
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(packet_types, ret)) {
|
if (strchr((char *)packet_types, ret)) {
|
||||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||||
return libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0);
|
return libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0);
|
||||||
}
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user