mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04: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>
|
||||
|
||||
* 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;
|
||||
#endif
|
||||
|
||||
void
|
||||
SSL_CTX *ssl_ctx;
|
||||
|
||||
static void
|
||||
ssl_init_prng (void)
|
||||
{
|
||||
/* 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);
|
||||
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 */
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
verify_callback (int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
char *s, buf[256];
|
||||
@ -139,30 +134,40 @@ verify_callback (int ok, X509_STORE_CTX *ctx)
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* pass all ssl errors to DEBUGP
|
||||
returns the number of printed errors */
|
||||
int
|
||||
ssl_printerrors (void)
|
||||
/* Print SSL errors. */
|
||||
|
||||
void
|
||||
ssl_print_errors (void)
|
||||
{
|
||||
int ocerr = 0;
|
||||
unsigned long curerr = 0;
|
||||
char errbuff[1024];
|
||||
xzero (errbuff);
|
||||
while ((curerr = ERR_get_error ()) != 0)
|
||||
{
|
||||
DEBUGP (("OpenSSL: %s\n", ERR_error_string (curerr, errbuff)));
|
||||
++ocerr;
|
||||
}
|
||||
return ocerr;
|
||||
logprintf (LOG_NOTQUIET, "OpenSSL: %s\n",
|
||||
ERR_error_string (curerr, errbuff));
|
||||
}
|
||||
|
||||
/* Creates a SSL Context and sets some defaults for it */
|
||||
uerr_t
|
||||
init_ssl (SSL_CTX **ctx)
|
||||
ssl_init ()
|
||||
{
|
||||
SSL_METHOD *meth = NULL;
|
||||
int verify;
|
||||
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_load_error_strings ();
|
||||
SSLeay_add_all_algorithms ();
|
||||
@ -184,20 +189,20 @@ init_ssl (SSL_CTX **ctx)
|
||||
}
|
||||
if (meth == NULL)
|
||||
{
|
||||
ssl_printerrors ();
|
||||
ssl_print_errors ();
|
||||
return SSLERRCTXCREATE;
|
||||
}
|
||||
|
||||
*ctx = SSL_CTX_new (meth);
|
||||
ssl_ctx = SSL_CTX_new (meth);
|
||||
if (meth == NULL)
|
||||
{
|
||||
ssl_printerrors ();
|
||||
ssl_print_errors ();
|
||||
return SSLERRCTXCREATE;
|
||||
}
|
||||
/* Can we validate the server Cert ? */
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -239,14 +244,16 @@ init_ssl (SSL_CTX **ctx)
|
||||
if (opt.sslcertfile == NULL)
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -254,28 +261,30 @@ init_ssl (SSL_CTX **ctx)
|
||||
return 0; /* Succeded */
|
||||
}
|
||||
|
||||
static
|
||||
int ssl_read (int fd, char *buf, int bufsize, void *ctx)
|
||||
static int
|
||||
ssl_read (int fd, char *buf, int bufsize, void *ctx)
|
||||
{
|
||||
int res;
|
||||
int ret;
|
||||
SSL *ssl = (SSL *) ctx;
|
||||
/* #### Does SSL_read actually set EINTR? */
|
||||
do
|
||||
res = SSL_read (ssl, buf, bufsize);
|
||||
while (res == -1 && errno == EINTR);
|
||||
return res;
|
||||
ret = SSL_read (ssl, buf, bufsize);
|
||||
while (ret == -1
|
||||
&& SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_write (int fd, char *buf, int bufsize, void *ctx)
|
||||
{
|
||||
int res = 0;
|
||||
int ret = 0;
|
||||
SSL *ssl = (SSL *) ctx;
|
||||
/* #### Does SSL_write actually set EINTR? */
|
||||
do
|
||||
res = SSL_write (ssl, buf, bufsize);
|
||||
while (res == -1 && errno == EINTR);
|
||||
return res;
|
||||
ret = SSL_write (ssl, buf, bufsize);
|
||||
while (ret == -1
|
||||
&& SSL_get_error (ssl, ret) == SSL_ERROR_SYSCALL
|
||||
&& errno == EINTR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -312,9 +321,12 @@ ssl_close (int fd, void *ctx)
|
||||
/* Sets up a SSL structure and performs the handshake on fd. */
|
||||
|
||||
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)
|
||||
goto err;
|
||||
if (!SSL_set_fd (ssl, fd))
|
||||
@ -331,14 +343,8 @@ connect_ssl (int fd, SSL_CTX *ctx)
|
||||
return ssl;
|
||||
|
||||
err:
|
||||
ssl_printerrors ();
|
||||
ssl_print_errors ();
|
||||
if (ssl)
|
||||
SSL_free (ssl);
|
||||
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
|
||||
#define GEN_SSLFUNC_H
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
int ssl_init PARAMS ((void));
|
||||
|
||||
void ssl_init_prng PARAMS ((void));
|
||||
int init_ssl PARAMS ((SSL_CTX **));
|
||||
|
||||
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));
|
||||
int ssl_connect PARAMS ((int));
|
||||
int ssl_print_error PARAMS ((void));
|
||||
|
||||
#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;
|
||||
int auth_tried_already;
|
||||
struct rbuf rbuf;
|
||||
#ifdef HAVE_SSL
|
||||
static SSL_CTX *ssl_ctx = NULL;
|
||||
#endif
|
||||
int using_ssl = 0;
|
||||
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;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/* initialize ssl_ctx on first run */
|
||||
if (!ssl_ctx)
|
||||
/* Initialize the SSL context. After the first run, this is a
|
||||
no-op. */
|
||||
switch (ssl_init ())
|
||||
{
|
||||
uerr_t err = init_ssl (&ssl_ctx);
|
||||
if (err != 0)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case SSLERRCTXCREATE:
|
||||
/* this is fatal */
|
||||
logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
|
||||
ssl_printerrors ();
|
||||
return err;
|
||||
case SSLERRCERTFILE:
|
||||
/* try without certfile */
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Failed to load certificates from %s\n"),
|
||||
opt.sslcertfile);
|
||||
ssl_printerrors ();
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Trying without the specified certificate\n"));
|
||||
break;
|
||||
case SSLERRCERTKEY:
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Failed to get certificate key from %s\n"),
|
||||
opt.sslcertkey);
|
||||
ssl_printerrors ();
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Trying without the specified certificate\n"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
case SSLERRCTXCREATE:
|
||||
/* this is fatal */
|
||||
logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
|
||||
return SSLERRCTXCREATE;
|
||||
case SSLERRCERTFILE:
|
||||
/* try without certfile */
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Failed to load certificates from %s\n"),
|
||||
opt.sslcertfile);
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Trying without the specified certificate\n"));
|
||||
break;
|
||||
case SSLERRCERTKEY:
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Failed to get certificate key from %s\n"),
|
||||
opt.sslcertkey);
|
||||
logprintf (LOG_NOTQUIET,
|
||||
_("Trying without the specified certificate\n"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
@ -699,7 +687,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
||||
#ifdef HAVE_SSL
|
||||
if (conn->scheme == SCHEME_HTTPS)
|
||||
{
|
||||
if (!connect_ssl (sock, ssl_ctx))
|
||||
if (!ssl_connect (sock))
|
||||
{
|
||||
logputs (LOG_VERBOSE, "\n");
|
||||
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 "convert.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
# include "gen_sslfunc.h"
|
||||
#endif
|
||||
|
||||
/* On GNU system this will include system-wide getopt.h. */
|
||||
#include "getopt.h"
|
||||
|
||||
@ -873,12 +869,6 @@ 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 */
|
||||
/* Retrieve the URLs from argument list. */
|
||||
for (t = url; *t; t++)
|
||||
|
Loading…
Reference in New Issue
Block a user