- Fix from Andre Lucas <andre.lucas@dial.pipex.com>

- Fixes command line printing segfaults (spotter: Bladt Norbert)
  - Fixes erroneous printing of debug messages to syslog
  - Fixes utmp for MacOS X (spotter: Aristedes Maniatis)
  - Gives useful error message if PRNG initialisation fails
  - Reduced ssh startup delay
  - Measures cumulative command time rather than the time between reads
	 after select()
  - 'fixprogs' perl script to eliminate non-working entropy commands, and
	 optionally run 'ent' to measure command entropy
This commit is contained in:
Damien Miller 2000-05-17 21:34:07 +10:00
parent 95fe91bd84
commit 8d1fd57a97
5 changed files with 83 additions and 26 deletions

View File

@ -1,3 +1,15 @@
20000517
- Fix from Andre Lucas <andre.lucas@dial.pipex.com>
- Fixes command line printing segfaults (spotter: Bladt Norbert)
- Fixes erroneous printing of debug messages to syslog
- Fixes utmp for MacOS X (spotter: Aristedes Maniatis)
- Gives useful error message if PRNG initialisation fails
- Reduced ssh startup delay
- Measures cumulative command time rather than the time between reads
after select()
- 'fixprogs' perl script to eliminate non-working entropy commands, and
optionally run 'ent' to measure command entropy
20000513 20000513
- Fix for non-recognised DSA keys from Arkadiusz Miskiewicz - Fix for non-recognised DSA keys from Arkadiusz Miskiewicz
<misiek@pld.org.pl> <misiek@pld.org.pl>

View File

