merge of '182c2d8dbd5321ef4d1df8758936f4dc7127015f'

and '31dcd7a22983ef19d6c63248e415e71d292dd0ec'

--HG--
extra : convert_revision : e84f66826c7ee6ebe99ef92cc0f6c22ecf638d01
This commit is contained in:
Matt Johnston 2006-12-06 13:11:41 +00:00
commit d5897b9a5d
36 changed files with 439 additions and 202 deletions

19
CHANGES
View File

@ -1,3 +1,22 @@
0.49 - Tues 13 June 2003
- Return immediately for "sleep 10 & echo foo", rather than waiting
for the sleep to return (pointed out by Rob Landley)
- Added -P pidfile argument to the server (from Swen Schillig)
- Compile fixes, make sure that all variable definitions are at the start
of a scope.
- Use $HOME in preference to that from /etc/passwd, so that it
dbclient can still work on systems with a broken setup.
- Add -N dbclient option for "no command"
- Add -f dbclient option for "background after auth"
- Try to finally fix ss_family compilation problems
0.48.1 - Sat 11 March 2006 0.48.1 - Sat 11 March 2006
- Compile fix for scp - Compile fix for scp

View File

@ -64,12 +64,12 @@ bindir=${exec_prefix}/bin
sbindir=${exec_prefix}/sbin sbindir=${exec_prefix}/sbin
CC=@CC@ CC=@CC@
LD=@LD@
AR=@AR@ AR=@AR@
RANLIB=@RANLIB@ RANLIB=@RANLIB@
STRIP=@STRIP@ STRIP=@STRIP@
INSTALL=@INSTALL@ INSTALL=@INSTALL@
CFLAGS=-I. -I$(srcdir)/libtomcrypt/src/headers/ @CFLAGS@ CPPFLAGS=@CPPFLAGS@
CFLAGS=-I. -I$(srcdir) -I$(srcdir)/libtomcrypt/src/headers/ $(CPPFLAGS) @CFLAGS@
LIBS=$(LTC) $(LTM) @LIBS@ LIBS=$(LTC) $(LTM) @LIBS@
LDFLAGS=@LDFLAGS@ LDFLAGS=@LDFLAGS@
@ -155,11 +155,11 @@ dropbearconvert: $(dropbearconvertobjs)
dropbear dbclient dropbearkey dropbearconvert: $(HEADERS) $(LTC) $(LTM) \ dropbear dbclient dropbearkey dropbearconvert: $(HEADERS) $(LTC) $(LTM) \
Makefile Makefile
$(LD) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBS) $(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBS)
# scp doesn't use the libs so is special. # scp doesn't use the libs so is special.
scp: $(SCPOBJS) $(HEADERS) Makefile scp: $(SCPOBJS) $(HEADERS) Makefile
$(LD) $(LDFLAGS) -o $@$(EXEEXT) $(SCPOBJS) $(CC) $(LDFLAGS) -o $@$(EXEEXT) $(SCPOBJS)
# multi-binary compilation. # multi-binary compilation.
@ -172,7 +172,7 @@ endif
dropbearmulti: multilink dropbearmulti: multilink
multibinary: $(HEADERS) $(MULTIOBJS) $(LTC) $(LTM) Makefile multibinary: $(HEADERS) $(MULTIOBJS) $(LTC) $(LTM) Makefile
$(LD) $(LDFLAGS) -o dropbearmulti$(EXEEXT) $(MULTIOBJS) $(LIBS) $(CC) $(LDFLAGS) -o dropbearmulti$(EXEEXT) $(MULTIOBJS) $(LIBS)
multilink: multibinary $(addprefix link, $(PROGRAMS)) multilink: multibinary $(addprefix link, $(PROGRAMS))
@ -186,6 +186,8 @@ $(LTC): options.h
$(LTM): options.h $(LTM): options.h
cd libtommath && $(MAKE) cd libtommath && $(MAKE)
.PHONY : clean sizes thisclean distclean tidy ltc-clean ltm-clean
ltc-clean: ltc-clean:
cd libtomcrypt && $(MAKE) clean cd libtomcrypt && $(MAKE) clean

2
auth.h
View File

@ -52,7 +52,7 @@ void cli_pubkeyfail();
void cli_auth_password(); void cli_auth_password();
int cli_auth_pubkey(); int cli_auth_pubkey();
void cli_auth_interactive(); void cli_auth_interactive();
char* getpass_or_cancel(); char* getpass_or_cancel(char* prompt);
#define MAX_USERNAME_LEN 25 /* arbitrary for the moment */ #define MAX_USERNAME_LEN 25 /* arbitrary for the moment */

View File

