1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Renamed the SSL switches and commands.

This commit is contained in:
hniksic 2005-04-26 10:22:56 -07:00
parent 72549063a9
commit 4edde35100
6 changed files with 221 additions and 148 deletions

View File

@ -1,3 +1,13 @@
2005-04-26 Hrvoje Niksic <hniksic@xemacs.org>
* gen_sslfunc.c (ssl_init): Use default locations for loading the
certificate bundles.
(ssl_init_prng): Disable the cryptographically weak PRNG
initialization fallback.
* init.c: Renamed SSL command-line arguments and wgetrc commands.
(defaults): Check the server certificate by default.
2005-04-26 Hrvoje Niksic <hniksic@xemacs.org>
* cookies.c (cookie_handle_set_cookie): Delete the part of the

View File

@ -1,6 +1,6 @@
/* SSL support.
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Christian Fraenkel.
/* SSL support via OpenSSL library.
Copyright (C) 2000-2005 Free Software Foundation, Inc.
Originally contributed by Christian Fraenkel.
This file is part of GNU Wget.
@ -70,7 +70,6 @@ ssl_init_prng (void)
#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. */
@ -82,9 +81,9 @@ ssl_init_prng (void)
if (RAND_status ())
return;
/* Get random data from EGD if opt.sslegdsock was set. */
if (opt.sslegdsock && *opt.sslegdsock)
RAND_egd (opt.sslegdsock);
/* Get random data from EGD if opt.egd_file was set. */
if (opt.egd_file && *opt.egd_file)
RAND_egd (opt.egd_file);
if (RAND_status ())
return;
@ -99,20 +98,25 @@ ssl_init_prng (void)
return;
#endif
/* Still not enough randomness, most likely because neither
/dev/random nor EGD were available. Resort to a simple and
stupid method -- seed OpenSSL's PRNG with libc PRNG. This is
cryptographically weak, but people who care about strong
cryptography should install /dev/random (default on Linux) or
specify their own source of randomness anyway. */
#if 0 /* don't do this by default */
{
int maxrand = 500;
logprintf (LOG_VERBOSE, _("Warning: using a weak random seed.\n"));
/* Still not random enough, presumably because neither /dev/random
nor EGD were available. Try to seed OpenSSL's PRNG with libc
PRNG. This is cryptographically weak and defeats the purpose
of using OpenSSL, which is why it is highly discouraged. */
logprintf (LOG_VERBOSE, _("WARNING: using a weak random seed.\n"));
while (RAND_status () == 0 && maxrand-- > 0)
{
unsigned char rnd = random_number (256);
RAND_seed (&rnd, sizeof (rnd));
}
}
#endif
while (RAND_status () == 0 && maxrand-- > 0)
{
unsigned char rnd = random_number (256);
RAND_seed (&rnd, sizeof (rnd));
}
#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */
}
@ -120,20 +124,23 @@ static int
verify_callback (int ok, X509_STORE_CTX *ctx)
{
char *s, buf[256];
s = X509_NAME_oneline (X509_get_subject_name (ctx->current_cert), buf, 256);
if (ok == 0) {
switch (ctx->error) {
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_CERT_HAS_EXPIRED:
/* This mean the CERT is not valid !!! */
ok = 0;
break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
/* Unsure if we should handle that this way */
ok = 1;
break;
s = X509_NAME_oneline (X509_get_subject_name (ctx->current_cert),
buf, sizeof (buf));
if (ok == 0)
{
switch (ctx->error)
{
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_CERT_HAS_EXPIRED:
/* This mean the CERT is not valid !!! */
ok = 0;
break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
/* Unsure if we should handle that this way */
ok = 1;
break;
}
}
}
return ok;
}
@ -152,8 +159,6 @@ uerr_t
ssl_init ()
{
SSL_METHOD *meth = NULL;
int verify;
int can_validate;
if (ssl_ctx)
return 0;
@ -172,20 +177,20 @@ ssl_init ()
SSL_load_error_strings ();
SSLeay_add_all_algorithms ();
SSLeay_add_ssl_algorithms ();
switch (opt.sslprotocol)
switch (opt.secure_protocol)
{
default:
meth = SSLv23_client_method ();
break;
case 1 :
meth = SSLv2_client_method ();
break;
case 2 :
meth = SSLv3_client_method ();
break;
case 3 :
meth = TLSv1_client_method ();
break;
case secure_protocol_auto:
meth = SSLv23_client_method ();
break;
case secure_protocol_sslv2:
meth = SSLv2_client_method ();
break;
case secure_protocol_sslv3:
meth = SSLv3_client_method ();
break;
case secure_protocol_tlsv1:
meth = TLSv1_client_method ();
break;
}
if (meth == NULL)
{
@ -199,61 +204,41 @@ ssl_init ()
ssl_print_errors ();
return SSLERRCTXCREATE;
}
/* Can we validate the server Cert ? */
if (opt.sslcadir != NULL || opt.sslcafile != NULL)
{
SSL_CTX_load_verify_locations (ssl_ctx, opt.sslcafile, opt.sslcadir);
can_validate = 1;
}
else
{
can_validate = 0;
}
if (!opt.sslcheckcert)
{
/* check cert but ignore error, do not break handshake on error */
verify = SSL_VERIFY_NONE;
}
else
{
if (!can_validate)
{
logputs (LOG_NOTQUIET,
_("Warning: validation of server certificate not possible!\n"));
verify = SSL_VERIFY_NONE;
}
else
{
/* break handshake if server cert is not valid but allow
NO-Cert mode */
verify = SSL_VERIFY_PEER;
}
}
SSL_CTX_set_default_verify_paths (ssl_ctx);
SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);
SSL_CTX_set_verify (ssl_ctx,
opt.check_cert ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
verify_callback);
SSL_CTX_set_verify (ssl_ctx, verify, verify_callback);
if (opt.sslcertfile != NULL || opt.sslcertkey != NULL)
if (opt.cert_file != NULL || opt.cert_key != NULL)
{
int ssl_cert_type;
if (!opt.sslcerttype)
ssl_cert_type = SSL_FILETYPE_PEM;
else
ssl_cert_type = SSL_FILETYPE_ASN1;
switch (opt.cert_type)
{
case cert_type_pem:
ssl_cert_type = SSL_FILETYPE_PEM;
break;
case cert_type_asn1:
ssl_cert_type = SSL_FILETYPE_ASN1;
break;
}
if (opt.sslcertkey == NULL)
opt.sslcertkey = opt.sslcertfile;
if (opt.sslcertfile == NULL)
opt.sslcertfile = opt.sslcertkey;
#if 0 /* what was this supposed to achieve? */
if (opt.cert_key == NULL)
opt.cert_key = opt.cert_file;
if (opt.cert_file == NULL)
opt.cert_file = opt.cert_key;
#endif
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.sslcertfile,
ssl_cert_type) <= 0)
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
ssl_cert_type) != 1)
{
ssl_print_errors ();
return SSLERRCERTFILE;
}
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.sslcertkey,
ssl_cert_type) <= 0)
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.cert_key,
ssl_cert_type) != 1)
{
ssl_print_errors ();
return SSLERRCERTKEY;

View File

@ -1197,14 +1197,14 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
/* try without certfile */
logprintf (LOG_NOTQUIET,
_("Failed to load certificates from %s\n"),
opt.sslcertfile);
opt.cert_file);
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);
opt.cert_key);
logprintf (LOG_NOTQUIET,
_("Trying without the specified certificate\n"));
break;

