a7fd8ce
diff -up wget-1.13.4/src/openssl.c.sslreadtimeout wget-1.13.4/src/openssl.c
a7fd8ce
--- wget-1.13.4/src/openssl.c.sslreadtimeout	2011-08-29 10:01:24.000000000 +0200
a7fd8ce
+++ wget-1.13.4/src/openssl.c	2012-05-29 12:30:42.000000000 +0200
a7fd8ce
@@ -254,19 +254,47 @@ struct openssl_transport_context {
a7fd8ce
   char *last_error;             /* last error printed with openssl_errstr */
a7fd8ce
 };
a7fd8ce
 
a7fd8ce
-static int
a7fd8ce
-openssl_read (int fd, char *buf, int bufsize, void *arg)
a7fd8ce
+struct openssl_read_args {
a7fd8ce
+  int fd;
a7fd8ce
+  struct openssl_transport_context *ctx;
a7fd8ce
+  char *buf;
a7fd8ce
+  int bufsize;
a7fd8ce
+  int retval;
a7fd8ce
+};
a7fd8ce
+
a7fd8ce
+static void openssl_read_callback(void *arg)
a7fd8ce
 {
a7fd8ce
-  int ret;
a7fd8ce
-  struct openssl_transport_context *ctx = arg;
a7fd8ce
+  struct openssl_read_args *args = (struct openssl_read_args *) arg;
a7fd8ce
+  struct openssl_transport_context *ctx = args->ctx;
a7fd8ce
   SSL *conn = ctx->conn;
a7fd8ce
+  char *buf = args->buf;
a7fd8ce
+  int bufsize = args->bufsize;
a7fd8ce
+
a7fd8ce
+  int ret;
a7fd8ce
+
a7fd8ce
   do
a7fd8ce
     ret = SSL_read (conn, buf, bufsize);
a7fd8ce
   while (ret == -1
a7fd8ce
          && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
a7fd8ce
          && errno == EINTR);
a7fd8ce
 
a7fd8ce
-  return ret;
a7fd8ce
+  args->retval = ret;
a7fd8ce
+}
a7fd8ce
+
a7fd8ce
+static int
a7fd8ce
+openssl_read (int fd, char *buf, int bufsize, void *arg)
a7fd8ce
+{
a7fd8ce
+  struct openssl_read_args args;
a7fd8ce
+  args.fd = fd;
a7fd8ce
+  args.buf = buf;
a7fd8ce
+  args.bufsize = bufsize;
a7fd8ce
+  args.ctx = (struct openssl_transport_context*) arg;
a7fd8ce
+
a7fd8ce
+  if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) {
a7fd8ce
+    return -1;
a7fd8ce
+  }
a7fd8ce
+  
a7fd8ce
+  return args.retval;
a7fd8ce
 }
a7fd8ce
 
a7fd8ce
 static int
a7fd8ce
@@ -384,6 +412,18 @@ static struct transport_implementation o
a7fd8ce
   openssl_peek, openssl_errstr, openssl_close
a7fd8ce
 };
a7fd8ce
 
a7fd8ce
+struct scwt_context {
a7fd8ce
+  SSL *ssl;
a7fd8ce
+  int result;
a7fd8ce
+};
a7fd8ce
+
a7fd8ce
+static void
a7fd8ce
+ssl_connect_with_timeout_callback(void *arg)
a7fd8ce
+{
a7fd8ce
+  struct scwt_context *ctx = (struct scwt_context *)arg;
a7fd8ce
+  ctx->result = SSL_connect(ctx->ssl);
a7fd8ce
+}
a7fd8ce
+
a7fd8ce
 /* Perform the SSL handshake on file descriptor FD, which is assumed
a7fd8ce
    to be connected to an SSL server.  The SSL handle provided by
a7fd8ce
    OpenSSL is registered with the file descriptor FD using
a7fd8ce
@@ -396,6 +436,7 @@ bool
a7fd8ce
 ssl_connect_wget (int fd)
a7fd8ce
 {
a7fd8ce
   SSL *conn;
a7fd8ce
+  struct scwt_context scwt_ctx;
a7fd8ce
   struct openssl_transport_context *ctx;
a7fd8ce
 
a7fd8ce
   DEBUGP (("Initiating SSL handshake.\n"));
a7fd8ce
@@ -410,7 +451,14 @@ ssl_connect_wget (int fd)
a7fd8ce
   if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
a7fd8ce
     goto error;
a7fd8ce
   SSL_set_connect_state (conn);
a7fd8ce
-  if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
a7fd8ce
+  
a7fd8ce
+  scwt_ctx.ssl = conn;
a7fd8ce
+  if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback, 
a7fd8ce
+                       &scwt_ctx)) {
a7fd8ce
+    DEBUGP (("SSL handshake timed out.\n"));
a7fd8ce
+    goto timeout;
a7fd8ce
+  }
a7fd8ce
+  if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
a7fd8ce
     goto error;
a7fd8ce
 
a7fd8ce
   ctx = xnew0 (struct openssl_transport_context);
a7fd8ce
@@ -426,6 +474,7 @@ ssl_connect_wget (int fd)
a7fd8ce
  error:
a7fd8ce
   DEBUGP (("SSL handshake failed.\n"));
a7fd8ce
   print_errors ();
a7fd8ce
+ timeout:
a7fd8ce
   if (conn)
a7fd8ce
     SSL_free (conn);
a7fd8ce
   return false;