From 790371a099f3e243c6e7a7ba10701133504d95aa Mon Sep 17 00:00:00 2001 From: Florian Hoss Date: Wed, 20 Apr 2022 08:17:55 +0200 Subject: [PATCH] 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; }