This commit is contained in:
Matt Johnston 2020-05-28 22:52:01 +08:00
commit dc12be0cfe
5 changed files with 106 additions and 59 deletions

View File

@ -184,7 +184,7 @@ static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype,
/* Returns 1 if a key was tried */
int cli_auth_pubkey() {
enum signature_type sigtype;
enum signature_type sigtype = DROPBEAR_SIGNATURE_NONE;
TRACE(("enter cli_auth_pubkey"))
#if DROPBEAR_CLI_AGENTFWD

View File

@ -131,6 +131,12 @@ static void cli_dropbear_log(int priority,
const char* format, va_list param) {
char printbuf[1024];
const char *name;
name = cli_opts.progname;
if (!name) {
name = "dbclient";
}
vsnprintf(printbuf, sizeof(printbuf), format, param);
@ -140,7 +146,7 @@ static void cli_dropbear_log(int priority,
}
#endif
fprintf(stderr, "%s: %s\n", cli_opts.progname, printbuf);
fprintf(stderr, "%s: %s\n", name, printbuf);
fflush(stderr);
}

View File

@ -370,7 +370,8 @@ AC_CHECK_HEADERS([netinet/in.h netinet/tcp.h \
crypt.h \
pty.h libutil.h libgen.h inttypes.h stropts.h utmp.h \
utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h \
pam/pam_appl.h netinet/in_systm.h sys/uio.h linux/pkt_sched.h])
pam/pam_appl.h netinet/in_systm.h sys/uio.h linux/pkt_sched.h \
sys/random.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@ -526,7 +527,7 @@ AC_CHECK_FUNCS(clock_gettime)
AC_CHECK_HEADERS([mach/mach_time.h])
AC_CHECK_FUNCS(mach_absolute_time)
AC_CHECK_FUNCS(explicit_bzero memset_s)
AC_CHECK_FUNCS(explicit_bzero memset_s getrandom)
AC_ARG_ENABLE(bundled-libtom,
[ --enable-bundled-libtom Force using bundled libtomcrypt/libtommath even if a system version exists.

View File

@ -49,24 +49,19 @@ static int donerandinit = 0;
*
*/
/* Pass len=0 to hash an entire file */
/* Pass wantlen=0 to hash an entire file */
static int
process_file(hash_state *hs, const char *filename,
unsigned int len, int prngd)
{
static int already_blocked = 0;
unsigned int wantlen, int prngd) {
int readfd;
unsigned int readcount;
int ret = DROPBEAR_FAILURE;
if (prngd) {
#if DROPBEAR_USE_PRNGD
if (prngd)
{
readfd = connect_unix(filename);
}
else
#endif
{
} else {
readfd = open(filename, O_RDONLY);
}
@ -75,58 +70,31 @@ process_file(hash_state *hs, const char *filename,
}
readcount = 0;
while (len == 0 || readcount < len)
{
while (wantlen == 0 || readcount < wantlen) {
int readlen, wantread;
unsigned char readbuf[4096];
if (!already_blocked && !prngd)
{
int res;
struct timeval timeout;
fd_set read_fds;
timeout.tv_sec = 2;
timeout.tv_usec = 0;
DROPBEAR_FD_ZERO(&read_fds);
FD_SET(readfd, &read_fds);
res = select(readfd + 1, &read_fds, NULL, NULL, &timeout);
if (res == 0)
{
dropbear_log(LOG_WARNING, "Warning: Reading the randomness source '%s' seems to have blocked.\nYou may need to find a better entropy source.", filename);
already_blocked = 1;
}
}
if (len == 0)
{
if (wantlen == 0) {
wantread = sizeof(readbuf);
}
else
{
wantread = MIN(sizeof(readbuf), len-readcount);
} else {
wantread = MIN(sizeof(readbuf), wantlen-readcount);
}
#if DROPBEAR_USE_PRNGD
if (prngd)
{
if (prngd) {
char egdcmd[2];
egdcmd[0] = 0x02; /* blocking read */
egdcmd[1] = (unsigned char)wantread;
if (write(readfd, egdcmd, 2) < 0)
{
if (write(readfd, egdcmd, 2) < 0) {
dropbear_exit("Can't send command to egd");
}
}
#endif
readlen = read(readfd, readbuf, wantread);
if (readlen <= 0) {
if (readlen < 0 && errno == EINTR) {
continue;
}
if (readlen == 0 && len == 0)
{
if (readlen == 0 && wantlen == 0) {
/* whole file was read as requested */
break;
}
@ -193,6 +161,63 @@ void fuzz_seed(void) {
}
#endif
#ifdef HAVE_GETRANDOM
/* Reads entropy seed with getrandom().
* May block if the kernel isn't ready.
* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
static int process_getrandom(hash_state *hs) {
char buf[INIT_SEED_SIZE];
ssize_t ret;
/* First try non-blocking so that we can warn about waiting */
ret = getrandom(buf, sizeof(buf), GRND_NONBLOCK);
if (ret == -1) {
if (errno == ENOSYS) {
/* Old kernel */
return DROPBEAR_FAILURE;
}
/* Other errors fall through to blocking getrandom() */
TRACE(("first getrandom() failed: %d %s", errno, strerror(errno)))
if (errno == EAGAIN) {
dropbear_log(LOG_WARNING, "Waiting for kernel randomness to be initialised...");
}
}
/* Wait blocking if needed. Loop in case we get EINTR */
while (ret != sizeof(buf)) {
ret = getrandom(buf, sizeof(buf), 0);
if (ret == sizeof(buf)) {
/* Success */
break;
}
if (ret == -1 && errno == EINTR) {
/* Try again. */
continue;
}
if (ret >= 0) {
TRACE(("Short read %zd from getrandom() shouldn't happen", ret))
/* Try again? */
continue;
}
/* Unexpected problem, fall back to /dev/urandom */
TRACE(("2nd getrandom() failed: %d %s", errno, strerror(errno)))
break;
}
if (ret == sizeof(buf)) {
/* Success, stir in the entropy */
sha1_process(hs, (void*)buf, sizeof(buf));
return DROPBEAR_SUCCESS;
}
return DROPBEAR_FAILURE;
}
#endif /* HAVE_GETRANDOM */
/* Initialise the prng from /dev/urandom or prngd. This function can
* be called multiple times */
void seedrandom() {
@ -202,6 +227,7 @@ void seedrandom() {
pid_t pid;
struct timeval tv;
clock_t clockval;
int urandom_seeded = 0;
#if DROPBEAR_FUZZ
if (fuzz.fuzzing) {
@ -215,11 +241,19 @@ void seedrandom() {
/* existing state */
sha1_process(&hs, (void*)hashpool, sizeof(hashpool));
#ifdef HAVE_GETRANDOM
if (process_getrandom(&hs) == DROPBEAR_SUCCESS) {
urandom_seeded = 1;
}
#endif
if (!urandom_seeded) {
#if DROPBEAR_USE_PRNGD
if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1)
!= DROPBEAR_SUCCESS) {
dropbear_exit("Failure reading random device %s",
DROPBEAR_PRNGD_SOCKET);
urandom_seeded = 1;
}
#else
/* non-blocking random source (probably /dev/urandom) */
@ -227,8 +261,10 @@ void seedrandom() {
!= DROPBEAR_SUCCESS) {
dropbear_exit("Failure reading random device %s",
DROPBEAR_URANDOM_DEV);
urandom_seeded = 1;
}
#endif
} /* urandom_seeded */
/* A few other sources to fall back on.
* Add more here for other platforms */

View File

@ -124,6 +124,10 @@
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_RANDOM_H
#include <sys/random.h>
#endif
#ifdef BUNDLED_LIBTOM
#include "libtomcrypt/src/headers/tomcrypt.h"
#include "libtommath/tommath.h"