@ -27,6 +27,7 @@ AR=@AR@
RANLIB=@RANLIB@ RANLIB=@RANLIB@
INSTALL=@INSTALL@ INSTALL=@INSTALL@
PERL=@PERL@ PERL=@PERL@
ENT=@ENT@
LDFLAGS=-L. @LDFLAGS@ LDFLAGS=-L. @LDFLAGS@
INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
@ -136,7 +137,8 @@ install: manpages $(TARGETS)
$(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \
fi fi
if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \
$(INSTALL) -m 644 ssh_prng_cmds $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ $(PERL) fixprogs ssh_prng_cmds $(ENT); \
$(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \
fi fi
host-key: ssh-keygen host-key: ssh-keygen

View File

@ -11,6 +11,8 @@ AC_PROG_INSTALL
AC_CHECK_PROG(AR, ar, ar) AC_CHECK_PROG(AR, ar, ar)
AC_PATH_PROG(PERL, perl) AC_PATH_PROG(PERL, perl)
AC_SUBST(PERL) AC_SUBST(PERL)
AC_PATH_PROG(ENT, ent)
AC_SUBST(ENT)
if test -z "$LD" ; then if test -z "$LD" ; then
LD=$CC LD=$CC

View File

@ -35,7 +35,7 @@
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/sha.h> #include <openssl/sha.h>
RCSID("$Id: entropy.c,v 1.9 2000/05/11 09:10:58 damien Exp $"); RCSID("$Id: entropy.c,v 1.10 2000/05/17 11:34:08 damien Exp $");
#ifdef EGD_SOCKET #ifdef EGD_SOCKET
#ifndef offsetof #ifndef offsetof
@ -133,6 +133,8 @@ typedef struct
char *path; char *path;
/* argv to pass to executable */ /* argv to pass to executable */
char *args[5]; char *args[5];
/* full command string (debug) */
char *cmdstring;
} entropy_source_t; } entropy_source_t;
double stir_from_system(void); double stir_from_system(void);
@ -211,8 +213,8 @@ stir_from_programs(void)
/* FIXME: turn this off later */ /* FIXME: turn this off later */
#if 1 #if 1
debug("Got %0.2f bytes of entropy from %s", entropy_estimate, debug("Got %0.2f bytes of entropy from '%s'", entropy_estimate,
entropy_sources[c].path); entropy_sources[c].cmdstring);
#endif #endif
total_entropy_estimate += entropy_estimate; total_entropy_estimate += entropy_estimate;
@ -225,9 +227,8 @@ stir_from_programs(void)
} else { } else {
/* FIXME: turn this off later */ /* FIXME: turn this off later */
#if 1 #if 1
debug("Command '%s %s %s' disabled (badness %d)", debug("Command '%s' disabled (badness %d)",
entropy_sources[c].path, entropy_sources[c].args[1], entropy_sources[c].cmdstring, entropy_sources[c].badness);
entropy_sources[c].args[2], entropy_sources[c].badness);
#endif #endif
if (entropy_sources[c].badness > 0) if (entropy_sources[c].badness > 0)
@ -286,6 +287,17 @@ stir_rusage(int who, double entropy_estimate)
#endif /* _HAVE_GETRUSAGE */ #endif /* _HAVE_GETRUSAGE */
} }
static
int
_get_timeval_msec_difference(struct timeval *t1, struct timeval *t2) {
int secdiff, usecdiff;
secdiff = t2->tv_sec - t1->tv_sec;
usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec);
return (int)(usecdiff / 1000);
}
double double
hash_output_from_command(entropy_source_t *src, char *hash) hash_output_from_command(entropy_source_t *src, char *hash)
{ {
@ -293,9 +305,11 @@ hash_output_from_command(entropy_source_t *src, char *hash)
int p[2]; int p[2];
fd_set rdset; fd_set rdset;
int cmd_eof = 0, error_abort = 0; int cmd_eof = 0, error_abort = 0;
struct timeval tv_start, tv_current;
int msec_elapsed = 0;
pid_t pid; pid_t pid;
int status; int status;
char buf[2048]; char buf[16384];
int bytes_read; int bytes_read;
int total_bytes_read; int total_bytes_read;
SHA_CTX sha; SHA_CTX sha;
@ -309,6 +323,8 @@ hash_output_from_command(entropy_source_t *src, char *hash)
if (pipe(p) == -1) if (pipe(p) == -1)
fatal("Couldn't open pipe: %s", strerror(errno)); fatal("Couldn't open pipe: %s", strerror(errno));
(void)gettimeofday(&tv_start, NULL); /* record start time */
switch (pid = fork()) { switch (pid = fork()) {
case -1: /* Error */ case -1: /* Error */
close(p[0]); close(p[0]);
@ -324,8 +340,8 @@ hash_output_from_command(entropy_source_t *src, char *hash)
close(devnull); close(devnull);
execv(src->path, (char**)(src->args)); execv(src->path, (char**)(src->args));
debug("(child) Couldn't exec '%s %s %s': %s", src->path, debug("(child) Couldn't exec '%s': %s", src->cmdstring,
src->args[1], src->args[2], strerror(errno)); strerror(errno));
src->badness = src->sticky_badness = 128; src->badness = src->sticky_badness = 128;
_exit(-1); _exit(-1);
default: /* Parent */ default: /* Parent */
@ -343,13 +359,24 @@ hash_output_from_command(entropy_source_t *src, char *hash)
while (!error_abort && !cmd_eof) { while (!error_abort && !cmd_eof) {
int ret; int ret;
struct timeval tv; struct timeval tv;
int msec_remaining;
(void) gettimeofday(&tv_current, 0);
msec_elapsed = _get_timeval_msec_difference(
&tv_start, &tv_current);
if (msec_elapsed >= entropy_timeout_current) {
error_abort=1;
continue;
}
msec_remaining = entropy_timeout_current - msec_elapsed;
FD_ZERO(&rdset); FD_ZERO(&rdset);
FD_SET(p[0], &rdset); FD_SET(p[0], &rdset);
tv.tv_sec = entropy_timeout_current / 1000; tv.tv_sec = msec_remaining / 1000;
tv.tv_usec = (entropy_timeout_current % 1000) * 1000; tv.tv_usec = (msec_remaining % 1000) * 1000;
ret = select(p[0]+1, &rdset, NULL, NULL, &tv); ret = select(p[0]+1, &rdset, NULL, NULL, &tv);
switch (ret) { switch (ret) {
case 0: case 0:
/* timer expired */ /* timer expired */
@ -363,17 +390,19 @@ hash_output_from_command(entropy_source_t *src, char *hash)
error_abort = 1; error_abort = 1;
break; break;
} }
SHA1_Update(&sha, buf, bytes_read); if (bytes_read) {
total_bytes_read += bytes_read; SHA1_Update(&sha, buf, bytes_read);
RAND_add(&bytes_read, sizeof(&bytes_read), 0.0); total_bytes_read += bytes_read;
cmd_eof = bytes_read ? 0 : 1; RAND_add(&bytes_read, sizeof(&bytes_read), 0.0);
} else
cmd_eof = 1;
break; break;
case -1: case -1:
default: default:
error("Command '%s %s': select() failed: %s", src->path, src->args[1], debug("Command '%s': select() failed: %s", src->cmdstring,
strerror(errno)); strerror(errno));
error_abort = 1; error_abort = 1;
break; break;
} /* switch ret */ } /* switch ret */
@ -385,10 +414,11 @@ hash_output_from_command(entropy_source_t *src, char *hash)
close(p[0]); close(p[0]);
debug("Time elapsed: %d msec", msec_elapsed);
if (waitpid(pid, &status, 0) == -1) { if (waitpid(pid, &status, 0) == -1) {
error("Couldn't wait for child '%s %s' completion: %s", src->path, debug("Couldn't wait for child '%s' completion: %s", src->cmdstring,
src->args[1], strerror(errno)); strerror(errno));
/* return(-1); */ /* FIXME: (ATL) this doesn't feel right */
return(0.0); return(0.0);
} }
@ -398,7 +428,7 @@ hash_output_from_command(entropy_source_t *src, char *hash)
/* closing p[0] on timeout causes the entropy command to /* closing p[0] on timeout causes the entropy command to
* SIGPIPE. Take whatever output we got, and mark this command * SIGPIPE. Take whatever output we got, and mark this command
* as slow */ * as slow */
debug("Command %s %s timed out", src->path, src->args[1]); debug("Command '%s' timed out", src->cmdstring);
src->sticky_badness *= 2; src->sticky_badness *= 2;
src->badness = src->sticky_badness; src->badness = src->sticky_badness;
return(total_bytes_read); return(total_bytes_read);
@ -615,6 +645,10 @@ prng_read_commands(char *cmdfilename)
continue; continue;
} }
/* save the command for debug messages */
entcmd[cur_cmd].cmdstring = (char*) xmalloc(strlen(cmd)+1);
strncpy(entcmd[cur_cmd].cmdstring, cmd, strlen(cmd)+1);
/* split the command args */ /* split the command args */
cp = strtok(cmd, WHITESPACE); cp = strtok(cmd, WHITESPACE);
arg = 0; argv = NULL; arg = 0; argv = NULL;
@ -713,6 +747,9 @@ seed_rng(void)
debug("%i bytes from programs", (int)stir_from_programs()); debug("%i bytes from programs", (int)stir_from_programs());
debug("OpenSSL random status is now %i\n", RAND_status()); debug("OpenSSL random status is now %i\n", RAND_status());
if (!RAND_status())
fatal("Couldn't initialise builtin random number generator -- exiting.");
if (!prng_seed_loaded) if (!prng_seed_loaded)
{ {
prng_seed_loaded = 1; prng_seed_loaded = 1;

12
login.c
View File

@ -18,7 +18,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$Id: login.c,v 1.25 2000/05/01 12:53:53 damien Exp $"); RCSID("$Id: login.c,v 1.26 2000/05/17 11:34:08 damien Exp $");
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
# include <utmpx.h> # include <utmpx.h>
@ -87,6 +87,7 @@ get_last_login_time(uid_t uid, const char *logname,
return ll.ll_time; return ll.ll_time;
#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ #else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
# ifdef HAVE_TYPE_IN_UTMP
/* Look in wtmp for the last login */ /* Look in wtmp for the last login */
struct utmp wt; struct utmp wt;
char *wt_file = _PATH_WTMP; char *wt_file = _PATH_WTMP;
@ -111,14 +112,14 @@ get_last_login_time(uid_t uid, const char *logname,
if ( wt.ut_type == USER_PROCESS) { if ( wt.ut_type == USER_PROCESS) {
if ( !strncmp(logname, wt.ut_user, 8) ) { if ( !strncmp(logname, wt.ut_user, 8) ) {
t = (unsigned long) wt.ut_time; t = (unsigned long) wt.ut_time;
#ifdef HAVE_HOST_IN_UTMP # ifdef HAVE_HOST_IN_UTMP
if (bufsize > sizeof(wt.ut_host) + 1) if (bufsize > sizeof(wt.ut_host) + 1)
bufsize = sizeof(wt.ut_host) + 1; bufsize = sizeof(wt.ut_host) + 1;
strncpy(buf, wt.ut_host, bufsize - 1); strncpy(buf, wt.ut_host, bufsize - 1);
buf[bufsize - 1] = 0; buf[bufsize - 1] = 0;
#else /* HAVE_HOST_IN_UTMP */ # else /* HAVE_HOST_IN_UTMP */
buf[0] = 0; buf[0] = 0;
#endif /* HAVE_HOST_IN_UTMP */ # endif /* HAVE_HOST_IN_UTMP */
} }
} }
@ -127,6 +128,9 @@ get_last_login_time(uid_t uid, const char *logname,
} while (t == 0); } while (t == 0);
return t; return t;
# else
return 0;
# endif /* HAVE_TYPE_IN_UTMP */
#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
} }