Blame SOURCES/wget-1.14-sslreadtimeout.patch

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