summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbluhm <>2015-01-13 17:35:35 +0000
committerbluhm <>2015-01-13 17:35:35 +0000
commit3fd2d1d95424716eaf5c4ecf17d6bf0be444a372 (patch)
tree675defc54ce1d8f4c3d5203592fb373c717de34d
parentdda895dbd2777a18c7cdf12a3ec6dd1c0c433b46 (diff)
downloadopenbsd-3fd2d1d95424716eaf5c4ecf17d6bf0be444a372.tar.gz
openbsd-3fd2d1d95424716eaf5c4ecf17d6bf0be444a372.tar.bz2
openbsd-3fd2d1d95424716eaf5c4ecf17d6bf0be444a372.zip
For non-blocking sockets tls_connect_fds() could fail with EAGAIN.
Use the same logic from the read, write, accept functions to inform the caller wether a readable or writable socket is needed. After that event, the connect function must be called again. All the checks before connecting are done only once. OK tedu@
-rw-r--r--src/lib/libtls/tls_client.c24
-rw-r--r--src/lib/libtls/tls_internal.h5
2 files changed, 22 insertions, 7 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c
index 79b1baf648..c6117c3292 100644
--- a/src/lib/libtls/tls_client.c
+++ b/src/lib/libtls/tls_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_client.c,v 1.7 2015/01/02 16:38:07 bluhm Exp $ */ 1/* $OpenBSD: tls_client.c,v 1.8 2015/01/13 17:35:35 bluhm Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -135,7 +135,10 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
135{ 135{
136 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; 136 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
137 X509 *cert = NULL; 137 X509 *cert = NULL;
138 int ret; 138 int ret, ssl_err;
139
140 if (ctx->flags & TLS_CONNECTING)
141 goto connecting;
139 142
140 if ((ctx->flags & TLS_CLIENT) == 0) { 143 if ((ctx->flags & TLS_CLIENT) == 0) {
141 tls_set_error(ctx, "not a client context"); 144 tls_set_error(ctx, "not a client context");
@@ -198,11 +201,22 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
198 } 201 }
199 } 202 }
200 203
204 connecting:
201 if ((ret = SSL_connect(ctx->ssl_conn)) != 1) { 205 if ((ret = SSL_connect(ctx->ssl_conn)) != 1) {
202 tls_set_error(ctx, "SSL connect failed: %i", 206 ssl_err = SSL_get_error(ctx->ssl_conn, ret);
203 SSL_get_error(ctx->ssl_conn, ret)); 207 switch (ssl_err) {
204 goto err; 208 case SSL_ERROR_WANT_READ:
209 ctx->flags |= TLS_CONNECTING;
210 return (TLS_READ_AGAIN);
211 case SSL_ERROR_WANT_WRITE:
212 ctx->flags |= TLS_CONNECTING;
213 return (TLS_WRITE_AGAIN);
214 default:
215 tls_set_error(ctx, "SSL connect failed: %i", ssl_err);
216 goto err;
217 }
205 } 218 }
219 ctx->flags &= ~TLS_CONNECTING;
206 220
207 if (ctx->config->verify_host) { 221 if (ctx->config->verify_host) {
208 cert = SSL_get_peer_certificate(ctx->ssl_conn); 222 cert = SSL_get_peer_certificate(ctx->ssl_conn);
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index 4b250574ef..1a2bd388b7 100644
--- a/src/lib/libtls/tls_internal.h
+++ b/src/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_internal.h,v 1.5 2014/12/17 17:51:33 doug Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.6 2015/01/13 17:35:35 bluhm Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> 3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -44,7 +44,8 @@ struct tls_config {
44 44
45#define TLS_CLIENT (1 << 0) 45#define TLS_CLIENT (1 << 0)
46#define TLS_SERVER (1 << 1) 46#define TLS_SERVER (1 << 1)
47#define TLS_SERVER_CONN (1 << 2) 47#define TLS_SERVER_CONN (1 << 2)
48#define TLS_CONNECTING (1 << 3)
48 49
49struct tls { 50struct tls {
50 struct tls_config *config; 51 struct tls_config *config;