packet.c   packet.c 
skipping to change at line 24 skipping to change at line 24
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILI TY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILI TY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details. * License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to * along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA. * MA 02111-1307, USA.
*/ */
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#ifndef _WIN32 #ifndef _WIN32
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
#include "config.h"
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/ssh2.h" #include "libssh/ssh2.h"
#include "libssh/ssh1.h" #include "libssh/ssh1.h"
#include "libssh/crypto.h" #include "libssh/crypto.h"
#include "libssh/buffer.h"
#include "libssh/packet.h"
#include "libssh/socket.h"
#include "libssh/channels.h"
#include "libssh/session.h"
#include "libssh/messages.h"
#include "libssh/pcap.h"
/* XXX include selected mac size */ /* XXX include selected mac size */
static int macsize=SHA_DIGEST_LEN; static int macsize=SHA_DIGEST_LEN;
/* in nonblocking mode, socket_read will read as much as it can, and return */ /* in nonblocking mode, socket_read will read as much as it can, and return */
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */ /* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
/* in blocking mode, it will read at least len bytes and will block until i t's ok. */ /* in blocking mode, it will read at least len bytes and will block until i t's ok. */
#define PACKET_STATE_INIT 0 #define PACKET_STATE_INIT 0
#define PACKET_STATE_SIZEREAD 1 #define PACKET_STATE_SIZEREAD 1
static int packet_read2(SSH_SESSION *session) { static int packet_read2(ssh_session session) {
unsigned int blocksize = (session->current_crypto ? unsigned int blocksize = (session->current_crypto ?
session->current_crypto->in_cipher->blocksize : 8); session->current_crypto->in_cipher->blocksize : 8);
int current_macsize = session->current_crypto ? macsize : 0; int current_macsize = session->current_crypto ? macsize : 0;
unsigned char mac[30] = {0}; unsigned char mac[30] = {0};
char buffer[16] = {0}; char buffer[16] = {0};
void *packet=NULL; void *packet=NULL;
int to_be_read; int to_be_read;
int rc = SSH_ERROR; int rc = SSH_ERROR;
u32 len; uint32_t len;
u8 padding; uint8_t padding;
enter_function(); enter_function();
if (session->alive == 0) { if (session->alive == 0) {
/* The error message was already set into this session */ /* The error message was already set into this session */
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
switch(session->packet_state) { switch(session->packet_state) {
skipping to change at line 105 skipping to change at line 112
if (buffer_add_data(session->in_buffer, buffer, blocksize) < 0) { if (buffer_add_data(session->in_buffer, buffer, blocksize) < 0) {
goto error; goto error;
} }
if(len > MAX_PACKET_LEN) { if(len > MAX_PACKET_LEN) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"read_packet(): Packet len too high(%u %.4x)", len, len); "read_packet(): Packet len too high(%u %.4x)", len, len);
goto error; goto error;
} }
to_be_read = len - blocksize + sizeof(u32); to_be_read = len - blocksize + sizeof(uint32_t);
if (to_be_read < 0) { if (to_be_read < 0) {
/* remote sshd sends invalid sizes? */ /* remote sshd sends invalid sizes? */
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"given numbers of bytes left to be read < 0 (%d)!", to_be_read) ; "given numbers of bytes left to be read < 0 (%d)!", to_be_read) ;
goto error; goto error;
} }
/* saves the status of the current operations */ /* saves the status of the current operations */
session->in_packet.len = len; session->in_packet.len = len;
session->packet_state = PACKET_STATE_SIZEREAD; session->packet_state = PACKET_STATE_SIZEREAD;
case PACKET_STATE_SIZEREAD: case PACKET_STATE_SIZEREAD:
len = session->in_packet.len; len = session->in_packet.len;
to_be_read = len - blocksize + sizeof(u32) + current_macsize; to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize;
/* if to_be_read is zero, the whole packet was blocksize bytes. */ /* if to_be_read is zero, the whole packet was blocksize bytes. */
if (to_be_read != 0) { if (to_be_read != 0) {
rc = ssh_socket_wait_for_data(session->socket,session,to_be_read); rc = ssh_socket_wait_for_data(session->socket,session,to_be_read);
if (rc != SSH_OK) { if (rc != SSH_OK) {
goto error; goto error;
} }
rc = SSH_ERROR; rc = SSH_ERROR;
packet = malloc(to_be_read); packet = malloc(to_be_read);
if (packet == NULL) { if (packet == NULL) {
skipping to change at line 150 skipping to change at line 157
} }
SAFE_FREE(packet); SAFE_FREE(packet);
} }
if (session->current_crypto) { if (session->current_crypto) {
/* /*
* decrypt the rest of the packet (blocksize bytes already * decrypt the rest of the packet (blocksize bytes already
* have been decrypted) * have been decrypted)
*/ */
if (packet_decrypt(session, if (packet_decrypt(session,
buffer_get(session->in_buffer) + blocksize, ((uint8_t*)buffer_get(session->in_buffer) + blocksize),
buffer_get_len(session->in_buffer) - blocksize) < 0) { buffer_get_len(session->in_buffer) - blocksize) < 0) {
ssh_set_error(session, SSH_FATAL, "Decrypt error"); ssh_set_error(session, SSH_FATAL, "Decrypt error");
goto error; goto error;
} }
#ifdef WITH_PCAP
if(session->pcap_ctx){
ssh_pcap_context_write(session->pcap_ctx,
SSH_PCAP_DIR_IN, buffer_get(session->in_buff
er),
buffer_get_len(session->in_buffer),
buffer_get_len(session->in_buffer));
}
#endif
ssh_socket_read(session->socket, mac, macsize); ssh_socket_read(session->socket, mac, macsize);
if (packet_hmac_verify(session, session->in_buffer, mac) < 0) { if (packet_hmac_verify(session, session->in_buffer, mac) < 0) {
ssh_set_error(session, SSH_FATAL, "HMAC error"); ssh_set_error(session, SSH_FATAL, "HMAC error");
goto error; goto error;
} }
} }
#ifdef WITH_PCAP
else {
/* No crypto */
if(session->pcap_ctx){
ssh_pcap_context_write(session->pcap_ctx,
SSH_PCAP_DIR_IN, buffer_get(session->in_buff
er),
buffer_get_len(session->in_buffer),
buffer_get_len(session->in_buffer));
}
}
#endif
buffer_pass_bytes(session->in_buffer, sizeof(u32)); buffer_pass_bytes(session->in_buffer, sizeof(uint32_t));
/* pass the size which has been processed before */ /* pass the size which has been processed before */
if (buffer_get_u8(session->in_buffer, &padding) == 0) { if (buffer_get_u8(session->in_buffer, &padding) == 0) {
ssh_set_error(session, SSH_FATAL, "Packet too short to read padding "); ssh_set_error(session, SSH_FATAL, "Packet too short to read padding ");
goto error; goto error;
} }
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PACKET,
"%hhd bytes padding, %d bytes left in buffer", "%hhd bytes padding, %d bytes left in buffer",
padding, buffer_get_rest_len(session->in_buffer)); padding, buffer_get_rest_len(session->in_buffer));
if (padding > buffer_get_rest_len(session->in_buffer)) { if (padding > buffer_get_rest_len(session->in_buffer)) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Invalid padding: %d (%d resting)", "Invalid padding: %d (%d resting)",
padding, padding,
buffer_get_rest_len(session->in_buffer)); buffer_get_rest_len(session->in_buffer));
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("incrimined packet", ssh_print_hexa("incrimined packet",
buffer_get(session->in_buffer), buffer_get(session->in_buffer),
buffer_get_len(session->in_buffer)); buffer_get_len(session->in_buffer));
#endif #endif
goto error; goto error;
} }
buffer_pass_bytes_end(session->in_buffer, padding); buffer_pass_bytes_end(session->in_buffer, padding);
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PACKET,
"After padding, %d bytes left in buffer", "After padding, %d bytes left in buffer",
buffer_get_rest_len(session->in_buffer)); buffer_get_rest_len(session->in_buffer));
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ) #if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
if (session->current_crypto && session->current_crypto->do_compress_i n) { if (session->current_crypto && session->current_crypto->do_compress_i n) {
ssh_log(session, SSH_LOG_RARE, "Decompressing in_buffer ..."); ssh_log(session, SSH_LOG_PACKET, "Decompressing in_buffer ...");
if (decompress_buffer(session, session->in_buffer) < 0) { if (decompress_buffer(session, session->in_buffer, MAX_PACKET_LEN)
< 0) {
goto error; goto error;
} }
} }
#endif #endif
session->recv_seq++; session->recv_seq++;
session->packet_state = PACKET_STATE_INIT; session->packet_state = PACKET_STATE_INIT;
leave_function(); leave_function();
return SSH_OK; return SSH_OK;
} }
skipping to change at line 218 skipping to change at line 244
"Invalid state into packet_read2(): %d", "Invalid state into packet_read2(): %d",
session->packet_state); session->packet_state);
error: error:
leave_function(); leave_function();
return rc; return rc;
} }
#ifdef WITH_SSH1 #ifdef WITH_SSH1
/* a slighty modified packet_read2() for SSH-1 protocol */ /* a slighty modified packet_read2() for SSH-1 protocol */
static int packet_read1(SSH_SESSION *session) { static int packet_read1(ssh_session session) {
void *packet = NULL; void *packet = NULL;
int rc = SSH_ERROR; int rc = SSH_ERROR;
int to_be_read; int to_be_read;
u32 padding; uint32_t padding;
u32 crc; uint32_t crc;
u32 len; uint32_t len;
enter_function(); enter_function();
if(!session->alive) { if(!session->alive) {
goto error; goto error;
} }
switch (session->packet_state){ switch (session->packet_state){
case PACKET_STATE_INIT: case PACKET_STATE_INIT:
memset(&session->in_packet, 0, sizeof(PACKET)); memset(&session->in_packet, 0, sizeof(PACKET));
skipping to change at line 247 skipping to change at line 273
if (buffer_reinit(session->in_buffer) < 0) { if (buffer_reinit(session->in_buffer) < 0) {
goto error; goto error;
} }
} else { } else {
session->in_buffer = buffer_new(); session->in_buffer = buffer_new();
if (session->in_buffer == NULL) { if (session->in_buffer == NULL) {
goto error; goto error;
} }
} }
rc = ssh_socket_read(session->socket, &len, sizeof(u32)); rc = ssh_socket_read(session->socket, &len, sizeof(uint32_t));
if (rc != SSH_OK) { if (rc != SSH_OK) {
goto error; goto error;
} }
rc = SSH_ERROR; rc = SSH_ERROR;
/* len is not encrypted */ /* len is not encrypted */
len = ntohl(len); len = ntohl(len);
if (len > MAX_PACKET_LEN) { if (len > MAX_PACKET_LEN) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
skipping to change at line 314 skipping to change at line 340
ssh_set_error(session, SSH_FATAL, "Packet decrypt error"); ssh_set_error(session, SSH_FATAL, "Packet decrypt error");
goto error; goto error;
} }
} }
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("read packet decrypted:", buffer_get(session->in_buffe r), ssh_print_hexa("read packet decrypted:", buffer_get(session->in_buffe r),
buffer_get_len(session->in_buffer)); buffer_get_len(session->in_buffer));
#endif #endif
ssh_log(session, SSH_LOG_PACKET, "%d bytes padding", padding); ssh_log(session, SSH_LOG_PACKET, "%d bytes padding", padding);
if(((len + padding) != buffer_get_rest_len(session->in_buffer)) || if(((len + padding) != buffer_get_rest_len(session->in_buffer)) ||
((len + padding) < sizeof(u32))) { ((len + padding) < sizeof(uint32_t))) {
ssh_log(session, SSH_LOG_RARE, "no crc32 in packet"); ssh_log(session, SSH_LOG_RARE, "no crc32 in packet");
ssh_set_error(session, SSH_FATAL, "no crc32 in packet"); ssh_set_error(session, SSH_FATAL, "no crc32 in packet");
goto error; goto error;
} }
memcpy(&crc, memcpy(&crc,
buffer_get_rest(session->in_buffer) + (len+padding) - sizeof(u32) (unsigned char *)buffer_get_rest(session->in_buffer) + (len+paddi
, ng) - sizeof(uint32_t),
sizeof(u32)); sizeof(uint32_t));
buffer_pass_bytes_end(session->in_buffer, sizeof(u32)); buffer_pass_bytes_end(session->in_buffer, sizeof(uint32_t));
crc = ntohl(crc); crc = ntohl(crc);
if (ssh_crc32(buffer_get_rest(session->in_buffer), if (ssh_crc32(buffer_get_rest(session->in_buffer),
(len + padding) - sizeof(u32)) != crc) { (len + padding) - sizeof(uint32_t)) != crc) {
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("crc32 on",buffer_get_rest(session->in_buffer), ssh_print_hexa("crc32 on",buffer_get_rest(session->in_buffer),
len + padding - sizeof(u32)); len + padding - sizeof(uint32_t));
#endif #endif
ssh_log(session, SSH_LOG_RARE, "Invalid crc32"); ssh_log(session, SSH_LOG_RARE, "Invalid crc32");
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Invalid crc32: expected %.8x, got %.8x", "Invalid crc32: expected %.8x, got %.8x",
crc, crc,
ssh_crc32(buffer_get_rest(session->in_buffer), ssh_crc32(buffer_get_rest(session->in_buffer),
len + padding - sizeof(u32))); len + padding - sizeof(uint32_t)));
goto error; goto error;
} }
/* pass the padding */ /* pass the padding */
buffer_pass_bytes(session->in_buffer, padding); buffer_pass_bytes(session->in_buffer, padding);
ssh_log(session, SSH_LOG_PACKET, "The packet is valid"); ssh_log(session, SSH_LOG_PACKET, "The packet is valid");
/* TODO FIXME /* TODO FIXME
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ) #if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
if(session->current_crypto && session->current_crypto->do_compress_in){ if(session->current_crypto && session->current_crypto->do_compress_in){
decompress_buffer(session,session->in_buffer); decompress_buffer(session,session->in_buffer);
skipping to change at line 368 skipping to change at line 394
"Invalid state into packet_read1(): %d", "Invalid state into packet_read1(): %d",
session->packet_state); session->packet_state);
error: error:
leave_function(); leave_function();
return rc; return rc;
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
/* that's where i'd like C to be object ... */ /* that's where i'd like C to be object ... */
int packet_read(SSH_SESSION *session) { int packet_read(ssh_session session) {
#ifdef WITH_SSH1 #ifdef WITH_SSH1
if (session->version == 1) { if (session->version == 1) {
return packet_read1(session); return packet_read1(session);
} }
#endif #endif
return packet_read2(session); return packet_read2(session);
} }
int packet_translate(SSH_SESSION *session) { int packet_translate(ssh_session session) {
enter_function(); enter_function();
memset(&session->in_packet, 0, sizeof(PACKET)); memset(&session->in_packet, 0, sizeof(PACKET));
if(session->in_buffer == NULL) { if(session->in_buffer == NULL) {
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
ssh_log(session, SSH_LOG_RARE, "Final size %d", ssh_log(session, SSH_LOG_PACKET, "Final size %d",
buffer_get_rest_len(session->in_buffer)); buffer_get_rest_len(session->in_buffer));
if(buffer_get_u8(session->in_buffer, &session->in_packet.type) == 0) { if(buffer_get_u8(session->in_buffer, &session->in_packet.type) == 0) {
ssh_set_error(session, SSH_FATAL, "Packet too short to read type"); ssh_set_error(session, SSH_FATAL, "Packet too short to read type");
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
ssh_log(session, SSH_LOG_RARE, "Type %hhd", session->in_packet.type); ssh_log(session, SSH_LOG_PACKET, "Type %hhd", session->in_packet.type);
session->in_packet.valid = 1; session->in_packet.valid = 1;
leave_function(); leave_function();
return SSH_OK; return SSH_OK;
} }
/* /*
* Write the the bufferized output. If the session is blocking, or * Write the the bufferized output. If the session is blocking, or
* enforce_blocking is set, the call may block. Otherwise, it won't block. * enforce_blocking is set, the call may block. Otherwise, it won't block.
* Return SSH_OK if everything has been sent, SSH_AGAIN if there are still * Return SSH_OK if everything has been sent, SSH_AGAIN if there are still
* things to send on buffer, SSH_ERROR if there is an error. * things to send on buffer, SSH_ERROR if there is an error.
*/ */
int packet_flush(SSH_SESSION *session, int enforce_blocking) { int packet_flush(ssh_session session, int enforce_blocking) {
if (enforce_blocking || session->blocking) { if (enforce_blocking || session->blocking) {
return ssh_socket_blocking_flush(session->socket); return ssh_socket_blocking_flush(session->socket);
} }
return ssh_socket_nonblocking_flush(session->socket); return ssh_socket_nonblocking_flush(session->socket);
} }
/* /*
* This function places the outgoing packet buffer into an outgoing * This function places the outgoing packet buffer into an outgoing
* socket buffer * socket buffer
*/ */
static int packet_write(SSH_SESSION *session) { static int packet_write(ssh_session session) {
int rc = SSH_ERROR; int rc = SSH_ERROR;
enter_function(); enter_function();
ssh_socket_write(session->socket, ssh_socket_write(session->socket,
buffer_get(session->out_buffer), buffer_get(session->out_buffer),
buffer_get_len(session->out_buffer)); buffer_get_len(session->out_buffer));
rc = packet_flush(session, 0); rc = packet_flush(session, 0);
leave_function(); leave_function();
return rc; return rc;
} }
static int packet_send2(SSH_SESSION *session) { static int packet_send2(ssh_session session) {
unsigned int blocksize = (session->current_crypto ? unsigned int blocksize = (session->current_crypto ?
session->current_crypto->out_cipher->blocksize : 8); session->current_crypto->out_cipher->blocksize : 8);
u32 currentlen = buffer_get_len(session->out_buffer); uint32_t currentlen = buffer_get_len(session->out_buffer);
unsigned char *hmac = NULL; unsigned char *hmac = NULL;
char padstring[32] = {0}; char padstring[32] = {0};
int rc = SSH_ERROR; int rc = SSH_ERROR;
u32 finallen; uint32_t finallen;
u8 padding; uint8_t padding;
enter_function(); enter_function();
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PACKET,
"Writing on the wire a packet having %u bytes before", currentlen); "Writing on the wire a packet having %u bytes before", currentlen);
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ) #if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
if (session->current_crypto && session->current_crypto->do_compress_out) { if (session->current_crypto && session->current_crypto->do_compress_out) {
ssh_log(session, SSH_LOG_RARE, "Compressing in_buffer ..."); ssh_log(session, SSH_LOG_PACKET, "Compressing in_buffer ...");
if (compress_buffer(session,session->out_buffer) < 0) { if (compress_buffer(session,session->out_buffer) < 0) {
goto error; goto error;
} }
currentlen = buffer_get_len(session->out_buffer); currentlen = buffer_get_len(session->out_buffer);
} }
#endif #endif
padding = (blocksize - ((currentlen +5) % blocksize)); padding = (blocksize - ((currentlen +5) % blocksize));
if(padding < 4) { if(padding < 4) {
padding += blocksize; padding += blocksize;
} }
if (session->current_crypto) { if (session->current_crypto) {
ssh_get_random(padstring, padding, 0); ssh_get_random(padstring, padding, 0);
} else { } else {
memset(padstring,0,padding); memset(padstring,0,padding);
} }
finallen = htonl(currentlen + padding + 1); finallen = htonl(currentlen + padding + 1);
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PACKET,
"%d bytes after comp + %d padding bytes = %lu bytes packet", "%d bytes after comp + %d padding bytes = %lu bytes packet",
currentlen, padding, (long unsigned int) ntohl(finallen)); currentlen, padding, (long unsigned int) ntohl(finallen));
if (buffer_prepend_data(session->out_buffer, &padding, sizeof(u8)) < 0) { if (buffer_prepend_data(session->out_buffer, &padding, sizeof(uint8_t)) < 0) {
goto error; goto error;
} }
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(u32)) < 0) { if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
goto error; goto error;
} }
if (buffer_add_data(session->out_buffer, padstring, padding) < 0) { if (buffer_add_data(session->out_buffer, padstring, padding) < 0) {
goto error; goto error;
} }
#ifdef WITH_PCAP
if(session->pcap_ctx){
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,
buffer_get(session->out_buffer),buffer_get_len(sessi
on->out_buffer)
,buffer_get_len(session->out_buffer));
}
#endif
hmac = packet_encrypt(session, buffer_get(session->out_buffer), hmac = packet_encrypt(session, buffer_get(session->out_buffer),
buffer_get_len(session->out_buffer)); buffer_get_len(session->out_buffer));
if (hmac) { if (hmac) {
if (buffer_add_data(session->out_buffer, hmac, 20) < 0) { if (buffer_add_data(session->out_buffer, hmac, 20) < 0) {
goto error; goto error;
} }
} }
rc = packet_write(session); rc = packet_write(session);
session->send_seq++; session->send_seq++;
if (buffer_reinit(session->out_buffer) < 0) { if (buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR; rc = SSH_ERROR;
} }
error: error:
leave_function(); leave_function();
return rc; /* SSH_OK, AGAIN or ERROR */ return rc; /* SSH_OK, AGAIN or ERROR */
} }
#ifdef HAVE_SSH1 #ifdef WITH_SSH1
static int packet_send1(SSH_SESSION *session) { static int packet_send1(ssh_session session) {
unsigned int blocksize = (session->current_crypto ? unsigned int blocksize = (session->current_crypto ?
session->current_crypto->out_cipher->blocksize : 8); session->current_crypto->out_cipher->blocksize : 8);
u32 currentlen = buffer_get_len(session->out_buffer) + sizeof(u32); uint32_t currentlen = buffer_get_len(session->out_buffer) + sizeof(uint32 _t);
char padstring[32] = {0}; char padstring[32] = {0};
int rc = SSH_ERROR; int rc = SSH_ERROR;
u32 finallen; uint32_t finallen;
u32 crc; uint32_t crc;
u8 padding; uint8_t padding;
enter_function(); enter_function();
ssh_log(session,SSH_LOG_PACKET,"Sending a %d bytes long packet",currentle n); ssh_log(session,SSH_LOG_PACKET,"Sending a %d bytes long packet",currentle n);
/* TODO FIXME /* TODO FIXME
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ) #if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
if (session->current_crypto && session->current_crypto->do_compress_out) { if (session->current_crypto && session->current_crypto->do_compress_out) {
if (compress_buffer(session, session->out_buffer) < 0) { if (compress_buffer(session, session->out_buffer) < 0) {
goto error; goto error;
} }
skipping to change at line 543 skipping to change at line 575
} }
finallen = htonl(currentlen); finallen = htonl(currentlen);
ssh_log(session, SSH_LOG_PACKET, ssh_log(session, SSH_LOG_PACKET,
"%d bytes after comp + %d padding bytes = %d bytes packet", "%d bytes after comp + %d padding bytes = %d bytes packet",
currentlen, padding, ntohl(finallen)); currentlen, padding, ntohl(finallen));
if (buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) { if (buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) {
goto error; goto error;
} }
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(u32)) < 0) { if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
goto error; goto error;
} }
crc = ssh_crc32(buffer_get(session->out_buffer) + sizeof(u32), crc = ssh_crc32((char *)buffer_get(session->out_buffer) + sizeof(uint32_t
buffer_get_len(session->out_buffer) - sizeof(u32)); ),
buffer_get_len(session->out_buffer) - sizeof(uint32_t));
if (buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) { if (buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) {
goto error; goto error;
} }
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("Clear packet", buffer_get(session->out_buffer), ssh_print_hexa("Clear packet", buffer_get(session->out_buffer),
buffer_get_len(session->out_buffer)); buffer_get_len(session->out_buffer));
#endif #endif
packet_encrypt(session, buffer_get(session->out_buffer) + sizeof(u32), packet_encrypt(session, (unsigned char *)buffer_get(session->out_buffer)
buffer_get_len(session->out_buffer) - sizeof(u32)); + sizeof(uint32_t),
buffer_get_len(session->out_buffer) - sizeof(uint32_t));
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("encrypted packet",buffer_get(session->out_buffer), ssh_print_hexa("encrypted packet",buffer_get(session->out_buffer),
buffer_get_len(session->out_buffer)); buffer_get_len(session->out_buffer));
#endif #endif
if (ssh_socket_write(session->socket, buffer_get(session->out_buffer), if (ssh_socket_write(session->socket, buffer_get(session->out_buffer),
buffer_get_len(session->out_buffer)) == SSH_ERROR) { buffer_get_len(session->out_buffer)) == SSH_ERROR) {
goto error; goto error;
} }
skipping to change at line 584 skipping to change at line 616
if (buffer_reinit(session->out_buffer) < 0) { if (buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR; rc = SSH_ERROR;
} }
error: error:
leave_function(); leave_function();
return rc; /* SSH_OK, AGAIN or ERROR */ return rc; /* SSH_OK, AGAIN or ERROR */
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
int packet_send(SSH_SESSION *session) { int packet_send(ssh_session session) {
#ifdef HAVE_SSH1 #ifdef WITH_SSH1
if (session->version == 1) { if (session->version == 1) {
return packet_send1(session); return packet_send1(session);
} }
#endif #endif
return packet_send2(session); return packet_send2(session);
} }
void packet_parse(SSH_SESSION *session) { void packet_parse(ssh_session session) {
STRING *error_s = NULL; ssh_string error_s = NULL;
char *error = NULL; char *error = NULL;
int type = session->in_packet.type; uint32_t type = session->in_packet.type;
u32 tmp; uint32_t tmp;
#ifdef WITH_SSH1 #ifdef WITH_SSH1
if (session->version == 1) { if (session->version == 1) {
/* SSH-1 */ /* SSH-1 */
switch(type) { switch(type) {
case SSH_MSG_DISCONNECT: case SSH_MSG_DISCONNECT:
ssh_log(session, SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT"); ssh_log(session, SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT");
ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT"); ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT");
ssh_socket_close(session->socket); ssh_socket_close(session->socket);
skipping to change at line 654 skipping to change at line 686
session->alive = 0; session->alive = 0;
return; return;
case SSH2_MSG_CHANNEL_WINDOW_ADJUST: case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
case SSH2_MSG_CHANNEL_DATA: case SSH2_MSG_CHANNEL_DATA:
case SSH2_MSG_CHANNEL_EXTENDED_DATA: case SSH2_MSG_CHANNEL_EXTENDED_DATA:
case SSH2_MSG_CHANNEL_REQUEST: case SSH2_MSG_CHANNEL_REQUEST:
case SSH2_MSG_CHANNEL_EOF: case SSH2_MSG_CHANNEL_EOF:
case SSH2_MSG_CHANNEL_CLOSE: case SSH2_MSG_CHANNEL_CLOSE:
channel_handle(session,type); channel_handle(session,type);
return;
case SSH2_MSG_IGNORE: case SSH2_MSG_IGNORE:
case SSH2_MSG_DEBUG: case SSH2_MSG_DEBUG:
return; return;
case SSH2_MSG_SERVICE_REQUEST:
case SSH2_MSG_USERAUTH_REQUEST:
case SSH2_MSG_CHANNEL_OPEN:
message_handle(session,type);
return;
default: default:
ssh_log(session, SSH_LOG_RARE, "Received unhandled packet %d", type ); ssh_log(session, SSH_LOG_RARE, "Received unhandled packet %d", type );
} }
#ifdef WITH_SSH1 #ifdef WITH_SSH1
} }
#endif #endif
} }
#ifdef WITH_SSH1 #ifdef WITH_SSH1
static int packet_wait1(SSH_SESSION *session, int type, int blocking) { static int packet_wait1(ssh_session session, int type, int blocking) {
enter_function(); enter_function();
ssh_log(session, SSH_LOG_PROTOCOL, "packet_wait1 waiting for %d", type); ssh_log(session, SSH_LOG_PROTOCOL, "packet_wait1 waiting for %d", type);
do { do {
if ((packet_read1(session) != SSH_OK) || if ((packet_read1(session) != SSH_OK) ||
(packet_translate(session) != SSH_OK)) { (packet_translate(session) != SSH_OK)) {
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
skipping to change at line 723 skipping to change at line 761
leave_function(); leave_function();
return SSH_OK; return SSH_OK;
} }
} while(1); } while(1);
leave_function(); leave_function();
return SSH_OK; return SSH_OK;
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
static int packet_wait2(SSH_SESSION *session, int type, int blocking) { static int packet_wait2(ssh_session session, int type, int blocking) {
int rc = SSH_ERROR; int rc = SSH_ERROR;
enter_function(); enter_function();
do { do {
rc = packet_read2(session); rc = packet_read2(session);
if (rc != SSH_OK) { if (rc != SSH_OK) {
leave_function(); leave_function();
return rc; return rc;
} }
if (packet_translate(session) != SSH_OK) { if (packet_translate(session) != SSH_OK) {
skipping to change at line 749 skipping to change at line 787
packet_parse(session); packet_parse(session);
ssh_log(session, SSH_LOG_PACKET, "received disconnect packet"); ssh_log(session, SSH_LOG_PACKET, "received disconnect packet");
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
case SSH2_MSG_CHANNEL_WINDOW_ADJUST: case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
case SSH2_MSG_CHANNEL_DATA: case SSH2_MSG_CHANNEL_DATA:
case SSH2_MSG_CHANNEL_EXTENDED_DATA: case SSH2_MSG_CHANNEL_EXTENDED_DATA:
case SSH2_MSG_CHANNEL_REQUEST: case SSH2_MSG_CHANNEL_REQUEST:
case SSH2_MSG_CHANNEL_EOF: case SSH2_MSG_CHANNEL_EOF:
case SSH2_MSG_CHANNEL_CLOSE: case SSH2_MSG_CHANNEL_CLOSE:
case SSH2_MSG_SERVICE_REQUEST:
case SSH2_MSG_USERAUTH_REQUEST:
case SSH2_MSG_CHANNEL_OPEN:
packet_parse(session); packet_parse(session);
break; break;
case SSH2_MSG_IGNORE: case SSH2_MSG_IGNORE:
case SSH2_MSG_DEBUG:
break; break;
default: default:
if (type && (type != session->in_packet.type)) { if (type && (type != session->in_packet.type)) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"packet_wait2(): Received a %d type packet, but expected a %d \n", "packet_wait2(): Received a %d type packet, but expected a %d \n",
session->in_packet.type, type); session->in_packet.type, type);
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
leave_function(); leave_function();
skipping to change at line 774 skipping to change at line 816
if (blocking == 0) { if (blocking == 0) {
leave_function(); leave_function();
return SSH_OK; //shouldn't it return SSH_AGAIN here ? return SSH_OK; //shouldn't it return SSH_AGAIN here ?
} }
} while(1); } while(1);
leave_function(); leave_function();
return SSH_OK; return SSH_OK;
} }
int packet_wait(SSH_SESSION *session, int type, int block) { int packet_wait(ssh_session session, int type, int block) {
#ifdef WITH_SSH1 #ifdef WITH_SSH1
if (session->version == 1) { if (session->version == 1) {
return packet_wait1(session, type, block); return packet_wait1(session, type, block);
} }
#endif #endif
return packet_wait2(session, type, block); return packet_wait2(session, type, block);
} }
/* vim: set ts=2 sw=2 et cindent: */ /* vim: set ts=2 sw=2 et cindent: */
 End of changes. 54 change blocks. 
62 lines changed or deleted 110 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/