From b2c2a967d919b3ff3dea843a29bfc68dc4a26509 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 07:58:06 +0200 Subject: [PATCH 01/15] create seperate api class --- .../arduino/lib/Firewall/esp32Firewall.cpp | 32 +------- .../arduino/lib/Firewall/esp32Firewall.hpp | 5 +- .../arduino/lib/Firewall/esp32FirewallAPI.cpp | 76 +++++++++++++++++++ .../arduino/lib/Firewall/esp32FirewallAPI.hpp | 29 +++++++ SourceCode/arduino/src/main.cpp | 12 +-- 5 files changed, 114 insertions(+), 40 deletions(-) create mode 100644 SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp create mode 100644 SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp index 14236fd..2bcd5b2 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp @@ -1,22 +1,8 @@ #include "esp32Firewall.hpp" -esp32Firewall::esp32Firewall(const uint16_t api_port) +esp32Firewall::esp32Firewall() { this->setup_eeprom(); - this->setup_certificate(); - this->firewall_api = new HTTPSServer(this->certificate, api_port, 5); - this->setup_routing(); - log_i("Starting server..."); - this->firewall_api->start(); - if (this->firewall_api->isRunning()) - { - log_i("Server ready."); - } -} - -void esp32Firewall::handle_firewall_api_clients() -{ - this->firewall_api->loop(); } String esp32Firewall::protocol_to_string(firewall_protocol_t &protocol) @@ -242,14 +228,10 @@ void esp32Firewall::setup_routing() ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&esp32Firewall::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&esp32Firewall::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&esp32Firewall::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *restart_device = new ResourceNode("/api/v1/device/restart", "GET", std::bind(&esp32Firewall::restart_device_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&esp32Firewall::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); this->firewall_api->registerNode(get_firewall_rule); this->firewall_api->registerNode(get_firewall_rules); this->firewall_api->registerNode(post_firewall); this->firewall_api->registerNode(delete_firewall); - this->firewall_api->setDefaultNode(restart_device); - this->firewall_api->setDefaultNode(not_found); } void esp32Firewall::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) @@ -305,18 +287,6 @@ String esp32Firewall::construct_json_firewall() return response; } -void esp32Firewall::not_found_handler(HTTPRequest *request, HTTPResponse *response) -{ - this->json_message_response(response, "not found", 404); -} - -void esp32Firewall::restart_device_handler(HTTPRequest *request, HTTPResponse *response) -{ - this->json_message_response(response, "restarting device in 2 sec", 200); - sleep(2000); - esp_restart(); -} - void esp32Firewall::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) { ResourceParameters *params = request->getParams(); diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp index 5dd9ae6..bc6c9ae 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp @@ -52,8 +52,6 @@ class esp32Firewall void json_message_response(HTTPResponse *, String, const uint16_t); String construct_json_firewall_rule(firewall_rule_t *); String construct_json_firewall(); - void not_found_handler(HTTPRequest *, HTTPResponse *); - void restart_device_handler(HTTPRequest *, HTTPResponse *); void get_firewall_rule_handler(HTTPRequest *, HTTPResponse *); void get_firewall_rules_handler(HTTPRequest *, HTTPResponse *); bool request_has_firewall_parameter(ResourceParameters *); @@ -61,8 +59,7 @@ class esp32Firewall void delete_firewall_handler(HTTPRequest *, HTTPResponse *); public: - esp32Firewall(const uint16_t = 8080); - void handle_firewall_api_clients(); + esp32Firewall(); }; #endif diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp new file mode 100644 index 0000000..68b4546 --- /dev/null +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp @@ -0,0 +1,76 @@ +#include "esp32FirewallAPI.hpp" + +esp32FirewallApi::esp32FirewallApi(const uint16_t port) +{ + this->setup_certificate(); + this->server = new HTTPSServer(this->certificate, port, 5); + this->setup_routing(); + log_i("Starting server..."); + this->server->start(); + if (this->server->isRunning()) + { + log_i("Server ready."); + } +} + +void esp32FirewallApi::handle_clients() +{ + this->server->loop(); +} + +void esp32FirewallApi::setup_certificate() +{ + log_i("Creating the certificate..."); + this->certificate = new SSLCert(); + int createCertResult = createSelfSignedCert( + *this->certificate, + KEYSIZE_2048, + "CN=myesp32.local,O=Firewall,C=DE", + "20220101000000", + "20320101000000"); + 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"); +} + +void esp32FirewallApi::setup_routing() +{ + ResourceNode *restart_device = new ResourceNode("/api/v1/device/restart", "GET", std::bind(&esp32FirewallApi::restart_device_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&esp32FirewallApi::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); + this->server->registerNode(restart_device); + this->server->setDefaultNode(not_found); +} + +void esp32FirewallApi::restart_device_handler(HTTPRequest *request, HTTPResponse *response) +{ + this->json_message_response(response, "restarting device in 2 sec", 200); + sleep(2000); + esp_restart(); +} + +void esp32FirewallApi::not_found_handler(HTTPRequest *request, HTTPResponse *response) +{ + this->json_message_response(response, "not found", 404); +} + +void esp32FirewallApi::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) +{ + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(response_code); + response->println(serialized); +} + +void esp32FirewallApi::json_message_response(HTTPResponse *response, String message, const uint16_t response_code) +{ + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(response_code); + StaticJsonDocument<96> json; + String serialized; + json["message"] = message; + serializeJson(json, serialized); + response->println(serialized); +} diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp new file mode 100644 index 0000000..94ed396 --- /dev/null +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp @@ -0,0 +1,29 @@ +#ifndef ESP32_FIREWALL_API_HPP +#define ESP32_FIREWALL_API_HPP + +#include "HTTPSServer.hpp" +#include "SSLCert.hpp" +#include "HTTPRequest.hpp" +#include "HTTPResponse.hpp" +#include "ArduinoJson.h" + +using namespace httpsserver; + +class esp32FirewallApi +{ + HTTPSServer *server; + SSLCert *certificate; + + void setup_certificate(); + void setup_routing(); + void restart_device_handler(HTTPRequest *, HTTPResponse *); + void not_found_handler(HTTPRequest *, HTTPResponse *); + +public: + esp32FirewallApi(const uint16_t = 8080); + void handle_clients(); + void json_generic_response(HTTPResponse *, String, const uint16_t); + void json_message_response(HTTPResponse *, String, const uint16_t); +}; + +#endif diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index 014c894..914b519 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -1,8 +1,10 @@ #include "theSecrets.h" #include "WiFi.h" -#include "esp32Firewall.hpp" -const char *esp_ip_address; +#include "esp32Firewall.hpp" +#include "esp32FirewallAPI.hpp" + +esp32FirewallApi *firewall_api; esp32Firewall *firewall; void setup_wifi() @@ -17,17 +19,17 @@ void setup_wifi() delay(2000); log_d("Connecting... (%i/%i)", retries++, max_retries); } - esp_ip_address = WiFi.localIP().toString().c_str(); - log_i("Connected, IP Address: %s", esp_ip_address); + log_i("Connected, IP Address: %s", WiFi.localIP().toString()); } void setup() { setup_wifi(); firewall = new esp32Firewall; + firewall_api = new esp32FirewallApi; } void loop() { - firewall->handle_firewall_api_clients(); + firewall_api->handle_clients(); } \ No newline at end of file From 790371a099f3e243c6e7a7ba10701133504d95aa Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 08:17:55 +0200 Subject: [PATCH 02/15] works with inheritance --- .../arduino/lib/Firewall/esp32Firewall.cpp | 166 +----------------- .../arduino/lib/Firewall/esp32Firewall.hpp | 40 ++--- .../arduino/lib/Firewall/esp32FirewallAPI.cpp | 117 ++++++++++++ .../arduino/lib/Firewall/esp32FirewallAPI.hpp | 16 +- SourceCode/arduino/src/main.cpp | 2 - 5 files changed, 144 insertions(+), 197 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp index 2bcd5b2..d77e67a 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp @@ -71,9 +71,9 @@ void esp32Firewall::eeprom_write_firewall_rule(firewall_rule_t *rule_ptr) { EEPROM.write(this->eeprom_settings_head, this->amount_of_rules); EEPROM.writeString(this->eeprom_rules_head, rule_ptr->source); - this->eeprom_rules_head += IP4ADDR_STRLEN_MAX; + this->eeprom_rules_head += IPV4ADDRESS_LENGTH; EEPROM.writeString(this->eeprom_rules_head, rule_ptr->destination); - this->eeprom_rules_head += IP4ADDR_STRLEN_MAX; + this->eeprom_rules_head += IPV4ADDRESS_LENGTH; EEPROM.write(this->eeprom_rules_head, rule_ptr->protocol); this->eeprom_rules_head += sizeof(firewall_protocol_t); EEPROM.write(this->eeprom_rules_head, rule_ptr->target); @@ -97,9 +97,9 @@ void esp32Firewall::eeprom_read_firewall_rule(uint8_t &eeprom_address, uint8_t & firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); rule_ptr->key = rule_nr; strcpy(rule_ptr->source, EEPROM.readString(eeprom_address).c_str()); - eeprom_address += IP4ADDR_STRLEN_MAX; + eeprom_address += IPV4ADDRESS_LENGTH; strcpy(rule_ptr->destination, EEPROM.readString(eeprom_address).c_str()); - eeprom_address += IP4ADDR_STRLEN_MAX; + eeprom_address += IPV4ADDRESS_LENGTH; rule_ptr->protocol = static_cast(EEPROM.read(eeprom_address)); eeprom_address += sizeof(firewall_protocol_t); rule_ptr->target = static_cast(EEPROM.read(eeprom_address)); @@ -202,161 +202,3 @@ bool esp32Firewall::delete_rule_from_firewall(uint8_t key) this->eeprom_write_firewall_rules(); return true; } - -void esp32Firewall::setup_certificate() -{ - log_i("Creating the certificate..."); - this->certificate = new SSLCert(); - int createCertResult = createSelfSignedCert( - *this->certificate, - KEYSIZE_2048, - "CN=myesp32.local,O=Firewall,C=DE", - "20220101000000", - "20320101000000"); - 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"); -} - -void esp32Firewall::setup_routing() -{ - ResourceNode *get_firewall_rule = new ResourceNode("/api/v1/firewall/*", "GET", std::bind(&esp32Firewall::get_firewall_rule_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&esp32Firewall::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&esp32Firewall::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&esp32Firewall::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - this->firewall_api->registerNode(get_firewall_rule); - this->firewall_api->registerNode(get_firewall_rules); - this->firewall_api->registerNode(post_firewall); - this->firewall_api->registerNode(delete_firewall); -} - -void esp32Firewall::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) -{ - response->setHeader("Content-Type", "application/json"); - response->setStatusCode(response_code); - response->println(serialized); -} - -void esp32Firewall::json_message_response(HTTPResponse *response, String message, const uint16_t response_code) -{ - response->setHeader("Content-Type", "application/json"); - response->setStatusCode(response_code); - StaticJsonDocument<96> json; - String serialized; - json["message"] = message; - serializeJson(json, serialized); - response->println(serialized); -} - -String esp32Firewall::construct_json_firewall_rule(firewall_rule_t *rule_ptr) -{ - StaticJsonDocument<256> doc; - doc["key"] = rule_ptr->key; - doc["source"] = rule_ptr->source; - doc["destination"] = rule_ptr->destination; - doc["protocol"] = protocol_to_string(rule_ptr->protocol); - doc["target"] = target_to_string(rule_ptr->target); - String response; - serializeJson(doc, response); - return response; -} - -String esp32Firewall::construct_json_firewall() -{ - firewall_rule_t *rule_ptr = this->head; - // Size for approx. 12 Rules - StaticJsonDocument<2048> doc; - String response; - doc["amount_of_rules"] = this->amount_of_rules; - JsonArray rules = doc.createNestedArray("rules"); - while (rule_ptr != NULL) - { - JsonObject rule = rules.createNestedObject(); - rule["key"] = rule_ptr->key; - rule["source"] = rule_ptr->source; - rule["destination"] = rule_ptr->destination; - rule["protocol"] = protocol_to_string(rule_ptr->protocol); - rule["target"] = target_to_string(rule_ptr->target); - rule_ptr = rule_ptr->next; - } - serializeJson(doc, response); - return response; -} - -void esp32Firewall::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) -{ - 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(response, "rule not found", 404); - } - else - { - response->setHeader("Content-Type", "application/json"); - response->setStatusCode(200); - response->print(this->construct_json_firewall_rule(rule_ptr)); - } -} - -void esp32Firewall::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) -{ - this->json_generic_response(response, this->construct_json_firewall(), 200); -} - -bool esp32Firewall::request_has_firewall_parameter(ResourceParameters *params) -{ - return params->isQueryParameterSet("source") || params->isQueryParameterSet("destination") || params->isQueryParameterSet("protocol") || params->isQueryParameterSet("target"); -} - -void esp32Firewall::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) -{ - 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 - std::string source; - params->getQueryParameter("source", source); - strcpy(rule_ptr->source, source.length() <= IPV4ADDRESS_LENGTH ? source.c_str() : ""); - std::string destination; - params->getQueryParameter("destination", destination); - strcpy(rule_ptr->destination, destination.length() <= IPV4ADDRESS_LENGTH ? destination.c_str() : ""); - - std::string protocol; - params->getQueryParameter("protocol", protocol); - rule_ptr->protocol = string_to_protocol(protocol); - 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); - this->json_generic_response(response, this->construct_json_firewall_rule(rule_ptr), 200); - } - else - { - this->json_message_response(response, "not enough parameter", 400); - } -} - -void esp32Firewall::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) -{ - 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(response, "firewall rule deleted", 200); - } - else - { - this->json_message_response(response, "cannot delete firewall rule", 500); - } -} diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp index bc6c9ae..15781b6 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp @@ -5,8 +5,6 @@ #include "ArduinoJson.h" #include "EEPROM.h" -#include "HTTPSServer.hpp" -#include "SSLCert.hpp" #include "HTTPRequest.hpp" #include "HTTPResponse.hpp" @@ -18,48 +16,30 @@ using namespace httpsserver; class esp32Firewall { uint16_t eeprom_size = 512; - uint8_t amount_of_rules = 0; uint8_t security_number = 93; int eeprom_settings_head = 0; int eeprom_rules_head = eeprom_start_firewall_rules; - struct firewall_rule *head = NULL; - HTTPSServer *firewall_api; - SSLCert *certificate; - - // Protocol / Target conversion - String protocol_to_string(firewall_protocol_t &); - firewall_protocol_t string_to_protocol(std::string &); - String target_to_string(firewall_target_t &); - firewall_target_t string_to_target(std::string &); - - // EEPROM void setup_eeprom(); - void eeprom_write_firewall_rule(firewall_rule_t *); void eeprom_write_firewall_rules(); void eeprom_read_firewall_rule(uint8_t &, uint8_t &); void eeprom_read_firewall_rules(); - // Firewall Actions +public: + uint8_t amount_of_rules = 0; + struct firewall_rule *head = NULL; + + esp32Firewall(); void add_rule_to_firewall(firewall_rule_t *); firewall_rule_t *get_rule_from_firewall(uint8_t); bool delete_rule_from_firewall(uint8_t); - // Firewall-API Actions - void setup_certificate(); - void setup_routing(); - void json_generic_response(HTTPResponse *, String, const uint16_t); - void json_message_response(HTTPResponse *, String, const uint16_t); - String construct_json_firewall_rule(firewall_rule_t *); - String construct_json_firewall(); - void get_firewall_rule_handler(HTTPRequest *, HTTPResponse *); - void get_firewall_rules_handler(HTTPRequest *, HTTPResponse *); - bool request_has_firewall_parameter(ResourceParameters *); - void post_firewall_handler(HTTPRequest *, HTTPResponse *); - void delete_firewall_handler(HTTPRequest *, HTTPResponse *); + void eeprom_write_firewall_rule(firewall_rule_t *); -public: - esp32Firewall(); + String protocol_to_string(firewall_protocol_t &); + firewall_protocol_t string_to_protocol(std::string &); + String target_to_string(firewall_target_t &); + firewall_target_t string_to_target(std::string &); }; #endif diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp index 68b4546..591e42b 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp @@ -39,8 +39,16 @@ void esp32FirewallApi::setup_certificate() void esp32FirewallApi::setup_routing() { + ResourceNode *get_firewall_rule = new ResourceNode("/api/v1/firewall/*", "GET", std::bind(&esp32FirewallApi::get_firewall_rule_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&esp32FirewallApi::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&esp32FirewallApi::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&esp32FirewallApi::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); ResourceNode *restart_device = new ResourceNode("/api/v1/device/restart", "GET", std::bind(&esp32FirewallApi::restart_device_handler, this, std::placeholders::_1, std::placeholders::_2)); ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&esp32FirewallApi::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); + this->server->registerNode(get_firewall_rule); + this->server->registerNode(get_firewall_rules); + this->server->registerNode(post_firewall); + this->server->registerNode(delete_firewall); this->server->registerNode(restart_device); this->server->setDefaultNode(not_found); } @@ -57,6 +65,80 @@ void esp32FirewallApi::not_found_handler(HTTPRequest *request, HTTPResponse *res this->json_message_response(response, "not found", 404); } +void esp32FirewallApi::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) +{ + 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(response, "rule not found", 404); + } + else + { + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(200); + response->print(this->construct_json_firewall_rule(rule_ptr)); + } +} + +void esp32FirewallApi::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) +{ + this->json_generic_response(response, this->construct_json_firewall(), 200); +} + +bool esp32FirewallApi::request_has_firewall_parameter(ResourceParameters *params) +{ + return params->isQueryParameterSet("source") || params->isQueryParameterSet("destination") || params->isQueryParameterSet("protocol") || params->isQueryParameterSet("target"); +} + +void esp32FirewallApi::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) +{ + 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 + std::string source; + params->getQueryParameter("source", source); + strcpy(rule_ptr->source, source.length() <= IPV4ADDRESS_LENGTH ? source.c_str() : ""); + std::string destination; + params->getQueryParameter("destination", destination); + strcpy(rule_ptr->destination, destination.length() <= IPV4ADDRESS_LENGTH ? destination.c_str() : ""); + + std::string protocol; + params->getQueryParameter("protocol", protocol); + rule_ptr->protocol = string_to_protocol(protocol); + 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); + this->json_generic_response(response, this->construct_json_firewall_rule(rule_ptr), 200); + } + else + { + this->json_message_response(response, "not enough parameter", 400); + } +} + +void esp32FirewallApi::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) +{ + 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(response, "firewall rule deleted", 200); + } + else + { + this->json_message_response(response, "cannot delete firewall rule", 500); + } +} + void esp32FirewallApi::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) { response->setHeader("Content-Type", "application/json"); @@ -74,3 +156,38 @@ void esp32FirewallApi::json_message_response(HTTPResponse *response, String mess serializeJson(json, serialized); response->println(serialized); } + +String esp32FirewallApi::construct_json_firewall_rule(firewall_rule_t *rule_ptr) +{ + StaticJsonDocument<256> doc; + doc["key"] = rule_ptr->key; + doc["source"] = rule_ptr->source; + doc["destination"] = rule_ptr->destination; + doc["protocol"] = protocol_to_string(rule_ptr->protocol); + doc["target"] = target_to_string(rule_ptr->target); + String response; + serializeJson(doc, response); + return response; +} + +String esp32FirewallApi::construct_json_firewall() +{ + firewall_rule_t *rule_ptr = this->head; + // Size for approx. 12 Rules + StaticJsonDocument<2048> doc; + String response; + doc["amount_of_rules"] = this->amount_of_rules; + JsonArray rules = doc.createNestedArray("rules"); + while (rule_ptr != NULL) + { + JsonObject rule = rules.createNestedObject(); + rule["key"] = rule_ptr->key; + rule["source"] = rule_ptr->source; + rule["destination"] = rule_ptr->destination; + rule["protocol"] = protocol_to_string(rule_ptr->protocol); + rule["target"] = target_to_string(rule_ptr->target); + rule_ptr = rule_ptr->next; + } + serializeJson(doc, response); + return response; +} \ No newline at end of file diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp index 94ed396..95672a9 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp @@ -7,23 +7,33 @@ #include "HTTPResponse.hpp" #include "ArduinoJson.h" +#include "esp32Firewall.hpp" + using namespace httpsserver; -class esp32FirewallApi +class esp32FirewallApi : public esp32Firewall { HTTPSServer *server; SSLCert *certificate; void setup_certificate(); void setup_routing(); + void get_firewall_rule_handler(HTTPRequest *, HTTPResponse *); + void get_firewall_rules_handler(HTTPRequest *, HTTPResponse *); + bool request_has_firewall_parameter(ResourceParameters *); + void post_firewall_handler(HTTPRequest *, HTTPResponse *); + void delete_firewall_handler(HTTPRequest *, HTTPResponse *); void restart_device_handler(HTTPRequest *, HTTPResponse *); void not_found_handler(HTTPRequest *, HTTPResponse *); + void json_generic_response(HTTPResponse *, String, const uint16_t); + void json_message_response(HTTPResponse *, String, const uint16_t); + String construct_json_firewall_rule(firewall_rule_t *); + String construct_json_firewall(); + public: esp32FirewallApi(const uint16_t = 8080); void handle_clients(); - void json_generic_response(HTTPResponse *, String, const uint16_t); - void json_message_response(HTTPResponse *, String, const uint16_t); }; #endif diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index 914b519..f28d940 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -5,7 +5,6 @@ #include "esp32FirewallAPI.hpp" esp32FirewallApi *firewall_api; -esp32Firewall *firewall; void setup_wifi() { @@ -25,7 +24,6 @@ void setup_wifi() void setup() { setup_wifi(); - firewall = new esp32Firewall; firewall_api = new esp32FirewallApi; } From d0eeab9c52b7a01b4b14f069621605ce5389f72e Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 08:21:04 +0200 Subject: [PATCH 03/15] remove old imports --- SourceCode/arduino/lib/Firewall/esp32Firewall.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp index 15781b6..800f533 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp @@ -1,17 +1,10 @@ #ifndef ESP32_FIREWALL_HPP #define ESP32_FIREWALL_HPP -#include "Arduino.h" -#include "ArduinoJson.h" #include "EEPROM.h" - -#include "HTTPRequest.hpp" -#include "HTTPResponse.hpp" - #include "FirewallTypes.h" #define eeprom_start_firewall_rules 4 -using namespace httpsserver; class esp32Firewall { From 0c7cbae18ae4f24f44bb3b407ce137ae61cd8def Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 11:06:17 +0200 Subject: [PATCH 04/15] ip needs to be c_str for console --- SourceCode/arduino/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index f28d940..def7ff8 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -18,7 +18,7 @@ void setup_wifi() delay(2000); log_d("Connecting... (%i/%i)", retries++, max_retries); } - log_i("Connected, IP Address: %s", WiFi.localIP().toString()); + log_i("Connected, IP Address: %s", WiFi.localIP().toString().c_str()); } void setup() From 73533e5d156765f245904a5baf18a97d9557b2c5 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 11:40:00 +0200 Subject: [PATCH 05/15] cleanup classes --- SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp | 11 +++++++++++ SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp | 16 ++++++++++++++++ .../arduino/lib/Firewall/esp32Firewall.cpp | 4 ++++ .../arduino/lib/Firewall/esp32Firewall.hpp | 8 ++++++-- .../arduino/lib/Firewall/esp32FirewallAPI.cpp | 4 ++++ .../arduino/lib/Firewall/esp32FirewallAPI.hpp | 2 ++ 6 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp create mode 100644 SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp diff --git a/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp b/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp new file mode 100644 index 0000000..51c99ee --- /dev/null +++ b/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp @@ -0,0 +1,11 @@ +#include "esp32Eeprom.hpp" + +esp32Eeprom::esp32Eeprom(const uint16_t eeprom_size) +{ + this->eeprom_size = eeprom_size; + EEPROM.begin(this->eeprom_size); +} + +esp32Eeprom::~esp32Eeprom() +{ +} diff --git a/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp b/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp new file mode 100644 index 0000000..17ed859 --- /dev/null +++ b/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp @@ -0,0 +1,16 @@ +#ifndef ESP32_EEPROM_HPP +#define ESP32_EEPROM_HPP + +#include "EEPROM.h" + +class esp32Eeprom +{ +private: + uint16_t eeprom_size; + +public: + esp32Eeprom(const uint16_t); + ~esp32Eeprom(); +}; + +#endif diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp index d77e67a..6793a9d 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp @@ -5,6 +5,10 @@ esp32Firewall::esp32Firewall() this->setup_eeprom(); } +esp32Firewall::~esp32Firewall() +{ +} + String esp32Firewall::protocol_to_string(firewall_protocol_t &protocol) { switch (protocol) diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp index 800f533..a9c6b39 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp @@ -8,6 +8,7 @@ class esp32Firewall { +private: uint16_t eeprom_size = 512; uint8_t security_number = 93; int eeprom_settings_head = 0; @@ -18,11 +19,10 @@ class esp32Firewall void eeprom_read_firewall_rule(uint8_t &, uint8_t &); void eeprom_read_firewall_rules(); -public: +protected: uint8_t amount_of_rules = 0; struct firewall_rule *head = NULL; - esp32Firewall(); void add_rule_to_firewall(firewall_rule_t *); firewall_rule_t *get_rule_from_firewall(uint8_t); bool delete_rule_from_firewall(uint8_t); @@ -33,6 +33,10 @@ public: firewall_protocol_t string_to_protocol(std::string &); String target_to_string(firewall_target_t &); firewall_target_t string_to_target(std::string &); + +public: + esp32Firewall(); + ~esp32Firewall(); }; #endif diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp index 591e42b..c5275ff 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp @@ -13,6 +13,10 @@ esp32FirewallApi::esp32FirewallApi(const uint16_t port) } } +esp32FirewallApi::~esp32FirewallApi() +{ +} + void esp32FirewallApi::handle_clients() { this->server->loop(); diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp index 95672a9..238ab57 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp @@ -13,6 +13,7 @@ using namespace httpsserver; class esp32FirewallApi : public esp32Firewall { +private: HTTPSServer *server; SSLCert *certificate; @@ -33,6 +34,7 @@ class esp32FirewallApi : public esp32Firewall public: esp32FirewallApi(const uint16_t = 8080); + ~esp32FirewallApi(); void handle_clients(); }; From beddd886537b341aca36ba4f56693ef76878e086 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 13:08:12 +0200 Subject: [PATCH 06/15] introduce namespace --- .../arduino/lib/Firewall/esp32Eeprom.cpp | 27 +- .../arduino/lib/Firewall/esp32Eeprom.hpp | 29 +- .../arduino/lib/Firewall/esp32Firewall.cpp | 357 +++++++++--------- .../arduino/lib/Firewall/esp32Firewall.hpp | 53 +-- .../arduino/lib/Firewall/esp32FirewallAPI.cpp | 351 ++++++++--------- .../arduino/lib/Firewall/esp32FirewallAPI.hpp | 47 +-- SourceCode/arduino/src/main.cpp | 10 +- 7 files changed, 459 insertions(+), 415 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp b/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp index 51c99ee..5e6ae6f 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp @@ -1,11 +1,26 @@ #include "esp32Eeprom.hpp" -esp32Eeprom::esp32Eeprom(const uint16_t eeprom_size) +namespace firewall { - this->eeprom_size = eeprom_size; - EEPROM.begin(this->eeprom_size); -} + Storage::Storage(const uint16_t eeprom_size) + { + this->eeprom_size = eeprom_size; + EEPROM.begin(this->eeprom_size); + set_amount_of_firewall_rules(EEPROM.read(this->settings_head)); + log_i("Amount of Rules: %i", get_amount_of_firewall_rules()); + } -esp32Eeprom::~esp32Eeprom() -{ + Storage::~Storage() + { + } + + uint8_t Storage::get_amount_of_firewall_rules() + { + return this->amount_of_rules; + } + + void Storage::set_amount_of_firewall_rules(const uint8_t new_amount) + { + this->amount_of_rules = new_amount; + } } diff --git a/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp b/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp index 17ed859..e8d04f7 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp @@ -2,15 +2,30 @@ #define ESP32_EEPROM_HPP #include "EEPROM.h" +#include "FirewallTypes.h" -class esp32Eeprom +namespace firewall { -private: - uint16_t eeprom_size; + class Storage + { + private: + uint16_t eeprom_size; + uint16_t settings_start = 0; + uint16_t settings_head = settings_start; + uint16_t rules_start = 1000; + uint16_t rules_head = rules_start; + uint16_t certificate_start = 3000; + uint16_t certificate_head = certificate_start; -public: - esp32Eeprom(const uint16_t); - ~esp32Eeprom(); -}; + protected: + uint8_t amount_of_rules; + uint8_t get_amount_of_firewall_rules(); + void set_amount_of_firewall_rules(const uint8_t); + + public: + Storage(const uint16_t = 4000); + ~Storage(); + }; +} #endif diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp index 6793a9d..9d18430 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp @@ -1,208 +1,211 @@ #include "esp32Firewall.hpp" -esp32Firewall::esp32Firewall() +namespace firewall { - this->setup_eeprom(); -} - -esp32Firewall::~esp32Firewall() -{ -} - -String esp32Firewall::protocol_to_string(firewall_protocol_t &protocol) -{ - switch (protocol) + esp32Firewall::esp32Firewall() { - case FW_TCP: - return "TCP"; - case FW_UDP: - return "UDP"; - default: - return "ALL"; + this->setup_eeprom(); } -} -firewall_protocol_t esp32Firewall::string_to_protocol(std::string &protocol) -{ - if (protocol.compare("TCP") == 0) - return FW_TCP; - else if (protocol.compare("UDP") == 0) - return FW_UDP; - else - return FW_ALL; -} - -String esp32Firewall::target_to_string(firewall_target_t &target) -{ - switch (target) + esp32Firewall::~esp32Firewall() { - case FW_REJECT: - return "REJECT"; - case FW_DROP: - return "DROP"; - default: - return "ACCEPT"; } -} -firewall_target_t esp32Firewall::string_to_target(std::string &target) -{ - if (target.compare("REJECT") == 0) - return FW_REJECT; - else if (target.compare("DROP") == 0) - return FW_DROP; - else - return FW_ACCEPT; -} - -void esp32Firewall::setup_eeprom() -{ - EEPROM.begin(this->eeprom_size); - this->amount_of_rules = EEPROM.read(this->eeprom_settings_head); - uint8_t security_number = EEPROM.read(this->eeprom_settings_head + 1); - if (this->amount_of_rules > 50 || security_number != this->security_number) + String esp32Firewall::protocol_to_string(firewall_protocol_t &protocol) + { + switch (protocol) + { + case FW_TCP: + return "TCP"; + case FW_UDP: + return "UDP"; + default: + return "ALL"; + } + } + + firewall_protocol_t esp32Firewall::string_to_protocol(std::string &protocol) + { + if (protocol.compare("TCP") == 0) + return FW_TCP; + else if (protocol.compare("UDP") == 0) + return FW_UDP; + else + return FW_ALL; + } + + String esp32Firewall::target_to_string(firewall_target_t &target) + { + switch (target) + { + case FW_REJECT: + return "REJECT"; + case FW_DROP: + return "DROP"; + default: + return "ACCEPT"; + } + } + + firewall_target_t esp32Firewall::string_to_target(std::string &target) + { + if (target.compare("REJECT") == 0) + return FW_REJECT; + else if (target.compare("DROP") == 0) + return FW_DROP; + else + return FW_ACCEPT; + } + + void esp32Firewall::setup_eeprom() + { + EEPROM.begin(this->eeprom_size); + this->amount_of_rules = EEPROM.read(this->eeprom_settings_head); + uint8_t security_number = EEPROM.read(this->eeprom_settings_head + 1); + if (this->amount_of_rules > 50 || security_number != this->security_number) + { + this->amount_of_rules = 0; + EEPROM.write(this->eeprom_settings_head, this->amount_of_rules); + EEPROM.write(this->eeprom_settings_head + 1, this->security_number); + EEPROM.commit(); + } + log_i("Amount of existing Rules %i", this->amount_of_rules); + this->eeprom_read_firewall_rules(); + } + + void esp32Firewall::eeprom_write_firewall_rule(firewall_rule_t *rule_ptr) { - this->amount_of_rules = 0; EEPROM.write(this->eeprom_settings_head, this->amount_of_rules); - EEPROM.write(this->eeprom_settings_head + 1, this->security_number); + EEPROM.writeString(this->eeprom_rules_head, rule_ptr->source); + this->eeprom_rules_head += IPV4ADDRESS_LENGTH; + EEPROM.writeString(this->eeprom_rules_head, rule_ptr->destination); + this->eeprom_rules_head += IPV4ADDRESS_LENGTH; + EEPROM.write(this->eeprom_rules_head, rule_ptr->protocol); + this->eeprom_rules_head += sizeof(firewall_protocol_t); + EEPROM.write(this->eeprom_rules_head, rule_ptr->target); + this->eeprom_rules_head += sizeof(firewall_target_t); EEPROM.commit(); } - log_i("Amount of existing Rules %i", this->amount_of_rules); - this->eeprom_read_firewall_rules(); -} -void esp32Firewall::eeprom_write_firewall_rule(firewall_rule_t *rule_ptr) -{ - EEPROM.write(this->eeprom_settings_head, this->amount_of_rules); - EEPROM.writeString(this->eeprom_rules_head, rule_ptr->source); - this->eeprom_rules_head += IPV4ADDRESS_LENGTH; - EEPROM.writeString(this->eeprom_rules_head, rule_ptr->destination); - this->eeprom_rules_head += IPV4ADDRESS_LENGTH; - EEPROM.write(this->eeprom_rules_head, rule_ptr->protocol); - this->eeprom_rules_head += sizeof(firewall_protocol_t); - EEPROM.write(this->eeprom_rules_head, rule_ptr->target); - this->eeprom_rules_head += sizeof(firewall_target_t); - EEPROM.commit(); -} - -void esp32Firewall::eeprom_write_firewall_rules() -{ - this->eeprom_rules_head = eeprom_start_firewall_rules; - firewall_rule_t *rule_ptr = this->head; - while (rule_ptr != NULL) + void esp32Firewall::eeprom_write_firewall_rules() { - this->eeprom_write_firewall_rule(rule_ptr); - rule_ptr = rule_ptr->next; - } -} - -void esp32Firewall::eeprom_read_firewall_rule(uint8_t &eeprom_address, uint8_t &rule_nr) -{ - firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); - rule_ptr->key = rule_nr; - strcpy(rule_ptr->source, EEPROM.readString(eeprom_address).c_str()); - eeprom_address += IPV4ADDRESS_LENGTH; - strcpy(rule_ptr->destination, EEPROM.readString(eeprom_address).c_str()); - eeprom_address += IPV4ADDRESS_LENGTH; - rule_ptr->protocol = static_cast(EEPROM.read(eeprom_address)); - eeprom_address += sizeof(firewall_protocol_t); - rule_ptr->target = static_cast(EEPROM.read(eeprom_address)); - eeprom_address += sizeof(firewall_target_t); - add_rule_to_firewall(rule_ptr); - log_i("%s, %s, %s, %s", - rule_ptr->source, - rule_ptr->destination, - protocol_to_string(rule_ptr->protocol), - target_to_string(rule_ptr->target)); -} - -void esp32Firewall::eeprom_read_firewall_rules() -{ - uint8_t eeprom_address = eeprom_start_firewall_rules; - for (uint8_t i = 1; i <= this->amount_of_rules; i++) - { - eeprom_read_firewall_rule(eeprom_address, i); - } -} - -void esp32Firewall::add_rule_to_firewall(firewall_rule_t *rule_ptr) -{ - firewall_rule_t *temp; - if (this->head == NULL) - { - this->head = rule_ptr; - rule_ptr->next = NULL; - return; - } - temp = this->head; - while (temp->next != NULL) - { - temp = temp->next; - } - temp->next = rule_ptr; - rule_ptr->next = NULL; - return; -} - -firewall_rule_t *esp32Firewall::get_rule_from_firewall(uint8_t key) -{ - firewall_rule_t *rule_ptr = this->head; - if (this->head == NULL) - { - return NULL; - } - while (rule_ptr->key != key) - { - if (rule_ptr->next == NULL) - { - return NULL; - } - else + this->eeprom_rules_head = eeprom_start_firewall_rules; + firewall_rule_t *rule_ptr = this->head; + while (rule_ptr != NULL) { + this->eeprom_write_firewall_rule(rule_ptr); rule_ptr = rule_ptr->next; } } - return rule_ptr; -} -bool esp32Firewall::delete_rule_from_firewall(uint8_t key) -{ - if (this->head == NULL) + void esp32Firewall::eeprom_read_firewall_rule(uint8_t &eeprom_address, uint8_t &rule_nr) { - return false; + firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); + rule_ptr->key = rule_nr; + strcpy(rule_ptr->source, EEPROM.readString(eeprom_address).c_str()); + eeprom_address += IPV4ADDRESS_LENGTH; + strcpy(rule_ptr->destination, EEPROM.readString(eeprom_address).c_str()); + eeprom_address += IPV4ADDRESS_LENGTH; + rule_ptr->protocol = static_cast(EEPROM.read(eeprom_address)); + eeprom_address += sizeof(firewall_protocol_t); + rule_ptr->target = static_cast(EEPROM.read(eeprom_address)); + eeprom_address += sizeof(firewall_target_t); + add_rule_to_firewall(rule_ptr); + log_i("%s, %s, %s, %s", + rule_ptr->source, + rule_ptr->destination, + protocol_to_string(rule_ptr->protocol), + target_to_string(rule_ptr->target)); } - firewall_rule_t *current_rule_ptr = this->head; - firewall_rule_t *previous_rule_ptr = NULL; - firewall_rule_t *temp = NULL; - while (current_rule_ptr->key != key) + + void esp32Firewall::eeprom_read_firewall_rules() { - if (current_rule_ptr->next == NULL) + uint8_t eeprom_address = eeprom_start_firewall_rules; + for (uint8_t i = 1; i <= this->amount_of_rules; i++) + { + eeprom_read_firewall_rule(eeprom_address, i); + } + } + + void esp32Firewall::add_rule_to_firewall(firewall_rule_t *rule_ptr) + { + firewall_rule_t *temp; + if (this->head == NULL) + { + this->head = rule_ptr; + rule_ptr->next = NULL; + return; + } + temp = this->head; + while (temp->next != NULL) + { + temp = temp->next; + } + temp->next = rule_ptr; + rule_ptr->next = NULL; + return; + } + + firewall_rule_t *esp32Firewall::get_rule_from_firewall(uint8_t key) + { + firewall_rule_t *rule_ptr = this->head; + if (this->head == NULL) + { + return NULL; + } + while (rule_ptr->key != key) + { + if (rule_ptr->next == NULL) + { + return NULL; + } + else + { + rule_ptr = rule_ptr->next; + } + } + return rule_ptr; + } + + bool esp32Firewall::delete_rule_from_firewall(uint8_t key) + { + if (this->head == NULL) { return false; } + firewall_rule_t *current_rule_ptr = this->head; + firewall_rule_t *previous_rule_ptr = NULL; + firewall_rule_t *temp = NULL; + while (current_rule_ptr->key != key) + { + if (current_rule_ptr->next == NULL) + { + return false; + } + else + { + previous_rule_ptr = current_rule_ptr; + current_rule_ptr = current_rule_ptr->next; + } + } + if (current_rule_ptr == this->head) + { + this->head = head->next; + temp = this->head; + } else { - previous_rule_ptr = current_rule_ptr; - current_rule_ptr = current_rule_ptr->next; + previous_rule_ptr->next = current_rule_ptr->next; + temp = previous_rule_ptr->next; } + while (temp != NULL) + { + temp->key--; + temp = temp->next; + } + free(current_rule_ptr); + this->amount_of_rules--; + this->eeprom_write_firewall_rules(); + return true; } - if (current_rule_ptr == this->head) - { - this->head = head->next; - temp = this->head; - } - else - { - previous_rule_ptr->next = current_rule_ptr->next; - temp = previous_rule_ptr->next; - } - while (temp != NULL) - { - temp->key--; - temp = temp->next; - } - free(current_rule_ptr); - this->amount_of_rules--; - this->eeprom_write_firewall_rules(); - return true; } diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp index a9c6b39..62db928 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp @@ -6,37 +6,40 @@ #define eeprom_start_firewall_rules 4 -class esp32Firewall +namespace firewall { -private: - uint16_t eeprom_size = 512; - uint8_t security_number = 93; - int eeprom_settings_head = 0; - int eeprom_rules_head = eeprom_start_firewall_rules; + class esp32Firewall + { + private: + uint16_t eeprom_size = 512; + uint8_t security_number = 93; + int eeprom_settings_head = 0; + int eeprom_rules_head = eeprom_start_firewall_rules; - void setup_eeprom(); - void eeprom_write_firewall_rules(); - void eeprom_read_firewall_rule(uint8_t &, uint8_t &); - void eeprom_read_firewall_rules(); + void setup_eeprom(); + void eeprom_write_firewall_rules(); + void eeprom_read_firewall_rule(uint8_t &, uint8_t &); + void eeprom_read_firewall_rules(); -protected: - uint8_t amount_of_rules = 0; - struct firewall_rule *head = NULL; + protected: + uint8_t amount_of_rules = 0; + struct firewall_rule *head = NULL; - void add_rule_to_firewall(firewall_rule_t *); - firewall_rule_t *get_rule_from_firewall(uint8_t); - bool delete_rule_from_firewall(uint8_t); + void add_rule_to_firewall(firewall_rule_t *); + firewall_rule_t *get_rule_from_firewall(uint8_t); + bool delete_rule_from_firewall(uint8_t); - void eeprom_write_firewall_rule(firewall_rule_t *); + void eeprom_write_firewall_rule(firewall_rule_t *); - String protocol_to_string(firewall_protocol_t &); - firewall_protocol_t string_to_protocol(std::string &); - String target_to_string(firewall_target_t &); - firewall_target_t string_to_target(std::string &); + String protocol_to_string(firewall_protocol_t &); + firewall_protocol_t string_to_protocol(std::string &); + String target_to_string(firewall_target_t &); + firewall_target_t string_to_target(std::string &); -public: - esp32Firewall(); - ~esp32Firewall(); -}; + public: + esp32Firewall(); + ~esp32Firewall(); + }; +} #endif diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp index c5275ff..dfdf615 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp @@ -1,197 +1,200 @@ #include "esp32FirewallAPI.hpp" -esp32FirewallApi::esp32FirewallApi(const uint16_t port) +namespace firewall { - this->setup_certificate(); - this->server = new HTTPSServer(this->certificate, port, 5); - this->setup_routing(); - log_i("Starting server..."); - this->server->start(); - if (this->server->isRunning()) + esp32FirewallApi::esp32FirewallApi(const uint16_t port) { - log_i("Server ready."); + this->setup_certificate(); + this->server = new HTTPSServer(this->certificate, port, 5); + this->setup_routing(); + log_i("Starting server..."); + this->server->start(); + if (this->server->isRunning()) + { + log_i("Server ready."); + } } -} -esp32FirewallApi::~esp32FirewallApi() -{ -} - -void esp32FirewallApi::handle_clients() -{ - this->server->loop(); -} - -void esp32FirewallApi::setup_certificate() -{ - log_i("Creating the certificate..."); - this->certificate = new SSLCert(); - int createCertResult = createSelfSignedCert( - *this->certificate, - KEYSIZE_2048, - "CN=myesp32.local,O=Firewall,C=DE", - "20220101000000", - "20320101000000"); - if (createCertResult != 0) + esp32FirewallApi::~esp32FirewallApi() { - 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"); -} -void esp32FirewallApi::setup_routing() -{ - ResourceNode *get_firewall_rule = new ResourceNode("/api/v1/firewall/*", "GET", std::bind(&esp32FirewallApi::get_firewall_rule_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&esp32FirewallApi::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&esp32FirewallApi::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&esp32FirewallApi::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *restart_device = new ResourceNode("/api/v1/device/restart", "GET", std::bind(&esp32FirewallApi::restart_device_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&esp32FirewallApi::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); - this->server->registerNode(get_firewall_rule); - this->server->registerNode(get_firewall_rules); - this->server->registerNode(post_firewall); - this->server->registerNode(delete_firewall); - this->server->registerNode(restart_device); - this->server->setDefaultNode(not_found); -} - -void esp32FirewallApi::restart_device_handler(HTTPRequest *request, HTTPResponse *response) -{ - this->json_message_response(response, "restarting device in 2 sec", 200); - sleep(2000); - esp_restart(); -} - -void esp32FirewallApi::not_found_handler(HTTPRequest *request, HTTPResponse *response) -{ - this->json_message_response(response, "not found", 404); -} - -void esp32FirewallApi::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) -{ - 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) + void esp32FirewallApi::handle_clients() { - this->json_message_response(response, "rule not found", 404); + this->server->loop(); } - else + + void esp32FirewallApi::setup_certificate() + { + log_i("Creating the certificate..."); + this->certificate = new SSLCert(); + int createCertResult = createSelfSignedCert( + *this->certificate, + KEYSIZE_2048, + "CN=myesp32.local,O=Firewall,C=DE", + "20220101000000", + "20320101000000"); + 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"); + } + + void esp32FirewallApi::setup_routing() + { + ResourceNode *get_firewall_rule = new ResourceNode("/api/v1/firewall/*", "GET", std::bind(&esp32FirewallApi::get_firewall_rule_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&esp32FirewallApi::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&esp32FirewallApi::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&esp32FirewallApi::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *restart_device = new ResourceNode("/api/v1/device/restart", "GET", std::bind(&esp32FirewallApi::restart_device_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&esp32FirewallApi::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); + this->server->registerNode(get_firewall_rule); + this->server->registerNode(get_firewall_rules); + this->server->registerNode(post_firewall); + this->server->registerNode(delete_firewall); + this->server->registerNode(restart_device); + this->server->setDefaultNode(not_found); + } + + void esp32FirewallApi::restart_device_handler(HTTPRequest *request, HTTPResponse *response) + { + this->json_message_response(response, "restarting device in 2 sec", 200); + sleep(2000); + esp_restart(); + } + + void esp32FirewallApi::not_found_handler(HTTPRequest *request, HTTPResponse *response) + { + this->json_message_response(response, "not found", 404); + } + + void esp32FirewallApi::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) + { + 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(response, "rule not found", 404); + } + else + { + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(200); + response->print(this->construct_json_firewall_rule(rule_ptr)); + } + } + + void esp32FirewallApi::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) + { + this->json_generic_response(response, this->construct_json_firewall(), 200); + } + + bool esp32FirewallApi::request_has_firewall_parameter(ResourceParameters *params) + { + return params->isQueryParameterSet("source") || params->isQueryParameterSet("destination") || params->isQueryParameterSet("protocol") || params->isQueryParameterSet("target"); + } + + void esp32FirewallApi::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) + { + 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 + std::string source; + params->getQueryParameter("source", source); + strcpy(rule_ptr->source, source.length() <= IPV4ADDRESS_LENGTH ? source.c_str() : ""); + std::string destination; + params->getQueryParameter("destination", destination); + strcpy(rule_ptr->destination, destination.length() <= IPV4ADDRESS_LENGTH ? destination.c_str() : ""); + + std::string protocol; + params->getQueryParameter("protocol", protocol); + rule_ptr->protocol = string_to_protocol(protocol); + 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); + this->json_generic_response(response, this->construct_json_firewall_rule(rule_ptr), 200); + } + else + { + this->json_message_response(response, "not enough parameter", 400); + } + } + + void esp32FirewallApi::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) + { + 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(response, "firewall rule deleted", 200); + } + else + { + this->json_message_response(response, "cannot delete firewall rule", 500); + } + } + + void esp32FirewallApi::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) { response->setHeader("Content-Type", "application/json"); - response->setStatusCode(200); - response->print(this->construct_json_firewall_rule(rule_ptr)); + response->setStatusCode(response_code); + response->println(serialized); } -} -void esp32FirewallApi::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) -{ - this->json_generic_response(response, this->construct_json_firewall(), 200); -} - -bool esp32FirewallApi::request_has_firewall_parameter(ResourceParameters *params) -{ - return params->isQueryParameterSet("source") || params->isQueryParameterSet("destination") || params->isQueryParameterSet("protocol") || params->isQueryParameterSet("target"); -} - -void esp32FirewallApi::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) -{ - ResourceParameters *params = request->getParams(); - if (request_has_firewall_parameter(params)) + void esp32FirewallApi::json_message_response(HTTPResponse *response, String message, const uint16_t response_code) { - 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 - std::string source; - params->getQueryParameter("source", source); - strcpy(rule_ptr->source, source.length() <= IPV4ADDRESS_LENGTH ? source.c_str() : ""); - std::string destination; - params->getQueryParameter("destination", destination); - strcpy(rule_ptr->destination, destination.length() <= IPV4ADDRESS_LENGTH ? destination.c_str() : ""); - - std::string protocol; - params->getQueryParameter("protocol", protocol); - rule_ptr->protocol = string_to_protocol(protocol); - 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); - this->json_generic_response(response, this->construct_json_firewall_rule(rule_ptr), 200); + response->setHeader("Content-Type", "application/json"); + response->setStatusCode(response_code); + StaticJsonDocument<96> json; + String serialized; + json["message"] = message; + serializeJson(json, serialized); + response->println(serialized); } - else + + String esp32FirewallApi::construct_json_firewall_rule(firewall_rule_t *rule_ptr) { - this->json_message_response(response, "not enough parameter", 400); + StaticJsonDocument<256> doc; + doc["key"] = rule_ptr->key; + doc["source"] = rule_ptr->source; + doc["destination"] = rule_ptr->destination; + doc["protocol"] = protocol_to_string(rule_ptr->protocol); + doc["target"] = target_to_string(rule_ptr->target); + String response; + serializeJson(doc, response); + return response; } -} -void esp32FirewallApi::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) -{ - ResourceParameters *params = request->getParams(); - int rule_number = atoi(params->getPathParameter(0).c_str()); - if (this->delete_rule_from_firewall(rule_number)) + String esp32FirewallApi::construct_json_firewall() { - this->json_message_response(response, "firewall rule deleted", 200); - } - else - { - this->json_message_response(response, "cannot delete firewall rule", 500); + firewall_rule_t *rule_ptr = this->head; + // Size for approx. 12 Rules + StaticJsonDocument<2048> doc; + String response; + doc["amount_of_rules"] = this->amount_of_rules; + JsonArray rules = doc.createNestedArray("rules"); + while (rule_ptr != NULL) + { + JsonObject rule = rules.createNestedObject(); + rule["key"] = rule_ptr->key; + rule["source"] = rule_ptr->source; + rule["destination"] = rule_ptr->destination; + rule["protocol"] = protocol_to_string(rule_ptr->protocol); + rule["target"] = target_to_string(rule_ptr->target); + rule_ptr = rule_ptr->next; + } + serializeJson(doc, response); + return response; } } - -void esp32FirewallApi::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) -{ - response->setHeader("Content-Type", "application/json"); - response->setStatusCode(response_code); - response->println(serialized); -} - -void esp32FirewallApi::json_message_response(HTTPResponse *response, String message, const uint16_t response_code) -{ - response->setHeader("Content-Type", "application/json"); - response->setStatusCode(response_code); - StaticJsonDocument<96> json; - String serialized; - json["message"] = message; - serializeJson(json, serialized); - response->println(serialized); -} - -String esp32FirewallApi::construct_json_firewall_rule(firewall_rule_t *rule_ptr) -{ - StaticJsonDocument<256> doc; - doc["key"] = rule_ptr->key; - doc["source"] = rule_ptr->source; - doc["destination"] = rule_ptr->destination; - doc["protocol"] = protocol_to_string(rule_ptr->protocol); - doc["target"] = target_to_string(rule_ptr->target); - String response; - serializeJson(doc, response); - return response; -} - -String esp32FirewallApi::construct_json_firewall() -{ - firewall_rule_t *rule_ptr = this->head; - // Size for approx. 12 Rules - StaticJsonDocument<2048> doc; - String response; - doc["amount_of_rules"] = this->amount_of_rules; - JsonArray rules = doc.createNestedArray("rules"); - while (rule_ptr != NULL) - { - JsonObject rule = rules.createNestedObject(); - rule["key"] = rule_ptr->key; - rule["source"] = rule_ptr->source; - rule["destination"] = rule_ptr->destination; - rule["protocol"] = protocol_to_string(rule_ptr->protocol); - rule["target"] = target_to_string(rule_ptr->target); - rule_ptr = rule_ptr->next; - } - serializeJson(doc, response); - return response; -} \ No newline at end of file diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp index 238ab57..86ebaf7 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp @@ -11,31 +11,34 @@ using namespace httpsserver; -class esp32FirewallApi : public esp32Firewall +namespace firewall { -private: - HTTPSServer *server; - SSLCert *certificate; + class esp32FirewallApi : public esp32Firewall + { + private: + HTTPSServer *server; + SSLCert *certificate; - void setup_certificate(); - void setup_routing(); - void get_firewall_rule_handler(HTTPRequest *, HTTPResponse *); - void get_firewall_rules_handler(HTTPRequest *, HTTPResponse *); - bool request_has_firewall_parameter(ResourceParameters *); - void post_firewall_handler(HTTPRequest *, HTTPResponse *); - void delete_firewall_handler(HTTPRequest *, HTTPResponse *); - void restart_device_handler(HTTPRequest *, HTTPResponse *); - void not_found_handler(HTTPRequest *, HTTPResponse *); + void setup_certificate(); + void setup_routing(); + void get_firewall_rule_handler(HTTPRequest *, HTTPResponse *); + void get_firewall_rules_handler(HTTPRequest *, HTTPResponse *); + bool request_has_firewall_parameter(ResourceParameters *); + void post_firewall_handler(HTTPRequest *, HTTPResponse *); + void delete_firewall_handler(HTTPRequest *, HTTPResponse *); + void restart_device_handler(HTTPRequest *, HTTPResponse *); + void not_found_handler(HTTPRequest *, HTTPResponse *); - void json_generic_response(HTTPResponse *, String, const uint16_t); - void json_message_response(HTTPResponse *, String, const uint16_t); - String construct_json_firewall_rule(firewall_rule_t *); - String construct_json_firewall(); + void json_generic_response(HTTPResponse *, String, const uint16_t); + void json_message_response(HTTPResponse *, String, const uint16_t); + String construct_json_firewall_rule(firewall_rule_t *); + String construct_json_firewall(); -public: - esp32FirewallApi(const uint16_t = 8080); - ~esp32FirewallApi(); - void handle_clients(); -}; + public: + esp32FirewallApi(const uint16_t = 8080); + ~esp32FirewallApi(); + void handle_clients(); + }; +} #endif diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index def7ff8..77707cd 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -1,10 +1,11 @@ #include "theSecrets.h" #include "WiFi.h" -#include "esp32Firewall.hpp" #include "esp32FirewallAPI.hpp" +#include "esp32Eeprom.hpp" -esp32FirewallApi *firewall_api; +firewall::esp32FirewallApi *firewall_api; +firewall::Storage *storage; void setup_wifi() { @@ -24,10 +25,11 @@ void setup_wifi() void setup() { setup_wifi(); - firewall_api = new esp32FirewallApi; + // firewall_api = new esp32FirewallApi; + storage = new firewall::Storage; } void loop() { - firewall_api->handle_clients(); + // firewall_api->handle_clients(); } \ No newline at end of file From e5c061ff32afedcd72c78e8dfa4ffad2fa61cbc9 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 14:37:21 +0200 Subject: [PATCH 07/15] rename... --- .../arduino/lib/Firewall/esp32Eeprom.cpp | 26 ------- .../arduino/lib/Firewall/esp32Storage.cpp | 70 +++++++++++++++++++ .../{esp32Eeprom.hpp => esp32Storage.hpp} | 15 ++-- SourceCode/arduino/src/main.cpp | 2 +- 4 files changed, 81 insertions(+), 32 deletions(-) delete mode 100644 SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp create mode 100644 SourceCode/arduino/lib/Firewall/esp32Storage.cpp rename SourceCode/arduino/lib/Firewall/{esp32Eeprom.hpp => esp32Storage.hpp} (62%) diff --git a/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp b/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp deleted file mode 100644 index 5e6ae6f..0000000 --- a/SourceCode/arduino/lib/Firewall/esp32Eeprom.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "esp32Eeprom.hpp" - -namespace firewall -{ - Storage::Storage(const uint16_t eeprom_size) - { - this->eeprom_size = eeprom_size; - EEPROM.begin(this->eeprom_size); - set_amount_of_firewall_rules(EEPROM.read(this->settings_head)); - log_i("Amount of Rules: %i", get_amount_of_firewall_rules()); - } - - Storage::~Storage() - { - } - - uint8_t Storage::get_amount_of_firewall_rules() - { - return this->amount_of_rules; - } - - void Storage::set_amount_of_firewall_rules(const uint8_t new_amount) - { - this->amount_of_rules = new_amount; - } -} diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp new file mode 100644 index 0000000..a4b718f --- /dev/null +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -0,0 +1,70 @@ +#include "esp32Storage.hpp" + +namespace firewall +{ + Storage::Storage(const uint16_t eeprom_size) + { + this->get_eeprom_hash(); + this->eeprom_size = eeprom_size; + EEPROM.begin(this->eeprom_size); + this->amount_of_rules = EEPROM.read(this->settings_head); + log_i("Amount of Rules: %i", this->amount_of_rules); + } + + Storage::~Storage() + { + } + + void Storage::clear_eeprom() + { + + for (int i = 0; i < this->eeprom_size; i++) + { + EEPROM.write(i, 0); + } + } + + void Storage::get_eeprom_hash() + { + char buffer[this->eeprom_size] = {0}; + for (int i = 0; i < this->eeprom_size; i++) + { + buffer[i] = EEPROM.readChar(i); + } + unsigned char *hashedPayload = get_hash(buffer); + for (int i = 0; i < sizeof(hashedPayload); i++) + { + char str[3]; + sprintf(str, "%02x", (int)hashedPayload[i]); + Serial.print(str); + } + } +} + +unsigned char *Storage::get_hash(const char *payload) +{ + unsigned char hashedPayload[32]; + mbedtls_md_context_t ctx; + mbedtls_md_type_t md_type = MBEDTLS_MD_MD5; + const size_t payloadLength = strlen(payload); + + mbedtls_md_init(&ctx); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0); + mbedtls_md_starts(&ctx); + mbedtls_md_update(&ctx, (const unsigned char *)payload, payloadLength); + mbedtls_md_finish(&ctx, hashedPayload); + mbedtls_md_free(&ctx); + + return hashedPayload; +} + +uint8_t Storage::get_amount_of_firewall_rules() +{ + return this->amount_of_rules; +} + +void Storage::set_amount_of_firewall_rules(const uint8_t new_amount) +{ + this->amount_of_rules = new_amount; +} +} diff --git a/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp similarity index 62% rename from SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp rename to SourceCode/arduino/lib/Firewall/esp32Storage.hpp index e8d04f7..3a92d1f 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Eeprom.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -1,8 +1,9 @@ -#ifndef ESP32_EEPROM_HPP -#define ESP32_EEPROM_HPP +#ifndef ESP32_STORAGE_HPP +#define ESP32_STORAGE_HPP #include "EEPROM.h" #include "FirewallTypes.h" +#include "mbedtls/md.h" namespace firewall { @@ -12,18 +13,22 @@ namespace firewall uint16_t eeprom_size; uint16_t settings_start = 0; uint16_t settings_head = settings_start; - uint16_t rules_start = 1000; + uint16_t rules_start = 100; uint16_t rules_head = rules_start; - uint16_t certificate_start = 3000; + uint16_t certificate_start = 800; uint16_t certificate_head = certificate_start; + void clear_eeprom(); + void get_eeprom_hash(); + unsigned char *Storage::get_hash(const char *); + protected: uint8_t amount_of_rules; uint8_t get_amount_of_firewall_rules(); void set_amount_of_firewall_rules(const uint8_t); public: - Storage(const uint16_t = 4000); + Storage(const uint16_t = 1000); ~Storage(); }; } diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index 77707cd..4b5dbf8 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -2,7 +2,7 @@ #include "WiFi.h" #include "esp32FirewallAPI.hpp" -#include "esp32Eeprom.hpp" +#include "esp32Storage.hpp" firewall::esp32FirewallApi *firewall_api; firewall::Storage *storage; From d05ccef834b4694115eb1a204cfb58719fcb8497 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 15:43:02 +0200 Subject: [PATCH 08/15] use preferences instead of eeprom --- .../arduino/lib/Firewall/esp32Storage.cpp | 92 ++++++++----------- .../arduino/lib/Firewall/esp32Storage.hpp | 23 ++--- 2 files changed, 46 insertions(+), 69 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index a4b718f..2474c49 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -2,69 +2,55 @@ namespace firewall { - Storage::Storage(const uint16_t eeprom_size) + Storage::Storage() { - this->get_eeprom_hash(); - this->eeprom_size = eeprom_size; - EEPROM.begin(this->eeprom_size); - this->amount_of_rules = EEPROM.read(this->settings_head); - log_i("Amount of Rules: %i", this->amount_of_rules); } Storage::~Storage() { } - void Storage::clear_eeprom() + uint8_t Storage::retrieve_amount_of_firewall_rules() { - - for (int i = 0; i < this->eeprom_size; i++) - { - EEPROM.write(i, 0); - } + uint8_t amount_of_rules; + this->preferences.begin("settings", false); + amount_of_rules = preferences.getUChar("amount_of_rules", 0); + this->preferences.end(); + return amount_of_rules; } - void Storage::get_eeprom_hash() + void Storage::store_amount_of_firewall_rules(const uint8_t new_amount) { - char buffer[this->eeprom_size] = {0}; - for (int i = 0; i < this->eeprom_size; i++) - { - buffer[i] = EEPROM.readChar(i); - } - unsigned char *hashedPayload = get_hash(buffer); - for (int i = 0; i < sizeof(hashedPayload); i++) - { - char str[3]; - sprintf(str, "%02x", (int)hashedPayload[i]); - Serial.print(str); - } + this->preferences.begin("settings", false); + this->preferences.putUChar("amount_of_rules", new_amount); + this->preferences.end(); + } + + firewall_rule_t *Storage::retrieve_firewall_rule(const uint8_t key) + { + char rulename[12]; + firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); + sprintf(rulename, "fw_rule_%i", key); + this->preferences.begin(rulename, false); + rule_ptr->key = key; + strcpy(rule_ptr->source, this->preferences.getString("source").c_str()); + strcpy(rule_ptr->destination, this->preferences.getString("destination").c_str()); + rule_ptr->protocol = static_cast(this->preferences.getUChar("protocol")); + rule_ptr->target = static_cast(this->preferences.getUChar("target")); + this->preferences.end(); + return rule_ptr; + } + + void Storage::store_firewall_rule(const uint8_t &new_amount, firewall_rule_t *rule_ptr) + { + this->store_amount_of_firewall_rules(new_amount); + char rulename[12]; + sprintf(rulename, "fw_rule_%i", rule_ptr->key); + this->preferences.begin(rulename, false); + this->preferences.putString("source", rule_ptr->source); + this->preferences.putString("destination", rule_ptr->destination); + this->preferences.putUChar("protocol", rule_ptr->protocol); + this->preferences.putUChar("target", rule_ptr->target); + this->preferences.end(); } } - -unsigned char *Storage::get_hash(const char *payload) -{ - unsigned char hashedPayload[32]; - mbedtls_md_context_t ctx; - mbedtls_md_type_t md_type = MBEDTLS_MD_MD5; - const size_t payloadLength = strlen(payload); - - mbedtls_md_init(&ctx); - mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0); - mbedtls_md_starts(&ctx); - mbedtls_md_update(&ctx, (const unsigned char *)payload, payloadLength); - mbedtls_md_finish(&ctx, hashedPayload); - mbedtls_md_free(&ctx); - - return hashedPayload; -} - -uint8_t Storage::get_amount_of_firewall_rules() -{ - return this->amount_of_rules; -} - -void Storage::set_amount_of_firewall_rules(const uint8_t new_amount) -{ - this->amount_of_rules = new_amount; -} -} diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp index 3a92d1f..aa16cfe 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -1,7 +1,7 @@ #ifndef ESP32_STORAGE_HPP #define ESP32_STORAGE_HPP -#include "EEPROM.h" +#include "Preferences.h" #include "FirewallTypes.h" #include "mbedtls/md.h" @@ -10,25 +10,16 @@ namespace firewall class Storage { private: - uint16_t eeprom_size; - uint16_t settings_start = 0; - uint16_t settings_head = settings_start; - uint16_t rules_start = 100; - uint16_t rules_head = rules_start; - uint16_t certificate_start = 800; - uint16_t certificate_head = certificate_start; - - void clear_eeprom(); - void get_eeprom_hash(); - unsigned char *Storage::get_hash(const char *); + Preferences preferences; protected: - uint8_t amount_of_rules; - uint8_t get_amount_of_firewall_rules(); - void set_amount_of_firewall_rules(const uint8_t); + uint8_t retrieve_amount_of_firewall_rules(); + void store_amount_of_firewall_rules(const uint8_t); + firewall_rule_t *retrieve_firewall_rule(const uint8_t); + void store_firewall_rule(const uint8_t &, firewall_rule_t *); public: - Storage(const uint16_t = 1000); + Storage(); ~Storage(); }; } From fe65ae486695e499df8036bf0e827c91a0af9644 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 15:53:54 +0200 Subject: [PATCH 09/15] store cert method --- SourceCode/arduino/lib/Firewall/esp32Storage.cpp | 14 ++++++++++++++ SourceCode/arduino/lib/Firewall/esp32Storage.hpp | 2 ++ 2 files changed, 16 insertions(+) diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index 2474c49..3a374a9 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -53,4 +53,18 @@ namespace firewall this->preferences.putUChar("target", rule_ptr->target); this->preferences.end(); } + + void Storage::store_certificate(httpsserver::SSLCert *certificate) + { + unsigned char *pk_data = certificate->getPKData(); + uint16_t pk_length = certificate->getPKLength(); + unsigned char *cert_data = certificate->getCertData(); + uint16_t cert_length = certificate->getCertLength(); + this->preferences.begin("certificate", false); + this->preferences.putBytes("pk_data", pk_data, sizeof(pk_data)); + this->preferences.putUInt("pk_length", pk_length); + this->preferences.putBytes("cert_data", cert_data, sizeof(cert_data)); + this->preferences.putUInt("pk_length", cert_length); + this->preferences.end(); + } } diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp index aa16cfe..4c58bc4 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -4,6 +4,7 @@ #include "Preferences.h" #include "FirewallTypes.h" #include "mbedtls/md.h" +#include "SSLCert.hpp" namespace firewall { @@ -17,6 +18,7 @@ namespace firewall void store_amount_of_firewall_rules(const uint8_t); firewall_rule_t *retrieve_firewall_rule(const uint8_t); void store_firewall_rule(const uint8_t &, firewall_rule_t *); + void store_certificate(httpsserver::SSLCert *certificate); public: Storage(); From d457949a76801e625f26cfe64d78447dbdf66193 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 16:02:10 +0200 Subject: [PATCH 10/15] get certificate from storage --- .../arduino/lib/Firewall/esp32Storage.cpp | 28 +++++++++++++++---- .../arduino/lib/Firewall/esp32Storage.hpp | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index 3a374a9..f245312 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -33,10 +33,10 @@ namespace firewall sprintf(rulename, "fw_rule_%i", key); this->preferences.begin(rulename, false); rule_ptr->key = key; - strcpy(rule_ptr->source, this->preferences.getString("source").c_str()); - strcpy(rule_ptr->destination, this->preferences.getString("destination").c_str()); - rule_ptr->protocol = static_cast(this->preferences.getUChar("protocol")); - rule_ptr->target = static_cast(this->preferences.getUChar("target")); + strcpy(rule_ptr->source, this->preferences.getString("source", "").c_str()); + strcpy(rule_ptr->destination, this->preferences.getString("destination", "").c_str()); + rule_ptr->protocol = static_cast(this->preferences.getUChar("protocol", FW_ALL)); + rule_ptr->target = static_cast(this->preferences.getUChar("target", FW_ACCEPT)); this->preferences.end(); return rule_ptr; } @@ -54,6 +54,22 @@ namespace firewall this->preferences.end(); } + httpsserver::SSLCert *Storage::retrieve_certificate() + { + unsigned char *pk_data; + uint16_t pk_length; + unsigned char *cert_data; + uint16_t cert_length; + this->preferences.begin("certificate", false); + pk_length = this->preferences.getUInt("pk_length", 0); + cert_length = this->preferences.getUInt("pk_length", 0); + this->preferences.getBytes("pk_data", pk_data, pk_length); + this->preferences.getBytes("cert_data", cert_data, cert_length); + this->preferences.end(); + httpsserver::SSLCert *certificate = new httpsserver::SSLCert(cert_data, cert_length, pk_data, pk_length); + return certificate; + } + void Storage::store_certificate(httpsserver::SSLCert *certificate) { unsigned char *pk_data = certificate->getPKData(); @@ -61,9 +77,9 @@ namespace firewall unsigned char *cert_data = certificate->getCertData(); uint16_t cert_length = certificate->getCertLength(); this->preferences.begin("certificate", false); - this->preferences.putBytes("pk_data", pk_data, sizeof(pk_data)); + this->preferences.putBytes("pk_data", pk_data, pk_length); this->preferences.putUInt("pk_length", pk_length); - this->preferences.putBytes("cert_data", cert_data, sizeof(cert_data)); + this->preferences.putBytes("cert_data", cert_data, cert_length); this->preferences.putUInt("pk_length", cert_length); this->preferences.end(); } diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp index 4c58bc4..2b3516b 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -18,6 +18,7 @@ namespace firewall void store_amount_of_firewall_rules(const uint8_t); firewall_rule_t *retrieve_firewall_rule(const uint8_t); void store_firewall_rule(const uint8_t &, firewall_rule_t *); + httpsserver::SSLCert *retrieve_certificate(); void store_certificate(httpsserver::SSLCert *certificate); public: From 89886a65e3b7b7dc601c6779df19ae78ba6421df Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 19:42:30 +0200 Subject: [PATCH 11/15] storing and reading works --- .../arduino/lib/Firewall/esp32Storage.cpp | 124 +++++++++++------- .../arduino/lib/Firewall/esp32Storage.hpp | 10 +- SourceCode/arduino/platformio.ini | 6 +- 3 files changed, 87 insertions(+), 53 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index f245312..9f02b4a 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -4,83 +4,117 @@ namespace firewall { Storage::Storage() { + store_settings_value("amount_of_rules", 21); + log_i("Amount: %i", retrieve_settings_value("amount_of_rules")); + + firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); + rule_ptr->key = 0; + strcpy(rule_ptr->source, "192.168.0.12"); + strcpy(rule_ptr->destination, "192.168.0.12"); + rule_ptr->protocol = FW_TCP; + rule_ptr->target = FW_DROP; + store_firewall_rule(rule_ptr); + free(rule_ptr); + rule_ptr = retrieve_firewall_rule(0); + log_i("%s, %s, %i, %i", + rule_ptr->source, + rule_ptr->destination, + rule_ptr->protocol, + rule_ptr->target); + free(rule_ptr); + rule_ptr = retrieve_firewall_rule(1); + log_i("%s, %s, %i, %i", + rule_ptr->source, + rule_ptr->destination, + rule_ptr->protocol, + rule_ptr->target); + free(rule_ptr); } Storage::~Storage() { } - uint8_t Storage::retrieve_amount_of_firewall_rules() + uint8_t Storage::retrieve_settings_value(const char *key) { uint8_t amount_of_rules; - this->preferences.begin("settings", false); - amount_of_rules = preferences.getUChar("amount_of_rules", 0); - this->preferences.end(); + + this->memory.begin("settings", true); + amount_of_rules = memory.getUChar(key, 0); + this->memory.end(); + return amount_of_rules; } - void Storage::store_amount_of_firewall_rules(const uint8_t new_amount) + void Storage::store_settings_value(const char *key, const uint8_t new_amount) { - this->preferences.begin("settings", false); - this->preferences.putUChar("amount_of_rules", new_amount); - this->preferences.end(); + this->memory.begin("settings", false); + this->memory.putUChar(key, new_amount); + this->memory.end(); } firewall_rule_t *Storage::retrieve_firewall_rule(const uint8_t key) { - char rulename[12]; firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); - sprintf(rulename, "fw_rule_%i", key); - this->preferences.begin(rulename, false); rule_ptr->key = key; - strcpy(rule_ptr->source, this->preferences.getString("source", "").c_str()); - strcpy(rule_ptr->destination, this->preferences.getString("destination", "").c_str()); - rule_ptr->protocol = static_cast(this->preferences.getUChar("protocol", FW_ALL)); - rule_ptr->target = static_cast(this->preferences.getUChar("target", FW_ACCEPT)); - this->preferences.end(); + + char rulename[9]; // fwRule99\n + sprintf(rulename, "fwRule%i", key); + + this->memory.begin(rulename, true); + strcpy(rule_ptr->source, this->memory.getString("source", "0.0.0.0").c_str()); + strcpy(rule_ptr->destination, this->memory.getString("destination", "0.0.0.0").c_str()); + rule_ptr->protocol = static_cast(this->memory.getUChar("protocol", FW_ALL)); + rule_ptr->target = static_cast(this->memory.getUChar("target", FW_REJECT)); + this->memory.end(); + return rule_ptr; } - void Storage::store_firewall_rule(const uint8_t &new_amount, firewall_rule_t *rule_ptr) + void Storage::store_firewall_rule(firewall_rule_t *rule_ptr) { - this->store_amount_of_firewall_rules(new_amount); - char rulename[12]; - sprintf(rulename, "fw_rule_%i", rule_ptr->key); - this->preferences.begin(rulename, false); - this->preferences.putString("source", rule_ptr->source); - this->preferences.putString("destination", rule_ptr->destination); - this->preferences.putUChar("protocol", rule_ptr->protocol); - this->preferences.putUChar("target", rule_ptr->target); - this->preferences.end(); + char rulename[9]; // fwRule99\n + sprintf(rulename, "fwRule%i", rule_ptr->key); + + this->memory.begin(rulename, false); + this->memory.putString("source", rule_ptr->source); + this->memory.putString("destination", rule_ptr->destination); + this->memory.putUChar("protocol", rule_ptr->protocol); + this->memory.putUChar("target", rule_ptr->target); + this->memory.end(); } httpsserver::SSLCert *Storage::retrieve_certificate() { - unsigned char *pk_data; - uint16_t pk_length; - unsigned char *cert_data; - uint16_t cert_length; - this->preferences.begin("certificate", false); - pk_length = this->preferences.getUInt("pk_length", 0); - cert_length = this->preferences.getUInt("pk_length", 0); - this->preferences.getBytes("pk_data", pk_data, pk_length); - this->preferences.getBytes("cert_data", cert_data, cert_length); - this->preferences.end(); - httpsserver::SSLCert *certificate = new httpsserver::SSLCert(cert_data, cert_length, pk_data, pk_length); - return certificate; + this->memory.begin("certificate", true); + uint16_t cert_data_length = this->memory.getBytesLength("cert_data"); + unsigned char cert_data[cert_data_length]; + this->memory.getBytes("cert_data", cert_data, cert_data_length); + + uint16_t pk_data_length = this->memory.getBytesLength("pk_data"); + unsigned char pk_data[pk_data_length]; + this->memory.getBytes("pk_data", pk_data, pk_data_length); + + uint16_t pk_length = this->memory.getUInt("pk_length", 0); + + uint16_t cert_length = this->memory.getUInt("pk_length", 0); + this->memory.end(); + + return new httpsserver::SSLCert(cert_data, cert_length, pk_data, pk_length); } void Storage::store_certificate(httpsserver::SSLCert *certificate) { unsigned char *pk_data = certificate->getPKData(); - uint16_t pk_length = certificate->getPKLength(); unsigned char *cert_data = certificate->getCertData(); + uint16_t pk_length = certificate->getPKLength(); uint16_t cert_length = certificate->getCertLength(); - this->preferences.begin("certificate", false); - this->preferences.putBytes("pk_data", pk_data, pk_length); - this->preferences.putUInt("pk_length", pk_length); - this->preferences.putBytes("cert_data", cert_data, cert_length); - this->preferences.putUInt("pk_length", cert_length); - this->preferences.end(); + + this->memory.begin("certificate", false); + this->memory.putBytes("pk_data", pk_data, pk_length); + this->memory.putBytes("cert_data", cert_data, cert_length); + this->memory.putUInt("pk_length", pk_length); + this->memory.putUInt("pk_length", cert_length); + this->memory.end(); } } diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp index 2b3516b..4bec08a 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -11,13 +11,15 @@ namespace firewall class Storage { private: - Preferences preferences; + Preferences memory; protected: - uint8_t retrieve_amount_of_firewall_rules(); - void store_amount_of_firewall_rules(const uint8_t); + uint8_t retrieve_settings_value(const char *); + void store_settings_value(const char *, const uint8_t); + firewall_rule_t *retrieve_firewall_rule(const uint8_t); - void store_firewall_rule(const uint8_t &, firewall_rule_t *); + void store_firewall_rule(firewall_rule_t *); + httpsserver::SSLCert *retrieve_certificate(); void store_certificate(httpsserver::SSLCert *certificate); diff --git a/SourceCode/arduino/platformio.ini b/SourceCode/arduino/platformio.ini index 823bfc9..8ea22a8 100644 --- a/SourceCode/arduino/platformio.ini +++ b/SourceCode/arduino/platformio.ini @@ -15,8 +15,7 @@ framework = arduino monitor_speed = 115200 build_flags = -DCORE_DEBUG_LEVEL=3 -lib_deps = - bblanchon/ArduinoJson@^6.19.4 +lib_deps = bblanchon/ArduinoJson@^6.19.4 [env:esp32-dev] platform = espressif32 @@ -25,5 +24,4 @@ framework = arduino monitor_speed = 115200 build_flags = -DCORE_DEBUG_LEVEL=3 -lib_deps = - bblanchon/ArduinoJson@^6.19.4 +lib_deps = bblanchon/ArduinoJson@^6.19.4 From 71b6fee0a6b24b94b636f9ecc033f66ee080159b Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 19:54:46 +0200 Subject: [PATCH 12/15] all working as expected --- .../arduino/lib/Firewall/esp32Storage.cpp | 31 ++----------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index 9f02b4a..3681987 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -4,31 +4,6 @@ namespace firewall { Storage::Storage() { - store_settings_value("amount_of_rules", 21); - log_i("Amount: %i", retrieve_settings_value("amount_of_rules")); - - firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); - rule_ptr->key = 0; - strcpy(rule_ptr->source, "192.168.0.12"); - strcpy(rule_ptr->destination, "192.168.0.12"); - rule_ptr->protocol = FW_TCP; - rule_ptr->target = FW_DROP; - store_firewall_rule(rule_ptr); - free(rule_ptr); - rule_ptr = retrieve_firewall_rule(0); - log_i("%s, %s, %i, %i", - rule_ptr->source, - rule_ptr->destination, - rule_ptr->protocol, - rule_ptr->target); - free(rule_ptr); - rule_ptr = retrieve_firewall_rule(1); - log_i("%s, %s, %i, %i", - rule_ptr->source, - rule_ptr->destination, - rule_ptr->protocol, - rule_ptr->target); - free(rule_ptr); } Storage::~Storage() @@ -111,10 +86,10 @@ namespace firewall uint16_t cert_length = certificate->getCertLength(); this->memory.begin("certificate", false); - this->memory.putBytes("pk_data", pk_data, pk_length); - this->memory.putBytes("cert_data", cert_data, cert_length); + this->memory.putBytes("pk_data", pk_data, sizeof(pk_data)); + this->memory.putBytes("cert_data", cert_data, sizeof(cert_data)); this->memory.putUInt("pk_length", pk_length); - this->memory.putUInt("pk_length", cert_length); + this->memory.putUInt("cert_length", cert_length); this->memory.end(); } } From c86be9feb4e912c4583fc7dfbc5f17e22c7af908 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 19:58:15 +0200 Subject: [PATCH 13/15] move helper functions to types --- .../arduino/lib/Firewall/FirewallTypes.h | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/SourceCode/arduino/lib/Firewall/FirewallTypes.h b/SourceCode/arduino/lib/Firewall/FirewallTypes.h index d89cc01..56a4b61 100644 --- a/SourceCode/arduino/lib/Firewall/FirewallTypes.h +++ b/SourceCode/arduino/lib/Firewall/FirewallTypes.h @@ -29,4 +29,50 @@ typedef struct firewall_rule struct firewall_rule *next; } firewall_rule_t; +String protocol_to_string(firewall_protocol_t &protocol) +{ + switch (protocol) + { + case FW_TCP: + return "TCP"; + case FW_UDP: + return "UDP"; + default: + return "ALL"; + } +} + +firewall_protocol_t string_to_protocol(std::string &protocol) +{ + if (protocol.compare("TCP") == 0) + return FW_TCP; + else if (protocol.compare("UDP") == 0) + return FW_UDP; + else + return FW_ALL; +} + +String target_to_string(firewall_target_t &target) +{ + switch (target) + { + case FW_REJECT: + return "REJECT"; + case FW_DROP: + return "DROP"; + default: + return "ACCEPT"; + } +} + +firewall_target_t string_to_target(std::string &target) +{ + if (target.compare("REJECT") == 0) + return FW_REJECT; + else if (target.compare("DROP") == 0) + return FW_DROP; + else + return FW_ACCEPT; +} + #endif From a08ea4803b7de7f93d754924a3b1db6dcdba1d3c Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 21:17:34 +0200 Subject: [PATCH 14/15] using SPIFFS for cert, eeprom for the rest --- .../arduino/lib/Firewall/FirewallTypes.h | 46 ----- .../{esp32FirewallAPI.cpp => esp32API.cpp} | 66 +++---- .../{esp32FirewallAPI.hpp => esp32API.hpp} | 12 +- .../arduino/lib/Firewall/esp32Firewall.cpp | 178 ++++++------------ .../arduino/lib/Firewall/esp32Firewall.hpp | 32 +--- .../arduino/lib/Firewall/esp32Storage.cpp | 90 ++++++--- .../arduino/lib/Firewall/esp32Storage.hpp | 2 + SourceCode/arduino/src/main.cpp | 12 +- 8 files changed, 175 insertions(+), 263 deletions(-) rename SourceCode/arduino/lib/Firewall/{esp32FirewallAPI.cpp => esp32API.cpp} (67%) rename SourceCode/arduino/lib/Firewall/{esp32FirewallAPI.hpp => esp32API.hpp} (80%) diff --git a/SourceCode/arduino/lib/Firewall/FirewallTypes.h b/SourceCode/arduino/lib/Firewall/FirewallTypes.h index 56a4b61..d89cc01 100644 --- a/SourceCode/arduino/lib/Firewall/FirewallTypes.h +++ b/SourceCode/arduino/lib/Firewall/FirewallTypes.h @@ -29,50 +29,4 @@ typedef struct firewall_rule struct firewall_rule *next; } firewall_rule_t; -String protocol_to_string(firewall_protocol_t &protocol) -{ - switch (protocol) - { - case FW_TCP: - return "TCP"; - case FW_UDP: - return "UDP"; - default: - return "ALL"; - } -} - -firewall_protocol_t string_to_protocol(std::string &protocol) -{ - if (protocol.compare("TCP") == 0) - return FW_TCP; - else if (protocol.compare("UDP") == 0) - return FW_UDP; - else - return FW_ALL; -} - -String target_to_string(firewall_target_t &target) -{ - switch (target) - { - case FW_REJECT: - return "REJECT"; - case FW_DROP: - return "DROP"; - default: - return "ACCEPT"; - } -} - -firewall_target_t string_to_target(std::string &target) -{ - if (target.compare("REJECT") == 0) - return FW_REJECT; - else if (target.compare("DROP") == 0) - return FW_DROP; - else - return FW_ACCEPT; -} - #endif diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp b/SourceCode/arduino/lib/Firewall/esp32API.cpp similarity index 67% rename from SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp rename to SourceCode/arduino/lib/Firewall/esp32API.cpp index dfdf615..6403d29 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32API.cpp @@ -1,8 +1,8 @@ -#include "esp32FirewallAPI.hpp" +#include "esp32API.hpp" namespace firewall { - esp32FirewallApi::esp32FirewallApi(const uint16_t port) + API::API(const uint16_t port) { this->setup_certificate(); this->server = new HTTPSServer(this->certificate, port, 5); @@ -15,17 +15,20 @@ namespace firewall } } - esp32FirewallApi::~esp32FirewallApi() + API::~API() { } - void esp32FirewallApi::handle_clients() + void API::handle_clients() { this->server->loop(); } - void esp32FirewallApi::setup_certificate() + void API::setup_certificate() { + this->certificate = retrieve_certificate(); + if (certificate != NULL) + return; log_i("Creating the certificate..."); this->certificate = new SSLCert(); int createCertResult = createSelfSignedCert( @@ -40,42 +43,34 @@ namespace firewall while (true) delay(500); } + store_certificate(certificate); log_i("Creating the certificate was successful"); } - void esp32FirewallApi::setup_routing() + void API::setup_routing() { - ResourceNode *get_firewall_rule = new ResourceNode("/api/v1/firewall/*", "GET", std::bind(&esp32FirewallApi::get_firewall_rule_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&esp32FirewallApi::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&esp32FirewallApi::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&esp32FirewallApi::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *restart_device = new ResourceNode("/api/v1/device/restart", "GET", std::bind(&esp32FirewallApi::restart_device_handler, this, std::placeholders::_1, std::placeholders::_2)); - ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&esp32FirewallApi::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *get_firewall_rule = new ResourceNode("/api/v1/firewall/*", "GET", std::bind(&API::get_firewall_rule_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *get_firewall_rules = new ResourceNode("/api/v1/firewall", "GET", std::bind(&API::get_firewall_rules_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *post_firewall = new ResourceNode("/api/v1/firewall", "POST", std::bind(&API::post_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *delete_firewall = new ResourceNode("/api/v1/firewall/*", "DELETE", std::bind(&API::delete_firewall_handler, this, std::placeholders::_1, std::placeholders::_2)); + ResourceNode *not_found = new ResourceNode("", "GET", std::bind(&API::not_found_handler, this, std::placeholders::_1, std::placeholders::_2)); this->server->registerNode(get_firewall_rule); this->server->registerNode(get_firewall_rules); this->server->registerNode(post_firewall); this->server->registerNode(delete_firewall); - this->server->registerNode(restart_device); this->server->setDefaultNode(not_found); } - void esp32FirewallApi::restart_device_handler(HTTPRequest *request, HTTPResponse *response) - { - this->json_message_response(response, "restarting device in 2 sec", 200); - sleep(2000); - esp_restart(); - } - - void esp32FirewallApi::not_found_handler(HTTPRequest *request, HTTPResponse *response) + void API::not_found_handler(HTTPRequest *request, HTTPResponse *response) { this->json_message_response(response, "not found", 404); } - void esp32FirewallApi::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) + void API::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) { 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); + firewall_rule_t *rule_ptr = get_rule_from_firewall(rule_number); if (rule_ptr == NULL) { this->json_message_response(response, "rule not found", 404); @@ -88,17 +83,17 @@ namespace firewall } } - void esp32FirewallApi::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) + void API::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) { this->json_generic_response(response, this->construct_json_firewall(), 200); } - bool esp32FirewallApi::request_has_firewall_parameter(ResourceParameters *params) + bool API::request_has_firewall_parameter(ResourceParameters *params) { return params->isQueryParameterSet("source") || params->isQueryParameterSet("destination") || params->isQueryParameterSet("protocol") || params->isQueryParameterSet("target"); } - void esp32FirewallApi::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) + void API::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) { ResourceParameters *params = request->getParams(); if (request_has_firewall_parameter(params)) @@ -121,8 +116,7 @@ namespace firewall 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); + add_rule_to_firewall(rule_ptr); this->json_generic_response(response, this->construct_json_firewall_rule(rule_ptr), 200); } else @@ -131,11 +125,11 @@ namespace firewall } } - void esp32FirewallApi::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) + void API::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) { ResourceParameters *params = request->getParams(); int rule_number = atoi(params->getPathParameter(0).c_str()); - if (this->delete_rule_from_firewall(rule_number)) + if (delete_rule_from_firewall(rule_number)) { this->json_message_response(response, "firewall rule deleted", 200); } @@ -145,14 +139,14 @@ namespace firewall } } - void esp32FirewallApi::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) + void API::json_generic_response(HTTPResponse *response, String serialized, const uint16_t response_code) { response->setHeader("Content-Type", "application/json"); response->setStatusCode(response_code); response->println(serialized); } - void esp32FirewallApi::json_message_response(HTTPResponse *response, String message, const uint16_t response_code) + void API::json_message_response(HTTPResponse *response, String message, const uint16_t response_code) { response->setHeader("Content-Type", "application/json"); response->setStatusCode(response_code); @@ -163,7 +157,7 @@ namespace firewall response->println(serialized); } - String esp32FirewallApi::construct_json_firewall_rule(firewall_rule_t *rule_ptr) + String API::construct_json_firewall_rule(firewall_rule_t *rule_ptr) { StaticJsonDocument<256> doc; doc["key"] = rule_ptr->key; @@ -176,13 +170,13 @@ namespace firewall return response; } - String esp32FirewallApi::construct_json_firewall() + String API::construct_json_firewall() { - firewall_rule_t *rule_ptr = this->head; + firewall_rule_t *rule_ptr = head; // Size for approx. 12 Rules StaticJsonDocument<2048> doc; String response; - doc["amount_of_rules"] = this->amount_of_rules; + doc["amount_of_rules"] = amount_of_rules; JsonArray rules = doc.createNestedArray("rules"); while (rule_ptr != NULL) { diff --git a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp b/SourceCode/arduino/lib/Firewall/esp32API.hpp similarity index 80% rename from SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp rename to SourceCode/arduino/lib/Firewall/esp32API.hpp index 86ebaf7..f001d9d 100644 --- a/SourceCode/arduino/lib/Firewall/esp32FirewallAPI.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32API.hpp @@ -1,5 +1,5 @@ -#ifndef ESP32_FIREWALL_API_HPP -#define ESP32_FIREWALL_API_HPP +#ifndef ESP32_API_HPP +#define ESP32_API_HPP #include "HTTPSServer.hpp" #include "SSLCert.hpp" @@ -7,13 +7,14 @@ #include "HTTPResponse.hpp" #include "ArduinoJson.h" +#include "FirewallTypes.h" #include "esp32Firewall.hpp" using namespace httpsserver; namespace firewall { - class esp32FirewallApi : public esp32Firewall + class API : public Firewall { private: HTTPSServer *server; @@ -26,7 +27,6 @@ namespace firewall bool request_has_firewall_parameter(ResourceParameters *); void post_firewall_handler(HTTPRequest *, HTTPResponse *); void delete_firewall_handler(HTTPRequest *, HTTPResponse *); - void restart_device_handler(HTTPRequest *, HTTPResponse *); void not_found_handler(HTTPRequest *, HTTPResponse *); void json_generic_response(HTTPResponse *, String, const uint16_t); @@ -35,8 +35,8 @@ namespace firewall String construct_json_firewall(); public: - esp32FirewallApi(const uint16_t = 8080); - ~esp32FirewallApi(); + API(const uint16_t = 8080); + ~API(); void handle_clients(); }; } diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp index 9d18430..b1ceb7f 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp @@ -2,133 +2,24 @@ namespace firewall { - esp32Firewall::esp32Firewall() + Firewall::Firewall() { - this->setup_eeprom(); - } - - esp32Firewall::~esp32Firewall() - { - } - - String esp32Firewall::protocol_to_string(firewall_protocol_t &protocol) - { - switch (protocol) + this->amount_of_rules = retrieve_settings_value("amount_of_rules"); + for (uint8_t i = 0; i < this->amount_of_rules; i++) { - case FW_TCP: - return "TCP"; - case FW_UDP: - return "UDP"; - default: - return "ALL"; + firewall_rule_t *rule_ptr = retrieve_firewall_rule(i); + add_rule_to_firewall(rule_ptr); } } - firewall_protocol_t esp32Firewall::string_to_protocol(std::string &protocol) + Firewall::~Firewall() { - if (protocol.compare("TCP") == 0) - return FW_TCP; - else if (protocol.compare("UDP") == 0) - return FW_UDP; - else - return FW_ALL; } - String esp32Firewall::target_to_string(firewall_target_t &target) - { - switch (target) - { - case FW_REJECT: - return "REJECT"; - case FW_DROP: - return "DROP"; - default: - return "ACCEPT"; - } - } - - firewall_target_t esp32Firewall::string_to_target(std::string &target) - { - if (target.compare("REJECT") == 0) - return FW_REJECT; - else if (target.compare("DROP") == 0) - return FW_DROP; - else - return FW_ACCEPT; - } - - void esp32Firewall::setup_eeprom() - { - EEPROM.begin(this->eeprom_size); - this->amount_of_rules = EEPROM.read(this->eeprom_settings_head); - uint8_t security_number = EEPROM.read(this->eeprom_settings_head + 1); - if (this->amount_of_rules > 50 || security_number != this->security_number) - { - this->amount_of_rules = 0; - EEPROM.write(this->eeprom_settings_head, this->amount_of_rules); - EEPROM.write(this->eeprom_settings_head + 1, this->security_number); - EEPROM.commit(); - } - log_i("Amount of existing Rules %i", this->amount_of_rules); - this->eeprom_read_firewall_rules(); - } - - void esp32Firewall::eeprom_write_firewall_rule(firewall_rule_t *rule_ptr) - { - EEPROM.write(this->eeprom_settings_head, this->amount_of_rules); - EEPROM.writeString(this->eeprom_rules_head, rule_ptr->source); - this->eeprom_rules_head += IPV4ADDRESS_LENGTH; - EEPROM.writeString(this->eeprom_rules_head, rule_ptr->destination); - this->eeprom_rules_head += IPV4ADDRESS_LENGTH; - EEPROM.write(this->eeprom_rules_head, rule_ptr->protocol); - this->eeprom_rules_head += sizeof(firewall_protocol_t); - EEPROM.write(this->eeprom_rules_head, rule_ptr->target); - this->eeprom_rules_head += sizeof(firewall_target_t); - EEPROM.commit(); - } - - void esp32Firewall::eeprom_write_firewall_rules() - { - this->eeprom_rules_head = eeprom_start_firewall_rules; - firewall_rule_t *rule_ptr = this->head; - while (rule_ptr != NULL) - { - this->eeprom_write_firewall_rule(rule_ptr); - rule_ptr = rule_ptr->next; - } - } - - void esp32Firewall::eeprom_read_firewall_rule(uint8_t &eeprom_address, uint8_t &rule_nr) - { - firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t)); - rule_ptr->key = rule_nr; - strcpy(rule_ptr->source, EEPROM.readString(eeprom_address).c_str()); - eeprom_address += IPV4ADDRESS_LENGTH; - strcpy(rule_ptr->destination, EEPROM.readString(eeprom_address).c_str()); - eeprom_address += IPV4ADDRESS_LENGTH; - rule_ptr->protocol = static_cast(EEPROM.read(eeprom_address)); - eeprom_address += sizeof(firewall_protocol_t); - rule_ptr->target = static_cast(EEPROM.read(eeprom_address)); - eeprom_address += sizeof(firewall_target_t); - add_rule_to_firewall(rule_ptr); - log_i("%s, %s, %s, %s", - rule_ptr->source, - rule_ptr->destination, - protocol_to_string(rule_ptr->protocol), - target_to_string(rule_ptr->target)); - } - - void esp32Firewall::eeprom_read_firewall_rules() - { - uint8_t eeprom_address = eeprom_start_firewall_rules; - for (uint8_t i = 1; i <= this->amount_of_rules; i++) - { - eeprom_read_firewall_rule(eeprom_address, i); - } - } - - void esp32Firewall::add_rule_to_firewall(firewall_rule_t *rule_ptr) + void Firewall::add_rule_to_firewall(firewall_rule_t *rule_ptr) { + store_settings_value("amount_of_rules", this->amount_of_rules); + store_firewall_rule(rule_ptr); firewall_rule_t *temp; if (this->head == NULL) { @@ -146,7 +37,7 @@ namespace firewall return; } - firewall_rule_t *esp32Firewall::get_rule_from_firewall(uint8_t key) + firewall_rule_t *Firewall::get_rule_from_firewall(uint8_t key) { firewall_rule_t *rule_ptr = this->head; if (this->head == NULL) @@ -167,7 +58,7 @@ namespace firewall return rule_ptr; } - bool esp32Firewall::delete_rule_from_firewall(uint8_t key) + bool Firewall::delete_rule_from_firewall(uint8_t key) { if (this->head == NULL) { @@ -205,7 +96,52 @@ namespace firewall } free(current_rule_ptr); this->amount_of_rules--; - this->eeprom_write_firewall_rules(); return true; } + + String Firewall::protocol_to_string(firewall_protocol_t &protocol) + { + switch (protocol) + { + case FW_TCP: + return "TCP"; + case FW_UDP: + return "UDP"; + default: + return "ALL"; + } + } + + firewall_protocol_t Firewall::string_to_protocol(std::string &protocol) + { + if (protocol.compare("TCP") == 0) + return FW_TCP; + else if (protocol.compare("UDP") == 0) + return FW_UDP; + else + return FW_ALL; + } + + String Firewall::target_to_string(firewall_target_t &target) + { + switch (target) + { + case FW_REJECT: + return "REJECT"; + case FW_DROP: + return "DROP"; + default: + return "ACCEPT"; + } + } + + firewall_target_t Firewall::string_to_target(std::string &target) + { + if (target.compare("REJECT") == 0) + return FW_REJECT; + else if (target.compare("DROP") == 0) + return FW_DROP; + else + return FW_ACCEPT; + } } diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp index 62db928..c03df2e 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.hpp @@ -1,26 +1,14 @@ #ifndef ESP32_FIREWALL_HPP #define ESP32_FIREWALL_HPP -#include "EEPROM.h" #include "FirewallTypes.h" - -#define eeprom_start_firewall_rules 4 +#include "esp32Storage.hpp" +#include "WString.h" namespace firewall { - class esp32Firewall + class Firewall : public Storage { - private: - uint16_t eeprom_size = 512; - uint8_t security_number = 93; - int eeprom_settings_head = 0; - int eeprom_rules_head = eeprom_start_firewall_rules; - - void setup_eeprom(); - void eeprom_write_firewall_rules(); - void eeprom_read_firewall_rule(uint8_t &, uint8_t &); - void eeprom_read_firewall_rules(); - protected: uint8_t amount_of_rules = 0; struct firewall_rule *head = NULL; @@ -29,16 +17,14 @@ namespace firewall firewall_rule_t *get_rule_from_firewall(uint8_t); bool delete_rule_from_firewall(uint8_t); - void eeprom_write_firewall_rule(firewall_rule_t *); - - String protocol_to_string(firewall_protocol_t &); - firewall_protocol_t string_to_protocol(std::string &); - String target_to_string(firewall_target_t &); - firewall_target_t string_to_target(std::string &); + String protocol_to_string(firewall_protocol_t &protocol); + firewall_protocol_t string_to_protocol(std::string &protocol); + String target_to_string(firewall_target_t &target); + firewall_target_t string_to_target(std::string &target); public: - esp32Firewall(); - ~esp32Firewall(); + Firewall(); + ~Firewall(); }; } diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index 3681987..882dda8 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -4,12 +4,27 @@ namespace firewall { Storage::Storage() { + this->mount_spiffs(); } Storage::~Storage() { } + void Storage::mount_spiffs() + { + if (!SPIFFS.begin(false)) + { + if (!SPIFFS.begin(true)) + { + log_e("SPIFFS cannot be mounted"); + while (true) + delay(500); + }; + } + log_i("SPIFFS mounted"); + } + uint8_t Storage::retrieve_settings_value(const char *key) { uint8_t amount_of_rules; @@ -61,35 +76,64 @@ namespace firewall httpsserver::SSLCert *Storage::retrieve_certificate() { - this->memory.begin("certificate", true); - uint16_t cert_data_length = this->memory.getBytesLength("cert_data"); - unsigned char cert_data[cert_data_length]; - this->memory.getBytes("cert_data", cert_data, cert_data_length); + File keyFile = SPIFFS.open("/key.der"); + File certFile = SPIFFS.open("/cert.der"); + if (!keyFile || !certFile || keyFile.size() == 0 || certFile.size() == 0) + { + log_w("No certificate found in SPIFFS"); + return NULL; + } + size_t keySize = keyFile.size(); + size_t certSize = certFile.size(); - uint16_t pk_data_length = this->memory.getBytesLength("pk_data"); - unsigned char pk_data[pk_data_length]; - this->memory.getBytes("pk_data", pk_data, pk_data_length); + uint8_t *keyBuffer = new uint8_t[keySize]; + if (keyBuffer == NULL) + { + log_w("Not enough memory to load privat key"); + return NULL; + } + uint8_t *certBuffer = new uint8_t[certSize]; + if (certBuffer == NULL) + { + delete[] keyBuffer; + log_w("Not enough memory to load certificate"); + return NULL; + } + keyFile.read(keyBuffer, keySize); + certFile.read(certBuffer, certSize); - uint16_t pk_length = this->memory.getUInt("pk_length", 0); - - uint16_t cert_length = this->memory.getUInt("pk_length", 0); - this->memory.end(); - - return new httpsserver::SSLCert(cert_data, cert_length, pk_data, pk_length); + keyFile.close(); + certFile.close(); + return new httpsserver::SSLCert(certBuffer, certSize, keyBuffer, keySize); } void Storage::store_certificate(httpsserver::SSLCert *certificate) { - unsigned char *pk_data = certificate->getPKData(); - unsigned char *cert_data = certificate->getCertData(); - uint16_t pk_length = certificate->getPKLength(); - uint16_t cert_length = certificate->getCertLength(); + File keyFile = SPIFFS.open("/key.der"); + File certFile = SPIFFS.open("/cert.der"); + bool failure = false; - this->memory.begin("certificate", false); - this->memory.putBytes("pk_data", pk_data, sizeof(pk_data)); - this->memory.putBytes("cert_data", cert_data, sizeof(cert_data)); - this->memory.putUInt("pk_length", pk_length); - this->memory.putUInt("cert_length", cert_length); - this->memory.end(); + keyFile = SPIFFS.open("/key.der", FILE_WRITE); + if (!keyFile || !keyFile.write(certificate->getPKData(), certificate->getPKLength())) + { + log_w("Could not write /key.der"); + failure = true; + } + if (keyFile) + keyFile.close(); + + certFile = SPIFFS.open("/cert.der", FILE_WRITE); + if (!certFile || !certFile.write(certificate->getCertData(), certificate->getCertLength())) + { + log_w("Could not write /key.der"); + failure = true; + } + if (certFile) + certFile.close(); + + if (failure) + { + log_w("Certificate could not be stored permanently, generating new certificate on reboot..."); + } } } diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp index 4bec08a..558c23b 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -2,6 +2,7 @@ #define ESP32_STORAGE_HPP #include "Preferences.h" +#include "SPIFFS.h" #include "FirewallTypes.h" #include "mbedtls/md.h" #include "SSLCert.hpp" @@ -12,6 +13,7 @@ namespace firewall { private: Preferences memory; + void mount_spiffs(); protected: uint8_t retrieve_settings_value(const char *); diff --git a/SourceCode/arduino/src/main.cpp b/SourceCode/arduino/src/main.cpp index 4b5dbf8..9a1af17 100644 --- a/SourceCode/arduino/src/main.cpp +++ b/SourceCode/arduino/src/main.cpp @@ -1,11 +1,8 @@ #include "theSecrets.h" #include "WiFi.h" +#include "esp32API.hpp" -#include "esp32FirewallAPI.hpp" -#include "esp32Storage.hpp" - -firewall::esp32FirewallApi *firewall_api; -firewall::Storage *storage; +firewall::API *firewall_api; void setup_wifi() { @@ -25,11 +22,10 @@ void setup_wifi() void setup() { setup_wifi(); - // firewall_api = new esp32FirewallApi; - storage = new firewall::Storage; + firewall_api = new firewall::API; } void loop() { - // firewall_api->handle_clients(); + firewall_api->handle_clients(); } \ No newline at end of file From a8cd48c756ba3b159741489e28948b656ace7ad2 Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 21:35:36 +0200 Subject: [PATCH 15/15] all working as intended --- SourceCode/arduino/lib/Firewall/esp32Firewall.cpp | 5 ++++- SourceCode/arduino/lib/Firewall/esp32Storage.cpp | 10 ++++++++++ SourceCode/arduino/lib/Firewall/esp32Storage.hpp | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp index b1ceb7f..223c305 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Firewall.cpp @@ -5,7 +5,7 @@ namespace firewall Firewall::Firewall() { this->amount_of_rules = retrieve_settings_value("amount_of_rules"); - for (uint8_t i = 0; i < this->amount_of_rules; i++) + for (uint8_t i = 1; i <= this->amount_of_rules; i++) { firewall_rule_t *rule_ptr = retrieve_firewall_rule(i); add_rule_to_firewall(rule_ptr); @@ -96,6 +96,9 @@ namespace firewall } free(current_rule_ptr); this->amount_of_rules--; + store_settings_value("amount_of_rules", this->amount_of_rules); + if (this->amount_of_rules != 0) + store_all_firewall_rules(head); return true; } diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp index 882dda8..cbdb75b 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.cpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.cpp @@ -61,6 +61,16 @@ namespace firewall return rule_ptr; } + void Storage::store_all_firewall_rules(firewall_rule_t *head) + { + firewall_rule_t *temp = head; + while (temp != NULL) + { + store_firewall_rule(temp); + temp = temp->next; + } + } + void Storage::store_firewall_rule(firewall_rule_t *rule_ptr) { char rulename[9]; // fwRule99\n diff --git a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp index 558c23b..cd88378 100644 --- a/SourceCode/arduino/lib/Firewall/esp32Storage.hpp +++ b/SourceCode/arduino/lib/Firewall/esp32Storage.hpp @@ -4,7 +4,6 @@ #include "Preferences.h" #include "SPIFFS.h" #include "FirewallTypes.h" -#include "mbedtls/md.h" #include "SSLCert.hpp" namespace firewall @@ -20,10 +19,11 @@ namespace firewall void store_settings_value(const char *, const uint8_t); firewall_rule_t *retrieve_firewall_rule(const uint8_t); + void store_all_firewall_rules(firewall_rule_t *); void store_firewall_rule(firewall_rule_t *); httpsserver::SSLCert *retrieve_certificate(); - void store_certificate(httpsserver::SSLCert *certificate); + void store_certificate(httpsserver::SSLCert *); public: Storage();