mirror of
https://github.com/clearml/dropbear
synced 2025-06-14 18:28:31 +00:00
merge of 4cbdd6e0a0d8c061075b9ed7609a06c4547f67d3
and 5d396842815593611f0d61762440145d1fc74d5a --HG-- extra : convert_revision : 4c883eb469d2d251ee8abddbc11ae4005db6da17
This commit is contained in:
commit
e4697de175
1
auth.h
1
auth.h
@ -52,6 +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();
|
||||||
|
|
||||||
|
|
||||||
#define MAX_USERNAME_LEN 25 /* arbitrary for the moment */
|
#define MAX_USERNAME_LEN 25 /* arbitrary for the moment */
|
||||||
|
15
cli-auth.c
15
cli-auth.c
@ -278,3 +278,18 @@ void cli_auth_try() {
|
|||||||
|
|
||||||
TRACE(("leave cli_auth_try"))
|
TRACE(("leave 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* password = NULL;
|
||||||
|
|
||||||
|
password = getpass("Password: ");
|
||||||
|
|
||||||
|
/* 0x03 is a ctrl-c character in the buffer. */
|
||||||
|
if (password == NULL || strchr(password, '\3') != NULL) {
|
||||||
|
dropbear_close("Interrupted.");
|
||||||
|
}
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
@ -115,7 +115,7 @@ void recv_msg_userauth_info_request() {
|
|||||||
echo = buf_getbool(ses.payload);
|
echo = buf_getbool(ses.payload);
|
||||||
|
|
||||||
if (!echo) {
|
if (!echo) {
|
||||||
unsigned char* p = getpass(prompt);
|
unsigned char* p = getpass_or_cancel(prompt);
|
||||||
response = m_strdup(p);
|
response = m_strdup(p);
|
||||||
m_burn(p, strlen(p));
|
m_burn(p, strlen(p));
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,10 +125,7 @@ void cli_auth_password() {
|
|||||||
password = gui_getpass("Password: ");
|
password = gui_getpass("Password: ");
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
password = getpass("Password: ");
|
password = getpass_or_cancel("Password: ");
|
||||||
|
|
||||||
if (password == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
|
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
|
||||||
|
|
||||||
|
@ -76,12 +76,14 @@ static const struct ChanType *cli_chantypes[] = {
|
|||||||
|
|
||||||
void cli_session(int sock, char* remotehost) {
|
void cli_session(int sock, char* remotehost) {
|
||||||
|
|
||||||
|
seedrandom();
|
||||||
|
|
||||||
crypto_init();
|
crypto_init();
|
||||||
|
|
||||||
common_session_init(sock, remotehost);
|
common_session_init(sock, remotehost);
|
||||||
|
|
||||||
chaninitialise(cli_chantypes);
|
chaninitialise(cli_chantypes);
|
||||||
|
|
||||||
|
|
||||||
/* Set up cli_ses vars */
|
/* Set up cli_ses vars */
|
||||||
cli_session_init();
|
cli_session_init();
|
||||||
|
|
||||||
@ -91,12 +93,8 @@ void cli_session(int sock, char* remotehost) {
|
|||||||
/* Exchange identification */
|
/* Exchange identification */
|
||||||
session_identification();
|
session_identification();
|
||||||
|
|
||||||
seedrandom();
|
|
||||||
|
|
||||||
send_msg_kexinit();
|
send_msg_kexinit();
|
||||||
|
|
||||||
/* XXX here we do stuff differently */
|
|
||||||
|
|
||||||
session_loop(cli_sessionloop);
|
session_loop(cli_sessionloop);
|
||||||
|
|
||||||
/* Not reached */
|
/* Not reached */
|
||||||
|
@ -376,7 +376,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
|
|||||||
cbuf_incrread(cbuf, len);
|
cbuf_incrread(cbuf, len);
|
||||||
channel->recvdonelen += len;
|
channel->recvdonelen += len;
|
||||||
|
|
||||||
if (fd == channel->writefd && len == maxlen && channel->recveof) {
|
if (fd == channel->writefd && cbuf_getused(cbuf) == 0 && channel->recveof) {
|
||||||
/* Check if we're closing up */
|
/* Check if we're closing up */
|
||||||
closewritefd(channel);
|
closewritefd(channel);
|
||||||
TRACE(("leave writechannel: recveof set"))
|
TRACE(("leave writechannel: recveof set"))
|
||||||
|
@ -232,10 +232,8 @@ void session_identification() {
|
|||||||
dropbear_exit("Error writing ident string");
|
dropbear_exit("Error writing ident string");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We allow up to 9 lines before the actual version string, to
|
/* If they send more than 50 lines, something is wrong */
|
||||||
* account for wrappers/cruft etc. According to the spec only the client
|
for (i = 0; i < 50; i++) {
|
||||||
* needs to handle this, but no harm in letting the server handle it too */
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
len = ident_readln(ses.sock, linebuf, sizeof(linebuf));
|
len = ident_readln(ses.sock, linebuf, sizeof(linebuf));
|
||||||
|
|
||||||
if (len < 0 && errno != EINTR) {
|
if (len < 0 && errno != EINTR) {
|
||||||
@ -259,6 +257,12 @@ void session_identification() {
|
|||||||
memcpy(ses.remoteident, linebuf, len);
|
memcpy(ses.remoteident, linebuf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shall assume that 2.x will be backwards compatible. */
|
||||||
|
if (strncmp(ses.remoteident, "SSH-2.", 6) != 0
|
||||||
|
&& strncmp(ses.remoteident, "SSH-1.99-", 9) != 0) {
|
||||||
|
dropbear_exit("Incompatible remote version '%s'", ses.remoteident);
|
||||||
|
}
|
||||||
|
|
||||||
TRACE(("remoteident: %s", ses.remoteident))
|
TRACE(("remoteident: %s", ses.remoteident))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
31
random.c
31
random.c
@ -30,8 +30,8 @@
|
|||||||
static int donerandinit = 0;
|
static int donerandinit = 0;
|
||||||
|
|
||||||
/* this is used to generate unique output from the same hashpool */
|
/* this is used to generate unique output from the same hashpool */
|
||||||
static unsigned int counter = 0;
|
static uint32_t counter = 0;
|
||||||
#define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */
|
#define MAX_COUNTER 1<<31 /* the max value for the counter, so it won't loop */
|
||||||
|
|
||||||
static unsigned char hashpool[SHA1_HASH_SIZE];
|
static unsigned char hashpool[SHA1_HASH_SIZE];
|
||||||
|
|
||||||
@ -132,7 +132,8 @@ void seedrandom() {
|
|||||||
|
|
||||||
hash_state hs;
|
hash_state hs;
|
||||||
|
|
||||||
/* initialise so compilers will be happy about hashing it */
|
/* initialise so that things won't warn about
|
||||||
|
* hashing an undefined buffer */
|
||||||
if (!donerandinit) {
|
if (!donerandinit) {
|
||||||
m_burn(hashpool, sizeof(hashpool));
|
m_burn(hashpool, sizeof(hashpool));
|
||||||
}
|
}
|
||||||
@ -150,6 +151,30 @@ void seedrandom() {
|
|||||||
donerandinit = 1;
|
donerandinit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* hash the current random pool with some unique identifiers
|
||||||
|
* for this process and point-in-time. this is used to separate
|
||||||
|
* the random pools for fork()ed processes. */
|
||||||
|
void reseedrandom() {
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
if (!donerandinit) {
|
||||||
|
dropbear_exit("seedrandom not done");
|
||||||
|
}
|
||||||
|
|
||||||
|
pid = getpid();
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
hash_state hs;
|
||||||
|
unsigned char hash[SHA1_HASH_SIZE];
|
||||||
|
sha1_init(&hs);
|
||||||
|
sha1_process(&hs, (void*)hashpool, sizeof(hashpool));
|
||||||
|
sha1_process(&hs, (void*)&pid, sizeof(pid));
|
||||||
|
sha1_process(&hs, (void*)&tv, sizeof(tv));
|
||||||
|
sha1_done(&hs, hashpool);
|
||||||
|
}
|
||||||
|
|
||||||
/* return len bytes of pseudo-random data */
|
/* return len bytes of pseudo-random data */
|
||||||
void genrandom(unsigned char* buf, unsigned int len) {
|
void genrandom(unsigned char* buf, unsigned int len) {
|
||||||
|
|
||||||
|
1
random.h
1
random.h
@ -28,6 +28,7 @@
|
|||||||
struct mp_int;
|
struct mp_int;
|
||||||
|
|
||||||
void seedrandom();
|
void seedrandom();
|
||||||
|
void reseedrandom();
|
||||||
void genrandom(unsigned char* buf, int len);
|
void genrandom(unsigned char* buf, int len);
|
||||||
void addrandom(unsigned char* buf, int len);
|
void addrandom(unsigned char* buf, int len);
|
||||||
void gen_random_mpint(mp_int *max, mp_int *rand);
|
void gen_random_mpint(mp_int *max, mp_int *rand);
|
||||||
|
32
scp.c
32
scp.c
@ -166,8 +166,22 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
close(reserved[0]);
|
close(reserved[0]);
|
||||||
close(reserved[1]);
|
close(reserved[1]);
|
||||||
|
|
||||||
|
// uClinux needs to build the args here before vforking,
|
||||||
|
// otherwise we do it later on.
|
||||||
|
#ifdef __uClinux__
|
||||||
|
args.list[0] = ssh_program;
|
||||||
|
if (remuser != NULL)
|
||||||
|
addargs(&args, "-l%s", remuser);
|
||||||
|
addargs(&args, "%s", host);
|
||||||
|
addargs(&args, "%s", cmd);
|
||||||
|
#endif /* __uClinux__ */
|
||||||
|
|
||||||
/* Fork a child to execute the command on the remote host using ssh. */
|
/* Fork a child to execute the command on the remote host using ssh. */
|
||||||
|
#ifdef __uClinux__
|
||||||
|
do_cmd_pid = vfork();
|
||||||
|
#else
|
||||||
do_cmd_pid = fork();
|
do_cmd_pid = fork();
|
||||||
|
#endif /* __uClinux__ */
|
||||||
if (do_cmd_pid == 0) {
|
if (do_cmd_pid == 0) {
|
||||||
/* Child. */
|
/* Child. */
|
||||||
close(pin[1]);
|
close(pin[1]);
|
||||||
@ -177,6 +191,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
close(pin[0]);
|
close(pin[0]);
|
||||||
close(pout[1]);
|
close(pout[1]);
|
||||||
|
|
||||||
|
#ifndef __uClinux__
|
||||||
args.list[0] = ssh_program;
|
args.list[0] = ssh_program;
|
||||||
if (remuser != NULL) {
|
if (remuser != NULL) {
|
||||||
addargs(&args, "-l");
|
addargs(&args, "-l");
|
||||||
@ -184,6 +199,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
}
|
}
|
||||||
addargs(&args, "%s", host);
|
addargs(&args, "%s", host);
|
||||||
addargs(&args, "%s", cmd);
|
addargs(&args, "%s", cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
execvp(ssh_program, args.list);
|
execvp(ssh_program, args.list);
|
||||||
perror(ssh_program);
|
perror(ssh_program);
|
||||||
@ -192,6 +208,22 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
|||||||
fprintf(stderr, "Fatal error: fork: %s\n", strerror(errno));
|
fprintf(stderr, "Fatal error: fork: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __uClinux__
|
||||||
|
/* clean up command */
|
||||||
|
/* pop cmd */
|
||||||
|
free(args->list[--args->num]);
|
||||||
|
args->list[args->num]=NULL;
|
||||||
|
/* pop host */
|
||||||
|
free(args->list[--args->num-1]);
|
||||||
|
args->list[args->num]=NULL;
|
||||||
|
/* pop user */
|
||||||
|
if (remuser != NULL) {
|
||||||
|
free(args->list[--args->num-1]);
|
||||||
|
args->list[args->num]=NULL;
|
||||||
|
}
|
||||||
|
#endif /* __uClinux__
|
||||||
|
|
||||||
/* Parent. Close the other side, and return the local side. */
|
/* Parent. Close the other side, and return the local side. */
|
||||||
close(pin[0]);
|
close(pin[0]);
|
||||||
*fdout = pin[1];
|
*fdout = pin[1];
|
||||||
|
@ -623,7 +623,12 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) {
|
|||||||
if (pipe(errfds) != 0)
|
if (pipe(errfds) != 0)
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
|
|
||||||
|
#ifdef __uClinux__
|
||||||
|
pid = vfork();
|
||||||
|
#else
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
|
|
||||||
@ -714,7 +719,11 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
|
|||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __uClinux__
|
||||||
|
pid = vfork();
|
||||||
|
#else
|
||||||
pid = fork();
|
pid = fork();
|
||||||
|
#endif
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
|
|
||||||
@ -828,12 +837,16 @@ static void execchild(struct ChanSess *chansess) {
|
|||||||
char * baseshell = NULL;
|
char * baseshell = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
/* with uClinux we'll have vfork()ed, so don't want to overwrite the
|
||||||
|
* hostkey. can't think of a workaround to clear it */
|
||||||
|
#ifndef __uClinux__
|
||||||
/* wipe the hostkey */
|
/* wipe the hostkey */
|
||||||
sign_key_free(svr_opts.hostkey);
|
sign_key_free(svr_opts.hostkey);
|
||||||
svr_opts.hostkey = NULL;
|
svr_opts.hostkey = NULL;
|
||||||
|
|
||||||
/* overwrite the prng state */
|
/* overwrite the prng state */
|
||||||
seedrandom();
|
reseedrandom();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* close file descriptors except stdin/stdout/stderr
|
/* close file descriptors except stdin/stdout/stderr
|
||||||
* Need to be sure FDs are closed here to avoid reading files as root */
|
* Need to be sure FDs are closed here to avoid reading files as root */
|
||||||
|
@ -83,7 +83,7 @@ static void main_inetd() {
|
|||||||
int remoteaddrlen;
|
int remoteaddrlen;
|
||||||
char * addrstring = NULL;
|
char * addrstring = NULL;
|
||||||
|
|
||||||
/* Set up handlers, syslog */
|
/* Set up handlers, syslog, seed random */
|
||||||
commonsetup();
|
commonsetup();
|
||||||
|
|
||||||
remoteaddrlen = sizeof(remoteaddr);
|
remoteaddrlen = sizeof(remoteaddr);
|
||||||
@ -359,6 +359,8 @@ static void commonsetup() {
|
|||||||
/* Now we can setup the hostkeys - needs to be after logging is on,
|
/* Now we can setup the hostkeys - needs to be after logging is on,
|
||||||
* otherwise we might end up blatting error messages to the socket */
|
* otherwise we might end up blatting error messages to the socket */
|
||||||
loadhostkeys();
|
loadhostkeys();
|
||||||
|
|
||||||
|
seedrandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up listening sockets for all the requested ports */
|
/* Set up listening sockets for all the requested ports */
|
||||||
|
@ -105,8 +105,12 @@ 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;
|
||||||
|
#ifdef ENABLE_SVR_LOCALTCPFWD
|
||||||
svr_opts.nolocaltcp = 0;
|
svr_opts.nolocaltcp = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_SVR_REMOTETCPFWD
|
||||||
svr_opts.noremotetcp = 0;
|
svr_opts.noremotetcp = 0;
|
||||||
|
#endif
|
||||||
/* not yet
|
/* not yet
|
||||||
opts.ipv4 = 1;
|
opts.ipv4 = 1;
|
||||||
opts.ipv6 = 1;
|
opts.ipv6 = 1;
|
||||||
@ -154,12 +158,12 @@ void svr_getopts(int argc, char ** argv) {
|
|||||||
svr_opts.usingsyslog = 0;
|
svr_opts.usingsyslog = 0;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_LOCALTCPFWD
|
#ifdef ENABLE_SVR_LOCALTCPFWD
|
||||||
case 'j':
|
case 'j':
|
||||||
svr_opts.nolocaltcp = 1;
|
svr_opts.nolocaltcp = 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef DISABLE_REMOTETCPFWD
|
#ifdef ENABLE_SVR_REMOTETCPFWD
|
||||||
case 'k':
|
case 'k':
|
||||||
svr_opts.noremotetcp = 1;
|
svr_opts.noremotetcp = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -79,6 +79,8 @@ void svr_session(int sock, int childpipe,
|
|||||||
|
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
|
reseedrandom();
|
||||||
|
|
||||||
crypto_init();
|
crypto_init();
|
||||||
common_session_init(sock, remotehost);
|
common_session_init(sock, remotehost);
|
||||||
|
|
||||||
@ -110,8 +112,6 @@ void svr_session(int sock, int childpipe,
|
|||||||
/* exchange identification, version etc */
|
/* exchange identification, version etc */
|
||||||
session_identification();
|
session_identification();
|
||||||
|
|
||||||
seedrandom();
|
|
||||||
|
|
||||||
/* start off with key exchange */
|
/* start off with key exchange */
|
||||||
send_msg_kexinit();
|
send_msg_kexinit();
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void recv_msg_global_request_remotetcp() {
|
|||||||
reqname = buf_getstring(ses.payload, &namelen);
|
reqname = buf_getstring(ses.payload, &namelen);
|
||||||
wantreply = buf_getbool(ses.payload);
|
wantreply = buf_getbool(ses.payload);
|
||||||
|
|
||||||
if (namelen > MAXNAMLEN) {
|
if (namelen > MAX_NAME_LEN) {
|
||||||
TRACE(("name len is wrong: %d", namelen))
|
TRACE(("name len is wrong: %d", namelen))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user