@ -281,11 +281,11 @@ void cli_auth_try() {
/* A helper for getpass() that exits if the user cancels. The returned /* A helper for getpass() that exits if the user cancels. The returned
* password is statically allocated by getpass() */ * password is statically allocated by getpass() */
char* getpass_or_cancel() char* getpass_or_cancel(char* prompt)
{ {
char* password = NULL; char* password = NULL;
password = getpass("Password: "); password = getpass(prompt);
/* 0x03 is a ctrl-c character in the buffer. */ /* 0x03 is a ctrl-c character in the buffer. */
if (password == NULL || strchr(password, '\3') != NULL) { if (password == NULL || strchr(password, '\3') != NULL) {

View File

@ -99,13 +99,14 @@ void recv_msg_userauth_info_request() {
if (strlen(name) > 0) { if (strlen(name) > 0) {
cleantext(name); cleantext(name);
fprintf(stderr, "%s", name); fprintf(stderr, "%s", name);
m_free(name);
} }
m_free(name);
if (strlen(instruction) > 0) { if (strlen(instruction) > 0) {
cleantext(instruction); cleantext(instruction);
fprintf(stderr, "%s", instruction); fprintf(stderr, "%s", instruction);
m_free(instruction);
} }
m_free(instruction);
for (i = 0; i < num_prompts; i++) { for (i = 0; i < num_prompts; i++) {
unsigned int response_len = 0; unsigned int response_len = 0;

View File

@ -116,16 +116,19 @@ static char *gui_getpass(const char *prompt) {
void cli_auth_password() { void cli_auth_password() {
char* password = NULL; char* password = NULL;
char prompt[80];
TRACE(("enter cli_auth_password")) TRACE(("enter cli_auth_password"))
CHECKCLEARTOWRITE(); CHECKCLEARTOWRITE();
snprintf(prompt, sizeof(prompt), "%s@%s's password: ",
cli_opts.username, cli_opts.remotehost);
#ifdef ENABLE_CLI_ASKPASS_HELPER #ifdef ENABLE_CLI_ASKPASS_HELPER
if (want_askpass()) if (want_askpass())
password = gui_getpass("Password: "); password = gui_getpass(prompt);
else else
#endif #endif
password = getpass_or_cancel("Password: "); password = getpass_or_cancel(prompt);
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);

View File

@ -112,6 +112,7 @@ void recv_msg_userauth_pk_ok() {
/* Success */ /* Success */
break; break;
} }
buf_free(keybuf);
if (keyitem != NULL) { if (keyitem != NULL) {
TRACE(("matching key")) TRACE(("matching key"))

View File

@ -122,6 +122,7 @@ static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) {
fprintf(stderr, "\nHost '%s' is not in the trusted hosts file.\n(fingerprint %s)\nDo you want to continue connecting? (y/n)\n", fprintf(stderr, "\nHost '%s' is not in the trusted hosts file.\n(fingerprint %s)\nDo you want to continue connecting? (y/n)\n",
cli_opts.remotehost, cli_opts.remotehost,
fp); fp);
m_free(fp);
tty = fopen(_PATH_TTY, "r"); tty = fopen(_PATH_TTY, "r");
if (tty) { if (tty) {
@ -132,7 +133,6 @@ static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) {
} }
if (response == 'y') { if (response == 'y') {
m_free(fp);
return; return;
} }
@ -145,34 +145,41 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
FILE *hostsfile = NULL; FILE *hostsfile = NULL;
int readonly = 0; int readonly = 0;
struct passwd *pw = NULL; struct passwd *pw = NULL;
char * homedir = NULL;
unsigned int hostlen, algolen; unsigned int hostlen, algolen;
unsigned long len; unsigned long len;
const char *algoname = NULL; const char *algoname = NULL;
buffer * line = NULL; buffer * line = NULL;
int ret; int ret;
pw = getpwuid(getuid()); homedir = getenv("HOME");
if (pw == NULL) { if (!homedir) {
dropbear_exit("Failed to get homedir"); pw = getpwuid(getuid());
if (pw) {
homedir = pw->pw_dir;
}
pw = NULL;
} }
len = strlen(pw->pw_dir); if (homedir) {
len = strlen(homedir);
filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/ filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/
snprintf(filename, len+18, "%s/.ssh", pw->pw_dir); snprintf(filename, len+18, "%s/.ssh", homedir);
/* Check that ~/.ssh exists - easiest way is just to mkdir */ /* Check that ~/.ssh exists - easiest way is just to mkdir */
if (mkdir(filename, S_IRWXU) != 0) { if (mkdir(filename, S_IRWXU) != 0) {
if (errno != EEXIST) { if (errno != EEXIST) {
dropbear_log(LOG_INFO, "Warning: failed creating ~/.ssh: %s", dropbear_log(LOG_INFO, "Warning: failed creating %s/.ssh: %s",
strerror(errno)); homedir, strerror(errno));
TRACE(("mkdir didn't work: %s", strerror(errno))) TRACE(("mkdir didn't work: %s", strerror(errno)))
ask_to_confirm(keyblob, keybloblen); ask_to_confirm(keyblob, keybloblen);
goto out; /* only get here on success */ goto out; /* only get here on success */
} }
} }
snprintf(filename, len+18, "%s/.ssh/known_hosts", pw->pw_dir); snprintf(filename, len+18, "%s/.ssh/known_hosts", homedir);
hostsfile = fopen(filename, "a+"); hostsfile = fopen(filename, "a+");
if (hostsfile != NULL) { if (hostsfile != NULL) {
@ -185,9 +192,12 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
hostsfile = fopen(filename, "r"); hostsfile = fopen(filename, "r");
} }
} }
}
if (hostsfile == NULL) { if (hostsfile == NULL) {
TRACE(("hostsfile didn't open: %s", strerror(errno))) TRACE(("hostsfile didn't open: %s", strerror(errno)))
dropbear_log(LOG_WARNING, "Failed to open %s/.ssh/known_hosts",
homedir);
ask_to_confirm(keyblob, keybloblen); ask_to_confirm(keyblob, keybloblen);
goto out; /* We only get here on success */ goto out; /* We only get here on success */
} }

View File

@ -44,12 +44,14 @@ static void addforward(char* str, struct TCPFwdList** fwdlist);
static void printhelp() { static void printhelp() {
fprintf(stderr, "Dropbear client v%s\n" fprintf(stderr, "Dropbear client v%s\n"
"Usage: %s [options] [user@]host\n" "Usage: %s [options] [user@]host [command]\n"
"Options are:\n" "Options are:\n"
"-p <remoteport>\n" "-p <remoteport>\n"
"-l <username>\n" "-l <username>\n"
"-t Allocate a pty\n" "-t Allocate a pty\n"
"-T Don't allocate a pty\n" "-T Don't allocate a pty\n"
"-N Don't run a remote command\n"
"-f Run in background after auth\n"
#ifdef ENABLE_CLI_PUBKEY_AUTH #ifdef ENABLE_CLI_PUBKEY_AUTH
"-i <identityfile> (multiple allowed)\n" "-i <identityfile> (multiple allowed)\n"
#endif #endif
@ -88,6 +90,8 @@ void cli_getopts(int argc, char ** argv) {
cli_opts.remoteport = NULL; cli_opts.remoteport = NULL;
cli_opts.username = NULL; cli_opts.username = NULL;
cli_opts.cmd = NULL; cli_opts.cmd = NULL;
cli_opts.no_cmd = 0;
cli_opts.backgrounded = 0;
cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */ cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */
#ifdef ENABLE_CLI_PUBKEY_AUTH #ifdef ENABLE_CLI_PUBKEY_AUTH
cli_opts.privkeys = NULL; cli_opts.privkeys = NULL;
@ -163,6 +167,12 @@ void cli_getopts(int argc, char ** argv) {
case 'T': /* don't want a pty */ case 'T': /* don't want a pty */
cli_opts.wantpty = 0; cli_opts.wantpty = 0;
break; break;
case 'N':
cli_opts.no_cmd = 1;
break;
case 'f':
cli_opts.backgrounded = 1;
break;
#ifdef ENABLE_CLI_LOCALTCPFWD #ifdef ENABLE_CLI_LOCALTCPFWD
case 'L': case 'L':
nextislocal = 1; nextislocal = 1;
@ -269,6 +279,11 @@ void cli_getopts(int argc, char ** argv) {
cli_opts.wantpty = 0; cli_opts.wantpty = 0;
} }
} }
if (cli_opts.backgrounded && cli_opts.cmd == NULL
&& cli_opts.no_cmd == 0) {
dropbear_exit("command required for -f");
}
} }
#ifdef ENABLE_CLI_PUBKEY_AUTH #ifdef ENABLE_CLI_PUBKEY_AUTH

View File

@ -82,6 +82,4 @@ void recv_msg_service_accept() {
} }
dropbear_exit("unrecognised service accept"); dropbear_exit("unrecognised service accept");
/* m_free(servicename); not reached */
} }

View File

@ -212,19 +212,38 @@ static void cli_sessionloop() {
*/ */
case USERAUTH_SUCCESS_RCVD: case USERAUTH_SUCCESS_RCVD:
if (cli_opts.backgrounded) {
int devnull;
// keeping stdin open steals input from the terminal and
// is confusing, though stdout/stderr could be useful.
devnull = open(_PATH_DEVNULL, O_RDONLY);
if (devnull < 0) {
dropbear_exit("opening /dev/null: %d %s",
errno, strerror(errno));
}
dup2(devnull, STDIN_FILENO);
if (daemon(0, 1) < 0) {
dropbear_exit("Backgrounding failed: %d %s",
errno, strerror(errno));
}
}
#ifdef ENABLE_CLI_LOCALTCPFWD #ifdef ENABLE_CLI_LOCALTCPFWD
setup_localtcp(); setup_localtcp();
#endif #endif
#ifdef ENABLE_CLI_REMOTETCPFWD #ifdef ENABLE_CLI_REMOTETCPFWD
setup_remotetcp(); setup_remotetcp();
#endif #endif
if (!cli_opts.no_cmd) {
cli_send_chansess_request(); cli_send_chansess_request();
TRACE(("leave cli_sessionloop: cli_send_chansess_request")) }
TRACE(("leave cli_sessionloop: running"))
cli_ses.state = SESSION_RUNNING; cli_ses.state = SESSION_RUNNING;
return; return;
case SESSION_RUNNING: case SESSION_RUNNING:
if (ses.chancount < 1) { if (ses.chancount < 1 && !cli_opts.no_cmd) {
cli_finished(); cli_finished();
} }

View File

@ -181,6 +181,7 @@ void channelio(fd_set *readfds, fd_set *writefds) {
struct Channel *channel; struct Channel *channel;
unsigned int i; unsigned int i;
int ret;
/* iterate through all the possible channels */ /* iterate through all the possible channels */
for (i = 0; i < ses.chansize; i++) { for (i = 0; i < ses.chansize; i++) {
@ -202,6 +203,25 @@ void channelio(fd_set *readfds, fd_set *writefds) {
send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR); send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
} }
/* if we can read from the writefd, it might be closed, so we try to
* see if it has errors */
if (IS_DROPBEAR_SERVER && channel->writefd >= 0
&& channel->writefd != channel->readfd
&& FD_ISSET(channel->writefd, readfds)) {
if (channel->initconn) {
/* Handling for "in progress" connection - this is needed
* to avoid spinning 100% CPU when we connect to a server
* which doesn't send anything (tcpfwding) */
checkinitdone(channel);
continue; /* Important not to use the channel after
checkinitdone(), as it may be NULL */
}
ret = write(channel->writefd, NULL, 0); /* Fake write */
if (ret < 0 && errno != EINTR && errno != EAGAIN) {
closewritefd(channel);
}
}
/* write to program/pipe stdin */ /* write to program/pipe stdin */
if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
if (channel->initconn) { if (channel->initconn) {
@ -241,13 +261,13 @@ static void checkclose(struct Channel *channel) {
channel->writebuf, channel->writebuf,
channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))) channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)))
if (!channel->sentclosed) { /* server chansession channels are special, since readfd mightn't
* close in the case of "sleep 4 & echo blah" until the sleep is up */
/* check for exited - currently only used for server sessions,
* if the shell has exited etc */
if (channel->type->checkclose) { if (channel->type->checkclose) {
if (channel->type->checkclose(channel)) { if (channel->type->checkclose(channel)) {
closewritefd(channel); closewritefd(channel);
closereadfd(channel, channel->readfd);
closereadfd(channel, channel->errfd);
} }
} }
@ -257,12 +277,12 @@ static void checkclose(struct Channel *channel) {
send_msg_channel_eof(channel); send_msg_channel_eof(channel);
} }
if (channel->writefd == FD_CLOSED if (!channel->sentclosed
&& channel->writefd == FD_CLOSED
&& channel->readfd == FD_CLOSED && channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) { && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_close(channel); send_msg_channel_close(channel);
} }
}
/* When either party wishes to terminate the channel, it sends /* When either party wishes to terminate the channel, it sends
* SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST * SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
@ -426,10 +446,22 @@ void setchannelfds(fd_set *readfds, fd_set *writefds) {
} }
} }
TRACE(("writefd = %d, readfd %d, errfd %d, bufused %d",
channel->writefd, channel->readfd,
channel->errfd,
cbuf_getused(channel->writebuf) ))
/* For checking FD status (ie closure etc) - we don't actually
* read data from writefd. We don't want to do this for the client,
* since redirection to /dev/null will make it spin in the select */
if (IS_DROPBEAR_SERVER && channel->writefd >= 0
&& channel->writefd != channel->readfd) {
FD_SET(channel->writefd, readfds);
}
/* Stuff from the wire */ /* Stuff from the wire */
if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 ) if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 )
|| channel->initconn) { || channel->initconn) {
FD_SET(channel->writefd, writefds); FD_SET(channel->writefd, writefds);
} }

View File

@ -262,6 +262,7 @@ void gen_new_keys() {
hash_state hs; hash_state hs;
unsigned int C2S_keysize, S2C_keysize; unsigned int C2S_keysize, S2C_keysize;
char mactransletter, macrecvletter; /* Client or server specific */ char mactransletter, macrecvletter; /* Client or server specific */
int recv_cipher = 0, trans_cipher = 0;
TRACE(("enter gen_new_keys")) TRACE(("enter gen_new_keys"))
/* the dh_K and hash are the start of all hashes, we make use of that */ /* the dh_K and hash are the start of all hashes, we make use of that */
@ -298,17 +299,20 @@ void gen_new_keys() {
hashkeys(C2S_key, C2S_keysize, &hs, 'C'); hashkeys(C2S_key, C2S_keysize, &hs, 'C');
hashkeys(S2C_key, S2C_keysize, &hs, 'D'); hashkeys(S2C_key, S2C_keysize, &hs, 'D');
if (cbc_start( recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name);
find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name), if (recv_cipher < 0)
recv_IV, recv_key, dropbear_exit("crypto error");
if (cbc_start(recv_cipher, recv_IV, recv_key,
ses.newkeys->recv_algo_crypt->keysize, 0, ses.newkeys->recv_algo_crypt->keysize, 0,
&ses.newkeys->recv_symmetric_struct) != CRYPT_OK) { &ses.newkeys->recv_symmetric_struct) != CRYPT_OK) {
dropbear_exit("crypto error"); dropbear_exit("crypto error");
} }
trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name);
if (trans_cipher < 0)
dropbear_exit("crypto error");
if (cbc_start( if (cbc_start(trans_cipher, trans_IV, trans_key,
find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name),
trans_IV, trans_key,
ses.newkeys->trans_algo_crypt->keysize, 0, ses.newkeys->trans_algo_crypt->keysize, 0,
&ses.newkeys->trans_symmetric_struct) != CRYPT_OK) { &ses.newkeys->trans_symmetric_struct) != CRYPT_OK) {
dropbear_exit("crypto error"); dropbear_exit("crypto error");
@ -517,7 +521,7 @@ void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
hash_state hs; hash_state hs;
/* read the prime and generator*/ /* read the prime and generator*/
mp_init(&dh_p); m_mp_init(&dh_p);
bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); 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] */ /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */

