mirror of
https://github.com/clearml/dropbear
synced 2025-04-10 15:35:41 +00:00
merge of '182c2d8dbd5321ef4d1df8758936f4dc7127015f'
and '31dcd7a22983ef19d6c63248e415e71d292dd0ec' --HG-- extra : convert_revision : e84f66826c7ee6ebe99ef92cc0f6c22ecf638d01
This commit is contained in:
commit
d5897b9a5d
19
CHANGES
19
CHANGES
@ -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
|
||||
|
12
Makefile.in
12
Makefile.in
@ -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
2
auth.h
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -112,6 +112,7 @@ void recv_msg_userauth_pk_ok() {
|
||||
/* Success */
|
||||
break;
|
||||
}
|
||||
buf_free(keybuf);
|
||||
|
||||
if (keyitem != NULL) {
|
||||
TRACE(("matching key"))
|
||||
|
68
cli-kex.c
68
cli-kex.c
@ -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 */
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -82,6 +82,4 @@ void recv_msg_service_accept() {
|
||||
}
|
||||
|
||||
dropbear_exit("unrecognised service accept");
|
||||
/* m_free(servicename); not reached */
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
20
common-kex.c
20
common-kex.c
@ -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] */
|
||||
|
@ -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);
|
||||
|
97
configure.in
97
configure.in
@ -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.)
|
||||
|
32
dbclient.1
32
dbclient.1
@ -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
|
||||
|
32
dbutil.c
32
dbutil.c
@ -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
34
debian/changelog
vendored
@ -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
|
||||
|
||||
|
11
debian/dropbear.README.Debian
vendored
11
debian/dropbear.README.Debian
vendored
@ -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
10
debian/implicit
vendored
@ -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 || \
|
||||
|
6
debug.h
6
debug.h
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
4
dss.c
@ -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*/
|
||||
|
@ -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__)
|
||||
|
45
keyimport.c
45
keyimport.c
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
14
options.h
14
options.h
@ -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
21
rsa.c
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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':
|
||||
|
@ -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"))
|
||||
|
Loading…
Reference in New Issue
Block a user