From f341fd2b6eaee85f3ec463cd60efb0b1d2434c48 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 31 Mar 2023 23:10:52 +0000 Subject: [PATCH] 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. --- TODO.txt | 10 +++++---- src/Tls/TlsOpenSSL.c | 50 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/TODO.txt b/TODO.txt index cab30e3..34b6d24 100644 --- a/TODO.txt +++ b/TODO.txt @@ -42,16 +42,18 @@ Milestone: v0.3.0 - Each object has port, threads, maxConnections - 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] Debug OpenSSL +[ ] Replace all usages of curl with http +[ ] Proper HTTP request router + - Support regex matching +[ ] Token permissions + [ ] Move configuration to database [ ] Initial configuration [ ] If no config, create one-time use registration token that grants user admin privileges. [ ] /_telodendria/admin/config endpoint [x] Refactor TelodendriaConfig to just Config -[ ] Proper HTTP request router - - Support regex matching -[ ] Debug OpenSSL -[ ] Replace all usages of curl with http [ ] Documentation [ ] Array diff --git a/src/Tls/TlsOpenSSL.c b/src/Tls/TlsOpenSSL.c index 417b766..fac7741 100644 --- a/src/Tls/TlsOpenSSL.c +++ b/src/Tls/TlsOpenSSL.c @@ -39,6 +39,29 @@ typedef struct OpenSSLCookie SSL *ssl; } 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 * TlsInitClient(int fd, const char *serverName) { @@ -110,6 +133,7 @@ TlsInitServer(int fd, const char *crt, const char *key) { OpenSSLCookie *cookie; char errorStr[256]; + int acceptRet = 0; cookie = Malloc(sizeof(OpenSSLCookie)); if (!cookie) @@ -123,44 +147,54 @@ TlsInitServer(int fd, const char *crt, const char *key) cookie->ctx = SSL_CTX_new(cookie->method); if (!cookie->ctx) { - Log(LOG_ERR, "TlsServerInit(): Unable to create SSL Context."); + Log(LOG_ERR, "TlsInitServer(): Unable to create SSL Context."); goto error; } 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; } 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; } cookie->ssl = SSL_new(cookie->ctx); if (!cookie->ssl) { - Log(LOG_ERR, "TlsServerInit(): Unable to create SSL object."); + Log(LOG_ERR, "TlsInitServer(): Unable to create SSL object."); goto error; } 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; } - if (SSL_accept(cookie->ssl) <= 0) + while ((acceptRet = SSL_accept(cookie->ssl)) <= 0) { - Log(LOG_ERR, "TlsServerInit(): Unable to accept connection."); - goto error; + switch (SSL_get_error(cookie->ssl, acceptRet)) + { + 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; 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)); if (cookie->ssl)