Re: Pre-configuring an ethernet interface
On 18.02.2013 09:58, Patrik Flykt wrote: On Thu, 2013-02-14 at 13:38 +0100, Simon Busch wrote: I have a similar case where something like this is needed. Anyone already working on getting this implemented? AFAIK not at the moment. I have a few things to do before I have a chance to look at this. Patches are always welcome. I started to work on it, patches coming soon. Cheers, Jukka ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH] iptables: Cannot flush all rules without API to set them
Currently there exists no API where iptables rules can be set. The flush code does not change the default chain policy at the moment, so any pre-existing iptables rules setting default policy to reject and relying on individual iptables rules allowing packets going through will prevent all IP communication. For the time being disable iptables flush on init. Thus please be careful with iptables rules. --- src/iptables.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/iptables.c b/src/iptables.c index 83612b9..8fa3687 100644 --- a/src/iptables.c +++ b/src/iptables.c @@ -36,6 +36,7 @@ #include connman.h +void flush_table(const char *name); /* * Some comments on how the iptables API works (some of them from the @@ -2243,7 +2244,7 @@ static int flush_table_cb(struct ipt_entry *entry, int builtin, return 0; } -static void flush_table(const char *name) +void flush_table(const char *name) { GSList *chains = NULL, *list; struct connman_iptables *table; @@ -2269,13 +2270,6 @@ static void flush_table(const char *name) g_slist_free_full(chains, g_free); } -static void flush_all_chains(void) -{ - flush_table(filter); - flush_table(mangle); - flush_table(nat); -} - int __connman_iptables_init(void) { DBG(); @@ -2288,8 +2282,6 @@ int __connman_iptables_init(void) xtables_init_all(iptables_globals, NFPROTO_IPV4); - flush_all_chains(); - return 0; } -- 1.7.10.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH] gsupplicant: Return zero for max scan SSID parameter
On Thu, 2013-02-14 at 23:37 +0200, patrik.fl...@linux.intel.com wrote: From: Patrik Flykt patrik.fl...@linux.intel.com A driver can return a valid max scan SSID value of zero. Thus no fast scans can be done, so the code falls back to a simple scan instead. A value of zero is properly handled in plugins/wifi.c. An active scan for a hidden SSID adds only the SSID parameter to the wpa_supplicant D-Bus method call, which wpa_supplicant then handles properly. Some drivers also report a max scan SSID value of one. In some of the cases that value is bogus, the driver will not be able to do a fast scan anyway. In addition, it is questionable why only one SSID can be fast scanned as the feature would not differ much from an active scan for a hidden network. Thus we set the limit to two, i.e. zero or one is treated as zero, two or more is reported as is. Thanks to Grant Erickson and Tomasz Bursztyka for finding and pinpointing this issue. Fixes BMC#25971 I start to get a Monty Pythonesq feeling about counting now... Applied. Patrik ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH (RFC) 1/2] gresolv: Do not remove a query on failure if other results are pending
On Fri, 2013-02-15 at 12:30 +0200, Tomasz Bursztyka wrote: Fixes BMC#25973 In the case one of the resolving failed, the query is removed and destroyed from the queue. So the responses of the requests sent to the other namerservers - which might be successful - will thus be lost since they cannot be matched anymore to their initial request. Applied, thanks! Patrik ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH 2/2] gresolv: Optimize the response parser
On Fri, 2013-02-15 at 12:30 +0200, Tomasz Bursztyka wrote: It will check first if the response belongs to a query, before interpreting any of its content (rcode, count...). Applied, thanks! Patrik ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 00/20] Add UID support to session policies
From: Daniel Wagner daniel.wag...@bmw-carit.de Hi, This version containts several small bug fixes. Though it also unreviels a nasty use after free bug in the session core. Note this bug is not introduced by this series. Changes v1: - fixed shutdown sequence (double free) - fixed memory leaks - handle loading/parsing errors v0: - initial version cheers, daniel original cover letter: here is the initial series to allow UID matching on policy files. The first part of the series are preparation patches and some small cleanups. I need first to split the ownership of the connman_session_policy data from the policy_hash table. In the end we can rename the policy_hash to file_hash. That means we have one hash for the sessions and one for the files. The ownership is transfered to a new policy list. I think overall that should make the code also better readable. With introducing a unit test for the UID support the second part starts. A few patches are needed to add the cb_data helpers and consequently fixing up the some parts which can make use of it. The very last patch gives you finally the UID matching. There are still a few broken in this version, so this is not ready to be applied. Daniel Wagner (20): session_policy_local: Refactor SELinux context parser session: Do not fail when creating default policy configuration session_policy_local: Do not handle small allocation session_policy_local: Track policy data structure in a separate list session_policy_local: Print warning if loading of policy fails session_policy_local: Use policy_hash only to track the policy files session_policy_local: Load policy from file session_policy_local: Rename policy_hash to file_hash session_policy_local: Rename ident to filename session_policy_local: Split LSM context ident from filename test-session: Add unit test for session_policy_local connman: Add callback helpers session: Add _t postfix to callback typedef session_policy_local: Use callback helpers dbus: Use callback helpers dbus: Add connman_dbus_get_connnection_unix_user() session_policy_local: Retrieve UID from session user session_policy_local: Add some more debug infos session_policy_local: Do not free policy on load error session: Reorder shutdown sequence include/dbus.h | 16 +- include/session.h | 10 +- include/types.h| 19 +++ plugins/session_policy_local.c | 372 +++-- src/dbus.c | 112 ++--- src/main.c | 2 +- src/session.c | 29 ++-- unit/test-session.c| 156 + 8 files changed, 537 insertions(+), 179 deletions(-) -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 01/20] session_policy_local: Refactor SELinux context parser
From: Daniel Wagner daniel.wag...@bmw-carit.de selinux_context_reply() should handle the 'type' conversion of data it gets from D-Bus. --- plugins/session_policy_local.c | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 5a8f6b8..d3e51a2 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -75,9 +75,9 @@ static void cleanup_policy(gpointer user_data) g_free(policy); } -static char *parse_ident(const unsigned char *context) +static char *parse_selinux_type(const char *context) { - char *str, *ident, **tokens; + char *ident, **tokens; /* * SELinux combines Role-Based Access Control (RBAC), Type @@ -97,23 +97,14 @@ static char *parse_ident(const unsigned char *context) * as haifux_t. */ - str = g_strdup((const gchar*)context); - if (str == NULL) + tokens = g_strsplit(context, :, 0); + if (tokens == NULL) return NULL; - DBG(SELinux context %s, str); - - tokens = g_strsplit(str, :, 0); - if (tokens == NULL) { - g_free(str); - return NULL; - } - /* Use the SELinux type as identification token. */ ident = g_strdup(tokens[2]); g_strfreev(tokens); - g_free(str); return ident; } @@ -167,14 +158,22 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, struct create_data *data = user_data; struct policy_data *policy; struct connman_session_config *config = NULL; - char *ident = NULL; + char *ident = NULL, *ctx = NULL; DBG(session %p, data-session); if (err 0) goto done; - ident = parse_ident(context); + ctx = g_strdup((const gchar*)context); + if (ctx == NULL) { + err = -ENOMEM; + goto done; + } + + DBG(SELinux context %s, ctx); + + ident = parse_selinux_type(ctx); if (ident == NULL) { err = -EINVAL; goto done; @@ -200,6 +199,7 @@ done: g_free(data); g_free(ident); + g_free(ctx); } static int policy_local_create(struct connman_session *session, -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 04/20] session_policy_local: Track policy data structure in a separate list
From: Daniel Wagner daniel.wag...@bmw-carit.de We want to make the lifetime of the policy data structure independent of the policy_hash table. --- plugins/session_policy_local.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 1e3abfb..8968d14 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -48,6 +48,7 @@ static DBusConnection *connection; static GHashTable *policy_hash; static GHashTable *session_hash; +static GSList *policy_list; struct create_data { struct connman_session *session; @@ -63,7 +64,7 @@ struct policy_data { struct connman_session_config *config; }; -static void cleanup_policy(gpointer user_data) +static void free_policy(gpointer user_data) { struct policy_data *policy = user_data; @@ -121,6 +122,8 @@ static struct policy_data *create_policy(const char *ident) policy-config = connman_session_create_default_config(); policy-ident = g_strdup(ident); + policy_list = g_slist_prepend(policy_list, policy); + g_hash_table_replace(policy_hash, policy-ident, policy); return policy; @@ -142,7 +145,11 @@ static void policy_unref(struct policy_data *policy) if (__sync_fetch_and_sub(policy-refcount, 1) != 1) return; + policy_list = g_slist_remove(policy_list, policy); + g_hash_table_remove(policy_hash, policy-ident); + + free_policy(policy); }; static void selinux_context_reply(const unsigned char *context, void *user_data, @@ -453,7 +460,7 @@ static int session_policy_local_init(void) session_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); policy_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - NULL, cleanup_policy); + NULL, NULL); err = connman_inotify_register(POLICYDIR, notify_handler); if (err 0) @@ -491,6 +498,8 @@ static void session_policy_local_exit(void) g_hash_table_destroy(session_hash); g_hash_table_destroy(policy_hash); + g_slist_free_full(policy_list, free_policy); + connman_session_policy_unregister(session_policy_local); dbus_connection_unref(connection); -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 03/20] session_policy_local: Do not handle small allocation
From: Daniel Wagner daniel.wag...@bmw-carit.de Let's remove the small allocations error path because glib will abort on memory exhausting anyway. Basically we remove dead code. --- plugins/session_policy_local.c | 39 --- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 90396cf..1e3abfb 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -115,12 +115,10 @@ static struct policy_data *create_policy(const char *ident) DBG(ident %s, ident); - policy = g_try_new0(struct policy_data, 1); - if (policy == NULL) - return NULL; + policy = g_new0(struct policy_data, 1); + policy-refcount = 1; policy-config = connman_session_create_default_config(); - policy-refcount = 1; policy-ident = g_strdup(ident); g_hash_table_replace(policy_hash, policy-ident, policy); @@ -161,10 +159,6 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, goto done; ctx = g_strdup((const gchar*)context); - if (ctx == NULL) { - err = -ENOMEM; - goto done; - } DBG(SELinux context %s, ctx); @@ -178,13 +172,8 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, if (policy != NULL) { policy_ref(policy); policy-session = data-session; - } else { + } else policy = create_policy(ident); - if (policy == NULL) { - err = -ENOMEM; - goto done; - } - } g_hash_table_replace(session_hash, data-session, policy); config = policy-config; @@ -207,9 +196,7 @@ static int policy_local_create(struct connman_session *session, DBG(session %p, session); - data = g_try_new0(struct create_data, 1); - if (data == NULL) - return -ENOMEM; + data = g_new0(struct create_data, 1); data-session = session; data-callback = callback; @@ -290,8 +277,6 @@ static int load_policy(struct policy_data *policy) int i, err = 0; pathname = g_strdup_printf(%s/%s, POLICYDIR, policy-ident); - if(pathname == NULL) - return -ENOMEM; err = load_keyfile(pathname, keyfile); if (err 0) { @@ -350,8 +335,6 @@ static int load_policy(struct policy_data *policy) } else { config-allowed_bearers = g_slist_append(NULL, GINT_TO_POINTER(CONNMAN_SERVICE_TYPE_UNKNOWN)); - if (config-allowed_bearers == NULL) - err = -ENOMEM; } g_key_file_free(keyfile); @@ -440,11 +423,6 @@ static int read_policies(void) struct policy_data *policy; policy = create_policy(file); - if (policy == NULL) { - err = -ENOMEM; - break; - } - err = load_policy(policy); if (err 0) break; @@ -474,17 +452,8 @@ static int session_policy_local_init(void) session_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); - if (session_hash == NULL) { - err = -ENOMEM; - goto err; - } - policy_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, cleanup_policy); - if (policy_hash == NULL) { - err = -ENOMEM; - goto err; - } err = connman_inotify_register(POLICYDIR, notify_handler); if (err 0) -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 05/20] session_policy_local: Print warning if loading of policy fails
From: Daniel Wagner daniel.wag...@bmw-carit.de Also continue reading the rest of the policy files when starting up. This makes the startup behavior consistent with the runtime behavior. --- plugins/session_policy_local.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 8968d14..b0317bb 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -377,6 +377,7 @@ static void notify_handler(struct inotify_event *event, const char *ident) { struct policy_data *policy; + int err; if (ident == NULL) return; @@ -398,7 +399,10 @@ static void notify_handler(struct inotify_event *event, if (event-mask IN_MODIFY) { connman_info(Policy modifed for '%s', ident); - if (load_policy(policy) 0) { + err = load_policy(policy); + if (err 0) { + connman_warn(Loading policy file '%s' failed with %s, + ident, strerror(-err)); remove_policy(policy); return; } @@ -415,10 +419,10 @@ static void notify_handler(struct inotify_event *event, update_session(policy-session); } -static int read_policies(void) +static void read_policies(void) { GDir *dir; - int err = 0; + int err; DBG(); @@ -431,14 +435,17 @@ static int read_policies(void) policy = create_policy(file); err = load_policy(policy); - if (err 0) - break; + if (err 0) { + connman_warn(Loading policy file '%s' failed with %s, + file, strerror(-err)); + policy_unref(policy); + continue; + } + } g_dir_close(dir); } - - return err; } static int session_policy_local_init(void) @@ -466,9 +473,7 @@ static int session_policy_local_init(void) if (err 0) goto err; - err = read_policies(); - if (err 0) - goto err_notify; + read_policies(); err = connman_session_policy_register(session_policy_local); if (err 0) -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 06/20] session_policy_local: Use policy_hash only to track the policy files
From: Daniel Wagner daniel.wag...@bmw-carit.de Let's move the owner ship to the policy_list. The policy_hash is only used to lookup the policy data structure. This patch removes the requirement that the 'ident' is key to lookup the policy data. Now we are able to define set of rules how we want associate the file with a session. --- plugins/session_policy_local.c | 63 +- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index b0317bb..b20084d 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -110,22 +110,17 @@ static char *parse_selinux_type(const char *context) return ident; } -static struct policy_data *create_policy(const char *ident) +static struct policy_data *create_policy(void) { struct policy_data *policy; - DBG(ident %s, ident); - policy = g_new0(struct policy_data, 1); policy-refcount = 1; policy-config = connman_session_create_default_config(); - policy-ident = g_strdup(ident); policy_list = g_slist_prepend(policy_list, policy); - g_hash_table_replace(policy_hash, policy-ident, policy); - return policy; } @@ -146,9 +141,6 @@ static void policy_unref(struct policy_data *policy) return; policy_list = g_slist_remove(policy_list, policy); - - g_hash_table_remove(policy_hash, policy-ident); - free_policy(policy); }; @@ -176,11 +168,12 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, } policy = g_hash_table_lookup(policy_hash, ident); - if (policy != NULL) { - policy_ref(policy); - policy-session = data-session; + if (policy == NULL) { + policy = create_policy(); + policy-ident = g_strdup(ident); } else - policy = create_policy(ident); + policy_ref(policy); + policy-session = data-session; g_hash_table_replace(session_hash, data-session, policy); config = policy-config; @@ -364,6 +357,7 @@ static void remove_policy(struct policy_data *policy) if (policy-session != NULL) update = TRUE; + g_hash_table_remove(policy_hash, policy-ident); policy_unref(policy); if (update == FALSE) @@ -373,12 +367,31 @@ static void remove_policy(struct policy_data *policy) update_session(policy-session); } +static struct policy_data *find_policy(const char *ident) +{ + GSList *list; + struct policy_data *policy; + + for (list = policy_list; list != NULL; list = list-next) { + policy = list-data; + + if (g_strcmp0(policy-ident, ident) != 0) + continue; + + return policy; + } + + return NULL; +} + static void notify_handler(struct inotify_event *event, const char *ident) { struct policy_data *policy; int err; + DBG(event %x file %s, event-mask, ident); + if (ident == NULL) return; @@ -387,10 +400,19 @@ static void notify_handler(struct inotify_event *event, if (event-mask (IN_CREATE | IN_MOVED_TO)) { connman_info(Policy added for '%s', ident); - if (policy != NULL) - policy_ref(policy); - else - policy = create_policy(ident); + /* policy != NULL can happen if the file is overwritten */ + if (policy == NULL) { + policy = find_policy(ident); + if (policy == NULL) + policy = create_policy(); + else + policy_ref(policy); + + policy-ident = g_strdup(ident); + } + + g_hash_table_replace(policy_hash, + g_strdup(ident), policy); } if (policy == NULL) @@ -433,7 +455,8 @@ static void read_policies(void) while ((file = g_dir_read_name(dir)) != NULL) { struct policy_data *policy; - policy = create_policy(file); + policy = create_policy(); + policy-ident = g_strdup(file); err = load_policy(policy); if (err 0) { connman_warn(Loading policy file '%s' failed with %s, @@ -442,6 +465,8 @@ static void read_policies(void) continue; } + g_hash_table_replace(policy_hash, g_strdup(file), + policy); } g_dir_close(dir); @@ -467,7 +492,7 @@ static int
[PATCH v1 09/20] session_policy_local: Rename ident to filename
From: Daniel Wagner daniel.wag...@bmw-carit.de ident is not shared anymore between the session policy and the file policy. Let's make this clear be renaming this member. --- plugins/session_policy_local.c | 44 +- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 90c6f1a..a46f1b3 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -58,7 +58,7 @@ struct create_data { struct policy_data { int refcount; - char *ident; + char *filename; struct connman_session *session; struct connman_session_config *config; @@ -71,7 +71,7 @@ static void free_policy(gpointer user_data) if (policy-config != NULL) g_slist_free(policy-config-allowed_bearers); - g_free(policy-ident); + g_free(policy-filename); g_free(policy-config); g_free(policy); } @@ -126,7 +126,7 @@ static struct policy_data *create_policy(void) static struct policy_data *policy_ref(struct policy_data *policy) { - DBG(%p %s ref %d, policy, policy-ident, policy-refcount + 1); + DBG(%p %s ref %d, policy, policy-filename, policy-refcount + 1); __sync_fetch_and_add(policy-refcount, 1); @@ -135,7 +135,7 @@ static struct policy_data *policy_ref(struct policy_data *policy) static void policy_unref(struct policy_data *policy) { - DBG( %p %s ref %d, policy, policy-ident, policy-refcount - 1); + DBG( %p %s ref %d, policy, policy-filename, policy-refcount - 1); if (__sync_fetch_and_sub(policy-refcount, 1) != 1) return; @@ -170,7 +170,7 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, policy = g_hash_table_lookup(file_hash, ident); if (policy == NULL) { policy = create_policy(); - policy-ident = g_strdup(ident); + policy-filename = g_strdup(ident); } else policy_ref(policy); policy-session = data-session; @@ -276,7 +276,7 @@ static int load_policy(struct policy_data *policy) char *str, **tokens; int i, err = 0; - pathname = g_strdup_printf(%s/%s, POLICYDIR, policy-ident); + pathname = g_strdup_printf(%s/%s, POLICYDIR, policy-filename); err = load_keyfile(pathname, keyfile); if (err 0) { @@ -357,7 +357,7 @@ static void remove_policy(struct policy_data *policy) if (policy-session != NULL) update = TRUE; - g_hash_table_remove(file_hash, policy-ident); + g_hash_table_remove(file_hash, policy-filename); policy_unref(policy); if (update == FALSE) @@ -367,7 +367,7 @@ static void remove_policy(struct policy_data *policy) update_session(policy-session); } -static struct policy_data *find_policy(const char *ident) +static struct policy_data *find_policy(const char *filename) { GSList *list; struct policy_data *policy; @@ -375,7 +375,7 @@ static struct policy_data *find_policy(const char *ident) for (list = policy_list; list != NULL; list = list-next) { policy = list-data; - if (g_strcmp0(policy-ident, ident) != 0) + if (g_strcmp0(policy-filename, filename) != 0) continue; return policy; @@ -385,61 +385,61 @@ static struct policy_data *find_policy(const char *ident) } static void notify_handler(struct inotify_event *event, -const char *ident) +const char *filename) { struct policy_data *policy; int err; - DBG(event %x file %s, event-mask, ident); + DBG(event %x file %s, event-mask, filename); - if (ident == NULL) + if (filename == NULL) return; - policy = g_hash_table_lookup(file_hash, ident); + policy = g_hash_table_lookup(file_hash, filename); if (event-mask (IN_CREATE | IN_MOVED_TO)) { - connman_info(Policy added for '%s', ident); + connman_info(Policy added for '%s', filename); /* policy != NULL can happen if the file is overwritten */ if (policy == NULL) { - policy = find_policy(ident); + policy = find_policy(filename); if (policy == NULL) policy = create_policy(); else policy_ref(policy); - policy-ident = g_strdup(ident); + policy-filename = g_strdup(filename); } err = load_policy(policy); if (err 0) { connman_warn(Loading policy file '%s' failed with %s, - ident,
[PATCH v1 10/20] session_policy_local: Split LSM context ident from filename
From: Daniel Wagner daniel.wag...@bmw-carit.de Separate the id which associates the file and the session. find_policy_by_file() and find_policy_by_lsm() contain the logic which associates the configuration file with a session. --- plugins/session_policy_local.c | 66 -- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index a46f1b3..55264ed 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -59,6 +59,7 @@ struct create_data { struct policy_data { int refcount; char *filename; + char *lsm_ctx; /* The Linux Security Module Context */ struct connman_session *session; struct connman_session_config *config; @@ -72,6 +73,7 @@ static void free_policy(gpointer user_data) g_slist_free(policy-config-allowed_bearers); g_free(policy-filename); + g_free(policy-lsm_ctx); g_free(policy-config); g_free(policy); } @@ -144,6 +146,40 @@ static void policy_unref(struct policy_data *policy) free_policy(policy); }; +static struct policy_data *find_policy_by_file(const char *filename) +{ + GSList *list; + struct policy_data *policy; + + for (list = policy_list; list != NULL; list = list-next) { + policy = list-data; + + if (g_strcmp0(policy-lsm_ctx, filename) != 0) + continue; + + return policy; + } + + return NULL; +} + +static struct policy_data *find_policy_by_session(const char *lsm_ctx) +{ + GSList *list; + struct policy_data *policy; + + for (list = policy_list; list != NULL; list = list-next) { + policy = list-data; + + if (g_strcmp0(policy-filename, lsm_ctx) != 0) + continue; + + return policy; + } + + return NULL; +} + static void selinux_context_reply(const unsigned char *context, void *user_data, int err) { @@ -167,12 +203,13 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, goto done; } - policy = g_hash_table_lookup(file_hash, ident); - if (policy == NULL) { + policy = find_policy_by_session(ident); + if (policy == NULL) policy = create_policy(); - policy-filename = g_strdup(ident); - } else + else policy_ref(policy); + + policy-lsm_ctx = g_strdup(ident); policy-session = data-session; g_hash_table_replace(session_hash, data-session, policy); @@ -227,6 +264,8 @@ static void policy_local_destroy(struct connman_session *session) return; g_hash_table_remove(session_hash, session); + g_free(policy-lsm_ctx); + policy-lsm_ctx = NULL; policy-session = NULL; policy_unref(policy); } @@ -367,23 +406,6 @@ static void remove_policy(struct policy_data *policy) update_session(policy-session); } -static struct policy_data *find_policy(const char *filename) -{ - GSList *list; - struct policy_data *policy; - - for (list = policy_list; list != NULL; list = list-next) { - policy = list-data; - - if (g_strcmp0(policy-filename, filename) != 0) - continue; - - return policy; - } - - return NULL; -} - static void notify_handler(struct inotify_event *event, const char *filename) { @@ -402,7 +424,7 @@ static void notify_handler(struct inotify_event *event, /* policy != NULL can happen if the file is overwritten */ if (policy == NULL) { - policy = find_policy(filename); + policy = find_policy_by_file(filename); if (policy == NULL) policy = create_policy(); else -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 12/20] connman: Add callback helpers
From: Daniel Wagner daniel.wag...@bmw-carit.de There is a common pattern when writing a callback function. Let's add a few helper for this. This is shamelessly stolen from oFono. --- include/types.h | 19 +++ 1 file changed, 19 insertions(+) diff --git a/include/types.h b/include/types.h index 0f671ec..051151a 100644 --- a/include/types.h +++ b/include/types.h @@ -22,6 +22,8 @@ #ifndef __CONNMAN_TYPES_H #define __CONNMAN_TYPES_H +#include glib.h + #ifdef __cplusplus extern C { #endif @@ -38,6 +40,23 @@ typedef int connman_bool_t; typedef unsigned char connman_uint8_t; typedef unsigned short connman_uint16_t; +struct cb_data { + void *cb; + void *user_data; + void *data; +}; + +static inline struct cb_data *cb_data_new(void *cb, void *user_data) +{ + struct cb_data *ret; + + ret = g_new0(struct cb_data, 1); + ret-cb = cb; + ret-user_data = user_data; + + return ret; +} + #ifdef __cplusplus } #endif -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 11/20] test-session: Add unit test for session_policy_local
From: Daniel Wagner daniel.wag...@bmw-carit.de Use the UID as identification. --- unit/test-session.c | 156 1 file changed, 156 insertions(+) diff --git a/unit/test-session.c b/unit/test-session.c index d6da8d7..4041e88 100644 --- a/unit/test-session.c +++ b/unit/test-session.c @@ -24,11 +24,16 @@ #endif #include stdio.h +#include unistd.h +#include pwd.h +#include sys/types.h #include gdbus.h #include test-connman.h +#define POLICYDIR STORAGEDIR /session_policy_local + enum test_session_state { TEST_SESSION_STATE_0 = 0, TEST_SESSION_STATE_1 = 1, @@ -495,6 +500,154 @@ static gboolean test_session_connect_free_ride(gpointer data) return FALSE; } +static void policy_save(GKeyFile *keyfile, char *pathname) +{ + gchar *data = NULL; + gsize length = 0; + GError *error = NULL; + + data = g_key_file_to_data(keyfile, length, NULL); + + if(!g_file_set_contents(pathname, data, length, error)) { + DBG(Failed to store information: %s, error-message); + g_error_free(error); + g_assert(0); + } + + g_free(data); +} + +static void policy_allowed_bearers(const char *allowed_bearers) +{ + struct passwd *pwd; + uid_t uid; + char *pathname; + GKeyFile *keyfile; + + LOG(update to '%s', allowed_bearers); + + uid = getuid(); + pwd = getpwuid(uid); + g_assert(pwd != NULL); + + pathname = g_strdup_printf(%s/%s, POLICYDIR, pwd-pw_name); + keyfile = g_key_file_new(); + g_key_file_set_string(keyfile, Default, AllowedBearers, + allowed_bearers); + + policy_save(keyfile, pathname); + + g_free(pathname); + g_key_file_free(keyfile); +} + +static void policy_remove_file(void) +{ + struct passwd *pwd; + uid_t uid; + char *pathname; + + uid = getuid(); + pwd = getpwuid(uid); + g_assert(pwd != NULL); + + pathname = g_strdup_printf(%s/%s, POLICYDIR, pwd-pw_name); + unlink(pathname); + g_free(pathname); +} + +static void test_session_policy_notify(struct test_session *session) +{ + enum test_session_state state = get_session_state(session); + enum test_session_state next_state = state; + DBusMessage *msg; + + LOG(state %d session %p %s state %d, state, session, + session-notify_path, session-info-state); + + switch (state) { + case TEST_SESSION_STATE_0: + if (session-info-state == CONNMAN_SESSION_STATE_DISCONNECTED) + next_state = TEST_SESSION_STATE_1; + break; + case TEST_SESSION_STATE_1: + if (session-info-state = CONNMAN_SESSION_STATE_CONNECTED) + next_state = TEST_SESSION_STATE_2; + break; + case TEST_SESSION_STATE_2: + if (session-info-state == CONNMAN_SESSION_STATE_DISCONNECTED) + next_state = TEST_SESSION_STATE_3; + default: + break; + } + + if (state == next_state) + return; + + set_session_state(session, next_state); + + LOG(next_state %d, next_state); + + switch (next_state) { + case TEST_SESSION_STATE_1: + policy_allowed_bearers(ethernet); + + msg = session_connect(session-connection, session); + g_assert(msg != NULL); + dbus_message_unref(msg); + return; + case TEST_SESSION_STATE_2: + policy_allowed_bearers(); + return; + case TEST_SESSION_STATE_3: + policy_remove_file(); + util_session_cleanup(session); + util_idle_call(session-fix, util_quit_loop, + util_session_destroy); + return; + default: + return; + } +} + +static gboolean test_session_policy(gpointer data) +{ + struct test_fix *fix = data; + struct test_session *session; + + /* +* +---+ +* | START | +* +---+ +* | +* | write policy AllowedBearers = ethernet +* v +* +---+ +* | FOO-CONNECTED | +* +---+ +* | +* | write policy AllowedBearers = +* v +* +---+ +* |END| +* +---+ +*/ + + util_session_create(fix, 1); + session = fix-session; + + session-notify_path = g_strdup(/foo); + session-notify = test_session_policy_notify; + + util_session_init(session); + + set_session_state(session, TEST_SESSION_STATE_0); + + policy_allowed_bearers(); + + return FALSE; +} + static connman_bool_t is_online(struct test_fix *fix) { if
[PATCH v1 13/20] session: Add _t postfix to callback typedef
From: Daniel Wagner daniel.wag...@bmw-carit.de Be more consistent with the rest. Also shorten the a bit to verbose name of the callback function. --- include/session.h | 8 plugins/session_policy_local.c | 8 src/session.c | 10 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/session.h b/include/session.h index cf32e48..62c303c 100644 --- a/include/session.h +++ b/include/session.h @@ -59,16 +59,16 @@ struct connman_session_config { GSList *allowed_bearers; }; -typedef int (* connman_session_config_cb) (struct connman_session *session, +typedef int (* connman_session_config_cb_t) (int error, + struct connman_session *session, struct connman_session_config *config, - void *user_data, int err); + void *user_data); struct connman_session_policy { const char *name; int priority; int (*create)(struct connman_session *session, - connman_session_config_cb callback, - void *user_data); + connman_session_config_cb_t cb, void *user_data); void (*destroy)(struct connman_session *session); }; diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 55264ed..0ffa512 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -52,7 +52,7 @@ static GSList *policy_list; struct create_data { struct connman_session *session; - connman_session_config_cb callback; + connman_session_config_cb_t cb; void *user_data; }; @@ -216,7 +216,7 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, config = policy-config; done: - (*data-callback)(data-session, config, data-user_data, err); + (*data-cb)(err, data-session, config, data-user_data); g_free(data); g_free(ident); @@ -224,7 +224,7 @@ done: } static int policy_local_create(struct connman_session *session, - connman_session_config_cb callback, + connman_session_config_cb_t cb, void *user_data) { struct create_data *data; @@ -236,7 +236,7 @@ static int policy_local_create(struct connman_session *session, data = g_new0(struct create_data, 1); data-session = session; - data-callback = callback; + data-cb = cb; data-user_data = user_data; owner = connman_session_get_owner(session); diff --git a/src/session.c b/src/session.c index b7b0a1f..365c71c 100644 --- a/src/session.c +++ b/src/session.c @@ -313,7 +313,7 @@ static void cleanup_user_config(struct user_config *user_config) } static int create_policy_config(struct connman_session *session, - connman_session_config_cb callback, + connman_session_config_cb_t cb, struct user_config *user_config) { struct connman_session_config *config; @@ -326,10 +326,10 @@ static int create_policy_config(struct connman_session *session, return -ENOMEM; } - return callback(session, config, user_config, 0); + return cb(0, session, config, user_config); } - return (*session-policy-create)(session, callback, user_config); + return (*session-policy-create)(session, cb, user_config); } static void probe_policy(struct connman_session_policy *policy) @@ -1616,9 +1616,9 @@ static const GDBusMethodTable session_methods[] = { { }, }; -static int session_create_cb(struct connman_session *session, +static int session_create_cb(int err, struct connman_session *session, struct connman_session_config *config, - void *user_data, int err) + void *user_data) { DBusMessage *reply; struct user_config *user_config = user_data; -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 14/20] session_policy_local: Use callback helpers
From: Daniel Wagner daniel.wag...@bmw-carit.de Use the generic callback helpers to encapsulate struct create_data. In a later patch we will add some more data elemets to struct create_data. That is the reason why it is not remove here. --- plugins/session_policy_local.c | 16 +--- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index 0ffa512..9366cb0 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -52,8 +52,6 @@ static GSList *policy_list; struct create_data { struct connman_session *session; - connman_session_config_cb_t cb; - void *user_data; }; struct policy_data { @@ -183,7 +181,9 @@ static struct policy_data *find_policy_by_session(const char *lsm_ctx) static void selinux_context_reply(const unsigned char *context, void *user_data, int err) { - struct create_data *data = user_data; + struct cb_data *cbd = user_data; + connman_session_config_cb_t cb = cbd-cb; + struct create_data *data = cbd-data; struct policy_data *policy; struct connman_session_config *config = NULL; char *ident = NULL, *ctx = NULL; @@ -216,8 +216,9 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, config = policy-config; done: - (*data-cb)(err, data-session, config, data-user_data); + (*cb)(err, data-session, config, cbd-user_data); + g_free(cbd); g_free(data); g_free(ident); g_free(ctx); @@ -227,6 +228,7 @@ static int policy_local_create(struct connman_session *session, connman_session_config_cb_t cb, void *user_data) { + struct cb_data *cbd = cb_data_new(cb, user_data); struct create_data *data; const char *owner; int err; @@ -234,19 +236,19 @@ static int policy_local_create(struct connman_session *session, DBG(session %p, session); data = g_new0(struct create_data, 1); + cbd-data = data; data-session = session; - data-cb = cb; - data-user_data = user_data; owner = connman_session_get_owner(session); err = connman_dbus_get_selinux_context(connection, owner, selinux_context_reply, - data); + cbd); if (err 0) { connman_error(Could not get SELinux context); g_free(data); + g_free(cbd); return err; } -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 17/20] session_policy_local: Retrieve UID from session user
From: Daniel Wagner daniel.wag...@bmw-carit.de When the session core ask to create a configuration, then we first ask the D-Bus server which UID the session belongs to. If possible we also ask for the SELinux context. Then we try to figure out which file containts the configuration for UID/SElinux identification. The SELinux identification has higher priority than UID. It is possible to run a mixed configuration but not really recommended. There might be dragons. --- plugins/session_policy_local.c | 93 ++ 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index c28b856..aeb4bbf 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -27,6 +27,8 @@ #include string.h #include sys/inotify.h #include sys/stat.h +#include sys/types.h +#include pwd.h #include glib.h @@ -52,12 +54,18 @@ static GSList *policy_list; struct create_data { struct connman_session *session; + char *user; + uid_t uid; + gid_t gid; }; struct policy_data { int refcount; char *filename; char *lsm_ctx; /* The Linux Security Module Context */ + char *user; + uid_t uid; + gid_t gid; struct connman_session *session; struct connman_session_config *config; @@ -72,6 +80,7 @@ static void free_policy(gpointer user_data) g_free(policy-filename); g_free(policy-lsm_ctx); + g_free(policy-user); g_free(policy-config); g_free(policy); } @@ -152,7 +161,8 @@ static struct policy_data *find_policy_by_file(const char *filename) for (list = policy_list; list != NULL; list = list-next) { policy = list-data; - if (g_strcmp0(policy-lsm_ctx, filename) != 0) + if (g_strcmp0(policy-lsm_ctx, filename) != 0 + g_strcmp0(policy-user, filename) != 0) continue; return policy; @@ -161,7 +171,8 @@ static struct policy_data *find_policy_by_file(const char *filename) return NULL; } -static struct policy_data *find_policy_by_session(const char *lsm_ctx) +static struct policy_data *find_policy_by_session(const char *lsm_ctx, + const char *user) { GSList *list; struct policy_data *policy; @@ -169,7 +180,8 @@ static struct policy_data *find_policy_by_session(const char *lsm_ctx) for (list = policy_list; list != NULL; list = list-next) { policy = list-data; - if (g_strcmp0(policy-filename, lsm_ctx) != 0) + if (g_strcmp0(policy-filename, lsm_ctx) != 0 + g_strcmp0(policy-filename, user) != 0) continue; return policy; @@ -203,13 +215,16 @@ static void selinux_context_reply(int error, goto done; } - policy = find_policy_by_session(ident); + policy = find_policy_by_session(ident, data-user); if (policy == NULL) policy = create_policy(); else policy_ref(policy); policy-lsm_ctx = g_strdup(ident); + policy-user = data-user; + policy-uid = data-uid; + policy-gid = data-gid; policy-session = data-session; g_hash_table_replace(session_hash, data-session, policy); @@ -224,6 +239,69 @@ done: g_free(ctx); } +static void get_uid_reply(int error, unsigned int uid, void *user_data) +{ + struct cb_data *cbd = user_data; + connman_session_config_cb_t cb = cbd-cb; + struct create_data *data = cbd-data; + struct policy_data *policy; + const char *owner; + struct passwd *pwd; + struct connman_session_config *config = NULL; + + DBG(session %p uid %d, data-session, uid); + + if (error 0) + goto done; + + errno = 0; + pwd = getpwuid((uid_t)uid); + if (pwd == NULL) { + if (errno != 0) + error = -errno; + else + error = -EINVAL; + goto done; + } + + data-user = g_strdup(pwd-pw_name); + data-uid = pwd-pw_uid; + data-gid = pwd-pw_gid; + + owner = connman_session_get_owner(data-session); + + error = connman_dbus_get_selinux_context(connection, owner, + selinux_context_reply, cbd); + if (error == 0) { + /* +* We are able to ask for a SELinux context. Let's defer the +* creation of the session config until we get the answer +* from D-Bus. +*/ + return; + } + + policy = find_policy_by_session(NULL, data-user); + if (policy == NULL) + policy = create_policy(); + else +
[PATCH v1 20/20] session: Reorder shutdown sequence
From: Daniel Wagner daniel.wag...@bmw-carit.de The core wants to call the destroy function from the plugin. Therefore we need to move __connman_session_cleanup() before the __connman_plugin_cleanup(). We also need to take care not to access the session_hash in remove_policy() function since that table has already been destroyed. --- src/main.c| 2 +- src/session.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index e21d056..0532abe 100644 --- a/src/main.c +++ b/src/main.c @@ -675,11 +675,11 @@ int main(int argc, char *argv[]) __connman_wpad_cleanup(); __connman_dhcpv6_cleanup(); __connman_dhcp_cleanup(); + __connman_session_cleanup(); __connman_plugin_cleanup(); __connman_provider_cleanup(); __connman_connection_cleanup(); __connman_timeserver_cleanup(); - __connman_session_cleanup(); __connman_detect_cleanup(); __connman_proxy_cleanup(); __connman_task_cleanup(); diff --git a/src/session.c b/src/session.c index 365c71c..ce7aa18 100644 --- a/src/session.c +++ b/src/session.c @@ -359,6 +359,9 @@ static void remove_policy(struct connman_session_policy *policy) gpointer key, value; struct connman_session *session; + if (session_hash == NULL) + return; + DBG(policy %p name %s, policy, policy-name); g_hash_table_iter_init(iter, session_hash); -- 1.8.1.3.566.gaa39828 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH v4 13/16] vpn-provider: Add route support in vpn config file
Hi, On Fri, 2013-02-15 at 12:19 +0200, Jukka Rissanen wrote: + family = connman_inet_check_ipaddress(network); + if (family 0) { + DBG(Cannot get address family of %s (%d/%s), network, + family, gai_strerror(family)); + if (strstr(network, :) != NULL) { + DBG(Guessing it is IPv6); + family = AF_INET6; + } else { + DBG(Guessing it is IPv4); + family = AF_INET; + } + } Here we should fail if connman_inet_check_ipaddress() returns something else than AF_INET6 or AF_INET. The function returns 0 if it's not a numeric address. Cheers, Patrik ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 01/16] config: Remove obsolete definition
--- src/config.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/config.c b/src/config.c index 6a5b12c..686d8ce 100644 --- a/src/config.c +++ b/src/config.c @@ -68,8 +68,6 @@ static GSList *protected_services = NULL; static connman_bool_t cleanup = FALSE; -#define INTERNAL_CONFIG_PREFIX __internal - /* Definition of possible strings in the .config files */ #define CONFIG_KEY_NAMEName #define CONFIG_KEY_DESCDescription -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 00/16] VPN provisioning support
Hi, v5 - ignore route if address family cannot be determined in patch 13 v4 - VPN config files are now in VPN_STORAGEDIR which is by default /var/lib/connman-vpn v3: - rebase against current head v2: - Split the patchset into smaller chunks as requested by Wagi - Use the new functions in inotify.c - Documentation clarifications in patch 7 - Added TODO entry to remove the compatibility functions in L2TP and PPTP VPN plugins v1: This patchset adds support for provisioning VPN services from a .config file. The VPN provisioining works the same way as the wifi service provisioning. User can create a config file in /var/lib/connman/vpn directory and information in that file is used to create a provider in connman-vpnd. The VPN config is only read by connman-vpnd process. Cheers, Jukka Jukka Rissanen (16): config: Remove obsolete definition config: Read only wifi config l2tp: Fixed the nodeflate pppd option name l2tp: Added rx and tx bps pppd options l2tp: Use PPPD prefix for pppd specific options pptp: Use PPPD prefix for pppd specific options doc: VPN config file specification storage: Add function to load provider configuration file vpn-provider: Initial .config file support vpn-config: Provision providers from .config file vpn-provider: Type string in provider needs to be in lower case vpn-provider: Remove unprovisioned providers at startup vpn-provider: Add route support in vpn config file vpn-provider: Add extra whitespace TODO: Add note about removal of L2TP and PPTP prefix for PPP options main: Create VPN_STORAGEDIR when starting up Makefile.am | 7 +- TODO | 10 + doc/vpn-config-format.txt | 215 + include/provision.h | 2 +- plugins/wifi.c| 2 +- src/config.c | 8 +- src/connman.h | 1 + src/storage.c | 16 ++ vpn/main.c| 14 ++ vpn/plugins/l2tp.c| 70 -- vpn/plugins/pptp.c| 62 +++-- vpn/vpn-config.c | 598 ++ vpn/vpn-provider.c| 327 ++--- vpn/vpn.h | 11 +- 14 files changed, 1266 insertions(+), 77 deletions(-) create mode 100644 doc/vpn-config-format.txt create mode 100644 vpn/vpn-config.c -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 14/16] vpn-provider: Add extra whitespace
--- vpn/vpn-provider.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index f530348..36db938 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -300,7 +300,7 @@ static void set_user_networks(struct vpn_provider *provider, GSList *networks) GSList *list; for (list = networks; list != NULL; list = g_slist_next(list)) { - struct vpn_route *route= list-data; + struct vpn_route *route = list-data; if (__vpn_provider_append_user_route(provider, route-family, route-network, -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 16/16] main: Create VPN_STORAGEDIR when starting up
Eventually all VPN directories from STORAGEDIR is to be migrated into VPN_STORAGEDIR --- vpn/main.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/vpn/main.c b/vpn/main.c index 8fd830c..d72fa74 100644 --- a/vpn/main.c +++ b/vpn/main.c @@ -273,12 +273,22 @@ int main(int argc, char *argv[]) perror(Failed to create state directory); } + /* +* At some point the VPN stuff is migrated into VPN_STORAGEDIR +* and this mkdir() call can be removed. +*/ if (mkdir(STORAGEDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) 0) { if (errno != EEXIST) perror(Failed to create storage directory); } + if (mkdir(VPN_STORAGEDIR, S_IRUSR | S_IWUSR | S_IXUSR | + S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) 0) { + if (errno != EEXIST) + perror(Failed to create VPN storage directory); + } + umask(0077); main_loop = g_main_loop_new(NULL, FALSE); -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 04/16] l2tp: Added rx and tx bps pppd options
--- vpn/plugins/l2tp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c index dce0e21..2355357 100644 --- a/vpn/plugins/l2tp.c +++ b/vpn/plugins/l2tp.c @@ -76,6 +76,8 @@ struct { } pppd_options[] = { { L2TP.User, name, OPT_ALL, NULL, OPT_STRING }, { L2TP.BPS, bps, OPT_L2, NULL, OPT_STRING }, + { L2TP.TXBPS, tx bps, OPT_L2, NULL, OPT_STRING }, + { L2TP.RXBPS, rx bps, OPT_L2, NULL, OPT_STRING }, { L2TP.LengthBit, length bit, OPT_L2, NULL, OPT_STRING }, { L2TP.Challenge, challenge, OPT_L2, NULL, OPT_STRING }, { L2TP.DefaultRoute, defaultroute, OPT_L2, NULL, OPT_STRING }, -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 03/16] l2tp: Fixed the nodeflate pppd option name
--- vpn/plugins/l2tp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c index 15f5128..dce0e21 100644 --- a/vpn/plugins/l2tp.c +++ b/vpn/plugins/l2tp.c @@ -107,7 +107,7 @@ struct { { L2TP.NoBSDComp, nobsdcomp, OPT_PPPD, NULL, OPT_BOOL }, { L2TP.NoPcomp, nopcomp, OPT_PPPD, NULL, OPT_BOOL }, { L2TP.UseAccomp, accomp, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.NoDeflate, nodeflatey, OPT_PPPD, NULL, OPT_BOOL }, + { L2TP.NoDeflate, nodeflate, OPT_PPPD, NULL, OPT_BOOL }, { L2TP.ReqMPPE, require-mppe, OPT_PPPD, NULL, OPT_BOOL }, { L2TP.ReqMPPE40, require-mppe-40, OPT_PPPD, NULL, OPT_BOOL }, { L2TP.ReqMPPE128, require-mppe-128, OPT_PPPD, NULL, OPT_BOOL }, -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 05/16] l2tp: Use PPPD prefix for pppd specific options
For backward compatibility purposes, support also the L2TP prefix for PPPD options. --- vpn/plugins/l2tp.c | 68 +- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c index 2355357..e0b2b04 100644 --- a/vpn/plugins/l2tp.c +++ b/vpn/plugins/l2tp.c @@ -98,23 +98,23 @@ struct { { L2TP.Rand Source, rand source, OPT_L2G, NULL, OPT_STRING }, { L2TP.IPsecSaref, ipsec saref, OPT_L2G, NULL, OPT_STRING }, { L2TP.Port, port, OPT_L2G, NULL, OPT_STRING }, - { L2TP.EchoFailure, lcp-echo-failure, OPT_PPPD, 0, OPT_STRING }, - { L2TP.EchoInterval, lcp-echo-interval, OPT_PPPD, 0, OPT_STRING }, - { L2TP.Debug, debug, OPT_PPPD, NULL, OPT_STRING }, - { L2TP.RefuseEAP, refuse-eap, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.RefusePAP, refuse-pap, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.RefuseCHAP, refuse-chap, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.RefuseMSCHAP, refuse-mschap, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.RefuseMSCHAP2, refuse-mschapv2, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.NoBSDComp, nobsdcomp, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.NoPcomp, nopcomp, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.UseAccomp, accomp, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.NoDeflate, nodeflate, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.ReqMPPE, require-mppe, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.ReqMPPE40, require-mppe-40, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.ReqMPPE128, require-mppe-128, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.ReqMPPEStateful, mppe-stateful, OPT_PPPD, NULL, OPT_BOOL }, - { L2TP.NoVJ, no-vj-comp, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.EchoFailure, lcp-echo-failure, OPT_PPPD, 0, OPT_STRING }, + { PPPD.EchoInterval, lcp-echo-interval, OPT_PPPD, 0, OPT_STRING }, + { PPPD.Debug, debug, OPT_PPPD, NULL, OPT_STRING }, + { PPPD.RefuseEAP, refuse-eap, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.RefusePAP, refuse-pap, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.RefuseCHAP, refuse-chap, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.RefuseMSCHAP, refuse-mschap, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.RefuseMSCHAP2, refuse-mschapv2, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.NoBSDComp, nobsdcomp, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.NoPcomp, nopcomp, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.UseAccomp, accomp, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.NoDeflate, nodeflate, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.ReqMPPE, require-mppe, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.ReqMPPE40, require-mppe-40, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.ReqMPPE128, require-mppe-128, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.ReqMPPEStateful, mppe-stateful, OPT_PPPD, NULL, OPT_BOOL }, + { PPPD.NoVJ, no-vj-comp, OPT_PPPD, NULL, OPT_BOOL }, }; static DBusConnection *connection; @@ -259,14 +259,40 @@ static int l2tp_notify(DBusMessage *msg, struct vpn_provider *provider) static int l2tp_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *option; + connman_bool_t l2tp_option, pppd_option; int i; for (i = 0; i (int)ARRAY_SIZE(pppd_options); i++) { - if (strncmp(pppd_options[i].cm_opt, L2TP., 5) == 0) { + l2tp_option = pppd_option = FALSE; + + if (strncmp(pppd_options[i].cm_opt, L2TP., 5) == 0) + l2tp_option = TRUE; + + if (strncmp(pppd_options[i].cm_opt, PPPD., 5) == 0) + pppd_option = TRUE; + + if (l2tp_option == TRUE || pppd_option == TRUE) { option = vpn_provider_get_string(provider, - pppd_options[i].cm_opt); - if (option == NULL) - continue; + pppd_options[i].cm_opt); + if (option == NULL) { + /* +* Check if the option prefix is L2TP as the +* PPPD options were using L2TP prefix earlier. +*/ + char *l2tp_str; + + if (pppd_option == FALSE) + continue; + + l2tp_str = g_strdup_printf(L2TP.%s, + pppd_options[i].cm_opt[5]); + option = vpn_provider_get_string(provider, + l2tp_str); + g_free(l2tp_str); + + if (option == NULL) + continue; + } g_key_file_set_string(keyfile,
[PATCH v5 06/16] pptp: Use PPPD prefix for pppd specific options
For backward compatibility purposes, support also the PPTP prefix for PPPD options. --- vpn/plugins/pptp.c | 62 ++ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c index 7269629..daa6ca3 100644 --- a/vpn/plugins/pptp.c +++ b/vpn/plugins/pptp.c @@ -63,21 +63,21 @@ struct { int type; } pptp_options[] = { { PPTP.User, user, NULL, OPT_STRING }, - { PPTP.EchoFailure, lcp-echo-failure, 0, OPT_STRING }, - { PPTP.EchoInterval, lcp-echo-interval, 0, OPT_STRING }, - { PPTP.Debug, debug, NULL, OPT_STRING }, - { PPTP.RefuseEAP, refuse-eap, NULL, OPT_BOOL }, - { PPTP.RefusePAP, refuse-pap, NULL, OPT_BOOL }, - { PPTP.RefuseCHAP, refuse-chap, NULL, OPT_BOOL }, - { PPTP.RefuseMSCHAP, refuse-mschap, NULL, OPT_BOOL }, - { PPTP.RefuseMSCHAP2, refuse-mschapv2, NULL, OPT_BOOL }, - { PPTP.NoBSDComp, nobsdcomp, NULL, OPT_BOOL }, - { PPTP.NoDeflate, nodeflate, NULL, OPT_BOOL }, - { PPTP.RequirMPPE, require-mppe, NULL, OPT_BOOL }, - { PPTP.RequirMPPE40, require-mppe-40, NULL, OPT_BOOL }, - { PPTP.RequirMPPE128, require-mppe-128, NULL, OPT_BOOL }, - { PPTP.RequirMPPEStateful, mppe-stateful, NULL, OPT_BOOL }, - { PPTP.NoVJ, no-vj-comp, NULL, OPT_BOOL }, + { PPPD.EchoFailure, lcp-echo-failure, 0, OPT_STRING }, + { PPPD.EchoInterval, lcp-echo-interval, 0, OPT_STRING }, + { PPPD.Debug, debug, NULL, OPT_STRING }, + { PPPD.RefuseEAP, refuse-eap, NULL, OPT_BOOL }, + { PPPD.RefusePAP, refuse-pap, NULL, OPT_BOOL }, + { PPPD.RefuseCHAP, refuse-chap, NULL, OPT_BOOL }, + { PPPD.RefuseMSCHAP, refuse-mschap, NULL, OPT_BOOL }, + { PPPD.RefuseMSCHAP2, refuse-mschapv2, NULL, OPT_BOOL }, + { PPPD.NoBSDComp, nobsdcomp, NULL, OPT_BOOL }, + { PPPD.NoDeflate, nodeflate, NULL, OPT_BOOL }, + { PPPD.RequirMPPE, require-mppe, NULL, OPT_BOOL }, + { PPPD.RequirMPPE40, require-mppe-40, NULL, OPT_BOOL }, + { PPPD.RequirMPPE128, require-mppe-128, NULL, OPT_BOOL }, + { PPPD.RequirMPPEStateful, mppe-stateful, NULL, OPT_BOOL }, + { PPPD.NoVJ, no-vj-comp, NULL, OPT_BOOL }, }; static DBusConnection *connection; @@ -218,14 +218,40 @@ static int pptp_notify(DBusMessage *msg, struct vpn_provider *provider) static int pptp_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *option; + connman_bool_t pptp_option, pppd_option; int i; for (i = 0; i (int)ARRAY_SIZE(pptp_options); i++) { - if (strncmp(pptp_options[i].cm_opt, PPTP., 5) == 0) { + pptp_option = pppd_option = FALSE; + + if (strncmp(pptp_options[i].cm_opt, PPTP., 5) == 0) + pptp_option = TRUE; + + if (strncmp(pptp_options[i].cm_opt, PPPD., 5) == 0) + pppd_option = TRUE; + + if (pptp_option == TRUE || pppd_option == TRUE) { option = vpn_provider_get_string(provider, pptp_options[i].cm_opt); - if (option == NULL) - continue; + if (option == NULL) { + /* +* Check if the option prefix is PPTP as the +* PPPD options were using PPTP prefix earlier. +*/ + char *pptp_str; + + if (pppd_option == FALSE) + continue; + + pptp_str = g_strdup_printf(PPTP.%s, + pptp_options[i].cm_opt[5]); + option = vpn_provider_get_string(provider, + pptp_str); + g_free(pptp_str); + + if (option == NULL) + continue; + } g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 08/16] storage: Add function to load provider configuration file
--- Makefile.am | 4 src/connman.h | 1 + src/storage.c | 16 3 files changed, 21 insertions(+) diff --git a/Makefile.am b/Makefile.am index 26081d8..2490f9e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -152,6 +152,7 @@ plugindir = $(libdir)/connman/plugins scriptdir = $(libdir)/connman/scripts storagedir = $(localstatedir)/lib/connman +vpn_storagedir = $(localstatedir)/lib/connman-vpn configdir = ${sysconfdir}/connman @@ -176,6 +177,7 @@ AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ -DPLUGINDIR=\$(build_plugindir)\ \ -DSCRIPTDIR=\$(build_scriptdir)\ \ -DSTORAGEDIR=\$(storagedir)\ \ + -DVPN_STORAGEDIR=\$(vpn_storagedir)\ \ -DCONFIGDIR=\$(configdir)\ if VPN @@ -191,6 +193,7 @@ src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ -DPLUGINDIR=\$(build_plugindir)\ \ -DSCRIPTDIR=\$(build_scriptdir)\ \ -DSTORAGEDIR=\$(storagedir)\ \ + -DVPN_STORAGEDIR=\$(vpn_storagedir)\ \ -DCONFIGDIR=\$(configdir)\ \ -I$(builddir)/src @@ -205,6 +208,7 @@ vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \ -DPLUGINDIR=\$(build_vpn_plugindir)\ \ -DSCRIPTDIR=\$(build_scriptdir)\ \ -DSTORAGEDIR=\$(storagedir)\ \ + -DVPN_STORAGEDIR=\$(vpn_storagedir)\ \ -DCONFIGDIR=\$(configdir)\ \ -I$(builddir)/vpn diff --git a/src/connman.h b/src/connman.h index 95e5c8a..49eafd3 100644 --- a/src/connman.h +++ b/src/connman.h @@ -206,6 +206,7 @@ int __connman_storage_save_global(GKeyFile *keyfile); void __connman_storage_delete_global(void); GKeyFile *__connman_storage_load_config(const char *ident); +GKeyFile *__connman_storage_load_provider_config(const char *ident); GKeyFile *__connman_storage_open_service(const char *ident); int __connman_storage_save_service(GKeyFile *keyfile, const char *ident); diff --git a/src/storage.c b/src/storage.c index 47822da..1ceafb9 100644 --- a/src/storage.c +++ b/src/storage.c @@ -147,6 +147,22 @@ GKeyFile *__connman_storage_load_config(const char *ident) return keyfile; } +GKeyFile *__connman_storage_load_provider_config(const char *ident) +{ + gchar *pathname; + GKeyFile *keyfile = NULL; + + pathname = g_strdup_printf(%s/%s.config, VPN_STORAGEDIR, ident); + if (pathname == NULL) + return NULL; + + keyfile = storage_load(pathname); + + g_free(pathname); + + return keyfile; +} + GKeyFile *__connman_storage_open_service(const char *service_id) { gchar *pathname; -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 10/16] vpn-config: Provision providers from .config file
--- Makefile.am | 3 +- vpn/main.c | 4 + vpn/vpn-config.c | 598 +++ vpn/vpn.h| 3 + 4 files changed, 607 insertions(+), 1 deletion(-) create mode 100644 vpn/vpn-config.c diff --git a/Makefile.am b/Makefile.am index 2490f9e..3265d83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -124,7 +124,8 @@ vpn_connman_vpnd_SOURCES = $(gdbus_sources) $(builtin_vpn_sources) \ vpn/vpn-provider.h vpn/vpn-rtnl.h \ vpn/vpn-ipconfig.c src/inet.c vpn/vpn-rtnl.c \ src/dbus.c src/storage.c src/ipaddress.c src/agent.c \ - vpn/vpn-agent.c vpn/vpn-agent.h + vpn/vpn-agent.c vpn/vpn-agent.h src/inotify.c \ + vpn/vpn-config.c vpn_connman_vpnd_LDADD = $(builtin_vpn_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \ @GNUTLS_LIBS@ -lresolv -ldl diff --git a/vpn/main.c b/vpn/main.c index a17f522..8fd830c 100644 --- a/vpn/main.c +++ b/vpn/main.c @@ -308,6 +308,7 @@ int main(int argc, char *argv[]) else config_init(option_config); + __connman_inotify_init(); __connman_agent_init(); __vpn_provider_init(option_routes); __vpn_manager_init(); @@ -315,6 +316,7 @@ int main(int argc, char *argv[]) __vpn_rtnl_init(); __connman_task_init(); __connman_plugin_init(option_plugin, option_noplugin); + __vpn_config_init(); __vpn_rtnl_start(); @@ -325,6 +327,7 @@ int main(int argc, char *argv[]) g_source_remove(signal); + __vpn_config_cleanup(); __connman_plugin_cleanup(); __connman_task_cleanup(); __vpn_rtnl_cleanup(); @@ -332,6 +335,7 @@ int main(int argc, char *argv[]) __vpn_manager_cleanup(); __vpn_provider_cleanup(); __connman_agent_cleanup(); + __connman_inotify_cleanup(); __connman_dbus_cleanup(); __connman_log_cleanup(FALSE); diff --git a/vpn/vpn-config.c b/vpn/vpn-config.c new file mode 100644 index 000..1ece7e9 --- /dev/null +++ b/vpn/vpn-config.c @@ -0,0 +1,598 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include stdio.h +#include unistd.h +#include string.h +#include sys/vfs.h +#include sys/inotify.h +#include glib.h + +#include connman/log.h +#include ../src/connman.h + +#include vpn.h + +enum what { + REMOVE = 1, + ADD = 2, +}; + +struct vpn_config_provider { + char *provider_identifier; + char *ident; + char *name; + char *type; + char *host; + char *domain; + char *networks; + GHashTable *setting_strings; + + char *config_ident; /* file prefix */ + char *config_entry; /* entry name */ +}; + +struct vpn_config { + char *ident; + char *name; + char *description; + connman_bool_t protected; + GHashTable *provider_table; +}; + +static GHashTable *config_table = NULL; +static GSList *protected_providers = NULL; + +static connman_bool_t cleanup = FALSE; + +/* Definition of possible strings in the .config files */ +#define CONFIG_KEY_NAMEName +#define CONFIG_KEY_DESCDescription +#define CONFIG_KEY_PROTProtected + +static const char *config_possible_keys[] = { + CONFIG_KEY_NAME, + CONFIG_KEY_DESC, + CONFIG_KEY_PROT, + NULL, +}; + +static void unregister_config(gpointer data) +{ + struct vpn_config *config = data; + + connman_info(Removing configuration %s, config-ident); + + g_hash_table_destroy(config-provider_table); + + g_free(config-description); + g_free(config-name); + g_free(config-ident); + g_free(config); +} + +static void unregister_provider(gpointer data) +{ + struct vpn_config_provider *config_provider = data; + struct vpn_provider *provider; + char *provider_id; + + if (cleanup == TRUE) + goto free_only; + + provider_id = config_provider-provider_identifier; + + connman_info(Removing provider configuration %s provider %s, +
[PATCH v5 11/16] vpn-provider: Type string in provider needs to be in lower case
--- vpn/vpn-provider.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index f6753b9..c80027d 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -1929,7 +1929,7 @@ int vpn_provider_set_string(struct vpn_provider *provider, if (g_str_equal(key, Type) == TRUE) { g_free(provider-type); - provider-type = g_strdup(value); + provider-type = g_ascii_strdown(value, -1); } else if (g_str_equal(key, Name) == TRUE) { g_free(provider-name); provider-name = g_strdup(value); -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 12/16] vpn-provider: Remove unprovisioned providers at startup
Check if there are any providers that were provisioned but their .config file is removed. If such providers are found, then remove the provider files from file system. --- vpn/vpn-provider.c | 80 +- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index c80027d..6750d6b 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -81,6 +81,8 @@ struct vpn_provider { char **nameservers; int what_changed; guint notify_id; + char *config_file; + char *config_entry; }; static void free_route(gpointer data) @@ -809,6 +811,15 @@ static int vpn_provider_save(struct vpn_provider *provider) } } + if (provider-config_file != NULL strlen(provider-config_file) 0) + g_key_file_set_string(keyfile, provider-identifier, + Config.file, provider-config_file); + + if (provider-config_entry != NULL + strlen(provider-config_entry) 0) + g_key_file_set_string(keyfile, provider-identifier, + Config.ident, provider-config_entry); + if (provider-driver != NULL provider-driver-save != NULL) provider-driver-save(provider, keyfile); @@ -922,6 +933,8 @@ static void provider_destruct(struct vpn_provider *provider) __vpn_ipconfig_unref(provider-ipconfig_ipv6); g_strfreev(provider-host_ip); + g_free(provider-config_file); + g_free(provider-config_entry); g_free(provider); } @@ -1833,6 +1846,9 @@ int __vpn_provider_create_from_config(GHashTable *settings, provider-name = g_strdup(name); provider-type = g_ascii_strdown(type, -1); + provider-config_file = g_strdup(config_ident); + provider-config_entry = g_strdup(config_entry); + if (provider_register(provider) == 0) vpn_provider_load(provider); @@ -2326,6 +2342,67 @@ static struct connman_agent_driver agent_driver = { .remove = agent_remove, }; +static void remove_unprovisioned_providers() +{ + gchar **providers; + GKeyFile *keyfile, *configkeyfile; + char *file, *section; + int i = 0; + + providers = __connman_storage_get_providers(); + if (providers == NULL) + return; + + for (; providers[i] != NULL; i++) { + char *group = providers[i] + sizeof(provider_) - 1; + file = section = NULL; + keyfile = configkeyfile = NULL; + + keyfile = __connman_storage_load_provider(group); + if (keyfile == NULL) + continue; + + file = g_key_file_get_string(keyfile, group, + Config.file, NULL); + if (file == NULL) + goto next; + + section = g_key_file_get_string(keyfile, group, + Config.ident, NULL); + if (section == NULL) + goto next; + + configkeyfile = __connman_storage_load_provider_config(file); + if (configkeyfile == NULL) { + /* +* Config file is missing, remove the provisioned +* service. +*/ + __connman_storage_remove_provider(group); + goto next; + } + + if (g_key_file_has_group(configkeyfile, section) == FALSE) + /* +* Config section is missing, remove the provisioned +* service. +*/ + __connman_storage_remove_provider(group); + + next: + if (keyfile != NULL) + g_key_file_free(keyfile); + + if (configkeyfile != NULL) + g_key_file_free(configkeyfile); + + g_free(section); + g_free(file); + } + + g_strfreev(providers); +} + int __vpn_provider_init(gboolean do_routes) { int err; @@ -2343,9 +2420,10 @@ int __vpn_provider_init(gboolean do_routes) connection = connman_dbus_get_connection(); + remove_unprovisioned_providers(); + provider_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, unregister_provider); - return 0; } -- 1.7.11.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v5 13/16] vpn-provider: Add route support in vpn config file
--- vpn/vpn-provider.c | 99 +- vpn/vpn.h | 3 +- 2 files changed, 86 insertions(+), 16 deletions(-) diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index 6750d6b..f530348 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -237,13 +237,9 @@ static GSList *read_route_dict(GSList *routes, DBusMessageIter *dicts) if (family 0) { DBG(Cannot get address family of %s (%d/%s), network, family, gai_strerror(family)); - if (strstr(network, :) != NULL) { - DBG(Guessing it is IPv6); - family = AF_INET6; - } else { - DBG(Guessing it is IPv4); - family = AF_INET; - } + + g_free(route); + return routes; } } else { switch (family) { @@ -308,7 +304,7 @@ static void set_user_networks(struct vpn_provider *provider, GSList *networks) if (__vpn_provider_append_user_route(provider, route-family, route-network, - route-netmask) != 0) + route-netmask, route-gateway) != 0) break; } } @@ -545,12 +541,15 @@ void __vpn_provider_append_properties(struct vpn_provider *provider, } int __vpn_provider_append_user_route(struct vpn_provider *provider, - int family, const char *network, const char *netmask) + int family, const char *network, + const char *netmask, const char *gateway) { struct vpn_route *route; - char *key = g_strdup_printf(%d/%s/%s, family, network, netmask); + char *key = g_strdup_printf(%d/%s/%s/%s, family, network, + netmask, gateway != NULL ? gateway : ); - DBG(family %d network %s netmask %s, family, network, netmask); + DBG(family %d network %s netmask %s gw %s, family, network, + netmask, gateway); route = g_hash_table_lookup(provider-user_routes, key); if (route == NULL) { @@ -563,6 +562,7 @@ int __vpn_provider_append_user_route(struct vpn_provider *provider, route-family = family; route-network = g_strdup(network); route-netmask = g_strdup(netmask); + route-gateway = g_strdup(gateway); g_hash_table_replace(provider-user_routes, key, route); } else @@ -1795,7 +1795,75 @@ static const char *get_string(GHashTable *settings, const char *key) static GSList *parse_user_networks(const char *network_str) { - return NULL; + GSList *networks = NULL; + char **elems = g_strsplit(network_str, ,, 0); + int i = 0; + + if (elems == NULL) + return NULL; + + while (elems[i] != NULL) { + struct vpn_route *vpn_route; + char *network, *netmask, *gateway; + int family; + char **route; + + route = g_strsplit(elems[i], /, 0); + if (route == NULL) + goto next; + + network = route[0]; + if (network == NULL || network[0] == '\0') + goto next; + + family = connman_inet_check_ipaddress(network); + if (family 0) { + DBG(Cannot get address family of %s (%d/%s), network, + family, gai_strerror(family)); + + goto next; + } + + switch (family) { + case AF_INET: + break; + case AF_INET6: + break; + default: + DBG(Unsupported address family %d, family); + goto next; + } + + netmask = route[1]; + if (netmask == NULL || netmask[0] == '\0') + goto next; + + gateway = route[2]; + + vpn_route = g_try_new0(struct vpn_route, 1); + if (vpn_route == NULL) { + g_strfreev(route); + break; + } + + vpn_route-family = family; + vpn_route-network = g_strdup(network); + vpn_route-netmask = g_strdup(netmask); + vpn_route-gateway = g_strdup(gateway); + + DBG(route %s/%s%s%s, network, netmask, + gateway ? via : , gateway ? gateway : ); + + networks = g_slist_prepend(networks, vpn_route); + + next: + g_strfreev(route); +