提交 de02ec27 编写于 作者: R Richard Levitte

Check if a random "file" is really a device file, and treat it

specially if it is.
Add a few OpenBSD-specific cases.
This is part of a large change submitted by Markus Friedl <markus@openbsd.org>
上级 11234103
...@@ -125,6 +125,24 @@ ...@@ -125,6 +125,24 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#ifdef __OpenBSD__
int RAND_poll(void)
{
u_int32_t rnd = 0, i;
unsigned char buf[ENTROPY_NEEDED];
for (i = 0; i < sizeof(buf); i++) {
if (i % 4 == 0)
rnd = arc4random();
buf[i] = rnd;
rnd >>= 8;
}
RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
memset(buf, 0, sizeof(buf));
return 1;
}
#else
int RAND_poll(void) int RAND_poll(void)
{ {
unsigned long l; unsigned long l;
...@@ -236,6 +254,7 @@ int RAND_poll(void) ...@@ -236,6 +254,7 @@ int RAND_poll(void)
#endif #endif
} }
#endif
#endif #endif
#if defined(OPENSSL_SYS_VXWORKS) #if defined(OPENSSL_SYS_VXWORKS)
......
...@@ -56,6 +56,9 @@ ...@@ -56,6 +56,9 @@
* [including the GNU Public Licence.] * [including the GNU Public Licence.]
*/ */
/* We need to define this to get macros like S_IFBLK and S_IFCHR */
#define _XOPEN_SOURCE 1
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -64,6 +67,7 @@ ...@@ -64,6 +67,7 @@
#include "e_os.h" #include "e_os.h"
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS #ifdef OPENSSL_SYS_VMS
#include <unixio.h> #include <unixio.h>
...@@ -106,6 +110,14 @@ int RAND_load_file(const char *file, long bytes) ...@@ -106,6 +110,14 @@ int RAND_load_file(const char *file, long bytes)
in=fopen(file,"rb"); in=fopen(file,"rb");
if (in == NULL) goto err; if (in == NULL) goto err;
if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
/* this file is a device. we don't want read an infinite number
* of bytes from a random device, nor do we want to use buffered
* I/O because we will waste system entropy.
*/
bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
}
for (;;) for (;;)
{ {
if (bytes > 0) if (bytes > 0)
...@@ -135,7 +147,20 @@ int RAND_write_file(const char *file) ...@@ -135,7 +147,20 @@ int RAND_write_file(const char *file)
int i,ret=0,rand_err=0; int i,ret=0,rand_err=0;
FILE *out = NULL; FILE *out = NULL;
int n; int n;
struct stat sb;
i=stat(file,&sb);
if (i != -1) {
if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
/* this file is a device. we don't write back to it.
* we "succeed" on the assumption this is some sort
* of random device. Otherwise attempting to write to
* and chmod the device causes problems.
*/
return(1);
}
}
#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) #if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32)
/* For some reason Win32 can't write to files created this way */ /* For some reason Win32 can't write to files created this way */
...@@ -197,16 +222,17 @@ err: ...@@ -197,16 +222,17 @@ err:
const char *RAND_file_name(char *buf, size_t size) const char *RAND_file_name(char *buf, size_t size)
{ {
char *s=NULL; char *s=NULL;
char *ret=NULL; int ok = 0;
#ifdef __OpenBSD__
struct stat sb;
#endif
if (OPENSSL_issetugid() == 0) if (OPENSSL_issetugid() == 0)
s=getenv("RANDFILE"); s=getenv("RANDFILE");
if (s != NULL) if (s != NULL && *s && strlen(s) + 1 < size)
{ {
if(strlen(s) >= size) if (BUF_strlcpy(buf,s,size) >= size)
return NULL; return NULL;
strcpy(buf,s);
ret=buf;
} }
else else
{ {
...@@ -218,17 +244,36 @@ const char *RAND_file_name(char *buf, size_t size) ...@@ -218,17 +244,36 @@ const char *RAND_file_name(char *buf, size_t size)
s = DEFAULT_HOME; s = DEFAULT_HOME;
} }
#endif #endif
if (s != NULL && (strlen(s)+strlen(RFILE)+2 < size)) if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
{ {
strcpy(buf,s); BUF_strlcpy(buf,s,size);
#ifndef OPENSSL_SYS_VMS #ifndef OPENSSL_SYS_VMS
strcat(buf,"/"); BUF_strlcat(buf,"/",size);
#endif #endif
strcat(buf,RFILE); BUF_strlcat(buf,RFILE,size);
ret=buf; ok = 1;
} }
else else
buf[0] = '\0'; /* no file name */ buf[0] = '\0'; /* no file name */
} }
return(ret);
#ifdef __OpenBSD__
/* given that all random loads just fail if the file can't be
* seen on a stat, we stat the file we're returning, if it
* fails, use /dev/arandom instead. this allows the user to
* use their own source for good random data, but defaults
* to something hopefully decent if that isn't available.
*/
if (!ok)
if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
return(NULL);
}
if (stat(buf,&sb) == -1)
if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
return(NULL);
}
#endif
return(buf);
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册