2022-04-23 23:36:44 +02:00
|
|
|
#include "API.hpp"
|
|
|
|
|
2022-04-24 00:13:20 +02:00
|
|
|
namespace fw
|
2022-04-23 23:36:44 +02:00
|
|
|
{
|
|
|
|
API::API(const char *username, const char *password, const uint16_t port)
|
|
|
|
{
|
|
|
|
if (this->setup_auth(username, password) == ERROR)
|
|
|
|
endless_loop();
|
|
|
|
#ifdef ESP32
|
|
|
|
this->server = new WebServer(port);
|
|
|
|
#elif defined(ESP8266)
|
|
|
|
this->server = new ESP8266WebServer(port);
|
|
|
|
#endif
|
|
|
|
this->setup_routing();
|
|
|
|
Serial.println("Starting server...");
|
|
|
|
this->server->begin();
|
|
|
|
}
|
|
|
|
|
|
|
|
API::~API()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void API::handle_client()
|
|
|
|
{
|
|
|
|
this->server->handleClient();
|
|
|
|
}
|
|
|
|
|
|
|
|
ok_t API::setup_auth(const char *username, const char *password)
|
|
|
|
{
|
|
|
|
if (!username || *username == 0x00 || strlen(username) > CREDENTIALS_LENGTH)
|
|
|
|
{
|
|
|
|
Serial.println("Username too long or missing!");
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
strncpy(credentials.username, username, CREDENTIALS_LENGTH);
|
|
|
|
if (!password || *password == 0x00 || strlen(password) > CREDENTIALS_LENGTH)
|
|
|
|
{
|
|
|
|
Serial.println("Password too long or missing!");
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
strncpy(credentials.password, password, CREDENTIALS_LENGTH);
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void API::setup_routing()
|
|
|
|
{
|
|
|
|
this->server->on(UriRegex("/api/v1/firewall/([0-9]+)"), HTTP_GET, std::bind(&API::get_firewall_rule_handler, this));
|
|
|
|
this->server->on("/api/v1/firewall", HTTP_GET, std::bind(&API::get_firewall_rules_handler, this));
|
|
|
|
this->server->on("/api/v1/firewall", HTTP_POST, std::bind(&API::post_firewall_handler, this));
|
|
|
|
this->server->on(UriRegex("/api/v1/firewall/([0-9]+)"), HTTP_DELETE, std::bind(&API::delete_firewall_handler, this));
|
|
|
|
this->server->onNotFound(std::bind(&API::not_found_handler, this));
|
|
|
|
}
|
|
|
|
|
|
|
|
void API::not_found_handler()
|
|
|
|
{
|
|
|
|
this->json_message_response("not found", 404);
|
|
|
|
}
|
|
|
|
|
|
|
|
void API::get_firewall_rule_handler()
|
|
|
|
{
|
|
|
|
String param = this->server->pathArg(0);
|
|
|
|
int rule_number = atoi(param.c_str());
|
|
|
|
firewall_rule_t *rule_ptr = get_rule_from_firewall(rule_number);
|
|
|
|
if (rule_ptr == NULL)
|
|
|
|
{
|
|
|
|
this->json_message_response("rule not found", 404);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->json_generic_response(construct_json_firewall_rule(rule_ptr), 200);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void API::get_firewall_rules_handler()
|
|
|
|
{
|
2022-04-23 23:50:46 +02:00
|
|
|
this->json_generic_response(this->construct_json_firewall(), 200);
|
2022-04-23 23:36:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void API::post_firewall_handler()
|
|
|
|
{
|
2022-04-23 23:50:46 +02:00
|
|
|
if (request_has_firewall_parameter())
|
|
|
|
{
|
|
|
|
firewall_rule_t *rule_ptr = (firewall_rule_t *)malloc(sizeof(firewall_rule_t));
|
|
|
|
rule_ptr->key = ++amount_of_rules;
|
|
|
|
|
|
|
|
String source = this->server->arg("source");
|
|
|
|
strncpy(rule_ptr->source, source.c_str(), sizeof(rule_ptr->source));
|
|
|
|
String destination = this->server->arg("destination");
|
|
|
|
strncpy(rule_ptr->destination, destination.c_str(), sizeof(rule_ptr->destination));
|
|
|
|
|
|
|
|
String protocol = this->server->arg("protocol");
|
|
|
|
rule_ptr->protocol = string_to_protocol(protocol);
|
|
|
|
String target = this->server->arg("target");
|
|
|
|
rule_ptr->target = string_to_target(target);
|
|
|
|
|
|
|
|
add_rule_to_firewall(rule_ptr);
|
|
|
|
this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 200);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->json_message_response("not enough parameter", 400);
|
|
|
|
}
|
2022-04-23 23:36:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void API::delete_firewall_handler()
|
|
|
|
{
|
2022-04-23 23:50:46 +02:00
|
|
|
String param = this->server->pathArg(0);
|
|
|
|
int rule_number = atoi(param.c_str());
|
|
|
|
if (delete_rule_from_firewall(rule_number) == SUCCESS)
|
|
|
|
{
|
|
|
|
this->json_message_response("firewall rule deleted", 200);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->json_message_response("cannot delete firewall rule", 500);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool API::request_has_firewall_parameter()
|
|
|
|
{
|
|
|
|
if (!this->server->args())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return this->server->hasArg("source") ||
|
|
|
|
this->server->hasArg("destination") ||
|
|
|
|
this->server->hasArg("protocol") ||
|
|
|
|
this->server->hasArg("target");
|
|
|
|
}
|
2022-04-23 23:36:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
String API::json_new_attribute(String key, String value, bool last)
|
|
|
|
{
|
|
|
|
String json_string;
|
|
|
|
json_string += "\"" + key + "\": \"" + value + "\"";
|
|
|
|
if (!last)
|
|
|
|
json_string += ",";
|
|
|
|
return json_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
String API::json_new_attribute(String key, uint8_t value, bool last)
|
|
|
|
{
|
|
|
|
return json_new_attribute(key, String(value), last);
|
|
|
|
}
|
|
|
|
|
|
|
|
void API::json_generic_response(String serialized_string, const uint16_t response_code)
|
|
|
|
{
|
|
|
|
this->server->send(response_code, "application/json; charset=utf-8", serialized_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
void API::json_message_response(String message, const uint16_t response_code)
|
|
|
|
{
|
|
|
|
String serialized_string = "{";
|
|
|
|
serialized_string += json_new_attribute("message", message, true);
|
|
|
|
serialized_string += "}";
|
|
|
|
this->server->send(response_code, "application/json; charset=utf-8", serialized_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
String API::construct_json_firewall_rule(firewall_rule_t *rule_ptr)
|
|
|
|
{
|
|
|
|
String serialized_string = "{";
|
|
|
|
serialized_string += json_new_attribute("key", rule_ptr->key);
|
|
|
|
serialized_string += json_new_attribute("source", rule_ptr->source);
|
|
|
|
serialized_string += json_new_attribute("destination", rule_ptr->destination);
|
|
|
|
serialized_string += json_new_attribute("protocol", protocol_to_string(rule_ptr->protocol));
|
|
|
|
serialized_string += json_new_attribute("target", target_to_string(rule_ptr->target), true);
|
|
|
|
serialized_string += "}";
|
|
|
|
return serialized_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
String API::construct_json_firewall()
|
|
|
|
{
|
|
|
|
firewall_rule_t *rule_ptr = head;
|
|
|
|
String serialized_string = "{";
|
|
|
|
serialized_string += json_new_attribute("amount_of_rules", amount_of_rules);
|
|
|
|
serialized_string += "\"rules\": [";
|
|
|
|
while (rule_ptr != NULL)
|
|
|
|
{
|
|
|
|
serialized_string += construct_json_firewall_rule(rule_ptr);
|
|
|
|
serialized_string += ",";
|
|
|
|
rule_ptr = rule_ptr->next;
|
|
|
|
}
|
|
|
|
serialized_string += "]}";
|
|
|
|
return serialized_string;
|
|
|
|
}
|
|
|
|
}
|