diff --git a/ESPFirewall/lib/Firewall/src/API.cpp b/ESPFirewall/lib/Firewall/src/API.cpp index 1d1e426..cf8186d 100644 --- a/ESPFirewall/lib/Firewall/src/API.cpp +++ b/ESPFirewall/lib/Firewall/src/API.cpp @@ -1,6 +1,6 @@ #include "API.hpp" -namespace firewall +namespace fw { API::API(const char *username, const char *password, const uint16_t port) { diff --git a/ESPFirewall/lib/Firewall/src/API.hpp b/ESPFirewall/lib/Firewall/src/API.hpp index e386785..fa2d7b0 100644 --- a/ESPFirewall/lib/Firewall/src/API.hpp +++ b/ESPFirewall/lib/Firewall/src/API.hpp @@ -8,12 +8,12 @@ #endif #include -#include "esp32Firewall.hpp" +#include "Rules.hpp" #include "Utils.hpp" -namespace firewall +namespace fw { - class API : public Firewall + class API : public Rules { private: #ifdef ESP32 @@ -40,10 +40,12 @@ namespace firewall String construct_json_firewall_rule(firewall_rule_t *); String construct_json_firewall(); - public: - API(const char *, const char *, const uint16_t = 8080); - ~API(); + protected: void handle_client(); + + public: + API(const char *, const char *, const uint16_t); + ~API(); }; } diff --git a/ESPFirewall/lib/Firewall/src/Firewall.hpp b/ESPFirewall/lib/Firewall/src/Firewall.hpp new file mode 100644 index 0000000..99e3174 --- /dev/null +++ b/ESPFirewall/lib/Firewall/src/Firewall.hpp @@ -0,0 +1,25 @@ +#ifndef FIREWALL_HPP +#define FIREWALL_HPP + +#include "API.hpp" + +namespace fw +{ + class Firewall : public API + { + private: + public: + Firewall(const char *, const char *, const uint16_t = 8080); + ~Firewall(); + void handle_api_client(); + }; + + Firewall::Firewall(const char *api_username, const char *api_password, const uint16_t port) : API(api_username, api_password, port) {} + Firewall::~Firewall() {} + void Firewall::handle_api_client() + { + handle_client(); + } +} + +#endif diff --git a/ESPFirewall/lib/Firewall/src/esp32Firewall.cpp b/ESPFirewall/lib/Firewall/src/Rules.cpp similarity index 88% rename from ESPFirewall/lib/Firewall/src/esp32Firewall.cpp rename to ESPFirewall/lib/Firewall/src/Rules.cpp index 07ec32e..3a40417 100644 --- a/ESPFirewall/lib/Firewall/src/esp32Firewall.cpp +++ b/ESPFirewall/lib/Firewall/src/Rules.cpp @@ -1,8 +1,8 @@ -#include "esp32Firewall.hpp" +#include "Rules.hpp" -namespace firewall +namespace fw { - Firewall::Firewall() + Rules::Rules() { this->amount_of_rules = retrieve_settings_value("amount_of_rules"); for (uint8_t i = 1; i <= this->amount_of_rules; i++) @@ -12,11 +12,11 @@ namespace firewall } } - Firewall::~Firewall() + Rules::~Rules() { } - void Firewall::add_rule_to_firewall(firewall_rule_t *rule_ptr) + void Rules::add_rule_to_firewall(firewall_rule_t *rule_ptr) { store_settings_value("amount_of_rules", this->amount_of_rules); store_firewall_rule(rule_ptr); @@ -37,7 +37,7 @@ namespace firewall return; } - firewall_rule_t *Firewall::get_rule_from_firewall(uint8_t key) + firewall_rule_t *Rules::get_rule_from_firewall(uint8_t key) { firewall_rule_t *rule_ptr = this->head; if (this->head == NULL) @@ -58,7 +58,7 @@ namespace firewall return rule_ptr; } - ok_t Firewall::delete_rule_from_firewall(uint8_t key) + ok_t Rules::delete_rule_from_firewall(uint8_t key) { if (this->head == NULL) return NO_ACTION; diff --git a/ESPFirewall/lib/Firewall/src/esp32Firewall.hpp b/ESPFirewall/lib/Firewall/src/Rules.hpp similarity index 81% rename from ESPFirewall/lib/Firewall/src/esp32Firewall.hpp rename to ESPFirewall/lib/Firewall/src/Rules.hpp index 7afd7fc..40f670b 100644 --- a/ESPFirewall/lib/Firewall/src/esp32Firewall.hpp +++ b/ESPFirewall/lib/Firewall/src/Rules.hpp @@ -5,9 +5,9 @@ #include "esp32Storage.hpp" #include "WString.h" -namespace firewall +namespace fw { - class Firewall : public Storage + class Rules : public Storage { protected: uint8_t amount_of_rules = 0; @@ -18,8 +18,8 @@ namespace firewall ok_t delete_rule_from_firewall(uint8_t); public: - Firewall(); - ~Firewall(); + Rules(); + ~Rules(); }; } diff --git a/ESPFirewall/lib/Firewall/src/Utils.cpp b/ESPFirewall/lib/Firewall/src/Utils.cpp index 67193b9..e6a2f75 100644 --- a/ESPFirewall/lib/Firewall/src/Utils.cpp +++ b/ESPFirewall/lib/Firewall/src/Utils.cpp @@ -1,6 +1,6 @@ #include "Utils.hpp" -namespace firewall +namespace fw { String protocol_to_string(firewall_protocol_t &protocol) { diff --git a/ESPFirewall/lib/Firewall/src/Utils.hpp b/ESPFirewall/lib/Firewall/src/Utils.hpp index 392a338..19c6fdc 100644 --- a/ESPFirewall/lib/Firewall/src/Utils.hpp +++ b/ESPFirewall/lib/Firewall/src/Utils.hpp @@ -4,7 +4,7 @@ #include "Arduino.h" #include "WString.h" -namespace firewall +namespace fw { static const uint8_t IPV4ADDRESS_LENGTH = 16; static const uint8_t CREDENTIALS_LENGTH = 32; diff --git a/ESPFirewall/lib/Firewall/src/esp32API.cpp b/ESPFirewall/lib/Firewall/src/esp32API.cpp deleted file mode 100644 index bc80051..0000000 --- a/ESPFirewall/lib/Firewall/src/esp32API.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include "esp32API.hpp" - -namespace firewall -{ - API::API(const char *username, const char *password, const uint16_t port) - { - if (this->setup_auth(username, password) == ERROR) - endless_loop(); - if (this->setup_certificate() == ERROR) - endless_loop(); - 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 on port: %i", port); - } - - API::~API() - { - } - - void API::handle_clients() - { - this->server->loop(); - } - - ok_t API::setup_auth(const char *username, const char *password) - { - if (!username || *username == 0x00 || strlen(username) > CREDENTIALS_LENGTH) - { - log_e("Username too long or missing!"); - return ERROR; - } - strncpy(credentials.username, username, CREDENTIALS_LENGTH); - if (!password || *password == 0x00 || strlen(password) > CREDENTIALS_LENGTH) - { - log_e("Password too long or missing!"); - return ERROR; - } - strncpy(credentials.password, password, CREDENTIALS_LENGTH); - return SUCCESS; - } - - auth_t API::check_auth(HTTPRequest *request, HTTPResponse *response) - { - std::string reqUsername = request->getBasicAuthUser(); - std::string reqPassword = request->getBasicAuthPassword(); - if ((strncmp(this->credentials.username, reqUsername.c_str(), CREDENTIALS_LENGTH) != 0) || - (strncmp(this->credentials.password, reqPassword.c_str(), CREDENTIALS_LENGTH) != 0)) - { - this->json_message_response(response, "unauthorized", 403); - return DENIED; - } - return AUTHENTICATED; - } - - ok_t API::setup_certificate() - { - this->certificate = retrieve_certificate(); - if (certificate != NULL) - return NO_ACTION; - log_i("Creating a new 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("Cannot create a server-certificate"); - return ERROR; - } - store_certificate(certificate); - log_i("Creating a server-certificate was successful"); - return SUCCESS; - } - - void API::setup_routing() - { - 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->setDefaultNode(not_found); - } - - void API::not_found_handler(HTTPRequest *request, HTTPResponse *response) - { - this->json_message_response(response, "not found", 404); - } - - void API::get_firewall_rule_handler(HTTPRequest *request, HTTPResponse *response) - { - if (this->check_auth(request, response) == DENIED) - return; - ResourceParameters *params = request->getParams(); - int rule_number = atoi(params->getPathParameter(0).c_str()); - firewall_rule_t *rule_ptr = 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 API::get_firewall_rules_handler(HTTPRequest *request, HTTPResponse *response) - { - if (this->check_auth(request, response) == DENIED) - return; - this->json_generic_response(response, this->construct_json_firewall(), 200); - } - - bool API::request_has_firewall_parameter(ResourceParameters *params) - { - return params->isQueryParameterSet("source") || - params->isQueryParameterSet("destination") || - params->isQueryParameterSet("protocol") || - params->isQueryParameterSet("target"); - } - - void API::post_firewall_handler(HTTPRequest *request, HTTPResponse *response) - { - if (this->check_auth(request, response) == DENIED) - return; - 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; - - std::string source; - params->getQueryParameter("source", source); - strncpy(rule_ptr->source, source.c_str(), sizeof(rule_ptr->source)); - std::string destination; - params->getQueryParameter("destination", destination); - strncpy(rule_ptr->destination, destination.c_str(), sizeof(rule_ptr->destination)); - - 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); - - add_rule_to_firewall(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 API::delete_firewall_handler(HTTPRequest *request, HTTPResponse *response) - { - if (this->check_auth(request, response) == DENIED) - return; - ResourceParameters *params = request->getParams(); - int rule_number = atoi(params->getPathParameter(0).c_str()); - if (delete_rule_from_firewall(rule_number) == SUCCESS) - { - this->json_message_response(response, "firewall rule deleted", 200); - } - else - { - this->json_message_response(response, "cannot delete firewall rule", 500); - } - } - - 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 API::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 API::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 API::construct_json_firewall() - { - firewall_rule_t *rule_ptr = head; - // Size for approx. 12 Rules - StaticJsonDocument<2048> doc; - String response; - doc["amount_of_rules"] = 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; - } -} diff --git a/ESPFirewall/lib/Firewall/src/esp32API.hpp b/ESPFirewall/lib/Firewall/src/esp32API.hpp deleted file mode 100644 index 95afed5..0000000 --- a/ESPFirewall/lib/Firewall/src/esp32API.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef ESP32_API_HPP -#define ESP32_API_HPP - -#include "HTTPSServer.hpp" -#include "SSLCert.hpp" -#include "HTTPRequest.hpp" -#include "HTTPResponse.hpp" -#include "ArduinoJson.h" - -#include "Utils.hpp" -#include "esp32Firewall.hpp" - -using namespace httpsserver; - -namespace firewall -{ - class API : public Firewall - { - private: - HTTPSServer *server; - SSLCert *certificate; - credential_t credentials; - - ok_t setup_auth(const char *, const char *); - auth_t check_auth(HTTPRequest *, HTTPResponse *); - ok_t 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 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: - API(const char *, const char *, const uint16_t = 8080); - ~API(); - void handle_clients(); - }; -} - -#endif diff --git a/ESPFirewall/lib/Firewall/src/esp32Storage.cpp b/ESPFirewall/lib/Firewall/src/esp32Storage.cpp index 0749107..7516f86 100644 --- a/ESPFirewall/lib/Firewall/src/esp32Storage.cpp +++ b/ESPFirewall/lib/Firewall/src/esp32Storage.cpp @@ -1,6 +1,6 @@ #include "esp32Storage.hpp" -namespace firewall +namespace fw { Storage::Storage() { @@ -84,66 +84,66 @@ namespace firewall this->memory.end(); } - httpsserver::SSLCert *Storage::retrieve_certificate() - { - File keyFile = SPIFFS.open("/key.der"); - File certFile = SPIFFS.open("/cert.der"); - if (!keyFile || !certFile || keyFile.size() == 0 || certFile.size() == 0) - { - log_e("No server-certificate found in SPIFFS"); - return NULL; - } - size_t keySize = keyFile.size(); - size_t certSize = certFile.size(); + // httpsserver::SSLCert *Storage::retrieve_certificate() + // { + // File keyFile = SPIFFS.open("/key.der"); + // File certFile = SPIFFS.open("/cert.der"); + // if (!keyFile || !certFile || keyFile.size() == 0 || certFile.size() == 0) + // { + // log_e("No server-certificate found in SPIFFS"); + // return NULL; + // } + // size_t keySize = keyFile.size(); + // size_t certSize = certFile.size(); - uint8_t *keyBuffer = new uint8_t[keySize]; - if (keyBuffer == NULL) - { - log_w("Not enough memory to load private key"); - return NULL; - } - uint8_t *certBuffer = new uint8_t[certSize]; - if (certBuffer == NULL) - { - delete[] keyBuffer; - log_w("Not enough memory to load server-certificate"); - return NULL; - } - keyFile.read(keyBuffer, keySize); - certFile.read(certBuffer, certSize); + // uint8_t *keyBuffer = new uint8_t[keySize]; + // if (keyBuffer == NULL) + // { + // log_w("Not enough memory to load private key"); + // return NULL; + // } + // uint8_t *certBuffer = new uint8_t[certSize]; + // if (certBuffer == NULL) + // { + // delete[] keyBuffer; + // log_w("Not enough memory to load server-certificate"); + // return NULL; + // } + // keyFile.read(keyBuffer, keySize); + // certFile.read(certBuffer, certSize); - keyFile.close(); - certFile.close(); - return new httpsserver::SSLCert(certBuffer, certSize, keyBuffer, keySize); - } + // keyFile.close(); + // certFile.close(); + // return new httpsserver::SSLCert(certBuffer, certSize, keyBuffer, keySize); + // } - void Storage::store_certificate(httpsserver::SSLCert *certificate) - { - File keyFile = SPIFFS.open("/key.der"); - File certFile = SPIFFS.open("/cert.der"); - bool failure = false; + // void Storage::store_certificate(httpsserver::SSLCert *certificate) + // { + // File keyFile = SPIFFS.open("/key.der"); + // File certFile = SPIFFS.open("/cert.der"); + // bool failure = false; - keyFile = SPIFFS.open("/key.der", FILE_WRITE); - if (!keyFile || !keyFile.write(certificate->getPKData(), certificate->getPKLength())) - { - log_w("Cannot write /key.der"); - failure = true; - } - if (keyFile) - keyFile.close(); + // keyFile = SPIFFS.open("/key.der", FILE_WRITE); + // if (!keyFile || !keyFile.write(certificate->getPKData(), certificate->getPKLength())) + // { + // log_w("Cannot 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("Cannot write /cert.der"); - failure = true; - } - if (certFile) - certFile.close(); + // certFile = SPIFFS.open("/cert.der", FILE_WRITE); + // if (!certFile || !certFile.write(certificate->getCertData(), certificate->getCertLength())) + // { + // log_w("Cannot write /cert.der"); + // failure = true; + // } + // if (certFile) + // certFile.close(); - if (failure) - { - log_w("Server-certificate could not be stored permanently, generating new certificate on reboot..."); - } - } + // if (failure) + // { + // log_w("Server-certificate could not be stored permanently, generating new certificate on reboot..."); + // } + // } } diff --git a/ESPFirewall/lib/Firewall/src/esp32Storage.hpp b/ESPFirewall/lib/Firewall/src/esp32Storage.hpp index 04ec725..0aa9d66 100644 --- a/ESPFirewall/lib/Firewall/src/esp32Storage.hpp +++ b/ESPFirewall/lib/Firewall/src/esp32Storage.hpp @@ -4,9 +4,8 @@ #include "Preferences.h" #include "SPIFFS.h" #include "Utils.hpp" -#include "SSLCert.hpp" -namespace firewall +namespace fw { class Storage { @@ -22,8 +21,8 @@ namespace firewall void store_all_firewall_rules(firewall_rule_t *); void store_firewall_rule(firewall_rule_t *); - httpsserver::SSLCert *retrieve_certificate(); - void store_certificate(httpsserver::SSLCert *); + // httpsserver::SSLCert *retrieve_certificate(); + // void store_certificate(httpsserver::SSLCert *); public: Storage(); diff --git a/ESPFirewall/platformio.ini b/ESPFirewall/platformio.ini index 1752a72..f51da2b 100644 --- a/ESPFirewall/platformio.ini +++ b/ESPFirewall/platformio.ini @@ -14,12 +14,10 @@ board = esp32dev framework = arduino monitor_speed = 115200 build_flags = -DCORE_DEBUG_LEVEL=3 -lib_deps = me-no-dev/ESP Async WebServer@^1.2.3 [env:esp8266] +platform = espressif8266 board = d1_mini framework = arduino monitor_speed = 115200 build_flags = -DCORE_DEBUG_LEVEL=3 -platform = espressif8266 -lib_deps = me-no-dev/ESP Async WebServer@^1.2.3 diff --git a/ESPFirewall/src/main.cpp b/ESPFirewall/src/main.cpp index 8d72398..5b8e8fa 100644 --- a/ESPFirewall/src/main.cpp +++ b/ESPFirewall/src/main.cpp @@ -6,9 +6,9 @@ #include #endif -#include "API.hpp" +#include "Firewall.hpp" -firewall::API *firewall_api; +fw::Firewall *firewall; void setup_wifi() { @@ -29,10 +29,10 @@ void setup_wifi() void setup() { setup_wifi(); - firewall_api = new firewall::API(api_username, api_password); + firewall = new fw::Firewall(api_username, api_password, 8080); } void loop() { - firewall_api->handle_client(); + firewall->handle_api_client(); } \ No newline at end of file