Re: Pre-configuring an ethernet interface

2013-02-18 Thread Jukka Rissanen

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

2013-02-18 Thread Patrik Flykt
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

2013-02-18 Thread Patrik Flykt
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

2013-02-18 Thread Patrik Flykt
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

2013-02-18 Thread Patrik Flykt
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Daniel Wagner
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

2013-02-18 Thread Patrik Flykt

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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
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

2013-02-18 Thread Jukka Rissanen
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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
---
 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

2013-02-18 Thread Jukka Rissanen
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

2013-02-18 Thread Jukka Rissanen
---
 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);
+