fix: SSL / TLS handshake trap
This commit is contained in:
+24
-2
@@ -267,14 +267,36 @@ void Proxy::handleClient(SOCKET clientSocket)
|
|||||||
SSL_CTX* hostCtx = _certManager.createHostContext(host);
|
SSL_CTX* hostCtx = _certManager.createHostContext(host);
|
||||||
if (!hostCtx) return;
|
if (!hostCtx) return;
|
||||||
|
|
||||||
|
auto sslHandshake = [](SSL* ssl, bool isAccept, SOCKET s) -> bool {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int ret = isAccept ? SSL_accept(ssl) : SSL_connect(ssl);
|
||||||
|
if (ret > 0) return true;
|
||||||
|
int err = SSL_get_error(ssl, ret);
|
||||||
|
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
|
||||||
|
{
|
||||||
|
fd_set fds;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(s, &fds);
|
||||||
|
struct timeval tv = {1, 0};
|
||||||
|
if (err == SSL_ERROR_WANT_READ)
|
||||||
|
select(0, &fds, NULL, NULL, &tv);
|
||||||
|
else
|
||||||
|
select(0, NULL, &fds, NULL, &tv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
SSL_ptr clientSSL(SSL_new(hostCtx));
|
SSL_ptr clientSSL(SSL_new(hostCtx));
|
||||||
SSL_set_fd(clientSSL.get(), (int)clientGuard);
|
SSL_set_fd(clientSSL.get(), (int)clientGuard);
|
||||||
if (SSL_accept(clientSSL.get()) <= 0) return;
|
if (!sslHandshake(clientSSL.get(), true, clientGuard)) return;
|
||||||
|
|
||||||
SSL_ptr remoteSSL(SSL_new(_clientCtx));
|
SSL_ptr remoteSSL(SSL_new(_clientCtx));
|
||||||
SSL_set_fd(remoteSSL.get(), (int)remoteGuard);
|
SSL_set_fd(remoteSSL.get(), (int)remoteGuard);
|
||||||
SSL_set_tlsext_host_name(remoteSSL.get(), host.c_str());
|
SSL_set_tlsext_host_name(remoteSSL.get(), host.c_str());
|
||||||
if (SSL_connect(remoteSSL.get()) <= 0) return;
|
if (!sslHandshake(remoteSSL.get(), false, remoteGuard)) return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
traffic handler
|
traffic handler
|
||||||
|
|||||||
Reference in New Issue
Block a user