gprs: make PPP authentication method configurable
authorPhilip Paeps <philip@paeps.cx>
Thu, 19 Jun 2014 10:07:08 +0000 (12:07 +0200)
committerDenis Kenzior <denkenz@gmail.com>
Sat, 21 Jun 2014 16:58:03 +0000 (11:58 -0500)
Add a new "AuthenticationMethod" property to select between "pap"
and "chap" PPP authentication, defaulting to "chap" (i.e.: previous
behaviour).

src/gprs.c

index e379f7baa79924ab41ba97dc5ad3c895b8defcac..71280f24a30291321afc136783687ec2aaa9552d 100644 (file)
@@ -264,6 +264,32 @@ static gboolean gprs_proto_from_string(const char *str,
        return FALSE;
 }
 
+static const char *gprs_auth_method_to_string(enum ofono_gprs_auth_method auth)
+{
+       switch (auth) {
+       case OFONO_GPRS_AUTH_METHOD_CHAP:
+               return "chap";
+       case OFONO_GPRS_AUTH_METHOD_PAP:
+               return "pap";
+       };
+
+       return NULL;
+}
+
+static gboolean gprs_auth_method_from_string(const char *str,
+                                       enum ofono_gprs_auth_method *auth)
+{
+       if (g_str_equal(str, "chap")) {
+               *auth = OFONO_GPRS_AUTH_METHOD_CHAP;
+               return TRUE;
+       } else if (g_str_equal(str, "pap")) {
+               *auth = OFONO_GPRS_AUTH_METHOD_PAP;
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static unsigned int gprs_cid_alloc(struct ofono_gprs *gprs)
 {
        return idmap_alloc(gprs->cid_map);
@@ -807,6 +833,10 @@ static void append_context_properties(struct pri_context *ctx,
        ofono_dbus_dict_append(dict, "Password", DBUS_TYPE_STRING,
                                &strvalue);
 
+       strvalue = gprs_auth_method_to_string(ctx->context.auth_method);
+       ofono_dbus_dict_append(dict, "AuthenticationMethod", DBUS_TYPE_STRING,
+                               &strvalue);
+
        if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
                strvalue = ctx->message_proxy;
                ofono_dbus_dict_append(dict, "MessageProxy",
@@ -1149,6 +1179,37 @@ static DBusMessage *pri_set_message_center(struct pri_context *ctx,
        return NULL;
 }
 
+static DBusMessage *pri_set_auth_method(struct pri_context *ctx,
+                                       DBusConnection *conn,
+                                       DBusMessage *msg, const char *str)
+{
+       GKeyFile *settings = ctx->gprs->settings;
+       enum ofono_gprs_auth_method auth;
+
+       if (gprs_auth_method_from_string(str, &auth) == FALSE)
+               return __ofono_error_invalid_format(msg);
+
+       if (ctx->context.auth_method == auth)
+               return dbus_message_new_method_return(msg);
+
+       ctx->context.auth_method = auth;
+
+       if (settings) {
+               g_key_file_set_string(settings, ctx->key,
+                                       "AuthenticationMethod", str);
+               storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
+       }
+
+       g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
+
+       ofono_dbus_signal_property_changed(conn, ctx->path,
+                                       OFONO_CONNECTION_CONTEXT_INTERFACE,
+                                       "AuthenticationMethod",
+                                       DBUS_TYPE_STRING, &str);
+
+       return NULL;
+}
+
 static DBusMessage *pri_set_property(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
@@ -1259,6 +1320,13 @@ static DBusMessage *pri_set_property(DBusConnection *conn,
                dbus_message_iter_get_basic(&var, &str);
 
                return pri_set_name(ctx, conn, msg, str);
+       } else if (!strcmp(property, "AuthenticationMethod")) {
+               if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
+                       return __ofono_error_invalid_args(msg);
+
+               dbus_message_iter_get_basic(&var, &str);
+
+               return pri_set_auth_method(ctx, conn, msg, str);
        }
 
        if (ctx->type != OFONO_GPRS_CONTEXT_TYPE_MMS)
@@ -1752,6 +1820,10 @@ static void write_context_settings(struct ofono_gprs *gprs,
                                "Username", context->context.username);
        g_key_file_set_string(gprs->settings, context->key,
                                "Password", context->context.password);
+       g_key_file_set_string(gprs->settings, context->key,
+                               "AuthenticationMethod",
+                               gprs_auth_method_to_string(
+                               context->context.auth_method));
        g_key_file_set_string(gprs->settings, context->key, "Type",
                                gprs_context_type_to_string(context->type));
        g_key_file_set_string(gprs->settings, context->key, "Protocol",
@@ -2698,11 +2770,13 @@ static gboolean load_context(struct ofono_gprs *gprs, const char *group)
        char *apn = NULL;
        char *msgproxy = NULL;
        char *msgcenter = NULL;
+       char *authstr = NULL;
        gboolean ret = FALSE;
        gboolean legacy = FALSE;
        struct pri_context *context;
        enum ofono_gprs_context_type type;
        enum ofono_gprs_proto proto;
+       enum ofono_gprs_auth_method auth;
        unsigned int id;
 
        if (sscanf(group, "context%d", &id) != 1) {
@@ -2747,6 +2821,14 @@ static gboolean load_context(struct ofono_gprs *gprs, const char *group)
        if (password == NULL)
                goto error;
 
+       authstr = g_key_file_get_string(gprs->settings, group,
+                                               "AuthenticationMethod", NULL);
+       if (authstr == NULL)
+               authstr = g_strdup("chap");
+
+       if (gprs_auth_method_from_string(authstr, &auth) == FALSE)
+               goto error;
+
        if (strlen(password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
                goto error;
 
@@ -2783,6 +2865,7 @@ static gboolean load_context(struct ofono_gprs *gprs, const char *group)
        strcpy(context->context.password, password);
        strcpy(context->context.apn, apn);
        context->context.proto = proto;
+       context->context.auth_method = auth;
 
        if (msgproxy != NULL)
                strcpy(context->message_proxy, msgproxy);
@@ -2812,6 +2895,7 @@ error:
        g_free(apn);
        g_free(msgproxy);
        g_free(msgcenter);
+       g_free(authstr);
 
        return ret;
 }