Hi!
Well, this is essentially the same patch. It just fixes
a few bugs (some cosmetical, some realy stupid) and
adds more detailed ssl debuging in the debug output.
Christian
NEWS:
** one can now specify a client certificate for ssl connections
src/ChangeLog:
2001-02-08 Christian Fraenkel <[EMAIL PROTECTED]>
* gen_sslfunc.c: verify_callback is now static
* gen_sslfunc.c (init_ssl): load certificate if specified
* gen_sslfunc.c (ssl_printerr): new function
* init.c: added new --sslcertfile and --sslcertkey switches
* main.c: ditto
* options.h: ditto
* html.c (gethttp): abort when init_ssl fails
diff -ur base/src/gen_sslfunc.c wget-1.7+dev-cert/src/gen_sslfunc.c
--- base/src/gen_sslfunc.c Tue Jan 2 12:07:27 2001
+++ wget-1.7+dev-cert/src/gen_sslfunc.c Thu Feb 1 15:08:54 2001
@@ -32,8 +32,6 @@
#include <openssl/err.h>
#include <openssl/pem.h>
-#define SSL_ERR_CTX_CREATION -2
-
#include "wget.h"
#include "connect.h"
@@ -41,11 +39,10 @@
extern int errno;
#endif
-/* #### Shouldn't this be static? --hniksic */
-int verify_callback PARAMS ((int, X509_STORE_CTX *));
+static int verify_callback PARAMS ((int, X509_STORE_CTX *));
/* Creates a SSL Context and sets some defaults for it */
-int
+uerr_t
init_ssl (SSL_CTX **ctx)
{
SSL_METHOD *meth = NULL;
@@ -57,7 +54,16 @@
meth = SSLv23_client_method ();
*ctx = SSL_CTX_new (meth);
SSL_CTX_set_verify (*ctx, verify, verify_callback);
- if (*ctx == NULL) return SSL_ERR_CTX_CREATION;
+ if (*ctx == NULL) return SSLERRCTXCREATE;
+ if (opt.sslcertfile)
+ {
+ if (SSL_CTX_use_certificate_file(*ctx, opt.sslcertfile, SSL_FILETYPE_PEM) <=
+0)
+ return SSLERRCERTFILE;
+ if (opt.sslcertkey == NULL)
+ opt.sslcertkey=opt.sslcertfile;
+ if (SSL_CTX_use_PrivateKey_file(*ctx, opt.sslcertkey, SSL_FILETYPE_PEM) <= 0)
+ return SSLERRCERTKEY;
+ }
return 0; /* Succeded */
}
@@ -107,6 +113,25 @@
return ok;
}
+/* pass all ssl errors to DEBUGP
+ returns the number of printed errors */
+int
+ssl_printerrors (void)
+{
+ int ocerr=0;
+ unsigned long curerr=0;
+ char errbuff[1024], debbuff[1024];
+ memset(errbuff, 0, 1024);
+ curerr=ERR_get_error();
+ while (curerr != 0)
+ {
+ sprintf (debbuff, "OpenSSL: %s\n", ERR_error_string (curerr, errbuff));
+ DEBUGP ((debbuff));
+ ocerr++;
+ curerr=ERR_get_error();
+ }
+ return ocerr;
+}
/* SSL version of iread. Only exchanged read for SSL_read
Read at most LEN bytes from FD, storing them to BUF. This is
virtually the same as read(), but takes care of EINTR braindamage
diff -ur base/src/gen_sslfunc.h wget-1.7+dev-cert/src/gen_sslfunc.h
--- base/src/gen_sslfunc.h Wed Dec 6 00:35:55 2000
+++ wget-1.7+dev-cert/src/gen_sslfunc.h Tue Jan 30 21:16:28 2001
@@ -28,4 +28,5 @@
int verify_callback PARAMS ((int, X509_STORE_CTX *));
int ssl_iread PARAMS ((SSL *, char *, int));
int ssl_iwrite PARAMS ((SSL *, char *, int));
+int ssl_printerrors PARAMS ((void));
diff -ur base/src/http.c wget-1.7+dev-cert/src/http.c
--- base/src/http.c Tue Jan 2 12:07:27 2001
+++ wget-1.7+dev-cert/src/http.c Thu Feb 1 12:40:34 2001
@@ -537,8 +537,31 @@
#ifdef HAVE_SSL
/* initialize ssl_ctx on first run */
- if (!ssl_ctx)
- init_ssl (&ssl_ctx);
+ if (!ssl_ctx) {
+ 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;
+ }
+ }
+ }
#endif /* HAVE_SSL */
if (!(*dt & HEAD_ONLY))
@@ -1417,7 +1440,8 @@
printwhat (count, opt.ntry);
continue;
break;
- case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
+ case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED:
+ case SSLERRCTXCREATE:
/* Fatal errors just return from the function. */
FREEHSTAT (hstat);
xfree (filename_plus_orig_suffix); /* must precede every return! */
diff -ur base/src/init.c wget-1.7+dev-cert/src/init.c
--- base/src/init.c Tue Jan 2 12:07:27 2001
+++ wget-1.7+dev-cert/src/init.c Tue Jan 30 14:31:52 2001
@@ -161,6 +161,10 @@
{ "simplehostcheck", &opt.simple_check, cmd_boolean },
{ "spanhosts", &opt.spanhost, cmd_boolean },
{ "spider", &opt.spider, cmd_boolean },
+#ifdef HAVE_SSL
+ { "sslcertfile", &opt.sslcertfile, cmd_string },
+ { "sslcertkey", &opt.sslcertkey, cmd_string },
+#endif /* HAVE_SSL */
{ "timeout", &opt.timeout, cmd_time },
{ "timestamping", &opt.timestamping, cmd_boolean },
{ "tries", &opt.ntry, cmd_number_inf },
@@ -1014,4 +1018,8 @@
FREE_MAYBE (opt.http_user);
FREE_MAYBE (opt.http_passwd);
FREE_MAYBE (opt.user_header);
+#ifdef HAVE_SSL
+ FREE_MAYBE (opt.sslcertkey);
+ FREE_MAYBE (opt.sslcertfile);
+#endif /* HAVE_SSL */
}
diff -ur base/src/main.c wget-1.7+dev-cert/src/main.c
--- base/src/main.c Mon Jan 29 21:29:37 2001
+++ wget-1.7+dev-cert/src/main.c Tue Jan 30 14:34:00 2001
@@ -150,6 +150,8 @@
-i, --input-file=FILE download URLs found in FILE.\n\
-F, --force-html treat input file as HTML.\n\
-B, --base=URL prepends URL to relative links in -F -i file.\n\
+ --sslcertfile optional client certificate \n\
+ --sslcertkey optional keyfile for this certificate \n\
\n"), _("\
Download:\n\
--bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host.\n\
@@ -303,6 +305,10 @@
{ "user-agent", required_argument, NULL, 'U' },
{ "referer", required_argument, NULL, 129 },
{ "use-proxy", required_argument, NULL, 'Y' },
+#ifdef HAVE_SSL
+ { "sslcertfile", required_argument, NULL, 132},
+ { "sslcertkey", required_argument, NULL, 133},
+#endif /* HAVE_SSL */
{ "wait", required_argument, NULL, 'w' },
{ "waitretry", required_argument, NULL, 24 },
{ 0, 0, 0, 0 }
@@ -506,6 +512,14 @@
case 129:
setval ("referer", optarg);
break;
+#ifdef HAVE_SSL
+ case 132:
+ setval ("sslcertfile", optarg);
+ break;
+ case 133:
+ setval ("sslcertkey", optarg);
+ break;
+#endif /* HAVE_SSL */
case 'A':
setval ("accept", optarg);
break;
diff -ur base/src/options.h wget-1.7+dev-cert/src/options.h
--- base/src/options.h Tue Jan 2 12:07:27 2001
+++ wget-1.7+dev-cert/src/options.h Tue Jan 30 14:30:54 2001
@@ -153,6 +153,12 @@
necessary to display a page properly. */
struct sockaddr_in *bind_address; /* What local IP address to bind to. */
+
+#ifdef HAVE_SSL
+ char * sslcertfile; /* external client cert to use. */
+ char * sslcertkey; /* the keyfile for this certificate
+ (if not internal) included in the certfile */
+#endif /* HAVE_SSL */
};
#ifndef OPTIONS_DEFINED_HERE
diff -ur base/src/wget.h wget-1.7+dev-cert/src/wget.h
--- base/src/wget.h Tue Jan 2 12:07:27 2001
+++ wget-1.7+dev-cert/src/wget.h Tue Jan 30 13:34:19 2001
@@ -257,7 +257,8 @@
FTPINVPASV, FTPNOPASV,
RETRFINISHED, READERR, TRYLIMEXC, URLBADPATTERN,
FILEBADFILE, RANGEERR, RETRBADPATTERN, RETNOTSUP,
- ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED
+ ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED,
+ SSLERRCERTFILE,SSLERRCERTKEY,SSLERRCTXCREATE
} uerr_t;
typedef unsigned char boolean;