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
- Compile fix for scp

View File

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

2
auth.h
View File

@ -52,7 +52,7 @@ void cli_pubkeyfail();
void cli_auth_password();
int cli_auth_pubkey();
void cli_auth_interactive();
char* getpass_or_cancel();
char* getpass_or_cancel(char* prompt);
#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
* password is statically allocated by getpass() */
char* getpass_or_cancel()
char* getpass_or_cancel(char* prompt)
{
char* password = NULL;
password = getpass("Password: ");
password = getpass(prompt);
/* 0x03 is a ctrl-c character in the buffer. */
if (password == NULL || strchr(password, '\3') != NULL) {

View File

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

View File

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

View File

@ -112,6 +112,7 @@ void recv_msg_userauth_pk_ok() {
/* Success */
break;
}
buf_free(keybuf);
if (keyitem != NULL) {
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",
cli_opts.remotehost,
fp);
m_free(fp);
tty = fopen(_PATH_TTY, "r");
if (tty) {
@ -132,7 +133,6 @@ static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) {
}
if (response == 'y') {
m_free(fp);
return;
}
@ -145,49 +145,59 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
FILE *hostsfile = NULL;
int readonly = 0;
struct passwd *pw = NULL;
char * homedir = NULL;
unsigned int hostlen, algolen;
unsigned long len;
const char *algoname = NULL;
buffer * line = NULL;
int ret;
pw = getpwuid(getuid());
homedir = getenv("HOME");
if (pw == NULL) {
dropbear_exit("Failed to get homedir");
}
len = strlen(pw->pw_dir);
filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/
snprintf(filename, len+18, "%s/.ssh", pw->pw_dir);
/* Check that ~/.ssh exists - easiest way is just to mkdir */
if (mkdir(filename, S_IRWXU) != 0) {
if (errno != EEXIST) {
dropbear_log(LOG_INFO, "Warning: failed creating ~/.ssh: %s",
strerror(errno));
TRACE(("mkdir didn't work: %s", strerror(errno)))
ask_to_confirm(keyblob, keybloblen);
goto out; /* only get here on success */
if (!homedir) {
pw = getpwuid(getuid());
if (pw) {
homedir = pw->pw_dir;
}
pw = NULL;
}
snprintf(filename, len+18, "%s/.ssh/known_hosts", pw->pw_dir);
hostsfile = fopen(filename, "a+");
if (hostsfile != NULL) {
fseek(hostsfile, 0, SEEK_SET);
} else {
/* We mightn't have been able to open it if it was read-only */
if (errno == EACCES || errno == EROFS) {
TRACE(("trying readonly: %s", strerror(errno)))
readonly = 1;
hostsfile = fopen(filename, "r");
if (homedir) {
len = strlen(homedir);
filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/
snprintf(filename, len+18, "%s/.ssh", homedir);
/* Check that ~/.ssh exists - easiest way is just to mkdir */
if (mkdir(filename, S_IRWXU) != 0) {
if (errno != EEXIST) {
dropbear_log(LOG_INFO, "Warning: failed creating %s/.ssh: %s",
homedir, strerror(errno));
TRACE(("mkdir didn't work: %s", strerror(errno)))
ask_to_confirm(keyblob, keybloblen);
goto out; /* only get here on success */
}
}
snprintf(filename, len+18, "%s/.ssh/known_hosts", homedir);
hostsfile = fopen(filename, "a+");
if (hostsfile != NULL) {
fseek(hostsfile, 0, SEEK_SET);
} else {
/* We mightn't have been able to open it if it was read-only */
if (errno == EACCES || errno == EROFS) {
TRACE(("trying readonly: %s", strerror(errno)))
readonly = 1;
hostsfile = fopen(filename, "r");
}
}
}
if (hostsfile == NULL) {
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);
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() {
fprintf(stderr, "Dropbear client v%s\n"
"Usage: %s [options] [user@]host\n"
"Usage: %s [options] [user@]host [command]\n"
"Options are:\n"
"-p <remoteport>\n"
"-l <username>\n"
"-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
"-i <identityfile> (multiple allowed)\n"
#endif
@ -88,6 +90,8 @@ void cli_getopts(int argc, char ** argv) {
cli_opts.remoteport = NULL;
cli_opts.username = 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 */
#ifdef ENABLE_CLI_PUBKEY_AUTH
cli_opts.privkeys = NULL;
@ -163,6 +167,12 @@ void cli_getopts(int argc, char ** argv) {
case 'T': /* don't want a pty */
cli_opts.wantpty = 0;
break;
case 'N':
cli_opts.no_cmd = 1;
break;
case 'f':
cli_opts.backgrounded = 1;
break;
#ifdef ENABLE_CLI_LOCALTCPFWD
case 'L':
nextislocal = 1;
@ -269,6 +279,11 @@ void cli_getopts(int argc, char ** argv) {
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

View File

@ -82,6 +82,4 @@ void recv_msg_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:
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
setup_localtcp();
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
setup_remotetcp();
#endif
cli_send_chansess_request();
TRACE(("leave cli_sessionloop: cli_send_chansess_request"))
if (!cli_opts.no_cmd) {
cli_send_chansess_request();
}
TRACE(("leave cli_sessionloop: running"))
cli_ses.state = SESSION_RUNNING;
return;
case SESSION_RUNNING:
if (ses.chancount < 1) {
if (ses.chancount < 1 && !cli_opts.no_cmd) {
cli_finished();
}

View File

@ -181,6 +181,7 @@ void channelio(fd_set *readfds, fd_set *writefds) {
struct Channel *channel;
unsigned int i;
int ret;
/* iterate through all the possible channels */
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);
}
/* 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 */
if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
if (channel->initconn) {
@ -241,27 +261,27 @@ static void checkclose(struct Channel *channel) {
channel->writebuf,
channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)))
if (!channel->sentclosed) {
/* check for exited - currently only used for server sessions,
* if the shell has exited etc */
if (channel->type->checkclose) {
if (channel->type->checkclose(channel)) {
closewritefd(channel);
}
/* server chansession channels are special, since readfd mightn't
* close in the case of "sleep 4 & echo blah" until the sleep is up */
if (channel->type->checkclose) {
if (channel->type->checkclose(channel)) {
closewritefd(channel);
closereadfd(channel, channel->readfd);
closereadfd(channel, channel->errfd);
}
}
if (!channel->senteof
&& channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_eof(channel);
}
if (!channel->senteof
&& channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_eof(channel);
}
if (channel->writefd == FD_CLOSED
&& channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_close(channel);
}
if (!channel->sentclosed
&& channel->writefd == FD_CLOSED
&& channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_close(channel);
}
/* When either party wishes to terminate the channel, it sends
@ -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 */
if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 )
|| channel->initconn) {
FD_SET(channel->writefd, writefds);
}

View File

@ -262,6 +262,7 @@ void gen_new_keys() {
hash_state hs;
unsigned int C2S_keysize, S2C_keysize;
char mactransletter, macrecvletter; /* Client or server specific */
int recv_cipher = 0, trans_cipher = 0;
TRACE(("enter gen_new_keys"))
/* 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(S2C_key, S2C_keysize, &hs, 'D');
if (cbc_start(
find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name),
recv_IV, recv_key,
recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name);
if (recv_cipher < 0)
dropbear_exit("crypto error");
if (cbc_start(recv_cipher, recv_IV, recv_key,
ses.newkeys->recv_algo_crypt->keysize, 0,
&ses.newkeys->recv_symmetric_struct) != CRYPT_OK) {
dropbear_exit("crypto error");
}
if (cbc_start(
find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name),
trans_IV, trans_key,
trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name);
if (trans_cipher < 0)
dropbear_exit("crypto error");
if (cbc_start(trans_cipher, trans_IV, trans_key,
ses.newkeys->trans_algo_crypt->keysize, 0,
&ses.newkeys->trans_symmetric_struct) != CRYPT_OK) {
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;
/* 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);
/* 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 */
if (atomicio(write, ses.sock, LOCAL_IDENT "\r\n",
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 */
@ -250,7 +250,7 @@ void session_identification() {
if (!done) {
TRACE(("err: %s for '%s'\n", strerror(errno), linebuf))
dropbear_exit("Failed to get remote version");
ses.remoteclosed();
} else {
/* linebuf is already null terminated */
ses.remoteident = m_malloc(len);

View File

@ -19,10 +19,13 @@ fi
AC_SUBST(LD)
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"
fi
# large file support is useful for scp
AC_SYS_LARGEFILE
# Host specific options
# this isn't a definitive list of hosts, they are just added as required
AC_CANONICAL_HOST
@ -75,7 +78,7 @@ dnl Can't use login() or logout() with uclibc
AC_CHECK_DECL(__UCLIBC__,
[
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.
@ -104,16 +107,16 @@ AC_ARG_ENABLE(zlib,
[
if test "x$enableval" = "xno"; then
AC_DEFINE(DISABLE_ZLIB,, Use zlib)
AC_MSG_RESULT(Disabling zlib)
AC_MSG_NOTICE(Disabling zlib)
else
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
],
[
# if not disabled, check for zlib
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
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
AC_DEFINE(DISABLE_PAM,, Use PAM)
AC_MSG_RESULT(Disabling PAM)
AC_MSG_NOTICE(Disabling PAM)
fi
],
[
# disable it by default
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],
[
if test "x$enableval" = "xno"; then
AC_MSG_RESULT(Not using openpty)
AC_MSG_NOTICE(Not using openpty)
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)])
fi
],
[
AC_MSG_RESULT(Using openpty if available)
AC_MSG_NOTICE(Using openpty if available)
AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY)])
]
)
@ -176,13 +179,13 @@ AC_ARG_ENABLE(syslog,
[
if test "x$enableval" = "xno"; then
AC_DEFINE(DISABLE_SYSLOG,, Using syslog)
AC_MSG_RESULT(Disabling syslog)
AC_MSG_NOTICE(Disabling syslog)
else
AC_MSG_RESULT(Enabling syslog)
AC_MSG_NOTICE(Enabling syslog)
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)],
[
if test "x$enableval" = "xno"; then
AC_MSG_RESULT(Not using shadow passwords)
AC_MSG_NOTICE(Not using shadow passwords)
else
AC_CHECK_HEADERS([shadow.h])
AC_MSG_RESULT(Using shadow passwords if available)
AC_MSG_NOTICE(Using shadow passwords if available)
fi
],
[
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
])
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/socket.h>
#if HAVE_UTMPX_H
@ -347,6 +350,11 @@ AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_
#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(utmpname)
AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline )
@ -379,7 +387,7 @@ AC_ARG_ENABLE(wtmpx,
AC_ARG_ENABLE(loginfunc,
[ --disable-loginfunc Disable use of login() etc. [no]],
[ no_loginfunc_check=1
AC_MSG_RESULT(Not using login() etc) ]
AC_MSG_NOTICE(Not using login() etc) ]
)
AC_ARG_ENABLE(pututline,
[ --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
AC_CHECK_FILE("/dev/ptmx", AC_DEFINE(USE_DEV_PTMX,,Use /dev/ptmx))
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
@ -604,14 +612,57 @@ if test -z "$no_ptc_check" ; 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))
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
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_OUTPUT(Makefile)
AC_OUTPUT(libtomcrypt/Makefile)
AC_OUTPUT(libtommath/Makefile)
AC_MSG_RESULT()
AC_MSG_RESULT(Now edit options.h to choose features.)
AC_MSG_NOTICE()
AC_MSG_NOTICE(Now edit options.h to choose features.)

View File

@ -29,24 +29,23 @@ Read the identity from file
.I idfile
(multiple allowed).
.TP
.B \-L \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR
.B \-L \fIlistenport\fR:\fIhost\fR:\fIport\fR
Local port forwarding.
Forward the port
.I localport
on the local host to port
.I remoteport
on the remote host
.IR remotehost .
.I listenport
on the local host through the SSH connection to port
.I port
on the host
.IR host .
.TP
.B \-R \fIlocalport\fR:\fIremotehost\fR:\fIremoteport\fR
.B \-R \fIlistenport\fR:\fIhost\fR:\fIport\fR
Remote port forwarding.
Forward the port
.I remoteport
on the remote host
.I remotehost
to port
.I localport
on the local host.
.I listenport
on the remote host through the SSH connection to port
.I port
on the host
.IR host .
.TP
.B \-l \fIuser
Username.
@ -60,6 +59,13 @@ Allocate a pty.
.B \-T
Don't allocate a pty.
.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
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

View File

@ -400,7 +400,10 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
len = sizeof(struct sockaddr_storage);
/* 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) {
len = sizeof(struct sockaddr_in);
}
@ -408,6 +411,7 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
if (addr->ss_family == AF_INET6) {
len = sizeof(struct sockaddr_in6);
}
#endif
#endif
ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
@ -448,6 +452,7 @@ char* getaddrhostname(struct sockaddr_storage * addr) {
len = sizeof(struct sockaddr_storage);
/* Some platforms such as Solaris 8 require that len is the length
* of the specific structure. */
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
if (addr->ss_family == AF_INET) {
len = sizeof(struct sockaddr_in);
}
@ -456,6 +461,7 @@ char* getaddrhostname(struct sockaddr_storage * addr) {
len = sizeof(struct sockaddr_in6);
}
#endif
#endif
ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
@ -521,26 +527,36 @@ char * stripcontrol(const char * text) {
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int buf_readfile(buffer* buf, const char* filename) {
int fd;
int fd = -1;
int len;
int maxlen;
int ret = DROPBEAR_FAILURE;
fd = open(filename, O_RDONLY);
if (fd < 0) {
close(fd);
return DROPBEAR_FAILURE;
goto out;
}
do {
maxlen = buf->size - buf->pos;
len = read(fd, buf_getwriteptr(buf, maxlen),
maxlen);
len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
if (len < 0) {
if (errno == EINTR || errno == EAGAIN) {
continue;
}
goto out;
}
buf_incrwritepos(buf, len);
} while (len < maxlen && len > 0);
close(fd);
return DROPBEAR_SUCCESS;
ret = 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

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.
* 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.
* 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

View File

@ -39,3 +39,14 @@ by following these steps:
See the Dropbear homepage for more information:
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
@ -38,6 +38,14 @@ deb-checkuid:
@gzip -9 debian/$*/usr/share/doc/$*/changelog*
%.deb-docs-docs:
@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; \
done
@test ! -r debian/$*.README.Debian || \

View File

@ -44,8 +44,10 @@
/* All functions writing to the cleartext payload buffer call
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
* attempting to track down a problem */
#define CHECKCLEARTOWRITE() assert(ses.writepayload->len == 0 && \
ses.writepayload->pos == 0)
/*#define CHECKCLEARTOWRITE() assert(ses.writepayload->len == 0 && \
ses.writepayload->pos == 0)*/
#define CHECKCLEARTOWRITE()
/* 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.

View File

@ -72,6 +72,10 @@ Use this option to run
under TCP/IP servers like inetd, tcpsvd, or tcpserver.
In program mode the \-F option is implied, and \-p options are ignored.
.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
Allow remote hosts to connect to forwarded ports.
.SH AUTHOR

View File

@ -283,8 +283,10 @@ out:
buf_burn(buf);
buf_free(buf);
buf = NULL;
sign_key_free(key);
key = NULL;
if (key) {
sign_key_free(key);
key = NULL;
}
exit(err);
}
@ -297,6 +299,9 @@ static void printpubkey(sign_key * key, int keytype) {
const char * typestring = NULL;
char *fp = NULL;
int len;
struct passwd * pw = NULL;
char * username = NULL;
char hostname[100];
buf = buf_new(MAX_PUBKEY_SIZE);
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);
printf("Public key portion is:\n%s %s\nFingerprint: %s\n",
typestring, base64key, fp);
/* a user@host comment is informative */
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);
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 */
m_mp_init(&dss_protok);
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);
m_burn(proto_k, SHA512_HASH_SIZE);
#else /* DSS_PROTOK not defined*/

View File

@ -135,13 +135,6 @@ typedef u_int16_t uint16_t;
#define LOG_AUTHPRIV LOG_AUTH
#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) */
#ifdef UNUSED
#elif defined(__GNUC__)

View File

@ -361,7 +361,7 @@ struct openssh_key {
static struct openssh_key *load_openssh_key(const char *filename)
{
struct openssh_key *ret;
FILE *fp;
FILE *fp = NULL;
char buffer[256];
char *errmsg = NULL, *p = NULL;
int headers_done;
@ -482,6 +482,9 @@ static struct openssh_key *load_openssh_key(const char *filename)
memset(&ret, 0, sizeof(ret));
m_free(ret);
}
if (fp) {
fclose(fp);
}
if (errmsg) {
fprintf(stderr, "Error: %s\n", errmsg);
}
@ -926,40 +929,6 @@ static int openssh_write(const char *filename, sign_key *key,
if (passphrase) {
fprintf(stderr, "Encrypted keys aren't supported currently\n");
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;
}
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);
fputs(footer, fp);
fclose(fp);

View File

@ -158,7 +158,7 @@ default:library
#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
$(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.
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) {
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);
}

View File

@ -128,7 +128,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
* You can't enable both PASSWORD and PAM. */
#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_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 */
#define _PATH_SSH_PROGRAM "/usr/bin/dbclient"
/* Multi-purpose binary configuration has now moved. Look at the top
* of the Makefile for instructions, or INSTALL */
/* Whether to log commands executed by a client. This only logs the
* (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.
*******************************************************************/
#ifndef DROPBEAR_VERSION
#define DROPBEAR_VERSION "0.48"
#define DROPBEAR_VERSION "0.49"
#endif
#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,
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_CP "/bin/cp"
@ -300,7 +305,6 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
#define MAX_PROPOSED_ALGO 20
/* size/count limits */
#define MAX_LISTEN_ADDR 10
#define MAX_PACKET_LEN 35000
#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 */
/* 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_s used as a temp var*/
if (mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != MP_OKAY) {
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' */
/* 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_tmp3 is 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

View File

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

View File

@ -67,8 +67,7 @@ static void get_termmodes(struct ChanSess *chansess);
extern char** environ;
static int sesscheckclose(struct Channel *channel) {
struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
return chansess->exit.exitpid >= 0;
return channel->writefd == -1;
}
/* 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"))
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
exit = NULL;
/* find the corresponding chansess */
for (i = 0; i < svr_ses.childpidsize; i++) {
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 */
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);
return DROPBEAR_FAILURE;
return DROPBEAR_SUCCESS;
}
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) {
/* no pty */
ret = noptycommand(channel, chansess);

View File

@ -52,7 +52,9 @@ void recv_msg_kexdh_init() {
}
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);

View File

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

View File

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

View File

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