Kevin Johnson | 29 Apr 16:20 2013

segfault in svr-authpasswd.c

For users with locked accounts, dropbear segfaults on password
authentication. The call to crypt() with glibc 2.17 returns NULL if
the passwd field is '!'. Strcmp() segfaults on the NULL value. Here's
a patch against 2013.58 that adds a check.

--- svr-authpasswd.c.old
+++ svr-authpasswd.c
 <at>  <at>  -66,6 +66,12  <at>  <at> 
     m_burn(password, passwordlen);

+    if (testcrypt == NULL) {
+        dropbear_log(LOG_WARNING, "Crypt against user '%s' password
failed, rejected",
+                ses.authstate.pw_name);
+        send_msg_userauth_failure(0, 1);
+        return;
+    }
     /* check for empty password */
     if (passwdcrypt[0] == '\0') {
         dropbear_log(LOG_WARNING, "User '%s' has blank password, rejected",

Kevin Johnson

Ed Sutter | 25 Apr 20:57 2013


I have a modified version of the dropbear ssh server running in
a multitasking RTOS environment that is not POSIX compliant.
In almost all cases it is running perfectly...
I run load tests on it by just using a simple expect script
that spawns an ssh client and sends commands and expects
responses (in a loop).
If, within that loop, I occasionally (every ~30 minutes)
disconnect and reconnect then I can let that run *forever*
(haven't fully tested that).  :-(

The problem I run into is if I just make an initial connection
and put the script in a loop that simply keeps issuing commands
and responses (I never disconnect; just maintain the initial session).
After some unpredictable amount of time (usually it takes an hour or
more); having invoked a few thousand commands, suddenly everything
just stops.  The server is sitting in the select of the session_loop,
and the client (in the expect script) is just waiting for a response.

It seems like everything is where its supposed to be, but the client
is not able to send any characters to the server.  It appears that the
connection dropped; however, I'm fairly certain that it has not.

So, I apparently broke something; hence my question...

After the client/server transactions for key exchange, login/password etc..
are complete and basically both sides are just passing encrypted data back
and forth, is there any other periodic responsibility (on the servers' part)
to issue any "keep-alive" type of commands (or something similar) that I
have not implemented?
(Continue reading)

Yuan-Yi Chang | 19 Apr 10:24 2013

About "DEFAULT_PATH" and "_PATH_SSH_PROGRAM" variables


I'm new to Embedded System World.  There are some problems, "scp not found", when I use dropbear-scp to copy some files. I trace the source code to find the DEFINE variables: DEFAULT_PATH & _PATH_SSH_PROGRAM.

Could we redefine it at configure or make process without modify the source code?

like that:
 #define _PATH_SSH_PROGRAM "/usr/bin/dbclient"

 #define DEFAULT_PATH "/usr/bin:/bin"

and then:
$ ./configure
$ CFLAGS=' -D_PATH_SSH_PROGRAM="/path/dbclient" -DDDEFAULT_PATH="/usr/bin:/bin:/mnt/ubi_boot/bin"  ' make
$ CFLAGS=' -D_PATH_SSH_PROGRAM="/path/dbclient" -DDDEFAULT_PATH="/usr/bin:/bin:/mnt/ubi_boot/bin"  ' make scp

Best Regards, 
Yuan-Yi Chang
Jonathan Chetwynd | 19 Apr 10:20 2013

howto: send the X commands to the X server on your host.

does dbclient take a command similar to -X in ssh?
to send the X commands to the X server on your host.

if not is there a workaround or plans to implement?

kind regards


Jonathan Chetwynd
Eyetracking in HTML5

Matt Johnston | 18 Apr 17:10 2013

Dropbear 2013.58 released

Hi all,

I've put up a new release 2013.58 that fixes building
2013.57 without zlib, and a couple of other things
thanks to Hans Harder.

As usual


2013.58 - Thursday 18 April 2013

- Fix building with Zlib disabled, thanks to Hans Harder and cuma <at> freetz

- Use % as a separator for ports, fixes scp in multihop mode, from Hans Harder

- Reject logins for other users when running as non-root, from Hans Harder

- Disable client immediate authentication request by default, it prevents
  passwordless logins from working

Hans Harder | 17 Apr 14:23 2013

Patch multihop scp with different ports

I had some problems with the multihop for scp using different portnumbers.
The original syntax uses / as separator, which conflicts with the
current code in scp for detecting source and destination
Ex.  scp file user <at> host1/2222,user <at> host2/22:.

Simplest way of solvng this was to allow also another char as
separator for a port, like '#'
So you can do: scp file user <at> host1#2222,user <at> host2#22:.

Just a one liner, which allows now to use both chars as a separator

--- cli-runopts.c      2013-04-15 08:01:57.000000000 -0600
+++ cli-runopts.c  2013-04-17 06:14:56.000000000 -0600
 <at>  <at>  -611,6 +611,7  <at>  <at>  static void parse_hostname(const char* o

        port = strchr(cli_opts.remotehost, '/');
+        if (!port)  port = strchr(cli_opts.remotehost, '#');
        if (port) {
                *port = '\0';
                cli_opts.remoteport = port+1;

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;

+       /* check if we are running as non-root, and login user is
different from the server */
+       uid=geteuid();
+       if (uid != 0 && uid != ses.authstate.pw_uid) {
+               TRACE(("running as nonroot, only server uid is allowed"))
+               dropbear_log(LOG_WARNING,
+                       "Login attempt with wrong user %s from %s",
+                       ses.authstate.pw_name,
+                       svr_ses.addrstring);
+               send_msg_userauth_failure(0, 1);
+               return DROPBEAR_FAILURE;
+       }
        /* check for non-root if desired */
        if (svr_opts.norootlogin && ses.authstate.pw_uid == 0) {
                TRACE(("leave checkusername: root login disabled"))

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"))
                ses.keys->trans = ses.newkeys->trans;
                m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans));
                ses.newkeys->trans.valid = 0;

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!!  :-(

Attachment (bn_mp_init.c): text/x-csrc, 1490 bytes
Attachment (bn_mp_div_2d.c): text/x-csrc, 2481 bytes