From fe862f413feed007451e932c3196c30511ce8d14 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 3 Sep 2020 20:28:47 +0200 Subject: [PATCH] https_server: Fix use of open_fn from application level https-server uses the open_fn() callback and potentially overwrites user defined callback. This commit adds the user defined open_fn() to https-server's context and calls it upon openning a session --- .../esp_https_server/src/https_server.c | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index a5befcf22f..31d2eefc5e 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -20,6 +20,11 @@ const static char *TAG = "esp_https_server"; +typedef struct httpd_ssl_ctx { + esp_tls_cfg_server_t *tls_cfg; + httpd_open_func_t open_fn; +} httpd_ssl_ctx_t; + /** * SSL socket close handler * @@ -93,7 +98,7 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd) assert(server != NULL); // Retrieve the SSL context from the global context field (set in config) - esp_tls_cfg_server_t *global_ctx = httpd_get_global_transport_ctx(server); + httpd_ssl_ctx_t *global_ctx = httpd_get_global_transport_ctx(server); assert(global_ctx != NULL); esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t)); @@ -101,7 +106,7 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd) return ESP_ERR_NO_MEM; } ESP_LOGI(TAG, "performing session handshake"); - int ret = esp_tls_server_session_create(global_ctx, sockfd, tls); + int ret = esp_tls_server_session_create(global_ctx->tls_cfg, sockfd, tls); if (ret != 0) { ESP_LOGE(TAG, "esp_tls_create_server_session failed"); goto fail; @@ -119,6 +124,9 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd) ESP_LOGD(TAG, "Secure socket open"); + if (global_ctx->open_fn) { + (global_ctx->open_fn)(server, sockfd); + } return ESP_OK; fail: esp_tls_server_session_delete(tls); @@ -133,7 +141,8 @@ fail: static void free_secure_context(void *ctx) { assert(ctx != NULL); - esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)ctx; + httpd_ssl_ctx_t *ssl_ctx = ctx; + esp_tls_cfg_server_t *cfg = ssl_ctx->tls_cfg; ESP_LOGI(TAG, "Server shuts down, releasing SSL context"); if (cfg->cacert_buf) { free((void *)cfg->cacert_buf); @@ -145,14 +154,21 @@ static void free_secure_context(void *ctx) free((void *)cfg->serverkey_buf); } free(cfg); + free(ssl_ctx); } -static esp_tls_cfg_server_t *create_secure_context(const struct httpd_ssl_config *config) +static httpd_ssl_ctx_t *create_secure_context(const struct httpd_ssl_config *config) { - esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)calloc(1, sizeof(esp_tls_cfg_server_t)); - if (!cfg) { + httpd_ssl_ctx_t *ssl_ctx = calloc(1, sizeof(httpd_ssl_ctx_t)); + if (!ssl_ctx) { return NULL; } + esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)calloc(1, sizeof(esp_tls_cfg_server_t)); + if (!cfg) { + free(ssl_ctx); + return NULL; + } + ssl_ctx->tls_cfg = cfg; /* cacert = CA which signs client cert, or client cert itself , which is mapped to client_verify_cert_pem */ if(config->client_verify_cert_pem != NULL) { cfg->cacert_buf = (unsigned char *)malloc(config->client_verify_cert_len); @@ -186,7 +202,7 @@ static esp_tls_cfg_server_t *create_secure_context(const struct httpd_ssl_config memcpy((char *)cfg->serverkey_buf, config->prvtkey_pem, config->prvtkey_len); cfg->serverkey_bytes = config->prvtkey_len; - return cfg; + return ssl_ctx; } /** Start the server */ @@ -199,16 +215,21 @@ esp_err_t httpd_ssl_start(httpd_handle_t *pHandle, struct httpd_ssl_config *conf if (HTTPD_SSL_TRANSPORT_SECURE == config->transport_mode) { - esp_tls_cfg_server_t *esp_tls_cfg = create_secure_context(config); - if (!esp_tls_cfg) { + httpd_ssl_ctx_t *ssl_ctx = create_secure_context(config); + if (!ssl_ctx) { return -1; } ESP_LOGD(TAG, "SSL context ready"); // set SSL specific config - config->httpd.global_transport_ctx = esp_tls_cfg; + config->httpd.global_transport_ctx = ssl_ctx; config->httpd.global_transport_ctx_free_fn = free_secure_context; + if (config->httpd.open_fn) { + // since the httpd's open_fn is used for opening the SSL session, we save the configured + // user pointer and call it upon opening the ssl socket + ssl_ctx->open_fn = config->httpd.open_fn; + } config->httpd.open_fn = httpd_ssl_open; // the open function configures the created SSL sessions config->httpd.server_port = config->port_secure;