merge of 9522146cb07d4576f161fc4567c2c2fbd6f61fbb

and b11630c15bc4d0649dba51c3572cac6f44e0ab0e

--HG--
extra : convert_revision : e0686662cdbee8c0b06e72e6105a390ea4f4c007
This commit is contained in:
Matt Johnston 2005-07-08 13:28:03 +00:00
commit aaa0b1ec3c
47 changed files with 373 additions and 230 deletions

21
CHANGES
View File

@ -1,3 +1,24 @@
0.46
- Fix long-standing bug which caused connections to be closed if an ssh-agent
socket was no longer available
- print a warning if we seem to be blocking on /dev/random
(suggested by Paul Fox)
- fixed a memory leak in DSS code (thanks to Boris Berezovsky for the patch)
- dbclient -L no longer segfaults, allocate correct buffer size (thanks
to David Cook for reporting it)
- added RSA blinding (recommended by Dan Kaminsky)
- rearranged bignum reading/random generation code
- Reset the non-blocking status on stderr and stdout as well as stdin,
fixes a problem where the shell running dbclient will exit (thanks to
Brent Roman for reporting it)
0.45 - Mon March 7 2005
- Makefile no longer appends 'static' to statically linked binaries

View File

@ -69,7 +69,7 @@ AR=@AR@
RANLIB=@RANLIB@
STRIP=@STRIP@
INSTALL=@INSTALL@
CFLAGS=-I. -I$(srcdir)/libtomcrypt @CFLAGS@
CFLAGS=-I. -I$(srcdir)/libtomcrypt/src/headers/ @CFLAGS@
LIBS=$(LTC) $(LTM) @LIBS@
LDFLAGS=@LDFLAGS@

8
TODO
View File

@ -2,12 +2,12 @@ Current:
Things which might need doing:
- default private dbclient keys
- Make options.h generated from configure perhaps?
- Improved queueing of unauthed connections
- fix agent fwd problems
- handle /etc/environment in AIX
- check that there aren't timing issues with valid/invalid user authentication
@ -15,9 +15,9 @@ Things which might need doing:
- Binding to different interfaces
- possible RSA blinding? need to check whether this is vuln to timing attacks
- check PRNG
- CTR mode, SSH_MSG_IGNORE sending to improve CBC security
- CTR mode
- SSH_MSG_IGNORE sending to improve CBC security
- DH Group Exchange possibly, or just add group14 (whatever it's called today)
- fix scp.c for IRIX

4
algo.h
View File

@ -51,13 +51,13 @@ extern const struct dropbear_cipher dropbear_nocipher;
extern const struct dropbear_hash dropbear_nohash;
struct dropbear_cipher {
const struct _cipher_descriptor *cipherdesc;
const struct ltc_cipher_descriptor *cipherdesc;
unsigned long keysize;
unsigned char blocksize;
};
struct dropbear_hash {
const struct _hash_descriptor *hashdesc;
const struct ltc_hash_descriptor *hashdesc;
unsigned long keysize;
unsigned char hashsize;
};

8
auth.h
View File

@ -84,13 +84,13 @@ struct AuthState {
};
struct PubkeyList;
/* A singly linked list of pubkeys */
struct PubkeyList {
struct SignKeyList;
/* A singly linked list of signing keys */
struct SignKeyList {
sign_key *key;
int type; /* The type of key */
struct PubkeyList *next;
struct SignKeyList *next;
/* filename? or the buffer? for encrypted keys, so we can later get
* the private key portion */

View File

@ -52,9 +52,9 @@ void m_mp_init_multi(mp_int *mp, ...)
va_end(args);
}
void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len) {
void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) {
if (mp_read_unsigned_bin(mp, bytes, len) != MP_OKAY) {
if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) {
dropbear_exit("mem alloc error");
}
}

View File

@ -29,7 +29,7 @@
void m_mp_init(mp_int *mp);
void m_mp_init_multi(mp_int *mp, ...);
void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len);
void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len);
void sha1_process_mp(hash_state *hs, mp_int *mp);
#endif /* _BIGNUM_H_ */

View File

@ -160,6 +160,16 @@ unsigned char buf_getbyte(buffer* buf) {
return buf->data[buf->pos++];
}
/* Get a bool from the buffer and increment the pos */
unsigned char buf_getbool(buffer* buf) {
unsigned char b;
b = buf_getbyte(buf);
if (b != 0)
b = 1;
return b;
}
/* put a byte, incrementing the length if required */
void buf_putbyte(buffer* buf, unsigned char val) {

View File

@ -50,6 +50,7 @@ void buf_setpos(buffer* buf, unsigned int pos);
void buf_incrpos(buffer* buf, int incr); /* -ve is ok, to go backwards */
void buf_incrwritepos(buffer* buf, unsigned int incr);
unsigned char buf_getbyte(buffer* buf);
unsigned char buf_getbool(buffer* buf);
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);

View File

@ -100,7 +100,7 @@ void chaninitialise();
void chancleanup();
void setchannelfds(fd_set *readfd, fd_set *writefd);
void channelio(fd_set *readfd, fd_set *writefd);
struct Channel* getchannel(unsigned int chan);
struct Channel* getchannel();
struct Channel* newchannel(unsigned int remotechan,
const struct ChanType *type,
unsigned int transwindow, unsigned int transmaxpacket);

View File

