Compare commits

..

51 Commits

Author SHA1 Message Date
Matt Johnston
5b2e57aa2f 2015.71 2015-12-03 21:23:54 +08:00
Matt Johnston
0b9793ccd0 wrong breakage version 2015-12-02 23:37:04 +08:00
Matt Johnston
fff298523d preliminary 2015.71 CHANGES 2015-12-02 23:35:14 +08:00
Matt Johnston
e81b6fbc6e ports and addresses must be malloced to avoid segfault on exit 2015-12-02 22:37:20 +08:00
Matt Johnston
f64a50f319 Merge pull request #15 from annulen/fix_cli_remotetcpfwd
Fixed build when ENABLE_CLI_REMOTETCPFWD is the only allowed TCP forw…
2015-11-30 21:13:03 +08:00
Juergen Daubert
f299caf612 The '==' comparision operator is not defined by POSIX, use '=' instead 2015-11-30 20:55:07 +08:00
Konstantin Tokarev
f76141a704 Fixed build when ENABLE_CLI_REMOTETCPFWD is the only allowed TCP forwarding. 2015-11-27 21:40:00 +03:00
Matt Johnston
a3049d6433 Fix "Avoid queueing into circbuffer when the channel is about to close"
which broken handling EAGAIN/EINTR
2015-11-27 22:19:08 +08:00
Matt Johnston
ee353847be Fix ses.channel_signal_pending race 2015-11-27 21:26:43 +08:00
Matt Johnston
33b2fbb5ef Added signature for changeset 5bb5976e6902 2015-11-26 23:15:27 +08:00
Matt Johnston
7d84615545 Added tag DROPBEAR_2015.70 for changeset 79a6ef02307d 2015-11-26 23:15:12 +08:00
Matt Johnston
b42113119a Wrong date 2015-11-26 23:05:38 +08:00
Matt Johnston
722944f307 2015.70 2015-11-26 23:04:13 +08:00
Matt Johnston
e038c26963 Another attempt at test for crypt() 2015-11-26 23:01:13 +08:00
Matt Johnston
56b9388702 Backed out changeset fbcd0a20e667 2015-11-26 22:21:14 +08:00
Matt Johnston
0e438f6d5c AC_SEARCH_LIBS not AC_CHECK_LIB to find crypt() 2015-11-26 21:58:25 +08:00
Matt Johnston
9f1eb695b4 release.sh reminds how to sign 2015-11-25 23:30:56 +08:00
Matt Johnston
9fef5d1050 Added signature for changeset af074dbcb68f 2015-11-25 23:30:44 +08:00
Matt Johnston
0bb7f77a8f Added tag DROPBEAR_2015.69 for changeset 1637dbd26212 2015-11-25 23:30:36 +08:00
Matt Johnston
9e4e562cfb 2015.69 2015-11-25 23:07:47 +08:00
Matt Johnston
92ec446cb9 debian changelog 2015-11-25 23:07:18 +08:00
Matt Johnston
9097da0284 changelog 2015-11-25 23:06:55 +08:00
Matt Johnston
eedeb009ec mention dropbearkey too 2015-11-25 23:05:41 +08:00
Matt Johnston
d8bc6abcf0 Mention "dropbear -R" if no hostkeys 2015-11-25 23:05:14 +08:00
Matt Johnston
2293e3d105 check for zero K value from curve25519 2015-11-25 22:15:59 +08:00
Guilhem Moulin
550b3056fd Fix minor manpage formatting issues 2015-11-25 20:46:06 +08:00
Matt Johnston
1ba5e8052e Improve dbclient manpage 2015-11-23 23:02:03 +08:00
Matt Johnston
6f5abeff2e Fix flags after the hostname 2015-11-23 22:47:43 +08:00
Guilhem Moulin
7cbf6b131b Bundling for dbclient 2015-11-23 22:28:56 +08:00
Matt Johnston
a461298109 Increase channel limit to 1000 2015-11-19 23:53:06 +08:00
Matt Johnston
90c3a74b2a Avoid queueing into circbuffer when the channel is about to close 2015-11-19 23:52:52 +08:00
Matt Johnston
87373be960 lazy allocation of circbuffer 2015-11-19 23:52:11 +08:00
Matt Johnston
85d9672e47 Send SSH_OPEN_RESOURCE_SHORTAGE response when too many channels open
rather than SSH_OPEN_UNKNOWN_CHANNEL_TYPE
2015-11-19 22:39:32 +08:00
Matt Johnston
e0ae527190 Only clear channel_signal_pending after handling all channels,
from Andrzej Szombierski
2015-11-17 20:53:30 +08:00
Guilhem Moulin
7fb1bec84a Enable bundling 2015-11-06 23:54:24 +08:00
Matt Johnston
1f308fb2b4 S_IWUSR rather than S_IWRITE for scp 2015-11-04 23:22:58 +08:00
Guilhem Moulin
e2d36d493f Mention -y flag 2015-10-28 21:44:16 +08:00
Matt Johnston
7c43594075 Add comment about compression 2015-10-28 21:42:09 +08:00
Matt Johnston
e4827025be Warn rather than fail if flags have trailing parts 2015-10-28 21:37:35 +08:00
Matt Johnston
00798ca8cc Test for crypt() rather than crypt.h
Print a message from configure if getpass() or crypt() were missing
2015-10-21 23:08:22 +08:00
Mike Frysinger
e84cb3c3c2 fix default build when getpass() is unavailable
if the system doesn't support getpass, we still default on the options
that require it which causes a build failure.  instead, only default
enable these when getpass is available.
2015-10-21 22:48:15 +08:00
Mike Frysinger
78b9cecb52 fix default build when crypt() is unavailable
if the system doesn't support crypt.h/crypt, then ENABLE_SVR_PASSWORD_AUTH
cannot work.  rather than default this to on all the time, do so only when
support for the header is found.
2015-10-21 22:40:11 +08:00
Mike Frysinger
93c54fe6f6 avoid getpass when not used
some systems (like android's bionic) do not provide getpass.  you can
disable ENABLE_CLI_PASSWORD_AUTH & ENABLE_CLI_INTERACT_AUTH to avoid
its use (and rely on pubkey auth), but the link still fails because
the support file calls getpass.  do not define this func if both of
those auth methods are not used.
2015-10-21 22:39:55 +08:00
Mike Frysinger
5f97d0fbbc fix build when ENABLE_CLI_INTERACT_AUTH is disabled
The session.h defines clientsession.cipher_none_after_auth only when
ENABLE_CLI_INTERACT_AUTH is defined, but cli-session.c will always
try to set that member.  export cipher_none_after_auth all the time.
2015-10-21 22:39:31 +08:00
Guilhem Moulin
dc01a8edd4 Don't display the MOTD when an explicit command is run.
(possibly via authorized_keys(5) restrictions), even when a
pseudo-terminal has been allocated for the session.  In other words,
only display the MOTD when the server starts the user's default shell.
2015-10-21 22:08:47 +08:00
Matt Johnston
23cc2bfb8c don't silently ignore extra flag arguments 2015-10-21 22:05:50 +08:00
Matt Johnston
9e379835c4 avoid invalidated iterator when connection fails 2015-09-29 22:19:11 +08:00
Matt Johnston
8ccbd216c6 make sure that the test for queued packets to write occurs after
those packets might have been enqueued by set_connect_fds()
2015-09-29 21:53:27 +08:00
Matt Johnston
90f4da29d7 Added signature for changeset ef4b26364b0c 2015-08-08 22:14:30 +08:00
Matt Johnston
54dbd5bbc8 Added signature for changeset a687f835236c 2015-08-08 22:14:19 +08:00
Matt Johnston
849b8ec469 Added tag DROPBEAR_2015.68 for changeset 809feaa9408f 2015-08-08 22:14:10 +08:00
24 changed files with 389 additions and 250 deletions

View File

@@ -14,3 +14,7 @@ a50a1dc743317fad9b3737bc68fbca640659bb6d 0 iEYEABECAAYFAlJeqL0ACgkQjPn4sExkf7yVq
caac692b366c153cea0e9cd59aa2d79a7d843d4e 0 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

View File

@@ -47,3 +47,6 @@ e894dbc015ba7ff4c3bf897ee20e28ca90c55a16 DROPBEAR_2013.61test
e9579816f20ea85affc6135e87f8477992808948 DROPBEAR_2014.65
735511a4c761141416ad0e6728989d2dafa55bc2 DROPBEAR_2014.66
cbd674d63cd4f3781464a8d4056a5506c8ae926f DROPBEAR_2015.67
809feaa9408f036734129c77f2b3c7e779d4f099 DROPBEAR_2015.68
1637dbd262124d113e52967df46afd6c715e4fad DROPBEAR_2015.69
79a6ef02307d05cb9dda10465cb5b807baa8f62e DROPBEAR_2015.70

39
CHANGES
View File

@@ -1,3 +1,42 @@
2015.71 - 3 December 2015
- Fix "bad buf_incrpos" when data is transferred, broke in 2015.69
- Fix crash on exit when -p address:port is used, broke in 2015.68
- Fix building with only ENABLE_CLI_REMOTETCPFWD given, patch from Konstantin Tokarev
- Fix bad configure script test which didn't work with dash shell, patch from Juergen Daubert,
broke in 2015.70
- Fix server race condition that could cause sessions to hang on exit,
https://github.com/robotframework/SSHLibrary/issues/128
2015.70 - 26 November 2015
- Fix server password authentication on Linux, broke in 2015.69
2015.69 - 25 November 2015
- Fix crash when forwarded TCP connections fail to connect (bug introduced in 2015.68)
- Avoid hang on session close when multiple sessions are started, affects Qt Creator
Patch from Andrzej Szombierski
- Reduce per-channel memory consumption in common case, increase default
channel limit from 100 to 1000 which should improve SOCKS forwarding for modern
webpages
- Handle multiple command line arguments in a single flag, thanks to Guilhem Moulin
- Manpage improvements from Guilhem Moulin
- Build fixes for Android from Mike Frysinger
- Don't display the MOTD when an explicit command is run from Guilhem Moulin
- Check curve25519 shared secret isn't zero
2015.68 - Saturday 8 August 2015
- Reduce local data copying for improved efficiency. Measured 30%

View File

@@ -37,9 +37,8 @@ circbuffer * cbuf_new(unsigned int size) {
}
cbuf = (circbuffer*)m_malloc(sizeof(circbuffer));
if (size > 0) {
cbuf->data = (unsigned char*)m_malloc(size);
}
/* data is malloced on first write */
cbuf->data = NULL;
cbuf->used = 0;
cbuf->readpos = 0;
cbuf->writepos = 0;
@@ -50,8 +49,10 @@ circbuffer * cbuf_new(unsigned int size) {
void cbuf_free(circbuffer * cbuf) {
m_burn(cbuf->data, cbuf->size);
m_free(cbuf->data);
if (cbuf->data) {
m_burn(cbuf->data, cbuf->size);
m_free(cbuf->data);
}
m_free(cbuf);
}
@@ -106,6 +107,11 @@ unsigned char* cbuf_writeptr(circbuffer *cbuf, unsigned int len) {
dropbear_exit("Bad cbuf write");
}
if (!cbuf->data) {
/* lazy allocation */
cbuf->data = (unsigned char*)m_malloc(cbuf->size);
}
return &cbuf->data[cbuf->writepos];
}

View File

@@ -324,6 +324,7 @@ int cli_auth_try() {
return DROPBEAR_FAILURE;
}
#if defined(ENABLE_CLI_PASSWORD_AUTH) || defined(ENABLE_CLI_INTERACT_AUTH)
/* A helper for getpass() that exits if the user cancels. The returned
* password is statically allocated by getpass() */
char* getpass_or_cancel(char* prompt)
@@ -347,3 +348,4 @@ char* getpass_or_cancel(char* prompt)
}
return password;
}
#endif

