[PATCH v2 5/6] vpnc: Implement VPN agent support
by Jussi Laakkonen
This adds VPN agent support for VPNC plugin. IPSec.Secret,
Xauth.Username and Xauth.Password are queried from agent if not set in
.config of the VPN provider.
By default, VPNC does not save the credentials to provider config. The
VPNC credentials stored by vpn-provider.c in the provider settings
strings are cleared after run_connect() has finished.
The values of IPSec.Secret, Xauth.Username and Xauth.Password are set to
"-" in order to get them retrieved via VPN agent at next connect request.
The credentials read from .config file are not being reset as the
immutable value of them is checked first. This approach supports also
partially defined credentials in .config, leaving some of them to be
retrieved using a VPN agent. The immutable values are sent as
informational, passwords are changed to "********" to hide them since
the values cannot be changed.
The approach for setting the credentials to "-" follows the approach of
OpenVPN plugin, where credential set as "-" is retrieved over management
interface.
If the credential has something else than "-" set it is forwarded to VPN
agent as old information, if at least one of the credentials is missing.
In this case request_input_credentials() is called and a message is sent
to VPN agent if any. request_input_credentials_reply() handles the
message sent by VPN agent, or errors (Error.Canceled = ECONNABORTED and
Error.Timeout = ETIMEDOUT) from VPN_AGENT_INTERFACE. vc_connect_done()
is invoked to call the callback function, which is executed only once,
with the error code, if any. In case of success, run_connect() is called
and VPN is attempted to connect.
When vc_notify() is called, it retrieves the plugin data from provider
and utilizes its callback by calling vc_connect_done() with the proper
error code, 0 being success.
If plugin dies or is disconnected, vc_died() handles the shutdown by
canceling all agent requests and calls vpn_died(). Last, the data
allocated for the connection is free'd.
---
Changes since V2:
* Remove testing debug messages that reveal secret and password.
* Set to send immutable values as informational to VPN agent. Also
hide immutable passwords as "********" when sending to VPN agent as
informational.
vpn/plugins/vpnc.c | 463 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 433 insertions(+), 30 deletions(-)
diff --git a/vpn/plugins/vpnc.c b/vpn/plugins/vpnc.c
index 87a746cc..05eeb283 100644
--- a/vpn/plugins/vpnc.c
+++ b/vpn/plugins/vpnc.c
@@ -39,15 +39,18 @@
#include <connman/task.h>
#include <connman/ipconfig.h>
#include <connman/dbus.h>
+#include <connman/agent.h>
+#include <connman/setting.h>
+#include <connman/vpn-dbus.h>
#include "../vpn-provider.h"
+#include "../vpn-agent.h"
#include "vpn.h"
+#include "../vpn.h"
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-static DBusConnection *connection;
-
enum {
OPT_STRING = 1,
OPT_BOOLEAN = 2,
@@ -83,14 +86,58 @@ struct {
true },
};
+struct vc_private_data {
+ struct vpn_provider *provider;
+ struct connman_task *task;
+ char *if_name;
+ vpn_provider_connect_cb_t cb;
+ void *user_data;
+};
+
+static void vc_connect_done(struct vc_private_data *data, int err)
+{
+ DBG("data %p err %d", data, err);
+
+ if (data && data->cb) {
+ vpn_provider_connect_cb_t cb = data->cb;
+ void *user_data = data->user_data;
+
+ /* Make sure we don't invoke this callback twice */
+ data->cb = NULL;
+ data->user_data = NULL;
+ cb(data->provider, user_data, err);
+ }
+}
+
+static void free_private_data(struct vc_private_data *data)
+{
+ DBG("data %p", data);
+
+ if (!data || !data->provider)
+ return;
+
+ DBG("provider %p", data->provider);
+
+ if (vpn_provider_get_plugin_data(data->provider) == data)
+ vpn_provider_set_plugin_data(data->provider, NULL);
+
+ vpn_provider_unref(data->provider);
+
+ g_free(data->if_name);
+ g_free(data);
+}
+
static int vc_notify(DBusMessage *msg, struct vpn_provider *provider)
{
DBusMessageIter iter, dict;
char *address = NULL, *netmask = NULL, *gateway = NULL;
struct connman_ipaddress *ipaddress;
const char *reason, *key, *value;
+ struct vc_private_data *data;
int type;
+ data = vpn_provider_get_plugin_data(provider);
+
dbus_message_iter_init(msg, &iter);
type = dbus_message_iter_get_arg_type(&iter);
@@ -104,11 +151,14 @@ static int vc_notify(DBusMessage *msg, struct vpn_provider *provider)
if (!provider) {
connman_error("No provider found");
+ vc_connect_done(data, ENOENT);
return VPN_STATE_FAILURE;
}
- if (strcmp(reason, "connect"))
+ if (g_strcmp0(reason, "connect")) {
+ vc_connect_done(data, EIO);
return VPN_STATE_DISCONNECT;
+ }
dbus_message_iter_recurse(&iter, &dict);
@@ -160,7 +210,7 @@ static int vc_notify(DBusMessage *msg, struct vpn_provider *provider)
g_free(address);
g_free(netmask);
g_free(gateway);
-
+ vc_connect_done(data, EIO);
return VPN_STATE_FAILURE;
}
@@ -172,6 +222,7 @@ static int vc_notify(DBusMessage *msg, struct vpn_provider *provider)
g_free(gateway);
connman_ipaddress_free(ipaddress);
+ vc_connect_done(data, 0);
return VPN_STATE_CONNECT;
}
@@ -280,27 +331,45 @@ static int vc_save(struct vpn_provider *provider, GKeyFile *keyfile)
return 0;
}
-static int vc_connect(struct vpn_provider *provider,
- struct connman_task *task, const char *if_name,
- vpn_provider_connect_cb_t cb, const char *dbus_sender,
- void *user_data)
+static void vc_died(struct connman_task *task, int exit_code, void *user_data)
{
- const char *option;
- int err = 0, fd;
+ struct vc_private_data *data = user_data;
- option = vpn_provider_get_string(provider, "Host");
- if (!option) {
- connman_error("Host not set; cannot enable VPN");
- err = -EINVAL;
- goto done;
- }
- option = vpn_provider_get_string(provider, "VPNC.IPSec.ID");
- if (!option) {
- connman_error("Group not set; cannot enable VPN");
- err = -EINVAL;
- goto done;
+ DBG("task %p data %p exit_code %d user_data %p", task, data, exit_code,
+ user_data);
+
+ if (!data)
+ return;
+
+ if (data->provider) {
+ connman_agent_cancel(data->provider);
+
+ if (task)
+ vpn_died(task, exit_code, data->provider);
}
+ free_private_data(data);
+}
+
+static int run_connect(struct vc_private_data *data)
+{
+ struct vpn_provider *provider;
+ struct connman_task *task;
+ const char *credentials[] = {"VPNC.IPSec.Secret", "VPNC.Xauth.Username",
+ "VPNC.Xauth.Password", NULL};
+ const char *if_name;
+ const char *option;
+ int err;
+ int fd;
+ int i;
+
+ provider = data->provider;
+ task = data->task;
+ if_name = data->if_name;
+
+ DBG("provider %p task %p interface %s user_data %p", provider, task,
+ if_name, data->user_data);
+
connman_task_add_argument(task, "--non-inter", NULL);
connman_task_add_argument(task, "--no-detach", NULL);
@@ -323,8 +392,7 @@ static int vc_connect(struct vpn_provider *provider,
connman_task_add_argument(task, "-", NULL);
- err = connman_task_run(task, vpn_died, provider,
- &fd, NULL, NULL);
+ err = connman_task_run(data->task, vc_died, data, &fd, NULL, NULL);
if (err < 0) {
connman_error("vpnc failed to start");
err = -EIO;
@@ -333,15 +401,354 @@ static int vc_connect(struct vpn_provider *provider,
err = vc_write_config_data(provider, fd);
- close(fd);
+ if (err) {
+ DBG("config write error %s", strerror(err));
+ goto done;
+ }
+
+ err = -EINPROGRESS;
done:
- if (cb)
- cb(provider, user_data, err);
+ close(fd);
+
+ /*
+ * Clear out credentials if they are non-immutable. If this is called
+ * directly from vc_connect() all credentials are read from config and
+ * are set as immutable, so no change is done. In case a VPN agent is
+ * used these values should be reset to "-" in order to retrieve them
+ * from VPN agent next time VPN connection is established. This supports
+ * then partially defined credentials in .config and some can be
+ * retrieved using an agent.
+ */
+ for (i = 0; credentials[i]; i++) {
+ const char *key = credentials[i];
+ if (!vpn_provider_get_string_immutable(provider, key))
+ vpn_provider_set_string(provider, key, "-");
+ }
return err;
}
+static void request_input_append_mandatory(DBusMessageIter *iter,
+ void *user_data)
+{
+ char *str = "string";
+
+ connman_dbus_dict_append_basic(iter, "Type",
+ DBUS_TYPE_STRING, &str);
+ str = "mandatory";
+ connman_dbus_dict_append_basic(iter, "Requirement",
+ DBUS_TYPE_STRING, &str);
+
+ if (!user_data)
+ return;
+
+ str = user_data;
+ connman_dbus_dict_append_basic(iter, "Value", DBUS_TYPE_STRING, &str);
+}
+
+static void request_input_append_password(DBusMessageIter *iter,
+ void *user_data)
+{
+ char *str = "password";
+
+ connman_dbus_dict_append_basic(iter, "Type",
+ DBUS_TYPE_STRING, &str);
+ str = "mandatory";
+ connman_dbus_dict_append_basic(iter, "Requirement",
+ DBUS_TYPE_STRING, &str);
+
+ if (!user_data)
+ return;
+
+ str = user_data;
+ connman_dbus_dict_append_basic(iter, "Value", DBUS_TYPE_STRING, &str);
+}
+
+static void request_input_append_informational(DBusMessageIter *iter,
+ void *user_data)
+{
+ char *str = "password";
+
+ connman_dbus_dict_append_basic(iter, "Type",
+ DBUS_TYPE_STRING, &str);
+ str = "informational";
+ connman_dbus_dict_append_basic(iter, "Requirement",
+ DBUS_TYPE_STRING, &str);
+
+ if (!user_data)
+ return;
+
+ str = user_data;
+ connman_dbus_dict_append_basic(iter, "Value", DBUS_TYPE_STRING, &str);
+}
+
+static void request_input_append_to_dict(struct vpn_provider *provider,
+ DBusMessageIter *dict,
+ connman_dbus_append_cb_t function_cb, const char *key)
+{
+ const char *str;
+ bool immutable = false;
+
+ if (!provider || !dict || !function_cb || !key)
+ return;
+
+ str = vpn_provider_get_string(provider, key);
+
+ /* If value is "-", it is cleared by VPN agent */
+ if (!g_strcmp0(str, "-"))
+ str = NULL;
+
+ if (str)
+ immutable = vpn_provider_get_string_immutable(provider, key);
+
+ if (immutable) {
+ /* Hide immutable password types */
+ if (function_cb == request_input_append_password)
+ str = "********";
+
+ /* Send immutable as informational */
+ function_cb = request_input_append_informational;
+ }
+
+ connman_dbus_dict_append_dict(dict, key, function_cb, (void *)str);
+}
+
+static void request_input_credentials_reply(DBusMessage *reply, void *user_data)
+{
+ struct vc_private_data *data = user_data;
+ char *secret = NULL, *username = NULL, *password = NULL;
+ const char *key;
+ DBusMessageIter iter, dict;
+ DBusError error;
+ int err_int = 0;
+
+ DBG("provider %p", data->provider);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ if (!g_strcmp0(error.name, VPN_AGENT_INTERFACE
+ ".Error.Canceled"))
+ err_int = ECONNABORTED;
+
+ if (!g_strcmp0(error.name, VPN_AGENT_INTERFACE
+ ".Error.Timeout"))
+ err_int = ETIMEDOUT;
+
+ dbus_error_free(&error);
+ goto abort;
+ }
+
+ if (!vpn_agent_check_reply_has_dict(reply))
+ goto err;
+
+ dbus_message_iter_init(reply, &iter);
+ dbus_message_iter_recurse(&iter, &dict);
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ break;
+
+ dbus_message_iter_get_basic(&entry, &key);
+
+ if (g_str_equal(key, "VPNC.IPSec.Secret")) {
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry)
+ != DBUS_TYPE_VARIANT)
+ break;
+ dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value)
+ != DBUS_TYPE_STRING)
+ break;
+ dbus_message_iter_get_basic(&value, &secret);
+ vpn_provider_set_string_hide_value(data->provider,
+ key, secret);
+
+ } else if (g_str_equal(key, "VPNC.Xauth.Username")) {
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry)
+ != DBUS_TYPE_VARIANT)
+ break;
+ dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value)
+ != DBUS_TYPE_STRING)
+ break;
+ dbus_message_iter_get_basic(&value, &username);
+ vpn_provider_set_string(data->provider, key, username);
+
+ } else if (g_str_equal(key, "VPNC.Xauth.Password")) {
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry)
+ != DBUS_TYPE_VARIANT)
+ break;
+ dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value)
+ != DBUS_TYPE_STRING)
+ break;
+ dbus_message_iter_get_basic(&value, &password);
+ vpn_provider_set_string_hide_value(data->provider, key,
+ password);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ if (!secret || !username || !password)
+ goto err;
+
+ err_int = run_connect(data);
+ if (err_int != -EINPROGRESS)
+ goto err;
+
+ return;
+
+err:
+ err_int = EACCES;
+
+abort:
+ vc_connect_done(data, err_int);
+
+ switch (err_int) {
+ case EACCES:
+ vpn_provider_indicate_error(data->provider,
+ VPN_PROVIDER_ERROR_AUTH_FAILED);
+ break;
+ case ECONNABORTED:
+ case ETIMEDOUT:
+ vpn_provider_indicate_error(data->provider,
+ VPN_PROVIDER_ERROR_UNKNOWN);
+ }
+}
+
+static int request_input_credentials(struct vc_private_data *data,
+ const char* dbus_sender)
+{
+ DBusMessage *message;
+ const char *path, *agent_sender, *agent_path;
+ DBusMessageIter iter;
+ DBusMessageIter dict;
+ int err;
+ void *agent;
+
+ if (!data || !data->provider)
+ return -ENOENT;
+
+ DBG("data %p provider %p sender %s", data, data->provider, dbus_sender);
+
+ agent = connman_agent_get_info(dbus_sender, &agent_sender, &agent_path);
+ if (!agent || !agent_path)
+ return -ESRCH;
+
+ message = dbus_message_new_method_call(agent_sender, agent_path,
+ VPN_AGENT_INTERFACE,
+ "RequestInput");
+ if (!message)
+ return -ENOMEM;
+
+ dbus_message_iter_init_append(message, &iter);
+
+ path = vpn_provider_get_path(data->provider);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+ connman_dbus_dict_open(&iter, &dict);
+
+ request_input_append_to_dict(data->provider, &dict,
+ request_input_append_password,
+ "VPNC.IPSec.Secret");
+ request_input_append_to_dict(data->provider, &dict,
+ request_input_append_mandatory,
+ "VPNC.Xauth.Username");
+ request_input_append_to_dict(data->provider, &dict,
+ request_input_append_password,
+ "VPNC.Xauth.Password");
+
+ vpn_agent_append_host_and_name(&dict, data->provider);
+
+ connman_dbus_dict_close(&iter, &dict);
+
+ err = connman_agent_queue_message(data->provider, message,
+ connman_timeout_input_request(),
+ request_input_credentials_reply, data, agent);
+
+ if (err < 0 && err != -EBUSY) {
+ DBG("error %d sending agent request", err);
+ dbus_message_unref(message);
+
+ return err;
+ }
+
+ dbus_message_unref(message);
+
+ return -EINPROGRESS;
+}
+
+static int vc_connect(struct vpn_provider *provider,
+ struct connman_task *task, const char *if_name,
+ vpn_provider_connect_cb_t cb, const char *dbus_sender,
+ void *user_data)
+{
+ struct vc_private_data *data;
+ const char *option;
+ bool username_set = false;
+ bool password_set = false;
+ bool ipsec_secret_set = false;
+ int err;
+
+ DBG("provider %p if_name %s user_data %p", provider, if_name, user_data);
+
+ option = vpn_provider_get_string(provider, "Host");
+ if (!option) {
+ connman_error("Host not set; cannot enable VPN");
+ return -EINVAL;
+ }
+
+ option = vpn_provider_get_string(provider, "VPNC.IPSec.ID");
+ if (!option) {
+ connman_error("Group not set; cannot enable VPN");
+ return -EINVAL;
+ }
+
+ option = vpn_provider_get_string(provider, "VPNC.IPSec.Secret");
+ if (option && *option && g_strcmp0(option, "-"))
+ ipsec_secret_set = true;
+
+ option = vpn_provider_get_string(provider, "VPNC.Xauth.Username");
+ if (option && *option && g_strcmp0(option, "-"))
+ username_set = true;
+
+ option = vpn_provider_get_string(provider, "VPNC.Xauth.Password");
+ if (option && *option && g_strcmp0(option, "-"))
+ password_set = true;
+
+ data = g_try_new0(struct vc_private_data, 1);
+ if (!data)
+ return -ENOMEM;
+
+ vpn_provider_set_plugin_data(provider, data);
+ data->provider = vpn_provider_ref(provider);
+ data->task = task;
+ data->if_name = g_strdup(if_name);
+ data->cb = cb;
+ data->user_data = user_data;
+
+ if (!ipsec_secret_set || !username_set || !password_set) {
+ err = request_input_credentials(data, dbus_sender);
+ if (err != -EINPROGRESS) {
+ vc_connect_done(data, ECONNABORTED);
+ vpn_provider_indicate_error(data->provider,
+ VPN_PROVIDER_ERROR_LOGIN_FAILED);
+ free_private_data(data);
+ }
+
+ return err;
+ }
+
+ return run_connect(data);
+}
+
static int vc_error_code(struct vpn_provider *provider, int exit_code)
{
switch (exit_code) {
@@ -384,16 +791,12 @@ static struct vpn_driver vpn_driver = {
static int vpnc_init(void)
{
- connection = connman_dbus_get_connection();
-
return vpn_register("vpnc", &vpn_driver, VPNC);
}
static void vpnc_exit(void)
{
vpn_unregister("vpnc");
-
- dbus_connection_unref(connection);
}
CONNMAN_PLUGIN_DEFINE(vpnc, "vpnc plugin", VERSION,
--
2.20.1
3 years, 2 months
[PATCH] dbus: Add dbus time synchronization method
by Yasser
Our project has strict time requirements so we needed to have a time
synchronization method. Hopefully it will be useful to someone else
also.
diff --git a/include/dbus.h b/include/dbus.h
index bcab418..d83662d 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -85,6 +85,8 @@ dbus_bool_t connman_dbus_setting_changed_array(const
char *owner,
const char *path, const char *key, int type,
connman_dbus_append_cb_t function,
void *user_data);
+dbus_bool_t connman_dbus_time_synced(const char *path,
+ const char *interface, double ts);
static inline void connman_dbus_dict_open(DBusMessageIter *iter,
DBusMessageIter *dict)
diff --git a/src/clock.c b/src/clock.c
index 0fde2c3..8b5503c 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -368,7 +368,32 @@ static DBusMessage *set_property(DBusConnection *conn,
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+static DBusMessage *synchronize(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ gboolean result = FALSE;
+
+ DBG("conn %p", conn);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ if (__connman_timeserver_sync(NULL) == 0)
+ result = TRUE;
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &result);
+
+ return reply;
+}
+
static const GDBusMethodTable clock_methods[] = {
+ { GDBUS_METHOD("Synchronize",
+ NULL, GDBUS_ARGS( { "success", "b" } ),
+ synchronize) },
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
get_properties) },
@@ -381,7 +406,8 @@ static const GDBusMethodTable clock_methods[] = {
static const GDBusSignalTable clock_signals[] = {
{ GDBUS_SIGNAL("PropertyChanged",
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
- { },
+ { GDBUS_SIGNAL("TimeSynced",
+ GDBUS_ARGS({ "timestamp", "d" })) }, { },
};
static DBusConnection *connection = NULL;
diff --git a/src/dbus.c b/src/dbus.c
index d80a46c..82d5cf0 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -382,6 +382,27 @@ dbus_bool_t
connman_dbus_setting_changed_array(const char *owner,
return TRUE;
}
+dbus_bool_t connman_dbus_time_synced(const char *path,
+ const char *interface, double ts)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter;
+
+ if (!path)
+ return FALSE;
+
+ signal = dbus_message_new_signal(path, interface, "TimeSynced");
+ if (!signal)
+ return FALSE;
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_DOUBLE, &ts);
+
+ g_dbus_send_message(connection, signal);
+
+ return TRUE;
+}
+
dbus_bool_t __connman_dbus_append_objpath_dict_array(DBusMessage *msg,
connman_dbus_append_cb_t function, void *user_data)
{
diff --git a/src/ntp.c b/src/ntp.c
index e7fee22..7d74f17 100644
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -356,6 +356,7 @@ static void decode_msg(struct ntp_data *nd, void
*base, size_t len,
tmx.esterror = 0;
connman_info("ntp: adjust (slew): %+.6f sec", offset);
+ connman_dbus_time_synced(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, offset);
} else {
tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET |
ADJ_MAXERROR | ADJ_ESTERROR;
@@ -372,6 +373,7 @@ static void decode_msg(struct ntp_data *nd, void
*base, size_t len,
}
connman_info("ntp: adjust (jump): %+.6f sec", offset);
+ connman_dbus_time_synced(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, offset);
}
if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_ADDSECOND)
3 years, 2 months
Re: IPv6 privacy extensions with connman
by Daniel Wagner
Hi Christian,
Please no top posting and dropping the mailing list.
On 5/13/19 10:06 AM, Christian wrote:
> Hi Daniel,
>
> thanks for looking into it. My setup is actually quite straight forward.
>
> I am using an Opnsense router that gets an /56 prefix from my provider.
> I delegate a /64 into my local network via router advertisement.
I've played with my network setup and I have similar. That is I get /56
prefix from my provider and have due to Fritbox a /62 prefix length to
my next main gateway. There is still something wrong with the routing
but that's a different story.
> Of course all clients with activated IPv6 get their fe80:: local network
> IPv6, but by the router advertisement all clients get an IPv6 - within
> the prefix - based on their MAC address. That are the "scope global
> dynamic" ones.
> This works with libreelec and connman. Hence you have a globally
> routable IPv6 assigned.
Verified that on my development machine, works as expected.
> For the clients I then activate the privacy extensions, to create an
> "scope global temporary dynamic". This does not work with the connman
> settings I have.
> Within Libreelec the configuration is quite limited, as you can only
> activate IPv6 in the settings or disable it.
I found my RPi and installed LibreELEC on it. As expected it has nothing
to do with the hardware or the LibreELEC system configuration.
After enabling the privacy feature I see:
LibreELEC:/proc # ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qlen 1000
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP8000> mtu 1500 qlen 1000
inet6 2001:a61:34ab:f4fc:1d1e:2e5c:b866:2754/64 scope global
secondary dynamic
valid_lft 86069sec preferred_lft 14069sec
inet6 2001:a61:34ab:f4fc:ba27:ebff:fed5:60cb/64 scope global dynamic
valid_lft 86069sec preferred_lft 14069sec
inet6 fe80::ba27:ebff:fed5:60cb/64 scope link
valid_lft forever preferred_lft forever
> To set the privacy extensions I added manually to
> "/storage/.cache/connman/settings"
FYI, ConnMan will overwrite this file if ConnMan is running in the
background. Use connmanctrl to modify the settings.
> [WiFi]
> Enable=true
> Tethering=false
> IPv6.privacy=preferred
This doesn't have an effect. The privacy settings are per service.
> Running a connmanctl services on my wifi (similar the wired one) then
> gives me the following (I edited out private infos):
>
> Type = wifi
> Security = [ psk ]
> State = online
> Strength = 81
> Favorite = True
> Immutable = False
> AutoConnect = True
> Name = Some Wifi Name
> Ethernet = [ Method=auto, Interface=wlan0, Address=XX:XX:XX:XX:XX:XX,
> MTU=1500 ]
> IPv4 = [ Method=dhcp, Address=192.168.2.196, Netmask=255.255.255.0,
> Gateway=192.168.2.1 ]
> IPv4.Configuration = [ Method=dhcp ]
> IPv6 = [ Method=auto,
> Address=xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, PrefixLength=64,
> Privacy=prefered ]
> IPv6.Configuration = [ Method=auto, Privacy=prefered ]
That is looks good, except spelling obviously...
> Nameservers = [ 192.168.2.1, xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx ]
> Nameservers.Configuration = [ ]
> Timeservers = [ ptbtime1.ptb.de, ptbtime2.ptb.de, 0.pool.ntp.org,
> 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org ]
> Timeservers.Configuration = [ ]
> Domains = [ xxxxx.xxx ]
> Domains.Configuration = [ ]
> Proxy = [ Method=direct ]
> Proxy.Configuration = [ ]
> mDNS = False
> mDNS.Configuration = False
> Provider = [ ]
>
> As you can see, it picks up the privacy extension config (even though
> with the spelling mistake ;-))
I found the spot where 'prefered' is appended to the D-Bus message. As I
said, by changing this we would break the API. Not sure if this would be
a clever idea.
, but when checking the IPv6s, I only get
> the "fe80:", the "scope global dynamic" and a "scope global secondary
> dynamic".
> The last one seems to be the wrong one, as it should be a "scope global
> temporary dynamic" that deprecates over time.
>
> Let me know if you need any other information.
Are you using DHCPv6 or SLAAC? In my setup I am using SLAAC.
Thanks,
Daniel
3 years, 2 months
connam 1.31, limited number of SSID?
by Mauro Ziliani
Hi all.
I'm working with connman 1.31 on Yocto Jethro.
There is a maximum number of ssid for connmand?
My trouble is this. I've build and application based on Yocto Jethto, Qt
5.6.2, libconnam-qt5 1.0.98.
The application works well until the user plugs the wifi usb dongle and
there is a lot of SSID scanned.
It seems that when there is a lot of SSID in the air sometimes the
application crashes.
Mauro
3 years, 2 months
Re: Problem connecting to WISPr access point
by Daniel Wagner
Hi Thomas,
Please no top posting and dropping the mailing list.
On 5/13/19 10:25 PM, Thomas Green wrote:
> After getting this patch to work the code seems to be that the gnutls_priority_set_direct takes the same arguments in both the cases of the #ifdef, and that it only doesn't set the low watermark. Am I understanding this correctly?
According the gnutls documentation[1], the priority setting
"NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT"
will take the defaults and removes ALL TLS version and enables only
TLSv1 and SSL3.0. Furthermore, the documentation says "NORMAL:%COMPAT"
is the most compatible mode. But I am no expert here. Just guessing.
The current setting was added by 14030eaee370 ("gweb: Fix
gnutls_priority_set_direct() for various GnuTLS versions") in 2011, this
is 8 years ago and things have changed. At least TLSv1 is considered as
broken and is being removed from many web servers.
The gnutls version check could probably also be removed 2.12.x ended in
2011 and the API breakage was with 3.x.
> The log for using this patch is attached. It doesn't even seem to attempt to do anything WISPr related. Thanks for looking into this.
The logs don't include the gweb subsystem. Add CONNMAN_WEB_DEBUG to your
environment to enable it.
CONNMAN_WEB_DEBUG=1 src/connmand -n -d
And also check if you see something in the network trace.
Thanks,
Daniel
[1] https://gnutls.org/manual/html_node/Priority-Strings.html
>
> Tom
>
> -----Original Message-----
> From: Daniel Wagner [mailto:wagi@monom.org]
> Sent: Saturday, May 11, 2019 12:27 PM
> To: Thomas Green <TGreen2(a)Sorenson.com>
> Cc: connman(a)connman.net
> Subject: Re: Problem connecting to WISPr access point
>
> [EXTERNAL]
>
> Hi Thomas,
>
>>> it never prompts for the wispr credentials. Turning on logging I
>>> see that the access point returns a 307 error when trying to attach.
>>> In wispr.c (line 735) it only checks for error 302. I added a case
>>> to that for 307 to handle the redirect, and tried it again. As you
>>> can see from the attached log, it now tries to handle the redirect,
>>> but fails to do so. As you can see in the log, it immediately
>>> returns a
>>> 400 (Bad Request) error. Trying to determine what is happening I
>>> then took a tcpdump of the connection process to see what happened then.
>>> When examining the pcap file that is attached, It doesn't look as if
>>> the attempt to actually perform the redirect actually happens. If
>>> you could help me determine what is happening, and fix this, I would
>>> surely appreciate it. Connecting to this access point works as
>>> expected on my android and apple devices, so I'm guessing that
>>> connman is doing something different.
>
> Thanks for the log and pcap trace. From them I can see that GET http://ipv4.connman.net/online/status.html is answered with a rederect to https://n195.network-auth.com/[...].
>
> ConnMan does the DNS lookup for n195.network-auth.com which works.
>
> After the DNS resolve a new TCP with TLSv1 session is initiated for
> 209.206.52.180 which is aborted. I would bet that TLSv1 is the problem.
>
> Can you try following patch with your changes?
>
> Thanks,
> Daniel
>
>
> diff --git a/gweb/giognutls.c b/gweb/giognutls.c index b5c476cbe670..8c97413a3bdd 100644
> --- a/gweb/giognutls.c
> +++ b/gweb/giognutls.c
> @@ -456,7 +456,7 @@ GIOChannel *g_io_channel_gnutls_new(int fd)
> "NORMAL:%COMPAT", NULL); #else
> gnutls_priority_set_direct(gnutls_channel->session,
> - "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL);
> + "NORMAL:%COMPAT", NULL);
> #endif
>
> gnutls_certificate_allocate_credentials(&gnutls_channel->cred);
>
3 years, 3 months
custom DHCP options connman
by alexander
Hi
During experimentation with connman, I ran into some issues while trying
to specify custom dhcp option. I looked into the source and saw that
only a subset of the official dhcp options are processed by the internal
dhcp client.
To provide a workaround I tried to use another dhcp client (in my case,
dhcpcd) to process the additional options. To prevent having multiple
dhcp clients. I want to disable the internal dhcp of connman (since I
had some issues with using IPv6 on the wifi driver I chose to disable
this as well). However, if both IPv4 and IPv6 configurations (which I've
turned off to resolve driver issues) are turned off, the wireless
network is not connected (as inspected with `iw wlan0 link`).
To me it seems odd that the network is not connected if IP configuration
within connman is turned off, since I specified how it should be
(connected without dhcp configuration), so I can handle that with
another client.
These are my questions related to this behaviour:
* Is, disabling the connection when both IPv4 and IPv6 is turned off,
considered normal behaviour?
o If not, are there changes in this behaviour since version
1.33-3+deb9u1?
* Is there a way to use a clean way to use an external dhcp client
instead of the internal gdhcp?
* Are custom dhcp options possible (by possible I mean able to process
the data given with those options)?
o If not, is this planned for the future?
Thanks in advance!
--
*Kind regards*
Alexander Vandenbulcke
tel.: 0032 491 22 71 90
3 years, 3 months
IPv6 privacy extensions with connman
by Christian
Hi there,
I am trying to activate IPv6 with privacy extension. (On a Libreelec
system, running on a Raspberry Pi 3).
First, I encountered a spelling mistake: The option for "IPv6.privacy"
actually has to be spelled "prefered" to work. With the correct
spelling "preferred" nothing happened. Only after changing it to the
wrong spelling a second IPv6 was generated and the option showed up in
the service (listed as: Privacy=prefered).
Second, after setting the privacy option to "prefered", I get an
additional IPv6, however it is set as "scope global secondary dynamic".
Privacy extensions should normally be "scope global temporary dynamic"
and get deprecated after some time.
Am I having the wrong configuration here or are these bugs?
Kind Regards
Christian
3 years, 3 months
Problem connecting to WISPr access point
by Thomas Green
I posted on this before, but I am doing it again, with more information. I am trying to attach to a WISPr enabled access point. The sequence of commands in connmanctl is:
connmanctl> agent on
connmanctl> connect wifi_3c6aa71c5057_5075626c6963_managed_none
connmanctl> connected wifi_3c6aa71c5057_5075626c6963_managed_none
it never prompts for the wispr credentials. Turning on logging I see that the access point returns a 307 error when trying to attach. In wispr.c (line 735) it only checks for error 302. I added a case to that for 307 to handle the redirect, and tried it again. As you can see from the attached log, it now tries to handle the redirect, but fails to do so. As you can see in the log, it immediately returns a 400 (Bad Request) error. Trying to determine what is happening I then took a tcpdump of the connection process to see what happened then. When examining the pcap file that is attached, It doesn't look as if the attempt to actually perform the redirect actually happens. If you could help me determine what is happening, and fix this, I would surely appreciate it. Connecting to this access point works as expected on my android and apple devices, so I'm guessing that connman is doing something different.
Thanks in advance,
Tom
3 years, 3 months
"P2P" not available in connman technologies
by vishal bs
Hi,
there is no p2p in the "technologies" list in the connman ,
I did follow one of the other mail lists which was on the same issue.
Link : https://lists.01.org/pipermail/connman/2017-August/022040.html
I gave the commands specified in the link to get the capabilities and
was able to get P2P in both "all global" capabilities of
wpa_supplicant(i.e I am running wpa_supplicant using the parameter -u)
as well as in "Interface" capabilities, further when i enabled the log
I came across this,
connmand[4569]:gsupplicant/suppicannt.c:debug_strvalmap() mode
capability: infrastructure
connmand[4569]:gsupplicant/suppicannt.c:debug_strvalmap() mode
capability: ad-hoc
connmand[4569]:gsupplicant/suppicannt.c:debug_strvalmap() mode capability: ap
connmand[4569]:gsupplicant/suppicannt.c:callback_interface_added()
which is confusing!
It would be great if anybody steps up to solve this problem.
The detailed log is attached.
I hope someone will help me regarding this.
Thank you
vishal
3 years, 3 months