@ -127,7 +127,7 @@ void recv_msg_userauth_failure() {
methods = buf_getstring(ses.payload, &methlen);
partial = buf_getbyte(ses.payload);
partial = buf_getbool(ses.payload);
if (partial) {
dropbear_log(LOG_INFO, "Authentication partially succeeded, more attempts required");

View File

@ -38,29 +38,29 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign);
* We use it to remove the key we tried from the list */
void cli_pubkeyfail() {
struct PubkeyList *keyitem;
struct PubkeyList **previtem;
struct SignKeyList *keyitem;
struct SignKeyList **previtem;
TRACE(("enter cli_pubkeyfail"))
previtem = &cli_opts.pubkeys;
previtem = &cli_opts.privkeys;
/* Find the key we failed with, and remove it */
for (keyitem = cli_opts.pubkeys; keyitem != NULL; keyitem = keyitem->next) {
if (keyitem == cli_ses.lastpubkey) {
for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) {
if (keyitem == cli_ses.lastprivkey) {
*previtem = keyitem->next;
}
previtem = &keyitem;
}
sign_key_free(cli_ses.lastpubkey->key); /* It won't be used again */
m_free(cli_ses.lastpubkey);
sign_key_free(cli_ses.lastprivkey->key); /* It won't be used again */
m_free(cli_ses.lastprivkey);
TRACE(("leave cli_pubkeyfail"))
}
void recv_msg_userauth_pk_ok() {
struct PubkeyList *keyitem;
struct SignKeyList *keyitem;
buffer* keybuf;
char* algotype = NULL;
unsigned int algolen;
@ -80,7 +80,7 @@ void recv_msg_userauth_pk_ok() {
/* Iterate through our keys, find which one it was that matched, and
* send a real request with that key */
for (keyitem = cli_opts.pubkeys; keyitem != NULL; keyitem = keyitem->next) {
for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) {
if (keyitem->type != keytype) {
/* Types differed */
@ -172,11 +172,11 @@ int cli_auth_pubkey() {
TRACE(("enter cli_auth_pubkey"))
if (cli_opts.pubkeys != NULL) {
if (cli_opts.privkeys != NULL) {
/* Send a trial request */
send_msg_userauth_pubkey(cli_opts.pubkeys->key,
cli_opts.pubkeys->type, 0);
cli_ses.lastpubkey = cli_opts.pubkeys;
send_msg_userauth_pubkey(cli_opts.privkeys->key,
cli_opts.privkeys->type, 0);
cli_ses.lastprivkey = cli_opts.privkeys;
TRACE(("leave cli_auth_pubkey-success"))
return 1;
} else {

View File

@ -33,15 +33,12 @@
/* We receive channel data - only used by the client chansession code*/
void recv_msg_channel_extended_data() {
unsigned int chan;
struct Channel *channel;
unsigned int datatype;
TRACE(("enter recv_msg_channel_extended_data"))
chan = buf_getint(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
dropbear_exit("Unknown channel");
}

View File

@ -62,7 +62,7 @@ static void cli_chansessreq(struct Channel *channel) {
TRACE(("enter cli_chansessreq"))
type = buf_getstring(ses.payload, NULL);
wantreply = buf_getbyte(ses.payload);
wantreply = buf_getbool(ses.payload);
if (strcmp(type, "exit-status") != 0) {
TRACE(("unknown request '%s'", type))

View File

@ -53,7 +53,7 @@ static void printhelp() {
"-i <identityfile> (multiple allowed)\n"
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
"-L <listenport:remotehsot:reportport> Local port forwarding\n"
"-L <listenport:remotehost:remoteport> Local port forwarding\n"
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
@ -89,7 +89,7 @@ void cli_getopts(int argc, char ** argv) {
cli_opts.cmd = NULL;
cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */
#ifdef ENABLE_CLI_PUBKEY_AUTH
cli_opts.pubkeys = NULL;
cli_opts.privkeys = NULL;
#endif
#ifdef ENABLE_CLI_LOCALTCPFWD
cli_opts.localfwds = NULL;
@ -271,7 +271,7 @@ void cli_getopts(int argc, char ** argv) {
#ifdef ENABLE_CLI_PUBKEY_AUTH
static void loadidentityfile(const char* filename) {
struct PubkeyList * nextkey;
struct SignKeyList * nextkey;
sign_key *key;
int keytype;
@ -284,11 +284,11 @@ static void loadidentityfile(const char* filename) {
} else {
nextkey = (struct PubkeyList*)m_malloc(sizeof(struct PubkeyList));
nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList));
nextkey->key = key;
nextkey->next = cli_opts.pubkeys;
nextkey->next = cli_opts.privkeys;
nextkey->type = keytype;
cli_opts.pubkeys = nextkey;
cli_opts.privkeys = nextkey;
}
}
#endif

View File

@ -113,16 +113,20 @@ static void cli_session_init() {
cli_ses.tty_raw_mode = 0;
cli_ses.winchange = 0;
/* We store stdin's flags, so we can set them back on exit (otherwise
* busybox's ash isn't happy */
/* We store std{in,out,err}'s flags, so we can set them back on exit
* (otherwise busybox's ash isn't happy */
cli_ses.stdincopy = dup(STDIN_FILENO);
cli_ses.stdinflags = fcntl(STDIN_FILENO, F_GETFL, 0);
cli_ses.stdoutcopy = dup(STDOUT_FILENO);
cli_ses.stdoutflags = fcntl(STDOUT_FILENO, F_GETFL, 0);
cli_ses.stderrcopy = dup(STDERR_FILENO);
cli_ses.stderrflags = fcntl(STDERR_FILENO, F_GETFL, 0);
cli_ses.retval = EXIT_SUCCESS; /* Assume it's clean if we don't get a
specific exit status */
/* Auth */
cli_ses.lastpubkey = NULL;
cli_ses.lastprivkey = NULL;
cli_ses.lastauthtype = 0;
/* For printing "remote host closed" for the user */
@ -250,9 +254,11 @@ void cli_session_cleanup() {
return;
}
/* Set stdin back to non-blocking - busybox ash dies nastily
* if we don't revert the flags */
/* Set std{in,out,err} back to non-blocking - busybox ash dies nastily if
* we don't revert the flags */
fcntl(cli_ses.stdincopy, F_SETFL, cli_ses.stdinflags);
fcntl(cli_ses.stdoutcopy, F_SETFL, cli_ses.stdoutflags);
fcntl(cli_ses.stderrcopy, F_SETFL, cli_ses.stderrflags);
cli_tty_cleanup();

View File

@ -94,7 +94,7 @@ static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr,
remoteport));
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener*));
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
tcpinfo->sendaddr = m_strdup(remoteaddr);
tcpinfo->sendport = remoteport;
tcpinfo->listenport = listenport;

View File

@ -125,7 +125,7 @@ algo_type sshkex[] = {
* This should be run before using any of the ciphers/hashes */
void crypto_init() {
const struct _cipher_descriptor *regciphers[] = {
const struct ltc_cipher_descriptor *regciphers[] = {
#ifdef DROPBEAR_AES128_CBC
&aes_desc,
#endif
@ -141,7 +141,7 @@ void crypto_init() {
NULL
};
const struct _hash_descriptor *reghashes[] = {
const struct ltc_hash_descriptor *reghashes[] = {
/* we need sha1 for hostkey stuff regardless */
&sha1_desc,
#ifdef DROPBEAR_MD5_HMAC

View File

@ -162,8 +162,13 @@ struct Channel* newchannel(unsigned int remotechan,
return newchan;
}
/* Get the channel structure corresponding to a channel number */
struct Channel* getchannel(unsigned int chan) {
/* Returns the channel structure corresponding to the channel in the current
* data packet (ses.payload must be positioned appropriately) */
struct Channel* getchannel() {
unsigned int chan;
chan = buf_getint(ses.payload);
if (chan >= ses.chansize || ses.channels[chan] == NULL) {
return NULL;
}
@ -474,14 +479,11 @@ void setchannelfds(fd_set *readfd, fd_set *writefd) {
* etc) FD is also EOF */
void recv_msg_channel_eof() {
unsigned int chan;
struct Channel * channel;
TRACE(("enter recv_msg_channel_eof"))
chan = buf_getint(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
dropbear_exit("EOF for unknown channel");
}
@ -500,15 +502,11 @@ void recv_msg_channel_eof() {
/* Handle channel closure(), respond in kind and close the channels */
void recv_msg_channel_close() {
unsigned int chan;
struct Channel * channel;
TRACE(("enter recv_msg_channel_close"))
chan = buf_getint(ses.payload);
TRACE(("close channel = %d", chan))
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
/* disconnect ? */
dropbear_exit("Close for unknown channel");
@ -567,14 +565,11 @@ static void deletechannel(struct Channel *channel) {
* such as chansession or x11fwd */
void recv_msg_channel_request() {
unsigned int chan;
struct Channel *channel;
TRACE(("enter recv_msg_channel_request"))
chan = buf_getint(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
/* disconnect ? */
dropbear_exit("Unknown channel");
@ -666,12 +661,9 @@ static void send_msg_channel_data(struct Channel *channel, int isextended,
/* We receive channel data */
void recv_msg_channel_data() {
unsigned int chan;
struct Channel *channel;
chan = buf_getint(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
dropbear_exit("Unknown channel");
}
@ -738,13 +730,10 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd,
* as data is sent, and incremented upon receiving window-adjust messages */
void recv_msg_channel_window_adjust() {
unsigned int chan;
struct Channel * channel;
unsigned int incr;
chan = buf_getint(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
dropbear_exit("Unknown channel");
}
@ -961,14 +950,12 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) {
* successful*/
void recv_msg_channel_open_confirmation() {
unsigned int chan;
struct Channel * channel;
int ret;
TRACE(("enter recv_msg_channel_open_confirmation"))
chan = buf_getint(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
dropbear_exit("Unknown channel");
}
@ -977,7 +964,8 @@ void recv_msg_channel_open_confirmation() {
channel->transwindow = buf_getint(ses.payload);
channel->transmaxpacket = buf_getint(ses.payload);
TRACE(("new chan remote %d localho %d", channel->remotechan, chan))
TRACE(("new chan remote %d local %d",
channel->remotechan, channel->index))
/* Run the inithandler callback */
if (channel->type->inithandler) {
@ -995,11 +983,9 @@ void recv_msg_channel_open_confirmation() {
/* Notification that our channel open request failed */
void recv_msg_channel_open_failure() {
unsigned int chan;
struct Channel * channel;
chan = buf_getbyte(ses.payload);
channel = getchannel(chan);
channel = getchannel();
if (channel == NULL) {
dropbear_exit("Unknown channel");
}

View File

@ -457,7 +457,6 @@ void recv_msg_kexinit() {
/* the rest of ses.kexhashbuf will be done after DH exchange */
ses.kexstate.recvkexinit = 1;
// ses.expecting = 0; // client matt
TRACE(("leave recv_msg_kexinit"))
}
@ -470,18 +469,13 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) {
DEF_MP_INT(dh_p);
DEF_MP_INT(dh_q);
DEF_MP_INT(dh_g);
unsigned char randbuf[DH_P_LEN];
int dh_q_len;
TRACE(("enter send_msg_kexdh_reply"))
m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL);
/* read the prime and generator*/
if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN)
!= MP_OKAY) {
dropbear_exit("Diffie-Hellman error");
}
bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN);
if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) {
dropbear_exit("Diffie-Hellman error");
@ -496,16 +490,8 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) {
dropbear_exit("Diffie-Hellman error");
}
dh_q_len = mp_unsigned_bin_size(&dh_q);
/* calculate our random value dh_y */
do {
assert((unsigned int)dh_q_len <= sizeof(randbuf));
genrandom(randbuf, dh_q_len);
if (mp_read_unsigned_bin(dh_priv, randbuf, dh_q_len) != MP_OKAY) {
dropbear_exit("Diffie-Hellman error");
}
} while (mp_cmp(dh_priv, &dh_q) == MP_GT || mp_cmp_d(dh_priv, 0) != MP_GT);
/* Generate a private portion 0 < dh_priv < dh_q */
gen_random_mpint(&dh_q, dh_priv);
/* f = g^y mod p */
if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) {
@ -527,10 +513,7 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
/* read the prime and generator*/
mp_init(&dh_p);
if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN)
!= MP_OKAY) {
dropbear_exit("Diffie-Hellman error");
}
bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN);
/* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
if (mp_cmp(dh_pub_them, &dh_p) != MP_LT
@ -683,7 +666,7 @@ static void read_kex_algos() {
buf_eatstring(ses.payload);
/* first_kex_packet_follows */
if (buf_getbyte(ses.payload)) {
if (buf_getbool(ses.payload)) {
ses.kexstate.firstfollows = 1;
/* if the guess wasn't good, we ignore the packet sent */
if (!allgood) {

69
dbclient.1 Normal file
View File

@ -0,0 +1,69 @@
.TH dbclient 1
.SH NAME
dbclient \- lightweight SSH2 client
.SH SYNOPSIS
.B dbclient
[\-Tt] [\-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
.IR user ]
.I host
.SH DESCRIPTION
.B dbclient
is a SSH 2 client designed to be small enough to be used in small memory
environments, while still being functional and secure enough for general use.
.SH OPTIONS
.TP
.B \-p \fIport
Remote port.
Connect to port
.I port
on the remote host.
Default is 22.
.TP
.B \-i \fIidfile
Identity file.
Read the identity from file
.I idfile
(multiple allowed).
.TP
.B \-L \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR
Local port forwarding.
Forward the port
.I localport
on the local host to port
.I remoteport
on the remote host
.IR remotehost .
.TP
.B \-R \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR
Remote port forwarding.
Forward the port
.I remoteport
on the remote host
.I remotehost
to port
.I localport
on the local host.
.TP
.B \-l \fIuser
Username.
Login as
.I user
on the remote host.
.TP
.B \-t
Allocate a pty.
.TP
.B \-T
Don't allocate a pty.
.SH AUTHOR
Matt Johnston (matt@ucc.asn.au).
.br
Gerrit Pape (pape@smarden.org) wrote this manual page.
.SH SEE ALSO
dropbear(8), dropbearkey(8)
.P
http://matt.ucc.asn.au/dropbear/dropbear.html

View File

@ -430,10 +430,11 @@ char* getaddrhostname(struct sockaddr_storage * addr) {
}
#ifdef DEBUG_TRACE
void printhex(unsigned char* buf, int len) {
void printhex(const char * label, const unsigned char * buf, int len) {
int i;
fprintf(stderr, "%s\n", label);
for (i = 0; i < len; i++) {
fprintf(stderr, "%02x", buf[i]);
if (i % 16 == 15) {

View File

@ -41,7 +41,7 @@ void dropbear_close(const char* format, ...);
void dropbear_log(int priority, const char* format, ...);
#ifdef DEBUG_TRACE
void dropbear_trace(const char* format, ...);
void printhex(unsigned char* buf, int len);
void printhex(const char * label, const unsigned char * buf, int len);
extern int debug_trace;
#endif
char * stripcontrol(const char * text);

15
debian/README.Debian.diet vendored Normal file
View File

@ -0,0 +1,15 @@
Building with the diet libc
---------------------------
This package optionally can be built with the diet libc instead of the
glibc to provide small statically linked programs. The resulting package
has no dependency on any other package.
To use the diet libc, make sure the latest versions of the dietlibc-dev
package is installed, and set DEB_BUILD_OPTIONS=diet in the environment
when building the package, e.g.:
# apt-get install dietlibc-dev
$ DEB_BUILD_OPTIONS=diet fakeroot apt-get source -b dropbear
-- Gerrit Pape <pape@smarden.org>, Sat, 17 Jul 2004 19:09:34 +0000

View File

@ -39,7 +39,7 @@
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
* since the printing may not sanitise strings etc. This will add a reasonable
* amount to your executable size. */
//#define DEBUG_TRACE
/*#define DEBUG_TRACE */
/* All functions writing to the cleartext payload buffer call
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're

View File

@ -76,6 +76,6 @@ Matt Johnston (matt@ucc.asn.au).
.br
Gerrit Pape (pape@smarden.org) wrote this manual page.
.SH SEE ALSO
dropbearkey(8)
dropbearkey(8), dbclient(1)
.P
http://matt.ucc.asn.au/dropbear/dropbear.html

View File

@ -42,6 +42,6 @@ Matt Johnston (matt@ucc.asn.au).
.br
Gerrit Pape (pape@smarden.org) wrote this manual page.
.SH SEE ALSO
dropbear(8)
dropbear(8), dbclient(1)
.P
http://matt.ucc.asn.au/dropbear/dropbear.html

34
dss.c
View File

@ -190,10 +190,8 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data,
/* create the signature - s' and r' are the received signatures in buf */
/* w = (s')-1 mod q */
/* let val1 = s' */
if (mp_read_unsigned_bin(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE)
!= MP_OKAY) {
goto out;
}
bytes_to_mp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE);
if (mp_cmp(&val1, key->q) != MP_LT) {
TRACE(("verify failed, s' >= q"))
goto out;
@ -205,9 +203,8 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data,
/* u1 = ((SHA(M')w) mod q */
/* let val1 = SHA(M') = msghash */
if (mp_read_unsigned_bin(&val1, msghash, SHA1_HASH_SIZE) != MP_OKAY) {
goto out;
}
bytes_to_mp(&val1, msghash, SHA1_HASH_SIZE);
/* let val3 = u1 = ((SHA(M')w) mod q */
if (mp_mulmod(&val1, &val2, key->q, &val3) != MP_OKAY) {
goto out;
@ -215,10 +212,7 @@ int buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data,
/* u2 = ((r')w) mod q */
/* let val1 = r' */
if (mp_read_unsigned_bin(&val1, &string[0], SHA1_HASH_SIZE)
!= MP_OKAY) {
goto out;
}
bytes_to_mp(&val1, &string[0], SHA1_HASH_SIZE);
if (mp_cmp(&val1, key->q) != MP_LT) {
TRACE(("verify failed, r' >= q"))
goto out;
@ -261,6 +255,7 @@ out:
}
#endif /* DROPBEAR_SIGNKEY_VERIFY */
#ifdef DSS_PROTOK
/* convert an unsigned mp into an array of bytes, malloced.
* This array must be freed after use, len contains the length of the array,
* if len != NULL */
@ -279,6 +274,7 @@ static unsigned char* mptobytes(mp_int *mp, int *len) {
}
return ret;
}
#endif
/* Sign the data presented with key, writing the signature contents
* to the buffer
@ -304,8 +300,6 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data,
unsigned char *privkeytmp;
unsigned char proto_k[SHA512_HASH_SIZE];
DEF_MP_INT(dss_protok);
#else
unsigned char kbuf[SHA1_HASH_SIZE];
#endif
DEF_MP_INT(dss_k);
DEF_MP_INT(dss_m);
@ -343,22 +337,16 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data,
/* generate k */
m_mp_init(&dss_protok);
bytestomp(&dss_protok, proto_k, SHA512_HASH_SIZE);
bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE);
mp_mod(&dss_protok, key->q, &dss_k);
mp_clear(&dss_protok);
m_burn(proto_k, SHA512_HASH_SIZE);
#else /* DSS_PROTOK not defined*/
do {
genrandom(kbuf, SHA1_HASH_SIZE);
if (mp_read_unsigned_bin(&dss_k, kbuf, SHA1_HASH_SIZE) != MP_OKAY) {
dropbear_exit("dss error");
}
} while (mp_cmp(&dss_k, key->q) == MP_GT || mp_cmp_d(&dss_k, 0) != MP_GT);
m_burn(kbuf, SHA1_HASH_SIZE);
gen_random_mpint(key->q, &dss_k);
#endif
/* now generate the actual signature */
bytestomp(&dss_m, msghash, SHA1_HASH_SIZE);
bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE);
/* g^k mod p */
if (mp_exptmod(key->g, &dss_k, key->p, &dss_temp1) != MP_OKAY) {
@ -417,7 +405,7 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data,
mp_clear(&dss_s);
buf_incrwritepos(buf, writelen);
mp_clear_multi(&dss_k, &dss_temp1, &dss_temp1, &dss_r, &dss_s,
mp_clear_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
&dss_m, NULL);
/* create the signature to return */

View File

@ -77,10 +77,7 @@ static void getq(dss_key *key) {
buf[0] |= 0x80; /* top bit high */
buf[QSIZE-1] |= 0x01; /* bottom bit high */
if (mp_read_unsigned_bin(key->q, buf, QSIZE) != MP_OKAY) {
fprintf(stderr, "dss key generation failed\n");
exit(1);
}
bytes_to_mp(key->q, buf, QSIZE);
/* 18 rounds are required according to HAC */
if (mp_prime_next_prime(key->q, 18, 0) != MP_OKAY) {
@ -116,10 +113,7 @@ static void getp(dss_key *key, unsigned int size) {
buf[0] |= 0x80; /* set the top bit high */
/* X is a random mp_int */
if (mp_read_unsigned_bin(&tempX, buf, size) != MP_OKAY) {
fprintf(stderr, "dss key generation failed\n");
exit(1);
}
bytes_to_mp(&tempX, buf, size);
/* C = X mod 2q */
if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) {
@ -147,6 +141,7 @@ static void getp(dss_key *key, unsigned int size) {
} while (!result);
mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
m_burn(buf, size);
m_free(buf);
}
@ -189,22 +184,7 @@ static void getg(dss_key * key) {
static void getx(dss_key *key) {
DEF_MP_INT(val);
char buf[QSIZE];
m_mp_init(&val);
do {
genrandom(buf, QSIZE);
if (mp_read_unsigned_bin(&val, buf, QSIZE) != MP_OKAY) {
fprintf(stderr, "dss key generation failed\n");
}
} while ((mp_cmp_d(&val, 1) == MP_GT) && (mp_cmp(&val, key->q) == MP_LT));
mp_copy(&val, key->x);
mp_clear(&val);
gen_random_mpint(key->q, key->x);
}
static void gety(dss_key *key) {

View File

@ -108,10 +108,7 @@ static void getrsaprime(mp_int* prime, mp_int *primeminus,
genrandom(buf, size+1);
buf[0] |= 0x80; /* MSB set */
if (mp_read_unsigned_bin(prime, buf, size+1) != MP_OKAY) {
fprintf(stderr, "rsa generation failed\n");
exit(1);
}
bytes_to_mp(prime, buf, size+1);
/* find the next integer which is prime, 8 round of miller-rabin */
if (mp_prime_next_prime(prime, 8, 0) != MP_OKAY) {

View File

@ -111,7 +111,7 @@
#include <libgen.h>
#endif
#include "libtomcrypt/mycrypt.h"
#include "libtomcrypt/src/headers/tomcrypt.h"
#include "libtommath/tommath.h"
#include "compat.h"

6
kex.h
View File

@ -37,10 +37,10 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv);
void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
sign_key *hostkey);
void recv_msg_kexdh_init(); // server
void recv_msg_kexdh_init(); /* server */
void send_msg_kexdh_init(); // client
void recv_msg_kexdh_reply(); // client
void send_msg_kexdh_init(); /* client */
void recv_msg_kexdh_reply(); /* client */
extern const unsigned char dh_p_val[];
#define DH_P_LEN 128 /* The length of the dh_p_val array */

View File

@ -90,6 +90,11 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
#define DROPBEAR_RSA
#define DROPBEAR_DSS
/* RSA can be vulnerable to timing attacks which use the time required for
* signing to guess the private key. Blinding avoids this attack, though makes
* signing operations slightly slower. */
#define RSA_BLINDING
/* Define DSS_PROTOK to use PuTTY's method of generating the value k for dss,
* rather than just from the random byte source. Undefining this will save you
* ~4k in binary size with static uclibc, but your DSS hostkey could be exposed
@ -313,14 +318,6 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
#define DISABLE_AGENTFWD
#endif
#ifndef ENABLE_LOCALTCPFWD
#define DISABLE_TCPDIRECT
#endif
#ifndef ENABLE_REMOTETCPFWD
#define DISABLE_REMOTETCPFWD
#endif
#if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD)
#define ENABLE_CLI_ANYTCPFWD
#endif
@ -329,7 +326,8 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
#define DROPBEAR_TCP_ACCEPT
#endif
#if defined(ENABLE_REMOTETCPFWD) || defined(ENABLE_LOCALTCPFWD) || \
#if defined(ENABLE_CLI_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) || \
defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_SVR_LOCALTCPFWD) || \
defined(ENABLE_AGENTFWD) || defined(ENABLE_X11FWD)
#define USING_LISTENERS
#endif

View File

@ -201,6 +201,7 @@ static void read_packet_init() {
/* decrypt it */
if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize),
buf_getwriteptr(ses.decryptreadbuf,blocksize),
blocksize,
&ses.keys->recv_symmetric_struct) != CRYPT_OK) {
dropbear_exit("error decrypting");
}
@ -254,6 +255,7 @@ void decrypt_packet() {
while (ses.readbuf->pos < ses.readbuf->len - macsize) {
if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize),
buf_getwriteptr(ses.decryptreadbuf, blocksize),
blocksize,
&ses.keys->recv_symmetric_struct) != CRYPT_OK) {
dropbear_exit("error decrypting");
}
@ -491,6 +493,7 @@ void encrypt_packet() {
while (clearwritebuf->pos < clearwritebuf->len) {
if (cbc_encrypt(buf_getptr(clearwritebuf, blocksize),
buf_getwriteptr(writebuf, blocksize),
blocksize,
&ses.keys->trans_symmetric_struct) != CRYPT_OK) {
dropbear_exit("error encrypting");
}

View File

@ -25,14 +25,15 @@
#include "includes.h"
#include "buffer.h"
#include "dbutil.h"
#include "bignum.h"
int donerandinit = 0;
static int donerandinit = 0;
/* this is used to generate unique output from the same hashpool */
unsigned int counter = 0;
static unsigned int counter = 0;
#define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */
unsigned char hashpool[SHA1_HASH_SIZE];
static unsigned char hashpool[SHA1_HASH_SIZE];
#define INIT_SEED_SIZE 32 /* 256 bits */
@ -50,6 +51,7 @@ static void readrand(unsigned char* buf, unsigned int buflen);
static void readrand(unsigned char* buf, unsigned int buflen) {
static int already_blocked = 0;
int readfd;
unsigned int readpos;
int readlen;
@ -92,6 +94,24 @@ static void readrand(unsigned char* buf, unsigned int buflen) {
/* read the actual random data */
readpos = 0;
do {
if (!already_blocked)
{
int ret;
struct timeval timeout;
fd_set read_fds;
timeout.tv_sec = 2; /* two seconds should be enough */
timeout.tv_usec = 0;
FD_ZERO(&read_fds);
FD_SET(readfd, &read_fds);
ret = select(readfd + 1, &read_fds, NULL, NULL, &timeout);
if (ret == 0)
{
dropbear_log(LOG_INFO, "Warning: Reading the random source seems to have blocked.\nIf you experience problems, you probably need to find a better entropy source.");
already_blocked = 1;
}
}
readlen = read(readfd, &buf[readpos], buflen - readpos);
if (readlen <= 0) {
if (readlen < 0 && errno == EINTR) {
@ -159,3 +179,38 @@ void genrandom(unsigned char* buf, unsigned int len) {
}
m_burn(hash, sizeof(hash));
}
/* Generates a random mp_int.
* max is a *mp_int specifying an upper bound.
* rand must be an initialised *mp_int for the result.
* the result rand satisfies: 0 < rand < max
* */
void gen_random_mpint(mp_int *max, mp_int *rand) {
unsigned char *randbuf = NULL;
unsigned int len = 0;
const char masks[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
const int size_bits = mp_count_bits(max);
len = size_bits / 8;
if ((size_bits % 8) != 0) {
len += 1;
}
randbuf = (unsigned char*)m_malloc(len);
do {
genrandom(randbuf, len);
/* Mask out the unrequired bits - mp_read_unsigned_bin expects
* MSB first.*/
randbuf[0] &= masks[size_bits % 8];
bytes_to_mp(rand, randbuf, len);
/* keep regenerating until we get one satisfying
* 0 < rand < max */
} while ( ( (max != NULL) && (mp_cmp(rand, max) != MP_LT) )
|| (mp_cmp_d(rand, 0) != MP_GT) );
m_burn(randbuf, len);
m_free(randbuf);
}

View File

@ -25,8 +25,11 @@
#ifndef _RANDOM_H_
#define _RANDOM_H_
struct mp_int;
void seedrandom();
void genrandom(unsigned char* buf, int len);
void addrandom(unsigned char* buf, int len);
void gen_random_mpint(mp_int *max, mp_int *rand);
#endif /* _RANDOM_H_ */

92
rsa.c
View File

@ -38,8 +38,9 @@
#ifdef DROPBEAR_RSA
static mp_int * rsa_pad_em(rsa_key * key,
const unsigned char * data, unsigned int len);
static void rsa_pad_em(rsa_key * key,
const unsigned char * data, unsigned int len,
mp_int * rsa_em);
/* Load a public rsa key from a buffer, initialising the values.
* The key will have the same format as buf_put_rsa_key.
@ -203,14 +204,14 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data,
unsigned int slen;
DEF_MP_INT(rsa_s);
DEF_MP_INT(rsa_mdash);
mp_int *rsa_em = NULL;
DEF_MP_INT(rsa_em);
int ret = DROPBEAR_FAILURE;
TRACE(("enter buf_rsa_verify"))
assert(key != NULL);
m_mp_init_multi(&rsa_mdash, &rsa_s, NULL);
m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL);
slen = buf_getint(buf);
if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) {
@ -231,29 +232,25 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data,
}
/* create the magic PKCS padded value */
rsa_em = rsa_pad_em(key, data, len);
rsa_pad_em(key, data, len, &rsa_em);
if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) {
TRACE(("failed exptmod rsa_s"))
goto out;
}
if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) {
if (mp_cmp(&rsa_em, &rsa_mdash) == MP_EQ) {
/* signature is valid */
TRACE(("success!"))
ret = DROPBEAR_SUCCESS;
}
out:
if (rsa_em) {
mp_clear(rsa_em);
m_free(rsa_em);
}
mp_clear_multi(&rsa_mdash, &rsa_s, NULL);
mp_clear_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL);
TRACE(("leave buf_rsa_verify: ret %d", ret))
return ret;
}
#endif /* DROPBEAR_SIGNKEY_VERIFY */
/* Sign the data presented with key, writing the signature contents
@ -264,22 +261,55 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data,
unsigned int nsize, ssize;
unsigned int i;
DEF_MP_INT(rsa_s);
mp_int *rsa_em = NULL;
DEF_MP_INT(rsa_tmp1);
DEF_MP_INT(rsa_tmp2);
DEF_MP_INT(rsa_tmp3);
unsigned char *tmpbuf;
TRACE(("enter buf_put_rsa_sign"))
assert(key != NULL);
rsa_em = rsa_pad_em(key, data, len);
m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
m_mp_init(&rsa_s);
rsa_pad_em(key, data, len, &rsa_tmp1);
/* the actual signing of the padded data */
#ifdef RSA_BLINDING
/* With blinding, s = (r^(-1))((em)*r^e)^d mod n */
/* generate the r blinding value */
/* rsa_tmp2 is r */
gen_random_mpint(key->n, &rsa_tmp2);
/* rsa_tmp1 is em */
/* em' = em * r^e mod n */
mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/
mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3);
mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2);
/* rsa_tmp2 is em' */
/* s' = (em')^d mod n */
mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1);
/* rsa_tmp1 is s' */
/* rsa_tmp3 is r^(-1) mod n */
/* s = (s')r^(-1) mod n */
mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s);
#else
/* s = em^d mod n */
if (mp_exptmod(rsa_em, key->d, key->n, &rsa_s) != MP_OKAY) {
/* rsa_tmp1 is em */
if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) {
dropbear_exit("rsa error");
}
mp_clear(rsa_em);
m_free(rsa_em);
#endif /* RSA_BLINDING */
mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
/* create the signature to return */
buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
@ -302,7 +332,7 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data,
mp_clear(&rsa_s);
#if defined(DEBUG_RSA) && defined(DEBUG_TRACE)
printhex(buf->data, buf->len);
printhex("RSA sig", buf->data, buf->len);
#endif
@ -318,19 +348,22 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data,
*
* prefix is the ASN1 designator prefix,
* hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14
*
* rsa_em must be a pointer to an initialised mp_int.
*/
static mp_int * rsa_pad_em(rsa_key * key,
const unsigned char * data, unsigned int len) {
static void rsa_pad_em(rsa_key * key,
const unsigned char * data, unsigned int len,
mp_int * rsa_em) {
/* ASN1 designator (including the 0x00 preceding) */
const char rsa_asn1_magic[] =
const unsigned char rsa_asn1_magic[] =
{0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
#define RSA_ASN1_MAGIC_LEN 16
const unsigned int RSA_ASN1_MAGIC_LEN = 16;
buffer * rsa_EM = NULL;
hash_state hs;
unsigned int nsize;
mp_int * rsa_em = NULL;
assert(key != NULL);
assert(data != NULL);
@ -358,16 +391,9 @@ static mp_int * rsa_pad_em(rsa_key * key,
/* Create the mp_int from the encoded bytes */
buf_setpos(rsa_EM, 0);
rsa_em = (mp_int*)m_malloc(sizeof(mp_int));
m_mp_init(rsa_em);
if (mp_read_unsigned_bin(rsa_em, buf_getptr(rsa_EM, rsa_EM->size),
rsa_EM->size) != MP_OKAY) {
dropbear_exit("rsa error");
}
bytes_to_mp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size),
rsa_EM->size);
buf_free(rsa_EM);
return rsa_em;
}
#endif /* DROPBEAR_RSA */

View File

@ -95,7 +95,7 @@ typedef struct cli_runopts {
char *cmd;
int wantpty;
#ifdef ENABLE_CLI_PUBKEY_AUTH
struct PubkeyList *pubkeys; /* Keys to use for public-key auth */
struct SignKeyList *privkeys; /* Keys to use for public-key auth */
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
struct TCPFwdList * remotefwds;

3
scp.c
View File

@ -244,9 +244,6 @@ main(int argc, char **argv)
extern char *optarg;
extern int optind;
/* hack, seems to work */
// __progname = argv[0];
args.list = NULL;
addargs(&args, "ssh"); /* overwritten with ssh_program */
addargs(&args, "-x");

View File

@ -211,19 +211,22 @@ struct clientsession {
mp_int *dh_e, *dh_x; /* Used during KEX */
cli_kex_state kex_state; /* Used for progressing KEX */
cli_state state; /* Used to progress auth/channelsession etc */
int something; /* XXX */
unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */
int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */
struct termios saved_tio;
int stdincopy;
int stdinflags;
int stdoutcopy;
int stdoutflags;
int stderrcopy;
int stderrflags;
int winchange; /* Set to 1 when a windowchange signal happens */
int lastauthtype; /* either AUTH_TYPE_PUBKEY or AUTH_TYPE_PASSWORD,
for the last type of auth we tried */
struct PubkeyList *lastpubkey;
struct SignKeyList *lastprivkey;
int retval; /* What the command exit status was - we emulate it */
#if 0

View File

@ -279,7 +279,7 @@ static char * sign_key_md5_fingerprint(unsigned char* keyblob,
char * ret;
hash_state hs;
unsigned char hash[MD5_HASH_SIZE];
unsigned int h, i;
unsigned int i;
unsigned int buflen;
md5_init(&hs);
@ -296,10 +296,11 @@ static char * sign_key_md5_fingerprint(unsigned char* keyblob,
memset(ret, 'Z', buflen);
strcpy(ret, "md5 ");
for (i = 4, h = 0; i < buflen; i+=3, h++) {
ret[i] = hexdig(hash[h] >> 4);
ret[i+1] = hexdig(hash[h] & 0x0f);
ret[i+2] = ':';
for (i = 0; i < MD5_HASH_SIZE; i++) {
unsigned int pos = 4 + i*3;
ret[pos] = hexdig(hash[i] >> 4);
ret[pos+1] = hexdig(hash[i] & 0x0f);
ret[pos+2] = ':';
}
ret[buflen-1] = 0x0;
@ -313,7 +314,7 @@ static char * sign_key_sha1_fingerprint(unsigned char* keyblob,
char * ret;
hash_state hs;
unsigned char hash[SHA1_HASH_SIZE];
unsigned int h, i;
unsigned int i;
unsigned int buflen;
sha1_init(&hs);
@ -329,10 +330,11 @@ static char * sign_key_sha1_fingerprint(unsigned char* keyblob,
strcpy(ret, "sha1 ");
for (i = 5, h = 0; i < buflen; i+=3, h++) {
ret[i] = hexdig(hash[h] >> 4);
ret[i+1] = hexdig(hash[h] & 0x0f);
ret[i+2] = ':';
for (i = 0; i < SHA1_HASH_SIZE; i++) {
unsigned int pos = 5 + 3*i;
ret[pos] = hexdig(hash[i] >> 4);
ret[pos+1] = hexdig(hash[i] & 0x0f);
ret[pos+2] = ':';
}
ret[buflen-1] = 0x0;

View File

@ -155,7 +155,7 @@ void svr_auth_pam() {
unsigned char changepw;
/* check if client wants to change password */
changepw = buf_getbyte(ses.payload);
changepw = buf_getbool(ses.payload);
if (changepw) {
/* not implemented by this server */
send_msg_userauth_failure(0, 1);

View File

@ -71,7 +71,7 @@ void svr_auth_password() {
}
/* check if client wants to change password */
changepw = buf_getbyte(ses.payload);
changepw = buf_getbool(ses.payload);
if (changepw) {
/* not implemented by this server */
send_msg_userauth_failure(0, 1);

View File

@ -64,7 +64,7 @@ void svr_auth_pubkey() {
/* 0 indicates user just wants to check if key can be used, 1 is an
* actual attempt*/
testkey = (buf_getbyte(ses.payload) == 0);
testkey = (buf_getbool(ses.payload) == 0);
algo = buf_getstring(ses.payload, &algolen);
keybloblen = buf_getint(ses.payload);

View File

@ -305,7 +305,7 @@ static void chansessionrequest(struct Channel *channel) {
TRACE(("enter chansessionrequest"))
type = buf_getstring(ses.payload, &typelen);
wantreply = buf_getbyte(ses.payload);
wantreply = buf_getbool(ses.payload);
if (typelen > MAX_NAME_LEN) {
TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/
@ -837,7 +837,7 @@ static void execchild(struct ChanSess *chansess) {
/* close file descriptors except stdin/stdout/stderr
* Need to be sure FDs are closed here to avoid reading files as root */
for (i = 3; i < (unsigned int)ses.maxfd; i++) {
for (i = 3; i <= (unsigned int)ses.maxfd; i++) {
if (m_close(i) == DROPBEAR_FAILURE) {
dropbear_exit("Error closing file desc");
}
@ -862,8 +862,10 @@ static void execchild(struct ChanSess *chansess) {
if ((setgid(ses.authstate.pw->pw_gid) < 0) ||
(initgroups(ses.authstate.pw->pw_name,
ses.authstate.pw->pw_gid) < 0) ||
(setuid(ses.authstate.pw->pw_uid) < 0)) {
ses.authstate.pw->pw_gid) < 0)) {
dropbear_exit("error changing user group");
}
if (setuid(ses.authstate.pw->pw_uid) < 0) {
dropbear_exit("error changing user");
}
} else {

View File

@ -78,7 +78,7 @@ void recv_msg_global_request_remotetcp() {
}
reqname = buf_getstring(ses.payload, &namelen);
wantreply = buf_getbyte(ses.payload);
wantreply = buf_getbool(ses.payload);
if (namelen > MAXNAMLEN) {
TRACE(("name len is wrong: %d", namelen))

View File

@ -52,7 +52,7 @@ int x11req(struct ChanSess * chansess) {
return DROPBEAR_FAILURE;
}
chansess->x11singleconn = buf_getbyte(ses.payload);
chansess->x11singleconn = buf_getbool(ses.payload);
chansess->x11authprot = buf_getstring(ses.payload, NULL);
chansess->x11authcookie = buf_getstring(ses.payload, NULL);
chansess->x11screennum = buf_getint(ses.payload);