diff options
-rw-r--r-- | cli-session.c | 8 | ||||
-rw-r--r-- | random.c | 31 | ||||
-rw-r--r-- | random.h | 1 | ||||
-rw-r--r-- | svr-chansession.c | 2 | ||||
-rw-r--r-- | svr-main.c | 4 | ||||
-rw-r--r-- | svr-session.c | 6 |
6 files changed, 39 insertions, 13 deletions
diff --git a/cli-session.c b/cli-session.c index 0e906e6..35510fa 100644 --- a/cli-session.c +++ b/cli-session.c @@ -76,12 +76,14 @@ static const struct ChanType *cli_chantypes[] = { void cli_session(int sock, char* remotehost) { + seedrandom(); + crypto_init(); + common_session_init(sock, remotehost); chaninitialise(cli_chantypes); - /* Set up cli_ses vars */ cli_session_init(); @@ -91,12 +93,8 @@ void cli_session(int sock, char* remotehost) { /* Exchange identification */ session_identification(); - seedrandom(); - send_msg_kexinit(); - /* XXX here we do stuff differently */ - session_loop(cli_sessionloop); /* Not reached */ @@ -30,8 +30,8 @@ static int donerandinit = 0; /* this is used to generate unique output from the same hashpool */ -static unsigned int counter = 0; -#define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */ +static uint32_t counter = 0; +#define MAX_COUNTER 1<<31 /* the max value for the counter, so it won't loop */ static unsigned char hashpool[SHA1_HASH_SIZE]; @@ -132,7 +132,8 @@ void seedrandom() { 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) { m_burn(hashpool, sizeof(hashpool)); } @@ -150,6 +151,30 @@ void seedrandom() { 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 */ void genrandom(unsigned char* buf, unsigned int len) { @@ -28,6 +28,7 @@ struct mp_int; void seedrandom(); +void reseedrandom(); void genrandom(unsigned char* buf, int len); void addrandom(unsigned char* buf, int len); void gen_random_mpint(mp_int *max, mp_int *rand); diff --git a/svr-chansession.c b/svr-chansession.c index 03ac40a..a645f69 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -833,7 +833,7 @@ static void execchild(struct ChanSess *chansess) { svr_opts.hostkey = NULL; /* overwrite the prng state */ - seedrandom(); + reseedrandom(); /* close file descriptors except stdin/stdout/stderr * Need to be sure FDs are closed here to avoid reading files as root */ @@ -83,7 +83,7 @@ static void main_inetd() { int remoteaddrlen; char * addrstring = NULL; - /* Set up handlers, syslog */ + /* Set up handlers, syslog, seed random */ commonsetup(); remoteaddrlen = sizeof(remoteaddr); @@ -359,6 +359,8 @@ static void commonsetup() { /* Now we can setup the hostkeys - needs to be after logging is on, * otherwise we might end up blatting error messages to the socket */ loadhostkeys(); + + seedrandom(); } /* Set up listening sockets for all the requested ports */ diff --git a/svr-session.c b/svr-session.c index 408209d..70029f8 100644 --- a/svr-session.c +++ b/svr-session.c @@ -78,7 +78,9 @@ void svr_session(int sock, int childpipe, char* remotehost, char *addrstring) { struct timeval timeout; - + + reseedrandom(); + crypto_init(); common_session_init(sock, remotehost); @@ -110,8 +112,6 @@ void svr_session(int sock, int childpipe, /* exchange identification, version etc */ session_identification(); - seedrandom(); - /* start off with key exchange */ send_msg_kexinit(); |