Previously wget didn't honor the --timeout option if the remote host did
not answer SSL handshake
Signed-off-by: Tomas Hozza <thozza@redhat.com>
+2013-07-11 Karsten Hopp <karsten@redhat.com>
+
+ * openssl.c (struct openssl_read_args, struct scwt_context): New struct.
+ (openssl_read, ssl_connect_with_timeout_callback): New function.
+ (ssl_connect_wget): respect connect timeout.
+
2013-07-11 Tim Ruehsen <tim.ruehsen@gmx.de>
* gnutls.c (ssl_connect_wget): respect connect timeout.
2013-07-11 Tim Ruehsen <tim.ruehsen@gmx.de>
* gnutls.c (ssl_connect_wget): respect connect timeout.
-struct openssl_transport_context {
+struct openssl_transport_context
+{
SSL *conn; /* SSL connection handle */
char *last_error; /* last error printed with openssl_errstr */
};
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;
+ char *buf = args->buf;
+ int bufsize = args->bufsize;
+ int ret;
+
do
ret = SSL_read (conn, buf, bufsize);
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
+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;
openssl_peek, openssl_errstr, openssl_close
};
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
/* 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
ssl_connect_wget (int fd, const char *hostname)
{
SSL *conn;
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"));
struct openssl_transport_context *ctx;
DEBUGP (("Initiating SSL handshake.\n"));
if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
goto error;
SSL_set_connect_state (conn);
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);
goto error;
ctx = xnew0 (struct openssl_transport_context);
error:
DEBUGP (("SSL handshake failed.\n"));
print_errors ();
error:
DEBUGP (("SSL handshake failed.\n"));
print_errors ();
if (conn)
SSL_free (conn);
return false;
if (conn)
SSL_free (conn);
return false;