View File

@ -229,7 +229,7 @@ void session_identification() {
/* write our version string, this blocks */ /* write our version string, this blocks */
if (atomicio(write, ses.sock, LOCAL_IDENT "\r\n", if (atomicio(write, ses.sock, LOCAL_IDENT "\r\n",
strlen(LOCAL_IDENT "\r\n")) == DROPBEAR_FAILURE) { strlen(LOCAL_IDENT "\r\n")) == DROPBEAR_FAILURE) {
dropbear_exit("Error writing ident string"); ses.remoteclosed();
} }
/* If they send more than 50 lines, something is wrong */ /* If they send more than 50 lines, something is wrong */
@ -250,7 +250,7 @@ void session_identification() {
if (!done) { if (!done) {
TRACE(("err: %s for '%s'\n", strerror(errno), linebuf)) TRACE(("err: %s for '%s'\n", strerror(errno), linebuf))
dropbear_exit("Failed to get remote version"); ses.remoteclosed();
} else { } else {
/* linebuf is already null terminated */ /* linebuf is already null terminated */
ses.remoteident = m_malloc(len); ses.remoteident = m_malloc(len);

View File

@ -19,10 +19,13 @@ fi
AC_SUBST(LD) AC_SUBST(LD)
if test -z "$OLDCFLAGS" && test "$GCC" = "yes"; then if test -z "$OLDCFLAGS" && test "$GCC" = "yes"; then
AC_MSG_RESULT(No \$CFLAGS set... using "-Os -W -Wall" for GCC) AC_MSG_NOTICE(No \$CFLAGS set... using "-Os -W -Wall" for GCC)
CFLAGS="-Os -W -Wall" CFLAGS="-Os -W -Wall"
fi fi
# large file support is useful for scp
AC_SYS_LARGEFILE
# Host specific options # Host specific options
# this isn't a definitive list of hosts, they are just added as required # this isn't a definitive list of hosts, they are just added as required
AC_CANONICAL_HOST AC_CANONICAL_HOST
@ -75,7 +78,7 @@ dnl Can't use login() or logout() with uclibc
AC_CHECK_DECL(__UCLIBC__, AC_CHECK_DECL(__UCLIBC__,
[ [
no_loginfunc_check=1 no_loginfunc_check=1
AC_MSG_RESULT(Using uClibc - login() and logout() probably don't work, so we won't use them.) AC_MSG_NOTICE([Using uClibc - login() and logout() probably don't work, so we won't use them.])
],,,) ],,,)
# Checks for libraries. # Checks for libraries.
@ -104,16 +107,16 @@ AC_ARG_ENABLE(zlib,
[ [
if test "x$enableval" = "xno"; then if test "x$enableval" = "xno"; then
AC_DEFINE(DISABLE_ZLIB,, Use zlib) AC_DEFINE(DISABLE_ZLIB,, Use zlib)
AC_MSG_RESULT(Disabling zlib) AC_MSG_NOTICE(Disabling zlib)
else else
AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR([*** zlib missing - install first or check config.log ***])) AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR([*** zlib missing - install first or check config.log ***]))
AC_MSG_RESULT(Enabling zlib) AC_MSG_NOTICE(Enabling zlib)
fi fi
], ],
[ [
# if not disabled, check for zlib # if not disabled, check for zlib
AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR([*** zlib missing - install first or check config.log ***])) AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR([*** zlib missing - install first or check config.log ***]))
AC_MSG_RESULT(Enabling zlib) AC_MSG_NOTICE(Enabling zlib)
] ]
) )
@ -141,16 +144,16 @@ AC_ARG_ENABLE(pam,
[ [
if test "x$enableval" = "xyes"; then if test "x$enableval" = "xyes"; then
AC_CHECK_LIB(pam, pam_authenticate, , AC_MSG_ERROR([*** PAM missing - install first or check config.log ***])) AC_CHECK_LIB(pam, pam_authenticate, , AC_MSG_ERROR([*** PAM missing - install first or check config.log ***]))
AC_MSG_RESULT(Enabling PAM) AC_MSG_NOTICE(Enabling PAM)
else else
AC_DEFINE(DISABLE_PAM,, Use PAM) AC_DEFINE(DISABLE_PAM,, Use PAM)
AC_MSG_RESULT(Disabling PAM) AC_MSG_NOTICE(Disabling PAM)
fi fi
], ],
[ [
# disable it by default # disable it by default
AC_DEFINE(DISABLE_PAM,, Use PAM) AC_DEFINE(DISABLE_PAM,, Use PAM)
AC_MSG_RESULT(Disabling PAM) AC_MSG_NOTICE(Disabling PAM)
] ]
) )
@ -158,14 +161,14 @@ AC_ARG_ENABLE(openpty,
[ --disable-openpty Don't use openpty, use alternative method], [ --disable-openpty Don't use openpty, use alternative method],
[ [
if test "x$enableval" = "xno"; then if test "x$enableval" = "xno"; then
AC_MSG_RESULT(Not using openpty) AC_MSG_NOTICE(Not using openpty)
else else
AC_MSG_RESULT(Using openpty if available) AC_MSG_NOTICE(Using openpty if available)
AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY,,Have openpty() function)]) AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY,,Have openpty() function)])
fi fi
], ],
[ [
AC_MSG_RESULT(Using openpty if available) AC_MSG_NOTICE(Using openpty if available)
AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY)]) AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY)])
] ]
) )
@ -176,13 +179,13 @@ AC_ARG_ENABLE(syslog,
[ [
if test "x$enableval" = "xno"; then if test "x$enableval" = "xno"; then
AC_DEFINE(DISABLE_SYSLOG,, Using syslog) AC_DEFINE(DISABLE_SYSLOG,, Using syslog)
AC_MSG_RESULT(Disabling syslog) AC_MSG_NOTICE(Disabling syslog)
else else
AC_MSG_RESULT(Enabling syslog) AC_MSG_NOTICE(Enabling syslog)
fi fi
], ],
[ [
AC_MSG_RESULT(Enabling syslog) AC_MSG_NOTICE(Enabling syslog)
] ]
) )
@ -190,15 +193,15 @@ AC_ARG_ENABLE(shadow,
[ --disable-shadow Don't use shadow passwords (if available)], [ --disable-shadow Don't use shadow passwords (if available)],
[ [
if test "x$enableval" = "xno"; then if test "x$enableval" = "xno"; then
AC_MSG_RESULT(Not using shadow passwords) AC_MSG_NOTICE(Not using shadow passwords)
else else
AC_CHECK_HEADERS([shadow.h]) AC_CHECK_HEADERS([shadow.h])
AC_MSG_RESULT(Using shadow passwords if available) AC_MSG_NOTICE(Using shadow passwords if available)
fi fi
], ],
[ [
AC_CHECK_HEADERS([shadow.h]) AC_CHECK_HEADERS([shadow.h])
AC_MSG_RESULT(Using shadow passwords if available) AC_MSG_NOTICE(Using shadow passwords if available)
] ]
) )
@ -339,7 +342,7 @@ AC_CHECK_MEMBERS([struct utmp.ut_host, struct utmp.ut_pid, struct utmp.ut_type,
#endif #endif
]) ])
AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_type, struct utmpx.ut_id, struct utmpx.ut_addr, struct utmpx.ut_addr_v6, struct utmpx.ut_time, struct utmpx.ut_tv, struct sockaddr_storage.ss_family, struct sockadd_storage.__family],,,[ AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_type, struct utmpx.ut_id, struct utmpx.ut_addr, struct utmpx.ut_addr_v6, struct utmpx.ut_time, struct utmpx.ut_tv],,,[
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#if HAVE_UTMPX_H #if HAVE_UTMPX_H
@ -347,6 +350,11 @@ AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_
#endif #endif
]) ])
AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family],,,[
#include <sys/types.h>
#include <sys/socket.h>
])
AC_CHECK_FUNCS(endutent getutent getutid getutline pututline setutent) AC_CHECK_FUNCS(endutent getutent getutid getutline pututline setutent)
AC_CHECK_FUNCS(utmpname) AC_CHECK_FUNCS(utmpname)
AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline )
@ -379,7 +387,7 @@ AC_ARG_ENABLE(wtmpx,
AC_ARG_ENABLE(loginfunc, AC_ARG_ENABLE(loginfunc,
[ --disable-loginfunc Disable use of login() etc. [no]], [ --disable-loginfunc Disable use of login() etc. [no]],
[ no_loginfunc_check=1 [ no_loginfunc_check=1
AC_MSG_RESULT(Not using login() etc) ] AC_MSG_NOTICE(Not using login() etc) ]
) )
AC_ARG_ENABLE(pututline, AC_ARG_ENABLE(pututline,
[ --disable-pututline Disable use of pututline() etc. ([uw]tmp) [no]], [ --disable-pututline Disable use of pututline() etc. ([uw]tmp) [no]],
@ -596,7 +604,7 @@ if test -z "$no_ptmx_check" ; then
if test x"$cross_compiling" = x"no" ; then if test x"$cross_compiling" = x"no" ; then
AC_CHECK_FILE("/dev/ptmx", AC_DEFINE(USE_DEV_PTMX,,Use /dev/ptmx)) AC_CHECK_FILE("/dev/ptmx", AC_DEFINE(USE_DEV_PTMX,,Use /dev/ptmx))
else else
AC_MSG_RESULT(Not checking for /dev/ptmx, we're cross-compiling) AC_MSG_NOTICE(Not checking for /dev/ptmx, we're cross-compiling)
fi fi
fi fi
@ -604,14 +612,57 @@ if test -z "$no_ptc_check" ; then
if test x"$cross_compiling" = x"no" ; then if test x"$cross_compiling" = x"no" ; then
AC_CHECK_FILE("/dev/ptc", AC_DEFINE(HAVE_DEV_PTS_AND_PTC,,Use /dev/ptc & /dev/pts)) AC_CHECK_FILE("/dev/ptc", AC_DEFINE(HAVE_DEV_PTS_AND_PTC,,Use /dev/ptc & /dev/pts))
else else
AC_MSG_RESULT(Not checking for /dev/ptc & /dev/pts\, we're cross-compiling) AC_MSG_NOTICE(Not checking for /dev/ptc & /dev/pts\, we're cross-compiling)
fi fi
fi fi
AC_EXEEXT AC_EXEEXT
# XXX there must be a nicer way to do this
AS_MKDIR_P(libtomcrypt/src/ciphers/aes)
AS_MKDIR_P(libtomcrypt/src/ciphers/safer)
AS_MKDIR_P(libtomcrypt/src/ciphers/twofish)
AS_MKDIR_P(libtomcrypt/src/encauth/ccm)
AS_MKDIR_P(libtomcrypt/src/encauth/eax)
AS_MKDIR_P(libtomcrypt/src/encauth/gcm)
AS_MKDIR_P(libtomcrypt/src/encauth/ocb)
AS_MKDIR_P(libtomcrypt/src/hashes)
AS_MKDIR_P(libtomcrypt/src/hashes/chc)
AS_MKDIR_P(libtomcrypt/src/hashes/helper)
AS_MKDIR_P(libtomcrypt/src/hashes/sha2)
AS_MKDIR_P(libtomcrypt/src/hashes/whirl)
AS_MKDIR_P(libtomcrypt/src/mac/hmac)
AS_MKDIR_P(libtomcrypt/src/mac/omac)
AS_MKDIR_P(libtomcrypt/src/mac/pelican)
AS_MKDIR_P(libtomcrypt/src/mac/pmac)
AS_MKDIR_P(libtomcrypt/src/misc/base64)
AS_MKDIR_P(libtomcrypt/src/misc/crypt)
AS_MKDIR_P(libtomcrypt/src/misc/mpi)
AS_MKDIR_P(libtomcrypt/src/misc/pkcs5)
AS_MKDIR_P(libtomcrypt/src/modes/cbc)
AS_MKDIR_P(libtomcrypt/src/modes/cfb)
AS_MKDIR_P(libtomcrypt/src/modes/ctr)
AS_MKDIR_P(libtomcrypt/src/modes/ecb)
AS_MKDIR_P(libtomcrypt/src/modes/ofb)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/bit)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/choice)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/ia5)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/integer)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/object_identifier)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/octet)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/printable_string)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/sequence)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/short_integer)
AS_MKDIR_P(libtomcrypt/src/pk/asn1/der/utctime)
AS_MKDIR_P(libtomcrypt/src/pk/dh)
AS_MKDIR_P(libtomcrypt/src/pk/dsa)
AS_MKDIR_P(libtomcrypt/src/pk/ecc)
AS_MKDIR_P(libtomcrypt/src/pk/pkcs1)
AS_MKDIR_P(libtomcrypt/src/pk/rsa)
AS_MKDIR_P(libtomcrypt/src/prng)
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
AC_OUTPUT(Makefile) AC_OUTPUT(Makefile)
AC_OUTPUT(libtomcrypt/Makefile) AC_OUTPUT(libtomcrypt/Makefile)
AC_OUTPUT(libtommath/Makefile) AC_OUTPUT(libtommath/Makefile)
AC_MSG_RESULT() AC_MSG_NOTICE()
AC_MSG_RESULT(Now edit options.h to choose features.) AC_MSG_NOTICE(Now edit options.h to choose features.)

