diff options
Diffstat (limited to 'src/nm-iodine-service.c')
-rw-r--r-- | src/nm-iodine-service.c | 302 |
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); |