[PATCH v2 13/13] ublox: check which auth methods are supported
Aleksander Morgado
aleksander at aleksander.es
Fri Sep 15 23:23:31 UTC 2017
On 14/09/17 22:01, Aleksander Morgado wrote:
> Don't assume the 'auto' auth method is supported for APN
> authentication, query the modem first:
>
> checking supported authentication methods...
> (ttyACM2): --> 'AT+UAUTHREQ=?<CR>'
> (ttyACM2): <-- '<CR><LF>+UAUTHREQ: (1-4),(0-2),,<CR><LF>'
> (ttyACM2): <-- '<CR><LF>OK<CR><LF>'
>
> Using automatic authentication method
>
> setting up authentication preferences in PDP context #2...
> (ttyACM2): --> 'AT+UAUTHREQ=2,1,"vodafone","vodafone"<CR>'
> (ttyACM2): <-- '<CR><LF>OK<CR><LF>'
> ---
Merged to git master.
> plugins/ublox/mm-broadband-bearer-ublox.c | 169 +++++++++++++++++++++++-------
> 1 file changed, 130 insertions(+), 39 deletions(-)
>
> diff --git a/plugins/ublox/mm-broadband-bearer-ublox.c b/plugins/ublox/mm-broadband-bearer-ublox.c
> index 866b2e7f..3cb17336 100644
> --- a/plugins/ublox/mm-broadband-bearer-ublox.c
> +++ b/plugins/ublox/mm-broadband-bearer-ublox.c
> @@ -51,9 +51,10 @@ typedef enum {
> } FeatureSupport;
>
> struct _MMBroadbandBearerUbloxPrivate {
> - MMUbloxUsbProfile profile;
> - MMUbloxNetworkingMode mode;
> - FeatureSupport statistics;
> + MMUbloxUsbProfile profile;
> + MMUbloxNetworkingMode mode;
> + MMUbloxBearerAllowedAuth allowed_auths;
> + FeatureSupport statistics;
> };
>
> /*****************************************************************************/
> @@ -393,59 +394,76 @@ uauthreq_ready (MMBaseModem *modem,
> static void
> authenticate_3gpp (GTask *task)
> {
> - const gchar *user;
> - const gchar *password;
> - MMBearerAllowedAuth allowed_auth;
> - CommonConnectContext *ctx;
> - gchar *cmd;
> + MMBroadbandBearerUblox *self;
> + CommonConnectContext *ctx;
> + gchar *cmd = NULL;
> + MMBearerAllowedAuth allowed_auth;
> + gint ublox_auth = -1;
>
> + self = g_task_get_source_object (task);
> ctx = (CommonConnectContext *) g_task_get_task_data (task);
>
> - user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> - password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
>
> - /* Flag whether authentication is required. If it isn't, we won't fail
> - * connection attempt if the +UAUTHREQ command fails */
> - ctx->auth_required = (user && password && allowed_auth != MM_BEARER_ALLOWED_AUTH_NONE);
> if (!ctx->auth_required) {
> mm_dbg ("Not using authentication");
> - cmd = g_strdup_printf ("+UAUTHREQ=%u,0", ctx->cid);
> - } else {
> - gchar *quoted_user;
> - gchar *quoted_password;
> - guint ublox_auth;
> + ublox_auth = 0;
> + goto out;
> + }
>
> - if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN || allowed_auth == (MM_BEARER_ALLOWED_AUTH_PAP | MM_BEARER_ALLOWED_AUTH_CHAP)) {
> - mm_dbg ("Using automatic authentication method");
> + if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN || allowed_auth == (MM_BEARER_ALLOWED_AUTH_PAP | MM_BEARER_ALLOWED_AUTH_CHAP)) {
> + mm_dbg ("Using automatic authentication method");
> + if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_AUTO)
> ublox_auth = 3;
> - } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
> - mm_dbg ("Using PAP authentication method");
> + else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_PAP)
> ublox_auth = 1;
> - } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
> - mm_dbg ("Using CHAP authentication method");
> + else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_CHAP)
> ublox_auth = 2;
> - } else {
> - gchar *str;
> + else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_NONE)
> + ublox_auth = 0;
> + } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
> + mm_dbg ("Using PAP authentication method");
> + ublox_auth = 1;
> + } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
> + mm_dbg ("Using CHAP authentication method");
> + ublox_auth = 2;
> + }
>
> - str = mm_bearer_allowed_auth_build_string_from_mask (allowed_auth);
> - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
> - "Cannot use any of the specified authentication methods (%s)", str);
> - g_object_unref (task);
> - g_free (str);
> - return;
> - }
> +out:
> +
> + if (ublox_auth < 0) {
> + gchar *str;
> +
> + str = mm_bearer_allowed_auth_build_string_from_mask (allowed_auth);
> + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
> + "Cannot use any of the specified authentication methods (%s)", str);
> + g_object_unref (task);
> + g_free (str);
> + return;
> + }
> +
> + if (ublox_auth > 0) {
> + const gchar *user;
> + const gchar *password;
> + gchar *quoted_user;
> + gchar *quoted_password;
>
> - quoted_user = mm_port_serial_at_quote_string (user);
> + user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> + password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> +
> + quoted_user = mm_port_serial_at_quote_string (user);
> quoted_password = mm_port_serial_at_quote_string (password);
> +
> cmd = g_strdup_printf ("+UAUTHREQ=%u,%u,%s,%s",
> ctx->cid,
> ublox_auth,
> quoted_password,
> quoted_user);
> +
> g_free (quoted_user);
> g_free (quoted_password);
> - }
> + } else
> + cmd = g_strdup_printf ("+UAUTHREQ=%u,0", ctx->cid);
>
> mm_dbg ("setting up authentication preferences in PDP context #%u...", ctx->cid);
> mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
> @@ -457,6 +475,78 @@ authenticate_3gpp (GTask *task)
> g_free (cmd);
> }
>
> +static void
> +uauthreq_test_ready (MMBaseModem *modem,
> + GAsyncResult *res,
> + GTask *task)
> +{
> + MMBroadbandBearerUblox *self;
> + const gchar *response;
> + GError *error = NULL;
> +
> + self = g_task_get_source_object (task);
> +
> + response = mm_base_modem_at_command_finish (modem, res, &error);
> + if (!response)
> + goto out;
> +
> + self->priv->allowed_auths = mm_ublox_parse_uauthreq_test (response, &error);
> +out:
> + if (error) {
> + CommonConnectContext *ctx;
> +
> + ctx = (CommonConnectContext *) g_task_get_task_data (task);
> + /* If authentication required and the +UAUTHREQ test failed, abort */
> + if (ctx->auth_required) {
> + g_task_return_error (task, error);
> + g_object_unref (task);
> + return;
> + }
> + /* Otherwise, ignore and jump to activate_3gpp directly as no auth setup
> + * is needed */
> + g_error_free (error);
> + activate_3gpp (task);
> + return;
> + }
> +
> + authenticate_3gpp (task);
> +}
> +
> +static void
> +check_supported_authentication_methods (GTask *task)
> +{
> + MMBroadbandBearerUblox *self;
> + CommonConnectContext *ctx;
> + const gchar *user;
> + const gchar *password;
> + MMBearerAllowedAuth allowed_auth;
> +
> + self = g_task_get_source_object (task);
> + ctx = (CommonConnectContext *) g_task_get_task_data (task);
> +
> + user = mm_bearer_properties_get_user (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> + password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> + allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
> +
> + /* Flag whether authentication is required. If it isn't, we won't fail
> + * connection attempt if the +UAUTHREQ command fails */
> + ctx->auth_required = (user && password && allowed_auth != MM_BEARER_ALLOWED_AUTH_NONE);
> +
> + /* If we already cached the support, not do it again */
> + if (self->priv->allowed_auths != MM_UBLOX_BEARER_ALLOWED_AUTH_UNKNOWN) {
> + authenticate_3gpp (task);
> + return;
> + }
> +
> + mm_dbg ("checking supported authentication methods...");
> + mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
> + "+UAUTHREQ=?",
> + 10,
> + TRUE, /* allow cached */
> + (GAsyncReadyCallback) uauthreq_test_ready,
> + task);
> +}
> +
> static void
> dial_3gpp (MMBroadbandBearer *self,
> MMBaseModem *modem,
> @@ -478,7 +568,7 @@ dial_3gpp (MMBroadbandBearer *self,
> user_data)))
> return;
>
> - authenticate_3gpp (task);
> + check_supported_authentication_methods (task);
> }
>
> /*****************************************************************************/
> @@ -785,9 +875,10 @@ mm_broadband_bearer_ublox_init (MMBroadbandBearerUblox *self)
> MMBroadbandBearerUbloxPrivate);
>
> /* Defaults */
> - self->priv->profile = MM_UBLOX_USB_PROFILE_UNKNOWN;
> - self->priv->mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN;
> - self->priv->statistics = FEATURE_SUPPORT_UNKNOWN;
> + self->priv->profile = MM_UBLOX_USB_PROFILE_UNKNOWN;
> + self->priv->mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN;
> + self->priv->allowed_auths = MM_UBLOX_BEARER_ALLOWED_AUTH_UNKNOWN;
> + self->priv->statistics = FEATURE_SUPPORT_UNKNOWN;
> }
>
> static void
> --
> 2.14.1
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list