View File

@ -29,24 +29,23 @@ Read the identity from file
.I idfile .I idfile
(multiple allowed). (multiple allowed).
.TP .TP
.B \-L \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR .B \-L \fIlistenport\fR:\fIhost\fR:\fIport\fR
Local port forwarding. Local port forwarding.
Forward the port Forward the port
.I localport .I listenport
on the local host to port on the local host through the SSH connection to port
.I remoteport .I port
on the remote host on the host
.IR remotehost . .IR host .
.TP .TP
.B \-R \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR .B \-R \fIlistenport\fR:\fIhost\fR:\fIport\fR
Remote port forwarding. Remote port forwarding.
Forward the port Forward the port
.I remoteport .I listenport
on the remote host on the remote host through the SSH connection to port
.I remotehost .I port
to port on the host
.I localport .IR host .
on the local host.
.TP .TP
.B \-l \fIuser .B \-l \fIuser
Username. Username.
@ -60,6 +59,13 @@ Allocate a pty.
.B \-T .B \-T
Don't allocate a pty. Don't allocate a pty.
.TP .TP
.B \-N
Don't request a remote shell or run any commands. Any command arguments are ignored.
.TP
.B \-f
Fork into the background after authentication. A command argument (or -N) is required.
This is useful when using password authentication.
.TP
.B \-g .B \-g
Allow non-local hosts to connect to forwarded ports. Applies to -L and -R Allow non-local hosts to connect to forwarded ports. Applies to -L and -R
forwarded ports, though remote connections to -R forwarded ports may be limited forwarded ports, though remote connections to -R forwarded ports may be limited

