From 34db1a88d1a26b20df926f7b87abd7ef7d4dccdd Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Mon, 18 Apr 2022 22:56:30 +0200 Subject: [PATCH] start to move to https --- SourceCode/arduino/lib/Firewall/Firewall.cpp | 129 ++++++++++++------- SourceCode/arduino/lib/Firewall/Firewall.h | 40 +++--- SourceCode/arduino/platformio.ini | 16 +-- SourceCode/arduino/src/main.cpp | 3 +- 4 files changed, 113 insertions(+), 75 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/Firewall.cpp b/SourceCode/arduino/lib/Firewall/Firewall.cpp index 976e34c..9e16889 100644 --- a/SourceCode/arduino/lib/Firewall/Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/Firewall.cpp @@ -3,11 +3,29 @@ ESPFirewall::ESPFirewall(int port) { this->setup_eeprom(); - log_i("Starting Firewall-API on %i", port); - this->firewall_api = new AsyncWebServer(port); + this->setup_certificate(); + this->firewall_api = new httpsserver::HTTPSServer(this->certificate, port); this->setup_routing(); } +void ESPFirewall::setup_certificate() +{ + this->certificate = new httpsserver::SSLCert(); + int createCertResult = httpsserver::createSelfSignedCert( + *this->certificate, + httpsserver::KEYSIZE_2048, + "CN=myesp32.local,O=FancyCompany,C=DE", + "20190101000000", + "20300101000000"); + if (createCertResult != 0) + { + log_e("Cerating certificate failed. Error Code = 0x%02X, check SSLCert.hpp for details", createCertResult); + while (true) + delay(500); + } + log_i("Creating the certificate was successful"); +} + String ESPFirewall::protocol_to_string(firewall_protocol_t &protocol) { switch (protocol) @@ -21,11 +39,11 @@ String ESPFirewall::protocol_to_string(firewall_protocol_t &protocol) } } -firewall_protocol_t ESPFirewall::string_to_protocol(String &protocol) +firewall_protocol_t ESPFirewall::string_to_protocol(std::string &protocol) { - if (protocol.equals("TCP")) + if (protocol.compare("TCP") == 0) return FW_TCP; - else if (protocol.equals("UDP")) + else if (protocol.compare("UDP") == 0) return FW_UDP; else return FW_ALL; @@ -44,11 +62,11 @@ String ESPFirewall::target_to_string(firewall_target_t &target) } } -firewall_target_t ESPFirewall::string_to_target(String &target) +firewall_target_t ESPFirewall::string_to_target(std::string &target) { - if (target.equals("REJECT")) + if (target.compare("REJECT") == 0) return FW_REJECT; - else if (target.equals("DROP")) + else if (target.compare("DROP") == 0) return FW_DROP; else return FW_ACCEPT; @@ -208,28 +226,39 @@ bool ESPFirewall::delete_rule_from_firewall(uint8_t key) void ESPFirewall::setup_routing() { - this->firewall_api->on("^\\/api/v1/firewall\\/([0-9]+)$", HTTP_GET, std::bind(&ESPFirewall::get_firewall_rule_handler, this, std::placeholders::_1)); - this->firewall_api->on("/api/v1/firewall", HTTP_GET, std::bind(&ESPFirewall::get_firewall_rules_handler, this, std::placeholders::_1)); - this->firewall_api->on("/api/v1/firewall", HTTP_POST, std::bind(&ESPFirewall::post_firewall_handler, this, std::placeholders::_1)); - this->firewall_api->on("^\\/api/v1/firewall\\/([0-9]+)$", HTTP_DELETE, std::bind(&ESPFirewall::delete_firewall_handler, this, std::placeholders::_1)); + httpsserver::ResourceNode *firewall_get = new httpsserver::ResourceNode("/api/v1/firewall", "GET", std::bind(&ESPFirewall::get_firewall_rule_handler, this, std::placeholders::_1)); + this->firewall_api->registerNode(firewall_get); + // this->firewall_api->on("^\\/api/v1/firewall\\/([0-9]+)$", HTTP_GET, std::bind(&ESPFirewall::get_firewall_rule_handler, this, std::placeholders::_1)); + // this->firewall_api->on("/api/v1/firewall", HTTP_GET, std::bind(&ESPFirewall::get_firewall_rules_handler, this, std::placeholders::_1)); + // this->firewall_api->on("/api/v1/firewall", HTTP_POST, std::bind(&ESPFirewall::post_firewall_handler, this, std::placeholders::_1)); + // this->firewall_api->on("^\\/api/v1/firewall\\/([0-9]+)$", HTTP_DELETE, std::bind(&ESPFirewall::delete_firewall_handler, this, std::placeholders::_1)); - this->firewall_api->on("/api/v1/device/restart", HTTP_GET, std::bind(&ESPFirewall::restart_device_handler, this, std::placeholders::_1)); - this->firewall_api->onNotFound(std::bind(&ESPFirewall::not_found, this, std::placeholders::_1)); - this->firewall_api->begin(); + // this->firewall_api->on("/api/v1/device/restart", HTTP_GET, std::bind(&ESPFirewall::restart_device_handler, this, std::placeholders::_1)); + // this->firewall_api->onNotFound(std::bind(&ESPFirewall::not_found, this, std::placeholders::_1)); + // this->firewall_api->begin(); } -void ESPFirewall::json_message_response(AsyncWebServerRequest *request, String message, int response_code) +void ESPFirewall::json_generic_response(httpsserver::HTTPResponse *response, String serialized, int response_code) { - DynamicJsonDocument json(256); - String response; + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(response_code); + response->print(serialized); +} + +void ESPFirewall::json_message_response(httpsserver::HTTPResponse *response, String message, int response_code) +{ + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(response_code); + StaticJsonDocument json; + String serialized; json["message"] = message; - serializeJson(json, response); - request->send(response_code, "application/json", response); + serializeJson(json, serialized); + response->print(serialized); } String ESPFirewall::construct_json_firewall_rule(firewall_rule_t *rule_ptr) { - StaticJsonDocument<192> doc; + StaticJsonDocument doc; doc["key"] = rule_ptr->key; doc["source"] = rule_ptr->source; doc["destination"] = rule_ptr->destination; @@ -262,77 +291,85 @@ String ESPFirewall::construct_json_firewall() return response; } -void ESPFirewall::not_found(AsyncWebServerRequest *request) +void ESPFirewall::not_found(httpsserver::HTTPRequest *request, httpsserver::HTTPResponse *response) { - this->json_message_response(request, "not found", 404); + this->json_message_response(response, "not found", 404); } -void ESPFirewall::restart_device_handler(AsyncWebServerRequest *request) +void ESPFirewall::restart_device_handler(httpsserver::HTTPRequest *request, httpsserver::HTTPResponse *response) { - this->json_message_response(request, "restarting device in 2 sec", 200); + this->json_message_response(response, "restarting device in 2 sec", 200); sleep(2000); esp_restart(); } -void ESPFirewall::get_firewall_rule_handler(AsyncWebServerRequest *request) +void ESPFirewall::get_firewall_rule_handler(httpsserver::HTTPRequest *request, httpsserver::HTTPResponse *response) { - int rule_number = request->pathArg(0).toInt(); + httpsserver::ResourceParameters *params = request->getParams(); + int rule_number = atoi(params->getPathParameter(0).c_str()); firewall_rule_t *rule_ptr = this->get_rule_from_firewall(rule_number); if (rule_ptr == NULL) { - this->json_message_response(request, "rule not found", 404); + this->json_message_response(response, "rule not found", 404); } else { - request->send(200, "application/json", this->construct_json_firewall_rule(rule_ptr)); + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(200); + response->print(this->construct_json_firewall_rule(rule_ptr)); } } -void ESPFirewall::get_firewall_rules_handler(AsyncWebServerRequest *request) +void ESPFirewall::get_firewall_rules_handler(httpsserver::HTTPRequest *request, httpsserver::HTTPResponse *response) { - String response = this->construct_json_firewall(); - request->send(200, "application/json", response); + this->json_generic_response(response, this->construct_json_firewall(), 200); } -bool ESPFirewall::request_has_firewall_parameter(AsyncWebServerRequest *request) +bool ESPFirewall::request_has_firewall_parameter(httpsserver::ResourceParameters *params) { - return request->hasParam("source") || request->hasParam("destination") || request->hasParam("protocol") || request->hasParam("target"); + return params->isQueryParameterSet("source") || params->isQueryParameterSet("destination") || params->isQueryParameterSet("protocol") || params->isQueryParameterSet("target"); } -void ESPFirewall::post_firewall_handler(AsyncWebServerRequest *request) +void ESPFirewall::post_firewall_handler(httpsserver::HTTPRequest *request, httpsserver::HTTPResponse *response) { - if (request_has_firewall_parameter(request)) + httpsserver::ResourceParameters *params = request->getParams(); + if (request_has_firewall_parameter(params)) { firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); rule_ptr->key = ++amount_of_rules; // carefully copying c-string that is shorter then the destination char-array length - String source = request->getParam("source")->value(); + std::string source; + params->getQueryParameter("source", source); strcpy(rule_ptr->source, source.length() <= IP4ADDR_STRLEN_MAX ? source.c_str() : ""); - String destination = request->getParam("destination")->value(); + std::string destination; + params->getQueryParameter("destination", destination); strcpy(rule_ptr->destination, destination.length() <= IP4ADDR_STRLEN_MAX ? destination.c_str() : ""); - String protocol = request->getParam("protocol")->value(); + std::string protocol; + params->getQueryParameter("protocol", protocol); rule_ptr->protocol = string_to_protocol(protocol); - String target = request->getParam("target")->value(); + std::string target; + params->getQueryParameter("target", target); rule_ptr->target = string_to_target(target); this->add_rule_to_firewall(rule_ptr); this->eeprom_write_firewall_rule(rule_ptr); - request->send(200, "application/json", this->construct_json_firewall_rule(rule_ptr)); + this->json_generic_response(response, this->construct_json_firewall_rule(rule_ptr), 200); } else { - this->json_message_response(request, "not enough parameter", 200); + this->json_message_response(response, "not enough parameter", 400); } } -void ESPFirewall::delete_firewall_handler(AsyncWebServerRequest *request) +void ESPFirewall::delete_firewall_handler(httpsserver::HTTPRequest *request, httpsserver::HTTPResponse *response) { - int rule_number = request->pathArg(0).toInt(); + httpsserver::ResourceParameters *params = request->getParams(); + int rule_number = atoi(params->getPathParameter(0).c_str()); if (this->delete_rule_from_firewall(rule_number)) { - this->json_message_response(request, "firewall rule deleted", 200); + this->json_message_response(response, "firewall rule deleted", 200); } - this->json_message_response(request, "cannot delete firewall rule", 500); + this->json_message_response(response, "cannot delete firewall rule", 500); } diff --git a/SourceCode/arduino/lib/Firewall/Firewall.h b/SourceCode/arduino/lib/Firewall/Firewall.h index 65033c4..a4aa3c4 100644 --- a/SourceCode/arduino/lib/Firewall/Firewall.h +++ b/SourceCode/arduino/lib/Firewall/Firewall.h @@ -2,17 +2,13 @@ #define FIREWALL_H #include "Arduino.h" -#include "AsyncJson.h" #include "ArduinoJson.h" #include "EEPROM.h" -#ifdef ESP32 -#include "WiFi.h" -#include "AsyncTCP.h" -#elif defined(ESP8266) -#include "ESP8266WiFi.h" -#include "ESPAsyncTCP.h" -#endif -#include "ESPAsyncWebServer.h" + +#include "HTTPSServer.hpp" +#include "SSLCert.hpp" +#include "HTTPRequest.hpp" +#include "HTTPResponse.hpp" #define eeprom_start_firewall_rules 4 @@ -49,13 +45,16 @@ class ESPFirewall int eeprom_rules_head = eeprom_start_firewall_rules; struct firewall_rule *head = NULL; - AsyncWebServer *firewall_api; + httpsserver::HTTPSServer *firewall_api; + httpsserver::SSLCert *certificate; + + void setup_certificate(); // Protocol / Target conversion String protocol_to_string(firewall_protocol_t &); - firewall_protocol_t string_to_protocol(String &); + firewall_protocol_t string_to_protocol(std::string &); String target_to_string(firewall_target_t &); - firewall_target_t string_to_target(String &); + firewall_target_t string_to_target(std::string &); // EEPROM void setup_eeprom(); @@ -71,16 +70,17 @@ class ESPFirewall // Firewall-API Actions void setup_routing(); - void json_message_response(AsyncWebServerRequest *, String, int); + void json_generic_response(httpsserver::HTTPResponse *, String, int); + void json_message_response(httpsserver::HTTPResponse *, String, int); String construct_json_firewall_rule(firewall_rule_t *); String construct_json_firewall(); - void not_found(AsyncWebServerRequest *); - void restart_device_handler(AsyncWebServerRequest *); - void get_firewall_rule_handler(AsyncWebServerRequest *); - void get_firewall_rules_handler(AsyncWebServerRequest *); - bool request_has_firewall_parameter(AsyncWebServerRequest *); - void post_firewall_handler(AsyncWebServerRequest *); - void delete_firewall_handler(AsyncWebServerRequest *); + void not_found(httpsserver::HTTPRequest *, httpsserver::HTTPResponse *); + void restart_device_handler(httpsserver::HTTPRequest *, httpsserver::HTTPResponse *); + void get_firewall_rule_handler(httpsserver::HTTPRequest *, httpsserver::HTTPResponse *); + void get_firewall_rules_handler(httpsserver::HTTPRequest *, httpsserver::HTTPResponse *); + bool request_has_firewall_parameter(httpsserver::ResourceParameters *); + void post_firewall_handler(httpsserver::HTTPRequest *, httpsserver::HTTPResponse *); + void delete_firewall_handler(httpsserver::HTTPRequest *, httpsserver::HTTPResponse *); public: ESPFirewall(int port = 8080); diff --git a/SourceCode/arduino/platformio.ini b/SourceCode/arduino/platformio.ini index 4c4e078..556d85d 100644 --- a/SourceCode/arduino/platformio.ini +++ b/SourceCode/arduino/platformio.ini @@ -13,21 +13,21 @@ platform = espressif32 board = esp32-evb framework = arduino monitor_speed = 115200 -build_flags = +build_flags = -DCORE_DEBUG_LEVEL=3 - -DASYNCWEBSERVER_REGEX -lib_deps = + -DASYNCWEBSERVER_REGEX +lib_deps = bblanchon/ArduinoJson@^6.19.4 - ottowinter/ESPAsyncWebServer-esphome@^2.1.0 + fhessel/esp32_https_server@^1.0.0 [env:esp32-dev] platform = espressif32 board = az-delivery-devkit-v4 framework = arduino monitor_speed = 115200 -build_flags = +build_flags = -DCORE_DEBUG_LEVEL=3 - -DASYNCWEBSERVER_REGEX -lib_deps = + -DASYNCWEBSERVER_REGEX +lib_deps = bblanchon/ArduinoJson@^6.19.4 - ottowinter/ESPAsyncWebServer-esphome@^2.1.0 + fhessel/esp32_https_server@^1.0.0 diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index 08e942a..6693c4f 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -1,5 +1,6 @@ -#include +#include "Arduino.h" #include "theSecrets.h" +#include "WiFi.h" #include "Firewall.h" #include "esp32-hal-log.h"