View File

@@ -105,25 +105,30 @@ static void printhelp() {
void cli_getopts(int argc, char ** argv) {
unsigned int i, j;
char ** next = 0;
unsigned int cmdlen;
enum {
#ifdef ENABLE_CLI_PUBKEY_AUTH
int nextiskey = 0; /* A flag if the next argument is a keyfile */
OPT_AUTHKEY,
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
int nextislocal = 0;
OPT_LOCALTCPFWD,
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
int nextisremote = 0;
OPT_REMOTETCPFWD,
#endif
#ifdef ENABLE_CLI_NETCAT
int nextisnetcat = 0;
OPT_NETCAT,
#endif
/* a flag (no arg) if 'next' is NULL, a string-valued option otherwise */
OPT_OTHER
} opt;
unsigned int cmdlen;
char* dummy = NULL; /* Not used for anything real */
char* recv_window_arg = NULL;
char* keepalive_arg = NULL;
char* idle_timeout_arg = NULL;
char *host_arg = NULL;
char c;
/* see printhelp() for options */
cli_opts.progname = argv[0];
@@ -172,54 +177,23 @@ void cli_getopts(int argc, char ** argv) {
fill_own_user();
/* Iterate all the arguments */
for (i = 1; i < (unsigned int)argc; i++) {
#ifdef ENABLE_CLI_PUBKEY_AUTH
if (nextiskey) {
/* Load a hostkey since the previous argument was "-i" */
loadidentityfile(argv[i], 1);
nextiskey = 0;
continue;
}
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
if (nextisremote) {
TRACE(("nextisremote true"))
addforward(argv[i], cli_opts.remotefwds);
nextisremote = 0;
continue;
}
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
if (nextislocal) {
TRACE(("nextislocal true"))
addforward(argv[i], cli_opts.localfwds);
nextislocal = 0;
continue;
}
#endif
#ifdef ENABLE_CLI_NETCAT
if (nextisnetcat) {
TRACE(("nextisnetcat true"))
add_netcat(argv[i]);
nextisnetcat = 0;
continue;
}
#endif
if (next) {
/* The previous flag set a value to assign */
*next = argv[i];
if (*next == NULL) {
dropbear_exit("Invalid null argument");
/* Handle non-flag arguments such as hostname or commands for the remote host */
if (argv[i][0] != '-')
{
if (host_arg == NULL) {
host_arg = argv[i];
continue;
}
next = NULL;
continue;
/* Commands to pass to the remote host. No more flag handling,
commands are consumed below */
break;
}
if (argv[i][0] == '-') {
/* A flag *waves* */
switch (argv[i][1]) {
/* Begins with '-' */
opt = OPT_OTHER;
for (j = 1; (c = argv[i][j]) != '\0' && !next && opt == OPT_OTHER; j++) {
switch (c) {
case 'y': /* always accept the remote hostkey */
if (cli_opts.always_accept_key) {
/* twice means no checking at all */
@@ -232,12 +206,7 @@ void cli_getopts(int argc, char ** argv) {
break;
#ifdef ENABLE_CLI_PUBKEY_AUTH
case 'i': /* an identityfile */
/* Keep scp happy when it changes "-i file" to "-ifile" */
if (strlen(argv[i]) > 2) {
loadidentityfile(&argv[i][2], 1);
} else {
nextiskey = 1;
}
opt = OPT_AUTHKEY;
break;
#endif
case 't': /* we want a pty */
@@ -257,7 +226,7 @@ void cli_getopts(int argc, char ** argv) {
break;
#ifdef ENABLE_CLI_LOCALTCPFWD
case 'L':
nextislocal = 1;
opt = OPT_LOCALTCPFWD;
break;
case 'g':
opts.listen_fwd_all = 1;
@@ -265,12 +234,12 @@ void cli_getopts(int argc, char ** argv) {
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
case 'R':
nextisremote = 1;
opt = OPT_REMOTETCPFWD;
break;
#endif
#ifdef ENABLE_CLI_NETCAT
case 'B':
nextisnetcat = 1;
opt = OPT_NETCAT;
break;
#endif
#ifdef ENABLE_CLI_PROXYCMD
@@ -336,50 +305,85 @@ void cli_getopts(int argc, char ** argv) {
case 'b':
next = &dummy;
default:
fprintf(stderr,
"WARNING: Ignoring unknown argument '%s'\n", argv[i]);
fprintf(stderr,
"WARNING: Ignoring unknown option -%c\n", c);
break;
} /* Switch */
/* Now we handle args where they might be "-luser" (no spaces)*/
if (next && strlen(argv[i]) > 2) {
*next = &argv[i][2];
next = NULL;
}
continue; /* next argument */
} else {
TRACE(("non-flag arg: '%s'", argv[i]))
/* Either the hostname or commands */
if (host_arg == NULL) {
host_arg = argv[i];
} else {
/* this is part of the commands to send - after this we
* don't parse any more options, and flags are sent as the
* command */
cmdlen = 0;
for (j = i; j < (unsigned int)argc; j++) {
cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */
}
/* Allocate the space */
cli_opts.cmd = (char*)m_malloc(cmdlen);
cli_opts.cmd[0] = '\0';
/* Append all the bits */
for (j = i; j < (unsigned int)argc; j++) {
strlcat(cli_opts.cmd, argv[j], cmdlen);
strlcat(cli_opts.cmd, " ", cmdlen);
}
/* It'll be null-terminated here */
/* We've eaten all the options and flags */
break;
}
}
if (!next && opt == OPT_OTHER) /* got a flag */
continue;
if (c == '\0') {
i++;
j = 0;
if (!argv[i])
dropbear_exit("Missing argument");
}
#ifdef ENABLE_CLI_PUBKEY_AUTH
if (opt == OPT_AUTHKEY) {
TRACE(("opt authkey"))
loadidentityfile(&argv[i][j], 1);
}
else
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
if (opt == OPT_REMOTETCPFWD) {
TRACE(("opt remotetcpfwd"))
addforward(&argv[i][j], cli_opts.remotefwds);
}
else
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
if (opt == OPT_LOCALTCPFWD) {
TRACE(("opt localtcpfwd"))
addforward(&argv[i][j], cli_opts.localfwds);
}
else
#endif
#ifdef ENABLE_CLI_NETCAT
if (opt == OPT_NETCAT) {
TRACE(("opt netcat"))
add_netcat(&argv[i][j]);
}
else
#endif
if (next) {
/* The previous flag set a value to assign */
*next = &argv[i][j];
if (*next == NULL)
dropbear_exit("Invalid null argument");
next = NULL;
}
}
/* Done with options/flags; now handle the hostname (which may not
* start with a hyphen) and optional command */
if (host_arg == NULL) { /* missing hostname */
printhelp();
exit(EXIT_FAILURE);
}
TRACE(("host is: %s", host_arg))
if (i < (unsigned int)argc) {
/* Build the command to send */
cmdlen = 0;
for (j = i; j < (unsigned int)argc; j++)
cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */
/* Allocate the space */
cli_opts.cmd = (char*)m_malloc(cmdlen);
cli_opts.cmd[0] = '\0';
/* Append all the bits */
for (j = i; j < (unsigned int)argc; j++) {
strlcat(cli_opts.cmd, argv[j], cmdlen);
strlcat(cli_opts.cmd, " ", cmdlen);
}
/* It'll be null-terminated here */
TRACE(("cmd is: %s", cli_opts.cmd))
}
/* And now a few sanity checks and setup */
@@ -388,11 +392,6 @@ void cli_getopts(int argc, char ** argv) {
parse_ciphers_macs();
#endif
if (host_arg == NULL) {
printhelp();
exit(EXIT_FAILURE);
}
#ifdef ENABLE_CLI_PROXYCMD
if (cli_opts.proxycmd) {
/* To match the common path of m_freeing it */

View File

@@ -42,7 +42,7 @@ 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 int 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);
@@ -100,15 +100,6 @@ void chancleanup() {
TRACE(("leave chancleanup"))
}
static void
chan_initwritebuf(struct Channel *channel)
{
dropbear_assert(channel->writebuf->size == 0 && channel->recvwindow == 0);
cbuf_free(channel->writebuf);
channel->writebuf = cbuf_new(opts.recv_window);
channel->recvwindow = opts.recv_window;
}
/* Create a new channel entry, send a reply confirm or failure */
/* If remotechan, transwindow and transmaxpacket are not know (for a new
* outgoing connection, with them to be filled on confirmation), they should
@@ -167,8 +158,8 @@ static struct Channel* newchannel(unsigned int remotechan,
newchan->await_open = 0;
newchan->flushing = 0;
newchan->writebuf = cbuf_new(0); /* resized later by chan_initwritebuf */
newchan->recvwindow = 0;
newchan->writebuf = cbuf_new(opts.recv_window);
newchan->recvwindow = opts.recv_window;
newchan->extrabuf = NULL; /* The user code can set it up */
newchan->recvdonelen = 0;
@@ -256,7 +247,6 @@ void channelio(fd_set *readfds, fd_set *writefds) {
if (ses.channel_signal_pending) {
/* SIGCHLD can change channel state for server sessions */
do_check_close = 1;
ses.channel_signal_pending = 0;
}
/* handle any channel closing etc */
@@ -378,7 +368,6 @@ void channel_connect_done(int result, int sock, void* user_data, const char* UNU
{
channel->readfd = channel->writefd = sock;
channel->conn_pending = NULL;
chan_initwritebuf(channel);
send_msg_channel_open_confirmation(channel, channel->recvwindow,
channel->recvmaxpacket);
TRACE(("leave channel_connect_done: success"))
@@ -435,7 +424,7 @@ static void send_msg_channel_eof(struct Channel *channel) {
}
#ifndef HAVE_WRITEV
static void writechannel_fallback(struct Channel* channel, int fd, circbuffer *cbuf,
static int writechannel_fallback(struct Channel* channel, int fd, circbuffer *cbuf,
const unsigned char *UNUSED(moredata), unsigned int *morelen) {
unsigned char *circ_p1, *circ_p2;
@@ -454,16 +443,18 @@ static void writechannel_fallback(struct Channel* channel, int fd, circbuffer *c
if (errno != EINTR && errno != EAGAIN) {
TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
close_chan_fd(channel, fd, SHUT_WR);
return DROPBEAR_FAILURE;
}
} else {
cbuf_incrread(cbuf, written);
channel->recvdonelen += written;
}
return DROPBEAR_SUCCESS;
}
#endif /* !HAVE_WRITEV */
#ifdef HAVE_WRITEV
static void writechannel_writev(struct Channel* channel, int fd, circbuffer *cbuf,
static int writechannel_writev(struct Channel* channel, int fd, circbuffer *cbuf,
const unsigned char *moredata, unsigned int *morelen) {
struct iovec iov[3];
@@ -502,7 +493,7 @@ static void writechannel_writev(struct Channel* channel, int fd, circbuffer *cbu
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;
return DROPBEAR_SUCCESS;
}
if (morelen) {
@@ -516,6 +507,7 @@ static void writechannel_writev(struct Channel* channel, int fd, circbuffer *cbu
if (errno != EINTR && errno != EAGAIN) {
TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
close_chan_fd(channel, fd, SHUT_WR);
return DROPBEAR_FAILURE;
}
} else {
int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written);
@@ -525,20 +517,22 @@ static void writechannel_writev(struct Channel* channel, int fd, circbuffer *cbu
}
channel->recvdonelen += written;
}
return DROPBEAR_SUCCESS;
}
#endif /* HAVE_WRITEV */
/* 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,
if not null. Will ignore EAGAIN.
Returns DROPBEAR_FAILURE if writing to fd had an error and the channel is being closed, DROPBEAR_SUCCESS otherwise */
static int writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
const unsigned char *moredata, unsigned int *morelen) {
int ret = DROPBEAR_SUCCESS;
TRACE(("enter writechannel fd %d", fd))
#ifdef HAVE_WRITEV
writechannel_writev(channel, fd, cbuf, moredata, morelen);
ret = writechannel_writev(channel, fd, cbuf, moredata, morelen);
#else
writechannel_fallback(channel, fd, cbuf, moredata, morelen);
ret = writechannel_fallback(channel, fd, cbuf, moredata, morelen);
#endif
/* Window adjust handling */
@@ -554,6 +548,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
channel->recvwindow <= cbuf_getavail(channel->extrabuf));
TRACE(("leave writechannel"))
return ret;
}
@@ -828,6 +823,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
unsigned int buflen;
unsigned int len;
unsigned int consumed;
int res;
TRACE(("enter recv_msg_channel_data"))
@@ -860,7 +856,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
/* 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);
res = writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed);
datalen -= consumed;
buf_incrpos(ses.payload, consumed);
@@ -868,17 +864,20 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
/* 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 */
len = datalen;
while (len > 0) {
buflen = cbuf_writelen(cbuf);
buflen = MIN(buflen, len);
* is payload data.
* If the writechannel() failed then remaining data is discarded */
if (res == DROPBEAR_SUCCESS) {
len = datalen;
while (len > 0) {
buflen = cbuf_writelen(cbuf);
buflen = MIN(buflen, len);
memcpy(cbuf_writeptr(cbuf, buflen),
buf_getptr(ses.payload, buflen), buflen);
cbuf_incrwrite(cbuf, buflen);
buf_incrpos(ses.payload, buflen);
len -= buflen;
memcpy(cbuf_writeptr(cbuf, buflen),
buf_getptr(ses.payload, buflen), buflen);
cbuf_incrwrite(cbuf, buflen);
buf_incrpos(ses.payload, buflen);
len -= buflen;
}
}
TRACE(("leave recv_msg_channel_data"))
@@ -970,6 +969,7 @@ void recv_msg_channel_open() {
if (channel == NULL) {
TRACE(("newchannel returned NULL"))
errtype = SSH_OPEN_RESOURCE_SHORTAGE;
goto failure;
}
@@ -991,8 +991,6 @@ void recv_msg_channel_open() {
channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
}
chan_initwritebuf(channel);
/* success */
send_msg_channel_open_confirmation(channel, channel->recvwindow,
channel->recvmaxpacket);
@@ -1135,7 +1133,6 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) {
/* Outbound opened channels don't make use of in-progress connections,
* we can set it up straight away */
chan_initwritebuf(chan);
/* set fd non-blocking */
setnonblocking(fd);

View File

@@ -760,6 +760,7 @@ void kexcurve25519_comb_key(struct kex_curve25519_param *param, buffer *buf_pub_
unsigned char out[CURVE25519_LEN];
const unsigned char* Q_C = NULL;
const unsigned char* Q_S = NULL;
char zeroes[CURVE25519_LEN] = {0};
if (buf_pub_them->len != CURVE25519_LEN)
{
@@ -767,6 +768,11 @@ void kexcurve25519_comb_key(struct kex_curve25519_param *param, buffer *buf_pub_
}
curve25519_donna(out, param->priv, buf_pub_them->data);
if (constant_time_memcmp(zeroes, out, CURVE25519_LEN) == 0) {
dropbear_exit("Bad curve25519");
}
m_mp_alloc_init_multi(&ses.dh_K, NULL);
bytes_to_mp(ses.dh_K, out, CURVE25519_LEN);
m_burn(out, sizeof(out));

View File

@@ -159,6 +159,17 @@ void session_loop(void(*loophandler)()) {
FD_ZERO(&readfd);
dropbear_assert(ses.payload == NULL);
/* We get woken up when signal handlers write to this pipe.
SIGCHLD in svr-chansession is the only one currently. */
FD_SET(ses.signal_pipe[0], &readfd);
ses.channel_signal_pending = 0;
/* set up for channels which can be read/written */
setchannelfds(&readfd, &writefd, writequeue_has_space);
/* Pending connections to test */
set_connect_fds(&writefd);
/* 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
@@ -170,19 +181,12 @@ void session_loop(void(*loophandler)()) {
&& writequeue_has_space) {
FD_SET(ses.sock_in, &readfd);
}
/* Ordering is important, this test must occur after any other function
might have queued packets (such as connection handlers) */
if (ses.sock_out != -1 && !isempty(&ses.writequeue)) {
FD_SET(ses.sock_out, &writefd);
}
/* We get woken up when signal handlers write to this pipe.
SIGCHLD in svr-chansession is the only one currently. */
FD_SET(ses.signal_pipe[0], &readfd);
/* set up for channels which can be read/written */
setchannelfds(&readfd, &writefd, writequeue_has_space);
/* Pending connections to test */
set_connect_fds(&writefd);
val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);
@@ -208,7 +212,9 @@ void session_loop(void(*loophandler)()) {
wake up the select() above. */
if (FD_ISSET(ses.signal_pipe[0], &readfd)) {
char x;
TRACE(("signal pipe set"))
while (read(ses.signal_pipe[0], &x, 1) > 0) {}
ses.channel_signal_pending = 1;
}
/* check for auth timeout, rekeying required etc */

View File

@@ -82,9 +82,19 @@ AC_CHECK_DECL(__UCLIBC__,
AC_MSG_NOTICE([Using uClibc - login() and logout() probably don't work, so we won't use them.])
],,,)
# Checks for libraries.
AC_CHECK_LIB(crypt, crypt, CRYPTLIB="-lcrypt")
dnl We test for crypt() specially. On Linux (and others?) it resides in libcrypt
dnl but we don't want link all binaries to -lcrypt, just dropbear server.
dnl OS X doesn't need -lcrypt
AC_CHECK_FUNC(crypt, found_crypt_func=here)
AC_CHECK_LIB(crypt, crypt,
[
CRYPTLIB="-lcrypt"
found_crypt_func=here
])
AC_SUBST(CRYPTLIB)
if test "t$found_crypt_func" = there; then
AC_DEFINE(HAVE_CRYPT, 1, [crypt() function])
fi
# Check if zlib is needed
AC_ARG_WITH(zlib,
@@ -632,7 +642,7 @@ fi
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_FUNC_SELECT_ARGTYPES
AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork writev])
AC_CHECK_FUNCS([dup2 getpass getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty getaddrinfo freeaddrinfo getnameinfo fork writev])
AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
@@ -719,10 +729,21 @@ AC_OUTPUT
AC_MSG_NOTICE()
if test $BUNDLED_LIBTOM = 1 ; then
AC_MSG_NOTICE(Using bundled libtomcrypt and libtommath)
AC_MSG_NOTICE([Using bundled libtomcrypt and libtommath])
else
AC_MSG_NOTICE(Using system libtomcrypt and libtommath)
AC_MSG_NOTICE([Using system libtomcrypt and libtommath])
fi
if test "x$ac_cv_func_getpass" != xyes; then
AC_MSG_NOTICE()
AC_MSG_NOTICE([getpass() not available, dbclient will only have public-key authentication])
fi
if test "t$found_crypt_func" != there; then
AC_MSG_NOTICE()
AC_MSG_NOTICE([crypt() not available, dropbear server will not have password authentication])
fi
AC_MSG_NOTICE()
AC_MSG_NOTICE(Now edit options.h to choose features.)
AC_MSG_NOTICE([Now edit options.h to choose features.])

View File

@@ -3,25 +3,32 @@
dbclient \- lightweight SSH client
.SH SYNOPSIS
.B dbclient
[\-Tt] [\-p
[\fIflag arguments\fR] [\-p
.I port\fR] [\-i
.I id\fR] [\-L
.I l\fR:\fIh\fR:\fIr\fR] [\-R
.I l\fR:\fIh\fR:\fIr\fR] [\-l
.I l\fR:\fIh\fR:\fIp\fR] [\-R
.I l\fR:\fIh\fR:\fIp\fR] [\-l
.IR user ]
.I host
.RI [ \fImore\ flags\fR ]
.RI [ command ]
.B dbclient
[
.I args ]
.I [user1]@host1[^port1],[user2]@host2[^port2],...
[\fIargs\fR]
[\fIuser1\fR]@\fIhost1\fR[^\fIport1\fR],[\fIuser2\fR]@\fIhost2\fR[^\fIport2\fR],...
.SH DESCRIPTION
.B dbclient
is a small SSH client
.SH OPTIONS
.TP
.TP
.B command
A command to run on the remote host. This will normally be run by the remote host
using the user's shell. The command begins at the first hyphen argument after the
host argument. If no command is specified an interactive terminal will be opened
(see -t and -T).
.TP
.B \-p \fIport
Connect to
.I port
@@ -35,7 +42,7 @@ Read the identity key from file
(multiple allowed). This file is created with dropbearkey(1) or converted
from OpenSSH with dropbearconvert(1). The default path ~/.ssh/id_dropbear is used
.TP
.B \-L [\fIlistenaddress\fR]:\fIlistenport\fR:\fIhost\fR:\fIport\fR
.B \-L\fR [\fIlistenaddress\fR]:\fIlistenport\fR:\fIhost\fR:\fIport\fR
Local port forwarding.
Forward the port
.I listenport
@@ -44,7 +51,7 @@ on the local host through the SSH connection to port
on the host
.IR host .
.TP
.B \-R [\fIlistenaddress\fR]:\fIlistenport\fR:\fIhost\fR:\fIport\fR
.B \-R\fR [\fIlistenaddress\fR]:\fIlistenport\fR:\fIhost\fR:\fIport\fR
Remote port forwarding.
Forward the port
.I listenport
@@ -60,10 +67,12 @@ Login as
on the remote host.
.TP
.B \-t
Allocate a PTY.
Allocate a PTY. This is the default when no command is given, it gives a full
interactive remote session. The main effect is that keystrokes are sent remotely
immediately as opposed to local line-based editing.
.TP
.B \-T
Don't allocate a PTY.
Don't allocate a PTY. This is the default a command is given. See -t.
.TP
.B \-N
Don't request a remote shell or run any commands. Any command arguments are ignored.
@@ -129,7 +138,7 @@ Dropbear will also allow multiple "hops" to be specified, separated by commas. I
this case a connection will be made to the first host, then a TCP forwarded
connection will be made through that to the second host, and so on. Hosts other than
the final destination will not see anything other than the encrypted SSH stream.
A port for a host can be specified with a hash (eg matt@martello^44 ).
A port for a host can be specified with a caret (eg matt@martello^44 ).
This syntax can also be used with scp or rsync (specifying dbclient as the
ssh/rsh command). A file can be "bounced" through multiple SSH hops, eg
@@ -157,6 +166,10 @@ SSH_ASKPASS should be set to the path of a program that will return a password
on standard output. This program will only be used if either DISPLAY is set and
standard input is not a TTY, or the environment variable SSH_ASKPASS_ALWAYS is
set.
.SH NOTES
If compiled with zlib support and if the server supports it, dbclient will
always use compression.
.SH AUTHOR
Matt Johnston (matt@ucc.asn.au).
.br

18
debian/changelog vendored
View File

@@ -1,3 +1,21 @@
dropbear (2015.71-0.1) unstable; urgency=low
* New upstream release.
-- Matt Johnston <matt@ucc.asn.au> Thu, 3 Dec 2015 22:52:58 +0800
dropbear (2015.70-0.1) unstable; urgency=low
* New upstream release.
-- Matt Johnston <matt@ucc.asn.au> Thu, 26 Nov 2015 22:52:58 +0800
dropbear (2015.69-0.1) unstable; urgency=low
* New upstream release.
-- Matt Johnston <matt@ucc.asn.au> Wed, 25 Nov 2015 22:52:58 +0800
dropbear (2015.68-0.1) unstable; urgency=low
* New upstream release.

View File

@@ -3,11 +3,10 @@
dropbear \- lightweight SSH server
.SH SYNOPSIS
.B dropbear
[\-RFEmwsgjki] [\-b
[\fIflag arguments\fR] [\-b
.I banner\fR]
[\-r
.I hostkeyfile\fR] [\-p
.IR [address:]port ]
.I hostkeyfile\fR] [\-p [\fIaddress\fR:]\fIport\fR]
.SH DESCRIPTION
.B dropbear
is a small SSH server
@@ -54,7 +53,7 @@ Disable local port forwarding.
.B \-k
Disable remote port forwarding.
.TP
.B \-p \fI[address:]port
.B \-p\fR [\fIaddress\fR:]\fIport
Listen on specified
.I address
and TCP
@@ -128,7 +127,7 @@ Disable PTY allocation. Note that a user can still obtain most of the
same functionality with other means even if no-pty is set.
.TP
.B command="\fIforced_command\fR"
.B command=\fR"\fIforced_command\fR"
Disregard the command provided by the user and always run \fIforced_command\fR.
The authorized_keys file and its containing ~/.ssh directory must only be

View File

@@ -21,24 +21,24 @@ from a private key by using
.P
Encrypted private keys are not supported, use ssh-keygen(1) to decrypt them
first.
.SH OPTIONS
.SH ARGUMENTS
.TP
.B input type
.I input_type
Either
.I dropbear
or
.I openssh
.TP
.B output type
.I output_type
Either
.I dropbear
or
.I openssh
.TP
.B input file
.I input_file
An existing Dropbear or OpenSSH private key file
.TP
.B output file
.I output_file
The path to write the converted private key file. For client authentication ~/.ssh/id_dropbear is loaded by default
.SH EXAMPLE
# dropbearconvert openssh dropbear ~/.ssh/id_rsa ~/.ssh/id_dropbear

View File

@@ -9,13 +9,11 @@ dropbearkey \- create private keys for the use with dropbear(8) or dbclient(1)
.I file
[\-s
.IR bits ]
[\-y]
.SH DESCRIPTION
.B dropbearkey
generates a
.I RSA
.I DSS,
or
.I ECDSA
\fIRSA\fR, \fIDSS\fR, or \fIECDSA\fR
format SSH private key, and saves it to a file for the use with the
Dropbear client or server.
Note that
@@ -33,18 +31,25 @@ or
.TP
.B \-f \fIfile
Write the secret key to the file
.IR file . For client authentication ~/.ssh/id_dropbear is loaded by default
\fIfile\fR. For client authentication ~/.ssh/id_dropbear is loaded by default
.TP
.B \-s \fIbits
Set the key size to
.I bits
bits, should be multiple of 8 (optional).
.TP
.B \-y
Just print the publickey and fingerprint for the private key in \fIfile\fR.
.SH NOTES
The program dropbearconvert(1) can be used to convert between Dropbear and OpenSSH key formats.
.P
Dropbear does not support encrypted keys.
.SH EXAMPLE
generate a host-key:
# dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
extract a public key suitable for authorized_keys from private key:
# dropbearkey -y -f id_rsa | grep "^ssh-rsa " >> authorized_keys
.SH AUTHOR
Matt Johnston (matt@ucc.asn.au).
.br

16
netio.c
View File

@@ -174,28 +174,26 @@ void remove_connect_pending() {
void set_connect_fds(fd_set *writefd) {
m_list_elem *iter;
TRACE(("enter handle_connect_fds"))
for (iter = ses.conn_pending.first; iter; iter = iter->next) {
TRACE(("enter set_connect_fds"))
iter = ses.conn_pending.first;
while (iter) {
m_list_elem *next_iter = iter->next;
struct dropbear_progress_connection *c = iter->item;
/* Set one going */
while (c->res_iter && c->sock < 0)
{
while (c->res_iter && c->sock < 0) {
connect_try_next(c);
}
if (c->sock >= 0) {
FD_SET(c->sock, writefd);
} else {
m_list_elem *remove_iter;
/* Final failure */
if (!c->errstring) {
c->errstring = m_strdup("unexpected failure");
}
c->cb(DROPBEAR_FAILURE, -1, c->cb_data, c->errstring);
/* Safely remove without invalidating iter */
remove_iter = iter;
iter = iter->prev;
remove_connect(c, remove_iter);
remove_connect(c, iter);
}
iter = next_iter;
}
}

View File

@@ -206,7 +206,10 @@ If you test it please contact the Dropbear author */
* PAM challenge/response.
* You can't enable both PASSWORD and PAM. */
/* This requires crypt() */
#ifdef HAVE_CRYPT
#define ENABLE_SVR_PASSWORD_AUTH
#endif
/* PAM requires ./configure --enable-pam */
/*#define ENABLE_SVR_PAM_AUTH */
#define ENABLE_SVR_PUBKEY_AUTH
@@ -217,9 +220,12 @@ If you test it please contact the Dropbear author */
#define ENABLE_SVR_PUBKEY_OPTIONS
#endif
/* This requires getpass. */
#ifdef HAVE_GETPASS
#define ENABLE_CLI_PASSWORD_AUTH
#define ENABLE_CLI_PUBKEY_AUTH
#define ENABLE_CLI_INTERACT_AUTH
#endif
#define ENABLE_CLI_PUBKEY_AUTH
/* A default argument for dbclient -i <privatekey>.
Homedir is prepended unless path begins with / */

View File

@@ -39,4 +39,7 @@ rm "$RELDIR/.hgtags"
ls -l $ARCHIVE
openssl sha -sha256 $ARCHIVE
echo "Done to $ARCHIVE"
echo Done to
echo "$ARCHIVE"
echo Sign it with
echo gpg2 --detach-sign -a -u F29C6773 "$ARCHIVE"

View File

@@ -33,7 +33,8 @@
typedef struct runopts {
#if defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD)
#if defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) \
|| defined(ENABLE_CLI_REMOTETCPFWD)
int listen_fwd_all;
#endif
unsigned int recv_window;
@@ -71,7 +72,8 @@ typedef struct svr_runopts {
int forkbg;
int usingsyslog;
/* ports is an array of the portcount listening ports */
/* ports and addresses are arrays of the portcount
listening ports. strings are malloced. */
char *ports[DROPBEAR_MAX_PORTS];
unsigned int portcount;
char *addresses[DROPBEAR_MAX_PORTS];

2
scp.c
View File

@@ -992,7 +992,7 @@ sink(int argc, char **argv)
continue;
}
omode = mode;
mode |= S_IWRITE;
mode |= S_IWUSR;
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
bad: run_err("%s: %s", np, strerror(errno));
continue;

View File

@@ -293,10 +293,9 @@ struct clientsession {
int interact_request_received; /* flag whether we've received an
info request from the server for
interactive auth.*/
#endif
int cipher_none_after_auth; /* Set to 1 if the user requested "none"
auth */
#endif
sign_key *lastprivkey;
int retval; /* What the command exit status was - we emulate it */

View File

@@ -814,7 +814,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
login_free_entry(li);
#ifdef DO_MOTD
if (svr_opts.domotd) {
if (svr_opts.domotd && !chansess->cmd) {
/* don't show the motd if ~/.hushlogin exists */
/* 12 == strlen("/.hushlogin\0") */

View File

@@ -33,7 +33,7 @@
svr_runopts svr_opts; /* GLOBAL */
static void printhelp(const char * progname);
static void addportandaddress(char* spec);
static void addportandaddress(const char* spec);
static void loadhostkey(const char *keyfile, int fatal_duplicate);
static void addhostkey(const char *keyfile);
@@ -112,13 +112,14 @@ static void printhelp(const char * progname) {
void svr_getopts(int argc, char ** argv) {
unsigned int i;
unsigned int i, j;
char ** next = 0;
int nextisport = 0;
char* recv_window_arg = NULL;
char* keepalive_arg = NULL;
char* idle_timeout_arg = NULL;
char* keyfile = NULL;
char c;
/* see printhelp() for options */
@@ -168,28 +169,11 @@ void svr_getopts(int argc, char ** argv) {
#endif
for (i = 1; i < (unsigned int)argc; i++) {
if (nextisport) {
addportandaddress(argv[i]);
nextisport = 0;
continue;
}
if (next) {
*next = argv[i];
if (*next == NULL) {
dropbear_exit("Invalid null argument");
}
next = 0x00;
if (argv[i][0] != '-' || argv[i][1] == '\0')
dropbear_exit("Invalid argument: %s", argv[i]);
if (keyfile) {
addhostkey(keyfile);
keyfile = NULL;
}
continue;
}
if (argv[i][0] == '-') {
switch (argv[i][1]) {
for (j = 1; (c = argv[i][j]) != '\0' && !next && !nextisport; j++) {
switch (c) {
case 'b':
next = &svr_opts.bannerfile;
break;
@@ -278,12 +262,39 @@ void svr_getopts(int argc, char ** argv) {
exit(EXIT_SUCCESS);
break;
default:
fprintf(stderr, "Unknown argument %s\n", argv[i]);
fprintf(stderr, "Invalid option -%c\n", c);
printhelp(argv[0]);
exit(EXIT_FAILURE);
break;
}
}
if (!next && !nextisport)
continue;
if (c == '\0') {
i++;
j = 0;
if (!argv[i]) {
dropbear_exit("Missing argument");
}
}
if (nextisport) {
addportandaddress(&argv[i][j]);
nextisport = 0;
} else if (next) {
*next = &argv[i][j];
if (*next == NULL) {
dropbear_exit("Invalid null argument");
}
next = 0x00;
if (keyfile) {
addhostkey(keyfile);
keyfile = NULL;
}
}
}
/* Set up listening ports */
@@ -337,54 +348,56 @@ void svr_getopts(int argc, char ** argv) {
}
}
static void addportandaddress(char* spec) {
char *myspec = NULL;
static void addportandaddress(const char* spec) {
char *spec_copy = NULL, *myspec = NULL, *port = NULL, *address = NULL;
if (svr_opts.portcount < DROPBEAR_MAX_PORTS) {
/* We don't free it, it becomes part of the runopt state */
myspec = m_strdup(spec);
spec_copy = m_strdup(spec);
myspec = spec_copy;
if (myspec[0] == '[') {
myspec++;
svr_opts.ports[svr_opts.portcount] = strchr(myspec, ']');
if (svr_opts.ports[svr_opts.portcount] == NULL) {
port = strchr(myspec, ']');
if (!port) {
/* Unmatched [ -> exit */
dropbear_exit("Bad listen address");
}
svr_opts.ports[svr_opts.portcount][0] = '\0';
svr_opts.ports[svr_opts.portcount]++;
if (svr_opts.ports[svr_opts.portcount][0] != ':') {
port[0] = '\0';
port++;
if (port[0] != ':') {
/* Missing port -> exit */
dropbear_exit("Missing port");
}
} else {
/* search for ':', that separates address and port */
svr_opts.ports[svr_opts.portcount] = strrchr(myspec, ':');
port = strrchr(myspec, ':');
}
if (svr_opts.ports[svr_opts.portcount] == NULL) {
if (!port) {
/* no ':' -> the whole string specifies just a port */
svr_opts.ports[svr_opts.portcount] = myspec;
port = myspec;
} else {
/* Split the address/port */
svr_opts.ports[svr_opts.portcount][0] = '\0';
svr_opts.ports[svr_opts.portcount]++;
svr_opts.addresses[svr_opts.portcount] = myspec;
port[0] = '\0';
port++;
address = myspec;
}
if (svr_opts.addresses[svr_opts.portcount] == NULL) {
if (!address) {
/* no address given -> fill in the default address */
svr_opts.addresses[svr_opts.portcount] = m_strdup(DROPBEAR_DEFADDRESS);
address = DROPBEAR_DEFADDRESS;
}
if (svr_opts.ports[svr_opts.portcount][0] == '\0') {
if (port[0] == '\0') {
/* empty port -> exit */
dropbear_exit("Bad port");
}
svr_opts.ports[svr_opts.portcount] = m_strdup(port);
svr_opts.addresses[svr_opts.portcount] = m_strdup(address);
svr_opts.portcount++;
m_free(spec_copy);
}
}
@@ -540,6 +553,6 @@ void load_all_hostkeys() {
#endif /* DROPBEAR_ECDSA */
if (!any_keys) {
dropbear_exit("No hostkeys available");
dropbear_exit("No hostkeys available. 'dropbear -R' may be useful or run dropbearkey.");
}
}

View File

@@ -4,7 +4,7 @@
*******************************************************************/
#ifndef DROPBEAR_VERSION
#define DROPBEAR_VERSION "2015.68"
#define DROPBEAR_VERSION "2015.71"
#endif
#define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION
@@ -150,7 +150,7 @@
RECV_WINDOWEXTEND bytes */
#define MAX_RECV_WINDOW (1024*1024) /* 1 MB should be enough */
#define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11
#define MAX_CHANNELS 1000 /* simple mem restriction, includes each tcp/x11
connection, so can't be _too_ small */
#define MAX_STRING_LEN (MAX(MAX_CMD_LEN, 2400)) /* Sun SSH needs 2400 for algos,