View File

@ -400,7 +400,10 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
len = sizeof(struct sockaddr_storage); len = sizeof(struct sockaddr_storage);
/* Some platforms such as Solaris 8 require that len is the length /* Some platforms such as Solaris 8 require that len is the length
* of the specific structure. */ * of the specific structure. Some older linux systems (glibc 2.1.3
* such as debian potato) have sockaddr_storage.__ss_family instead
* but we'll ignore them */
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
if (addr->ss_family == AF_INET) { if (addr->ss_family == AF_INET) {
len = sizeof(struct sockaddr_in); len = sizeof(struct sockaddr_in);
} }
@ -408,6 +411,7 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
if (addr->ss_family == AF_INET6) { if (addr->ss_family == AF_INET6) {
len = sizeof(struct sockaddr_in6); len = sizeof(struct sockaddr_in6);
} }
#endif
#endif #endif
ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf), ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
@ -448,6 +452,7 @@ char* getaddrhostname(struct sockaddr_storage * addr) {
len = sizeof(struct sockaddr_storage); len = sizeof(struct sockaddr_storage);
/* Some platforms such as Solaris 8 require that len is the length /* Some platforms such as Solaris 8 require that len is the length
* of the specific structure. */ * of the specific structure. */
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
if (addr->ss_family == AF_INET) { if (addr->ss_family == AF_INET) {
len = sizeof(struct sockaddr_in); len = sizeof(struct sockaddr_in);
} }
@ -456,6 +461,7 @@ char* getaddrhostname(struct sockaddr_storage * addr) {
len = sizeof(struct sockaddr_in6); len = sizeof(struct sockaddr_in6);
} }
#endif #endif
#endif
ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf), ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
@ -521,26 +527,36 @@ char * stripcontrol(const char * text) {
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int buf_readfile(buffer* buf, const char* filename) { int buf_readfile(buffer* buf, const char* filename) {
int fd; int fd = -1;
int len; int len;
int maxlen; int maxlen;
int ret = DROPBEAR_FAILURE;
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) { if (fd < 0) {
close(fd); goto out;
return DROPBEAR_FAILURE;
} }
do { do {
maxlen = buf->size - buf->pos; maxlen = buf->size - buf->pos;
len = read(fd, buf_getwriteptr(buf, maxlen), len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
maxlen); if (len < 0) {
if (errno == EINTR || errno == EAGAIN) {
continue;
}
goto out;
}
buf_incrwritepos(buf, len); buf_incrwritepos(buf, len);
} while (len < maxlen && len > 0); } while (len < maxlen && len > 0);
close(fd); ret = DROPBEAR_SUCCESS;
return DROPBEAR_SUCCESS;
out:
if (fd >= 0) {
m_close(fd);
}
return ret;
} }
/* get a line from the file into buffer in the style expected for an /* get a line from the file into buffer in the style expected for an

34
debian/changelog vendored
View File

@ -1,14 +1,38 @@
dropbear (0.48-0.1) unstable; urgency=high dropbear (0.49-0.1) unstable; urgency=low
* New upstream release. * New upstream release.
* SECURITY: Improve handling of denial of service attempts from a single IP.
-- Matt Johnston <matt@ucc.asn.au> Thu, 8 Mar 2006 19:20:21 +0800 -- Matt Johnston <matt@ucc.asn.au> Tues, 13 June 2005 19:20:21 +0800
dropbear (0.47-0.1) unstable; urgency=high dropbear (0.48.1-1) unstable; urgency=medium
* new upstream point release.
* Compile fix for scp
* debian/diff/dbclient.1.diff: new: document -R option to dbclient
accurately (thx Markus Schaber; closes: #351882).
* debian/dropbear.README.Debian: document a workaround for systems with
possibly blocking /dev/random device (closes: #355414)..
-- Gerrit Pape <pape@smarden.org> Sun, 16 Apr 2006 16:16:40 +0000
dropbear (0.48-1) unstable; urgency=medium
* New upstream release. * New upstream release.
* SECURITY: Fix incorrect buffer sizing. * SECURITY: Improve handling of denial of service attempts from a single
IP.
* debian/implicit: update to revision 1.11.
* new upstream release updates to scp from OpenSSH 4.3p2 - fixes a
security issue where use of system() could cause users to execute
arbitrary code through malformed filenames; CVE-2006-0225 (see also
#349645); the scp binary is not provided by this package though.
-- Gerrit Pape <pape@smarden.org> Fri, 10 Mar 2006 22:00:32 +0000
dropbear (0.47-1) unstable; urgency=high
* New upstream release.
* SECURITY: Fix incorrect buffer sizing; CVE-2005-4178.
-- Matt Johnston <matt@ucc.asn.au> Thu, 8 Dec 2005 19:20:21 +0800 -- Matt Johnston <matt@ucc.asn.au> Thu, 8 Dec 2005 19:20:21 +0800

View File

@ -39,3 +39,14 @@ by following these steps:
See the Dropbear homepage for more information: See the Dropbear homepage for more information:
http://matt.ucc.asn.au/dropbear/dropbear.html http://matt.ucc.asn.au/dropbear/dropbear.html
Entropy from /dev/random
------------------------
The dropbear binary package is configured at compile time to read
entropy from /dev/random. If /dev/random on a system blocks when
reading data from it, client logins may be delayed until the client
times out. The dropbear server writes a notice to the logs when it
sees /dev/random blocking. A workaround for such systems is to
re-compile the package with DROPBEAR_RANDOM_DEV set to /dev/urandom
in options.h.

10
debian/implicit vendored
View File

@ -1,4 +1,4 @@
# $Id: implicit,v 1.10 2004/07/03 15:20:00 pape Exp $ # $Id: implicit,v 1.11 2005/11/29 21:57:55 pape Exp $
.PHONY: deb-checkdir deb-checkuid .PHONY: deb-checkdir deb-checkuid
@ -38,6 +38,14 @@ deb-checkuid:
@gzip -9 debian/$*/usr/share/doc/$*/changelog* @gzip -9 debian/$*/usr/share/doc/$*/changelog*
%.deb-docs-docs: %.deb-docs-docs:
@for i in `cat debian/$*.docs 2>/dev/null || :`; do \ @for i in `cat debian/$*.docs 2>/dev/null || :`; do \
if test -d $$i; then \
sh -cx "install -d -m0755 debian/$*/usr/share/doc/$*/$${i##*/}" && \
for j in $$i/*; do \
sh -cx "install -m0644 $$j \
debian/$*/usr/share/doc/$*/$${i##*/}/" || exit 1; \
done || exit 1; \
continue; \
fi; \
sh -cx "install -m0644 $$i debian/$*/usr/share/doc/$*/" || exit 1; \ sh -cx "install -m0644 $$i debian/$*/usr/share/doc/$*/" || exit 1; \
done done
@test ! -r debian/$*.README.Debian || \ @test ! -r debian/$*.README.Debian || \

View File

@ -44,8 +44,10 @@
/* All functions writing to the cleartext payload buffer call /* All functions writing to the cleartext payload buffer call
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're * CHECKCLEARTOWRITE() before writing. This is only really useful if you're
* attempting to track down a problem */ * attempting to track down a problem */
#define CHECKCLEARTOWRITE() assert(ses.writepayload->len == 0 && \ /*#define CHECKCLEARTOWRITE() assert(ses.writepayload->len == 0 && \
ses.writepayload->pos == 0) ses.writepayload->pos == 0)*/
#define CHECKCLEARTOWRITE()
/* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon /* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon
* output when Dropbear forks. This will allow it gprof to be used. * output when Dropbear forks. This will allow it gprof to be used.

View File

@ -72,6 +72,10 @@ Use this option to run
under TCP/IP servers like inetd, tcpsvd, or tcpserver. under TCP/IP servers like inetd, tcpsvd, or tcpserver.
In program mode the \-F option is implied, and \-p options are ignored. In program mode the \-F option is implied, and \-p options are ignored.
.TP .TP
.B \-P \fIpidfile
Specify a pidfile to create when running as a daemon. If not specified, the
default is /var/run/dropbear.pid
.TP
.B \-a .B \-a
Allow remote hosts to connect to forwarded ports. Allow remote hosts to connect to forwarded ports.
.SH AUTHOR .SH AUTHOR

View File

@ -283,8 +283,10 @@ out:
buf_burn(buf); buf_burn(buf);
buf_free(buf); buf_free(buf);
buf = NULL; buf = NULL;
if (key) {
sign_key_free(key); sign_key_free(key);
key = NULL; key = NULL;
}
exit(err); exit(err);
} }
@ -297,6 +299,9 @@ static void printpubkey(sign_key * key, int keytype) {
const char * typestring = NULL; const char * typestring = NULL;
char *fp = NULL; char *fp = NULL;
int len; int len;
struct passwd * pw = NULL;
char * username = NULL;
char hostname[100];
buf = buf_new(MAX_PUBKEY_SIZE); buf = buf_new(MAX_PUBKEY_SIZE);
buf_put_pub_key(buf, key, keytype); buf_put_pub_key(buf, key, keytype);
@ -315,8 +320,18 @@ static void printpubkey(sign_key * key, int keytype) {
fp = sign_key_fingerprint(buf_getptr(buf, len), len); fp = sign_key_fingerprint(buf_getptr(buf, len), len);
printf("Public key portion is:\n%s %s\nFingerprint: %s\n", /* a user@host comment is informative */
typestring, base64key, fp); username = "";
pw = getpwuid(getuid());
if (pw) {
username = pw->pw_name;
}
gethostname(hostname, sizeof(hostname));
hostname[sizeof(hostname)-1] = '\0';
printf("Public key portion is:\n%s %s %s@%s\nFingerprint: %s\n",
typestring, base64key, username, hostname, fp);
m_free(fp); m_free(fp);
buf_free(buf); buf_free(buf);

