location: validate SUPL host as FQDN or IP
When parsing a SUPL address, if the host is not a valid IPv4 address, validate it as a FQDN (allowing only alphanumeric characters, dots, and hyphens). This prevents injecting AT command delimiters (like CR or semicolon) into the host string, which is later spliced into modem-specific AT commands (+XLCSSLP). Introduce a common helper mm_utils_is_valid_fqdn() to validate FQDNs, and add unit tests for it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1063 Signed-off-by: Aleksander Morgado <aleksandermj@google.com>
This commit is contained in:
committed by
Aleksander Morgado
parent
1ee3a443b1
commit
a39d46c637
@@ -5554,6 +5554,11 @@ mm_parse_supl_address (const gchar *supl,
|
||||
/* Try to parse first item as IP */
|
||||
if (inet_pton (AF_INET, split[0], &ip) <= 0) {
|
||||
/* Otherwise, assume it's a domain name */
|
||||
if (!mm_utils_is_valid_fqdn (split[0])) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Invalid SUPL host: not a valid FQDN or IP: %s", split[0]);
|
||||
goto out;
|
||||
}
|
||||
if (out_fqdn)
|
||||
*out_fqdn = g_strdup (split[0]);
|
||||
if (out_ip)
|
||||
@@ -5957,3 +5962,18 @@ mm_utils_remove_control_characters (gchar *str)
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_utils_is_valid_fqdn (const gchar *fqdn)
|
||||
{
|
||||
const gchar *c;
|
||||
|
||||
if (!fqdn || !fqdn[0])
|
||||
return FALSE;
|
||||
|
||||
for (c = fqdn; *c; c++) {
|
||||
if (!g_ascii_isalnum (*c) && *c != '-' && *c != '.')
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -572,6 +572,7 @@ gboolean mm_parse_supl_address (const gchar *supl,
|
||||
GError **error);
|
||||
|
||||
void mm_utils_remove_control_characters (gchar *str);
|
||||
gboolean mm_utils_is_valid_fqdn (const gchar *fqdn);
|
||||
|
||||
gboolean mm_validate_cbs_channels (GArray *channels,
|
||||
GError **error);
|
||||
|
||||
@@ -4891,6 +4891,23 @@ test_remove_control_characters (void *f, gpointer d)
|
||||
mm_utils_remove_control_characters (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_is_valid_fqdn (void *f, gpointer d)
|
||||
{
|
||||
g_assert (mm_utils_is_valid_fqdn ("google.com"));
|
||||
g_assert (mm_utils_is_valid_fqdn ("a.b.c.d"));
|
||||
g_assert (mm_utils_is_valid_fqdn ("valid-host.com"));
|
||||
g_assert (mm_utils_is_valid_fqdn ("123.com"));
|
||||
g_assert (mm_utils_is_valid_fqdn ("a"));
|
||||
|
||||
g_assert (!mm_utils_is_valid_fqdn (NULL));
|
||||
g_assert (!mm_utils_is_valid_fqdn (""));
|
||||
g_assert (!mm_utils_is_valid_fqdn ("invalid host.com"));
|
||||
g_assert (!mm_utils_is_valid_fqdn ("host;com"));
|
||||
g_assert (!mm_utils_is_valid_fqdn ("host\rcom"));
|
||||
g_assert (!mm_utils_is_valid_fqdn ("host/com"));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
@@ -5438,6 +5455,7 @@ int main (int argc, char **argv)
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_at_quote_string, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_is_valid_fqdn, NULL));
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user