--HG--
branch : coverity
This commit is contained in:
Matt Johnston
2015-08-07 21:26:03 +08:00
13 changed files with 71 additions and 65 deletions

View File

@@ -3,7 +3,7 @@ compiler:
- gcc
script:
- autoconf && autoheader && ./configure $BUNDLEDLIBTOM CFLAGS="-O2 -Wall -Wno-pointer-sign" --prefix=$HOME/inst
- autoconf && autoheader && ./configure $BUNDLEDLIBTOM CFLAGS="-O2 -Wall -Wno-pointer-sign $WEXTRAFLAGS" --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

11
CHANGES
View File

@@ -8,7 +8,7 @@
with networks and systems.
- Forwarded TCP ports connect asynchronously and retry with other available
addresses (IPv4 or IPv6, round robin IPs)
addresses (IPv4 versus IPv6, round robin IPs)
- Free memory before exiting, patch from Thorsten Horstmann. Useful for
Dropbear ports to embedded systems and for checking memory leaks
@@ -22,10 +22,17 @@
- 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.
Matta Consulting. Odds of bad values are around 2**-512 -- improbable.
- Twofish-ctr cipher is supported though disabled by default
- Fix pre-authentication timeout when waiting for client SSH-2.0 banner, thanks
to CL Ouyang
- Increase maximum command size to 9000 bytes
- DROPBEAR_DEFAULT_CLI_AUTHKEY setting now always prepends home directory unless
there is a leading slash (~ isn't treated specially)
2015.67 - Wednesday 28 January 2015

View File

@@ -449,7 +449,7 @@ void cli_getopts(int argc, char ** argv) {
#if defined(DROPBEAR_DEFAULT_CLI_AUTHKEY) && defined(ENABLE_CLI_PUBKEY_AUTH)
{
char *expand_path = expand_tilde(DROPBEAR_DEFAULT_CLI_AUTHKEY);
char *expand_path = expand_homedir_path(DROPBEAR_DEFAULT_CLI_AUTHKEY);
loadidentityfile(expand_path, 0);
m_free(expand_path);
}

View File

@@ -76,6 +76,7 @@ void common_session_init(int sock_in, int sock_out) {
update_channel_prio();
now = monotonic_now();
ses.connect_time = now;
ses.last_packet_time_keepalive_recv = now;
ses.last_packet_time_idle = now;
ses.last_packet_time_any_sent = 0;
@@ -486,6 +487,11 @@ static void checktimeouts() {
time_t now;
now = monotonic_now();
if (IS_DROPBEAR_SERVER && ses.connect_time != 0
&& now - ses.connect_time >= AUTH_TIMEOUT) {
dropbear_close("Timeout before auth");
}
/* we can't rekey if we haven't done remote ident exchange yet */
if (ses.remoteident == NULL) {
return;
@@ -526,20 +532,39 @@ static void checktimeouts() {
}
}
static void update_timeout(long limit, long now, long last_event, long * timeout) {
TRACE2(("update_timeout limit %ld, now %ld, last %ld, timeout %ld",
limit, now, last_event, *timeout))
if (last_event > 0 && limit > 0) {
*timeout = MIN(*timeout, last_event+limit-now);
TRACE2(("new timeout %ld", *timeout))
}
}
static long select_timeout() {
/* determine the minimum timeout that might be required, so
as to avoid waking when unneccessary */
long ret = LONG_MAX;
if (KEX_REKEY_TIMEOUT > 0)
ret = MIN(KEX_REKEY_TIMEOUT, ret);
/* AUTH_TIMEOUT is only relevant before authdone */
if (ses.authstate.authdone != 1 && AUTH_TIMEOUT > 0)
ret = MIN(AUTH_TIMEOUT, ret);
if (opts.keepalive_secs > 0)
ret = MIN(opts.keepalive_secs, ret);
if (opts.idle_timeout_secs > 0)
ret = MIN(opts.idle_timeout_secs, ret);
return ret;
long timeout = LONG_MAX;
long now = monotonic_now();
update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout);
if (ses.authstate.authdone != 1 && IS_DROPBEAR_SERVER) {
/* AUTH_TIMEOUT is only relevant before authdone */
update_timeout(AUTH_TIMEOUT, now, ses.connect_time, &timeout);
}
if (ses.authstate.authdone) {
update_timeout(opts.keepalive_secs, now,
MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent),
&timeout);
}
update_timeout(opts.idle_timeout_secs, now, ses.last_packet_time_idle,
&timeout);
/* clamp negative timeouts to zero - event has already triggered */
return MAX(timeout, 0);
}
const char* get_user_shell() {

View File

@@ -613,15 +613,16 @@ int m_str_to_uint(const char* str, unsigned int *val) {
}
}
/* Returns malloced path. Only expands ~ in first character */
char * expand_tilde(const char *inpath) {
/* Returns malloced path. inpath beginning with '/' is returned as-is,
otherwise home directory is prepended */
char * expand_homedir_path(const char *inpath) {
struct passwd *pw = NULL;
if (inpath[0] == '~') {
if (inpath[0] != '/') {
pw = getpwuid(getuid());
if (pw && pw->pw_dir) {
int len = strlen(inpath) + strlen(pw->pw_dir) + 1;
int len = strlen(inpath) + strlen(pw->pw_dir) + 2;
char *buf = m_malloc(len);
snprintf(buf, len, "%s/%s", pw->pw_dir, &inpath[1]);
snprintf(buf, len, "%s/%s", pw->pw_dir, inpath);
return buf;
}
}

View File

@@ -78,7 +78,7 @@ void m_close(int fd);
void * m_malloc(size_t size);
void * m_strdup(const char * str);
void * m_realloc(void* ptr, size_t size);
#define m_free(X) do {free(X); (X) = NULL;} while (0);
#define m_free(X) do {free(X); (X) = NULL;} while (0)
void m_burn(void* data, unsigned int len);
void setnonblocking(int fd);
void disallow_core();
@@ -97,6 +97,6 @@ int constant_time_memcmp(const void* a, const void *b, size_t n);
a real-world clock */
time_t monotonic_now();
char * expand_tilde(const char *inpath);
char * expand_homedir_path(const char *inpath);
#endif /* DROPBEAR_DBUTIL_H_ */

21
netio.c
View File

@@ -21,23 +21,6 @@ struct dropbear_progress_connection {
char* errstring;
};
#if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
static void set_piggyback_ack(int sock) {
/* Undocumented Linux feature - set TCP_DEFER_ACCEPT and data will be piggybacked
on the 3rd packet (ack) of the TCP handshake. Saves a IP packet.
http://thread.gmane.org/gmane.linux.network/224627/focus=224727
"Piggyback the final ACK of the three way TCP connection establishment with the data" */
int val = 1;
/* No error checking, this is opportunistic */
int err = setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (void*)&val, sizeof(val));
if (err)
{
TRACE(("Failed setsockopt TCP_DEFER_ACCEPT: %s", strerror(errno)))
}
}
#endif
/* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
Does not close sockets */
static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *iter) {
@@ -87,10 +70,6 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
set_sock_nodelay(c->sock);
setnonblocking(c->sock);
#if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
set_piggyback_ack(c->sock);
#endif
#ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN
fastopen = (c->writequeue != NULL);

View File

@@ -222,8 +222,8 @@ If you test it please contact the Dropbear author */
#define ENABLE_CLI_INTERACT_AUTH
/* A default argument for dbclient -i <privatekey>.
leading "~" is expanded */
#define DROPBEAR_DEFAULT_CLI_AUTHKEY "~/.ssh/id_dropbear"
Homedir is prepended unless path begins with / */
#define DROPBEAR_DEFAULT_CLI_AUTHKEY ".ssh/id_dropbear"
/* This variable can be used to set a password for client
* authentication on the commandline. Beware of platforms

View File

@@ -33,7 +33,9 @@ hg archive "$RELDIR" || exit 2
rm -r "$RELDIR/autom4te.cache" || exit 2
(cd $RELDIR/.. && tar cjf $ARCHIVE `basename "$RELDIR"`) || exit 2
rm "$RELDIR/.hgtags"
(cd "$RELDIR/.." && tar cjf $ARCHIVE `basename "$RELDIR"`) || exit 2
ls -l $ARCHIVE
openssl sha -sha256 $ARCHIVE

View File

@@ -109,6 +109,11 @@ struct sshsession {
/* Is it a client or server? */
unsigned char isserver;
time_t connect_time; /* time the connection was established
(cleared after auth once we're not
respecting AUTH_TIMEOUT any more).
A monotonic time, not realworld */
int sock_in;
int sock_out;
@@ -231,11 +236,6 @@ struct serversession {
/* The resolved remote address, used for lastlog etc */
char *remotehost;
time_t connect_time; /* time the connection was established
(cleared after auth once we're not
respecting AUTH_TIMEOUT any more).
A monotonic time, not realworld */
#ifdef USE_VFORK
pid_t server_pid;
#endif

View File

@@ -392,7 +392,8 @@ void send_msg_userauth_success() {
/* authdone must be set after encrypt_packet() for
* delayed-zlib mode */
ses.authstate.authdone = 1;
svr_ses.connect_time = 0;
ses.connect_time = 0;
if (ses.authstate.pw_uid == 0) {
ses.allowprivport = 1;

View File

@@ -88,22 +88,12 @@ svr_session_cleanup(void) {
svr_ses.childpidsize = 0;
}
static void
svr_sessionloop() {
if (svr_ses.connect_time != 0
&& monotonic_now() - svr_ses.connect_time >= AUTH_TIMEOUT) {
dropbear_close("Timeout before auth");
}
}
void svr_session(int sock, int childpipe) {
char *host, *port;
size_t len;
common_session_init(sock, sock);
svr_ses.connect_time = monotonic_now();;
/* Initialise server specific parts of the session */
svr_ses.childpipe = childpipe;
#ifdef USE_VFORK
@@ -146,7 +136,7 @@ void svr_session(int sock, int childpipe) {
/* Run the main for loop. NULL is for the dispatcher - only the client
* code makes use of it */
session_loop(svr_sessionloop);
session_loop(NULL);
/* Not reached */

View File

@@ -47,7 +47,7 @@
* the clearenv() function */
#define ENV_SIZE 100
#define MAX_CMD_LEN 1024 /* max length of a command */
#define MAX_CMD_LEN 9000 /* max length of a command */
#define MAX_TERM_LEN 200 /* max length of TERM name */
#define MAX_HOST_LEN 254 /* max hostname len for tcp fwding */
@@ -153,7 +153,8 @@
#define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11
connection, so can't be _too_ small */
#define MAX_STRING_LEN 2400 /* Sun SSH needs this long for algos */
#define MAX_STRING_LEN (MAX(MAX_CMD_LEN, 2400)) /* Sun SSH needs 2400 for algos,
MAX_CMD_LEN is usually longer */
/* For a 4096 bit DSS key, empirically determined */
#define MAX_PUBKEY_SIZE 1700