4
dss.c
View File

@ -341,7 +341,9 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data,
/* generate k */ /* generate k */
m_mp_init(&dss_protok); m_mp_init(&dss_protok);
bytes_to_mp(&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); if (mp_mod(&dss_protok, key->q, &dss_k) != MP_OKAY) {
dropbear_exit("dss error");
}
mp_clear(&dss_protok); mp_clear(&dss_protok);
m_burn(proto_k, SHA512_HASH_SIZE); m_burn(proto_k, SHA512_HASH_SIZE);
#else /* DSS_PROTOK not defined*/ #else /* DSS_PROTOK not defined*/

View File

@ -135,13 +135,6 @@ typedef u_int16_t uint16_t;
#define LOG_AUTHPRIV LOG_AUTH #define LOG_AUTHPRIV LOG_AUTH
#endif #endif
/* glibc 2.1.3 systems have sockaddr_storage.__ss_family rather than
* sockaddr_storage.ss_family */
#if !defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY) \
&& defined(HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY)
#define ss_family __ss_family
#endif
/* so we can avoid warnings about unused params (ie in signal handlers etc) */ /* so we can avoid warnings about unused params (ie in signal handlers etc) */
#ifdef UNUSED #ifdef UNUSED
#elif defined(__GNUC__) #elif defined(__GNUC__)

