mirror of
https://github.com/mirror/wget.git
synced 2025-01-08 19:30:41 +08:00
[svn] Improve SSL code. Only initialize PRNG when needed.
This commit is contained in:
parent
49dfcb6036
commit
bc764dbb7c
@ -1,3 +1,10 @@
|
|||||||
|
2003-11-06 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
|
* gen_sslfunc.c (ssl_read): Implement a more correct check for
|
||||||
|
EINTR.
|
||||||
|
(ssl_write): Ditto.
|
||||||
|
(init_ssl): Use a global SSL context.
|
||||||
|
|
||||||
2003-11-06 Hrvoje Niksic <hniksic@xemacs.org>
|
2003-11-06 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* connect.c (xclose): Free INFO even if it doesn't provide a
|
* connect.c (xclose): Free INFO even if it doesn't provide a
|
||||||
|
@ -58,7 +58,9 @@ so, delete this exception statement from your version. */
|
|||||||
extern int errno;
|
extern int errno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
SSL_CTX *ssl_ctx;
|
||||||
|
|
||||||
|
static void
|
||||||
ssl_init_prng (void)
|
ssl_init_prng (void)
|
||||||
{
|
{
|
||||||
/* It is likely that older versions of OpenSSL will fail on
|
/* It is likely that older versions of OpenSSL will fail on
|
||||||
@ -108,17 +110,10 @@ ssl_init_prng (void)
|
|||||||
unsigned char rnd = random_number (256);
|
unsigned char rnd = random_number (256);
|
||||||
RAND_seed (&rnd, sizeof (rnd));
|
RAND_seed (&rnd, sizeof (rnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RAND_status () == 0)
|
|
||||||
{
|
|
||||||
logprintf (LOG_NOTQUIET,
|
|
||||||
_("Could not seed OpenSSL PRNG; disabling SSL.\n"));
|
|
||||||
scheme_disable (SCHEME_HTTPS);
|
|
||||||
}
|
|
||||||
#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */
|
#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
verify_callback (int ok, X509_STORE_CTX *ctx)
|
verify_callback (int ok, X509_STORE_CTX *ctx)
|
||||||
{
|
{
|
||||||
char *s, buf[256];
|
char *s, buf[256];
|
||||||
@ -139,30 +134,40 @@ verify_callback (int ok, X509_STORE_CTX *ctx)
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass all ssl errors to DEBUGP
|
/* Print SSL errors. */
|
||||||
returns the number of printed errors */
|
|
||||||
int
|
void
|
||||||
ssl_printerrors (void)
|
ssl_print_errors (void)
|
||||||
{
|
{
|
||||||
int ocerr = 0;
|
|
||||||
unsigned long curerr = 0;
|
unsigned long curerr = 0;
|
||||||
char errbuff[1024];
|
char errbuff[1024];
|
||||||
xzero (errbuff);
|
xzero (errbuff);
|
||||||
while ((curerr = ERR_get_error ()) != 0)
|
while ((curerr = ERR_get_error ()) != 0)
|
||||||
{
|
logprintf (LOG_NOTQUIET, "OpenSSL: %s\n",
|
||||||
DEBUGP (("OpenSSL: %s\n", ERR_error_string (curerr, errbuff)));
|
ERR_error_string (curerr, errbuff));
|
||||||
++ocerr;
|
|
||||||
}
|
|
||||||
return ocerr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates a SSL Context and sets some defaults for it */
|
/* Creates a SSL Context and sets some defaults for it */
|
||||||
uerr_t
|
uerr_t
|
||||||
init_ssl (SSL_CTX **ctx)
|
ssl_init ()
|
||||||
{
|
{
|
||||||
SSL_METHOD *meth = NULL;
|
SSL_METHOD *meth = NULL;
|
||||||
int verify;
|
int verify;
|
||||||
int can_validate;
|
int can_validate;
|
||||||
|
|
||||||
|
if (ssl_ctx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Init the PRNG. If that fails, bail out. */
|
||||||
|
ssl_init_prng ();
|
||||||
|
if (RAND_status () == 0)
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET,
|
||||||
|
_("Could not seed OpenSSL PRNG; disabling SSL.\n"));
|
||||||
|
scheme_disable (SCHEME_HTTPS);
|
||||||
|
return SSLERRCTXCREATE;
|
||||||
|
}
|
||||||
|
|
||||||
SSL_library_init ();
|
SSL_library_init ();
|
||||||
SSL_load_error_strings ();
|
SSL_load_error_strings ();
|
||||||
SSLeay_add_all_algorithms ();
|
SSLeay_add_all_algorithms ();
|
||||||
@ -184,20 +189,20 @@ init_ssl (SSL_CTX **ctx)
|
|||||||
}
|
}
|
||||||
if (meth == NULL)
|
if (meth == NULL)
|
||||||
{
|
{
|
||||||
ssl_printerrors ();
|
ssl_print_errors ();
|
||||||
return SSLERRCTXCREATE;
|
return SSLERRCTXCREATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ctx = SSL_CTX_new (meth);
|
ssl_ctx = SSL_CTX_new (meth);
|
||||||
if (meth == NULL)
|
if (meth == NULL)
|
||||||
{
|
{
|
||||||
ssl_printerrors ();
|
ssl_print_errors ();
|
||||||
return SSLERRCTXCREATE;
|
return SSLERRCTXCREATE;
|
||||||
}
|
}
|
||||||
/* Can we validate the server Cert ? */
|
/* Can we validate the server Cert ? */
|
||||||
if (opt.sslcadir != NULL || opt.sslcafile != NULL)
|
if (opt.sslcadir != NULL || opt.sslcafile != NULL)
|
||||||
{
|
{
|
||||||
SSL_CTX_load_verify_locations (*ctx, opt.sslcafile, opt.sslcadir);
|
SSL_CTX_load_verify_locations (ssl_ctx, opt.sslcafile, opt.sslcadir);
|
||||||
can_validate = 1;
|
can_validate = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -224,7 +229,7 @@ init_ssl (SSL_CTX **ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX_set_verify (*ctx, verify, verify_callback);
|
SSL_CTX_set_verify (ssl_ctx, verify, verify_callback);
|
||||||
|
|
||||||
if (opt.sslcertfile != NULL || opt.sslcertkey != NULL)
|
if (opt.sslcertfile != NULL || opt.sslcertkey != NULL)
|
||||||
{
|
{
|
||||||
@ -239,14 +244,16 @@ init_ssl (SSL_CTX **ctx)
|
|||||||
if (opt.sslcertfile == NULL)
|
if (opt.sslcertfile == NULL)
|
||||||
opt.sslcertfile = opt.sslcertkey;
|
opt.sslcertfile = opt.sslcertkey;
|
||||||
|
|
||||||
if (SSL_CTX_use_certificate_file (*ctx, opt.sslcertfile, ssl_cert_type) <= 0)
|
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.sslcertfile,
|
||||||
|
ssl_cert_type) <= 0)
|
||||||
{
|
{
|
||||||
ssl_printerrors ();
|
ssl_print_errors ();
|
||||||
return SSLERRCERTFILE;
|
return SSLERRCERTFILE;
|
||||||
}
|
}
|
||||||
if (SSL_CTX_use_PrivateKey_file (*ctx, opt.sslcertkey , ssl_cert_type) <= 0)
|
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.sslcertkey,
|
||||||
|
ssl_cert_type) <= 0)
|
||||||
{
|
{
|
||||||
ssl_printerrors ();
|
ssl_print_errors ();
|
||||||
return SSLERRCERTKEY;
|
return SSLERRCERTKEY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,28 +261,30 @@ init_ssl (SSL_CTX **ctx)
|
|||||||
return 0; /* Succeded */
|
return 0; /* Succeded */
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static int
|
||||||
int ssl_read (int fd, char *buf, int bufsize, void *ctx)
|
ssl_read (int fd, char *buf, int bufsize, void *ctx)
|
||||||
{
|
{
|
||||||
int res;
|
int ret;
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = (SSL *) ctx;
|
||||||
/* #### Does SSL_read actually set EINTR? */
|
|
||||||
do
|
do
|
||||||
res = SSL_read (ssl, buf, bufsize);
|
ret = SSL_read (ssl, buf, bufsize);
|
||||||
while (res == -1 && errno == EINTR);
|
while (ret == -1
|
||||||
return res;
|
&& SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
|
||||||
|
&& errno == EINTR);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ssl_write (int fd, char *buf, int bufsize, void *ctx)
|
ssl_write (int fd, char *buf, int bufsize, void *ctx)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int ret = 0;
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = (SSL *) ctx;
|
||||||
/* #### Does SSL_write actually set EINTR? */
|
|
||||||
do
|
do
|
||||||
res = SSL_write (ssl, buf, bufsize);
|
ret = SSL_write (ssl, buf, bufsize);
|
||||||
while (res == -1 && errno == EINTR);
|
while (ret == -1
|
||||||
return res;
|
&& SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
|
||||||
|
&& errno == EINTR);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -312,9 +321,12 @@ ssl_close (int fd, void *ctx)
|
|||||||
/* Sets up a SSL structure and performs the handshake on fd. */
|
/* Sets up a SSL structure and performs the handshake on fd. */
|
||||||
|
|
||||||
SSL *
|
SSL *
|
||||||
connect_ssl (int fd, SSL_CTX *ctx)
|
ssl_connect (int fd)
|
||||||
{
|
{
|
||||||
SSL *ssl = SSL_new (ctx);
|
SSL *ssl;
|
||||||
|
|
||||||
|
assert (ssl_ctx != NULL);
|
||||||
|
ssl = SSL_new (ssl_ctx);
|
||||||
if (!ssl)
|
if (!ssl)
|
||||||
goto err;
|
goto err;
|
||||||
if (!SSL_set_fd (ssl, fd))
|
if (!SSL_set_fd (ssl, fd))
|
||||||
@ -331,14 +343,8 @@ connect_ssl (int fd, SSL_CTX *ctx)
|
|||||||
return ssl;
|
return ssl;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
ssl_printerrors ();
|
ssl_print_errors ();
|
||||||
if (ssl)
|
if (ssl)
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
free_ssl_ctx (SSL_CTX * ctx)
|
|
||||||
{
|
|
||||||
SSL_CTX_free (ctx);
|
|
||||||
}
|
|
||||||
|
@ -31,16 +31,9 @@ so, delete this exception statement from your version. */
|
|||||||
#ifndef GEN_SSLFUNC_H
|
#ifndef GEN_SSLFUNC_H
|
||||||
#define GEN_SSLFUNC_H
|
#define GEN_SSLFUNC_H
|
||||||
|
|
||||||
#ifdef HAVE_SSL
|
int ssl_init PARAMS ((void));
|
||||||
# include <openssl/ssl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ssl_init_prng PARAMS ((void));
|
int ssl_connect PARAMS ((int));
|
||||||
int init_ssl PARAMS ((SSL_CTX **));
|
int ssl_print_error PARAMS ((void));
|
||||||
|
|
||||||
SSL *connect_ssl PARAMS ((int, SSL_CTX *));
|
|
||||||
void free_ssl_ctx PARAMS ((SSL_CTX *));
|
|
||||||
int verify_callback PARAMS ((int, X509_STORE_CTX *));
|
|
||||||
int ssl_printerrors PARAMS ((void));
|
|
||||||
|
|
||||||
#endif /* GEN_SSLFUNC_H */
|
#endif /* GEN_SSLFUNC_H */
|
||||||
|
62
src/http.c
62
src/http.c
@ -583,9 +583,6 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
int auth_tried_already;
|
int auth_tried_already;
|
||||||
struct rbuf rbuf;
|
struct rbuf rbuf;
|
||||||
#ifdef HAVE_SSL
|
|
||||||
static SSL_CTX *ssl_ctx = NULL;
|
|
||||||
#endif
|
|
||||||
int using_ssl = 0;
|
int using_ssl = 0;
|
||||||
char *cookies = NULL;
|
char *cookies = NULL;
|
||||||
|
|
||||||
@ -610,40 +607,31 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
long post_data_size = 0;
|
long post_data_size = 0;
|
||||||
|
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
/* initialize ssl_ctx on first run */
|
/* Initialize the SSL context. After the first run, this is a
|
||||||
if (!ssl_ctx)
|
no-op. */
|
||||||
|
switch (ssl_init ())
|
||||||
{
|
{
|
||||||
uerr_t err = init_ssl (&ssl_ctx);
|
case SSLERRCTXCREATE:
|
||||||
if (err != 0)
|
/* this is fatal */
|
||||||
{
|
logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
|
||||||
switch (err)
|
return SSLERRCTXCREATE;
|
||||||
{
|
case SSLERRCERTFILE:
|
||||||
case SSLERRCTXCREATE:
|
/* try without certfile */
|
||||||
/* this is fatal */
|
logprintf (LOG_NOTQUIET,
|
||||||
logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
|
_("Failed to load certificates from %s\n"),
|
||||||
ssl_printerrors ();
|
opt.sslcertfile);
|
||||||
return err;
|
logprintf (LOG_NOTQUIET,
|
||||||
case SSLERRCERTFILE:
|
_("Trying without the specified certificate\n"));
|
||||||
/* try without certfile */
|
break;
|
||||||
logprintf (LOG_NOTQUIET,
|
case SSLERRCERTKEY:
|
||||||
_("Failed to load certificates from %s\n"),
|
logprintf (LOG_NOTQUIET,
|
||||||
opt.sslcertfile);
|
_("Failed to get certificate key from %s\n"),
|
||||||
ssl_printerrors ();
|
opt.sslcertkey);
|
||||||
logprintf (LOG_NOTQUIET,
|
logprintf (LOG_NOTQUIET,
|
||||||
_("Trying without the specified certificate\n"));
|
_("Trying without the specified certificate\n"));
|
||||||
break;
|
break;
|
||||||
case SSLERRCERTKEY:
|
default:
|
||||||
logprintf (LOG_NOTQUIET,
|
break;
|
||||||
_("Failed to get certificate key from %s\n"),
|
|
||||||
opt.sslcertkey);
|
|
||||||
ssl_printerrors ();
|
|
||||||
logprintf (LOG_NOTQUIET,
|
|
||||||
_("Trying without the specified certificate\n"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SSL */
|
#endif /* HAVE_SSL */
|
||||||
|
|
||||||
@ -699,7 +687,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
if (conn->scheme == SCHEME_HTTPS)
|
if (conn->scheme == SCHEME_HTTPS)
|
||||||
{
|
{
|
||||||
if (!connect_ssl (sock, ssl_ctx))
|
if (!ssl_connect (sock))
|
||||||
{
|
{
|
||||||
logputs (LOG_VERBOSE, "\n");
|
logputs (LOG_VERBOSE, "\n");
|
||||||
logprintf (LOG_NOTQUIET,
|
logprintf (LOG_NOTQUIET,
|
||||||
|
10
src/main.c
10
src/main.c
@ -65,10 +65,6 @@ extern int errno;
|
|||||||
#include "progress.h" /* for progress_handle_sigwinch */
|
#include "progress.h" /* for progress_handle_sigwinch */
|
||||||
#include "convert.h"
|
#include "convert.h"
|
||||||
|
|
||||||
#ifdef HAVE_SSL
|
|
||||||
# include "gen_sslfunc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* On GNU system this will include system-wide getopt.h. */
|
/* On GNU system this will include system-wide getopt.h. */
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
|
||||||
@ -873,12 +869,6 @@ Can't timestamp and not clobber old files at the same time.\n"));
|
|||||||
#endif
|
#endif
|
||||||
#endif /* HAVE_SIGNAL */
|
#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 */
|
status = RETROK; /* initialize it, just-in-case */
|
||||||
/* Retrieve the URLs from argument list. */
|
/* Retrieve the URLs from argument list. */
|
||||||
for (t = url; *t; t++)
|
for (t = url; *t; t++)
|
||||||
|
Loading…
Reference in New Issue
Block a user