[packages/wget] - rel 5; honour timeout for ssl connections (fix from git)

arekm arekm at pld-linux.org
Sat Jan 18 14:14:01 CET 2014


commit 7ed1e99770abbb8c1ed079da6a5d33dd4e43d456
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Sat Jan 18 14:13:59 2014 +0100

    - rel 5; honour timeout for ssl connections (fix from git)

 wget-ssl-timeout.patch | 281 +++++++++++++++++++++++++++++++++++++++++++++++++
 wget.spec              |   4 +-
 2 files changed, 284 insertions(+), 1 deletion(-)
---
diff --git a/wget.spec b/wget.spec
index 70cf5ff..3879a89 100644
--- a/wget.spec
+++ b/wget.spec
@@ -17,7 +17,7 @@ Summary(uk.UTF-8):	Утиліта для отримання файлів по п
 Summary(zh_CN.UTF-8):	[通讯]功能强大的下载程序,支持断点续传
 Name:		wget
 Version:	1.14
-Release:	4
+Release:	5
 License:	GPL v3+ with OpenSSL exception
 Group:		Networking/Utilities
 Source0:	http://ftp.gnu.org/gnu/wget/%{name}-%{version}.tar.xz
@@ -29,6 +29,7 @@ Patch1:		%{name}-wgetrc_path.patch
 Patch2:		%{name}-home_etc.patch
 Patch3:		%{name}-ssl-certs.patch
 Patch4:		%{name}-pod.patch
+Patch5:		%{name}-ssl-timeout.patch
 URL:		http://www.gnu.org/software/wget/
 BuildRequires:	autoconf >= 2.61
 BuildRequires:	automake >= 1:1.9
@@ -122,6 +123,7 @@ Proxy серверів, настроюваність.
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
 %{__rm} doc/wget.info doc/sample.wgetrc.munged_for_texi_inclusion po/stamp-po
 
 # temp hack for 1.13.4