View File

@ -361,7 +361,7 @@ struct openssh_key {
static struct openssh_key *load_openssh_key(const char *filename) static struct openssh_key *load_openssh_key(const char *filename)
{ {
struct openssh_key *ret; struct openssh_key *ret;
FILE *fp; FILE *fp = NULL;
char buffer[256]; char buffer[256];
char *errmsg = NULL, *p = NULL; char *errmsg = NULL, *p = NULL;
int headers_done; int headers_done;
@ -482,6 +482,9 @@ static struct openssh_key *load_openssh_key(const char *filename)
memset(&ret, 0, sizeof(ret)); memset(&ret, 0, sizeof(ret));
m_free(ret); m_free(ret);
} }
if (fp) {
fclose(fp);
}
if (errmsg) { if (errmsg) {
fprintf(stderr, "Error: %s\n", errmsg); fprintf(stderr, "Error: %s\n", errmsg);
} }
@ -926,40 +929,6 @@ static int openssh_write(const char *filename, sign_key *key,
if (passphrase) { if (passphrase) {
fprintf(stderr, "Encrypted keys aren't supported currently\n"); fprintf(stderr, "Encrypted keys aren't supported currently\n");
goto error; goto error;
#if 0
/*
* Invent an iv. Then derive encryption key from passphrase
* and iv/salt:
*
* - let block A equal MD5(passphrase || iv)
* - let block B equal MD5(A || passphrase || iv)
* - block C would be MD5(B || passphrase || iv) and so on
* - encryption key is the first N bytes of A || B
*/
struct MD5Context md5c;
unsigned char keybuf[32];
for (i = 0; i < 8; i++) iv[i] = random_byte();
MD5Init(&md5c);
MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
MD5Update(&md5c, iv, 8);
MD5Final(keybuf, &md5c);
MD5Init(&md5c);
MD5Update(&md5c, keybuf, 16);
MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
MD5Update(&md5c, iv, 8);
MD5Final(keybuf+16, &md5c);
/*
* Now encrypt the key blob.
*/
des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
memset(&md5c, 0, sizeof(md5c));
memset(keybuf, 0, sizeof(keybuf));
#endif
} }
/* /*
@ -976,12 +945,6 @@ static int openssh_write(const char *filename, sign_key *key,
goto error; goto error;
} }
fputs(header, fp); fputs(header, fp);
if (passphrase) {
fprintf(fp, "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,");
for (i = 0; i < 8; i++)
fprintf(fp, "%02X", iv[i]);
fprintf(fp, "\n\n");
}
base64_encode_fp(fp, outblob, outlen, 64); base64_encode_fp(fp, outblob, outlen, 64);
fputs(footer, fp); fputs(footer, fp);
fclose(fp); fclose(fp);

View File

@ -158,7 +158,7 @@ default:library
#ciphers come in two flavours... enc+dec and enc #ciphers come in two flavours... enc+dec and enc
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o $(CC) $(CFLAGS) -DENCRYPT_ONLY -c $< -o src/ciphers/aes/aes_enc.o
#These are the rules to make certain object files. #These are the rules to make certain object files.
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c

View File

@ -269,7 +269,9 @@ int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
} }
if (d != NULL) { if (d != NULL) {
mp_div_2d (&x, norm, &x, NULL); if ((res = mp_div_2d (&x, norm, &x, NULL)) != MP_OKAY) {
goto LBL_Y;
}
mp_exch (&x, d); mp_exch (&x, d);
} }

View File

@ -128,7 +128,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
* You can't enable both PASSWORD and PAM. */ * You can't enable both PASSWORD and PAM. */
#define ENABLE_SVR_PASSWORD_AUTH #define ENABLE_SVR_PASSWORD_AUTH
/* #define ENABLE_SVR_PAM_AUTH */ /* requires ./configure --enable-pam */ /*#define ENABLE_SVR_PAM_AUTH */
#define ENABLE_SVR_PUBKEY_AUTH #define ENABLE_SVR_PUBKEY_AUTH
#define ENABLE_CLI_PASSWORD_AUTH #define ENABLE_CLI_PASSWORD_AUTH
@ -199,15 +199,17 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
* not using the Dropbear client, you'll need to change it */ * not using the Dropbear client, you'll need to change it */
#define _PATH_SSH_PROGRAM "/usr/bin/dbclient" #define _PATH_SSH_PROGRAM "/usr/bin/dbclient"
/* Multi-purpose binary configuration has now moved. Look at the top /* Whether to log commands executed by a client. This only logs the
* of the Makefile for instructions, or INSTALL */ * (single) command sent to the server, not what a user did in a
* shell/sftp session etc. */
/* #define LOG_COMMANDS */
/******************************************************************* /*******************************************************************
* You shouldn't edit below here unless you know you need to. * You shouldn't edit below here unless you know you need to.
*******************************************************************/ *******************************************************************/
#ifndef DROPBEAR_VERSION #ifndef DROPBEAR_VERSION
#define DROPBEAR_VERSION "0.48" #define DROPBEAR_VERSION "0.49"
#endif #endif
#define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION #define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION
@ -250,6 +252,9 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
#define DROPBEAR_MAX_PORTS 10 /* max number of ports which can be specified, #define DROPBEAR_MAX_PORTS 10 /* max number of ports which can be specified,
ipv4 and ipv6 don't count twice */ ipv4 and ipv6 don't count twice */
/* Each port might have at least a v4 and a v6 address */
#define MAX_LISTEN_ADDR (DROPBEAR_MAX_PORTS*3)
#define _PATH_TTY "/dev/tty" #define _PATH_TTY "/dev/tty"
#define _PATH_CP "/bin/cp" #define _PATH_CP "/bin/cp"
@ -300,7 +305,6 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
#define MAX_PROPOSED_ALGO 20 #define MAX_PROPOSED_ALGO 20
/* size/count limits */ /* size/count limits */
#define MAX_LISTEN_ADDR 10
#define MAX_PACKET_LEN 35000 #define MAX_PACKET_LEN 35000
#define MIN_PACKET_LEN 16 #define MIN_PACKET_LEN 16

21
rsa.c
View File

@ -300,18 +300,29 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data,
/* rsa_tmp1 is em */ /* rsa_tmp1 is em */
/* em' = em * r^e mod n */ /* em' = em * r^e mod n */
mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/ /* rsa_s used as a temp var*/
mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3); if (mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != MP_OKAY) {
mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2); dropbear_exit("rsa error");
}
if (mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3) != MP_OKAY) {
dropbear_exit("rsa error");
}
if (mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2) != MP_OKAY) {
dropbear_exit("rsa error");
}
/* rsa_tmp2 is em' */ /* rsa_tmp2 is em' */
/* s' = (em')^d mod n */ /* s' = (em')^d mod n */
mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1); if (mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1) != MP_OKAY) {
dropbear_exit("rsa error");
}
/* rsa_tmp1 is s' */ /* rsa_tmp1 is s' */
/* rsa_tmp3 is r^(-1) mod n */ /* rsa_tmp3 is r^(-1) mod n */
/* s = (s')r^(-1) mod n */ /* s = (s')r^(-1) mod n */
mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s); if (mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s) != MP_OKAY) {
dropbear_exit("rsa error");
}
#else #else

