ublox: check which auth methods are supported

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>'
This commit is contained in:
Aleksander Morgado
2017-09-14 21:24:15 -07:00
parent b774e58dd0
commit 3bfbb59beb

View File

@@ -51,9 +51,10 @@ typedef enum {
} FeatureSupport; } FeatureSupport;
struct _MMBroadbandBearerUbloxPrivate { struct _MMBroadbandBearerUbloxPrivate {
MMUbloxUsbProfile profile; MMUbloxUsbProfile profile;
MMUbloxNetworkingMode mode; MMUbloxNetworkingMode mode;
FeatureSupport statistics; MMUbloxBearerAllowedAuth allowed_auths;
FeatureSupport statistics;
}; };
/*****************************************************************************/ /*****************************************************************************/
@@ -393,59 +394,76 @@ uauthreq_ready (MMBaseModem *modem,
static void static void
authenticate_3gpp (GTask *task) authenticate_3gpp (GTask *task)
{ {
const gchar *user; MMBroadbandBearerUblox *self;
const gchar *password; CommonConnectContext *ctx;
MMBearerAllowedAuth allowed_auth; gchar *cmd = NULL;
CommonConnectContext *ctx; MMBearerAllowedAuth allowed_auth;
gchar *cmd; gint ublox_auth = -1;
self = g_task_get_source_object (task);
ctx = (CommonConnectContext *) g_task_get_task_data (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))); 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) { if (!ctx->auth_required) {
mm_dbg ("Not using authentication"); mm_dbg ("Not using authentication");
cmd = g_strdup_printf ("+UAUTHREQ=%u,0", ctx->cid); ublox_auth = 0;
} else { goto out;
gchar *quoted_user; }
gchar *quoted_password;
guint ublox_auth;
if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN || allowed_auth == (MM_BEARER_ALLOWED_AUTH_PAP | MM_BEARER_ALLOWED_AUTH_CHAP)) { 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"); mm_dbg ("Using automatic authentication method");
if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_AUTO)
ublox_auth = 3; ublox_auth = 3;
} else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) { else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_PAP)
mm_dbg ("Using PAP authentication method");
ublox_auth = 1; ublox_auth = 1;
} else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) { else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_CHAP)
mm_dbg ("Using CHAP authentication method");
ublox_auth = 2; ublox_auth = 2;
} else { else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_NONE)
gchar *str; 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); out:
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;
}
quoted_user = mm_port_serial_at_quote_string (user); 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;
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); quoted_password = mm_port_serial_at_quote_string (password);
cmd = g_strdup_printf ("+UAUTHREQ=%u,%u,%s,%s", cmd = g_strdup_printf ("+UAUTHREQ=%u,%u,%s,%s",
ctx->cid, ctx->cid,
ublox_auth, ublox_auth,
quoted_password, quoted_password,
quoted_user); quoted_user);
g_free (quoted_user); g_free (quoted_user);
g_free (quoted_password); 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_dbg ("setting up authentication preferences in PDP context #%u...", ctx->cid);
mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem), mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
@@ -457,6 +475,78 @@ authenticate_3gpp (GTask *task)
g_free (cmd); 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 static void
dial_3gpp (MMBroadbandBearer *self, dial_3gpp (MMBroadbandBearer *self,
MMBaseModem *modem, MMBaseModem *modem,
@@ -478,7 +568,7 @@ dial_3gpp (MMBroadbandBearer *self,
user_data))) user_data)))
return; return;
authenticate_3gpp (task); check_supported_authentication_methods (task);
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -785,9 +875,10 @@ mm_broadband_bearer_ublox_init (MMBroadbandBearerUblox *self)
MMBroadbandBearerUbloxPrivate); MMBroadbandBearerUbloxPrivate);
/* Defaults */ /* Defaults */
self->priv->profile = MM_UBLOX_USB_PROFILE_UNKNOWN; self->priv->profile = MM_UBLOX_USB_PROFILE_UNKNOWN;
self->priv->mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN; self->priv->mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN;
self->priv->statistics = FEATURE_SUPPORT_UNKNOWN; self->priv->allowed_auths = MM_UBLOX_BEARER_ALLOWED_AUTH_UNKNOWN;
self->priv->statistics = FEATURE_SUPPORT_UNKNOWN;
} }
static void static void