mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Fix OpenSSL PRNG seeding.
Published in <sxs7ks1noc4.fsf@florida.arsdigita.de>.
This commit is contained in:
parent
b248bfe395
commit
0620ada923
@ -1,3 +1,16 @@
|
||||
2001-12-06 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* url.c (scheme_disable): New function.
|
||||
|
||||
* main.c (main): Call ssl_init_prng from here rather than from
|
||||
init_ssl, so that it has a chance to disable support for https
|
||||
before a URL has been resolved.
|
||||
|
||||
* gen_sslfunc.c (ssl_init_prng): Seed with rand() if all else
|
||||
failed.
|
||||
(ssl_init_prng): Disable support for https if seeding the PRNG
|
||||
fails.
|
||||
|
||||
2001-12-06 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* utils.c (read_whole_line): Handle lines beginning with \0.
|
||||
|
@ -43,6 +43,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "wget.h"
|
||||
#include "connect.h"
|
||||
#include "url.h"
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
@ -50,57 +51,66 @@ extern int errno;
|
||||
|
||||
static int verify_callback PARAMS ((int, X509_STORE_CTX *));
|
||||
|
||||
static void
|
||||
void
|
||||
ssl_init_prng (void)
|
||||
{
|
||||
/* It is likely that older versions of OpenSSL will fail on
|
||||
non-Linux machines because this code is unable to seed the PRNG
|
||||
on older versions of the library. */
|
||||
|
||||
#if SSLEAY_VERSION_NUMBER >= 0x00905100
|
||||
char rand_file[256];
|
||||
int maxrand = 500;
|
||||
|
||||
/* First, seed from a file specified by the user. This will be
|
||||
$RANDFILE, if set, or ~/.rnd. */
|
||||
RAND_file_name (rand_file, sizeof (rand_file));
|
||||
if (rand_file)
|
||||
/* Seed at most 16k (value borrowed from curl) from random file. */
|
||||
RAND_load_file (rand_file, 16384);
|
||||
|
||||
if (RAND_status ())
|
||||
return;
|
||||
|
||||
/* Get random data from EGD if opt.sslegdsock was set. */
|
||||
if (opt.sslegdsock)
|
||||
RAND_egd (opt.sslegdsock);
|
||||
|
||||
if (RAND_status ())
|
||||
return;
|
||||
|
||||
#ifdef WINDOWS
|
||||
/* Under Windows, we can try to seed the PRNG using screen content.
|
||||
This may or may not work, depending on whether we'll calling Wget
|
||||
interactively. */
|
||||
|
||||
RAND_screen ();
|
||||
if (RAND_status ())
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Still not enough randomness, presumably because neither random
|
||||
file nor EGD have been available. Use the stupidest possible
|
||||
method -- seed OpenSSL's PRNG with the system's PRNG. This is
|
||||
insecure in the cryptographic sense, but people who care about
|
||||
security will use /dev/random or their own source of randomness
|
||||
anyway. */
|
||||
|
||||
srand (time (NULL));
|
||||
while (RAND_status () == 0 && maxrand-- > 0)
|
||||
{
|
||||
int rnd = rand ();
|
||||
RAND_seed ((unsigned char *)&rnd, sizeof (rnd));
|
||||
}
|
||||
|
||||
if (RAND_status () == 0)
|
||||
{
|
||||
char rand_file[256];
|
||||
time_t t;
|
||||
long l,seed;
|
||||
|
||||
t = time(NULL);
|
||||
/* gets random data from egd if opt.sslegdsock was set */
|
||||
if (opt.sslegdsock != NULL)
|
||||
RAND_egd(opt.sslegdsock);
|
||||
/* gets the file ~/.rnd or $RANDFILE if set */
|
||||
RAND_file_name(rand_file, 256);
|
||||
if (rand_file != NULL)
|
||||
{
|
||||
/* Seed as much as 1024 bytes from RAND_file_name */
|
||||
RAND_load_file(rand_file, 1024);
|
||||
}
|
||||
/* Seed in time (mod_ssl does this) */
|
||||
RAND_seed((unsigned char *)&t, sizeof(time_t));
|
||||
/* Initialize system's random number generator */
|
||||
RAND_bytes((unsigned char *)&seed, sizeof(long));
|
||||
#ifndef WINDOWS
|
||||
srand48(seed);
|
||||
while (RAND_status () == 0)
|
||||
{
|
||||
/* Repeatedly seed the PRNG using the system's random number
|
||||
generator until it has been seeded with enough data. */
|
||||
l = lrand48();
|
||||
RAND_seed((unsigned char *)&l, sizeof(long));
|
||||
}
|
||||
#else /* WINDOWS */
|
||||
RAND_screen();
|
||||
if (RAND_status() == 0)
|
||||
/* Here we should probably disable the whole ssl protocol ? HEH */
|
||||
DEBUGP (("SSL random data generator not seeded correctly, %i",RAND_status()));
|
||||
#endif /* WINDOWS */
|
||||
if (rand_file != NULL)
|
||||
{
|
||||
/* Write a rand_file */
|
||||
RAND_write_file(rand_file);
|
||||
}
|
||||
logprintf (LOG_NOTQUIET, "Could not seed OpenSSL PRNG; disabling SSL.\n");
|
||||
scheme_disable (SCHEME_HTTPS);
|
||||
}
|
||||
#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Creates a SSL Context and sets some defaults for it */
|
||||
uerr_t
|
||||
init_ssl (SSL_CTX **ctx)
|
||||
@ -126,7 +136,6 @@ init_ssl (SSL_CTX **ctx)
|
||||
SSL_FILETYPE_PEM) <= 0)
|
||||
return SSLERRCERTKEY;
|
||||
}
|
||||
ssl_init_prng();
|
||||
return 0; /* Succeded */
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
void ssl_init_prng PARAMS ((void));
|
||||
int init_ssl PARAMS ((SSL_CTX **));
|
||||
|
||||
int connect_ssl PARAMS ((SSL **, SSL_CTX *, int));
|
||||
void shutdown_ssl PARAMS ((SSL*));
|
||||
void free_ssl_ctx PARAMS ((SSL_CTX *));
|
||||
|
11
src/main.c
11
src/main.c
@ -53,6 +53,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "url.h"
|
||||
#include "progress.h" /* for progress_handle_sigwinch */
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
# include "gen_sslfunc.h"
|
||||
#endif
|
||||
|
||||
/* On GNU system this will include system-wide getopt.h. */
|
||||
#include "getopt.h"
|
||||
|
||||
@ -794,8 +798,13 @@ Can't timestamp and not clobber old files at the same time.\n"));
|
||||
#endif
|
||||
#endif /* HAVE_SIGNAL */
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/* Must call this before resolving any URLs because it has the power
|
||||
to disable `https'. */
|
||||
ssl_init_prng ();
|
||||
#endif
|
||||
|
||||
status = RETROK; /* initialize it, just-in-case */
|
||||
/*recursive_reset ();*/
|
||||
/* Retrieve the URLs from argument list. */
|
||||
for (t = url; *t; t++)
|
||||
{
|
||||
|
33
src/url.c
33
src/url.c
@ -54,19 +54,20 @@ struct scheme_data
|
||||
{
|
||||
char *leading_string;
|
||||
int default_port;
|
||||
int enabled;
|
||||
};
|
||||
|
||||
/* Supported schemes: */
|
||||
static struct scheme_data supported_schemes[] =
|
||||
{
|
||||
{ "http://", DEFAULT_HTTP_PORT },
|
||||
{ "http://", DEFAULT_HTTP_PORT, 1 },
|
||||
#ifdef HAVE_SSL
|
||||
{ "https://", DEFAULT_HTTPS_PORT },
|
||||
{ "https://", DEFAULT_HTTPS_PORT, 1 },
|
||||
#endif
|
||||
{ "ftp://", DEFAULT_FTP_PORT },
|
||||
{ "ftp://", DEFAULT_FTP_PORT, 1 },
|
||||
|
||||
/* SCHEME_INVALID */
|
||||
{ NULL, -1 }
|
||||
{ NULL, -1, 0 }
|
||||
};
|
||||
|
||||
static char *construct_relative PARAMS ((const char *, const char *));
|
||||
@ -420,9 +421,15 @@ url_scheme (const char *url)
|
||||
int i;
|
||||
|
||||
for (i = 0; supported_schemes[i].leading_string; i++)
|
||||
if (!strncasecmp (url, supported_schemes[i].leading_string,
|
||||
strlen (supported_schemes[i].leading_string)))
|
||||
return (enum url_scheme)i;
|
||||
if (0 == strncasecmp (url, supported_schemes[i].leading_string,
|
||||
strlen (supported_schemes[i].leading_string)))
|
||||
{
|
||||
if (supported_schemes[i].enabled)
|
||||
return (enum url_scheme) i;
|
||||
else
|
||||
return SCHEME_INVALID;
|
||||
}
|
||||
|
||||
return SCHEME_INVALID;
|
||||
}
|
||||
|
||||
@ -466,6 +473,12 @@ scheme_default_port (enum url_scheme scheme)
|
||||
return supported_schemes[scheme].default_port;
|
||||
}
|
||||
|
||||
void
|
||||
scheme_disable (enum url_scheme scheme)
|
||||
{
|
||||
supported_schemes[scheme].enabled = 0;
|
||||
}
|
||||
|
||||
/* Skip the username and password, if present here. The function
|
||||
should be called *not* with the complete URL, but with the part
|
||||
right after the scheme.
|
||||
@ -606,8 +619,8 @@ lowercase_str (char *str)
|
||||
static char *parse_errors[] = {
|
||||
#define PE_NO_ERROR 0
|
||||
"No error",
|
||||
#define PE_UNRECOGNIZED_SCHEME 1
|
||||
"Unrecognized scheme",
|
||||
#define PE_UNSUPPORTED_SCHEME 1
|
||||
"Unsupported scheme",
|
||||
#define PE_EMPTY_HOST 2
|
||||
"Empty host",
|
||||
#define PE_BAD_PORT_NUMBER 3
|
||||
@ -650,7 +663,7 @@ url_parse (const char *url, int *error)
|
||||
scheme = url_scheme (url);
|
||||
if (scheme == SCHEME_INVALID)
|
||||
{
|
||||
SETERR (error, PE_UNRECOGNIZED_SCHEME);
|
||||
SETERR (error, PE_UNSUPPORTED_SCHEME);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -133,6 +133,7 @@ enum url_scheme url_scheme PARAMS ((const char *));
|
||||
int url_skip_scheme PARAMS ((const char *));
|
||||
int url_has_scheme PARAMS ((const char *));
|
||||
int scheme_default_port PARAMS ((enum url_scheme));
|
||||
void scheme_disable PARAMS ((enum url_scheme));
|
||||
|
||||
int url_skip_uname PARAMS ((const char *));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user