Skip to content

Commit

Permalink
New feature added: MAC Filter
Browse files Browse the repository at this point in the history
- Added a new MAC Filter feature for enhanced network security.
  • Loading branch information
gjroots committed Jan 26, 2024
1 parent 2ad4fca commit d82673d
Show file tree
Hide file tree
Showing 26 changed files with 489 additions and 22 deletions.
2 changes: 1 addition & 1 deletion components/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(SRCS utils.c initialization.c nvm.c mac_generator.c
idf_component_register(SRCS utils.c initialization.c nvm.c mac_generator.c mac_filter.c

INCLUDE_DIRS include
REQUIRES cmd_router cmd_nvs nvs_flash json esp_http_server)
2 changes: 1 addition & 1 deletion components/utils/include/initialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extern "C"
#define DEFAULT_SSID "ESP32_NAT_Router +"

bool IsLedEnable, IsWebServerEnable, IsCustomDnsEnable,
IsRandomizeMacEnable, IsDarkModeEnable, IsWifiAuthFail;
IsRandomizeMacEnable, IsDarkModeEnable, IsWifiAuthFail, IsMacFilterEnable, IsAllowList;

char *customDNSip, *authUsername,
*authPass, *macAp, *dnsIP, *cache;
Expand Down
32 changes: 32 additions & 0 deletions components/utils/include/mac_filter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @author Jaya Satish
*
*@copyright Copyright (c) 2023
*Licensed under MIT
*
*/

#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <stdbool.h>
#include <esp_err.h>
#include <cJSON.h>

#define MAX_MAC_ADDRESSES 10
#define NVS_KEY "stored_macs"


esp_err_t store_mac_address_in_nvs(const char *macAddress);
esp_err_t remove_mac_address_from_nvs(const char *macAddress);
bool check_mac_address_in_nvs(const char *macAddress);
cJSON *retrieve_mac_addresses_as_json();
void mac_filter(const uint8_t mac[6],uint8_t aid);
void refresh_mac_filter();

#ifdef __cplusplus
}
#endif
9 changes: 7 additions & 2 deletions components/utils/initialization.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ static const char *TAG = "utils/initialization";

bool IsLedEnable = true, IsWebServerEnable = true,
IsCustomDnsEnable = false, IsRandomizeMacEnable = false,
IsDarkModeEnable = false, IsWifiAuthFail = false;
IsDarkModeEnable = false, IsWifiAuthFail = false,
IsMacFilterEnable = false, IsAllowList = false;

