Ensure the MQTT address is an IPv4 before determining it's private (#5081)

* Ensure the mqtt address is an IPv4 (or at least not a domain) before determining it's private.

* check address length
This commit is contained in:
Johnathon Mohr 2024-10-16 03:19:00 -07:00 committed by GitHub
parent ad214ea42a
commit 3e5f129fce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 7 deletions

View File

@ -704,26 +704,40 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
(json.find("payload") != json.end()); // should have a payload
}
bool MQTT::isPrivateIpAddress(const char ip[])
bool MQTT::isPrivateIpAddress(const char address[])
{
// Min. length like 10.0.0.0, max like 192.168.255.255
size_t length = strlen(address);
if (length < 8 || length > 15) {
return false;
}
// Ensure the address contains only digits and dots.
// Even if it's not a valid IP address, we will know it's not a domain.
for (int i = 0; i < length; i++) {
if (!isdigit(address[i]) && address[i] != '.') {
return false;
}
}
// Check the easy ones first.
if (strcmp(ip, "127.0.0.1") == 0 || strncmp(ip, "10.", 3) == 0 || strncmp(ip, "192.168", 7) == 0) {
if (strcmp(address, "127.0.0.1") == 0 || strncmp(address, "10.", 3) == 0 || strncmp(address, "192.168", 7) == 0) {
return true;
}
// See if it's definitely not a 172 address.
if (strncmp(ip, "172", 3) != 0) {
if (strncmp(address, "172", 3) != 0) {
return false;
}
// We know it's a 172 address, now see if the second octet is 2 digits.
if (ip[6] != '.') {
if (address[6] != '.') {
return false;
}
// Copy the second octet into a secondary buffer we can null-terminate and parse.
char octet2[3];
strncpy(octet2, ip + 4, 2);
strncpy(octet2, address + 4, 2);
octet2[2] = 0;
int octet2Num = atoi(octet2);

View File

@ -120,9 +120,9 @@ class MQTT : private concurrency::OSThread
// returns true if this is a valid JSON envelope which we accept on downlink
bool isValidJsonEnvelope(JSONObject &json);
/// Determines if the given IP address is a private address, i.e. not routable on the public internet.
/// Determines if the given address is a private IPv4 address, i.e. not routable on the public internet.
/// These are the ranges: 127.0.0.1, 10.0.0.0-10.255.255.255, 172.16.0.0-172.31.255.255, 192.168.0.0-192.168.255.255.
bool isPrivateIpAddress(const char ip[]);
bool isPrivateIpAddress(const char address[]);
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }