diff options
author | jsing <> | 2015-04-15 16:05:23 +0000 |
---|---|---|
committer | jsing <> | 2015-04-15 16:05:23 +0000 |
commit | dcb31e966f316332772152f9dc4003581bf31395 (patch) | |
tree | 3d6921045d591206b78b5802a3cd741aa49ea5ef /src | |
parent | f62c289c77e6f576e0fd3f26d631b4d0fe2cac1c (diff) | |
download | openbsd-dcb31e966f316332772152f9dc4003581bf31395.tar.gz openbsd-dcb31e966f316332772152f9dc4003581bf31395.tar.bz2 openbsd-dcb31e966f316332772152f9dc4003581bf31395.zip |
Make tls_close() more robust - do not rely on a close notify being received
from the other side and only return TLS_READ_AGAIN/TLS_WRITE_AGAIN if we
failed to send a close notify on a non-blocking socket.
Otherwise be more forceful and always shutdown/close the socket regardless
of other failures. Also do not consider ENOTCONN or ECONNRESET to be a
shutdown failure, since there are various situations where this can occur.
ok doug@ guenther@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libtls/tls.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index d942c35fec..002cccda5f 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.9 2015/04/02 13:19:15 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.10 2015/04/15 16:05:23 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -327,30 +327,34 @@ int | |||
327 | tls_close(struct tls *ctx) | 327 | tls_close(struct tls *ctx) |
328 | { | 328 | { |
329 | int ssl_ret; | 329 | int ssl_ret; |
330 | int rv = 0; | ||
330 | 331 | ||
331 | if (ctx->ssl_conn != NULL) { | 332 | if (ctx->ssl_conn != NULL) { |
332 | ssl_ret = SSL_shutdown(ctx->ssl_conn); | 333 | ssl_ret = SSL_shutdown(ctx->ssl_conn); |
333 | if (ssl_ret == 0) | 334 | if (ssl_ret < 0) { |
334 | ssl_ret = SSL_shutdown(ctx->ssl_conn); | 335 | rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, |
335 | if (ssl_ret < 0) | ||
336 | return tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, | ||
337 | "shutdown"); | 336 | "shutdown"); |
337 | if (rv == TLS_READ_AGAIN || rv == TLS_WRITE_AGAIN) | ||
338 | return (rv); | ||
339 | } | ||
338 | } | 340 | } |
339 | 341 | ||
340 | if (ctx->socket != -1) { | 342 | if (ctx->socket != -1) { |
341 | if (shutdown(ctx->socket, SHUT_RDWR) != 0) { | 343 | if (shutdown(ctx->socket, SHUT_RDWR) != 0) { |
342 | tls_set_error(ctx, "shutdown"); | 344 | if (rv == 0 && |
343 | goto err; | 345 | errno != ENOTCONN && errno != ECONNRESET) { |
346 | tls_set_error(ctx, "shutdown"); | ||
347 | rv = -1; | ||
348 | } | ||
344 | } | 349 | } |
345 | if (close(ctx->socket) != 0) { | 350 | if (close(ctx->socket) != 0) { |
346 | tls_set_error(ctx, "close"); | 351 | if (rv == 0) { |
347 | goto err; | 352 | tls_set_error(ctx, "close"); |
353 | rv = -1; | ||
354 | } | ||
348 | } | 355 | } |
349 | ctx->socket = -1; | 356 | ctx->socket = -1; |
350 | } | 357 | } |
351 | 358 | ||
352 | return (0); | 359 | return (rv); |
353 | |||
354 | err: | ||
355 | return (-1); | ||
356 | } | 360 | } |