Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(740)

Unified Diff: src/service.c

Issue 6659006: flimflam: add support for multiple profiles (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/flimflam.git@master
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/service.c
diff --git a/src/service.c b/src/service.c
index f56c40559a818176faef070d50c4644b20d282ba..f1234eaed30a2c99f090481891efc28b1e1ed291 100644
--- a/src/service.c
+++ b/src/service.c
@@ -95,7 +95,7 @@ struct connman_service {
char *key_mgmt;
} eap;
- char *profile;
+ const struct connman_storage_ident *profile;
char *proxy_config;
/* TODO(sleffler) overlay storage */
@@ -213,8 +213,12 @@ static const char* kEAPPIN = "EAP.PIN";
static const char* kEAPPassword = "EAP.Password";
static const char* kEAPKeyMgmt = "EAP.KeyMgmt";
+static void service_clear_passphrase(struct connman_service *service);
static void service_modified(struct connman_service *service);
+static void service_clear_eap(struct connman_service *service);
static void __service_resort(struct connman_service *service);
+static void set_reconnect_state(struct connman_service *service,
+ connman_bool_t onoff);
static connman_bool_t is_timeset(const GTimeVal *tv)
{
@@ -389,6 +393,40 @@ static struct connman_service *find_service(const char *path)
return data.service;
}
+static void invalidate_profile(gpointer value, gpointer user_data)
+{
+ struct connman_service *service = value;
+ const struct connman_storage_ident *profile = user_data;
+
+ if (service->profile == profile) {
+ /*
+ * Invalidate profile-related data and force a re-load
+ * the next time the service is to be used (so it can
+ * come from the active profile).
+ */
+ service->profile = NULL;
+
+ /*
+ * network_disconnect may drop the last reference to the
+ * service and cause it to be freed, so take a reference
+ * temporarily until we are done with it.
+ */
+ set_reconnect_state(service, FALSE);
+ connman_service_ref(service);
+ __connman_service_disconnect(service);
+ service_clear_passphrase(service);
+ service_clear_eap(service);
+ connman_service_unref(service);
+ }
+}
+
+void __connman_service_invalidate_profile(const struct connman_storage_ident *ident)
+{
+ _DBG_SERVICE("ident %s/%s", ident->user, ident->ident);
+
+ g_sequence_foreach(service_list, invalidate_profile, (gpointer) ident);
+}
+
static const char *identifier(struct connman_service *service)
{
return service ? service->identifier : "<nil>";
@@ -770,12 +808,13 @@ static void hidden_ssid_changed(struct connman_service *service)
*/
int connman_service_append_hidden_ssids(GSList **hidden_ssids)
{
- const char *ident = __connman_profile_active_ident();
+ const struct connman_storage_ident *ident =
+ __connman_profile_active_ident();
GKeyFile *keyfile;
gchar **keys;
int ret = 0;
- _DBG_SERVICE("ident %s", ident);
+ _DBG_SERVICE("ident %s:%s", ident->user, ident->ident);
keyfile = __connman_storage_open(ident);
if (keyfile == NULL)
@@ -815,7 +854,7 @@ int connman_service_append_hidden_ssids(GSList **hidden_ssids)
}
done:
- g_key_file_free(keyfile);
+ __connman_storage_close(ident, keyfile, FALSE);
return ret;
}
@@ -1434,7 +1473,7 @@ static DBusMessage *set_eap_string(struct connman_service *service,
CONNMAN_SERVICE_INTERFACE, servicename,
DBUS_TYPE_STRING, storage);
- __connman_storage_save_service(service);
+ service_modified(service);
return NULL;
}
@@ -1481,8 +1520,7 @@ static DBusMessage *set_property(DBusConnection *conn,
hidden_ssid_changed(service);
- __connman_storage_save_service(service);
-
+ service_modified(service);
} else if (g_str_equal(name, "Passphrase") == TRUE) {
const char *passphrase;
@@ -1524,7 +1562,7 @@ static DBusMessage *set_property(DBusConnection *conn,
if (service->network != NULL)
prepare_network_passphrase(service);
- __connman_storage_save_service(service);
+ service_modified(service);
} else if (g_str_equal(name, kEAPIdentity) == TRUE) {
returnmsg = set_eap_string(service, msg, type, value,
&service->eap.identity,
@@ -1629,7 +1667,7 @@ static DBusMessage *set_property(DBusConnection *conn,
autoconnect_changed(service);
- __connman_storage_save_service(service);
+ service_modified(service);
} else if (g_str_equal(name, "ProxyConfig") == TRUE) {
const char *proxy_config;
@@ -1643,7 +1681,7 @@ static DBusMessage *set_property(DBusConnection *conn,
proxy_configuration_changed(service);
- __connman_storage_save_service(service);
+ service_modified(service);
} else if (g_str_has_prefix(name, "Priority") == TRUE) {
int pri;
@@ -1664,7 +1702,7 @@ static DBusMessage *set_property(DBusConnection *conn,
service_priority_changed(service);
- __connman_storage_save_service(service);
+ service_modified(service);
}
} else
return __connman_error_invalid_property(msg);
@@ -1689,12 +1727,17 @@ static void set_idle(struct connman_service *service)
state_change(service, CONNMAN_SERVICE_STATE_IDLE, TRUE);
}
-static void __connman_service_clear_passphrase(struct connman_service *service)
+static void service_clear_passphrase(struct connman_service *service)
{
g_free(service->passphrase);
service->passphrase = NULL;
memset(&service->wifi, 0, sizeof(service->wifi));
+}
+
+static void __connman_service_clear_passphrase(struct connman_service *service)
+{
+ service_clear_passphrase(service);
passphrase_required_changed(service);
}
@@ -1702,14 +1745,13 @@ static void __connman_service_clear_passphrase(struct connman_service *service)
static void service_modified(struct connman_service *service)
{
g_get_current_time(&service->modified);
- __connman_storage_save_service(service);
+
+ service->profile = __connman_profile_active_ident();
+ __connman_profile_save_service(service);
}
-void __connman_service_reset(struct connman_service *service)
+static void service_clear_eap(struct connman_service *service)
{
- connman_service_set_favorite(service, FALSE);
- __connman_service_clear_passphrase(service);
-
g_free(service->eap.identity);
service->eap.identity = NULL;
@@ -1748,6 +1790,13 @@ void __connman_service_reset(struct connman_service *service)
g_free(service->eap.password);
service->eap.password = NULL;
+}
+
+void __connman_service_reset(struct connman_service *service)
+{
+ connman_service_set_favorite(service, FALSE);
+ __connman_service_clear_passphrase(service);
+ service_clear_eap(service);
service_modified(service);
}
@@ -2655,7 +2704,7 @@ static DBusMessage *set_apn(DBusConnection *conn, DBusMessage *msg,
apn_info->password = g_strdup(password);
}
- __connman_storage_save_service(service);
+ service_modified(service);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -2709,7 +2758,6 @@ static void service_free(gpointer user_data)
if (service->provider != NULL)
connman_provider_unref(service->provider);
- g_free(service->profile);
g_free(service->name);
g_free(service->passphrase);
g_free(service->eap.identity);
@@ -3777,7 +3825,7 @@ DBusMessage *__connman_configure_wifi_service(DBusMessage *msg)
_DBG_SERVICE("service %p created %d", service, created);
- __connman_storage_save_service(service);
+ service_modified(service);
/*
* If __connman_get_wifi_service_int created the network object
@@ -3824,9 +3872,9 @@ static struct connman_service *__connman_service_get(const char *identifier)
service->identifier = g_strdup(identifier);
- service->profile = g_strdup(__connman_profile_active_ident());
+ service->profile = __connman_profile_active_ident();
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
iter = g_sequence_insert_sorted(service_list, service,
service_compare, NULL);
@@ -3854,7 +3902,7 @@ static int service_register(struct connman_service *service)
service_methods, service_signals,
NULL, service, NULL);
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
__service_resort(service);
@@ -3923,7 +3971,7 @@ __connman_service_create_from_device(struct connman_device *device)
service->device = device;
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
service_register(service);
@@ -4325,7 +4373,7 @@ __connman_service_create_from_network(struct connman_network *network)
update_from_network(service, network, FALSE);
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
service_register(service);
@@ -4527,21 +4575,25 @@ static char *__old_security(GKeyFile *keyfile,
if (service->security == CONNMAN_SERVICE_SECURITY_WPA) {
group = g_strdup(service->identifier);
g_strlcpy(group + strlen(group) - 3, "wpa", 4);
+ if (g_key_file_has_group(keyfile, group) == FALSE) {
+ g_free(group);
+ group = NULL;
+ }
} else if (service->security == CONNMAN_SERVICE_SECURITY_RSN) {
group = g_strdup(service->identifier);
g_strlcpy(group + strlen(group) - 3, "rsn", 4);
+ if (g_key_file_has_group(keyfile, group) == FALSE) {
+ g_free(group);
+ group = NULL;
+ }
}
return group;
}
-static int service_load(struct connman_service *service)
+static int service_load(struct connman_service *service, GKeyFile *keyfile)
{
- const char *ident = service->profile;
const char *group = service->identifier;
- GKeyFile *keyfile;
GError *error = NULL;
- gchar *pathname, *data = NULL;
- gsize length;
gchar *str;
connman_bool_t autoconnect;
unsigned int ssid_len;
@@ -4550,40 +4602,22 @@ static int service_load(struct connman_service *service)
_DBG_SERVICE("service %p", service);
- if (ident == NULL)
- return -EINVAL;
-
- pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
- if (pathname == NULL)
- return -ENOMEM;
-
- keyfile = g_key_file_new();
-
- if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE) {
- g_free(pathname);
- return -ENOENT;
- }
-
- g_free(pathname);
-
- if (g_key_file_load_from_data(keyfile, data, length,
- 0, NULL) == FALSE) {
- g_free(data);
- return -EILSEQ;
- }
-
- g_free(data);
-
- /*
- * Handle upgrade of old-style entries for wpa/rsn services.
- */
- if (g_key_file_has_group(keyfile, group) == FALSE &&
- g_str_has_suffix(group, "_psk") == TRUE) {
- char *old_group = __old_security(keyfile, service);
- if (old_group != NULL) {
- _DBG_SERVICE("check old entry %s", old_group);
- group = old_group;
+ if (g_key_file_has_group(keyfile, group) == FALSE) {
+ char *old_group;
+ /*
+ * Handle upgrade of old-style entries for wpa/rsn services.
+ */
+ if (g_str_has_suffix(group, "_psk") == FALSE) {
+ err = -ESRCH;
+ goto done;
+ }
+ old_group = __old_security(keyfile, service);
+ if (old_group == NULL) {
+ err = -ESRCH;
+ goto done;
}
+ _DBG_SERVICE("check old entry %s", old_group);
+ group = old_group;
}
switch (service->type) {
@@ -4669,8 +4703,8 @@ static int service_load(struct connman_service *service)
g_free(str);
}
- str = __connman_storage_get_encrypted_value(keyfile, service->profile,
- group, "Passphrase");
+ str = __connman_storage_get_encrypted_value(keyfile, group,
+ "Passphrase");
if (str != NULL) {
connman_bool_t valid_pass = TRUE;
g_free(service->passphrase);
@@ -4761,8 +4795,6 @@ static int service_load(struct connman_service *service)
apn->network_id = NULL;
}
done:
- g_key_file_free(keyfile);
-
if (group != service->identifier)
g_free((char *)group);
@@ -4778,39 +4810,13 @@ static void save_property(GKeyFile *keyfile, struct connman_service *service,
g_key_file_remove_key(keyfile, service->identifier, key, NULL);
}
-static int service_save(struct connman_service *service)
+static int service_save(struct connman_service *service, GKeyFile *keyfile)
{
- const char *ident = service->profile;
struct connman_network_apn *apn = &service->cellular.apn;
- GKeyFile *keyfile;
- gchar *pathname, *data = NULL;
- gsize length;
gchar *str;
- int err = 0;
_DBG_SERVICE("service %p", service);
- if (ident == NULL)
- return -EINVAL;
-
- pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
- if (pathname == NULL)
- return -ENOMEM;
-
- keyfile = g_key_file_new();
-
- if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
- goto update;
-
- if (length > 0) {
- if (g_key_file_load_from_data(keyfile, data, length,
- 0, NULL) == FALSE)
- goto done;
- }
-
- g_free(data);
-
-update:
if (service->name != NULL)
g_key_file_set_string(keyfile, service->identifier,
"Name", service->name);
@@ -4880,7 +4886,7 @@ update:
}
if (service->passphrase != NULL && strlen(service->passphrase) > 0) {
- __connman_storage_set_encrypted_value(keyfile, service->profile,
+ __connman_storage_set_encrypted_value(keyfile,
service->identifier, "Passphrase", service->passphrase);
} else {
g_key_file_remove_key(keyfile, service->identifier,
@@ -4940,19 +4946,7 @@ update:
"Cellular.APN.network_id", NULL);
}
- data = g_key_file_to_data(keyfile, &length, NULL);
-
- if (g_file_set_contents(pathname, data, length, NULL) == FALSE)
- connman_error("Failed to store service information");
-
-done:
- g_free(data);
-
- g_key_file_free(keyfile);
-
- g_free(pathname);
-
- return err;
+ return 0;
}
static struct connman_storage service_storage = {

Powered by Google App Engine
This is Rietveld 408576698