asyncnet, net: call SSL_shutdown only when connection established

This commit prevents "SSL_shutdown while in init" errors from happening.

See https://github.com/openssl/openssl/issues/710#issuecomment-253897666
This commit is contained in:
Leorize 2020-06-01 17:10:02 -05:00 • committed by Andreas Rumpf
commit 82092b3bb7
4 changed files with 52 additions and 12 deletions

View file

@ -201,6 +201,9 @@ const
SSL_OP_ALL* = 0x000FFFFF
SSL_VERIFY_NONE* = 0x00000000
SSL_VERIFY_PEER* = 0x00000001
SSL_ST_CONNECT* = 0x1000
SSL_ST_ACCEPT* = 0x2000
SSL_ST_INIT* = SSL_ST_CONNECT or SSL_ST_ACCEPT
OPENSSL_DES_DECRYPT* = 0
OPENSSL_DES_ENCRYPT* = 1
X509_V_OK* = 0
@ -282,6 +285,13 @@ when compileOption("dynlibOverride", "ssl") or defined(noOpenSSLHacks):
# Static linking against OpenSSL < 1.1.0 is not supported
discard
when defined(libressl) or defined(openssl10):
proc SSL_state(ssl: SslPtr): cint {.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_in_init*(ssl: SslPtr): cint {.inline.} =
SSl_state(ssl) and SSL_ST_INIT
else:
proc SSL_in_init*(ssl: SslPtr): cint {.cdecl, dynlib: DLLSSLName, importc.}
template OpenSSL_add_all_algorithms*() = discard
proc SSLv23_client_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
@ -382,6 +392,24 @@ else:
if theProc.isNil: 0.culong
else: theProc()
proc SSL_in_init*(ssl: SslPtr): cint =
# A compatibility wrapper for `SSL_in_init()` for OpenSSL 1.0, 1.1 and LibreSSL
const MainProc = "SSL_in_init"
let
theProc {.global.} = cast[proc(ssl: SslPtr): cint {.cdecl.}](sslSymNullable(MainProc))
# Fallback
sslState {.global.} = cast[proc(ssl: SslPtr): cint {.cdecl.}](sslSymNullable("SSL_state"))
# FIXME: This shouldn't be needed, but the compiler is complaining about
# `sslState` being GC-ed memory???
{.gcsafe.}:
if not theProc.isNil:
theProc(ssl)
elif not sslState.isNil:
sslState(ssl) and SSL_ST_INIT
else:
raiseInvalidLibrary MainProc
proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLUtilName, importc.}
proc SSL_new*(context: SslCtx): SslPtr{.cdecl, dynlib: DLLSSLName, importc.}