Blame SOURCES/wget-1.14-sslreadtimeout.patch

bc22e6
diff -up wget-1.14/src/openssl.c.ssltimeout wget-1.14/src/openssl.c
bc22e6
--- wget-1.14/src/openssl.c.ssltimeout	2012-08-09 14:30:14.987964706 +0200
bc22e6
+++ wget-1.14/src/openssl.c	2012-08-09 14:44:05.467660741 +0200
bc22e6
@@ -256,19 +256,42 @@ struct openssl_transport_context {
bc22e6
   char *last_error;             /* last error printed with openssl_errstr */
bc22e6
 };
bc22e6
 
bc22e6
-static int
bc22e6
-openssl_read (int fd, char *buf, int bufsize, void *arg)
bc22e6
-{
bc22e6
-  int ret;
bc22e6
-  struct openssl_transport_context *ctx = arg;
bc22e6
+struct openssl_read_args {
bc22e6
+  int fd;
bc22e6
+  struct openssl_transport_context *ctx;
bc22e6
+  char *buf;
bc22e6
+  int bufsize;
bc22e6
+  int retval;
bc22e6
+};
bc22e6
+
bc22e6
+static void openssl_read_callback(void *arg) {
bc22e6
+  struct openssl_read_args *args = (struct openssl_read_args *) arg;
bc22e6
+  struct openssl_transport_context *ctx = args->ctx;
bc22e6
   SSL *conn = ctx->conn;
bc22e6
+  char *buf = args->buf;
bc22e6
+  int bufsize = args->bufsize;
bc22e6
+  int ret;
bc22e6
+
bc22e6
   do
bc22e6
     ret = SSL_read (conn, buf, bufsize);
bc22e6
-  while (ret == -1
bc22e6
-         && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
bc22e6
+  while (ret == -1 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
bc22e6
          && errno == EINTR);
bc22e6
+  args->retval = ret;
bc22e6
+}
bc22e6
 
bc22e6
-  return ret;
bc22e6
+static int
bc22e6
+openssl_read (int fd, char *buf, int bufsize, void *arg)
bc22e6
+{
bc22e6
+  struct openssl_read_args args;
bc22e6
+  args.fd = fd;
bc22e6
+  args.buf = buf;
bc22e6
+  args.bufsize = bufsize;
bc22e6
+  args.ctx = (struct openssl_transport_context*) arg;
bc22e6
+
bc22e6
+  if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) {
bc22e6
+    return -1;
bc22e6
+  }
bc22e6
+  return args.retval;
bc22e6
 }
bc22e6
 
bc22e6
 static int
bc22e6
@@ -386,6 +409,18 @@ static struct transport_implementation o
bc22e6
   openssl_peek, openssl_errstr, openssl_close
bc22e6
 };
bc22e6
 
bc22e6
+struct scwt_context {
bc22e6
+  SSL *ssl;
bc22e6
+  int result;
bc22e6
+};
bc22e6
+
bc22e6
+static void
bc22e6
+ssl_connect_with_timeout_callback(void *arg)
bc22e6
+{
bc22e6
+  struct scwt_context *ctx = (struct scwt_context *)arg;
bc22e6
+  ctx->result = SSL_connect(ctx->ssl);
bc22e6
+}
bc22e6
+
bc22e6
 /* Perform the SSL handshake on file descriptor FD, which is assumed
bc22e6
    to be connected to an SSL server.  The SSL handle provided by
bc22e6
    OpenSSL is registered with the file descriptor FD using
bc22e6
@@ -398,6 +433,7 @@ bool
bc22e6
 ssl_connect_wget (int fd, const char *hostname)
bc22e6
 {
bc22e6
   SSL *conn;
bc22e6
+  struct scwt_context scwt_ctx;
bc22e6
   struct openssl_transport_context *ctx;
bc22e6
 
bc22e6
   DEBUGP (("Initiating SSL handshake.\n"));
bc22e6
@@ -425,7 +461,14 @@ ssl_connect_wget (int fd, const char *ho
bc22e6
   if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
bc22e6
     goto error;
bc22e6
   SSL_set_connect_state (conn);
bc22e6
-  if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
bc22e6
+
bc22e6
+  scwt_ctx.ssl = conn;
bc22e6
+  if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback, 
bc22e6
+                       &scwt_ctx)) {
bc22e6
+    DEBUGP (("SSL handshake timed out.\n"));
bc22e6
+    goto timeout;
bc22e6
+  }
bc22e6
+  if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
bc22e6
     goto error;
bc22e6
 
bc22e6
   ctx = xnew0 (struct openssl_transport_context);
bc22e6
@@ -441,6 +484,7 @@ ssl_connect_wget (int fd, const char *ho
bc22e6
  error:
bc22e6
   DEBUGP (("SSL handshake failed.\n"));
bc22e6
   print_errors ();
bc22e6
+  timeout:
bc22e6
   if (conn)
bc22e6
     SSL_free (conn);
bc22e6
   return false;