char *ssid, *ent_username, *ent_identity,
*passwd, *static_ip, *subnet_mask, *gateway_addr,
Expand All @@ -29,7 +30,7 @@ char currentMAC[18];
esp_err_t IRAM_ATTR parms_init()
{
int webServer = 1, ledEnable = 1, customDnsEnable = 0,
darkModeEnable = 0, randomizeMac = 0;
darkModeEnable = 0, randomizeMac = 0, isMacFilterEnable = 0, isAllowList = 0;

// ESP_LOGW(TAG, "initialization Started");
get_config_param_str("ssid", &ssid);
Expand All @@ -54,6 +55,8 @@ esp_err_t IRAM_ATTR parms_init()
get_config_param_int("randomize_mac", &randomizeMac);
get_config_param_int("max_login_attempts", &max_login_attempts);
get_config_param_int("lock_out_time_minutes", &lock_out_time_minutes);
get_config_param_int("mac_Filter", &isMacFilterEnable);
get_config_param_int("Is_allow_list", &isAllowList);

ap_ssid = (ap_ssid != NULL) ? ap_ssid : DEFAULT_SSID;
ap_passwd = (ap_passwd != NULL) ? ap_passwd : "";
Expand All @@ -79,6 +82,8 @@ esp_err_t IRAM_ATTR parms_init()
IsCustomDnsEnable = (customDnsEnable != 0);
IsDarkModeEnable = (darkModeEnable != 0);
IsRandomizeMacEnable = (randomizeMac != 0);
IsMacFilterEnable = (isMacFilterEnable != 0);
IsAllowList = (isAllowList != 0);
auth_info.username = authUsername;
auth_info.password = authPass;

Expand Down
82 changes: 82 additions & 0 deletions components/utils/mac_filter.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* @author Jaya Satish
* @license
* this software licensed under MIT
*
*
*/

#include <stdio.h>
#include <nvs_flash.h>
#include <cJSON.h>
#include <string.h>
#include <esp_log.h>
#include <esp_wifi.h>
#include <esp_netif.h>
#include <esp_wifi_types.h>

#include "mac_filter.h"
#include "initialization.h"


bool check_mac_address_in_nvs(const char *macAddress) {
cJSON *json = retrieve_mac_addresses_as_json();
if (json == NULL) return false;

int numMacs = cJSON_GetArraySize(json);
for (int i = 0; i < numMacs; i++) {
if (strcmp(cJSON_GetArrayItem(json, i)->valuestring, macAddress) == 0) {
cJSON_Delete(json);
return true;
}
}

cJSON_Delete(json);
return false;
}

//-----------------------------------------------------------------------------
void mac_filter(const uint8_t mac[6], uint8_t aid) {
char mac_address[18];
sprintf(mac_address, MACSTR, MAC2STR(mac));
if (IsMacFilterEnable) {
if ((IsAllowList && !check_mac_address_in_nvs(mac_address)) ||
(!IsAllowList && check_mac_address_in_nvs(mac_address))) {
ESP_LOGI("MAC Filter","MAC Address %s not allowed, disconnecting...\n", IsAllowList ? "NOT found in Allow List" : "found in Deny List");
esp_wifi_deauth_sta(aid);
}
}
}

//-----------------------------------------------------------------------------
esp_err_t check_in_filter_list(const uint8_t mac[6]) {
uint16_t aid;
esp_err_t err = esp_wifi_ap_get_sta_aid(mac, &aid);
if (err == ESP_OK) {
mac_filter(mac, aid);
} else {
printf("Failed to get AID for MAC address\n");
}
return err;
}

//-----------------------------------------------------------------------------
void refresh_mac_filter() {
wifi_sta_list_t wifi_sta_list;
tcpip_adapter_sta_list_t adapter_sta_list;
memset(&wifi_sta_list, 0, sizeof(wifi_sta_list));
memset(&adapter_sta_list, 0, sizeof(adapter_sta_list));
ESP_ERROR_CHECK(esp_wifi_ap_get_sta_list(&wifi_sta_list));
ESP_ERROR_CHECK(tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list));

for (int i = 0; i < adapter_sta_list.num; i++) {
tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
esp_err_t result = check_in_filter_list(station.mac);
if (result != ESP_OK) {
//printf("Error processing MAC address at index %d\n", i);
}

}
}

//-----------------------------------------------------------------------------
113 changes: 113 additions & 0 deletions components/utils/nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
#include <nvs_flash.h>
#include <esp_log.h>
#include "esp_err.h"
#include <cJSON.h>

#include "nvm.h"
#include "router_globals.h"
#include "utils.h"
#include "mac_filter.h"

static const char *TAG = "utils/nvm";

Expand Down Expand Up @@ -66,3 +69,113 @@ esp_err_t nvm_erase(void)
nvs_close(nvs_handle);
return ESP_OK;
}

//-----------------------------------------------------------------------------
cJSON *retrieve_mac_addresses_as_json() {
nvs_handle_t handle;
esp_err_t err = nvs_open(PARAM_NAMESPACE, NVS_READONLY, &handle);
if (err != ESP_OK) {
return NULL;
}

size_t required_size;
err = nvs_get_str(handle, NVS_KEY, NULL, &required_size);
if (err != ESP_OK || required_size == 0) {
nvs_close(handle);
return NULL;
}

char *buffer = malloc(required_size);
if (buffer == NULL) {
nvs_close(handle);
return NULL;
}

err = nvs_get_str(handle, NVS_KEY, buffer, &required_size);
if (err != ESP_OK) {
free(buffer);
nvs_close(handle);
return NULL;
}

cJSON *json = cJSON_Parse(buffer);
free(buffer);
nvs_close(handle);
return json;
}

//-----------------------------------------------------------------------------
esp_err_t save_mac_addresses_as_json(cJSON *json) {
nvs_handle_t handle;
esp_err_t err = nvs_open(PARAM_NAMESPACE, NVS_READWRITE, &handle);
if (err != ESP_OK) {
cJSON_Delete(json);
return err;
}

char *serialized = cJSON_Print(json);
if (serialized == NULL) {
cJSON_Delete(json);
nvs_close(handle);
return ESP_ERR_NO_MEM;
}

err = nvs_set_str(handle, NVS_KEY, serialized);

ESP_LOGI("MACS ARE","%s",serialized);
free(serialized);
nvs_close(handle);
return err;
}

