Fix OpenSSL server accept call.

Apparently it can EAGAIN on non-blocking connections... I don't think
LibreSSL's TLS library does this, but something to keep in mind if it
doesn't work for somebody.
This commit is contained in:
Jordan Bancino 2023-03-31 23:10:52 +00:00
parent eef615fc9a
commit f341fd2b6e
2 changed files with 48 additions and 12 deletions

View file

@ -42,16 +42,18 @@ Milestone: v0.3.0
- Each object has port, threads, maxConnections - Each object has port, threads, maxConnections
- If tls is given, it can be null, false, or an object with cert and key - If tls is given, it can be null, false, or an object with cert and key
[x] Pass TLS certs and keys into HttpServer [x] Pass TLS certs and keys into HttpServer
[x] Debug OpenSSL
[ ] Replace all usages of curl with http
[ ] Proper HTTP request router
- Support regex matching
[ ] Token permissions
[ ] Move configuration to database [ ] Move configuration to database
[ ] Initial configuration [ ] Initial configuration
[ ] If no config, create one-time use registration token that [ ] If no config, create one-time use registration token that
grants user admin privileges. grants user admin privileges.
[ ] /_telodendria/admin/config endpoint [ ] /_telodendria/admin/config endpoint
[x] Refactor TelodendriaConfig to just Config [x] Refactor TelodendriaConfig to just Config
[ ] Proper HTTP request router
- Support regex matching
[ ] Debug OpenSSL
[ ] Replace all usages of curl with http
[ ] Documentation [ ] Documentation
[ ] Array [ ] Array

View file

@ -39,6 +39,29 @@ typedef struct OpenSSLCookie
SSL *ssl; SSL *ssl;
} OpenSSLCookie; } OpenSSLCookie;
static char *
SSLErrorString(int err)
{
switch (err) {
case SSL_ERROR_NONE:
return "No error.";
case SSL_ERROR_ZERO_RETURN:
return "The TLS/SSL connection has been closed.";
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_ACCEPT:
return "The operation did not complete.";
case SSL_ERROR_WANT_X509_LOOKUP:
return "X509 lookup failed.";
case SSL_ERROR_SYSCALL:
return "I/O Error.";
case SSL_ERROR_SSL:
return "SSL library error.";
}
return NULL;
}
void * void *
TlsInitClient(int fd, const char *serverName) TlsInitClient(int fd, const char *serverName)
{ {
@ -110,6 +133,7 @@ TlsInitServer(int fd, const char *crt, const char *key)
{ {
OpenSSLCookie *cookie; OpenSSLCookie *cookie;
char errorStr[256]; char errorStr[256];
int acceptRet = 0;
cookie = Malloc(sizeof(OpenSSLCookie)); cookie = Malloc(sizeof(OpenSSLCookie));
if (!cookie) if (!cookie)
@ -123,44 +147,54 @@ TlsInitServer(int fd, const char *crt, const char *key)
cookie->ctx = SSL_CTX_new(cookie->method); cookie->ctx = SSL_CTX_new(cookie->method);
if (!cookie->ctx) if (!cookie->ctx)
{ {
Log(LOG_ERR, "TlsServerInit(): Unable to create SSL Context."); Log(LOG_ERR, "TlsInitServer(): Unable to create SSL Context.");
goto error; goto error;
} }
if (SSL_CTX_use_certificate_file(cookie->ctx, crt, SSL_FILETYPE_PEM) <= 0) if (SSL_CTX_use_certificate_file(cookie->ctx, crt, SSL_FILETYPE_PEM) <= 0)
{ {
Log(LOG_ERR, "TlsServerInit(): Unable to set certificate file."); Log(LOG_ERR, "TlsInitServer(): Unable to set certificate file.");
goto error; goto error;
} }
if (SSL_CTX_use_PrivateKey_file(cookie->ctx, key, SSL_FILETYPE_PEM) <= 0) if (SSL_CTX_use_PrivateKey_file(cookie->ctx, key, SSL_FILETYPE_PEM) <= 0)
{ {
Log(LOG_ERR, "TlsServerInit(): Unable to set key file."); Log(LOG_ERR, "TlsInitServer(): Unable to set key file.");
goto error; goto error;
} }
cookie->ssl = SSL_new(cookie->ctx); cookie->ssl = SSL_new(cookie->ctx);
if (!cookie->ssl) if (!cookie->ssl)
{ {
Log(LOG_ERR, "TlsServerInit(): Unable to create SSL object."); Log(LOG_ERR, "TlsInitServer(): Unable to create SSL object.");
goto error; goto error;
} }
if (!SSL_set_fd(cookie->ssl, fd)) if (!SSL_set_fd(cookie->ssl, fd))
{ {
Log(LOG_ERR, "TlsServerInit(): Unable to set file descriptor."); Log(LOG_ERR, "TlsInitServer(): Unable to set file descriptor.");
goto error; goto error;
} }
if (SSL_accept(cookie->ssl) <= 0) while ((acceptRet = SSL_accept(cookie->ssl)) <= 0)
{ {
Log(LOG_ERR, "TlsServerInit(): Unable to accept connection."); switch (SSL_get_error(cookie->ssl, acceptRet))
goto error; {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_ACCEPT:
continue;
default:
Log(LOG_ERR, "TlsInitServer(): Unable to accept connection.");
goto error;
}
} }
return cookie; return cookie;
error: error:
Log(LOG_ERR, "TlsServerInit(): %s", SSLErrorString(SSL_get_error(cookie->ssl, acceptRet)));
Log(LOG_ERR, "TlsServerInit(): %s", ERR_error_string(ERR_get_error(), errorStr)); Log(LOG_ERR, "TlsServerInit(): %s", ERR_error_string(ERR_get_error(), errorStr));
if (cookie->ssl) if (cookie->ssl)