View File

@ -83,6 +83,7 @@ typedef struct svr_runopts {
sign_key *hostkey; sign_key *hostkey;
buffer * banner; buffer * banner;
char * pidfile;
} svr_runopts; } svr_runopts;
@ -101,6 +102,8 @@ typedef struct cli_runopts {
char *cmd; char *cmd;
int wantpty; int wantpty;
int no_cmd;
int backgrounded;
#ifdef ENABLE_CLI_PUBKEY_AUTH #ifdef ENABLE_CLI_PUBKEY_AUTH
struct SignKeyList *privkeys; /* Keys to use for public-key auth */ struct SignKeyList *privkeys; /* Keys to use for public-key auth */
#endif #endif

View File

@ -67,8 +67,7 @@ static void get_termmodes(struct ChanSess *chansess);
extern char** environ; extern char** environ;
static int sesscheckclose(struct Channel *channel) { static int sesscheckclose(struct Channel *channel) {
struct ChanSess *chansess = (struct ChanSess*)channel->typedata; return channel->writefd == -1;
return chansess->exit.exitpid >= 0;
} }
/* Handler for childs exiting, store the state for return to the client */ /* Handler for childs exiting, store the state for return to the client */
@ -89,6 +88,8 @@ static void sesssigchild_handler(int UNUSED(dummy)) {
TRACE(("enter sigchld handler")) TRACE(("enter sigchld handler"))
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
exit = NULL;
/* find the corresponding chansess */ /* find the corresponding chansess */
for (i = 0; i < svr_ses.childpidsize; i++) { for (i = 0; i < svr_ses.childpidsize; i++) {
if (svr_ses.childpids[i].pid == pid) { if (svr_ses.childpids[i].pid == pid) {
@ -119,7 +120,6 @@ static void sesssigchild_handler(int UNUSED(dummy)) {
/* we use this to determine how pid exited */ /* we use this to determine how pid exited */
exit->exitsignal = -1; exit->exitsignal = -1;
} }
exit = NULL;
} }
@ -410,7 +410,7 @@ static int sessionwinchange(struct ChanSess *chansess) {
pty_change_window_size(chansess->master, termr, termc, termw, termh); pty_change_window_size(chansess->master, termr, termc, termw, termh);
return DROPBEAR_FAILURE; return DROPBEAR_SUCCESS;
} }
static void get_termmodes(struct ChanSess *chansess) { static void get_termmodes(struct ChanSess *chansess) {
@ -588,6 +588,16 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
} }
} }
#ifdef LOG_COMMANDS
if (chansess->cmd) {
dropbear_log(LOG_INFO, "user %s executing '%s'",
ses.authstate.printableuser, chansess->cmd);
} else {
dropbear_log(LOG_INFO, "user %s executing login shell",
ses.authstate.printableuser);
}
#endif
if (chansess->term == NULL) { if (chansess->term == NULL) {
/* no pty */ /* no pty */
ret = noptycommand(channel, chansess); ret = noptycommand(channel, chansess);

View File

@ -52,7 +52,9 @@ void recv_msg_kexdh_init() {
} }
m_mp_init(&dh_e); m_mp_init(&dh_e);
buf_getmpint(ses.payload, &dh_e); if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) {
dropbear_exit("Failed to get kex value");
}
send_msg_kexdh_reply(&dh_e); send_msg_kexdh_reply(&dh_e);

View File

@ -146,7 +146,7 @@ void main_noinetd() {
} }
/* create a PID file so that we can be killed easily */ /* create a PID file so that we can be killed easily */
pidfile = fopen(DROPBEAR_PIDFILE, "w"); pidfile = fopen(svr_opts.pidfile, "w");
if (pidfile) { if (pidfile) {
fprintf(pidfile, "%d\n", getpid()); fprintf(pidfile, "%d\n", getpid());
fclose(pidfile); fclose(pidfile);
@ -189,7 +189,7 @@ void main_noinetd() {
val = select(maxsock+1, &fds, NULL, NULL, &seltimeout); val = select(maxsock+1, &fds, NULL, NULL, &seltimeout);
if (exitflag) { if (exitflag) {
unlink(DROPBEAR_PIDFILE); unlink(svr_opts.pidfile);
dropbear_exit("Terminated by signal"); dropbear_exit("Terminated by signal");
} }

View File

@ -72,6 +72,8 @@ static void printhelp(const char * progname) {
#endif #endif
"-p port Listen on specified tcp port, up to %d can be specified\n" "-p port Listen on specified tcp port, up to %d can be specified\n"
" (default %s if none specified)\n" " (default %s if none specified)\n"
"-P PidFile Create pid file PidFile\n"
" (default %s)\n"
#ifdef INETD_MODE #ifdef INETD_MODE
"-i Start for inetd\n" "-i Start for inetd\n"
#endif #endif
@ -85,7 +87,7 @@ static void printhelp(const char * progname) {
#ifdef DROPBEAR_RSA #ifdef DROPBEAR_RSA
RSA_PRIV_FILENAME, RSA_PRIV_FILENAME,
#endif #endif
DROPBEAR_MAX_PORTS, DROPBEAR_DEFPORT); DROPBEAR_MAX_PORTS, DROPBEAR_DEFPORT, DROPBEAR_PIDFILE);
} }
void svr_getopts(int argc, char ** argv) { void svr_getopts(int argc, char ** argv) {
@ -105,6 +107,7 @@ void svr_getopts(int argc, char ** argv) {
svr_opts.inetdmode = 0; svr_opts.inetdmode = 0;
svr_opts.portcount = 0; svr_opts.portcount = 0;
svr_opts.hostkey = NULL; svr_opts.hostkey = NULL;
svr_opts.pidfile = DROPBEAR_PIDFILE;
#ifdef ENABLE_SVR_LOCALTCPFWD #ifdef ENABLE_SVR_LOCALTCPFWD
svr_opts.nolocaltcp = 0; svr_opts.nolocaltcp = 0;
#endif #endif
@ -185,6 +188,9 @@ void svr_getopts(int argc, char ** argv) {
svr_opts.portcount++; svr_opts.portcount++;
} }
break; break;
case 'P':
next = &svr_opts.pidfile;
break;
#ifdef DO_MOTD #ifdef DO_MOTD
/* motd is displayed by default, -m turns it off */ /* motd is displayed by default, -m turns it off */
case 'm': case 'm':

View File

@ -216,7 +216,7 @@ out:
if (ret == DROPBEAR_FAILURE) { if (ret == DROPBEAR_FAILURE) {
/* we only free it if a listener wasn't created, since the listener /* we only free it if a listener wasn't created, since the listener
* has to remember it if it's to be cancelled */ * has to remember it if it's to be cancelled */
m_free(tcpinfo->listenaddr); m_free(bindaddr);
m_free(tcpinfo); m_free(tcpinfo);
} }
TRACE(("leave remotetcpreq")) TRACE(("leave remotetcpreq"))