//-----------------------------------------------------------------------------
esp_err_t store_mac_address_in_nvs(const char *macAddress) {
cJSON *json = retrieve_mac_addresses_as_json();
if (json == NULL) {
json = cJSON_CreateArray();
}

int numMacs = cJSON_GetArraySize(json);
if (numMacs >= MAX_MAC_ADDRESSES) {
cJSON_Delete(json);
return ESP_ERR_NO_MEM;
}

for (int i = 0; i < numMacs; i++) {
const char *storedMac = cJSON_GetArrayItem(json, i)->valuestring;
if (strcmp(storedMac, macAddress) == 0) {
cJSON_Delete(json);
return ESP_OK;
}
}

cJSON_AddItemToArray(json, cJSON_CreateString(macAddress));

esp_err_t err = save_mac_addresses_as_json(json);
cJSON_Delete(json);
return err;
}

//-----------------------------------------------------------------------------
esp_err_t remove_mac_address_from_nvs(const char *macAddress) {
cJSON *json = retrieve_mac_addresses_as_json();
if (json == NULL) {
return ESP_ERR_NVS_NOT_FOUND;
}

int numMacs = cJSON_GetArraySize(json);
for (int i = 0; i < numMacs; i++) {
const char *storedMac = cJSON_GetArrayItem(json, i)->valuestring;
if (strcmp(storedMac, macAddress) == 0) {
cJSON_DeleteItemFromArray(json, i);

esp_err_t err = save_mac_addresses_as_json(json);
cJSON_Delete(json);
return err;
}
}
cJSON_Delete(json);
return ESP_ERR_NOT_FOUND;
}

//-----------------------------------------------------------------------------
1 change: 1 addition & 0 deletions components/web_server/get_data_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ esp_err_t get_settings_data_handler(httpd_req_t *req)
cJSON_AddBoolToObject(root, "ledEnable", IsLedEnable);
cJSON_AddBoolToObject(root, "darkMode", IsDarkModeEnable);
cJSON_AddBoolToObject(root, "webServer", IsWebServerEnable);
cJSON_AddBoolToObject(root, "macFilterEnabled", IsMacFilterEnable);
cJSON_AddStringToObject(root, "authUsername", authUsername);
cJSON_AddStringToObject(root, "authPassword", authPass);
cJSON_AddNumberToObject(root, "maxLoginAttempts", max_login_attempts);
Expand Down
31 changes: 31 additions & 0 deletions components/web_server/storage_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "request_handler.h"
#include "initialization.h"
#include "utils.h"
#include "mac_filter.h"

static const char *TAG = "url_handler/get_data_handler";

Expand Down Expand Up @@ -185,6 +186,36 @@ esp_err_t save_settings_data_handler(httpd_req_t *req)
IsDarkModeEnable = str_to_bool(html_escape(strdup(param_buf)));
err = nvs_set_i32(handle, "dark_mode", bool_to_int(IsDarkModeEnable));
}
if (httpd_query_key_value(query_buf, "macFilterEnable", param_buf, sizeof(param_buf)) == ESP_OK)
{
IsMacFilterEnable = str_to_bool(html_escape(strdup(param_buf)));
err = nvs_set_i32(handle, "mac_Filter", bool_to_int(IsMacFilterEnable));
printf("Commit failed! (%s)\n", esp_err_to_name(err));

}
///////////////////
if (httpd_query_key_value(query_buf, "add_mac_address", param_buf, sizeof(param_buf)) == ESP_OK)
{
store_mac_address_in_nvs(html_escape(strdup(param_buf)));
refresh_mac_filter();

}

if (httpd_query_key_value(query_buf, "remove_mac_address", param_buf, sizeof(param_buf)) == ESP_OK)
{
remove_mac_address_from_nvs(html_escape(strdup(param_buf)));
refresh_mac_filter();
}

if (httpd_query_key_value(query_buf, "filter_list_type", param_buf, sizeof(param_buf)) == ESP_OK)
{
IsAllowList = word_check(html_escape(strdup(param_buf)),"Allow");
err = nvs_set_i32(handle, "Is_allow_list", bool_to_int(IsAllowList));
refresh_mac_filter();
}


/////////////////

valid_query = (err == ESP_OK);

Expand Down
1 change: 1 addition & 0 deletions components/web_server/www/html/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sass:


jekyll-minifier:
compress_javascript: false
exclude: "*.json"
uglifier_args:
harmony: true
Expand Down
Loading

0 comments on commit d82673d

Please sign in to comment.