From 6574947a80f4ff5b869f513d5cb204e7ee1b7dc7 Mon Sep 17 00:00:00 2001 From: Marcel Peterkau Date: Sun, 2 Jun 2024 23:35:20 +0200 Subject: [PATCH] hardened WiFi-String stuff --- Software/include/eeprom.h | 1 - Software/include/globals.h | 2 +- Software/include/utilities.h | 36 ++++++++++++++ Software/src/eeprom.cpp | 43 +---------------- Software/src/main.cpp | 5 +- Software/src/utilities.cpp | 94 ++++++++++++++++++++++++++++++++++++ 6 files changed, 136 insertions(+), 45 deletions(-) create mode 100644 Software/include/utilities.h create mode 100644 Software/src/utilities.cpp diff --git a/Software/include/eeprom.h b/Software/include/eeprom.h index b7bb008..8e5b0de 100644 --- a/Software/include/eeprom.h +++ b/Software/include/eeprom.h @@ -102,7 +102,6 @@ uint32_t Checksum_EEPROM(uint8_t const *data, size_t len); void dumpEEPROM(uint16_t memoryAddress, uint16_t length); void MovePersistencePage_EEPROM(boolean reset); uint32_t ConfigSanityCheck(bool autocorrect = false); -bool validateWiFiString(char *string, size_t size); void writeSequentialToEEPROM(uint16_t memoryAddress, uint16_t length); void writeZeroToEEPROM(uint16_t memoryAddress, uint16_t length); diff --git a/Software/include/globals.h b/Software/include/globals.h index 3e16928..6abf70a 100644 --- a/Software/include/globals.h +++ b/Software/include/globals.h @@ -10,7 +10,7 @@ typedef struct Globals_s tSystem_Status resumeStatus = sysStat_Startup; /**< Status to resume after rain mode */ char systemStatustxt[16] = ""; /**< Text representation of system status */ EERequest_t requestEEAction = EE_IDLE; /**< EEPROM-related request */ - char DeviceName[33]; /**< Device name */ + char DeviceName[25]; /**< Device name */ char DeviceNameId[sizeof(DeviceName) + 8]; /**< Device name plus 8 chars chipID */ char FlashVersion[10]; /**< Flash version */ uint16_t eePersistanceAdress; /**< EEPROM persistence address */ diff --git a/Software/include/utilities.h b/Software/include/utilities.h new file mode 100644 index 0000000..1c74318 --- /dev/null +++ b/Software/include/utilities.h @@ -0,0 +1,36 @@ +#ifndef UTILITIES_H +#define UTILITIES_H + +#include + +/** + * @brief Validates whether a given string contains only characters allowed in WiFi SSIDs and passwords. + * + * This function checks each character in the provided string to ensure + * that it contains only characters allowed in WiFi SSIDs and passwords. + * It considers characters from 'A' to 'Z', 'a' to 'z', '0' to '9', as well as + * the following special characters: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + * + * @param string Pointer to the string to be validated. + * @param size Size of the string including the null-terminator. + * @return true if the string contains only allowed characters or is NULL, + * false otherwise. + */ +bool validateWiFiString(char *string, size_t size); + +/** + * @brief Copies a string to a buffer, replacing invalid WiFi SSID characters with a placeholder. + * + * This function checks each character in the provided input string to ensure + * that it contains only characters allowed in WiFi SSIDs and passwords. If a character + * is invalid, it replaces it with a placeholder character (e.g., '_'). + * It considers characters from 'A' to 'Z', 'a' to 'z', '0' to '9', as well as + * the following special characters: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + * + * @param input Pointer to the input string to be validated and copied. + * @param buffer Pointer to the buffer where the output string will be copied. + * @param bufferSize Size of the buffer including the null-terminator. + */ +void sanitizeWiFiString(const char *input, char *buffer, size_t bufferSize); + +#endif // UTILITIES_H diff --git a/Software/src/eeprom.cpp b/Software/src/eeprom.cpp index 0104f7e..ce156ea 100644 --- a/Software/src/eeprom.cpp +++ b/Software/src/eeprom.cpp @@ -9,6 +9,7 @@ #include "eeprom.h" #include "debugger.h" #include "globals.h" +#include "utilities.h" // Instance of I2C_eeprom for EEPROM access I2C_eeprom ee(I2C_EE_ADDRESS, EEPROM_SIZE_BYTES); @@ -430,48 +431,6 @@ uint32_t ConfigSanityCheck(bool autocorrect) return setting_reset_bits; } -/** - * @brief Validates whether a given string contains only characters allowed in WiFi SSIDs and passwords. - * - * This function checks each character in the provided string to ensure - * that it contains only characters allowed in WiFi SSIDs and passwords. - * It considers characters from 'A' to 'Z', 'a' to 'z', '0' to '9', as well as - * the following special characters: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ - * - * @param string Pointer to the string to be validated. - * @param size Size of the string including the null-terminator. - * @return true if the string contains only allowed characters or is NULL, - * false otherwise. - */ -bool validateWiFiString(char *string, size_t size) -{ - if (string == NULL) - return false; - - for (size_t i = 0; i < size; i++) - { - char c = string[i]; - if (c == '\0') - { - // Reached the end of the string, all characters were valid WiFi characters. - return true; - } - if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || c == '!' || c == '"' || c == '#' || - c == '$' || c == '%' || c == '&' || c == '\'' || c == '(' || - c == ')' || c == '*' || c == '+' || c == ',' || c == '-' || - c == '.' || c == '/' || c == ':' || c == ';' || c == '<' || - c == '=' || c == '>' || c == '?' || c == '@' || c == '[' || - c == '\\' || c == ']' || c == '^' || c == '_' || c == '`' || - c == '{' || c == '|' || c == '}' || c == '~')) - { - // Found a character that is not a valid WiFi character. - return false; - } - } - // If the loop completes without finding a null terminator, the string is invalid. - return false; -} /** * @brief Write sequential numbers to a portion of EEPROM. diff --git a/Software/src/main.cpp b/Software/src/main.cpp index 95ccb50..e9ebf2d 100644 --- a/Software/src/main.cpp +++ b/Software/src/main.cpp @@ -19,6 +19,7 @@ #include "globals.h" #include "dtc.h" #include "debugger.h" +#include "utilities.h" #if defined(FEATURE_ENABLE_LORA) || defined(FEATURE_ENABLE_UARTLORA) #include "lora_net.h" #endif @@ -571,6 +572,7 @@ void wifiMaintainConnectionTicker_callback() */ void toggleWiFiAP(bool shutdown) { + char buffer[33]; // Check if WiFi is currently active if (WiFi.getMode() != WIFI_OFF) { @@ -588,7 +590,8 @@ void toggleWiFiAP(bool shutdown) // Start WiFi in Access Point (AP) mode WiFi.mode(WIFI_AP); WiFi.softAPConfig(IPAddress(WIFI_AP_IP_GW), IPAddress(WIFI_AP_IP_GW), IPAddress(255, 255, 255, 0)); - WiFi.softAP(globals.DeviceNameId, QUOTE(WIFI_AP_PASSWORD)); + sanitizeWiFiString(globals.DeviceNameId, buffer, sizeof(buffer)); + WiFi.softAP(buffer, QUOTE(WIFI_AP_PASSWORD)); // Stop WiFi maintenance connection ticker if enabled and display debug messages #ifdef FEATURE_ENABLE_WIFI_CLIENT diff --git a/Software/src/utilities.cpp b/Software/src/utilities.cpp new file mode 100644 index 0000000..5a31703 --- /dev/null +++ b/Software/src/utilities.cpp @@ -0,0 +1,94 @@ +#include "utilities.h" + +/** + * @brief Validates whether a given string contains only characters allowed in WiFi SSIDs and passwords. + * + * This function checks each character in the provided string to ensure + * that it contains only characters allowed in WiFi SSIDs and passwords. + * It considers characters from 'A' to 'Z', 'a' to 'z', '0' to '9', as well as + * the following special characters: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + * + * @param string Pointer to the string to be validated. + * @param size Size of the string including the null-terminator. + * @return true if the string contains only allowed characters or is NULL, + * false otherwise. + */ +bool validateWiFiString(char *string, size_t size) +{ + if (string == NULL) + return false; + + for (size_t i = 0; i < size; i++) + { + char c = string[i]; + if (c == '\0') + { + // Reached the end of the string, all characters were valid WiFi characters. + return true; + } + if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || c == '!' || c == '"' || c == '#' || + c == '$' || c == '%' || c == '&' || c == '\'' || c == '(' || + c == ')' || c == '*' || c == '+' || c == ',' || c == '-' || + c == '.' || c == '/' || c == ':' || c == ';' || c == '<' || + c == '=' || c == '>' || c == '?' || c == '@' || c == '[' || + c == '\\' || c == ']' || c == '^' || c == '_' || c == '`' || + c == '{' || c == '|' || c == '}' || c == '~')) + { + // Found a character that is not a valid WiFi character. + return false; + } + } + // If the loop completes without finding a null terminator, the string is invalid. + return false; +} + +/** + * @brief Copies a string to a buffer, replacing invalid WiFi SSID characters with a placeholder. + * + * This function checks each character in the provided input string to ensure + * that it contains only characters allowed in WiFi SSIDs and passwords. If a character + * is invalid, it replaces it with a placeholder character (e.g., '_'). + * It considers characters from 'A' to 'Z', 'a' to 'z', '0' to '9', as well as + * the following special characters: ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + * + * @param input Pointer to the input string to be validated and copied. + * @param buffer Pointer to the buffer where the output string will be copied. + * @param bufferSize Size of the buffer including the null-terminator. + */ +void sanitizeWiFiString(const char *input, char *buffer, size_t bufferSize) +{ + if (input == NULL || buffer == NULL || bufferSize == 0) + return; + + size_t i; + for (i = 0; i < bufferSize - 1; i++) // Leave space for null-terminator + { + char c = input[i]; + if (c == '\0') + { + // Reached the end of the input string, terminate the buffer + buffer[i] = '\0'; + return; + } + if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || c == '!' || c == '"' || c == '#' || + c == '$' || c == '%' || c == '&' || c == '\'' || c == '(' || + c == ')' || c == '*' || c == '+' || c == ',' || c == '-' || + c == '.' || c == '/' || c == ':' || c == ';' || c == '<' || + c == '=' || c == '>' || c == '?' || c == '@' || c == '[' || + c == '\\' || c == ']' || c == '^' || c == '_' || c == '`' || + c == '{' || c == '|' || c == '}' || c == '~')) + { + // Replace invalid character with placeholder + buffer[i] = '_'; + } + else + { + // Copy valid character to buffer + buffer[i] = c; + } + } + // Null-terminate the buffer + buffer[i] = '\0'; +}