Merge request !1464 from 'aleksander/vreports'
Sanitize user inputs https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/1464
This commit is contained in:
@@ -440,6 +440,13 @@ handle_deflect_auth_ready (MMAuthProvider *authp,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate input number */
|
||||
if (!mm_utils_is_valid_dial_number (ctx->number, &error)) {
|
||||
mm_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_deflect_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
state = mm_gdbus_call_get_state (MM_GDBUS_CALL (ctx->self));
|
||||
|
||||
/* We can only deflect incoming call in ringing or waiting state */
|
||||
|
||||
+61
-1
@@ -261,6 +261,13 @@ handle_change_pin_auth_ready (MMAuthProvider *authp,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mm_utils_is_numeric (ctx->old_pin) || !mm_utils_is_numeric (ctx->new_pin)) {
|
||||
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"PIN must be numeric");
|
||||
handle_change_pin_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If changing PIN is not implemented, report an error */
|
||||
if (!MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin ||
|
||||
!MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin_finish) {
|
||||
@@ -445,6 +452,13 @@ handle_enable_pin_auth_ready (MMAuthProvider *authp,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mm_utils_is_numeric (ctx->pin)) {
|
||||
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"PIN must be numeric");
|
||||
handle_enable_pin_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If changing PIN is not implemented, report an error */
|
||||
if (!MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin ||
|
||||
!MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin_finish) {
|
||||
@@ -869,6 +883,13 @@ handle_send_pin_auth_ready (MMAuthProvider *authp,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mm_utils_is_numeric (ctx->pin)) {
|
||||
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"PIN must be numeric");
|
||||
handle_send_pin_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mm_gdbus_sim_get_active (MM_GDBUS_SIM (ctx->self))) {
|
||||
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
|
||||
"Cannot send PIN: SIM not currently active");
|
||||
@@ -974,6 +995,13 @@ handle_send_puk_auth_ready (MMAuthProvider *authp,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mm_utils_is_numeric (ctx->puk) || !mm_utils_is_numeric (ctx->new_pin)) {
|
||||
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"PIN/PUK must be numeric");
|
||||
handle_send_puk_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mm_gdbus_sim_get_active (MM_GDBUS_SIM (ctx->self))) {
|
||||
mm_dbus_method_invocation_return_error_literal (ctx->invocation, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
|
||||
"Cannot send PUK: SIM not currently active");
|
||||
@@ -1518,12 +1546,34 @@ handle_set_preferred_networks_ready (MMBaseSim *self,
|
||||
handle_set_preferred_networks_context_free (ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_networks_list (GList *networks_list,
|
||||
GError **error)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = networks_list; l; l = g_list_next (l)) {
|
||||
MMSimPreferredNetwork *network = (MMSimPreferredNetwork *)l->data;
|
||||
const gchar *operator_code;
|
||||
|
||||
operator_code = mm_sim_preferred_network_get_operator_code (network);
|
||||
if (!mm_utils_is_numeric (operator_code)) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Invalid operator code: '%s'", operator_code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_set_preferred_networks_auth_ready (MMAuthProvider *authp,
|
||||
GAsyncResult *res,
|
||||
HandleSetPreferredNetworksContext *ctx)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GList *networks_list = NULL;
|
||||
|
||||
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
|
||||
mm_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
@@ -1553,12 +1603,22 @@ handle_set_preferred_networks_auth_ready (MMAuthProvider *authp,
|
||||
return;
|
||||
}
|
||||
|
||||
networks_list = mm_sim_preferred_network_list_new_from_variant (ctx->networks);
|
||||
if (!validate_networks_list (networks_list, &error)) {
|
||||
g_list_free_full (networks_list, g_object_unref);
|
||||
mm_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_set_preferred_networks_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
mm_obj_info (ctx->self, "processing user request to set preferred networks...");
|
||||
MM_BASE_SIM_GET_CLASS (ctx->self)->set_preferred_networks (
|
||||
ctx->self,
|
||||
mm_sim_preferred_network_list_new_from_variant (ctx->networks),
|
||||
networks_list,
|
||||
(GAsyncReadyCallback)handle_set_preferred_networks_ready,
|
||||
ctx);
|
||||
|
||||
g_list_free_full (networks_list, g_object_unref);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -6419,6 +6419,7 @@ modem_3gpp_ussd_context_send_unencoded (MMBroadbandModem *self)
|
||||
{
|
||||
Modem3gppUssdSendContext *ctx;
|
||||
gchar *at_command = NULL;
|
||||
gchar *quoted_command;
|
||||
|
||||
g_assert (self->priv->pending_ussd_action);
|
||||
ctx = g_task_get_task_data (self->priv->pending_ussd_action);
|
||||
@@ -6426,9 +6427,11 @@ modem_3gpp_ussd_context_send_unencoded (MMBroadbandModem *self)
|
||||
/* Build AT command with action unencoded */
|
||||
ctx->unencoded_used = TRUE;
|
||||
ctx->current_is_unencoded = TRUE;
|
||||
at_command = g_strdup_printf ("+CUSD=1,\"%s\",%d",
|
||||
ctx->command,
|
||||
MM_MODEM_GSM_USSD_SCHEME_7BIT);
|
||||
quoted_command = mm_at_quote_string (ctx->command);
|
||||
at_command = g_strdup_printf ("+CUSD=1,%s,%d",
|
||||
quoted_command,
|
||||
MM_MODEM_GSM_USSD_SCHEME_7BIT);
|
||||
g_free (quoted_command);
|
||||
|
||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||
at_command,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "mm-call-list.h"
|
||||
#include "mm-error-helpers.h"
|
||||
#include "mm-log-object.h"
|
||||
#include "mm-modem-helpers.h"
|
||||
|
||||
#define CALL_LIST_POLLING_CONTEXT_TAG "voice-call-list-polling-context-tag"
|
||||
#define IN_CALL_EVENT_CONTEXT_TAG "voice-in-call-event-context-tag"
|
||||
@@ -176,14 +177,9 @@ create_outgoing_call_from_properties (MMIfaceModemVoice *self,
|
||||
guint dtmf_tone_duration;
|
||||
|
||||
/* Don't create CALL from properties if either number is missing */
|
||||
number = mm_call_properties_get_number (properties) ;
|
||||
if (!number) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Cannot create call: mandatory parameter 'number' is missing");
|
||||
number = mm_call_properties_get_number (properties);
|
||||
if (!mm_utils_is_valid_dial_number (number, error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dtmf_tone_duration = mm_call_properties_get_dtmf_tone_duration (properties) ;
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -5936,3 +5941,76 @@ mm_dtmf_split (const gchar *dtmf)
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
mm_utils_remove_control_characters (gchar *str)
|
||||
{
|
||||
gchar *src = str;
|
||||
gchar *dst = str;
|
||||
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
while (*src) {
|
||||
if (((guint8)*src) >= 0x20) {
|
||||
*dst = *src;
|
||||
dst++;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
*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;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_utils_is_numeric (const gchar *str)
|
||||
{
|
||||
const gchar *c;
|
||||
|
||||
if (!str || !str[0])
|
||||
return FALSE;
|
||||
|
||||
for (c = str; *c; c++) {
|
||||
if (!g_ascii_isdigit (*c))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_utils_is_valid_dial_number (const gchar *str,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *c;
|
||||
|
||||
if (!str || !str[0]) {
|
||||
g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"missing number");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (c = str; *c; c++) {
|
||||
if (((guint8)*c) < 0x20 || *c == ';') {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
|
||||
"invalid character '0x%02x' in number", (guint8)*c);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -571,6 +571,12 @@ gboolean mm_parse_supl_address (const gchar *supl,
|
||||
guint16 *out_port,
|
||||
GError **error);
|
||||
|
||||
void mm_utils_remove_control_characters (gchar *str);
|
||||
gboolean mm_utils_is_valid_fqdn (const gchar *fqdn);
|
||||
gboolean mm_utils_is_numeric (const gchar *str);
|
||||
gboolean mm_utils_is_valid_dial_number (const gchar *str,
|
||||
GError **error);
|
||||
|
||||
gboolean mm_validate_cbs_channels (GArray *channels,
|
||||
GError **error);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "mm-sms-part-3gpp.h"
|
||||
#include "mm-charsets.h"
|
||||
#include "mm-log.h"
|
||||
#include "mm-modem-helpers.h"
|
||||
|
||||
#define PDU_SIZE 200
|
||||
|
||||
@@ -141,6 +142,8 @@ sms_decode_address (const guint8 *address,
|
||||
unpacked = mm_charset_gsm_unpack (address, (len_digits * 4) / 7, 0, &unpacked_len);
|
||||
unpacked_array = g_byte_array_new_take (unpacked, unpacked_len);
|
||||
utf8 = mm_modem_charset_bytearray_to_utf8 (unpacked_array, MM_MODEM_CHARSET_GSM, FALSE, error);
|
||||
if (utf8)
|
||||
mm_utils_remove_control_characters (utf8);
|
||||
} else if (addrtype == SMS_NUMBER_TYPE_INTL &&
|
||||
addrplan == SMS_NUMBER_PLAN_TELEPHONE) {
|
||||
/* International telphone number, format as "+1234567890" */
|
||||
|
||||
@@ -4872,6 +4872,114 @@ test_at_quote_string (void *f, gpointer d)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_remove_control_characters (void *f, gpointer d)
|
||||
{
|
||||
gchar str1[] = "hello\r\nworld";
|
||||
gchar str2[] = "no_controls";
|
||||
gchar str3[] = "\r\n\t";
|
||||
|
||||
mm_utils_remove_control_characters (str1);
|
||||
g_assert_cmpstr (str1, ==, "helloworld");
|
||||
|
||||
mm_utils_remove_control_characters (str2);
|
||||
g_assert_cmpstr (str2, ==, "no_controls");
|
||||
|
||||
mm_utils_remove_control_characters (str3);
|
||||
g_assert_cmpstr (str3, ==, "");
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
static void
|
||||
test_is_numeric (void *f, gpointer d)
|
||||
{
|
||||
g_assert (mm_utils_is_numeric ("123456"));
|
||||
g_assert (mm_utils_is_numeric ("0"));
|
||||
g_assert (mm_utils_is_numeric ("0123456789"));
|
||||
|
||||
g_assert (!mm_utils_is_numeric (NULL));
|
||||
g_assert (!mm_utils_is_numeric (""));
|
||||
g_assert (!mm_utils_is_numeric ("123a45"));
|
||||
g_assert (!mm_utils_is_numeric ("123 45"));
|
||||
g_assert (!mm_utils_is_numeric ("123\r45"));
|
||||
g_assert (!mm_utils_is_numeric ("+123"));
|
||||
}
|
||||
|
||||
static void
|
||||
test_is_valid_dial_number (void *f, gpointer d)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean r;
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123456", &error);
|
||||
g_assert (r);
|
||||
g_assert_no_error (error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("+123456", &error);
|
||||
g_assert (r);
|
||||
g_assert_no_error (error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("*123#", &error);
|
||||
g_assert (r);
|
||||
g_assert_no_error (error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123,456", &error);
|
||||
g_assert (r);
|
||||
g_assert_no_error (error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123W456", &error);
|
||||
g_assert (r);
|
||||
g_assert_no_error (error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number (NULL, &error);
|
||||
g_assert (!r);
|
||||
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
||||
g_clear_error (&error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("", &error);
|
||||
g_assert (!r);
|
||||
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
||||
g_clear_error (&error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123;456", &error);
|
||||
g_assert (!r);
|
||||
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
||||
g_clear_error (&error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123\r456", &error);
|
||||
g_assert (!r);
|
||||
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
||||
g_clear_error (&error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123\n456", &error);
|
||||
g_assert (!r);
|
||||
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
||||
g_clear_error (&error);
|
||||
|
||||
r = mm_utils_is_valid_dial_number ("123\x01" "456", &error);
|
||||
g_assert (!r);
|
||||
g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
@@ -5418,6 +5526,10 @@ int main (int argc, char **argv)
|
||||
g_test_suite_add (suite, TESTCASE (test_bcd_to_string, NULL));
|
||||
|
||||
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_is_numeric, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_is_valid_dial_number, NULL));
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user