diff --git a/wget-ssl-timeout.patch b/wget-ssl-timeout.patch
new file mode 100644
index 0000000..57aec9d
--- /dev/null
+++ b/wget-ssl-timeout.patch
@@ -0,0 +1,281 @@
+From ae80fd2ec75fafdbec9895b9d973f2966209d588 Mon Sep 17 00:00:00 2001
+From: mancha <mancha1 at hush.com>
+Date: Sun, 05 May 2013 05:16:58 +0000
+Subject: gnutls: do not abort on non-fatal alerts during handshake
+
+Signed-off-by: mancha <mancha1 at hush.com>
+---
+(limited to 'src/gnutls.c')
+
+diff --git a/src/gnutls.c b/src/gnutls.c
+index 769b005..54422fc 100644
+--- a/src/gnutls.c
++++ b/src/gnutls.c
+@@ -376,8 +376,9 @@ ssl_connect_wget (int fd, const char *hostname)
+ {
+   struct wgnutls_transport_context *ctx;
+   gnutls_session_t session;
+-  int err;
++  int err,alert;
+   gnutls_init (&session, GNUTLS_CLIENT);
++  const char *str;
+ 
+   /* We set the server name but only if it's not an IP address. */
+   if (! is_valid_ip_address (hostname))
+@@ -440,10 +441,28 @@ ssl_connect_wget (int fd, const char *hostname)
+       return false;
+     }
+ 
+-  err = gnutls_handshake (session);
++  /* We don't stop the handshake process for non-fatal errors */
++  do
++    {
++      err = gnutls_handshake (session);
++      if (err < 0)
++        {
++          logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
++          if (err == GNUTLS_E_WARNING_ALERT_RECEIVED ||
++              err == GNUTLS_E_FATAL_ALERT_RECEIVED)
++            {
++              alert = gnutls_alert_get (session);
++              str = gnutls_alert_get_name (alert);
++              if (str == NULL)
++                str = "(unknown)";
++              logprintf (LOG_NOTQUIET, "GnuTLS: received alert [%d]: %s\n", alert, str);
++            }
++        }
++    }
++  while (err == GNUTLS_E_WARNING_ALERT_RECEIVED && gnutls_error_is_fatal (err) == 0);
++
+   if (err < 0)
+     {
+-      logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
+       gnutls_deinit (session);
+       return false;
+     }
+--
+cgit v0.9.0.2
+From 91f0f99e9a607cc72cd5dc8aa1f57a299f30948e Mon Sep 17 00:00:00 2001
+From: Tim Ruehsen <tim.ruehsen at gmx.de>
+Date: Thu, 11 Jul 2013 12:29:20 +0000
+Subject: gnutls: honor connect timeout
+
+---
+diff --git a/src/gnutls.c b/src/gnutls.c
+index 54422fc..06f9020 100644
+--- a/src/gnutls.c
++++ b/src/gnutls.c
+@@ -374,6 +374,9 @@ static struct transport_implementation wgnutls_transport =
+ bool
+ ssl_connect_wget (int fd, const char *hostname)
+ {
++#ifdef F_GETFL
++  int flags = 0;
++#endif
+   struct wgnutls_transport_context *ctx;
+   gnutls_session_t session;
+   int err,alert;
+@@ -441,11 +444,54 @@ ssl_connect_wget (int fd, const char *hostname)
+       return false;
+     }
+ 
++  if (opt.connect_timeout)
++    {
++#ifdef F_GETFL
++      flags = fcntl (fd, F_GETFL, 0);
++      if (flags < 0)
++        return flags;
++      if (fcntl (fd, F_SETFL, flags | O_NONBLOCK))
++        return -1;
++#else
++      /* XXX: Assume it was blocking before.  */
++      const int one = 1;
++      if (ioctl (fd, FIONBIO, &one) < 0)
++        return -1;
++#endif
++    }
++
+   /* We don't stop the handshake process for non-fatal errors */
+   do
+     {
+       err = gnutls_handshake (session);
+-      if (err < 0)
++
++      if (opt.connect_timeout && err == GNUTLS_E_AGAIN)
++        {
++          if (gnutls_record_get_direction (session))
++            {
++              /* wait for writeability */
++              err = select_fd (fd, opt.connect_timeout, WAIT_FOR_WRITE);
++            }
++          else
++            {
++              /* wait for readability */
++              err = select_fd (fd, opt.connect_timeout, WAIT_FOR_READ);
++            }
++
++          if (err <= 0)
++            {
++              if (err == 0)
++                {
++                  errno = ETIMEDOUT;
++                  err = -1;
++                }
++              break;
++            }
++
++          if (err <= 0)
++            break;
++        }
++      else if (err < 0)
+         {
+           logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err));
+           if (err == GNUTLS_E_WARNING_ALERT_RECEIVED ||
+@@ -461,6 +507,18 @@ ssl_connect_wget (int fd, const char *hostname)
+     }
+   while (err == GNUTLS_E_WARNING_ALERT_RECEIVED && gnutls_error_is_fatal (err) == 0);
+ 
++  if (opt.connect_timeout)
++    {
++#ifdef F_GETFL
++      if (fcntl (fd, F_SETFL, flags) < 0)
++        return -1;
++#else
++      const int zero = 0;
++      if (ioctl (fd, FIONBIO, &zero) < 0)
++        return -1;
++#endif
++    }
++
+   if (err < 0)
+     {
+       gnutls_deinit (session);
+--
+cgit v0.9.0.2
+From b8f036d16c508efde5bacfab9a96d8b6c6aeeeb2 Mon Sep 17 00:00:00 2001
+From: Karsten Hopp <karsten at redhat.com>
+Date: Thu, 11 Jul 2013 09:27:35 +0000
+Subject: Fix timeout option when used with SSL
+
+Previously wget didn't honor the --timeout option if the remote host did
+not answer SSL handshake
+
+Signed-off-by: Tomas Hozza <thozza at redhat.com>
+---
+diff --git a/src/openssl.c b/src/openssl.c
+index 3924e41..e2eec4f 100644
+--- a/src/openssl.c
++++ b/src/openssl.c
+@@ -251,24 +251,50 @@ ssl_init (void)
+   return false;
+ }
+ 
+-struct openssl_transport_context {
++struct openssl_transport_context
++{
+   SSL *conn;                    /* SSL connection handle */
+   char *last_error;             /* last error printed with openssl_errstr */
+ };
+ 
+-static int
+-openssl_read (int fd, char *buf, int bufsize, void *arg)
++struct openssl_read_args
+ {
+-  int ret;
+-  struct openssl_transport_context *ctx = arg;
++  int fd;
++  struct openssl_transport_context *ctx;
++  char *buf;
++  int bufsize;
++  int retval;
++};
++
++static void openssl_read_callback(void *arg)
++{
++  struct openssl_read_args *args = (struct openssl_read_args *) arg;
++  struct openssl_transport_context *ctx = args->ctx;
+   SSL *conn = ctx->conn;
++  char *buf = args->buf;
++  int bufsize = args->bufsize;
++  int ret;
++
+   do
+     ret = SSL_read (conn, buf, bufsize);
+-  while (ret == -1
+-         && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
++  while (ret == -1 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
+          && errno == EINTR);
++  args->retval = ret;
++}
+ 
+-  return ret;
++static int
++openssl_read (int fd, char *buf, int bufsize, void *arg)
++{
++  struct openssl_read_args args;
++  args.fd = fd;
++  args.buf = buf;
++  args.bufsize = bufsize;
++  args.ctx = (struct openssl_transport_context*) arg;
++
++  if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) {
++    return -1;
++  }
++  return args.retval;
+ }
+ 
+ static int
+@@ -386,6 +412,19 @@ static struct transport_implementation openssl_transport = {
+   openssl_peek, openssl_errstr, openssl_close
+ };
+ 
++struct scwt_context
++{
++  SSL *ssl;
++  int result;
++};
++
++static void
++ssl_connect_with_timeout_callback(void *arg)
++{
++  struct scwt_context *ctx = (struct scwt_context *)arg;
++  ctx->result = SSL_connect(ctx->ssl);
++}
++
+ /* Perform the SSL handshake on file descriptor FD, which is assumed
+    to be connected to an SSL server.  The SSL handle provided by
+    OpenSSL is registered with the file descriptor FD using
+@@ -398,6 +437,7 @@ bool
+ ssl_connect_wget (int fd, const char *hostname)
+ {
+   SSL *conn;
++  struct scwt_context scwt_ctx;
+   struct openssl_transport_context *ctx;
+ 
+   DEBUGP (("Initiating SSL handshake.\n"));
+@@ -425,7 +465,14 @@ ssl_connect_wget (int fd, const char *hostname)
+   if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
+     goto error;
+   SSL_set_connect_state (conn);
+-  if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
++
++  scwt_ctx.ssl = conn;
++  if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback,
++                       &scwt_ctx)) {
++    DEBUGP (("SSL handshake timed out.\n"));
++    goto timeout;
++  }
++  if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
+     goto error;
+ 
+   ctx = xnew0 (struct openssl_transport_context);
+@@ -441,6 +488,7 @@ ssl_connect_wget (int fd, const char *hostname)
+  error:
+   DEBUGP (("SSL handshake failed.\n"));
+   print_errors ();
++ timeout:
+   if (conn)
+     SSL_free (conn);
+   return false;
+--
+cgit v0.9.0.2
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/wget.git/commitdiff/7ed1e99770abbb8c1ed079da6a5d33dd4e43d456



More information about the pld-cvs-commit mailing list