]> sjero.net Git - wget/commitdiff
[svn] Applied Christian Fraenkel's patch "custom certificate patch for wget-1.7+dev;
authorhniksic <devnull@localhost>
Sat, 10 Feb 2001 22:33:31 +0000 (14:33 -0800)
committerhniksic <devnull@localhost>
Sat, 10 Feb 2001 22:33:31 +0000 (14:33 -0800)
2nd try", published in <200102082132220160.00474E73@pop.gmx.net>.
It adds two options for custom certificates.

src/ChangeLog
src/gen_sslfunc.c
src/gen_sslfunc.h
src/http.c
src/init.c
src/main.c
src/options.h
src/wget.h

index 7c9eeea9addb275ff51962581d98bb3d91268a71..d505b4c5bafd8e10bb072d599d84635f124b7447 100644 (file)
@@ -1,3 +1,19 @@
+2001-02-08  Christian Fraenkel <christian.fraenkel@gmx.net>
+
+        * 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
+
+        * http.c (gethttp): abort when init_ssl fails
+
 2001-01-23  Herold Heiko  <Heiko.Herold@previnet.it>
 
        * mswindows.h: Include <malloc.h>; it's needed for alloca().
index 8b64b581e106945a1dad379a408c3eca178a699f..c19cc66fe08d0af64e9e272b143a5d55ce1df66f 100644 (file)
@@ -32,8 +32,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <openssl/err.h>
 #include <openssl/pem.h>
 
-#define SSL_ERR_CTX_CREATION -2
-
 #include "wget.h"
 #include "connect.h"
 
@@ -41,11 +39,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 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,18 @@ init_ssl (SSL_CTX **ctx)
   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 +115,23 @@ 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) 
+{
+  int ocerr = 0;
+  unsigned long curerr = 0;
+  char errbuff[1024];
+  memset(errbuff, 0, sizeof(errbuff));
+  for (curerr = ERR_get_error (); curerr; curerr = ERR_get_error ())
+    {
+      DEBUGP (("OpenSSL: %s\n", ERR_error_string (curerr, errbuff)));
+      ++ocerr;
+    }
+  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
index 066ebfed14400d39628c6a326a781a1aae23df89..fdd3da1a1784e1c2fd93a829737326f9d14ee81a 100644 (file)
@@ -28,4 +28,5 @@ void free_ssl_ctx PARAMS ((SSL_CTX *));
 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)); 
 
index 0d81a30d1afe2c09f178e06043141e12b6a45c30..b8151ea2f751cbbf280aa26502478e89709b7421 100644 (file)
@@ -536,9 +536,41 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
   int inhibit_keep_alive;
 
 #ifdef HAVE_SSL
-/* initialize ssl_ctx on first run */
+  /* initialize ssl_ctx on first run */
   if (!ssl_ctx)
-    init_ssl (&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 +1449,8 @@ File `%s' already there, will not retrieve.\n"), u->local);
          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! */
index 900f807d4ce8084e7b8e5e6fb8af89fcbe2ce536..321f50d4bf7d63ada9e695b2f6f898c6e989acda 100644 (file)
@@ -161,6 +161,10 @@ static struct {
   { "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 @@ cleanup (void)
   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 */
 }
index d6a19bfdbaaf314f5faa84cba04cebcc024f15a5..275605ca58cef7264eff79dcf634ce8d00584158 100644 (file)
@@ -150,6 +150,8 @@ Logging and input file:\n\
   -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=FILE     optional client certificate.\n\
+       --sslcertkey=KEYFILE   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 @@ main (int argc, char *const *argv)
     { "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 @@ GNU General Public License for more details.\n"));
        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;
index 7c1fac51a46f0d58d2c4a4d7cbe8291af6512fb3..13b0bf20e41adb426498f318669cd7e00854b0f7 100644 (file)
@@ -153,6 +153,13 @@ struct options
                                   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
index 42964411bdd9c6dff2bbd777c686deb3b691bfd9..86fa953d99f69807d797bb6d87ea4979de5f6c2f 100644 (file)
@@ -257,7 +257,8 @@ typedef enum
   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;