[svn] GnuPG - r3999 - in trunk: . cipher g10
svn author wk
cvs at cvs.gnupg.org
Thu Feb 9 13:54:43 CET 2006
Author: wk
Date: 2006-02-09 13:54:41 +0100 (Thu, 09 Feb 2006)
New Revision: 3999
Modified:
trunk/ChangeLog
trunk/cipher/ChangeLog
trunk/cipher/random.c
trunk/cipher/random.h
trunk/configure.ac
trunk/g10/ChangeLog
trunk/g10/gpg.c
Log:
Lock random seed file
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/ChangeLog 2006-02-09 12:54:41 UTC (rev 3999)
@@ -1,3 +1,7 @@
+2006-02-09 Werner Koch <wk at g10code.com>
+
+ * configure.ac: Check for fcntl and ftruncate.
+
2006-01-22 David Shaw <dshaw at jabberwocky.com>
* configure.ac: Add define for EXEEXT so we can find keyserver
Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/cipher/ChangeLog 2006-02-09 12:54:41 UTC (rev 3999)
@@ -1,3 +1,9 @@
+2006-02-09 Werner Koch <wk at g10code.com>
+
+ * random.c (lock_seed_file): New.
+ (read_seed_file, update_random_seed_file): Use it.
+ (random_disable_locking): New.
+
2005-12-06 David Shaw <dshaw at jabberwocky.com>
* idea-stub.c (load_module): Not legal to return a void * as a
Modified: trunk/cipher/random.c
===================================================================
--- trunk/cipher/random.c 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/cipher/random.c 2006-02-09 12:54:41 UTC (rev 3999)
@@ -1,6 +1,6 @@
/* random.c - random number generator
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 Free Software Foundation, Inc.
+ * 2003, 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -70,6 +70,14 @@
#endif
+/* Check whether we can lock the seed file read write. */
+#if defined(HAVE_FCNTL) && defined(HAVE_FTRUNCATE) && !defined(HAVE_W32_SYSTEM)
+#define LOCK_SEED_FILE 1
+#else
+#define LOCK_SEED_FILE 0
+#endif
+
+
#if SIZEOF_UNSIGNED_LONG == 8
#define ADD_VALUE 0xa5a5a5a5a5a5a5a5
#elif SIZEOF_UNSIGNED_LONG == 4
@@ -105,6 +113,7 @@
static int did_initial_extra_seeding;
static char *seed_file_name;
static int allow_seed_file_update;
+static int no_seed_file_locking;
static int secure_alloc;
static int quick_test;
@@ -272,6 +281,13 @@
return faked_rng || quick_test;
}
+/* Disable locking of seed files. */
+void
+random_disable_locking ()
+{
+ no_seed_file_locking = 1;
+}
+
/****************
* Return a pointer to a randomized buffer of level 0 and LENGTH bits
* caller must free the buffer.
@@ -359,6 +375,50 @@
seed_file_name = xstrdup( name );
}
+
+/* Lock an open file identified by file descriptor FD and wait a
+ reasonable time to succeed. With FOR_WRITE set to true a Rite lock
+ will be taken. FNAME is used only for diagnostics. Returns 0 on
+ success or -1 on error. */
+#if LOCK_SEED_FILE
+static int
+lock_seed_file (int fd, const char *fname, int for_write)
+{
+ struct flock lck;
+ struct timeval tv;
+ int backoff=0;
+
+ if (no_seed_file_locking)
+ return 0;
+
+ /* We take a lock on the entire file. */
+ memset (&lck, 0, sizeof lck);
+ lck.l_type = for_write? F_WRLCK : F_RDLCK;
+ lck.l_whence = SEEK_SET;
+
+ while (fcntl (fd, F_SETLK, &lck) == -1)
+ {
+ if (errno != EAGAIN && errno != EACCES)
+ {
+ log_info (_("can't lock `%s': %s\n"), fname, strerror (errno));
+ return -1;
+ }
+
+ if (backoff > 2) /* Show the first message after ~2.25 seconds. */
+ log_info( _("waiting for lock on `%s'...\n"), fname);
+
+ tv.tv_sec = backoff;
+ tv.tv_usec = 250000;
+ select (0, NULL, NULL, NULL, &tv);
+ if (backoff < 10)
+ backoff++ ;
+ }
+ return 0;
+}
+#endif /*LOCK_SEED_FILE*/
+
+
+
/****************
* Read in a seed form the random_seed file
* and return true if this was successful
@@ -388,6 +448,12 @@
log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
return 0;
}
+ if (lock_seed_file (fd, seed_file_name, 0))
+ {
+ close (fd);
+ return 0;
+ }
+
if( fstat( fd, &sb ) ) {
log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
close(fd);
@@ -468,12 +534,31 @@
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
S_IRUSR|S_IWUSR );
#else
+# if LOCK_SEED_FILE
+ fd = open( seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
+# else
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
+# endif
#endif
if( fd == -1 ) {
log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
return;
}
+
+ if (lock_seed_file (fd, seed_file_name, 1))
+ {
+ close (fd);
+ return;
+ }
+#if LOCK_SEED_FILE
+ if (ftruncate (fd, 0))
+ {
+ log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno));
+ close (fd);
+ return;
+ }
+#endif /*LOCK_SEED_FILE*/
+
do {
i = write( fd, keypool, POOLSIZE );
} while( i == -1 && errno == EINTR );
Modified: trunk/cipher/random.h
===================================================================
--- trunk/cipher/random.h 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/cipher/random.h 2006-02-09 12:54:41 UTC (rev 3999)
@@ -30,6 +30,7 @@
void update_random_seed_file(void);
int quick_random_gen( int onoff );
int random_is_faked(void);
+void random_disable_locking (void);
void randomize_buffer( byte *buffer, size_t length, int level );
byte *get_random_bits( size_t nbits, int level, int secure );
void fast_random_poll( void );
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/configure.ac 2006-02-09 12:54:41 UTC (rev 3999)
@@ -858,6 +858,7 @@
AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime)
AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale)
AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo)
+AC_CHECK_FUNCS(fcntl ftruncate)
AC_REPLACE_FUNCS(mkdtemp timegm isascii memrchr)
AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/g10/ChangeLog 2006-02-09 12:54:41 UTC (rev 3999)
@@ -1,3 +1,7 @@
+2006-02-09 Werner Koch <wk at g10code.com>
+
+ * gpg.c (main) <oLockNever>: Disable random locking.
+
2006-02-06 Werner Koch <wk at g10code.com>
* ccid-driver.c, ccid-driver.h: Updated from GnuPG 1.9. Changes:
Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c 2006-02-08 17:56:01 UTC (rev 3998)
+++ trunk/g10/gpg.c 2006-02-09 12:54:41 UTC (rev 3999)
@@ -2404,7 +2404,10 @@
case oEscapeFrom: opt.escape_from = 1; break;
case oNoEscapeFrom: opt.escape_from = 0; break;
case oLockOnce: opt.lock_once = 1; break;
- case oLockNever: disable_dotlock(); break;
+ case oLockNever:
+ disable_dotlock ();
+ random_disable_locking ();
+ break;
case oLockMultiple:
#ifndef __riscos__
opt.lock_once = 0;
More information about the Gnupg-commits
mailing list