Skip to content

Commit

Permalink
civetweb support mbedtsl v2.16.2
Browse files Browse the repository at this point in the history
  • Loading branch information
qinchao authored and Qinch committed Sep 21, 2020
1 parent 8e1f656 commit 161f06c
Show file tree
Hide file tree
Showing 2 changed files with 322 additions and 5 deletions.
150 changes: 145 additions & 5 deletions src/civetweb.c
Expand Up @@ -446,6 +446,9 @@ _civet_safe_clock_gettime(int clk_id, struct timespec *t)
#include "zlib.h"
#endif

#if defined(MG_MBEDTLS)
#include "mod_mbedtls.inl"
#endif

/********************************************************************/
/* CivetWeb configuration defines */
Expand Down Expand Up @@ -1848,9 +1851,11 @@ typedef int socklen_t;
#endif


#if defined(NO_SSL)
typedef struct SSL SSL; /* dummy for SSL argument to push/pull */
typedef struct SSL_CTX SSL_CTX;
#if defined(NO_SSL)
#if !defined(MG_MBEDTLS)
typedef struct SSL SSL; /* dummy for SSL argument to push/pull */
typedef struct SSL_CTX SSL_CTX;
#endif
#else
#if defined(NO_SSL_DL)
#include <openssl/bn.h>
Expand Down Expand Up @@ -6469,7 +6474,7 @@ push_inner(struct mg_context *ctx,
return -2;
}

#if defined(NO_SSL)
#if defined(NO_SSL) && !defined(MG_MBEDTLS)
if (ssl) {
return -2;
}
Expand Down Expand Up @@ -6501,6 +6506,23 @@ push_inner(struct mg_context *ctx,
}
} else
#endif

