mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* random.c: Automagically detect the entrop gatherer when
configure so. * rndegd.c (rndegd_connect_socket): New. Factored out from .. (rndegd_gather_random): here and call it. (do_read): Update the counter variables correctly. This was not a problem due to the way EGD works. Bug found by Christian Biere.
This commit is contained in:
parent
262a8719a4
commit
0073d6865d
@ -1,3 +1,12 @@
|
||||
2002-08-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* random.c: Automagically detect the entrop gatherer when
|
||||
configure so.
|
||||
* rndegd.c (rndegd_connect_socket): New. Factored out from ..
|
||||
(rndegd_gather_random): here and call it.
|
||||
(do_read): Update the counter variables correctly. This was not a
|
||||
problem due to the way EGD works. Bug found by Christian Biere.
|
||||
|
||||
2002-08-20 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* primegen.c (generate_elg_prime): Return all factors for mode 1.
|
||||
|
@ -32,7 +32,7 @@
|
||||
/* We have support for a DUMMY encryption cipher which comes handy to
|
||||
debug MDCs and similar things. Because this is a bit dangerous it
|
||||
is not enabled. */
|
||||
/*#define ALLOW_DUMMY 1 */
|
||||
#define ALLOW_DUMMY 1
|
||||
|
||||
#define MAX_BLOCKSIZE 16
|
||||
#define TABLE_SIZE 14
|
||||
|
@ -24,6 +24,7 @@ int rndunix_gather_random (void (*add)(const void*, size_t, int),
|
||||
int requester, size_t length, int level);
|
||||
int rndlinux_gather_random (void (*add)(const void*, size_t, int),
|
||||
int requester, size_t length, int level);
|
||||
int rndegd_connect_socket (int nofail);
|
||||
int rndegd_gather_random (void (*add)(const void*, size_t, int),
|
||||
int requester, size_t length, int level );
|
||||
int rndw32_gather_random (void (*add)(const void*, size_t, int),
|
||||
|
@ -129,20 +129,49 @@ static int (*
|
||||
getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
|
||||
size_t, int)
|
||||
{
|
||||
#ifdef USE_RNDLINUX
|
||||
#ifdef USE_ALL_RANDOM_MODULES
|
||||
static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int);
|
||||
|
||||
if (fnc)
|
||||
return fnc;
|
||||
# ifdef USE_RNDLINUX
|
||||
if ( !access (NAME_OF_DEV_RANDOM, R_OK)
|
||||
&& !access (NAME_OF_DEV_RANDOM, R_OK))
|
||||
{
|
||||
fnc = rndlinux_gather_random;
|
||||
return fnc;
|
||||
}
|
||||
# endif
|
||||
# ifdef USE_RNDEGD
|
||||
if ( rndegd_connect_socket (1) != -1 )
|
||||
{
|
||||
fnc = rndegd_gather_random;
|
||||
return fnc;
|
||||
}
|
||||
# endif
|
||||
# ifdef USE_RNDUNIX
|
||||
fnc = rndunix_gather_random;
|
||||
return fnc;
|
||||
# endif
|
||||
|
||||
log_fatal (_("no entropy gathering module detected\n"));
|
||||
|
||||
#else
|
||||
# ifdef USE_RNDLINUX
|
||||
return rndlinux_gather_random;
|
||||
#endif
|
||||
#ifdef USE_RNDUNIX
|
||||
# endif
|
||||
# ifdef USE_RNDUNIX
|
||||
return rndunix_gather_random;
|
||||
#endif
|
||||
#ifdef USE_RNDEGD
|
||||
# endif
|
||||
# ifdef USE_RNDEGD
|
||||
return rndegd_gather_random;
|
||||
#endif
|
||||
#ifdef USE_RNDW32
|
||||
# endif
|
||||
# ifdef USE_RNDW32
|
||||
return rndw32_gather_random;
|
||||
#endif
|
||||
#ifdef USE_RNDRISCOS
|
||||
# endif
|
||||
# ifdef USE_RNDRISCOS
|
||||
return rndriscos_gather_random;
|
||||
# endif
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
137
cipher/rndegd.c
137
cipher/rndegd.c
@ -20,7 +20,7 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef USE_RNDEG
|
||||
#ifdef USE_RNDEGD
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -45,6 +45,8 @@
|
||||
#define offsetof(type, member) ((size_t) &((type *)0)->member)
|
||||
#endif
|
||||
|
||||
static int egd_socket = -1;
|
||||
|
||||
static int
|
||||
do_write( int fd, void *buf, size_t nbytes )
|
||||
{
|
||||
@ -67,24 +69,81 @@ do_write( int fd, void *buf, size_t nbytes )
|
||||
static int
|
||||
do_read( int fd, void *buf, size_t nbytes )
|
||||
{
|
||||
int n, nread = 0;
|
||||
|
||||
do {
|
||||
do {
|
||||
n = read(fd, (char*)buf + nread, nbytes );
|
||||
} while( n == -1 && errno == EINTR );
|
||||
if( n == -1 )
|
||||
return -1;
|
||||
else if( n == 0 ) {
|
||||
/* EGD probably died. */
|
||||
errno = ECONNRESET;
|
||||
return -1;
|
||||
}
|
||||
nread += n;
|
||||
} while( nread < nbytes );
|
||||
return nbytes;
|
||||
int n, nread = 0;
|
||||
|
||||
while (nbytes)
|
||||
{
|
||||
do {
|
||||
n = read(fd, (char*)buf + nread, nbytes );
|
||||
} while( n == -1 && errno == EINTR );
|
||||
if( n == -1 )
|
||||
return nread? nread:-1;
|
||||
else if( n == 0 ) {
|
||||
/* EGD probably died. */
|
||||
errno = ECONNRESET;
|
||||
return -1;
|
||||
}
|
||||
nread += n;
|
||||
nbytes -= n;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
/* Connect to the EGD and return the file descriptor. Return -1 on
|
||||
error. With NOFAIL set to true, silently fail and return the
|
||||
error, otherwise print an error message and die. */
|
||||
int
|
||||
rndegd_connect_socket (int nofail)
|
||||
{
|
||||
int fd;
|
||||
const char *bname = NULL;
|
||||
char *name;
|
||||
struct sockaddr_un addr;
|
||||
int addr_len;
|
||||
|
||||
if (egd_socket != -1)
|
||||
{
|
||||
close (egd_socket);
|
||||
egd_socket = -1;
|
||||
}
|
||||
|
||||
#ifdef EGD_SOCKET_NAME
|
||||
bname = EGD_SOCKET_NAME;
|
||||
#endif
|
||||
if ( !bname || !*bname )
|
||||
bname = "=entropy";
|
||||
|
||||
if ( *bname == '=' && bname[1] )
|
||||
name = make_filename( g10_opt_homedir, bname+1 , NULL );
|
||||
else
|
||||
name = make_filename( bname , NULL );
|
||||
|
||||
if ( strlen(name)+1 >= sizeof addr.sun_path )
|
||||
g10_log_fatal ("EGD socketname is too long\n");
|
||||
|
||||
memset( &addr, 0, sizeof addr );
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy( addr.sun_path, name );
|
||||
addr_len = (offsetof( struct sockaddr_un, sun_path )
|
||||
+ strlen( addr.sun_path ));
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1 && !nofail)
|
||||
g10_log_fatal("can't create unix domain socket: %s\n",
|
||||
strerror(errno) );
|
||||
else if (connect (fd, (struct sockaddr*)&addr, addr_len) == -1)
|
||||
{
|
||||
if (!nofail)
|
||||
g10_log_fatal("can't connect to `%s': %s\n",
|
||||
name, strerror(errno) );
|
||||
close (fd);
|
||||
fd = -1;
|
||||
}
|
||||
m_free(name);
|
||||
if (fd != -1)
|
||||
egd_socket = fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
@ -99,7 +158,7 @@ int
|
||||
rndegd_gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
size_t length, int level )
|
||||
{
|
||||
static int fd = -1;
|
||||
int fd = egd_socket;
|
||||
int n;
|
||||
byte buffer[256+2];
|
||||
int nbytes;
|
||||
@ -111,47 +170,9 @@ rndegd_gather_random( void (*add)(const void*, size_t, int), int requester,
|
||||
return 0;
|
||||
|
||||
restart:
|
||||
if( do_restart ) {
|
||||
if( fd != -1 ) {
|
||||
close( fd );
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
if( fd == -1 ) {
|
||||
const char *bname = NULL;
|
||||
char *name;
|
||||
struct sockaddr_un addr;
|
||||
int addr_len;
|
||||
|
||||
#ifdef EGD_SOCKET_NAME
|
||||
bname = EGD_SOCKET_NAME;
|
||||
#endif
|
||||
if ( !bname || !*bname )
|
||||
bname = "=entropy";
|
||||
if (fd == -1 || do_restart)
|
||||
fd = rndegd_connect_socket (0);
|
||||
|
||||
if ( *bname == '=' && bname[1] )
|
||||
name = make_filename( g10_opt_homedir, bname+1 , NULL );
|
||||
else
|
||||
name = make_filename( bname , NULL );
|
||||
|
||||
if ( strlen(name)+1 >= sizeof addr.sun_path )
|
||||
g10_log_fatal ("EGD socketname is too long\n");
|
||||
|
||||
memset( &addr, 0, sizeof addr );
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy( addr.sun_path, name );
|
||||
addr_len = offsetof( struct sockaddr_un, sun_path )
|
||||
+ strlen( addr.sun_path );
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if( fd == -1 )
|
||||
g10_log_fatal("can't create unix domain socket: %s\n",
|
||||
strerror(errno) );
|
||||
if( connect( fd, (struct sockaddr*)&addr, addr_len) == -1 )
|
||||
g10_log_fatal("can't connect to `%s': %s\n",
|
||||
name, strerror(errno) );
|
||||
m_free(name);
|
||||
}
|
||||
do_restart = 0;
|
||||
|
||||
nbytes = length < 255? length : 255;
|
||||
|
Loading…
x
Reference in New Issue
Block a user