Mercurial > dropbear
changeset 1127:b803ad2b9f4c
Merge pull request #11 from nshopik/patch-2
Prepend DROPBEAR for scp.c
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 12 Jun 2015 22:57:48 +0800 |
parents | 7cb1f49d89a8 (diff) 2dee3eef5344 (current diff) |
children | a9e074b78cd5 45830474d83c |
files | |
diffstat | 61 files changed, 348 insertions(+), 273 deletions(-) [+] |
line wrap: on
line diff
--- a/.travis.yml Thu Mar 12 15:14:47 2015 +0300 +++ b/.travis.yml Fri Jun 12 22:57:48 2015 +0800 @@ -3,7 +3,9 @@ - gcc script: - - autoconf && autoheader && ./configure $BUNDLEDLIBTOM CFLAGS="-O2 -Wall -Wno-pointer-sign" --prefix=$HOME/inst && make install + - autoconf && autoheader && ./configure $BUNDLEDLIBTOM CFLAGS="-O2 -Wall -Wno-pointer-sign" --prefix=$HOME/inst + - test "$NOWRITEV" && sed -i s/HAVE_WRITEV/DONT_HAVE_WRITEV/ config.h || true + - make install - ~/inst/bin/dropbearkey -t rsa -f testrsa - ~/inst/bin/dropbearkey -t dss -f testdss - ~/inst/bin/dropbearkey -t ecdsa -f testec256 -s 256 @@ -18,3 +20,4 @@ - BUNDLEDLIBTOM=--disable-bundled-libtom - BUNDLEDLIBTOM=--enable-bundled-libtom - MULTI=1 + - NOWRITEV=1
--- a/CHANGES Thu Mar 12 15:14:47 2015 +0300 +++ b/CHANGES Fri Jun 12 22:57:48 2015 +0800 @@ -1,19 +1,32 @@ -- Improve efficiency of writing data to local program/pipes, measured 30% for - connections to localhost +- Improve efficiency of writing data to local program/pipes, measured 30% increase + increase in throughput for connections to localhost - Use TCP Fast Open on Linux if available. saves a round trip at connection to hosts that have previously been connected. Needs a recent Linux kernel and possibly "sysctl -w net.ipv4.tcp_fastopen=3" + Client side is disabled by default pending further compatibility testing + with networks and systems. - Forwarded TCP ports connect asynchronously and retry with other available - addresses (IPv4 or IPv6) + addresses (IPv4 or IPv6, round robin IPs) - Free memory before exiting, patch from Thorsten Horstmann. Useful for Dropbear ports to embedded systems and for checking memory leaks with valgrind. Only partially implemented for client side. +- Fix all compile warnings, patch from Gaƫl Portay + (note that configure with -Werror may not be successful on some platforms + such as OS X and some configuration options may result in unused variable + warnings) + - Fix small ECC memory leaks +- Tighten validation of Diffie-Hellman parameters, from Florent Daigniere of + Matt Consulting. Odds of bad values are around 2**-512 -- improbable. + +- Twofish-ctr cipher is supported though disabled by default + + 2015.67 - Wednesday 28 January 2015 - Call fsync() after generating private keys to ensure they aren't lost if a
--- a/LICENSE Thu Mar 12 15:14:47 2015 +0300 +++ b/LICENSE Fri Jun 12 22:57:48 2015 +0800 @@ -8,7 +8,7 @@ Portions of the client-mode work are (c) 2004 Mihnea Stoenescu, under the same license: -Copyright (c) 2002-2014 Matt Johnston +Copyright (c) 2002-2015 Matt Johnston Portions copyright (c) 2004 Mihnea Stoenescu All rights reserved.
--- a/algo.h Thu Mar 12 15:14:47 2015 +0300 +++ b/algo.h Fri Jun 12 22:57:48 2015 +0800 @@ -35,7 +35,7 @@ struct Algo_Type { - const unsigned char *name; /* identifying name */ + const char *name; /* identifying name */ char val; /* a value for this cipher, or -1 for invalid */ const void *data; /* algorithm specific data */ char usable; /* whether we can use this algorithm */
--- a/auth.h Thu Mar 12 15:14:47 2015 +0300 +++ b/auth.h Fri Jun 12 22:57:48 2015 +0800 @@ -133,7 +133,7 @@ int no_x11_forwarding_flag; int no_pty_flag; /* "command=" option. */ - unsigned char * forced_command; + char * forced_command; }; #endif
--- a/buffer.c Thu Mar 12 15:14:47 2015 +0300 +++ b/buffer.c Fri Jun 12 22:57:48 2015 +0800 @@ -203,10 +203,10 @@ /* Return a null-terminated string, it is malloced, so must be free()ed * Note that the string isn't checked for null bytes, hence the retlen * may be longer than what is returned by strlen */ -unsigned char* buf_getstring(buffer* buf, unsigned int *retlen) { +char* buf_getstring(buffer* buf, unsigned int *retlen) { unsigned int len; - unsigned char* ret; + char* ret; len = buf_getint(buf); if (len > MAX_STRING_LEN) { dropbear_exit("String too long"); @@ -262,16 +262,16 @@ } /* put a SSH style string into the buffer, increasing buffer len if required */ -void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len) { +void buf_putstring(buffer* buf, const char* str, unsigned int len) { buf_putint(buf, len); - buf_putbytes(buf, str, len); + buf_putbytes(buf, (const unsigned char*)str, len); } /* puts an entire buffer as a SSH string. ignore pos of buf_str. */ void buf_putbufstring(buffer *buf, const buffer* buf_str) { - buf_putstring(buf, buf_str->data, buf_str->len); + buf_putstring(buf, (const char*)buf_str->data, buf_str->len); } /* put the set of len bytes into the buffer, incrementing the pos, increasing
--- a/buffer.h Thu Mar 12 15:14:47 2015 +0300 +++ b/buffer.h Fri Jun 12 22:57:48 2015 +0800 @@ -56,11 +56,11 @@ void buf_putbyte(buffer* buf, unsigned char val); unsigned char* buf_getptr(buffer* buf, unsigned int len); unsigned char* buf_getwriteptr(buffer* buf, unsigned int len); -unsigned char* buf_getstring(buffer* buf, unsigned int *retlen); +char* buf_getstring(buffer* buf, unsigned int *retlen); buffer * buf_getstringbuf(buffer *buf); void buf_eatstring(buffer *buf); void buf_putint(buffer* buf, unsigned int val); -void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len); +void buf_putstring(buffer* buf, const char* str, unsigned int len); void buf_putbufstring(buffer *buf, const buffer* buf_str); void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len); void buf_putmpint(buffer* buf, mp_int * mp);
--- a/channel.h Thu Mar 12 15:14:47 2015 +0300 +++ b/channel.h Fri Jun 12 22:57:48 2015 +0800 @@ -106,7 +106,7 @@ void chaninitialise(const struct ChanType *chantypes[]); void chancleanup(); -void setchannelfds(fd_set *readfd, fd_set *writefd); +void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads); void channelio(fd_set *readfd, fd_set *writefd); struct Channel* getchannel(); /* Returns an arbitrary channel that is in a ready state - not @@ -135,7 +135,7 @@ void recv_msg_channel_open_confirmation(); void recv_msg_channel_open_failure(); #endif -void start_send_channel_request(struct Channel *channel, unsigned char *type); +void start_send_channel_request(struct Channel *channel, char *type); void send_msg_request_success(); void send_msg_request_failure();
--- a/chansession.h Thu Mar 12 15:14:47 2015 +0300 +++ b/chansession.h Fri Jun 12 22:57:48 2015 +0800 @@ -39,14 +39,14 @@ struct ChanSess { - unsigned char * cmd; /* command to exec */ + char * cmd; /* command to exec */ pid_t pid; /* child process pid */ /* pty details */ int master; /* the master terminal fd*/ int slave; - unsigned char * tty; - unsigned char * term; + char * tty; + char * term; /* exit details */ struct exitinfo exit;
--- a/circbuffer.c Thu Mar 12 15:14:47 2015 +0300 +++ b/circbuffer.c Fri Jun 12 22:57:48 2015 +0800 @@ -67,23 +67,6 @@ } -unsigned int cbuf_readlen(circbuffer *cbuf) { - - dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size); - dropbear_assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size); - - if (cbuf->used == 0) { - TRACE(("cbuf_readlen: unused buffer")) - return 0; - } - - if (cbuf->readpos < cbuf->writepos) { - return cbuf->writepos - cbuf->readpos; - } - - return cbuf->size - cbuf->readpos; -} - unsigned int cbuf_writelen(circbuffer *cbuf) { dropbear_assert(cbuf->used <= cbuf->size); @@ -102,14 +85,6 @@ return cbuf->size - cbuf->writepos; } -unsigned char* cbuf_readptr(circbuffer *cbuf, unsigned int len) { - if (len > cbuf_readlen(cbuf)) { - dropbear_exit("Bad cbuf read"); - } - - return &cbuf->data[cbuf->readpos]; -} - void cbuf_readptrs(circbuffer *cbuf, unsigned char **p1, unsigned int *len1, unsigned char **p2, unsigned int *len2) { @@ -146,12 +121,6 @@ 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; cbuf->readpos = (cbuf->readpos + len) % cbuf->size;
--- a/circbuffer.h Thu Mar 12 15:14:47 2015 +0300 +++ b/circbuffer.h Fri Jun 12 22:57:48 2015 +0800 @@ -40,10 +40,9 @@ unsigned int cbuf_getused(circbuffer * cbuf); /* how much data stored */ unsigned int cbuf_getavail(circbuffer * cbuf); /* how much we can write */ -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); +/* returns pointers to the two portions of the circular buffer that can be read */ void cbuf_readptrs(circbuffer *cbuf, unsigned char **p1, unsigned int *len1, unsigned char **p2, unsigned int *len2);
--- a/cli-auth.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-auth.c Fri Jun 12 22:57:48 2015 +0800 @@ -43,9 +43,9 @@ TRACE(("enter cli_auth_getmethods")) CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); - buf_putstring(ses.writepayload, cli_opts.username, + buf_putstring(ses.writepayload, cli_opts.username, strlen(cli_opts.username)); - buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, + buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, SSH_SERVICE_CONNECTION_LEN); buf_putstring(ses.writepayload, "none", 4); /* 'none' method */ @@ -75,7 +75,7 @@ void recv_msg_userauth_banner() { - unsigned char* banner = NULL; + char* banner = NULL; unsigned int bannerlen; unsigned int i, linecount; @@ -151,8 +151,8 @@ void recv_msg_userauth_failure() { - unsigned char * methods = NULL; - unsigned char * tok = NULL; + char * methods = NULL; + char * tok = NULL; unsigned int methlen = 0; unsigned int partial = 0; unsigned int i = 0;
--- a/cli-authinteract.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-authinteract.c Fri Jun 12 22:57:48 2015 +0800 @@ -31,10 +31,10 @@ #ifdef ENABLE_CLI_INTERACT_AUTH -static unsigned char* get_response(unsigned char* prompt) +static char* get_response(char* prompt) { FILE* tty = NULL; - unsigned char* response = NULL; + char* response = NULL; /* not a password, but a reasonable limit */ char buf[DROPBEAR_MAX_CLI_PASS]; char* ret = NULL; @@ -50,13 +50,13 @@ } if (ret == NULL) { - response = (unsigned char*)m_strdup(""); + response = m_strdup(""); } else { unsigned int buflen = strlen(buf); /* fgets includes newlines */ if (buflen > 0 && buf[buflen-1] == '\n') buf[buflen-1] = '\0'; - response = (unsigned char*)m_strdup(buf); + response = m_strdup(buf); } m_burn(buf, sizeof(buf)); @@ -66,14 +66,14 @@ void recv_msg_userauth_info_request() { - unsigned char *name = NULL; - unsigned char *instruction = NULL; + char *name = NULL; + char *instruction = NULL; unsigned int num_prompts = 0; unsigned int i; - unsigned char *prompt = NULL; + char *prompt = NULL; unsigned int echo = 0; - unsigned char *response = NULL; + char *response = NULL; TRACE(("enter recv_msg_recv_userauth_info_request")) @@ -121,7 +121,7 @@ echo = buf_getbool(ses.payload); if (!echo) { - unsigned char* p = getpass_or_cancel(prompt); + char* p = getpass_or_cancel(prompt); response = m_strdup(p); m_burn(p, strlen(p)); } else { @@ -153,7 +153,7 @@ strlen(cli_opts.username)); /* service name */ - buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, + buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, SSH_SERVICE_CONNECTION_LEN); /* method */
--- a/cli-authpasswd.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-authpasswd.c Fri Jun 12 22:57:48 2015 +0800 @@ -143,10 +143,10 @@ buf_putstring(ses.writepayload, cli_opts.username, strlen(cli_opts.username)); - buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, + buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, SSH_SERVICE_CONNECTION_LEN); - buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD, + buf_putstring(ses.writepayload, AUTH_METHOD_PASSWORD, AUTH_METHOD_PASSWORD_LEN); buf_putbyte(ses.writepayload, 0); /* FALSE - so says the spec */
--- a/cli-authpubkey.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-authpubkey.c Fri Jun 12 22:57:48 2015 +0800 @@ -141,7 +141,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) { const char *algoname = NULL; - int algolen; + unsigned int algolen; buffer* sigbuf = NULL; TRACE(("enter send_msg_userauth_pubkey")) @@ -152,10 +152,10 @@ buf_putstring(ses.writepayload, cli_opts.username, strlen(cli_opts.username)); - buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, + buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, SSH_SERVICE_CONNECTION_LEN); - buf_putstring(ses.writepayload, AUTH_METHOD_PUBKEY, + buf_putstring(ses.writepayload, AUTH_METHOD_PUBKEY, AUTH_METHOD_PUBKEY_LEN); buf_putbyte(ses.writepayload, realsign);
--- a/cli-chansession.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-chansession.c Fri Jun 12 22:57:48 2015 +0800 @@ -56,7 +56,7 @@ static void cli_chansessreq(struct Channel *channel) { - unsigned char* type = NULL; + char* type = NULL; int wantreply; TRACE(("enter cli_chansessreq")) @@ -272,7 +272,7 @@ static void send_chansess_pty_req(struct Channel *channel) { - unsigned char* term = NULL; + char* term = NULL; TRACE(("enter send_chansess_pty_req")) @@ -305,7 +305,7 @@ static void send_chansess_shell_req(struct Channel *channel) { - unsigned char* reqtype = NULL; + char* reqtype = NULL; TRACE(("enter send_chansess_shell_req")) @@ -392,7 +392,7 @@ void cli_send_netcat_request() { - const unsigned char* source_host = "127.0.0.1"; + const char* source_host = "127.0.0.1"; const int source_port = 22; TRACE(("enter cli_send_netcat_request")) @@ -403,7 +403,7 @@ dropbear_exit("Couldn't open initial channel"); } - buf_putstring(ses.writepayload, cli_opts.netcat_host, + buf_putstring(ses.writepayload, cli_opts.netcat_host, strlen(cli_opts.netcat_host)); buf_putint(ses.writepayload, cli_opts.netcat_port);
--- a/cli-kex.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-kex.c Fri Jun 12 22:57:48 2015 +0800 @@ -79,7 +79,7 @@ } cli_ses.curve25519_param = gen_kexcurve25519_param(); } - buf_putstring(ses.writepayload, cli_ses.curve25519_param->pub, CURVE25519_LEN); + buf_putstring(ses.writepayload, (const char*)cli_ses.curve25519_param->pub, CURVE25519_LEN); #endif break; } @@ -322,7 +322,7 @@ } /* Compare hostnames */ - if (strncmp(cli_opts.remotehost, buf_getptr(line, hostlen), + if (strncmp(cli_opts.remotehost, (const char *) buf_getptr(line, hostlen), hostlen) != 0) { continue; } @@ -334,7 +334,7 @@ continue; } - if (strncmp(buf_getptr(line, algolen), algoname, algolen) != 0) { + if (strncmp((const char *) buf_getptr(line, algolen), algoname, algolen) != 0) { TRACE(("algo doesn't match")) continue; } @@ -346,7 +346,7 @@ } /* Now we're at the interesting hostkey */ - ret = cmp_base64_key(keyblob, keybloblen, algoname, algolen, + ret = cmp_base64_key(keyblob, keybloblen, (const unsigned char *) algoname, algolen, line, &fingerprint); if (ret == DROPBEAR_SUCCESS) { @@ -382,9 +382,9 @@ fseek(hostsfile, 0, SEEK_END); /* In case it wasn't opened append */ buf_setpos(line, 0); buf_setlen(line, 0); - buf_putbytes(line, cli_opts.remotehost, hostlen); + buf_putbytes(line, (const unsigned char *) cli_opts.remotehost, hostlen); buf_putbyte(line, ' '); - buf_putbytes(line, algoname, algolen); + buf_putbytes(line, (const unsigned char *) algoname, algolen); buf_putbyte(line, ' '); len = line->size - line->pos; /* The only failure with base64 is buffer_overflow, but buf_getwriteptr
--- a/cli-runopts.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-runopts.c Fri Jun 12 22:57:48 2015 +0800 @@ -447,7 +447,7 @@ } #endif -#ifdef DROPBEAR_DEFAULT_CLI_AUTHKEY +#if defined(DROPBEAR_DEFAULT_CLI_AUTHKEY) && defined(ENABLE_CLI_PUBKEY_AUTH) { char *expand_path = expand_tilde(DROPBEAR_DEFAULT_CLI_AUTHKEY); loadidentityfile(expand_path, 0); @@ -498,11 +498,14 @@ m_list_elem *iter; /* Fill out -i, -y, -W options that make sense for all * the intermediate processes */ +#ifdef ENABLE_CLI_PUBKEY_AUTH for (iter = cli_opts.privkeys->first; iter; iter = iter->next) { sign_key * key = (sign_key*)iter->item; len += 3 + strlen(key->filename); } +#endif /* ENABLE_CLI_PUBKEY_AUTH */ + len += 30; /* space for -W <size>, terminator. */ ret = m_malloc(len); total = 0; @@ -524,6 +527,7 @@ total += written; } +#ifdef ENABLE_CLI_PUBKEY_AUTH for (iter = cli_opts.privkeys->first; iter; iter = iter->next) { sign_key * key = (sign_key*)iter->item; @@ -532,6 +536,7 @@ dropbear_assert((unsigned int)written < size); total += written; } +#endif /* ENABLE_CLI_PUBKEY_AUTH */ /* if args were passed, total will be not zero, and it will have a space at the end, so remove that */ if (total > 0)
--- a/cli-session.c Thu Mar 12 15:14:47 2015 +0300 +++ b/cli-session.c Fri Jun 12 22:57:48 2015 +0800 @@ -124,6 +124,8 @@ /* Exchange identification */ send_session_identification(); + kexfirstinitialise(); /* initialise the kex state */ + send_msg_kexinit(); session_loop(cli_sessionloop); @@ -372,10 +374,10 @@ /* Operates in-place turning dirty (untrusted potentially containing control * characters) text into clean text. * Note: this is safe only with ascii - other charsets could have problems. */ -void cleantext(unsigned char* dirtytext) { +void cleantext(char* dirtytext) { unsigned int i, j; - unsigned char c; + char c; j = 0; for (i = 0; dirtytext[i] != '\0'; i++) {
--- a/common-algo.c Thu Mar 12 15:14:47 2015 +0300 +++ b/common-algo.c Fri Jun 12 22:57:48 2015 +0800 @@ -144,12 +144,15 @@ #ifdef DROPBEAR_AES256 {"aes256-ctr", 0, &dropbear_aes256, 1, &dropbear_mode_ctr}, #endif +#ifdef DROPBEAR_TWOFISH_CTR +/* twofish ctr is conditional as it hasn't been tested for interoperability, see options.h */ #ifdef DROPBEAR_TWOFISH256 {"twofish256-ctr", 0, &dropbear_twofish256, 1, &dropbear_mode_ctr}, #endif #ifdef DROPBEAR_TWOFISH128 {"twofish128-ctr", 0, &dropbear_twofish128, 1, &dropbear_mode_ctr}, #endif +#endif /* DROPBEAR_TWOFISH_CTR */ #endif /* DROPBEAR_ENABLE_CTR_MODE */ #ifdef DROPBEAR_ENABLE_CBC_MODE @@ -322,10 +325,10 @@ buf_putbyte(algolist, ','); donefirst = 1; len = strlen(localalgos[i].name); - buf_putbytes(algolist, localalgos[i].name, len); + buf_putbytes(algolist, (const unsigned char *) localalgos[i].name, len); } } - buf_putstring(buf, algolist->data, algolist->len); + buf_putstring(buf, (const char*)algolist->data, algolist->len); buf_free(algolist); } @@ -338,12 +341,12 @@ enum kexguess2_used *kexguess2, int *goodguess) { - unsigned char * algolist = NULL; - const unsigned char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO]; + char * algolist = NULL; + const char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO]; unsigned int len; unsigned int remotecount, localcount, clicount, servcount, i, j; algo_type * ret = NULL; - const unsigned char **clinames, **servnames; + const char **clinames, **servnames; if (goodguess) { *goodguess = 0; @@ -488,7 +491,7 @@ buf_setpos(b, b->len); buf_putbyte(b, '\0'); buf_setpos(b, 4); - ret_list = m_strdup(buf_getptr(b, b->len - b->pos)); + ret_list = m_strdup((const char *) buf_getptr(b, b->len - b->pos)); buf_free(b); return ret_list; }
--- a/common-channel.c Thu Mar 12 15:14:47 2015 +0300 +++ b/common-channel.c Fri Jun 12 22:57:48 2015 +0800 @@ -38,7 +38,7 @@ #include "netio.h" static void send_msg_channel_open_failure(unsigned int remotechan, int reason, - const unsigned char *text, const unsigned char *lang); + const char *text, const char *lang); static void send_msg_channel_open_confirmation(struct Channel* channel, unsigned int recvwindow, unsigned int recvmaxpacket); @@ -434,10 +434,36 @@ TRACE(("leave send_msg_channel_eof")) } -/* Called to write data out to the local side of the channel. - 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, +#ifndef HAVE_WRITEV +static void writechannel_fallback(struct Channel* channel, int fd, circbuffer *cbuf, + const unsigned char *UNUSED(moredata), unsigned int *morelen) { + + unsigned char *circ_p1, *circ_p2; + unsigned int circ_len1, circ_len2; + ssize_t written; + + if (morelen) { + /* fallback doesn't consume moredata */ + *morelen = 0; + } + + /* Write the first portion of the circular buffer */ + cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2); + written = write(fd, circ_p1, circ_len1); + if (written < 0) { + if (errno != EINTR && errno != EAGAIN) { + TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) + close_chan_fd(channel, fd, SHUT_WR); + } + } else { + cbuf_incrread(cbuf, written); + channel->recvdonelen += written; + } +} +#endif /* !HAVE_WRITEV */ + +#ifdef HAVE_WRITEV +static void writechannel_writev(struct Channel* channel, int fd, circbuffer *cbuf, const unsigned char *moredata, unsigned int *morelen) { struct iovec iov[3]; @@ -445,9 +471,7 @@ unsigned int circ_len1, circ_len2; int io_count = 0; - int written; - - TRACE(("enter writechannel fd %d", fd)) + ssize_t written; cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2); @@ -473,6 +497,14 @@ io_count++; } + if (io_count == 0) { + /* writechannel may sometimes be called twice in a main loop iteration. + From common_recv_msg_channel_data() then channelio(). + The second call may not have any data to write, so we just return. */ + TRACE(("leave writechannel, no data")) + return; + } + if (morelen) { /* Default return value, none consumed */ *morelen = 0; @@ -482,7 +514,7 @@ if (written < 0) { if (errno != EINTR && errno != EAGAIN) { - TRACE(("errno %d len %d", errno, len)) + TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) close_chan_fd(channel, fd, SHUT_WR); } } else { @@ -494,24 +526,19 @@ channel->recvdonelen += written; } -#if 0 - - maxlen = cbuf_readlen(cbuf); +} +#endif /* HAVE_WRITEV */ - /* Write the data out */ - len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen); - if (len <= 0) { - TRACE(("errno %d len %d", errno, len)) - if (len < 0 && errno != EINTR) { - close_chan_fd(channel, fd, SHUT_WR); - } - TRACE(("leave writechannel: len <= 0")) - return; - } - TRACE(("writechannel wrote %d", len)) - - cbuf_incrread(cbuf, len); - channel->recvdonelen += len; +/* Called to write data out to the local side of the channel. + 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) { + TRACE(("enter writechannel fd %d", fd)) +#ifdef HAVE_WRITEV + writechannel_writev(channel, fd, cbuf, moredata, morelen); +#else + writechannel_fallback(channel, fd, cbuf, moredata, morelen); #endif /* Window adjust handling */ @@ -529,9 +556,10 @@ TRACE(("leave writechannel")) } + /* Set the file descriptors for the main select in session.c * This avoid channels which don't have any window available, are closed, etc*/ -void setchannelfds(fd_set *readfds, fd_set *writefds) { +void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads) { unsigned int i; struct Channel * channel; @@ -549,7 +577,7 @@ FD if there's the possibility of "~."" to kill an interactive session (the read_mangler) */ if (channel->transwindow > 0 - && (ses.dataallowed || channel->read_mangler)) { + && ((ses.dataallowed && allow_reads) || channel->read_mangler)) { if (channel->readfd >= 0) { FD_SET(channel->readfd, readfds); @@ -830,6 +858,7 @@ channel->recvwindow -= datalen; dropbear_assert(channel->recvwindow <= opts.recv_window); + /* Attempt to write the data immediately without having to put it in the circular buffer */ consumed = datalen; writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed); @@ -892,7 +921,7 @@ /* Handle a new channel request, performing any channel-type-specific setup */ void recv_msg_channel_open() { - unsigned char *type; + char *type; unsigned int typelen; unsigned int remotechan, transwindow, transmaxpacket; struct Channel *channel; @@ -1010,7 +1039,7 @@ /* Send a channel open failure message, with a corresponding reason * code (usually resource shortage or unknown chan type) */ static void send_msg_channel_open_failure(unsigned int remotechan, - int reason, const unsigned char *text, const unsigned char *lang) { + int reason, const char *text, const char *lang) { TRACE(("enter send_msg_channel_open_failure")) CHECKCLEARTOWRITE(); @@ -1018,8 +1047,8 @@ buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE); buf_putint(ses.writepayload, remotechan); buf_putint(ses.writepayload, reason); - buf_putstring(ses.writepayload, text, strlen((char*)text)); - buf_putstring(ses.writepayload, lang, strlen((char*)lang)); + buf_putstring(ses.writepayload, text, strlen(text)); + buf_putstring(ses.writepayload, lang, strlen(lang)); encrypt_packet(); TRACE(("leave send_msg_channel_open_failure")) @@ -1215,7 +1244,7 @@ } void start_send_channel_request(struct Channel *channel, - unsigned char *type) { + char *type) { CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
--- a/common-kex.c Thu Mar 12 15:14:47 2015 +0300 +++ b/common-kex.c Fri Jun 12 22:57:48 2015 +0800 @@ -511,7 +511,7 @@ /* start the kex hash */ local_ident_len = strlen(LOCAL_IDENT); - remote_ident_len = strlen((char*)ses.remoteident); + remote_ident_len = strlen(ses.remoteident); kexhashbuf_len = local_ident_len + remote_ident_len + ses.transkexinit->len + ses.payload->len @@ -525,18 +525,17 @@ read_kex_algos(); /* V_C, the client's version string (CR and NL excluded) */ - buf_putstring(ses.kexhashbuf, - (unsigned char*)LOCAL_IDENT, local_ident_len); + buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len); /* V_S, the server's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); /* I_C, the payload of the client's SSH_MSG_KEXINIT */ buf_putstring(ses.kexhashbuf, - ses.transkexinit->data, ses.transkexinit->len); + (const char*)ses.transkexinit->data, ses.transkexinit->len); /* I_S, the payload of the server's SSH_MSG_KEXINIT */ buf_setpos(ses.payload, ses.payload_beginning); buf_putstring(ses.kexhashbuf, - buf_getptr(ses.payload, ses.payload->len-ses.payload->pos), + (const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos), ses.payload->len-ses.payload->pos); ses.requirenext = SSH_MSG_KEXDH_REPLY; } else { @@ -547,18 +546,17 @@ /* V_C, the client's version string (CR and NL excluded) */ buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); /* V_S, the server's version string (CR and NL excluded) */ - buf_putstring(ses.kexhashbuf, - (unsigned char*)LOCAL_IDENT, local_ident_len); + buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len); /* I_C, the payload of the client's SSH_MSG_KEXINIT */ buf_setpos(ses.payload, ses.payload_beginning); buf_putstring(ses.kexhashbuf, - buf_getptr(ses.payload, ses.payload->len-ses.payload->pos), + (const char*)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, - ses.transkexinit->data, ses.transkexinit->len); + (const char*)ses.transkexinit->data, ses.transkexinit->len); ses.requirenext = SSH_MSG_KEXDH_INIT; } @@ -783,9 +781,9 @@ /* K_S, the host key */ buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); /* Q_C, client's ephemeral public key octet string */ - buf_putstring(ses.kexhashbuf, Q_C, CURVE25519_LEN); + buf_putstring(ses.kexhashbuf, (const char*)Q_C, CURVE25519_LEN); /* Q_S, server's ephemeral public key octet string */ - buf_putstring(ses.kexhashbuf, Q_S, CURVE25519_LEN); + buf_putstring(ses.kexhashbuf, (const char*)Q_S, CURVE25519_LEN); /* K, the shared secret */ buf_putmpint(ses.kexhashbuf, ses.dh_K);
--- a/common-session.c Thu Mar 12 15:14:47 2015 +0300 +++ b/common-session.c Fri Jun 12 22:57:48 2015 +0800 @@ -1,7 +1,7 @@ /* * Dropbear - a SSH2 server * - * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) Matt Johnston * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -64,6 +64,13 @@ ses.sock_out = sock_out; ses.maxfd = MAX(sock_in, sock_out); + if (sock_in >= 0) { + setnonblocking(sock_in); + } + if (sock_out >= 0) { + setnonblocking(sock_out); + } + ses.socket_prio = DROPBEAR_PRIO_DEFAULT; /* Sets it to lowdelay */ update_channel_prio(); @@ -83,8 +90,6 @@ ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[0]); ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[1]); - kexfirstinitialise(); /* initialise the kex state */ - ses.writepayload = buf_new(TRANS_MAX_PAYLOAD_LEN); ses.transseq = 0; @@ -145,6 +150,7 @@ /* main loop, select()s for all sockets in use */ for(;;) { + const int writequeue_has_space = (ses.writequeue_len <= 2*TRANS_MAX_PAYLOAD_LEN); timeout.tv_sec = select_timeout(); timeout.tv_usec = 0; @@ -155,8 +161,12 @@ /* 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))) { + read for the remote ident. + We also avoid reading from the socket if the writequeue is full, that avoids + replies backing up */ + if (ses.sock_in != -1 + && (ses.remoteident || isempty(&ses.writequeue)) + && writequeue_has_space) { FD_SET(ses.sock_in, &readfd); } if (ses.sock_out != -1 && !isempty(&ses.writequeue)) { @@ -168,7 +178,7 @@ FD_SET(ses.signal_pipe[0], &readfd); /* set up for channels which can be read/written */ - setchannelfds(&readfd, &writefd); + setchannelfds(&readfd, &writefd, writequeue_has_space); /* Pending connections to test */ set_connect_fds(&writefd); @@ -268,7 +278,7 @@ return; } - /* Beware of changing order of functions here. */ + /* BEWARE of changing order of functions here. */ /* Must be before extra_session_cleanup() */ chancleanup(); @@ -277,7 +287,7 @@ ses.extra_session_cleanup(); } - /* After these are freed most functions will exit */ + /* After these are freed most functions will fail */ #ifdef DROPBEAR_CLEANUP /* listeners call cleanup functions, this should occur before other session state is freed. */ @@ -317,10 +327,8 @@ void send_session_identification() { buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1); - buf_putbytes(writebuf, LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); - buf_putbyte(writebuf, 0x0); /* packet type */ - buf_setpos(writebuf, 0); - enqueue(&ses.writequeue, writebuf); + buf_putbytes(writebuf, (const unsigned char *) LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); + writebuf_enqueue(writebuf, 0); } static void read_session_identification() {
--- a/configure.ac Thu Mar 12 15:14:47 2015 +0300 +++ b/configure.ac Fri Jun 12 22:57:48 2015 +0800 @@ -265,7 +265,7 @@ #include <sys/types.h> #include <sys/socket.h> ]], - [[ struct sockaddr_storage s; ]])], + [[ if (sizeof(struct sockaddr_storage)) return 0 ]])], [ ac_cv_have_struct_sockaddr_storage="yes" ], [ ac_cv_have_struct_sockaddr_storage="no" ] ) @@ -279,7 +279,7 @@ #include <sys/types.h> #include <netinet/in.h> ]], - [[ struct sockaddr_in6 s; s.sin6_family = 0; ]])], + [[ if (sizeof(struct sockaddr_in6)) return 0 ]])], [ ac_cv_have_struct_sockaddr_in6="yes" ], [ ac_cv_have_struct_sockaddr_in6="no" ] ) @@ -293,7 +293,7 @@ #include <sys/types.h> #include <netinet/in.h> ]], - [[ struct in6_addr s; s.s6_addr[0] = 0; ]])], + [[ if (sizeof(struct in6_addr)) return 0 ]])], [ ac_cv_have_struct_in6_addr="yes" ], [ ac_cv_have_struct_in6_addr="no" ] ) @@ -308,7 +308,7 @@ #include <sys/socket.h> #include <netdb.h> ]], - [[ struct addrinfo s; s.ai_flags = AI_PASSIVE; ]])], + [[ if (sizeof(struct addrinfo)) return 0 ]])], [ ac_cv_have_struct_addrinfo="yes" ], [ ac_cv_have_struct_addrinfo="no" ] )
--- a/dbrandom.c Thu Mar 12 15:14:47 2015 +0300 +++ b/dbrandom.c Fri Jun 12 22:57:48 2015 +0800 @@ -141,7 +141,7 @@ return ret; } -void addrandom(char * buf, unsigned int len) +void addrandom(unsigned char * buf, unsigned int len) { hash_state hs;
--- a/dbrandom.h Thu Mar 12 15:14:47 2015 +0300 +++ b/dbrandom.h Fri Jun 12 22:57:48 2015 +0800 @@ -29,7 +29,7 @@ void seedrandom(); void genrandom(unsigned char* buf, unsigned int len); -void addrandom(char * buf, unsigned int len); +void addrandom(unsigned char * buf, unsigned int len); void gen_random_mpint(mp_int *max, mp_int *rand); #endif /* DROPBEAR_RANDOM_H_ */
--- a/dss.c Thu Mar 12 15:14:47 2015 +0300 +++ b/dss.c Fri Jun 12 22:57:48 2015 +0800 @@ -165,7 +165,7 @@ DEF_MP_INT(val3); DEF_MP_INT(val4); char * string = NULL; - int stringlen; + unsigned int stringlen; TRACE(("enter buf_dss_verify")) dropbear_assert(key != NULL); @@ -186,7 +186,7 @@ /* create the signature - s' and r' are the received signatures in buf */ /* w = (s')-1 mod q */ /* let val1 = s' */ - bytes_to_mp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE); + bytes_to_mp(&val1, (const unsigned char*) &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE); if (mp_cmp(&val1, key->q) != MP_LT) { TRACE(("verify failed, s' >= q")) @@ -208,7 +208,7 @@ /* u2 = ((r')w) mod q */ /* let val1 = r' */ - bytes_to_mp(&val1, &string[0], SHA1_HASH_SIZE); + bytes_to_mp(&val1, (const unsigned char*) &string[0], SHA1_HASH_SIZE); if (mp_cmp(&val1, key->q) != MP_LT) { TRACE(("verify failed, r' >= q")) goto out;
--- a/ecc.h Thu Mar 12 15:14:47 2015 +0300 +++ b/ecc.h Fri Jun 12 22:57:48 2015 +0800 @@ -12,7 +12,7 @@ int ltc_size; /* to match the byte sizes in ltc_ecc_sets[] */ const ltc_ecc_set_type *dp; /* curve domain parameters */ const struct ltc_hash_descriptor *hash_desc; - const unsigned char *name; + const char *name; }; extern struct dropbear_ecc_curve ecc_curve_nistp256;
--- a/ecdsa.c Thu Mar 12 15:14:47 2015 +0300 +++ b/ecdsa.c Fri Jun 12 22:57:48 2015 +0800 @@ -83,9 +83,9 @@ ecc_key *new_key = NULL; /* string "ecdsa-sha2-[identifier]" */ - key_ident = buf_getstring(buf, &key_ident_len); + key_ident = (unsigned char*)buf_getstring(buf, &key_ident_len); /* string "[identifier]" */ - identifier = buf_getstring(buf, &identifier_len); + identifier = (unsigned char*)buf_getstring(buf, &identifier_len); if (key_ident_len != identifier_len + strlen("ecdsa-sha2-")) { TRACE(("Bad identifier lengths")) @@ -140,10 +140,10 @@ void buf_put_ecdsa_pub_key(buffer *buf, ecc_key *key) { struct dropbear_ecc_curve *curve = NULL; - unsigned char key_ident[30]; + char key_ident[30]; curve = curve_for_dp(key->dp); - snprintf((char*)key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name); + snprintf(key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name); buf_putstring(buf, key_ident, strlen(key_ident)); buf_putstring(buf, curve->name, strlen(curve->name)); buf_put_ecc_raw_pubkey_string(buf, key); @@ -161,7 +161,7 @@ hash_state hs; unsigned char hash[64]; void *e = NULL, *p = NULL, *s = NULL, *r; - unsigned char key_ident[30]; + char key_ident[30]; buffer *sigbuf = NULL; TRACE(("buf_put_ecdsa_sign")) @@ -222,7 +222,7 @@ } } - snprintf((char*)key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name); + snprintf(key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name); buf_putstring(buf, key_ident, strlen(key_ident)); /* enough for nistp521 */ sigbuf = buf_new(200);
--- a/gendss.c Thu Mar 12 15:14:47 2015 +0300 +++ b/gendss.c Fri Jun 12 22:57:48 2015 +0800 @@ -67,7 +67,7 @@ static void getq(dropbear_dss_key *key) { - char buf[QSIZE]; + unsigned char buf[QSIZE]; /* 160 bit prime */ genrandom(buf, QSIZE);
--- a/keyimport.c Thu Mar 12 15:14:47 2015 +0300 +++ b/keyimport.c Fri Jun 12 22:57:48 2015 +0800 @@ -193,7 +193,7 @@ static void base64_encode_fp(FILE * fp, unsigned char *data, int datalen, int cpl) { - char out[100]; + unsigned char out[100]; int n; unsigned long outlen; int rawcpl; @@ -445,7 +445,7 @@ ret->keyblob_size); } outlen = ret->keyblob_size - ret->keyblob_len; - if (base64_decode(buffer, len, + if (base64_decode((const unsigned char *)buffer, len, ret->keyblob + ret->keyblob_len, &outlen) != CRYPT_OK){ errmsg = "Error decoding base64"; goto error; @@ -507,7 +507,7 @@ int i, num_integers = 0; sign_key *retval = NULL; char *errmsg; - char *modptr = NULL; + unsigned char *modptr = NULL; int modlen = -9999; enum signkey_type type; @@ -646,12 +646,12 @@ */ if (i == 1) { /* Save the details for after we deal with number 2. */ - modptr = (char *)p; + modptr = p; modlen = len; } else if (i >= 2 && i <= 5) { - buf_putstring(blobbuf, p, len); + buf_putstring(blobbuf, (const char*)p, len); if (i == 2) { - buf_putstring(blobbuf, modptr, modlen); + buf_putstring(blobbuf, (const char*)modptr, modlen); } } } else if (key->type == OSSH_DSA) { @@ -659,7 +659,7 @@ * OpenSSH key order is p, q, g, y, x, * we want the same. */ - buf_putstring(blobbuf, p, len); + buf_putstring(blobbuf, (const char*)p, len); } /* Skip past the number. */ @@ -1043,7 +1043,7 @@ int curve_oid_len = 0; const void* curve_oid = NULL; unsigned long pubkey_size = 2*curve_size+1; - unsigned int k_size; + int k_size; int err = 0; /* version. less than 10 bytes */
--- a/libtomcrypt/src/ciphers/aes/aes.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/ciphers/aes/aes.c Fri Jun 12 22:57:48 2015 +0800 @@ -122,9 +122,10 @@ */ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { - int i, j; + int i; ulong32 temp, *rk; #ifndef ENCRYPT_ONLY + int j; ulong32 *rrk; #endif LTC_ARGCHK(key != NULL); @@ -148,7 +149,9 @@ LOAD32H(rk[2], key + 8); LOAD32H(rk[3], key + 12); if (keylen == 16) { + #ifndef ENCRYPT_ONLY j = 44; + #endif for (;;) { temp = rk[3]; rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; @@ -161,7 +164,9 @@ rk += 4; } } else if (keylen == 24) { + #ifndef ENCRYPT_ONLY j = 52; + #endif LOAD32H(rk[4], key + 16); LOAD32H(rk[5], key + 20); for (;;) { @@ -182,7 +187,9 @@ rk += 6; } } else if (keylen == 32) { + #ifndef ENCRYPT_ONLY j = 60; + #endif LOAD32H(rk[4], key + 16); LOAD32H(rk[5], key + 20); LOAD32H(rk[6], key + 24); @@ -728,6 +735,7 @@ */ void ECB_DONE(symmetric_key *skey) { + (void)skey; }
--- a/libtomcrypt/src/ciphers/des.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/ciphers/des.c Fri Jun 12 22:57:48 2015 +0800 @@ -1871,6 +1871,7 @@ */ void des3_done(symmetric_key *skey) { + (void)skey; }
--- a/libtomcrypt/src/ciphers/twofish/twofish.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/ciphers/twofish/twofish.c Fri Jun 12 22:57:48 2015 +0800 @@ -684,6 +684,7 @@ */ void twofish_done(symmetric_key *skey) { + (void)skey; } /**
--- a/libtomcrypt/src/hashes/helper/hash_file.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/hashes/helper/hash_file.c Fri Jun 12 22:57:48 2015 +0800 @@ -25,6 +25,7 @@ int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + (void)hash; (void)fname; (void)out; (void)outlen; return CRYPT_NOP; #else FILE *in;
--- a/libtomcrypt/src/hashes/helper/hash_filehandle.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/hashes/helper/hash_filehandle.c Fri Jun 12 22:57:48 2015 +0800 @@ -26,6 +26,7 @@ int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + (void)hash; (void)in; (void)out; (void)outlen; return CRYPT_NOP; #else hash_state md;
--- a/libtomcrypt/src/mac/hmac/hmac_file.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/mac/hmac/hmac_file.c Fri Jun 12 22:57:48 2015 +0800 @@ -32,6 +32,7 @@ unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE + (void)hash; (void)fname; (void)key; (void)keylen; (void)out; (void)outlen; return CRYPT_NOP; #else hmac_state hmac;
--- a/libtomcrypt/src/misc/crypt/crypt_argchk.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/misc/crypt/crypt_argchk.c Fri Jun 12 22:57:48 2015 +0800 @@ -21,7 +21,7 @@ { fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", v, d, s); - (void)raise(SIGABRT); + abort(); } #endif
--- a/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c Thu Mar 12 15:14:47 2015 +0300 +++ b/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c Fri Jun 12 22:57:48 2015 +0800 @@ -40,7 +40,7 @@ int i, j, err; void *mu, *mp; unsigned long buf; - int first, bitbuf, bitcpy, bitcnt, mode, digidx; + int bitcnt, mode, digidx; LTC_ARGCHK(k != NULL); LTC_ARGCHK(G != NULL); @@ -98,8 +98,6 @@ bitcnt = 1; buf = 0; digidx = mp_get_digit_count(k) - 1; - bitcpy = bitbuf = 0; - first = 1; /* perform ops */ for (;;) {
--- a/netio.c Thu Mar 12 15:14:47 2015 +0300 +++ b/netio.c Fri Jun 12 22:57:48 2015 +0800 @@ -70,13 +70,13 @@ struct addrinfo *r; int res = 0; int fastopen = 0; -#ifdef DROPBEAR_TCP_FAST_OPEN +#ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN struct msghdr message; #endif for (r = c->res_iter; r; r = r->ai_next) { - assert(c->sock == -1); + dropbear_assert(c->sock == -1); c->sock = socket(c->res_iter->ai_family, c->res_iter->ai_socktype, c->res_iter->ai_protocol); if (c->sock < 0) { @@ -91,31 +91,36 @@ set_piggyback_ack(c->sock); #endif -#ifdef DROPBEAR_TCP_FAST_OPEN +#ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN fastopen = (c->writequeue != NULL); - memset(&message, 0x0, sizeof(message)); - message.msg_name = r->ai_addr; - message.msg_namelen = r->ai_addrlen; - - if (c->writequeue) { - int iovlen; /* Linux msg_iovlen is a size_t */ - message.msg_iov = packet_queue_to_iovec(c->writequeue, &iovlen); + if (fastopen) { + memset(&message, 0x0, sizeof(message)); + message.msg_name = r->ai_addr; + message.msg_namelen = r->ai_addrlen; + /* 6 is arbitrary, enough to hold initial packets */ + unsigned int iovlen = 6; /* Linux msg_iovlen is a size_t */ + struct iovec iov[6]; + packet_queue_to_iovec(c->writequeue, iov, &iovlen); + message.msg_iov = iov; message.msg_iovlen = iovlen; res = sendmsg(c->sock, &message, MSG_FASTOPEN); - if (res < 0 && errno != EINPROGRESS) { - m_free(c->errstring); - c->errstring = m_strdup(strerror(errno)); - /* Not entirely sure which kind of errors are normal - 2.6.32 seems to - return EPIPE for any (nonblocking?) sendmsg(). just fall back */ - TRACE(("sendmsg tcp_fastopen failed, falling back. %s", strerror(errno))); - /* No kernel MSG_FASTOPEN support. Fall back below */ - fastopen = 0; - /* Set to NULL to avoid trying again */ - c->writequeue = NULL; + /* Returns EINPROGRESS if FASTOPEN wasn't available */ + if (res < 0) { + if (errno != EINPROGRESS) { + m_free(c->errstring); + c->errstring = m_strdup(strerror(errno)); + /* Not entirely sure which kind of errors are normal - 2.6.32 seems to + return EPIPE for any (nonblocking?) sendmsg(). just fall back */ + TRACE(("sendmsg tcp_fastopen failed, falling back. %s", strerror(errno))); + /* No kernel MSG_FASTOPEN support. Fall back below */ + fastopen = 0; + /* Set to NULL to avoid trying again */ + c->writequeue = NULL; + } + } else { + packet_queue_consume(c->writequeue, res); } - m_free(message.msg_iov); - packet_queue_consume(c->writequeue, res); } #endif @@ -163,7 +168,7 @@ memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; - hints.ai_family = PF_UNSPEC; + hints.ai_family = AF_UNSPEC; err = getaddrinfo(remotehost, remoteport, &hints, &c->res); if (err) { @@ -258,8 +263,7 @@ c->writequeue = writequeue; } -struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) { - struct iovec *iov = NULL; +void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count) { struct Link *l; unsigned int i; int len; @@ -269,10 +273,9 @@ #define IOV_MAX UIO_MAXIOV #endif - *ret_iov_count = MIN(queue->count, IOV_MAX); + *iov_count = MIN(MIN(queue->count, IOV_MAX), *iov_count); - iov = m_malloc(sizeof(*iov) * *ret_iov_count); - for (l = queue->head, i = 0; l; l = l->link, i++) + for (l = queue->head, i = 0; i < *iov_count; l = l->link, i++) { writebuf = (buffer*)l->item; len = writebuf->len - 1 - writebuf->pos; @@ -282,8 +285,6 @@ iov[i].iov_base = buf_getptr(writebuf, len); iov[i].iov_len = len; } - - return iov; } void packet_queue_consume(struct Queue *queue, ssize_t written) { @@ -312,7 +313,7 @@ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); } -#ifdef DROPBEAR_TCP_FAST_OPEN +#ifdef DROPBEAR_SERVER_TCP_FAST_OPEN void set_listen_fast_open(int sock) { int qlen = MAX(MAX_UNAUTH_PER_IP, 5); if (setsockopt(sock, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) != 0) {
--- a/netio.h Thu Mar 12 15:14:47 2015 +0300 +++ b/netio.h Fri Jun 12 22:57:48 2015 +0800 @@ -44,10 +44,11 @@ void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue); /* TODO: writev #ifdef guard */ -struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count); +/* Fills out iov which contains iov_count slots, returning the number filled in iov_count */ +void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count); void packet_queue_consume(struct Queue *queue, ssize_t written); -#ifdef DROPBEAR_TCP_FAST_OPEN +#ifdef DROPBEAR_SERVER_TCP_FAST_OPEN /* Try for any Linux builds, will fall back if the kernel doesn't support it */ void set_listen_fast_open(int sock); /* Define values which may be supported by the kernel even if the libc is too old */
--- a/options.h Thu Mar 12 15:14:47 2015 +0300 +++ b/options.h Fri Jun 12 22:57:48 2015 +0800 @@ -103,10 +103,15 @@ #define DROPBEAR_ENABLE_CBC_MODE /* Enable "Counter Mode" for ciphers. This is more secure than normal - * CBC mode against certain attacks. This adds around 1kB to binary - * size and is recommended for most cases */ + * CBC mode against certain attacks. It is recommended for security + * and forwards compatibility */ #define DROPBEAR_ENABLE_CTR_MODE +/* Twofish counter mode is disabled by default because it +has not been tested for interoperability with other SSH implementations. +If you test it please contact the Dropbear author */ +/* #define DROPBEAR_TWOFISH_CTR */ + /* You can compile with no encryption if you want. In some circumstances * this could be safe security-wise, though make sure you know what * you're doing. Anyone can see everything that goes over the wire, so
--- a/packet.c Thu Mar 12 15:14:47 2015 +0300 +++ b/packet.c Fri Jun 12 22:57:48 2015 +0800 @@ -58,8 +58,13 @@ ssize_t written; #ifdef HAVE_WRITEV - struct iovec *iov = NULL; - int iov_count; + /* 50 is somewhat arbitrary */ + unsigned int iov_count = 50; + struct iovec iov[50]; +#else + int len; + buffer* writebuf; + int packet_type; #endif TRACE2(("enter write_packet")) @@ -67,7 +72,7 @@ #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV)) - iov = packet_queue_to_iovec(&ses.writequeue, &iov_count); + packet_queue_to_iovec(&ses.writequeue, iov, &iov_count); /* This may return EAGAIN. The main loop sometimes calls write_packet() without bothering to test with select() since it's likely to be necessary */ @@ -75,15 +80,14 @@ if (written < 0) { if (errno == EINTR || errno == EAGAIN) { TRACE2(("leave write_packet: EINTR")) - m_free(iov); return; } else { dropbear_exit("Error writing: %s", strerror(errno)); } } - m_free(iov); packet_queue_consume(&ses.writequeue, written); + ses.writequeue_len -= written; if (written == 0) { ses.remoteclosed(); @@ -97,6 +101,8 @@ * a cleartext packet_type indicator */ packet_type = writebuf->data[writebuf->len-1]; len = writebuf->len - 1 - writebuf->pos; + TRACE2(("write_packet type %d len %d/%d", packet_type, + len, writebuf->len-1)) dropbear_assert(len > 0); /* Try to write as much as possible */ written = write(ses.sock_out, buf_getptr(writebuf, len), len); @@ -114,6 +120,8 @@ ses.remoteclosed(); } + ses.writequeue_len -= written; + if (written == len) { /* We've finished with the packet, free it */ dequeue(&ses.writequeue); @@ -571,15 +579,12 @@ /* stick the MAC on it */ buf_putbytes(writebuf, mac_bytes, mac_size); - /* The last byte of the buffer stores the cleartext packet_type. It is not - * transmitted but is used for transmit timeout purposes */ - buf_putbyte(writebuf, packet_type); - /* enqueue the packet for sending. It will get freed after transmission. */ - buf_setpos(writebuf, 0); - enqueue(&ses.writequeue, (void*)writebuf); + /* Update counts */ + ses.kexstate.datatrans += writebuf->len; + + writebuf_enqueue(writebuf, packet_type); /* Update counts */ - ses.kexstate.datatrans += writebuf->len; ses.transseq++; now = monotonic_now(); @@ -597,6 +602,16 @@ TRACE2(("leave encrypt_packet()")) } +void writebuf_enqueue(buffer * writebuf, unsigned char packet_type) { + /* The last byte of the buffer stores the cleartext packet_type. It is not + * transmitted but is used for transmit timeout purposes */ + buf_putbyte(writebuf, packet_type); + /* enqueue the packet for sending. It will get freed after transmission. */ + buf_setpos(writebuf, 0); + enqueue(&ses.writequeue, (void*)writebuf); + ses.writequeue_len += writebuf->len-1; +} + /* Create the packet mac, and append H(seqno|clearbuf) to the output */ /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */
--- a/packet.h Thu Mar 12 15:14:47 2015 +0300 +++ b/packet.h Fri Jun 12 22:57:48 2015 +0800 @@ -28,12 +28,15 @@ #include "includes.h" #include "queue.h" +#include "buffer.h" void write_packet(); void read_packet(); void decrypt_packet(); void encrypt_packet(); +void writebuf_enqueue(buffer * writebuf, unsigned char packet_type); + void process_packet(); void maybe_flush_reply_queue();
--- a/session.h Thu Mar 12 15:14:47 2015 +0300 +++ b/session.h Fri Jun 12 22:57:48 2015 +0800 @@ -63,7 +63,7 @@ /* Client */ void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection *progress) ATTRIB_NORETURN; void cli_connected(int result, int sock, void* userdata, const char *errstring); -void cleantext(unsigned char* dirtytext); +void cleantext(char* dirtytext); /* crypto parameters that are stored individually for transmit and receive */ struct key_context_directional { @@ -115,7 +115,7 @@ /* remotehost will be initially NULL as we delay * reading the remote version string. it will be set * by the time any recv_() packet methods are called */ - unsigned char *remoteident; + char *remoteident; int maxfd; /* the maximum file descriptor to check with select() */ @@ -125,6 +125,7 @@ throughout the code, as handlers fill out this buffer with the packet to send. */ struct Queue writequeue; /* A queue of encrypted packets to send */ + unsigned int writequeue_len; /* Number of bytes pending to send in writequeue */ buffer *readbuf; /* From the wire, decrypted in-place */ buffer *payload; /* Post-decompression, the actual SSH packet. May have extra data at the beginning, will be
--- a/signkey.c Thu Mar 12 15:14:47 2015 +0300 +++ b/signkey.c Fri Jun 12 22:57:48 2015 +0800 @@ -138,7 +138,7 @@ * on return is set to the type read (useful when type = _ANY) */ int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) { - unsigned char* ident; + char *ident; unsigned int len; enum signkey_type keytype; int ret = DROPBEAR_FAILURE; @@ -209,7 +209,7 @@ * on return is set to the type read (useful when type = _ANY) */ int buf_get_priv_key(buffer *buf, sign_key *key, enum signkey_type *type) { - unsigned char* ident; + char *ident; unsigned int len; enum signkey_type keytype; int ret = DROPBEAR_FAILURE; @@ -515,7 +515,7 @@ * signature blob */ int buf_verify(buffer * buf, sign_key *key, buffer *data_buf) { - unsigned char * type_name = NULL; + char *type_name = NULL; unsigned int type_name_len = 0; enum signkey_type type;
--- a/svr-auth.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-auth.c Fri Jun 12 22:57:48 2015 +0800 @@ -36,7 +36,7 @@ #include "dbrandom.h" static void authclear(); -static int checkusername(unsigned char *username, unsigned int userlen); +static int checkusername(char *username, unsigned int userlen); /* initialise the first time for a session, resetting all parameters */ void svr_authinitialise() { @@ -100,7 +100,7 @@ * checking, and handle success or failure */ void recv_msg_userauth_request() { - unsigned char *username = NULL, *servicename = NULL, *methodname = NULL; + char *username = NULL, *servicename = NULL, *methodname = NULL; unsigned int userlen, servicelen, methodlen; int valid_user = 0; @@ -227,7 +227,7 @@ /* Check that the username exists and isn't disallowed (root), and has a valid shell. * returns DROPBEAR_SUCCESS on valid username, DROPBEAR_FAILURE on failure */ -static int checkusername(unsigned char *username, unsigned int userlen) { +static int checkusername(char *username, unsigned int userlen) { char* listshell = NULL; char* usershell = NULL; @@ -333,14 +333,14 @@ typebuf = buf_new(30); /* long enough for PUBKEY and PASSWORD */ if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) { - buf_putbytes(typebuf, AUTH_METHOD_PUBKEY, AUTH_METHOD_PUBKEY_LEN); + buf_putbytes(typebuf, (const unsigned char *)AUTH_METHOD_PUBKEY, AUTH_METHOD_PUBKEY_LEN); if (ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { buf_putbyte(typebuf, ','); } } if (ses.authstate.authtypes & AUTH_TYPE_PASSWORD) { - buf_putbytes(typebuf, AUTH_METHOD_PASSWORD, AUTH_METHOD_PASSWORD_LEN); + buf_putbytes(typebuf, (const unsigned char *)AUTH_METHOD_PASSWORD, AUTH_METHOD_PASSWORD_LEN); } buf_putbufstring(ses.writepayload, typebuf);
--- a/svr-authpam.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-authpam.c Fri Jun 12 22:57:48 2015 +0800 @@ -188,7 +188,7 @@ pam_handle_t* pamHandlep = NULL; - unsigned char * password = NULL; + char * password = NULL; unsigned int passwordlen; int rc = PAM_SUCCESS;
--- a/svr-authpasswd.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-authpasswd.c Fri Jun 12 22:57:48 2015 +0800 @@ -33,6 +33,8 @@ #ifdef ENABLE_SVR_PASSWORD_AUTH +/* not constant time when strings are differing lengths. + string content isn't leaked, and crypt hashes are predictable length. */ static int constant_time_strcmp(const char* a, const char* b) { size_t la = strlen(a); size_t lb = strlen(b); @@ -50,7 +52,7 @@ char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */ char * testcrypt = NULL; /* crypt generated from the user's password sent */ - unsigned char * password; + char * password; unsigned int passwordlen; unsigned int changepw; @@ -73,7 +75,7 @@ password = buf_getstring(ses.payload, &passwordlen); /* the first bytes of passwdcrypt are the salt */ - testcrypt = crypt((char*)password, passwdcrypt); + testcrypt = crypt(password, passwdcrypt); m_burn(password, passwordlen); m_free(password);
--- a/svr-authpubkey.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-authpubkey.c Fri Jun 12 22:57:48 2015 +0800 @@ -70,10 +70,10 @@ #define MIN_AUTHKEYS_LINE 10 /* "ssh-rsa AB" - short but doesn't matter */ #define MAX_AUTHKEYS_LINE 4200 /* max length of a line in authkeys */ -static int checkpubkey(unsigned char* algo, unsigned int algolen, +static int checkpubkey(char* algo, unsigned int algolen, unsigned char* keyblob, unsigned int keybloblen); static int checkpubkeyperms(); -static void send_msg_userauth_pk_ok(unsigned char* algo, unsigned int algolen, +static void send_msg_userauth_pk_ok(char* algo, unsigned int algolen, unsigned char* keyblob, unsigned int keybloblen); static int checkfileperm(char * filename); @@ -82,7 +82,7 @@ void svr_auth_pubkey() { unsigned char testkey; /* whether we're just checking if a key is usable */ - unsigned char* algo = NULL; /* pubkey algo */ + char* algo = NULL; /* pubkey algo */ unsigned int algolen; unsigned char* keyblob = NULL; unsigned int keybloblen; @@ -173,7 +173,7 @@ /* Reply that the key is valid for auth, this is sent when the user sends * a straight copy of their pubkey to test, to avoid having to perform * expensive signing operations with a worthless key */ -static void send_msg_userauth_pk_ok(unsigned char* algo, unsigned int algolen, +static void send_msg_userauth_pk_ok(char* algo, unsigned int algolen, unsigned char* keyblob, unsigned int keybloblen) { TRACE(("enter send_msg_userauth_pk_ok")) @@ -181,7 +181,7 @@ buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_PK_OK); buf_putstring(ses.writepayload, algo, algolen); - buf_putstring(ses.writepayload, keyblob, keybloblen); + buf_putstring(ses.writepayload, (const char*)keyblob, keybloblen); encrypt_packet(); TRACE(("leave send_msg_userauth_pk_ok")) @@ -191,7 +191,7 @@ /* Checks whether a specified publickey (and associated algorithm) is an * acceptable key for authentication */ /* Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */ -static int checkpubkey(unsigned char* algo, unsigned int algolen, +static int checkpubkey(char* algo, unsigned int algolen, unsigned char* keyblob, unsigned int keybloblen) { FILE * authfile = NULL; @@ -260,9 +260,9 @@ /* check the key type - will fail if there are options */ TRACE(("a line!")) - if (strncmp(buf_getptr(line, algolen), algo, algolen) != 0) { + if (strncmp((const char *) buf_getptr(line, algolen), algo, algolen) != 0) { int is_comment = 0; - char *options_start = NULL; + unsigned char *options_start = NULL; int options_len = 0; int escape, quoted; @@ -308,7 +308,7 @@ if (line->pos + algolen+3 > line->len) { continue; } - if (strncmp(buf_getptr(line, algolen), algo, algolen) != 0) { + if (strncmp((const char *) buf_getptr(line, algolen), algo, algolen) != 0) { continue; } } @@ -330,7 +330,7 @@ TRACE(("checkpubkey: line pos = %d len = %d", line->pos, line->len)) - ret = cmp_base64_key(keyblob, keybloblen, algo, algolen, line, NULL); + ret = cmp_base64_key(keyblob, keybloblen, (const unsigned char *) algo, algolen, line, NULL); if (ret == DROPBEAR_SUCCESS && options_buf) { ret = svr_add_pubkey_options(options_buf, line_num, filename);
--- a/svr-authpubkeyoptions.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-authpubkeyoptions.c Fri Jun 12 22:57:48 2015 +0800 @@ -120,7 +120,7 @@ if (options_buf->len - options_buf->pos < len) { return DROPBEAR_FAILURE; } - if (strncasecmp(buf_getptr(options_buf, len), opt_name, len) == 0) { + if (strncasecmp((const char *) buf_getptr(options_buf, len), opt_name, len) == 0) { buf_incrpos(options_buf, len); return DROPBEAR_SUCCESS; }
--- a/svr-chansession.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-chansession.c Fri Jun 12 22:57:48 2015 +0800 @@ -343,7 +343,7 @@ * or x11/authagent forwarding. These are passed to appropriate handlers */ static void chansessionrequest(struct Channel *channel) { - unsigned char * type = NULL; + char * type = NULL; unsigned int typelen; unsigned char wantreply; int ret = 1; @@ -406,7 +406,7 @@ static int sessionsignal(struct ChanSess *chansess) { int sig = 0; - unsigned char* signame = NULL; + char* signame = NULL; int i; if (chansess->pid == 0) { @@ -557,7 +557,7 @@ static int sessionpty(struct ChanSess * chansess) { unsigned int termlen; - unsigned char namebuf[65]; + char namebuf[65]; struct passwd * pw = NULL; TRACE(("enter sessionpty")) @@ -583,7 +583,7 @@ return DROPBEAR_FAILURE; } - chansess->tty = (char*)m_strdup(namebuf); + chansess->tty = m_strdup(namebuf); if (!chansess->tty) { dropbear_exit("Out of memory"); /* TODO disconnect */ } @@ -603,6 +603,7 @@ return DROPBEAR_SUCCESS; } +#ifndef USE_VFORK static void make_connection_string(struct ChanSess *chansess) { char *local_ip, *local_port, *remote_ip, *remote_port; size_t len; @@ -624,6 +625,7 @@ m_free(remote_ip); m_free(remote_port); } +#endif /* Handle a command request from the client. This is used for both shell * and command-execution requests, and passes the command to
--- a/svr-kex.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-kex.c Fri Jun 12 22:57:48 2015 +0800 @@ -247,7 +247,7 @@ { struct kex_curve25519_param *param = gen_kexcurve25519_param(); kexcurve25519_comb_key(param, ecdh_qs, svr_opts.hostkey); - buf_putstring(ses.writepayload, param->pub, CURVE25519_LEN); + buf_putstring(ses.writepayload, (const char*)param->pub, CURVE25519_LEN); free_kexcurve25519_param(param); } #endif
--- a/svr-main.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-main.c Fri Jun 12 22:57:48 2015 +0800 @@ -429,7 +429,7 @@ for (n = 0; n < (unsigned int)nsock; n++) { int sock = socks[sockpos + n]; set_sock_priority(sock, DROPBEAR_PRIO_LOWDELAY); -#ifdef DROPBEAR_TCP_FAST_OPEN +#ifdef DROPBEAR_SERVER_TCP_FAST_OPEN set_listen_fast_open(sock); #endif }
--- a/svr-service.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-service.c Fri Jun 12 22:57:48 2015 +0800 @@ -30,13 +30,13 @@ #include "ssh.h" #include "auth.h" -static void send_msg_service_accept(unsigned char *name, int len); +static void send_msg_service_accept(char *name, int len); /* processes a SSH_MSG_SERVICE_REQUEST, returning 0 if finished, * 1 if not */ void recv_msg_service_request() { - unsigned char * name; + char * name; unsigned int len; TRACE(("enter recv_msg_service_request")) @@ -73,7 +73,7 @@ } -static void send_msg_service_accept(unsigned char *name, int len) { +static void send_msg_service_accept(char *name, int len) { TRACE(("accepting service %s", name))
--- a/svr-session.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-session.c Fri Jun 12 22:57:48 2015 +0800 @@ -138,6 +138,8 @@ /* exchange identification, version etc */ send_session_identification(); + + kexfirstinitialise(); /* initialise the kex state */ /* start off with key exchange */ send_msg_kexinit();
--- a/svr-tcpfwd.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-tcpfwd.c Fri Jun 12 22:57:48 2015 +0800 @@ -65,7 +65,7 @@ * similar to the request-switching in chansession.c */ void recv_msg_global_request_remotetcp() { - unsigned char* reqname = NULL; + char* reqname = NULL; unsigned int namelen; unsigned int wantreply = 0; int ret = DROPBEAR_FAILURE; @@ -120,7 +120,7 @@ static int svr_cancelremotetcp() { int ret = DROPBEAR_FAILURE; - unsigned char * bindaddr = NULL; + char * bindaddr = NULL; unsigned int addrlen; unsigned int port; struct Listener * listener = NULL; @@ -155,7 +155,7 @@ static int svr_remotetcpreq() { int ret = DROPBEAR_FAILURE; - unsigned char * request_addr = NULL; + char * request_addr = NULL; unsigned int addrlen; struct TCPListener *tcpinfo = NULL; unsigned int port; @@ -232,12 +232,12 @@ * address */ static int newtcpdirect(struct Channel * channel) { - unsigned char* desthost = NULL; + char* desthost = NULL; unsigned int destport; - unsigned char* orighost = NULL; + char* orighost = NULL; unsigned int origport; char portstring[NI_MAXSERV]; - int len; + unsigned int len; int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; TRACE(("newtcpdirect channel %d", channel->index))
--- a/svr-x11fwd.c Thu Mar 12 15:14:47 2015 +0300 +++ b/svr-x11fwd.c Fri Jun 12 22:57:48 2015 +0800 @@ -107,7 +107,7 @@ int fd; struct sockaddr_in addr; - int len; + socklen_t len; int ret; struct ChanSess * chansess = (struct ChanSess *)(listener->typedata);
--- a/sysoptions.h Thu Mar 12 15:14:47 2015 +0300 +++ b/sysoptions.h Fri Jun 12 22:57:48 2015 +0800 @@ -262,9 +262,12 @@ /* Use this string since some implementations might special-case it */ #define DROPBEAR_KEEPALIVE_STRING "[email protected]" -/* Linux will attempt TCP fast open, falling back if not supported by the kernel */ +/* Linux will attempt TCP fast open, falling back if not supported by the kernel. + * Currently server is enabled but client is disabled by default until there + * is further compatibility testing */ #ifdef __linux__ -#define DROPBEAR_TCP_FAST_OPEN 1 +#define DROPBEAR_SERVER_TCP_FAST_OPEN +/* #define DROPBEAR_CLIENT_TCP_FAST_OPEN */ #endif /* no include guard for this file */
--- a/tcp-accept.c Thu Mar 12 15:14:47 2015 +0300 +++ b/tcp-accept.c Fri Jun 12 22:57:48 2015 +0800 @@ -75,7 +75,7 @@ } if (send_msg_channel_open_init(fd, tcpinfo->chantype) == DROPBEAR_SUCCESS) { - unsigned char* addr = NULL; + char* addr = NULL; unsigned int port = 0; if (tcpinfo->tcp_type == direct) {
--- a/tcpfwd.h Thu Mar 12 15:14:47 2015 +0300 +++ b/tcpfwd.h Fri Jun 12 22:57:48 2015 +0800 @@ -31,16 +31,16 @@ /* For a direct-tcpip request, it's the addr/port we want the other * end to connect to */ - unsigned char *sendaddr; + char *sendaddr; unsigned int sendport; /* This is the address/port that we listen on. The address has special * meanings as per the rfc, "" for all interfaces, "localhost" for * localhost, or a normal interface name. */ - unsigned char *listenaddr; + char *listenaddr; unsigned int listenport; /* The address that the remote host asked to listen on */ - unsigned char *request_listenaddr; + char *request_listenaddr; const struct ChanType *chantype; enum {direct, forwarded} tcp_type; @@ -48,9 +48,9 @@ /* A forwarding entry */ struct TCPFwdEntry { - const unsigned char* connectaddr; + const char *connectaddr; unsigned int connectport; - const unsigned char* listenaddr; + const char *listenaddr; unsigned int listenport; unsigned int have_reply; /* is set to 1 after a reply has been received when setting up the forwarding */