View File

@ -84,6 +84,9 @@ CMD_DECLARE (cmd_directory);
CMD_DECLARE (cmd_time);
CMD_DECLARE (cmd_vector);
#ifdef HAVE_SSL
CMD_DECLARE (cmd_spec_cert_type);
#endif
CMD_DECLARE (cmd_spec_dirstruct);
CMD_DECLARE (cmd_spec_header);
CMD_DECLARE (cmd_spec_htmlify);
@ -92,6 +95,9 @@ CMD_DECLARE (cmd_spec_prefer_family);
CMD_DECLARE (cmd_spec_progress);
CMD_DECLARE (cmd_spec_recursive);
CMD_DECLARE (cmd_spec_restrict_file_names);
#ifdef HAVE_SSL
CMD_DECLARE (cmd_spec_secure_protocol);
#endif
CMD_DECLARE (cmd_spec_timeout);
CMD_DECLARE (cmd_spec_useragent);
@ -115,7 +121,17 @@ static struct {
{ "backups", &opt.backups, cmd_number },
{ "base", &opt.base_href, cmd_string },
{ "bindaddress", &opt.bind_address, cmd_string },
#ifdef HAVE_SSL
{ "cacertificate", &opt.ca_cert, cmd_file },
#endif
{ "cache", &opt.allow_cache, cmd_boolean },
#ifdef HAVE_SSL
{ "cadirectory", &opt.ca_directory, cmd_directory },
{ "certificate", &opt.cert_file, cmd_file },
{ "certificatekey", &opt.cert_key, cmd_file },
{ "certificatetype", &opt.cert_type, cmd_spec_cert_type },
{ "checkcertificate", &opt.check_cert, cmd_boolean },
#endif
{ "connecttimeout", &opt.connect_timeout, cmd_time },
{ "continue", &opt.always_rest, cmd_boolean },
{ "convertlinks", &opt.convert_links, cmd_boolean },
@ -135,7 +151,7 @@ static struct {
{ "dotspacing", &opt.dot_spacing, cmd_number },
{ "dotstyle", &opt.dot_style, cmd_string },
#ifdef HAVE_SSL
{ "egdfile", &opt.sslegdsock, cmd_file },
{ "egdfile", &opt.egd_file, cmd_file },
#endif
{ "excludedirectories", &opt.excludes, cmd_directory_vector },
{ "excludedomains", &opt.exclude_domains, cmd_vector },
@ -200,18 +216,12 @@ static struct {
{ "robots", &opt.use_robots, cmd_boolean },
{ "savecookies", &opt.cookies_output, cmd_file },
{ "saveheaders", &opt.save_headers, cmd_boolean },
#ifdef HAVE_SSL
{ "secureprotocol", &opt.secure_protocol, cmd_spec_secure_protocol },
#endif
{ "serverresponse", &opt.server_response, cmd_boolean },
{ "spanhosts", &opt.spanhost, cmd_boolean },
{ "spider", &opt.spider, cmd_boolean },
#ifdef HAVE_SSL
{ "sslcadir", &opt.sslcadir, cmd_directory },
{ "sslcafile", &opt.sslcafile, cmd_file },
{ "sslcertfile", &opt.sslcertfile, cmd_file },
{ "sslcertkey", &opt.sslcertkey, cmd_file },
{ "sslcerttype", &opt.sslcerttype, cmd_number },
{ "sslcheckcert", &opt.sslcheckcert, cmd_number },
{ "sslprotocol", &opt.sslprotocol, cmd_number },
#endif /* HAVE_SSL */
{ "strictcomments", &opt.strict_comments, cmd_boolean },
{ "timeout", NULL, cmd_spec_timeout },
{ "timestamping", &opt.timestamping, cmd_boolean },
@ -289,6 +299,10 @@ defaults (void)
opt.dns_cache = 1;
opt.ftp_pasv = 1;
#ifdef HAVE_SSL
opt.check_cert = 1;
#endif
/* The default for file name restriction defaults to the OS type. */
#if !defined(WINDOWS) && !defined(__CYGWIN__)
opt.restrict_files_os = restrict_unix;
@ -1016,6 +1030,28 @@ cmd_time (const char *com, const char *val, void *closure)
options specially. */
static int check_user_specified_header PARAMS ((const char *));
/* Forward decl */
struct decode_item {
const char *name;
int code;
};
static int decode_string PARAMS ((const char *, const struct decode_item *,
int, int *));
#ifdef HAVE_SSL
static int
cmd_spec_cert_type (const char *com, const char *val, void *closure)
{
static const struct decode_item choices[] = {
{ "pem", cert_type_pem },
{ "asn1", cert_type_asn1 },
};
int ok = decode_string (val, choices, countof (choices), closure);
if (!ok)
fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
return ok;
}
#endif
static int
cmd_spec_dirstruct (const char *com, const char *val, void *closure)
@ -1080,24 +1116,16 @@ cmd_spec_mirror (const char *com, const char *val, void *closure)
static int
cmd_spec_prefer_family (const char *com, const char *val, void *closure)
{
if (0 == strcasecmp (val, "ipv4"))
{
opt.prefer_family = prefer_ipv4;
return 1;
}
else if (0 == strcasecmp (val, "ipv6"))
{
opt.prefer_family = prefer_ipv6;
return 1;
}
else if (0 == strcasecmp (val, "none"))
{
opt.prefer_family = prefer_none;
return 1;
}
fprintf (stderr, _("%s: %s: Invalid preferred family `%s'.\n"),
exec_name, com, val);
return 0;
static const struct decode_item choices[] = {
{ "IPv4", prefer_ipv4 },
{ "IPv6", prefer_ipv6 },
{ "none", prefer_none },
};
int ok = decode_string (val, choices, countof (choices),
(int *) &opt.prefer_family);
if (!ok)
fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
return ok;
}
/* Set progress.type to VAL, but verify that it's a valid progress
@ -1179,6 +1207,23 @@ cmd_spec_restrict_file_names (const char *com, const char *val, void *closure)
return 1;
}
#ifdef HAVE_SSL
static int
cmd_spec_secure_protocol (const char *com, const char *val, void *closure)
{
static const struct decode_item choices[] = {
{ "auto", secure_protocol_auto },
{ "sslv2", secure_protocol_sslv2 },
{ "sslv3", secure_protocol_sslv3 },
{ "tlsv1", secure_protocol_tlsv1 },
};
int ok = decode_string (val, choices, countof (choices), closure);
if (!ok)
fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"), exec_name, com, val);
return ok;
}
#endif
/* Set all three timeout values. */
static int
@ -1312,6 +1357,10 @@ simple_atof (const char *beg, const char *end, double *dest)
return 1;
}
/* Verify that the user-specified header in S is valid. It must
contain a colon preceded by non-white-space characters and must not
contain newlines. */
static int
check_user_specified_header (const char *s)
{
@ -1327,6 +1376,23 @@ check_user_specified_header (const char *s)
return 0;
return 1;
}
/* Decode VAL into a number, according to ITEMS. */
static int
decode_string (const char *val, const struct decode_item *items, int itemcount,
int *place)
{
int i;
for (i = 0; i < itemcount; i++)
if (0 == strcasecmp (val, items[i].name))
{
*place = items[i].code;
return 1;
}
return 0;
}
void cleanup_html_url PARAMS ((void));
void http_cleanup PARAMS ((void));

View File

@ -157,7 +157,13 @@ struct cmdline_option option_data[] =
{ "backups", 0, OPT_BOOLEAN, "backups", -1 },
{ "base", 'B', OPT_VALUE, "base", -1 },
{ "bind-address", 0, OPT_VALUE, "bindaddress", -1 },
{ IF_SSL ("ca-certificate"), 0, OPT_VALUE, "cacertificate", -1 },
{ IF_SSL ("ca-directory"), 0, OPT_VALUE, "cadirectory", -1 },
{ "cache", 0, OPT_BOOLEAN, "cache", -1 },
{ IF_SSL ("certificate"), 0, OPT_VALUE, "certificate", -1 },
{ IF_SSL ("certificate-key"), 0, OPT_VALUE, "certificatekey", -1 },
{ IF_SSL ("certificate-type"), 0, OPT_VALUE, "certificatetype", -1 },
{ IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 },
{ "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
{ "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 },
{ "continue", 'c', OPT_BOOLEAN, "continue", -1 },
@ -219,7 +225,7 @@ struct cmdline_option option_data[] =
{ "progress", 0, OPT_VALUE, "progress", -1 },
{ "protocol-directories", 0, OPT_BOOLEAN, "protocoldirectories", -1 },
{ "proxy", 0, OPT_BOOLEAN, "useproxy", -1 },
{ "_proxy-compat", 'Y', OPT_VALUE, "useproxy", -1 }, /* back-compatible */
{ "proxy__compat", 'Y', OPT_VALUE, "useproxy", -1 }, /* back-compatible */
{ "proxy-passwd", 0, OPT_VALUE, "proxypasswd", -1 },
{ "proxy-user", 0, OPT_VALUE, "proxyuser", -1 },
{ "quiet", 'q', OPT_BOOLEAN, "quiet", -1 },
@ -236,16 +242,10 @@ struct cmdline_option option_data[] =
{ "retry-connrefused", 0, OPT_BOOLEAN, "retryconnrefused", -1 },
{ "save-cookies", 0, OPT_VALUE, "savecookies", -1 },
{ "save-headers", 0, OPT_BOOLEAN, "saveheaders", -1 },
{ IF_SSL ("secure-protocol"), 0, OPT_VALUE, "secureprotocol", -1 },
{ "server-response", 'S', OPT_BOOLEAN, "serverresponse", -1 },
{ "span-hosts", 'H', OPT_BOOLEAN, "spanhosts", -1 },
{ "spider", 0, OPT_BOOLEAN, "spider", -1 },
{ IF_SSL ("sslcadir"), 0, OPT_VALUE, "sslcadir", -1 },
{ IF_SSL ("sslcafile"), 0, OPT_VALUE, "sslcafile", -1 },
{ IF_SSL ("sslcertfile"), 0, OPT_VALUE, "sslcertfile", -1 },
{ IF_SSL ("sslcertkey"), 0, OPT_VALUE, "sslcertkey", -1 },
{ IF_SSL ("sslcerttype"), 0, OPT_VALUE, "sslcerttype", -1 },
{ IF_SSL ("sslcheckcert"), 0, OPT_VALUE, "sslcheckcert", -1 },
{ IF_SSL ("sslprotocol"), 0, OPT_VALUE, "sslprotocol", -1 },
{ "strict-comments", 0, OPT_BOOLEAN, "strictcomments", -1 },
{ "timeout", 'T', OPT_VALUE, "timeout", -1 },
{ "timestamping", 'N', OPT_BOOLEAN, "timestamping", -1 },
@ -532,24 +532,24 @@ HTTP options:\n"),
#ifdef HAVE_SSL
N_("\
HTTPS (SSL) options:\n"),
HTTPS (SSL/TLS) options:\n"),
N_("\
--sslcertfile=FILE optional client certificate.\n"),
--secure-protocol=PR choose SSL protocol, one of auto, SSLv2, SSLv3,\n\
and TLSv1.\n"),
N_("\
--sslcertkey=KEYFILE optional keyfile for this certificate.\n"),
--no-check-certificate don't validate the server's certificate.\n"),
N_("\
--sslcadir=DIR dir where hash list of CA's are stored.\n"),
--certificate=FILE client certificate file.\n"),
N_("\
--sslcafile=FILE file with bundle of CA's.\n"),
--certificate-key=FILE optional key file for this certificate.\n"),
N_("\
--sslcerttype=0/1 Client-Cert type 0=PEM (default) / 1=ASN1 (DER).\n"),
--certificate-type=TYPE client certificate type, PEM or ASN1.\n"),
N_("\
--sslcheckcert=0/1 Check the server cert against given CA.\n"),
--sslcadir=DIR dir where hash list of CA's are stored.\n"),
N_("\
--sslprotocol=0-3 choose SSL protocol; 0=automatic,\n\
1=SSLv2 2=SSLv3 3=TLSv1.\n"),
--sslcafile=FILE file with bundle of CA's.\n"),
N_("\
--egd-file=FILE file name of the EGD socket.\n"),
--egd-file=FILE file name of the EGD socket.\n"),
"\n",
#endif /* HAVE_SSL */

View File

@ -157,17 +157,29 @@ struct options
int page_requisites; /* Whether we need to download all files
necessary to display a page properly. */
char *bind_address; /* What local IP address to bind to. */
#ifdef HAVE_SSL
char *sslcadir; /* CA directory (hash files) */
char *sslcafile; /* CA File to use */
char *sslcertfile; /* external client cert to use. */
char *sslcertkey; /* the keyfile for this certificate
enum {
secure_protocol_auto,
secure_protocol_sslv2,
secure_protocol_sslv3,
secure_protocol_tlsv1
} secure_protocol; /* type of secure protocol to use. */
int check_cert; /* whether to validate the server's cert */
char *cert_file; /* external client certificate to use. */
char *cert_key; /* the keyfile for this certificate
(if not internal) included in the
certfile. */
int sslcerttype; /* 0 = PEM / 1=ASN1 (DER) */
int sslcheckcert; /* 0 do not check / 1 check server cert */
char *sslegdsock; /* optional socket of the egd daemon */
int sslprotocol; /* 0 = auto / 1 = v2 / 2 = v3 / 3 = TLSv1 */
enum {
cert_type_pem,
cert_type_asn1
} cert_type; /* type of client certificate */
char *ca_directory; /* CA directory (hash files) */
char *ca_cert; /* CA certificate file to use */
char *egd_file; /* file name of the egd daemon socket */
#endif /* HAVE_SSL */
int cookies; /* whether cookies are used. */