summaryrefslogtreecommitdiff
path: root/src/nm-iodine-service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-iodine-service.c')
-rw-r--r--src/nm-iodine-service.c302
1 files changed, 134 insertions, 168 deletions
diff --git a/src/nm-iodine-service.c b/src/nm-iodine-service.c
index c99c384..89023d4 100644
--- a/src/nm-iodine-service.c
+++ b/src/nm-iodine-service.c
@@ -40,23 +40,25 @@
#include <pwd.h>
#include <grp.h>
#include <glib/gi18n.h>
+#include <arpa/inet.h>
-#include <nm-setting-vpn.h>
+#include <NetworkManager.h>
+#include <nm-vpn-service-plugin.h>
#include "nm-iodine-service.h"
#include "nm-utils.h"
#define NM_IODINE_USER "nm-iodine"
#define NM_IODINE_RUNDIR LOCALSTATEDIR "/run/" NM_IODINE_USER
-G_DEFINE_TYPE (NMIODINEPlugin, nm_iodine_plugin, NM_TYPE_VPN_PLUGIN)
+G_DEFINE_TYPE (NMIodinePlugin, nm_iodine_plugin, NM_TYPE_VPN_SERVICE_PLUGIN)
typedef struct {
GPid pid;
- NMVPNPluginFailure failure;
- GHashTable *ip4config;
-} NMIODINEPluginPrivate;
+ NMVpnPluginFailure failure;
+ GVariantBuilder ip4config;
+} NMIodinePluginPrivate;
-#define NM_IODINE_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IODINE_PLUGIN, NMIODINEPluginPrivate))
+#define NM_IODINE_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IODINE_PLUGIN, NMIodinePluginPrivate))
static const char *iodine_binary_paths[] =
{
@@ -129,7 +131,7 @@ validate_one_property (const char *key, const char *value, gpointer user_data)
NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
_("invalid integer property '%s' or out of range "
- "[%d -> %d]"),
+ "[%d -> %d]"),
key, prop.int_min, prop.int_max);
break;
case G_TYPE_BOOLEAN:
@@ -153,7 +155,7 @@ validate_one_property (const char *key, const char *value, gpointer user_data)
}
/* Did not find the property from valid_properties or the type did not
- match */
+ match */
if (!info->table[i].name && strncmp(key, "form:", 5)) {
g_warning ("property '%s' unknown", key);
if (0)
@@ -166,7 +168,7 @@ validate_one_property (const char *key, const char *value, gpointer user_data)
}
static gboolean
-nm_iodine_properties_validate (NMSettingVPN *s_vpn, GError **error)
+nm_iodine_properties_validate (NMSettingVpn *s_vpn, GError **error)
{
ValidateInfo info = { &valid_properties[0], error, FALSE };
@@ -185,7 +187,7 @@ nm_iodine_properties_validate (NMSettingVPN *s_vpn, GError **error)
static gboolean
-nm_iodine_secrets_validate (NMSettingVPN *s_vpn, GError **error)
+nm_iodine_secrets_validate (NMSettingVpn *s_vpn, GError **error)
{
ValidateInfo info = { &valid_secrets[0], error, FALSE };
@@ -202,52 +204,32 @@ nm_iodine_secrets_validate (NMSettingVPN *s_vpn, GError **error)
return *error ? FALSE : TRUE;
}
-static GValue *
-str_to_gvalue (const char *str, gboolean try_convert)
+static GVariant *
+str_to_gvariant (const char *str, gboolean try_convert)
{
- GValue *val;
-
/* Empty */
if (!str || strlen (str) < 1)
return NULL;
if (!g_utf8_validate (str, -1, NULL)) {
if (try_convert && !(str = g_convert (str,
- -1,
- "ISO-8859-1",
- "UTF-8",
- NULL,
- NULL,
- NULL)))
+ -1,
+ "ISO-8859-1",
+ "UTF-8",
+ NULL,
+ NULL,
+ NULL)))
str = g_convert (str, -1, "C", "UTF-8", NULL, NULL, NULL);
if (!str)
/* Invalid */
return NULL;
}
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
- return val;
+ return g_variant_new_string (str);
}
-static GValue *
-uint_to_gvalue (guint32 num)
-{
- GValue *val;
-
- if (num == 0)
- return NULL;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_UINT);
- g_value_set_uint (val, num);
-
- return val;
-}
-
-static GValue *
-addr_to_gvalue (const char *str)
+static GVariant *
+addr4_to_gvariant (const char *str)
{
struct in_addr temp_addr;
@@ -258,26 +240,16 @@ addr_to_gvalue (const char *str)
if (inet_pton (AF_INET, str, &temp_addr) <= 0)
return NULL;
- return uint_to_gvalue (temp_addr.s_addr);
-}
-
-static void
-value_destroy (gpointer data)
-{
- GValue *val = (GValue *) data;
-
- g_value_unset (val);
- g_slice_free (GValue, val);
+ return g_variant_new_uint32 (temp_addr.s_addr);
}
static gint
-iodine_parse_stderr_line (NMVPNPlugin *plugin,
- const char* line,
- GHashTable *ip4config)
+iodine_parse_stderr_line (NMVpnServicePlugin *plugin,
+ const char* line)
{
- NMIODINEPluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
+ NMIodinePluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
gchar **split = NULL;
- GValue *val;
+ GVariant *val;
gint len;
gint ret = 1;
@@ -295,60 +267,60 @@ iodine_parse_stderr_line (NMVPNPlugin *plugin,
if (g_str_has_prefix(line, "Server tunnel IP is ")) {
g_message("PTP address: %s", split[len-1]);
- val = addr_to_gvalue (split[len-1]);
+ val = addr4_to_gvariant (split[len-1]);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_PTP,
- val);
- val = addr_to_gvalue (split[len-1]);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_PTP,
+ val);
+ val = addr4_to_gvariant (split[len-1]);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY,
- val);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY,
+ val);
} else if (g_str_has_prefix(line, "Sending DNS queries for ")) {
g_message("External gw: %s", split[len-1]);
- val = addr_to_gvalue (split[len-1]);
+ val = addr4_to_gvariant (split[len-1]);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY,
- val);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY,
+ val);
} else if (g_str_has_prefix(line, "Sending raw traffic directly to ")) {
/* If the DNS server is directly reachable we need to set it
as external gateway overwriting the above valus */
g_message("Overwrite ext. gw. address: %s", split[len-1]);
- val = addr_to_gvalue (split[len-1]);
+ val = addr4_to_gvariant (split[len-1]);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY,
- val);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY,
+ val);
} else if (g_str_has_prefix(line, "Setting IP of dns")) {
g_message("Address: %s", split[len-1]);
- val = addr_to_gvalue (split[len-1]);
+ val = addr4_to_gvariant (split[len-1]);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS,
- val);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS,
+ val);
} else if (g_str_has_prefix(line, "Setting MTU of ")) {
g_message("MTU: %s", split[len-1]);
- val = addr_to_gvalue (split[len-1]);
+ val = addr4_to_gvariant (split[len-1]);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_MTU,
- val);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_MTU,
+ val);
} else if (g_str_has_prefix(line, "Opened dns")) {
g_message("Interface: %s", split[len-1]);
- val = str_to_gvalue (split[len-1], FALSE);
+ val = str_to_gvariant (split[len-1], FALSE);
if (val)
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV,
- val);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV,
+ val);
} else if (g_str_has_prefix(line,
- "Connection setup complete, "
- "transmitting data.")) {
- val = uint_to_gvalue(27);
- g_hash_table_insert (ip4config,
- NM_VPN_PLUGIN_IP4_CONFIG_PREFIX,
- val);
+ "Connection setup complete, "
+ "transmitting data.")) {
+ val = g_variant_new_uint32 (27);
+ g_variant_builder_add (&priv->ip4config, "{sv}",
+ NM_VPN_PLUGIN_IP4_CONFIG_PREFIX,
+ val);
ret = 0; /* success */
} else
g_message("%s", line);
@@ -366,7 +338,7 @@ iodine_stderr_cb (GIOChannel *source, GIOCondition condition, gpointer plugin)
GError *err = NULL;
gchar *line;
gint ret, l;
- NMIODINEPluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
+ NMIodinePluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
status = g_io_channel_read_line (source, &line, NULL, NULL, &err);
if (status != G_IO_STATUS_NORMAL) {
@@ -378,13 +350,11 @@ iodine_stderr_cb (GIOChannel *source, GIOCondition condition, gpointer plugin)
if (l)
line[l-1] = '\0';
- ret = iodine_parse_stderr_line(plugin, line, priv->ip4config);
+ ret = iodine_parse_stderr_line(plugin, line);
if (!ret) {
g_message("Parsing done, sending IP4 config");
- nm_vpn_plugin_set_ip4_config(plugin, priv->ip4config);
-
- g_hash_table_destroy (priv->ip4config);
- priv->ip4config = NULL;
+ nm_vpn_service_plugin_set_ip4_config(plugin,
+ g_variant_builder_end (&priv->ip4config));
}
g_free (line);
return TRUE;
@@ -394,8 +364,8 @@ iodine_stderr_cb (GIOChannel *source, GIOCondition condition, gpointer plugin)
static void
iodine_watch_cb (GPid pid, gint status, gpointer user_data)
{
- NMIODINEPlugin *plugin = NM_IODINE_PLUGIN (user_data);
- NMIODINEPluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
+ NMIodinePlugin *plugin = NM_IODINE_PLUGIN (user_data);
+ NMIodinePluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
guint error = 0;
if (WIFEXITED (status)) {
@@ -416,15 +386,12 @@ iodine_watch_cb (GPid pid, gint status, gpointer user_data)
priv->pid = 0;
if (priv->failure >= 0) {
- nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin),
- priv->failure);
+ nm_vpn_service_plugin_failure (NM_VPN_SERVICE_PLUGIN (plugin), priv->failure);
} else if (error) {
- nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin),
- NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+ nm_vpn_service_plugin_failure (NM_VPN_SERVICE_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+ } else {
+ nm_vpn_service_plugin_disconnect (NM_VPN_SERVICE_PLUGIN (plugin), NULL);
}
-
- nm_vpn_plugin_set_state (NM_VPN_PLUGIN (plugin),
- NM_VPN_SERVICE_STATE_STOPPED);
}
static gboolean
@@ -435,7 +402,7 @@ has_user(const char* user)
static void
-send_password(gint fd, NMSettingVPN *s_vpn)
+send_password(gint fd, NMSettingVpn *s_vpn)
{
const char *passwd;
ssize_t ret;
@@ -455,16 +422,16 @@ send_password(gint fd, NMSettingVPN *s_vpn)
static gint
-nm_iodine_start_iodine_binary(NMIODINEPlugin *plugin,
- NMSettingVPN *s_vpn,
- GError **error)
+nm_iodine_start_iodine_binary (NMIodinePlugin *plugin,
+ NMSettingVpn *s_vpn,
+ GError **error)
{
- GPid pid;
+ GPid pid;
const char **iodine_binary = NULL;
GPtrArray *iodine_argv;
GSource *iodine_watch;
GIOChannel *stderr_channel;
- gint stdin_fd, stderr_fd;
+ gint stdin_fd, stderr_fd;
const char *props_topdomain, *props_fragsize, *props_nameserver;
/* Find iodine */
@@ -484,12 +451,9 @@ nm_iodine_start_iodine_binary(NMIODINEPlugin *plugin,
return -1;
}
- props_fragsize = nm_setting_vpn_get_data_item (s_vpn,
- NM_IODINE_KEY_FRAGSIZE);
- props_nameserver = nm_setting_vpn_get_data_item (s_vpn,
- NM_IODINE_KEY_NAMESERVER);
- props_topdomain = nm_setting_vpn_get_data_item (s_vpn,
- NM_IODINE_KEY_TOPDOMAIN);
+ props_fragsize = nm_setting_vpn_get_data_item (s_vpn, NM_IODINE_KEY_FRAGSIZE);
+ props_nameserver = nm_setting_vpn_get_data_item (s_vpn, NM_IODINE_KEY_NAMESERVER);
+ props_topdomain = nm_setting_vpn_get_data_item (s_vpn, NM_IODINE_KEY_TOPDOMAIN);
iodine_argv = g_ptr_array_new ();
g_ptr_array_add (iodine_argv, (gpointer) (*iodine_binary));
/* Run in foreground */
@@ -521,9 +485,9 @@ nm_iodine_start_iodine_binary(NMIODINEPlugin *plugin,
g_ptr_array_add (iodine_argv, NULL);
if (!g_spawn_async_with_pipes (NULL, (char **) iodine_argv->pdata, NULL,
- G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL,
- &pid, &stdin_fd, NULL, &stderr_fd, error)) {
+ G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL,
+ &pid, &stdin_fd, NULL, &stderr_fd, error)) {
g_ptr_array_free (iodine_argv, TRUE);
g_warning ("iodine failed to start. error: '%s'", (*error)->message);
return -1;
@@ -537,16 +501,16 @@ nm_iodine_start_iodine_binary(NMIODINEPlugin *plugin,
stderr_channel = g_io_channel_unix_new (stderr_fd);
g_io_add_watch(stderr_channel,
- G_IO_IN,
- iodine_stderr_cb,
- plugin);
+ G_IO_IN,
+ iodine_stderr_cb,
+ plugin);
NM_IODINE_PLUGIN_GET_PRIVATE (plugin)->pid = pid;
iodine_watch = g_child_watch_source_new (pid);
g_source_set_callback (iodine_watch,
- (GSourceFunc) iodine_watch_cb,
- plugin,
- NULL);
+ (GSourceFunc) iodine_watch_cb,
+ plugin,
+ NULL);
g_source_attach (iodine_watch, NULL);
g_source_unref (iodine_watch);
@@ -554,15 +518,14 @@ nm_iodine_start_iodine_binary(NMIODINEPlugin *plugin,
}
static gboolean
-real_connect (NMVPNPlugin *plugin,
- NMConnection *connection,
- GError **error)
+real_connect (NMVpnServicePlugin *plugin,
+ NMConnection *connection,
+ GError **error)
{
- NMSettingVPN *s_vpn;
+ NMSettingVpn *s_vpn;
gint ret = -1;
- s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection,
- NM_TYPE_SETTING_VPN));
+ s_vpn = nm_connection_get_setting_vpn (connection);
g_assert (s_vpn);
if (!nm_iodine_properties_validate (s_vpn, error))
goto out;
@@ -570,8 +533,7 @@ real_connect (NMVPNPlugin *plugin,
if (!nm_iodine_secrets_validate (s_vpn, error))
goto out;
- ret = nm_iodine_start_iodine_binary (NM_IODINE_PLUGIN (plugin),
- s_vpn, error);
+ ret = nm_iodine_start_iodine_binary (NM_IODINE_PLUGIN (plugin), s_vpn, error);
if (!ret)
return TRUE;
@@ -580,26 +542,24 @@ real_connect (NMVPNPlugin *plugin,
}
static gboolean
-real_need_secrets (NMVPNPlugin *plugin,
-
- NMConnection *connection,
- char **setting_name,
- GError **error)
+real_need_secrets (NMVpnServicePlugin *plugin,
+ NMConnection *connection,
+ const char **setting_name,
+ GError **error)
{
- NMSettingVPN *s_vpn;
+ NMSettingVpn *s_vpn;
- g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
+ g_return_val_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
- s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection,
- NM_TYPE_SETTING_VPN));
+ s_vpn = nm_connection_get_setting_vpn (connection);
if (!s_vpn) {
- g_set_error (error,
+ g_set_error (error,
NM_VPN_PLUGIN_ERROR,
- NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
+ NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
"%s",
- "Could not process the request because the VPN"
- "connection settings were invalid.");
+ "Could not process the request because the VPN "
+ "connection settings were invalid.");
return FALSE;
}
@@ -623,10 +583,9 @@ ensure_killed (gpointer data)
}
static gboolean
-real_disconnect (NMVPNPlugin *plugin,
- GError **err)
+real_disconnect (NMVpnServicePlugin *plugin, GError **err)
{
- NMIODINEPluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
+ NMIodinePluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
if (priv->pid) {
if (kill (priv->pid, SIGTERM) == 0)
@@ -642,24 +601,21 @@ real_disconnect (NMVPNPlugin *plugin,
}
static void
-nm_iodine_plugin_init (NMIODINEPlugin *plugin)
+nm_iodine_plugin_init (NMIodinePlugin *plugin)
{
- NMIODINEPluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
+ NMIodinePluginPrivate *priv = NM_IODINE_PLUGIN_GET_PRIVATE (plugin);
- priv->ip4config = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- value_destroy);
+ g_variant_builder_init (&priv->ip4config, G_VARIANT_TYPE_VARDICT);
priv->failure = -1;
}
static void
-nm_iodine_plugin_class_init (NMIODINEPluginClass *iodine_class)
+nm_iodine_plugin_class_init (NMIodinePluginClass *iodine_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (iodine_class);
- NMVPNPluginClass *parent_class = NM_VPN_PLUGIN_CLASS (iodine_class);
+ NMVpnServicePluginClass *parent_class = NM_VPN_SERVICE_PLUGIN_CLASS (iodine_class);
- g_type_class_add_private (object_class, sizeof (NMIODINEPluginPrivate));
+ g_type_class_add_private (object_class, sizeof (NMIodinePluginPrivate));
/* virtual methods */
parent_class->connect = real_connect;
@@ -667,24 +623,34 @@ nm_iodine_plugin_class_init (NMIODINEPluginClass *iodine_class)
parent_class->disconnect = real_disconnect;
}
-NMIODINEPlugin *
+NMIodinePlugin *
nm_iodine_plugin_new (void)
{
- return (NMIODINEPlugin *) g_object_new (NM_TYPE_IODINE_PLUGIN,
- NM_VPN_PLUGIN_DBUS_SERVICE_NAME,
- NM_DBUS_SERVICE_IODINE,
- NULL);
+ NMIodinePlugin *plugin;
+ GError *error = NULL;
+
+ plugin = (NMIodinePlugin *) g_initable_new (NM_TYPE_IODINE_PLUGIN, NULL, &error,
+ NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME,
+ NM_DBUS_SERVICE_IODINE,
+ NULL);
+
+ if (!plugin) {
+ g_warning ("Failed to initialize a plugin instance: %s", error->message);
+ g_error_free (error);
+ }
+
+ return plugin;
}
static void
-quit_mainloop (NMIODINEPlugin *plugin, gpointer user_data)
+quit_mainloop (NMIodinePlugin *plugin, gpointer user_data)
{
g_main_loop_quit ((GMainLoop *) user_data);
}
int main (int argc, char *argv[])
{
- NMIODINEPlugin *plugin;
+ NMIodinePlugin *plugin;
GMainLoop *main_loop;
#if !GLIB_CHECK_VERSION(2,36,0)
@@ -698,8 +664,8 @@ int main (int argc, char *argv[])
main_loop = g_main_loop_new (NULL, FALSE);
g_signal_connect (plugin, "quit",
- G_CALLBACK (quit_mainloop),
- main_loop);
+ G_CALLBACK (quit_mainloop),
+ main_loop);
g_main_loop_run (main_loop);