mirror of
https://github.com/clearml/dropbear
synced 2025-06-26 18:17:32 +00:00
merge
--HG-- branch : coverity
This commit is contained in:
32
buffer.c
32
buffer.c
@@ -46,17 +46,15 @@ buffer* buf_new(unsigned int size) {
|
||||
dropbear_exit("buf->size too big");
|
||||
}
|
||||
|
||||
buf = (buffer*)m_malloc(sizeof(buffer));
|
||||
buf = (buffer*)m_malloc(sizeof(buffer)+size);
|
||||
|
||||
if (size > 0) {
|
||||
buf->data = (unsigned char*)m_malloc(size);
|
||||
buf->data = (unsigned char*)buf + sizeof(buffer);
|
||||
} else {
|
||||
buf->data = NULL;
|
||||
}
|
||||
|
||||
buf->size = size;
|
||||
buf->pos = 0;
|
||||
buf->len = 0;
|
||||
|
||||
return buf;
|
||||
|
||||
@@ -65,7 +63,6 @@ buffer* buf_new(unsigned int size) {
|
||||
/* free the buffer's data and the buffer itself */
|
||||
void buf_free(buffer* buf) {
|
||||
|
||||
m_free(buf->data)
|
||||
m_free(buf);
|
||||
}
|
||||
|
||||
@@ -78,17 +75,18 @@ void buf_burn(buffer* buf) {
|
||||
|
||||
/* resize a buffer, pos and len will be repositioned if required when
|
||||
* downsizing */
|
||||
void buf_resize(buffer *buf, unsigned int newsize) {
|
||||
buffer* buf_resize(buffer *buf, unsigned int newsize) {
|
||||
|
||||
if (newsize > BUF_MAX_SIZE) {
|
||||
dropbear_exit("buf->size too big");
|
||||
}
|
||||
|
||||
buf->data = m_realloc(buf->data, newsize);
|
||||
buf = m_realloc(buf, sizeof(buffer)+newsize);
|
||||
buf->data = (unsigned char*)buf + sizeof(buffer);
|
||||
buf->size = newsize;
|
||||
buf->len = MIN(newsize, buf->len);
|
||||
buf->pos = MIN(newsize, buf->pos);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Create a copy of buf, allocating required memory etc. */
|
||||
@@ -227,15 +225,15 @@ unsigned char* buf_getstring(buffer* buf, unsigned int *retlen) {
|
||||
|
||||
/* Return a string as a newly allocated buffer */
|
||||
buffer * buf_getstringbuf(buffer *buf) {
|
||||
buffer *ret;
|
||||
unsigned char* str;
|
||||
unsigned int len;
|
||||
str = buf_getstring(buf, &len);
|
||||
ret = m_malloc(sizeof(*ret));
|
||||
ret->data = str;
|
||||
ret->len = len;
|
||||
ret->size = len;
|
||||
ret->pos = 0;
|
||||
buffer *ret = NULL;
|
||||
unsigned int len = buf_getint(buf);
|
||||
if (len > MAX_STRING_LEN) {
|
||||
dropbear_exit("String too long");
|
||||
}
|
||||
ret = buf_new(len);
|
||||
memcpy(buf_getwriteptr(ret, len), buf_getptr(buf, len), len);
|
||||
buf_incrpos(buf, len);
|
||||
buf_incrlen(ret, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
6
buffer.h
6
buffer.h
@@ -29,7 +29,8 @@
|
||||
#include "includes.h"
|
||||
|
||||
struct buf {
|
||||
|
||||
/* don't manipulate data member outside of buffer.c - it
|
||||
is a pointer into the malloc holding buffer itself */
|
||||
unsigned char * data;
|
||||
unsigned int len; /* the used size */
|
||||
unsigned int pos;
|
||||
@@ -40,7 +41,8 @@ struct buf {
|
||||
typedef struct buf buffer;
|
||||
|
||||
buffer * buf_new(unsigned int size);
|
||||
void buf_resize(buffer *buf, unsigned int newsize);
|
||||
/* Possibly returns a new buffer*, like realloc() */
|
||||
buffer * buf_resize(buffer *buf, unsigned int newsize);
|
||||
void buf_free(buffer* buf);
|
||||
void buf_burn(buffer* buf);
|
||||
buffer* buf_newcopy(buffer* buf);
|
||||
|
||||
17
circbuffer.c
17
circbuffer.c
@@ -110,6 +110,21 @@ unsigned char* cbuf_readptr(circbuffer *cbuf, unsigned int len) {
|
||||
return &cbuf->data[cbuf->readpos];
|
||||
}
|
||||
|
||||
void cbuf_readptrs(circbuffer *cbuf,
|
||||
unsigned char **p1, unsigned int *len1,
|
||||
unsigned char **p2, unsigned int *len2) {
|
||||
*p1 = &cbuf->data[cbuf->readpos];
|
||||
*len1 = MIN(cbuf->used, cbuf->size - cbuf->readpos);
|
||||
|
||||
if (*len1 < cbuf->used) {
|
||||
*p2 = cbuf->data;
|
||||
*len2 = cbuf->used - *len1;
|
||||
} else {
|
||||
*p2 = NULL;
|
||||
*len2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* cbuf_writeptr(circbuffer *cbuf, unsigned int len) {
|
||||
|
||||
if (len > cbuf_writelen(cbuf)) {
|
||||
@@ -131,9 +146,11 @@ void cbuf_incrwrite(circbuffer *cbuf, unsigned int len) {
|
||||
|
||||
|
||||
void cbuf_incrread(circbuffer *cbuf, unsigned int len) {
|
||||
#if 0
|
||||
if (len > cbuf_readlen(cbuf)) {
|
||||
dropbear_exit("Bad cbuf read");
|
||||
}
|
||||
#endif
|
||||
|
||||
dropbear_assert(cbuf->used >= len);
|
||||
cbuf->used -= len;
|
||||
|
||||
@@ -44,6 +44,9 @@ unsigned int cbuf_readlen(circbuffer *cbuf); /* max linear read len */
|
||||
unsigned int cbuf_writelen(circbuffer *cbuf); /* max linear write len */
|
||||
|
||||
unsigned char* cbuf_readptr(circbuffer *cbuf, unsigned int len);
|
||||
void cbuf_readptrs(circbuffer *cbuf,
|
||||
unsigned char **p1, unsigned int *len1,
|
||||
unsigned char **p2, unsigned int *len2);
|
||||
unsigned char* cbuf_writeptr(circbuffer *cbuf, unsigned int len);
|
||||
void cbuf_incrwrite(circbuffer *cbuf, unsigned int len);
|
||||
void cbuf_incrread(circbuffer *cbuf, unsigned int len);
|
||||
|
||||
@@ -155,7 +155,7 @@ static buffer * agent_request(unsigned char type, buffer *data) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf_resize(inbuf, readlen);
|
||||
inbuf = buf_resize(inbuf, readlen);
|
||||
buf_setpos(inbuf, 0);
|
||||
ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen);
|
||||
if ((size_t)ret != readlen) {
|
||||
|
||||
@@ -42,7 +42,8 @@ static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
|
||||
static void send_msg_channel_open_confirmation(struct Channel* channel,
|
||||
unsigned int recvwindow,
|
||||
unsigned int recvmaxpacket);
|
||||
static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf);
|
||||
static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
|
||||
const unsigned char *moredata, unsigned int *morelen);
|
||||
static void send_msg_channel_window_adjust(struct Channel *channel,
|
||||
unsigned int incr);
|
||||
static void send_msg_channel_data(struct Channel *channel, int isextended);
|
||||
@@ -241,14 +242,14 @@ void channelio(fd_set *readfds, fd_set *writefds) {
|
||||
|
||||
/* write to program/pipe stdin */
|
||||
if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
|
||||
writechannel(channel, channel->writefd, channel->writebuf);
|
||||
writechannel(channel, channel->writefd, channel->writebuf, NULL, NULL);
|
||||
do_check_close = 1;
|
||||
}
|
||||
|
||||
/* stderr for client mode */
|
||||
if (ERRFD_IS_WRITE(channel)
|
||||
&& channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
|
||||
writechannel(channel, channel->errfd, channel->extrabuf);
|
||||
writechannel(channel, channel->errfd, channel->extrabuf, NULL, NULL);
|
||||
do_check_close = 1;
|
||||
}
|
||||
|
||||
@@ -434,14 +435,67 @@ static void send_msg_channel_eof(struct Channel *channel) {
|
||||
}
|
||||
|
||||
/* Called to write data out to the local side of the channel.
|
||||
* Only called when we know we can write to a channel, writes as much as
|
||||
* possible */
|
||||
static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
|
||||
Writes the circular buffer contents and also the "moredata" buffer
|
||||
if not null. Will ignore EAGAIN */
|
||||
static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
|
||||
const unsigned char *moredata, unsigned int *morelen) {
|
||||
|
||||
int len, maxlen;
|
||||
struct iovec iov[3];
|
||||
unsigned char *circ_p1, *circ_p2;
|
||||
unsigned int circ_len1, circ_len2;
|
||||
int io_count = 0;
|
||||
|
||||
int written;
|
||||
|
||||
TRACE(("enter writechannel fd %d", fd))
|
||||
|
||||
cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2);
|
||||
|
||||
if (circ_len1 > 0) {
|
||||
TRACE(("circ1 %d", circ_len1))
|
||||
iov[io_count].iov_base = circ_p1;
|
||||
iov[io_count].iov_len = circ_len1;
|
||||
io_count++;
|
||||
}
|
||||
|
||||
if (circ_len2 > 0) {
|
||||
TRACE(("circ2 %d", circ_len2))
|
||||
iov[io_count].iov_base = circ_p2;
|
||||
iov[io_count].iov_len = circ_len2;
|
||||
io_count++;
|
||||
}
|
||||
|
||||
if (morelen) {
|
||||
assert(moredata);
|
||||
TRACE(("more %d", *morelen))
|
||||
iov[io_count].iov_base = (void*)moredata;
|
||||
iov[io_count].iov_len = *morelen;
|
||||
io_count++;
|
||||
}
|
||||
|
||||
if (morelen) {
|
||||
/* Default return value, none consumed */
|
||||
*morelen = 0;
|
||||
}
|
||||
|
||||
written = writev(fd, iov, io_count);
|
||||
|
||||
if (written < 0) {
|
||||
if (errno != EINTR && errno != EAGAIN) {
|
||||
TRACE(("errno %d len %d", errno, len))
|
||||
close_chan_fd(channel, fd, SHUT_WR);
|
||||
}
|
||||
} else {
|
||||
int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written);
|
||||
cbuf_incrread(cbuf, cbuf_written);
|
||||
if (morelen) {
|
||||
*morelen = written - cbuf_written;
|
||||
}
|
||||
channel->recvdonelen += written;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
maxlen = cbuf_readlen(cbuf);
|
||||
|
||||
/* Write the data out */
|
||||
@@ -458,10 +512,10 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
|
||||
|
||||
cbuf_incrread(cbuf, len);
|
||||
channel->recvdonelen += len;
|
||||
#endif
|
||||
|
||||
/* Window adjust handling */
|
||||
if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
|
||||
/* Set it back to max window */
|
||||
send_msg_channel_window_adjust(channel, channel->recvdonelen);
|
||||
channel->recvwindow += channel->recvdonelen;
|
||||
channel->recvdonelen = 0;
|
||||
@@ -745,6 +799,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
|
||||
unsigned int maxdata;
|
||||
unsigned int buflen;
|
||||
unsigned int len;
|
||||
unsigned int consumed;
|
||||
|
||||
TRACE(("enter recv_msg_channel_data"))
|
||||
|
||||
@@ -771,6 +826,17 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
|
||||
dropbear_exit("Oversized packet");
|
||||
}
|
||||
|
||||
dropbear_assert(channel->recvwindow >= datalen);
|
||||
channel->recvwindow -= datalen;
|
||||
dropbear_assert(channel->recvwindow <= opts.recv_window);
|
||||
|
||||
consumed = datalen;
|
||||
writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed);
|
||||
|
||||
datalen -= consumed;
|
||||
buf_incrpos(ses.payload, consumed);
|
||||
|
||||
|
||||
/* We may have to run throught twice, if the buffer wraps around. Can't
|
||||
* just "leave it for next time" like with writechannel, since this
|
||||
* is payload data */
|
||||
@@ -786,10 +852,6 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
|
||||
len -= buflen;
|
||||
}
|
||||
|
||||
dropbear_assert(channel->recvwindow >= datalen);
|
||||
channel->recvwindow -= datalen;
|
||||
dropbear_assert(channel->recvwindow <= opts.recv_window);
|
||||
|
||||
TRACE(("leave recv_msg_channel_data"))
|
||||
}
|
||||
|
||||
|
||||
12
common-kex.c
12
common-kex.c
@@ -534,8 +534,10 @@ void recv_msg_kexinit() {
|
||||
buf_putstring(ses.kexhashbuf,
|
||||
ses.transkexinit->data, ses.transkexinit->len);
|
||||
/* I_S, the payload of the server's SSH_MSG_KEXINIT */
|
||||
buf_setpos(ses.payload, 0);
|
||||
buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
|
||||
buf_setpos(ses.payload, ses.payload_beginning);
|
||||
buf_putstring(ses.kexhashbuf,
|
||||
buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
|
||||
ses.payload->len-ses.payload->pos);
|
||||
ses.requirenext = SSH_MSG_KEXDH_REPLY;
|
||||
} else {
|
||||
/* SERVER */
|
||||
@@ -549,8 +551,10 @@ void recv_msg_kexinit() {
|
||||
(unsigned char*)LOCAL_IDENT, local_ident_len);
|
||||
|
||||
/* I_C, the payload of the client's SSH_MSG_KEXINIT */
|
||||
buf_setpos(ses.payload, 0);
|
||||
buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
|
||||
buf_setpos(ses.payload, ses.payload_beginning);
|
||||
buf_putstring(ses.kexhashbuf,
|
||||
buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
|
||||
ses.payload->len-ses.payload->pos);
|
||||
|
||||
/* I_S, the payload of the server's SSH_MSG_KEXINIT */
|
||||
buf_putstring(ses.kexhashbuf,
|
||||
|
||||
@@ -152,8 +152,10 @@ void session_loop(void(*loophandler)()) {
|
||||
FD_ZERO(&readfd);
|
||||
dropbear_assert(ses.payload == NULL);
|
||||
|
||||
/* during initial setup we flush out the KEXINIT packet before
|
||||
* attempting to read the remote version string, which might block */
|
||||
/* We delay reading from the input socket during initial setup until
|
||||
after we have written out our initial KEXINIT packet (empty writequeue).
|
||||
This means our initial packet can be in-flight while we're doing a blocking
|
||||
read for the remote ident */
|
||||
if (ses.sock_in != -1 && (ses.remoteident || isempty(&ses.writequeue))) {
|
||||
FD_SET(ses.sock_in, &readfd);
|
||||
}
|
||||
|
||||
5
ecc.c
5
ecc.c
@@ -86,11 +86,6 @@ static int ecc_is_point(ecc_key *key)
|
||||
{
|
||||
mp_int *prime, *b, *t1, *t2;
|
||||
int err;
|
||||
|
||||
prime = m_malloc(sizeof(mp_int));
|
||||
b = m_malloc(sizeof(mp_int));
|
||||
t1 = m_malloc(sizeof(mp_int));
|
||||
t2 = m_malloc(sizeof(mp_int));
|
||||
|
||||
m_mp_alloc_init_multi(&prime, &b, &t1, &t2, NULL);
|
||||
|
||||
|
||||
2
ecdsa.c
2
ecdsa.c
@@ -409,7 +409,7 @@ int buf_ecdsa_verify(buffer *buf, ecc_key *key, buffer *data_buf) {
|
||||
out:
|
||||
ltc_ecc_del_point(mG);
|
||||
ltc_ecc_del_point(mQ);
|
||||
mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
|
||||
ltc_deinit_multi(r, s, v, w, u1, u2, p, e, m, NULL);
|
||||
if (mp != NULL) {
|
||||
ltc_mp.montgomery_deinit(mp);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
*/
|
||||
int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned char *buf, *isha;
|
||||
unsigned char buf[MAXBLOCKSIZE], isha[MAXBLOCKSIZE];
|
||||
unsigned long hashsize, i;
|
||||
int hash, err;
|
||||
|
||||
@@ -44,19 +44,6 @@ int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
|
||||
/* get the hash message digest size */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
/* allocate buffers */
|
||||
buf = XMALLOC(HMAC_BLOCKSIZE);
|
||||
isha = XMALLOC(hashsize);
|
||||
if (buf == NULL || isha == NULL) {
|
||||
if (buf != NULL) {
|
||||
XFREE(buf);
|
||||
}
|
||||
if (isha != NULL) {
|
||||
XFREE(isha);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* Get the hash of the first HMAC vector plus the data */
|
||||
if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
@@ -96,9 +83,6 @@ LBL_ERR:
|
||||
zeromem(hmac, sizeof(*hmac));
|
||||
#endif
|
||||
|
||||
XFREE(isha);
|
||||
XFREE(buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
unsigned long hashsize;
|
||||
unsigned long i, z;
|
||||
int err;
|
||||
@@ -49,16 +49,9 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* allocate ram for buf */
|
||||
buf = XMALLOC(HMAC_BLOCKSIZE);
|
||||
if (buf == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* allocate memory for key */
|
||||
hmac->key = XMALLOC(HMAC_BLOCKSIZE);
|
||||
if (hmac->key == NULL) {
|
||||
XFREE(buf);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
@@ -101,7 +94,6 @@ done:
|
||||
zeromem(buf, HMAC_BLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
7
netio.c
7
netio.c
@@ -169,11 +169,10 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
|
||||
snprintf(c->errstring, len, "Error resolving '%s' port '%s'. %s",
|
||||
remotehost, remoteport, gai_strerror(err));
|
||||
TRACE(("Error resolving: %s", gai_strerror(err)))
|
||||
return NULL;
|
||||
} else {
|
||||
c->res_iter = c->res;
|
||||
}
|
||||
|
||||
c->res_iter = c->res;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -220,7 +219,7 @@ void handle_connect_fds(fd_set *writefd) {
|
||||
socklen_t vallen = sizeof(val);
|
||||
struct dropbear_progress_connection *c = iter->item;
|
||||
|
||||
if (!FD_ISSET(c->sock, writefd)) {
|
||||
if (c->sock < 0 || !FD_ISSET(c->sock, writefd)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
1
netio.h
1
netio.h
@@ -27,6 +27,7 @@ struct dropbear_progress_connection;
|
||||
errstring is only set on DROPBEAR_FAILURE, returns failure message for the last attempted socket */
|
||||
typedef void(*connect_callback)(int result, int sock, void* data, const char* errstring);
|
||||
|
||||
/* Always returns a progress connection, if it fails it will call the callback at a later point */
|
||||
struct dropbear_progress_connection * connect_remote (const char* remotehost, const char* remoteport,
|
||||
connect_callback cb, void *cb_data);
|
||||
|
||||
|
||||
64
packet.c
64
packet.c
@@ -257,7 +257,7 @@ static int read_packet_init() {
|
||||
}
|
||||
|
||||
if (len > ses.readbuf->size) {
|
||||
buf_resize(ses.readbuf, len);
|
||||
ses.readbuf = buf_resize(ses.readbuf, len);
|
||||
}
|
||||
buf_setlen(ses.readbuf, len);
|
||||
buf_setpos(ses.readbuf, blocksize);
|
||||
@@ -314,18 +314,21 @@ void decrypt_packet() {
|
||||
if (is_compress_recv()) {
|
||||
/* decompress */
|
||||
ses.payload = buf_decompress(ses.readbuf, len);
|
||||
buf_setpos(ses.payload, 0);
|
||||
ses.payload_beginning = 0;
|
||||
buf_free(ses.readbuf);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ses.payload = ses.readbuf;
|
||||
ses.payload_beginning = ses.payload->pos;
|
||||
buf_setlen(ses.payload, ses.payload->pos + len);
|
||||
/* copy payload */
|
||||
ses.payload = buf_new(len);
|
||||
memcpy(ses.payload->data, buf_getptr(ses.readbuf, len), len);
|
||||
buf_incrlen(ses.payload, len);
|
||||
//ses.payload = buf_new(len);
|
||||
//memcpy(ses.payload->data, buf_getptr(ses.readbuf, len), len);
|
||||
//buf_incrlen(ses.payload, len);
|
||||
}
|
||||
|
||||
buf_free(ses.readbuf);
|
||||
ses.readbuf = NULL;
|
||||
buf_setpos(ses.payload, 0);
|
||||
|
||||
ses.recvseq++;
|
||||
|
||||
@@ -398,7 +401,7 @@ static buffer* buf_decompress(buffer* buf, unsigned int len) {
|
||||
dropbear_exit("bad packet, oversized decompressed");
|
||||
}
|
||||
new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR);
|
||||
buf_resize(ret, new_size);
|
||||
ret = buf_resize(ret, new_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -637,7 +640,8 @@ static void make_mac(unsigned int seqno, const struct key_context_directional *
|
||||
|
||||
#ifndef DISABLE_ZLIB
|
||||
/* compresses len bytes from src, outputting to dest (starting from the
|
||||
* respective current positions. */
|
||||
* respective current positions. dest must have sufficient space,
|
||||
* len+ZLIB_COMPRESS_EXPANSION */
|
||||
static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
|
||||
|
||||
unsigned int endpos = src->pos + len;
|
||||
@@ -645,38 +649,28 @@ static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
|
||||
|
||||
TRACE2(("enter buf_compress"))
|
||||
|
||||
while (1) {
|
||||
dropbear_assert(dest->size - dest->pos >= len+ZLIB_COMPRESS_EXPANSION);
|
||||
|
||||
ses.keys->trans.zstream->avail_in = endpos - src->pos;
|
||||
ses.keys->trans.zstream->next_in =
|
||||
buf_getptr(src, ses.keys->trans.zstream->avail_in);
|
||||
ses.keys->trans.zstream->avail_in = endpos - src->pos;
|
||||
ses.keys->trans.zstream->next_in =
|
||||
buf_getptr(src, ses.keys->trans.zstream->avail_in);
|
||||
|
||||
ses.keys->trans.zstream->avail_out = dest->size - dest->pos;
|
||||
ses.keys->trans.zstream->next_out =
|
||||
buf_getwriteptr(dest, ses.keys->trans.zstream->avail_out);
|
||||
ses.keys->trans.zstream->avail_out = dest->size - dest->pos;
|
||||
ses.keys->trans.zstream->next_out =
|
||||
buf_getwriteptr(dest, ses.keys->trans.zstream->avail_out);
|
||||
|
||||
result = deflate(ses.keys->trans.zstream, Z_SYNC_FLUSH);
|
||||
result = deflate(ses.keys->trans.zstream, Z_SYNC_FLUSH);
|
||||
|
||||
buf_setpos(src, endpos - ses.keys->trans.zstream->avail_in);
|
||||
buf_setlen(dest, dest->size - ses.keys->trans.zstream->avail_out);
|
||||
buf_setpos(dest, dest->len);
|
||||
|
||||
if (result != Z_OK) {
|
||||
dropbear_exit("zlib error");
|
||||
}
|
||||
|
||||
if (ses.keys->trans.zstream->avail_in == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
dropbear_assert(ses.keys->trans.zstream->avail_out == 0);
|
||||
|
||||
/* the buffer has been filled, we must extend. This only happens in
|
||||
* unusual circumstances where the data grows in size after deflate(),
|
||||
* but it is possible */
|
||||
buf_resize(dest, dest->size + ZLIB_COMPRESS_EXPANSION);
|
||||
buf_setpos(src, endpos - ses.keys->trans.zstream->avail_in);
|
||||
buf_setlen(dest, dest->size - ses.keys->trans.zstream->avail_out);
|
||||
buf_setpos(dest, dest->len);
|
||||
|
||||
if (result != Z_OK) {
|
||||
dropbear_exit("zlib error");
|
||||
}
|
||||
|
||||
/* fails if destination buffer wasn't large enough */
|
||||
dropbear_assert(ses.keys->trans.zstream->avail_in == 0);
|
||||
TRACE2(("leave buf_compress"))
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -126,7 +126,11 @@ struct sshsession {
|
||||
buffer with the packet to send. */
|
||||
struct Queue writequeue; /* A queue of encrypted packets to send */
|
||||
buffer *readbuf; /* From the wire, decrypted in-place */
|
||||
buffer *payload; /* Post-decompression, the actual SSH packet */
|
||||
buffer *payload; /* Post-decompression, the actual SSH packet.
|
||||
May have extra data at the beginning, will be
|
||||
passed to packet processing functions positioned past
|
||||
that, see payload_beginning */
|
||||
unsigned int payload_beginning;
|
||||
unsigned int transseq, recvseq; /* Sequence IDs */
|
||||
|
||||
/* Packet-handling flags */
|
||||
|
||||
@@ -187,6 +187,7 @@ int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
|
||||
if (eck) {
|
||||
if (*eck) {
|
||||
ecc_free(*eck);
|
||||
m_free(*eck);
|
||||
*eck = NULL;
|
||||
}
|
||||
*eck = buf_get_ecdsa_pub_key(buf);
|
||||
@@ -255,6 +256,7 @@ int buf_get_priv_key(buffer *buf, sign_key *key, enum signkey_type *type) {
|
||||
if (eck) {
|
||||
if (*eck) {
|
||||
ecc_free(*eck);
|
||||
m_free(*eck);
|
||||
*eck = NULL;
|
||||
}
|
||||
*eck = buf_get_ecdsa_priv_key(buf);
|
||||
@@ -355,18 +357,21 @@ void sign_key_free(sign_key *key) {
|
||||
#ifdef DROPBEAR_ECC_256
|
||||
if (key->ecckey256) {
|
||||
ecc_free(key->ecckey256);
|
||||
m_free(key->ecckey256);
|
||||
key->ecckey256 = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef DROPBEAR_ECC_384
|
||||
if (key->ecckey384) {
|
||||
ecc_free(key->ecckey384);
|
||||
m_free(key->ecckey384);
|
||||
key->ecckey384 = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef DROPBEAR_ECC_521
|
||||
if (key->ecckey521) {
|
||||
ecc_free(key->ecckey521);
|
||||
m_free(key->ecckey521);
|
||||
key->ecckey521 = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -86,6 +86,7 @@ void svr_auth_pubkey() {
|
||||
unsigned int algolen;
|
||||
unsigned char* keyblob = NULL;
|
||||
unsigned int keybloblen;
|
||||
unsigned int sign_payload_length;
|
||||
buffer * signbuf = NULL;
|
||||
sign_key * key = NULL;
|
||||
char* fp = NULL;
|
||||
@@ -125,9 +126,18 @@ void svr_auth_pubkey() {
|
||||
|
||||
/* create the data which has been signed - this a string containing
|
||||
* session_id, concatenated with the payload packet up to the signature */
|
||||
assert(ses.payload_beginning <= ses.payload->pos);
|
||||
sign_payload_length = ses.payload->pos - ses.payload_beginning;
|
||||
signbuf = buf_new(ses.payload->pos + 4 + ses.session_id->len);
|
||||
buf_putbufstring(signbuf, ses.session_id);
|
||||
buf_putbytes(signbuf, ses.payload->data, ses.payload->pos);
|
||||
|
||||
/* The entire contents of the payload prior. */
|
||||
buf_setpos(ses.payload, ses.payload_beginning);
|
||||
buf_putbytes(signbuf,
|
||||
buf_getptr(ses.payload, sign_payload_length),
|
||||
sign_payload_length);
|
||||
buf_incrpos(ses.payload, sign_payload_length);
|
||||
|
||||
buf_setpos(signbuf, 0);
|
||||
|
||||
/* ... and finally verify the signature */
|
||||
|
||||
Reference in New Issue
Block a user