From b3fa7fcf7356b755cd103461d9ea3381bad9b2e7 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 16 Dec 2022 16:04:22 +0530 Subject: [PATCH] esp_local_ctrl: Add support for insecure HTTP server transport --- components/esp_local_ctrl/CMakeLists.txt | 7 +--- .../esp_local_ctrl/include/esp_local_ctrl.h | 11 ++++-- .../src/esp_local_ctrl_transport_httpd.c | 30 +++++++++++--- examples/protocols/esp_local_ctrl/README.md | 4 +- .../main/esp_local_ctrl_service.c | 16 ++++++-- .../esp_local_ctrl/pytest_esp_local_ctrl.py | 39 ++++++++++++++----- .../esp_local_ctrl/scripts/esp_local_ctrl.py | 6 ++- .../esp_local_ctrl/sdkconfig.ci.http | 2 + 8 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 examples/protocols/esp_local_ctrl/sdkconfig.ci.http diff --git a/components/esp_local_ctrl/CMakeLists.txt b/components/esp_local_ctrl/CMakeLists.txt index d71ac890df3..9c8574eb287 100644 --- a/components/esp_local_ctrl/CMakeLists.txt +++ b/components/esp_local_ctrl/CMakeLists.txt @@ -4,11 +4,6 @@ set(srcs "src/esp_local_ctrl.c" "src/esp_local_ctrl_handler.c" "proto-c/esp_local_ctrl.pb-c.c") -if(CONFIG_ESP_HTTPS_SERVER_ENABLE) - list(APPEND srcs - "src/esp_local_ctrl_transport_httpd.c") -endif() - if(CONFIG_BT_ENABLED) if(CONFIG_BT_BLUEDROID_ENABLED) list(APPEND srcs @@ -16,6 +11,8 @@ if(CONFIG_BT_ENABLED) endif() endif() +list(APPEND srcs + "src/esp_local_ctrl_transport_httpd.c") idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" diff --git a/components/esp_local_ctrl/include/esp_local_ctrl.h b/components/esp_local_ctrl/include/esp_local_ctrl.h index 6e9b90a81b7..f05e6473f42 100644 --- a/components/esp_local_ctrl/include/esp_local_ctrl.h +++ b/components/esp_local_ctrl/include/esp_local_ctrl.h @@ -197,12 +197,17 @@ typedef struct protocomm_ble_config esp_local_ctrl_transport_config_ble_t; /** * @brief Configuration for transport mode HTTPD * - * This is a forward declaration for `httpd_ssl_config_t`. - * To use this, application must set CONFIG_ESP_HTTPS_SERVER_ENABLE + * This is a forward declaration for `httpd_ssl_config_t` (for HTTPS) + * or `httpd_config_t` (for HTTP) + */ +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE +/* To use this, application must set CONFIG_ESP_HTTPS_SERVER_ENABLE * and include `esp_https_server.h` */ typedef struct httpd_ssl_config esp_local_ctrl_transport_config_httpd_t; - +#else +typedef struct httpd_config esp_local_ctrl_transport_config_httpd_t; +#endif /** * @brief Transport mode (BLE / HTTPD) configuration */ diff --git a/components/esp_local_ctrl/src/esp_local_ctrl_transport_httpd.c b/components/esp_local_ctrl/src/esp_local_ctrl_transport_httpd.c index 9a83fdc6320..329b4722c4e 100644 --- a/components/esp_local_ctrl/src/esp_local_ctrl_transport_httpd.c +++ b/components/esp_local_ctrl/src/esp_local_ctrl_transport_httpd.c @@ -19,7 +19,19 @@ #include #include #include +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE #include +#else +#include +#endif + +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE +#define esp_local_ctrl_httpd_start httpd_ssl_start +#define esp_local_ctrl_httpd_stop httpd_ssl_stop +#else +#define esp_local_ctrl_httpd_start httpd_start +#define esp_local_ctrl_httpd_stop httpd_stop +#endif #include "esp_local_ctrl_priv.h" @@ -38,12 +50,17 @@ static esp_err_t start_httpd_transport(protocomm_t *pc, const esp_local_ctrl_tra esp_err_t err; #ifdef WITH_MDNS + uint16_t port = 0; +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE /* Extract configured port */ - uint16_t port = ( + port = ( config->httpd->transport_mode == HTTPD_SSL_TRANSPORT_SECURE ? config->httpd->port_secure : config->httpd->port_insecure ); +#else + port = config->httpd->server_port; +#endif err = mdns_service_add("Local Control Service", "_esp_local_ctrl", "_tcp", port, NULL, 0); if (err != ESP_OK) { @@ -64,9 +81,9 @@ static esp_err_t start_httpd_transport(protocomm_t *pc, const esp_local_ctrl_tra } } #endif - err = httpd_ssl_start(&server_handle, config->httpd); + err = esp_local_ctrl_httpd_start(&server_handle, config->httpd); if (ESP_OK != err) { - ESP_LOGE(TAG, "Error starting HTTPS service!"); + ESP_LOGE(TAG, "Error starting HTTP/S service!"); #ifdef WITH_MDNS mdns_service_remove("_esp_local_ctrl", "_tcp"); #endif @@ -89,7 +106,7 @@ static void stop_httpd_transport(protocomm_t *pc) mdns_service_remove("_esp_local_ctrl", "_tcp"); #endif protocomm_httpd_stop(pc); - if (httpd_ssl_stop(server_handle) == ESP_OK) { + if (esp_local_ctrl_httpd_stop(server_handle) == ESP_OK) { server_handle = NULL; } } @@ -101,14 +118,15 @@ static esp_err_t copy_httpd_config(esp_local_ctrl_transport_config_t *dest_confi return ESP_ERR_INVALID_ARG; } - dest_config->httpd = calloc(1, sizeof(httpd_ssl_config_t)); + dest_config->httpd = calloc(1, sizeof(esp_local_ctrl_transport_config_httpd_t)); if (!dest_config->httpd) { ESP_LOGE(TAG, "Failed to allocate memory for HTTPD transport config"); return ESP_ERR_NO_MEM; } memcpy(dest_config->httpd, src_config->httpd, - sizeof(httpd_ssl_config_t)); + sizeof(esp_local_ctrl_transport_config_httpd_t)); + return ESP_OK; } diff --git a/examples/protocols/esp_local_ctrl/README.md b/examples/protocols/esp_local_ctrl/README.md index 42c825b3861..82749c11c9f 100644 --- a/examples/protocols/esp_local_ctrl/README.md +++ b/examples/protocols/esp_local_ctrl/README.md @@ -74,12 +74,14 @@ Select properties to set (0 to re-read, 'q' to quit) : q Quitting... ``` -The script also allows to connect over BLE, and provide a custom service name. To display the list of supported parameters, run: +The script also allows to connect over plain HTTP or BLE, and provide a custom service name. To display the list of supported parameters, run: ``` python scripts/esp_local_ctrl.py --help ``` +**Note:** To use plain HTTP transport, disable the config option `CONFIG_ESP_HTTPS_SERVER_ENABLE`. + ## Certificates You can generate a new server certificate using the OpenSSL command line tool. diff --git a/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c b/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c index 4dc3e9c1009..921dfb54383 100644 --- a/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c +++ b/examples/protocols/esp_local_ctrl/main/esp_local_ctrl_service.c @@ -20,8 +20,11 @@ #include #include #include +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE #include - +#else +#include +#endif static const char *TAG = "control"; #define SERVICE_NAME "my_esp_ctrl_device" @@ -225,6 +228,7 @@ static void free_str(void *arg) /* Function used by app_main to start the esp_local_ctrl service */ void start_esp_local_ctrl_service(void) { +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE /* Set the configuration */ httpd_ssl_config_t https_conf = HTTPD_SSL_CONFIG_DEFAULT(); @@ -239,7 +243,9 @@ void start_esp_local_ctrl_service(void) extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end"); https_conf.prvtkey_pem = prvtkey_pem_start; https_conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start; - +#else + httpd_config_t http_conf = HTTPD_DEFAULT_CONFIG(); +#endif #ifdef CONFIG_EXAMPLE_PROTOCOMM_SECURITY_VERSION_1 /* What is the security level that we want (0, 1, 2): * - PROTOCOMM_SECURITY_0 is simply plain text communication. @@ -284,7 +290,11 @@ void start_esp_local_ctrl_service(void) esp_local_ctrl_config_t config = { .transport = ESP_LOCAL_CTRL_TRANSPORT_HTTPD, .transport_config = { - .httpd = &https_conf +#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE + .httpd = &https_conf, +#else + .httpd = &http_conf, +#endif }, .proto_sec = { .version = security, diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index 17819348c2f..bdc984f226e 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -42,7 +42,15 @@ def __exit__(self, type, value, traceback): # type: ignore @pytest.mark.supported_targets @pytest.mark.temp_skip_ci(targets=['esp32c6'], reason='c6 support TBD') @pytest.mark.wifi_router -def test_examples_esp_local_ctrl(dut: Dut) -> None: +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'http', + ], + indirect=True, +) +def test_examples_esp_local_ctrl(config: str, dut: Dut) -> None: rel_project_path = os.path.join('examples', 'protocols', 'esp_local_ctrl') idf_path = get_sdk_path() @@ -54,8 +62,9 @@ def test_examples_esp_local_ctrl(dut: Dut) -> None: ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') dut_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]')[1].decode() - dut.expect('esp_https_server: Starting server') - dut.expect('esp_https_server: Server listening on port 443') + if config == 'default': + dut.expect('esp_https_server: Starting server') + dut.expect('esp_https_server: Server listening on port 443') dut.expect('control: esp_local_ctrl service started with name : my_esp_ctrl_device') def dut_expect_read() -> None: @@ -66,12 +75,21 @@ def dut_expect_read() -> None: # Running mDNS services in docker is not a trivial task. Therefore, the script won't connect to the host name but # to IP address. However, the certificates were generated for the host name and will be rejected. - cmd = ' '.join([sys.executable, os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'), - '--sec_ver 2', - '--sec2_username wifiprov', - '--sec2_pwd abcd1234', - '--name', dut_ip, - '--dont-check-hostname']) # don't reject the certificate because of the hostname + if config == 'default': + cmd = ' '.join([sys.executable, os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'), + '--sec_ver 2', + '--sec2_username wifiprov', + '--sec2_pwd abcd1234', + '--name', dut_ip, + '--dont-check-hostname']) # don't reject the certificate because of the hostname + elif config == 'http': + cmd = ' '.join([sys.executable, os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'), + '--sec_ver 2', + '--transport http', + '--sec2_username wifiprov', + '--sec2_pwd abcd1234', + '--name', dut_ip, + '--dont-check-hostname']) esp_local_ctrl_log = os.path.join(idf_path, rel_project_path, 'esp_local_ctrl.log') with CustomProcess(cmd, esp_local_ctrl_log) as ctrl_py: @@ -89,7 +107,8 @@ def expect_properties(prop1: int, prop3: str) -> None: property3 = '' ctrl_py.pexpect_proc.expect_exact('Connecting to {}'.format(dut_ip)) - dut.expect('esp_https_server: performing session handshake', timeout=60) + if config == 'default': + dut.expect('esp_https_server: performing session handshake', timeout=60) expect_properties(property1, property3) ctrl_py.pexpect_proc.sendline('1') diff --git a/examples/protocols/esp_local_ctrl/scripts/esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/scripts/esp_local_ctrl.py index 7fd934ddf0a..dbbd6297249 100644 --- a/examples/protocols/esp_local_ctrl/scripts/esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/scripts/esp_local_ctrl.py @@ -127,6 +127,8 @@ async def get_transport(sel_transport, service_name, check_hostname): try: tp = None if (sel_transport == 'http'): + tp = esp_prov.transport.Transport_HTTP(service_name, None) + elif (sel_transport == 'https'): example_path = os.environ['IDF_PATH'] + '/examples/protocols/esp_local_ctrl' cert_path = example_path + '/main/certs/rootCA.pem' ssl_ctx = ssl.create_default_context(cafile=cert_path) @@ -277,7 +279,7 @@ async def main(): help='Protocol version', default='') parser.add_argument('--transport', dest='transport', type=str, - help='transport i.e http or ble', default='http') + help='transport i.e http/https/ble', default='https') parser.add_argument('--name', dest='service_name', type=str, help='BLE Device Name / HTTP Server hostname or IP', default='') @@ -332,7 +334,7 @@ async def main(): if args.service_name == '': args.service_name = 'my_esp_ctrl_device' - if args.transport == 'http': + if args.transport == 'http' or args.transport == 'https': args.service_name += '.local' obj_transport = await get_transport(args.transport, args.service_name, not args.dont_check_hostname) diff --git a/examples/protocols/esp_local_ctrl/sdkconfig.ci.http b/examples/protocols/esp_local_ctrl/sdkconfig.ci.http new file mode 100644 index 00000000000..2c0d3001114 --- /dev/null +++ b/examples/protocols/esp_local_ctrl/sdkconfig.ci.http @@ -0,0 +1,2 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y +CONFIG_ESP_HTTPS_SERVER_ENABLE=n