diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-08-14 15:36:44 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2018-09-12 17:14:36 +0000 |
commit | 6e84f3d45934e4f1e334c4bfd0d9a43d88889039 (patch) | |
tree | 31acc1e5dec441b3cda6fd35a4739bf5a942dff6 | |
parent | 47ed19d5be68f139d4fbb00c997cd2805488ace7 (diff) | |
download | ModemManager-6e84f3d45934e4f1e334c4bfd0d9a43d88889039.tar.gz |
iface-modem-location: validate SUPL server address
Devices will expect SUPL server given as either IP:PORT or FQDN:PORT,
so just avoid saying we require a 'URL' because it's not true.
We will use a new helper method to parse and validate user-provided
SUPL server address.
-rw-r--r-- | cli/mmcli-modem-location.c | 2 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Modem.Location.xml | 4 | ||||
-rw-r--r-- | src/mm-iface-modem-location.c | 8 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 58 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 6 | ||||
-rw-r--r-- | src/mm-shared-qmi.c | 40 |
6 files changed, 80 insertions, 38 deletions
diff --git a/cli/mmcli-modem-location.c b/cli/mmcli-modem-location.c index 997e1a84a..f96a521df 100644 --- a/cli/mmcli-modem-location.c +++ b/cli/mmcli-modem-location.c @@ -145,7 +145,7 @@ static GOptionEntry entries[] = { }, { "location-set-supl-server", 0, 0, G_OPTION_ARG_STRING, &set_supl_server_str, "Set SUPL server address", - "[IP:PORT] or [URL]" + "[IP:PORT] or [FQDN:PORT]" }, { "location-inject-assistance-data", 0, 0, G_OPTION_ARG_FILENAME, &inject_assistance_data_str, "Inject assistance data in the GNSS module", diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml index 7c490c6ae..e36f8e0fe 100644 --- a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml +++ b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml @@ -71,7 +71,7 @@ <!-- SetSuplServer: - @supl: SUPL server configuration, given either as IP:PORT or with a full URL. + @supl: SUPL server configuration, given either as IP:PORT or as FQDN:PORT. Configure the SUPL server for A-GPS. --> @@ -334,7 +334,7 @@ <!-- SuplServer: - SUPL server configuration for A-GPS, given either as IP:PORT or with a full URL. + SUPL server configuration for A-GPS, given either as IP:PORT or FQDN:PORT. --> <property name="SuplServer" type="s" access="read" /> diff --git a/src/mm-iface-modem-location.c b/src/mm-iface-modem-location.c index e5aaa43d2..88fd2bf82 100644 --- a/src/mm-iface-modem-location.c +++ b/src/mm-iface-modem-location.c @@ -21,6 +21,7 @@ #include "mm-iface-modem.h" #include "mm-iface-modem-location.h" #include "mm-log.h" +#include "mm-modem-helpers.h" #define MM_LOCATION_GPS_REFRESH_TIME_SECS 30 @@ -992,6 +993,13 @@ handle_set_supl_server_auth_ready (MMBaseModem *self, return; } + /* Validate SUPL address string: either FQDN:PORT or IP:PORT */ + if (!mm_parse_supl_address (ctx->supl, NULL, NULL, NULL, &error)) { + g_dbus_method_invocation_return_gerror (ctx->invocation, error); + handle_set_supl_server_context_free (ctx); + return; + } + /* Check if plugin implements it */ if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->set_supl_server || !MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->set_supl_server_finish) { diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index c25867120..f7ee0f627 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -4372,3 +4372,61 @@ out: g_assert (retries >= 0); return retries; } + +/*****************************************************************************/ + +gboolean +mm_parse_supl_address (const gchar *supl, + gchar **out_fqdn, + guint32 *out_ip, + guint16 *out_port, + GError **error) +{ + gboolean valid = FALSE; + gchar **split; + guint port; + guint32 ip; + + split = g_strsplit (supl, ":", -1); + if (g_strv_length (split) != 2) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "Invalid SUPL address format: expected FQDN:PORT or IP:PORT"); + goto out; + } + + if (!mm_get_uint_from_str (split[1], &port)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "Invalid SUPL port number specified: not a number: %s", split[1]); + goto out; + } + + if (port == 0 || port > G_MAXUINT16) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "Invalid SUPL port number specified: out of range: %u", port); + goto out; + } + + /* Port is valid */ + if (out_port) + *out_port = (guint16) port; + + /* Try to parse first item as IP */ + if (inet_pton (AF_INET, split[0], &ip) <= 0) { + /* Otherwise, assume it's a domain name */ + if (out_fqdn) + *out_fqdn = g_strdup (split[0]); + if (out_ip) + *out_ip = 0; + } else { + if (out_ip) + *out_ip = ip; + if (out_fqdn) + *out_fqdn = NULL; + } + + valid = TRUE; + +out: + g_strfreev (split); + return valid; +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 54dcce731..a7c7eaca8 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -404,4 +404,10 @@ gboolean mm_parse_cclk_response (const gchar *response, gint mm_parse_csim_response (const gchar *response, GError **error); +gboolean mm_parse_supl_address (const gchar *supl, + gchar **out_fqdn, + guint32 *out_ip, + guint16 *out_port, + GError **error); + #endif /* MM_MODEM_HELPERS_H */ diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c index dd08d7fd5..5c91aefee 100644 --- a/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c @@ -113,36 +113,6 @@ set_supl_server_context_free (SetSuplServerContext *ctx) g_slice_free (SetSuplServerContext, ctx); } -static gboolean -parse_as_ip_port (const gchar *supl, - guint32 *out_ip, - guint32 *out_port) -{ - gboolean valid = FALSE; - gchar **split; - guint port; - guint32 ip; - - split = g_strsplit (supl, ":", -1); - if (g_strv_length (split) != 2) - goto out; - - if (!mm_get_uint_from_str (split[1], &port)) - goto out; - if (port == 0 || port > G_MAXUINT16) - goto out; - if (inet_pton (AF_INET, split[0], &ip) <= 0) - goto out; - - *out_ip = ip; - *out_port = port; - valid = TRUE; - -out: - g_strfreev (split); - return valid; -} - static GArray * parse_as_utf16_url (const gchar *supl) { @@ -197,7 +167,7 @@ pds_set_supl_server (GTask *task) SetSuplServerContext *ctx; QmiMessagePdsSetAgpsConfigInput *input; guint32 ip; - guint32 port; + guint16 port; GArray *url; self = g_task_get_source_object (task); @@ -211,7 +181,7 @@ pds_set_supl_server (GTask *task) else if (mm_iface_modem_is_cdma (MM_IFACE_MODEM (self))) qmi_message_pds_set_agps_config_input_set_network_mode (input, QMI_PDS_NETWORK_MODE_CDMA, NULL); - if (parse_as_ip_port (ctx->supl, &ip, &port)) + if (mm_parse_supl_address (ctx->supl, NULL, &ip, &port, NULL)) qmi_message_pds_set_agps_config_input_set_location_server_address (input, ip, port, NULL); else { url = parse_as_utf16_url (ctx->supl); @@ -312,7 +282,7 @@ loc_set_supl_server (GTask *task) SetSuplServerContext *ctx; QmiMessageLocSetServerInput *input; guint32 ip; - guint32 port; + guint16 port; self = g_task_get_source_object (task); ctx = g_task_get_task_data (task); @@ -325,8 +295,8 @@ loc_set_supl_server (GTask *task) else if (mm_iface_modem_is_cdma (MM_IFACE_MODEM (self))) qmi_message_loc_set_server_input_set_server_type (input, QMI_LOC_SERVER_TYPE_CDMA_PDE, NULL); - if (parse_as_ip_port (ctx->supl, &ip, &port)) - qmi_message_loc_set_server_input_set_ipv4 (input, ip, port, NULL); + if (mm_parse_supl_address (ctx->supl, NULL, &ip, &port, NULL)) + qmi_message_loc_set_server_input_set_ipv4 (input, ip, (guint32) port, NULL); else qmi_message_loc_set_server_input_set_url (input, ctx->supl, NULL); |