#if defined(MG_MBEDTLS)
if (ssl != NULL) {
n = mbed_ssl_write(ssl, (const unsigned char *)buf, len);
if (n <= 0) {
if ((n == MBEDTLS_ERR_SSL_WANT_READ)
|| (n == MBEDTLS_ERR_SSL_WANT_WRITE) || n == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
n = 0;
} else {
fprintf(stderr, "SSL write failed, error %d\n", n);
return -2;
}
} else {
err = 0;
}
} else
#endif
if (fp != NULL) {
n = (int)fwrite(buf, 1, (size_t)len, fp);
if (ferror(fp)) {
Expand Down Expand Up @@ -6728,6 +6750,47 @@ pull_inner(FILE *fp,
}
#endif

#if defined(MG_MBEDTLS)
} else if (conn->ssl != NULL) {
/* We already know there is no more data buffered in conn->buf
* but there is more available in the SSL layer. So don't poll
* conn->client.sock yet. */
struct pollfd pfd[1];
int pollres;

pfd[0].fd = conn->client.sock;
pfd[0].events = POLLIN;
pollres = mg_poll(pfd,
1,
(int)(timeout * 1000.0),
&(conn->phys_ctx->stop_flag));
if (conn->phys_ctx->stop_flag) {
return -2;
}

if (pollres > 0) {
nread = mbed_ssl_read(conn->ssl, (unsigned char *)buf, len);
if (nread <= 0) {
if ((nread == MBEDTLS_ERR_SSL_WANT_READ)
|| (nread == MBEDTLS_ERR_SSL_WANT_WRITE)|| nread == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
nread = 0;
} else {
fprintf(stderr, "SSL read failed, error %d\n", nread);
return -2;
}
} else {
err = 0;
}

} else if (pollres < 0) {
/* Error */
return -2;
} else {
/* pollres = 0 means timeout */
nread = 0;
}
#endif

} else {
struct mg_pollfd pfd[1];
int pollres;
Expand Down Expand Up @@ -16881,6 +16944,34 @@ uninitialize_ssl(void)
}
#endif /* !NO_SSL */

#if defined(MG_MBEDTLS)
/* Check if SSL is required.
* If so, set up ctx->ssl_ctx pointer. */
static int
mg_sslctx_init(struct mg_context *phys_ctx, struct mg_domain_context *dom_ctx)
{
if (!phys_ctx) {
return 0;
}

if (!dom_ctx) {
dom_ctx = &(phys_ctx->dd);
}

if (!is_ssl_port_used(dom_ctx->config[LISTENING_PORTS])) {
/* No SSL port is set. No need to setup SSL. */
return 1;
}

dom_ctx->ssl_ctx = mg_calloc(1, sizeof(*dom_ctx->ssl_ctx));
if (dom_ctx->ssl_ctx == NULL) {
fprintf(stderr, "ssl_ctx malloc failed\n");
return 0;
}

return mbed_sslctx_init(dom_ctx->ssl_ctx, dom_ctx->config[SSL_CERTIFICATE]) == 0 ? 1 : 0;
}
#endif /* MG_MBEDTLS */

#if !defined(NO_FILESYSTEMS)
static int
Expand Down Expand Up @@ -17140,6 +17231,14 @@ close_connection(struct mg_connection *conn)
conn->conn_state = 7; /* closing */
#endif

#if defined(MG_MBEDTLS)
if (conn->ssl != NULL) {
mbed_ssl_close(conn->ssl);
mg_free(conn->ssl);
conn->ssl = NULL;
}
#endif

#if !defined(NO_SSL)
if (conn->ssl != NULL) {
/* Run SSL_shutdown twice to ensure completely close SSL connection
Expand Down Expand Up @@ -18881,6 +18980,19 @@ worker_thread_run(struct mg_connection *conn)
conn->request_info.is_ssl = conn->client.is_ssl;

if (conn->client.is_ssl) {
#if defined(MG_MBEDTLS)
/* HTTPS connection */
if (mbed_ssl_accept(&conn->ssl,
conn->dom_ctx->ssl_ctx, &conn->client.sock) == 0) {
/* conn->dom_ctx is set in get_request */
/* process HTTPS connection */
process_new_connection(conn);
} else {
/* make sure the connection is cleaned up on SSL failure */
close_connection(conn);
}
#endif

#if !defined(NO_SSL)
/* HTTPS connection */
if (sslize(conn, SSL_accept, NULL)) {
Expand Down Expand Up @@ -19290,6 +19402,14 @@ free_context(struct mg_context *ctx)
mg_free(tmp_rh);
}

#if defined(MG_MBEDTLS)
if (ctx->dd.ssl_ctx != NULL) {
mbed_sslctx_uninit(ctx->dd.ssl_ctx);
mg_free(ctx->dd.ssl_ctx);
ctx->dd.ssl_ctx = NULL;
}
#endif

#if !defined(NO_SSL)
/* Deallocate SSL context */
if (ctx->dd.ssl_ctx != NULL) {
Expand Down Expand Up @@ -19772,6 +19892,26 @@ static
}
#endif

#if defined(MG_MBEDTLS)
if (!mg_sslctx_init(ctx, NULL)) {
const char *err_msg = "Error initializing SSL context";
/* Fatal error - abort start. */
mg_cry_ctx_internal(ctx, "%s", err_msg);

if ((error != NULL) && (error->text_buffer_size > 0)) {
mg_snprintf(NULL,
NULL, /* No truncation check for error buffers */
error->text,
error->text_buffer_size,
"%s",
err_msg);
}
free_context(ctx);
pthread_setspecific(sTlsKey, NULL);
return NULL;
}
#endif

#if !defined(NO_SSL)
if (!init_ssl_ctx(ctx, NULL)) {
const char *err_msg = "Error initializing SSL context";
Expand Down Expand Up @@ -20277,7 +20417,7 @@ mg_check_feature(unsigned feature)
#if !defined(NO_FILES)
| MG_FEATURES_FILES
#endif
#if !defined(NO_SSL)
#if !defined(NO_SSL) || defined(MG_MBEDTLS)
| MG_FEATURES_SSL
#endif
#if !defined(NO_CGI)
Expand Down

0 comments on commit 161f06c

Please sign in to comment.