Hans Harder | 17 Apr 14:12 2013

Patch for usermode server

Added check that only the dropbear user is allowed to login if it is
running as non-root.
Removed the log message,

--- loginrec.c 2013-04-15 08:01:58.000000000 -0600
+++ loginrec.c     2013-04-17 06:01:57.000000000 -0600
 <at>  <at>  -329,8 +329,6  <at>  <at>  login_write (struct logininfo *li)
 #ifndef HAVE_CYGWIN
        if ((int)geteuid() != 0) {
-         dropbear_log(LOG_WARNING,
-                         "Attempt to write login records by non-root
user (aborting)");
          return 1;
--- svr-auth.c 2013-04-15 08:01:58.000000000 -0600
+++ svr-auth.c     2013-04-17 06:00:22.000000000 -0600
 <at>  <at>  -226,6 +226,7  <at>  <at>  static int checkusername(unsigned char *

        char* listshell = NULL;
        char* usershell = NULL;
+       int   uid;
        TRACE(("enter checkusername"))
        if (userlen > MAX_USERNAME_LEN) {
                return DROPBEAR_FAILURE;
 <at>  <at>  -255,6 +256,18  <at>  <at>  static int checkusername(unsigned char *
                return DROPBEAR_FAILURE;

(Continue reading)

Hans Harder | 16 Apr 23:13 2013

Compile errors on 2013.57

I get compile errors with the new version, because I compile this in a
uclib environment without zlib.
I use ./configure --disable-zlib

In common-kex.c I run into compile errors.

common-kex.o(.text+0x203): In function `switch_keys':
: undefined reference to `gen_new_zstream_recv'
common-kex.o(.text+0x257): In function `switch_keys':
: undefined reference to `gen_new_zstream_trans'
collect2: ld returned 1 exit status
make: *** [dropbear] Error 1

Probably this will solve it.

--- common-kex.c        2013-04-16 14:44:42.000000000 -0600
+++ common-kex.c    2013-04-16 15:08:54.000000000 -0600
 <at>  <at>  -171,14 +171,18  <at>  <at>  static void switch_keys() {
        if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) {
                TRACE(("switch_keys recv"))
                ses.keys->recv = ses.newkeys->recv;
                m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv));
                ses.newkeys->recv.valid = 0;
        if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) {
                TRACE(("switch_keys trans"))
(Continue reading)

Ed Sutter | 16 Apr 19:26 2013

dropbearkey question...

I now have the dropbearkey code integrated into my embedded stuff.
I assume the idea is to call this function each time the server starts up.

Then each time the server starts, future client connections will reject the
server connection until $HOME/.ssh/known_hosts is purged of that server's
key information.

Correct so far?
Assuming yes...

Then, the user of the client has to accept the new credentials based on
the RSA key fingerprint from the server.  So, shouldn't the message that
comes out of the client reflect the same fingerprint as that which was
printed when the key was created on the server?

(mine doesn't)

Ed Sutter | 15 Apr 22:36 2013


Sorry for the burst of email, but as I was browsing code that calls 
I may have stumbled on something else...
Does anyone know if the "build_lut" function is ever used?
Take a quick peek at it and notice this...

static int build_lut(int idx, void *modulus, void *mp, void *mu)
    unsigned x, y, err, bitlen, lut_gap;
    void    *tmp;

    tmp = NULL;


    if ((err = mp_init(&tmp)) != CRYPT_OK)
            { goto ERR; }

With mp_init() assuming it is getting a pointer to an mp_int structure,
this looks bad.


Ed Sutter | 15 Apr 22:24 2013

mp_init/mp_clear memory allocation

I started digging into the possibility of reducing the number of malloc/free
calls (by replacing small/quick fixed-size allocations with stack arrays),
and I think I found one that makes a substantial difference...

The call to mp_div_2d() in a loop inside the function 

If I create a version of mp_init() (call it mp_init_nomalloc() that does 
not allocate
and then I put that small array on the stack in mp_div_2d(), I observed 
a dramatic
decrease in the number of malloc/free calls (dropped from about 2100 to 
about 550) for
a single session that simply connects and then exits.

This is tough to observe dynamically without a debuggable malloc (which 
I have);
but its always possible that my diagnostics are off too; hence it would
be nice to get a second set of eyes looking at this to see if my 
observation is
correct.  If it is, then it would apply to any function that does both the
mp_init() and the matching mp_clear() in the same block of code.

New versions of libtomath/bn_mp_div_2d.c and bn_mp_init.c are attached
if someone has time to double check me.

Hopefully I won't realize my mistake immediately after I send this as I
did before and have to retract my statement!!  :-(

(Continue reading)

Ed Sutter | 15 Apr 19:00 2013

embedded dropbear (more)...

Just to put a few things in perspective regarding the likelihood of this
working in a really small embedded system...

Regarding memory...
It really depends on just how small you need to be...

One session looks like it uses upwards of 2100 malloc calls. Long term
fragmentation from one session to the next is not an issue simply because I
have a dedicated heap, which I flush at the end of each session; however
my heap analytics show that the high-water level is under 200K of heap.
I'm hoping that some of these allocations can be replaced with 
stack-based arrays,
but I haven't looked into that much yet.

Regarding speed...
No "real" data here, other than to say that I'm on a ~450Mhz PowerPC (no 
and it seems to be fine.


Ed Sutter | 15 Apr 18:19 2013

embedded dropbear...

I've got what I think is a reasonably stable version of dropbear's SSH 
server working
in a non-posix, thread-based embedded system. I'd like to review the 
changes I
made for anyone that may be considering doing this, but also to see if 
any flags
get raised by the folks that have been using this for a while.

Since I don't really know if there's much interest in this within the 
group, I'll skip
a lot of detail for this pass and just note the main points.  Then if it 
turns out that
this is of interest we can dig in more (and I'll probably learn 

- A single ssh login at any given time, to connect to an embedded 
command line interface
   (no shell, no processes, no posix, etc..).

- Running a small kernel that supports threads;
- Using GCC for powerpc.
- I assume very little about any OS support for anything other than libc 
(in my case I do
   have an embedded FS, but that's easily bypassed).  In other words: no 
shell process,
   no fork(), no exec(), no pipes, etc..  This includes no use of 
fprintf(...) as well.
(Continue reading)

Matt Johnston | 15 Apr 16:14 2013

Dropbear 2013.57 released

Hi all,

I've put up Dropbear 2013.57 as usual at

As well as a few bug fixes it has significant improvements
to the number of round trips required to set up a connection
- useful for high latency links.


2013.57 - Monday 15 April 2013

- Decreased connection setup time particularly with high latency connections,
  the number of round trips has been reduced for both client and server. 
  CPU time hasn't been changed.

- Client will send an initial key exchange guess to save a round trip.
  Dropbear implements an extension kexguess2 <at> matt.ucc.asn.au to allow the first
  packet guess to succeed in wider circumstances than the standard behaviour.
  When communicating with other implementations the standard behaviour is used.

- Client side: when public key or password authentication with
  $DROPBEAR_PASSWORD is used an initial authentication request will
  be sent immediately rather than querying the list of available methods.
  This behaviour is enabled by CLI_IMMEDIATE_AUTH option (on by default),
  please let the Dropbear author know if it causes any interoperability

(Continue reading)

Ed Sutter | 11 Apr 23:56 2013

embedded dropbear

I managed to get dropbear-ssh running under a uC/OS-II thread.
Obviously had to do a lot of hacking to make this work, and
I'm sure its not the most efficient way of doing it.

Not being an ssh/cryptography wizard by any stretch of the
imagination, I have two questions that may be trivial...

Because I'm not on a Unix-ish system, I don't have any of
the /proc stuff or /dev/urandom for seedrandom().  Is it
essential that this function have *that* much random
input?  How does this affect the security of the connection?

I essentially hard-coded the -r option (ssh server) to use a
pre-established rsa_host_key file.  Should this file be built
once for a given system, and then reused or is this something
that should be recreated each time the server is started?

Thanks in advance,

hhm | 11 Apr 09:26 2013

[PATCH] add dropbearmulti arg1 support

This patch adds support for calling dropbearmulti with a program name as its *first* parameter.

This enables use of dropbearmulti without any symlinks. The following are examples of where this can be useful:
1) on file systems which do not support symlinks (FAT for example)
2) for convenience; needing only one file


diff -u a/dbmulti.c b/dbmulti.c
--- a/dbmulti.c
+++ b/dbmulti.c
<at> <at> -33,10 +33,33 <at> <at>
 int main(int argc, char ** argv) {
  char * progname;
+ int arg1;
- if (argc > 0) {
- /* figure which form we're being called as */
- progname = basename(argv[0]);
+ if (argc > 0 
+ || argc < 0
+ ) {
+ if (argc > 0) {
+ arg1 = 0;
+ /* figure which form we're being called as */
+ progname = basename(argv[0]);
+ } else {
+ char buf[64];
+ arg1 = -1;
+ progname = argv[1];
+ snprintf(buf, sizeof buf, "%s %s", argv[0], progname); /* this appears in usages, maybe should just use original argv0 if needed by a sub-program */
+ argv[1] = buf; /* new argv[0] */
+ argv += 1;
+ argc = -argc; /* restore argc to pre-signaling state */
+ argc -= 1;
+ }
 #ifdef DBMULTI_dropbear
  if (strcmp(progname, "dropbear") == 0) {
<at> <at> -66,8 +89,19 <at> <at>
+ if (!arg1 && argc > 1) { /* matched none of the prognames, has args on cmdline */
+ argc = -argc; /* negate argc as signal */
+ return main(argc, argv);
+ }
fprintf(stderr, "Dropbear SSH multi-purpose v%s\n"
- "Make a symlink pointing at this binary with one of the following names:\n"
+ "Make a symlink pointing at this binary"
+ ", or pass a name to it as the first parameter,"
+ " with one of the following names:\n"
 #ifdef DBMULTI_dropbear
  "'dropbear' - the Dropbear server\n"
diff -u a/MULTI b/MULTI
--- a/MULTI
+++ b/MULTI
<at> <at> -21,6 +21,12 <at> <at>
 ./dropbear <options here>
+Alternatively, call dropbearmulti with the name of an executable as its first argument (if this option was chosen):
+./dropbearmulti dropbear <options here>
+./dropbearmulti dbclient <options here>
 "make install" doesn't currently work for multi-binary configuration, though
 in most situations where it is being used, the target and build systems will
diff -u a/options.h b/options.h
--- a/options.h
+++ b/options.h
<at> <at> -14,6 +14,11 <at> <at>
 #define DROPBEAR_DEFPORT "22"
+/* Dropbearmulti program invocation via argv1 */
 /* Listen on all interfaces */
Hans Harder | 7 Apr 16:03 2013

Patch for stricthostkey and a multihop fix

Underneath some modifications against a stock 2013.56 version

- Added -Y option to completely ignore check for hostkeys
  Needed this for connections to logical hosts, same as openssh -o

- Added -y and -Y in function multihop_passthrough_args

- fix: in function multihop_passthrough_args there was no space kept
between the -W and -i args
  so added always a space after each added arg
  after last addition the last space is removed.

I am new to the dropbear sources, so perhaps I didn't see it
correctly....if so please correct me...
Overall nice sourcecode, very clean.

Quote:  ech`echo xiun|tr nu oc|sed 'sx\([sx]\)\([xoi]\)xo un\2\1 is xg'`ol

diff -ruBpN dropbear-2013.56/cli-kex.c work/cli-kex.c
--- dropbear-2013.56/cli-kex.c  2013-03-21 08:29:34.000000000 -0700
+++ work/cli-kex.c      2013-04-07 03:01:31.000000000 -0600
 <at>  <at>  -217,6 +217,11  <at>  <at>  static void checkhostkey(unsigned char*
        buffer * line = NULL;
        int ret;

+       if (!cli_opts.strict_hostkey) {
+               TRACE(("strict_hostkey disabled, ignoring hostkey check"));
+               return;
+        }
        hostsfile = open_known_hosts_file(&readonly);
        if (!hostsfile) {
                ask_to_confirm(keyblob, keybloblen);
diff -ruBpN dropbear-2013.56/cli-runopts.c work/cli-runopts.c
--- dropbear-2013.56/cli-runopts.c      2013-03-21 08:29:34.000000000 -0700
+++ work/cli-runopts.c  2013-04-07 03:08:59.000000000 -0600
 <at>  <at>  -62,6 +62,7  <at>  <at>  static void printhelp() {
                                        "-N    Don't run a remote command\n"
                                        "-f    Run in background after auth\n"
                                        "-y    Always accept remote
host key if unknown\n"
+                                       "-Y    Always ignore the
remote host key\n"
                                        "-s    Request a subsystem
(use by external sftp)\n"
                                        "-i <identityfile>   (multiple
 <at>  <at>  -130,6 +131,7  <at>  <at>  void cli_getopts(int argc, char ** argv)
        cli_opts.backgrounded = 0;
        cli_opts.wantpty = 9; /* 9 means "it hasn't been touched",
gets set later */
        cli_opts.always_accept_key = 0;
+       cli_opts.strict_hostkey = 1;
        cli_opts.is_subsystem = 0;
        cli_opts.privkeys = list_new();
 <at>  <at>  -215,6 +217,9  <at>  <at>  void cli_getopts(int argc, char ** argv)
                                case 'y': /* always accept the remote hostkey */
                                        cli_opts.always_accept_key = 1;
+                               case 'Y': /* always ignore the remote hostkey */
+                                       cli_opts.strict_hostkey = 0;
+                                       break;
                                case 'p': /* remoteport */
                                        next = &cli_opts.remoteport;
 <at>  <at>  -461,20 +466,32  <at>  <at>  multihop_passthrough_args() {
        int total;
        unsigned int len = 0;
        m_list_elem *iter;
-       /* Fill out -i and -W options that make sense for all
+       /* Fill out -i , -W, -y and -Y options that make sense for all
         * the intermediate processes */
        for (iter = cli_opts.privkeys->first; iter; iter = iter->next)
                sign_key * key = (sign_key*)iter->item;
                len += 3 + strlen(key->filename);
-       len += 20; // space for -W <size>, terminator.
+       len += 30; // space for -W <size>, terminator.
        ret = m_malloc(len);
        total = 0;

+       if (cli_opts.always_accept_key)
+       {
+               int written = snprintf(ret+total, len-total, "-y ");
+               total += written;
+       }
+       if (cli_opts.strict_hostkey == 0)
+       {
+               int written = snprintf(ret+total, len-total, "-Y ");
+               total += written;
+       }
        if (opts.recv_window != DEFAULT_RECV_WINDOW)
-               int written = snprintf(ret+total, len-total, "-W %d",
+               int written = snprintf(ret+total, len-total, "-W %d ",
                total += written;

 <at>  <at>  -482,11 +499,17  <at>  <at>  multihop_passthrough_args() {
                sign_key * key = (sign_key*)iter->item;
                const size_t size = len - total;
-               int written = snprintf(ret+total, size, "-i %s", key->filename);
+               int written = snprintf(ret+total, size, "-i %s ",
                dropbear_assert((unsigned int)written < size);
                total += written;
+       /* if args where passed, total will be not zero, and it will
have a space at the end, so remove that */
+       if (total) total--;
+       /* make sure arg string is ended, especially if no args were passed. */
+       ret[total]='\0';
        return ret;

diff -ruBpN dropbear-2013.56/runopts.h work/runopts.h
--- dropbear-2013.56/runopts.h  2013-03-21 08:29:35.000000000 -0700
+++ work/runopts.h      2013-04-07 01:55:25.000000000 -0700
 <at>  <at>  -121,6 +121,7  <at>  <at>  typedef struct cli_runopts {
        char *cmd;
        int wantpty;
        int always_accept_key;
+       int strict_hostkey;
        int no_cmd;
        int backgrounded;
        int is_subsystem;