1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301 USA.
18 * Copyright 2007 - 2008 Novell, Inc.
19 * Copyright 2007 - 2008 Red Hat, Inc.
22 #include "nm-default.h"
24 #include "nm-vpn-plugin-old.h"
30 #include "nm-enum-types.h"
32 #include "nm-connection.h"
33 #include "nm-dbus-helpers.h"
34 #include "nm-core-internal.h"
35 #include "nm-simple-connection.h"
37 #include "nmdbus-vpn-plugin.h"
39 #define NM_VPN_PLUGIN_OLD_QUIT_TIMER 180
41 static void nm_vpn_plugin_old_initable_iface_init (GInitableIface *iface);
43 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMVpnPluginOld, nm_vpn_plugin_old, G_TYPE_OBJECT,
44 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_vpn_plugin_old_initable_iface_init);
48 NMVpnServiceState state;
51 GDBusConnection *connection;
52 NMDBusVpnPlugin *dbus_vpn_plugin_old;
53 char *dbus_service_name;
62 gboolean has_ip4, got_ip4;
63 gboolean has_ip6, got_ip6;
65 /* Config stuff copied from config to ip4config */
66 GVariant *banner, *tundev, *gateway, *mtu;
67 } NMVpnPluginOldPrivate;
69 #define NM_VPN_PLUGIN_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldPrivate))
84 static guint signals[LAST_SIGNAL] = { 0 };
88 PROP_DBUS_SERVICE_NAME,
94 static GSList *active_plugins = NULL;
98 nm_vpn_plugin_old_set_connection (NMVpnPluginOld *plugin,
99 GDBusConnection *connection)
101 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
103 g_clear_object (&priv->connection);
106 priv->connection = g_object_ref (connection);
110 * nm_vpn_plugin_old_get_connection:
112 * Returns: (transfer full):
114 * Deprecated: 1.2: replaced by NMVpnServicePlugin
117 nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin)
119 GDBusConnection *connection;
121 g_return_val_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin), NULL);
123 connection = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin)->connection;
126 g_object_ref (connection);
132 * nm_vpn_plugin_old_get_state:
134 * Deprecated: 1.2: replaced by NMVpnServicePlugin
137 nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin)
139 g_return_val_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin), NM_VPN_SERVICE_STATE_UNKNOWN);
141 return NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin)->state;
145 * nm_vpn_plugin_old_set_state:
147 * Deprecated: 1.2: replaced by NMVpnServicePlugin
150 nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin,
151 NMVpnServiceState state)
153 NMVpnPluginOldPrivate *priv;
155 g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
157 priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
158 if (priv->state != state) {
160 g_signal_emit (plugin, signals[STATE_CHANGED], 0, state);
165 * nm_vpn_plugin_old_set_login_banner:
167 * Deprecated: 1.2: replaced by NMVpnServicePlugin
170 nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin,
173 g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
174 g_return_if_fail (banner != NULL);
176 g_signal_emit (plugin, signals[LOGIN_BANNER], 0, banner);
180 * nm_vpn_plugin_old_failure:
182 * Deprecated: 1.2: replaced by NMVpnServicePlugin
185 nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin,
186 NMVpnPluginFailure reason)
188 g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
190 g_signal_emit (plugin, signals[FAILURE], 0, reason);
194 * nm_vpn_plugin_old_disconnect:
196 * Deprecated: 1.2: replaced by NMVpnServicePlugin
199 nm_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin, GError **err)
201 gboolean ret = FALSE;
202 NMVpnServiceState state;
204 g_return_val_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin), FALSE);
206 state = nm_vpn_plugin_old_get_state (plugin);
208 case NM_VPN_SERVICE_STATE_STOPPING:
211 NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
213 "Could not process the request because the VPN connection is already being stopped.");
215 case NM_VPN_SERVICE_STATE_STOPPED:
218 NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,
220 "Could not process the request because no VPN connection was active.");
222 case NM_VPN_SERVICE_STATE_STARTING:
223 case NM_VPN_SERVICE_STATE_STARTED:
224 nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING);
225 ret = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->disconnect (plugin, err);
226 nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
228 case NM_VPN_SERVICE_STATE_INIT:
233 g_warning ("Unhandled VPN service state %d", state);
234 g_assert_not_reached ();
242 nm_vpn_plugin_old_emit_quit (NMVpnPluginOld *plugin)
244 g_signal_emit (plugin, signals[QUIT], 0);
248 connect_timer_expired (gpointer data)
250 NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data);
253 NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin)->connect_timer = 0;
254 g_message ("Connect timer expired, disconnecting.");
255 nm_vpn_plugin_old_disconnect (plugin, &err);
257 g_warning ("Disconnect failed: %s", err->message);
261 return G_SOURCE_REMOVE;
265 quit_timer_expired (gpointer data)
267 NMVpnPluginOld *self = NM_VPN_PLUGIN_OLD (data);
269 NM_VPN_PLUGIN_OLD_GET_PRIVATE (self)->quit_timer = 0;
270 nm_vpn_plugin_old_emit_quit (self);
271 return G_SOURCE_REMOVE;
275 schedule_quit_timer (NMVpnPluginOld *self)
277 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (self);
279 nm_clear_g_source (&priv->quit_timer);
280 priv->quit_timer = g_timeout_add_seconds (NM_VPN_PLUGIN_OLD_QUIT_TIMER,
286 fail_stop (gpointer data)
288 NMVpnPluginOld *self = NM_VPN_PLUGIN_OLD (data);
290 NM_VPN_PLUGIN_OLD_GET_PRIVATE (self)->fail_stop_id = 0;
291 nm_vpn_plugin_old_set_state (self, NM_VPN_SERVICE_STATE_STOPPED);
292 return G_SOURCE_REMOVE;
296 schedule_fail_stop (NMVpnPluginOld *plugin, guint timeout_secs)
298 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
300 nm_clear_g_source (&priv->fail_stop_id);
302 priv->fail_stop_id = g_timeout_add_seconds (timeout_secs, fail_stop, plugin);
304 priv->fail_stop_id = g_idle_add (fail_stop, plugin);
308 * nm_vpn_plugin_old_set_config:
310 * Deprecated: 1.2: replaced by NMVpnServicePlugin
313 nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin,
316 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
318 g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
319 g_return_if_fail (config != NULL);
321 priv->got_config = TRUE;
323 (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &priv->has_ip4);
324 (void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &priv->has_ip6);
326 g_warn_if_fail (priv->has_ip4 || priv->has_ip6);
328 /* Record the items that need to also be inserted into the
329 * ip4config, for compatibility with older daemons.
332 g_variant_unref (priv->banner);
333 priv->banner = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_BANNER,
334 G_VARIANT_TYPE ("s"));
336 g_variant_unref (priv->tundev);
337 priv->tundev = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_TUNDEV,
338 G_VARIANT_TYPE ("s"));
340 g_variant_unref (priv->gateway);
341 priv->gateway = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY,
342 G_VARIANT_TYPE ("u"));
344 g_variant_unref (priv->mtu);
345 priv->mtu = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_MTU,
346 G_VARIANT_TYPE ("u"));
348 g_signal_emit (plugin, signals[CONFIG], 0, config);
352 * nm_vpn_plugin_old_set_ip4_config:
354 * Deprecated: 1.2: replaced by NMVpnServicePlugin
357 nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin,
358 GVariant *ip4_config)
360 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
361 GVariant *combined_config;
362 GVariantBuilder builder;
367 g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
368 g_return_if_fail (ip4_config != NULL);
370 priv->got_ip4 = TRUE;
372 /* Old plugins won't send the "config" signal and thus can't send
373 * NM_VPN_PLUGIN_OLD_CONFIG_HAS_IP4 either. But since they don't support IPv6,
374 * we can safely assume that, if we don't receive a "config" signal but do
375 * receive an "ip4-config" signal, the old plugin supports IPv4.
377 if (!priv->got_config)
378 priv->has_ip4 = TRUE;
380 /* Older NetworkManager daemons expect all config info to be in
381 * the ip4 config, so they won't even notice the "config" signal
382 * being emitted. So just copy all of that data into the ip4
385 g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
386 g_variant_iter_init (&iter, ip4_config);
387 while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) {
388 g_variant_builder_add (&builder, "{sv}", key, value);
389 g_variant_unref (value);
393 g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner);
395 g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev);
397 g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway);
399 g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu);
401 combined_config = g_variant_builder_end (&builder);
402 g_variant_ref_sink (combined_config);
403 g_signal_emit (plugin, signals[IP4_CONFIG], 0, combined_config);
404 g_variant_unref (combined_config);
406 if ( priv->has_ip4 == priv->got_ip4
407 && priv->has_ip6 == priv->got_ip6)
408 nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
412 * nm_vpn_plugin_old_set_ip6_config:
414 * Deprecated: 1.2: replaced by NMVpnServicePlugin
417 nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin,
418 GVariant *ip6_config)
420 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
422 g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
423 g_return_if_fail (ip6_config != NULL);
425 g_variant_ref_sink (ip6_config);
427 priv->got_ip6 = TRUE;
428 g_signal_emit (plugin, signals[IP6_CONFIG], 0, ip6_config);
430 g_variant_unref (ip6_config);
432 if ( priv->has_ip4 == priv->got_ip4
433 && priv->has_ip6 == priv->got_ip6)
434 nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
438 connect_timer_start (NMVpnPluginOld *plugin)
440 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
442 priv->connect_timer = g_timeout_add_seconds (60, connect_timer_expired, plugin);
446 _connect_generic (NMVpnPluginOld *plugin,
447 GDBusMethodInvocation *context,
448 GVariant *properties,
451 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
452 NMVpnPluginOldClass *vpn_class = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin);
453 NMConnection *connection;
454 gboolean success = FALSE;
455 GError *error = NULL;
456 guint fail_stop_timeout = 0;
458 if (priv->state != NM_VPN_SERVICE_STATE_STOPPED &&
459 priv->state != NM_VPN_SERVICE_STATE_INIT) {
460 g_dbus_method_invocation_return_error (context,
462 NM_VPN_PLUGIN_ERROR_WRONG_STATE,
463 "Could not start connection: wrong plugin state %d",
468 connection = nm_simple_connection_new_from_dbus (properties, &error);
470 g_dbus_method_invocation_return_error (context,
472 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
473 "Invalid connection: %s",
475 g_clear_error (&error);
478 priv->interactive = FALSE;
479 if (details && !vpn_class->connect_interactive) {
480 g_dbus_method_invocation_return_error (context,
482 NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED,
483 "Plugin does not implement ConnectInteractive()");
487 nm_clear_g_source (&priv->fail_stop_id);
490 priv->interactive = TRUE;
491 success = vpn_class->connect_interactive (plugin, connection, details, &error);
492 if (g_error_matches (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED)) {
493 /* Give NetworkManager a bit of time to fall back to Connect() */
494 fail_stop_timeout = 5;
497 success = vpn_class->connect (plugin, connection, &error);
500 nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);
502 g_dbus_method_invocation_return_value (context, NULL);
504 /* Add a timer to make sure we do not wait indefinitely for the successful connect. */
505 connect_timer_start (plugin);
507 g_dbus_method_invocation_take_error (context, error);
509 /* Stop the plugin from an idle handler so that the Connect
510 * method return gets sent before the STOP StateChanged signal.
512 schedule_fail_stop (plugin, fail_stop_timeout);
515 g_object_unref (connection);
519 impl_vpn_plugin_old_connect (NMVpnPluginOld *plugin,
520 GDBusMethodInvocation *context,
521 GVariant *connection,
524 _connect_generic (plugin, context, connection, NULL);
528 impl_vpn_plugin_old_connect_interactive (NMVpnPluginOld *plugin,
529 GDBusMethodInvocation *context,
530 GVariant *connection,
534 _connect_generic (plugin, context, connection, details);
537 /***************************************************************/
540 impl_vpn_plugin_old_need_secrets (NMVpnPluginOld *plugin,
541 GDBusMethodInvocation *context,
542 GVariant *properties,
545 NMConnection *connection;
546 const char *setting_name;
548 GError *error = NULL;
550 connection = nm_simple_connection_new_from_dbus (properties, &error);
552 g_dbus_method_invocation_return_error (context,
554 NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
555 "The connection was invalid: %s",
557 g_error_free (error);
561 if (!NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->need_secrets) {
562 g_dbus_method_invocation_return_value (context,
563 g_variant_new ("(s)", ""));
567 needed = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->need_secrets (plugin, connection, &setting_name, &error);
569 g_dbus_method_invocation_take_error (context, error);
574 /* Push back the quit timer so the VPN plugin doesn't quit in the
575 * middle of asking the user for secrets.
577 schedule_quit_timer (plugin);
579 g_assert (setting_name);
580 g_dbus_method_invocation_return_value (context,
581 g_variant_new ("(s)", setting_name));
583 /* No secrets required */
584 g_dbus_method_invocation_return_value (context,
585 g_variant_new ("(s)", ""));
590 impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin,
591 GDBusMethodInvocation *context,
592 GVariant *properties,
595 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
596 NMConnection *connection;
597 GError *error = NULL;
600 if (priv->state != NM_VPN_SERVICE_STATE_STARTING) {
601 g_dbus_method_invocation_return_error (context,
603 NM_VPN_PLUGIN_ERROR_WRONG_STATE,
604 "Could not accept new secrets: wrong plugin state %d",
609 connection = nm_simple_connection_new_from_dbus (properties, &error);
611 g_dbus_method_invocation_return_error (context,
613 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
614 "Invalid connection: %s",
616 g_clear_error (&error);
620 if (!NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->new_secrets) {
621 g_dbus_method_invocation_return_error (context,
623 NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED,
624 "Could not accept new secrets: plugin cannot process interactive secrets");
625 g_object_unref (connection);
629 success = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->new_secrets (plugin, connection, &error);
631 g_dbus_method_invocation_return_value (context, NULL);
633 /* Add a timer to make sure we do not wait indefinitely for the successful connect. */
634 connect_timer_start (plugin);
636 g_dbus_method_invocation_take_error (context, error);
638 /* Stop the plugin from and idle handler so that the NewSecrets
639 * method return gets sent before the STOP StateChanged signal.
641 schedule_fail_stop (plugin, 0);
644 g_object_unref (connection);
648 * nm_vpn_plugin_old_secrets_required:
649 * @plugin: the #NMVpnPluginOld
650 * @message: an information message about why secrets are required, if any
651 * @hints: VPN specific secret names for required new secrets
653 * Called by VPN plugin implementations to signal to NetworkManager that secrets
654 * are required during the connection process. This signal may be used to
655 * request new secrets when the secrets originally provided by NetworkManager
656 * are insufficient, or the VPN process indicates that it needs additional
657 * information to complete the request.
659 * Deprecated: 1.2: replaced by NMVpnServicePlugin
662 nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin,
666 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
668 /* Plugin must be able to accept the new secrets if it calls this method */
669 g_return_if_fail (NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->new_secrets);
671 /* Plugin cannot call this method if NetworkManager didn't originally call
672 * ConnectInteractive().
674 g_return_if_fail (priv->interactive == TRUE);
676 /* Cancel the connect timer since secrets might take a while. It'll
677 * get restarted when the secrets come back via NewSecrets().
679 nm_clear_g_source (&priv->connect_timer);
681 g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints);
684 /***************************************************************/
686 #define DATA_KEY_TAG "DATA_KEY="
687 #define DATA_VAL_TAG "DATA_VAL="
688 #define SECRET_KEY_TAG "SECRET_KEY="
689 #define SECRET_VAL_TAG "SECRET_VAL="
692 free_secret (gpointer data)
696 memset (secret, 0, strlen (secret));
701 * nm_vpn_plugin_old_read_vpn_details:
702 * @fd: file descriptor to read from, usually stdin (0)
703 * @out_data: (out) (transfer full): on successful return, a hash table
704 * (mapping char*:char*) containing the key/value pairs of VPN data items
705 * @out_secrets: (out) (transfer full): on successful return, a hash table
706 * (mapping char*:char*) containing the key/value pairsof VPN secrets
708 * Parses key/value pairs from a file descriptor (normally stdin) passed by
709 * an applet when the applet calls the authentication dialog of the VPN plugin.
711 * Returns: %TRUE if reading values was successful, %FALSE if not
713 * Deprecated: 1.2: replaced by NMVpnServicePlugin
716 nm_vpn_plugin_old_read_vpn_details (int fd,
717 GHashTable **out_data,
718 GHashTable **out_secrets)
720 GHashTable *data, *secrets;
721 gboolean success = FALSE;
722 char *key = NULL, *val = NULL;
727 g_return_val_if_fail (*out_data == NULL, FALSE);
729 g_return_val_if_fail (*out_secrets == NULL, FALSE);
731 data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
732 secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_secret);
734 line = g_string_new (NULL);
736 /* Read stdin for data and secret items until we get a DONE */
739 GHashTable *hash = NULL;
742 nr = read (fd, &c, 1);
744 if (errno == EAGAIN) {
752 g_string_append_c (line, c);
756 /* Check for the finish marker */
757 if (strcmp (line->str, "DONE") == 0)
760 /* Otherwise it's a data/secret item */
761 if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) {
763 key = g_strdup (line->str + strlen (DATA_KEY_TAG));
764 } else if (strncmp (line->str, DATA_VAL_TAG, strlen (DATA_VAL_TAG)) == 0) {
766 val = g_strdup (line->str + strlen (DATA_VAL_TAG));
767 } else if (strncmp (line->str, SECRET_KEY_TAG, strlen (SECRET_KEY_TAG)) == 0) {
769 key = g_strdup (line->str + strlen (SECRET_KEY_TAG));
770 } else if (strncmp (line->str, SECRET_VAL_TAG, strlen (SECRET_VAL_TAG)) == 0) {
772 val = g_strdup (line->str + strlen (SECRET_VAL_TAG));
774 g_string_truncate (line, 0);
776 if (key && val && hash) {
777 g_hash_table_insert (hash, key, val);
780 success = TRUE; /* Got at least one value */
788 g_hash_table_destroy (data);
791 *out_secrets = secrets;
793 g_hash_table_destroy (secrets);
795 g_hash_table_destroy (data);
796 g_hash_table_destroy (secrets);
799 g_string_free (line, TRUE);
804 * nm_vpn_plugin_old_get_secret_flags:
805 * @data: hash table containing VPN key/value pair data items
806 * @secret_name: VPN secret key name for which to retrieve flags for
807 * @out_flags: (out): on success, the flags associated with @secret_name
809 * Given a VPN secret key name, attempts to find the corresponding flags data
810 * item in @data. If found, converts the flags data item to
811 * #NMSettingSecretFlags and returns it.
813 * Returns: %TRUE if the flag data item was found and successfully converted
814 * to flags, %FALSE if not
816 * Deprecated: 1.2: replaced by NMVpnServicePlugin
819 nm_vpn_plugin_old_get_secret_flags (GHashTable *data,
820 const char *secret_name,
821 NMSettingSecretFlags *out_flags)
826 gboolean success = FALSE;
828 g_return_val_if_fail (data != NULL, FALSE);
829 g_return_val_if_fail (secret_name != NULL, FALSE);
830 g_return_val_if_fail (out_flags != NULL, FALSE);
831 g_return_val_if_fail (*out_flags == NM_SETTING_SECRET_FLAG_NONE, FALSE);
833 flag_name = g_strdup_printf ("%s-flags", secret_name);
835 /* Try new flags value first */
836 val = g_hash_table_lookup (data, flag_name);
839 tmp = strtoul (val, NULL, 10);
840 if (errno == 0 && tmp <= NM_SETTING_SECRET_FLAGS_ALL) {
841 *out_flags = (NMSettingSecretFlags) tmp;
850 /***************************************************************/
853 impl_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin,
854 GDBusMethodInvocation *context,
857 GError *error = NULL;
859 if (nm_vpn_plugin_old_disconnect (plugin, &error))
860 g_dbus_method_invocation_return_value (context, NULL);
862 g_dbus_method_invocation_take_error (context, error);
866 impl_vpn_plugin_old_set_config (NMVpnPluginOld *plugin,
867 GDBusMethodInvocation *context,
871 nm_vpn_plugin_old_set_config (plugin, config);
872 g_dbus_method_invocation_return_value (context, NULL);
876 impl_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin,
877 GDBusMethodInvocation *context,
881 nm_vpn_plugin_old_set_ip4_config (plugin, config);
882 g_dbus_method_invocation_return_value (context, NULL);
886 impl_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin,
887 GDBusMethodInvocation *context,
891 nm_vpn_plugin_old_set_ip6_config (plugin, config);
892 g_dbus_method_invocation_return_value (context, NULL);
896 impl_vpn_plugin_old_set_failure (NMVpnPluginOld *plugin,
897 GDBusMethodInvocation *context,
901 nm_vpn_plugin_old_failure (plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG);
902 g_dbus_method_invocation_return_value (context, NULL);
905 /*********************************************************************/
908 sigterm_handler (int signum)
910 g_slist_foreach (active_plugins, (GFunc) nm_vpn_plugin_old_emit_quit, NULL);
914 setup_unix_signal_handler (void)
916 struct sigaction action;
919 action.sa_handler = sigterm_handler;
920 sigemptyset (&block_mask);
921 action.sa_mask = block_mask;
923 sigaction (SIGINT, &action, NULL);
924 sigaction (SIGTERM, &action, NULL);
927 /*********************************************************************/
930 one_plugin_destroyed (gpointer data,
933 active_plugins = g_slist_remove (active_plugins, object);
937 nm_vpn_plugin_old_init (NMVpnPluginOld *plugin)
939 active_plugins = g_slist_append (active_plugins, plugin);
940 g_object_weak_ref (G_OBJECT (plugin),
941 one_plugin_destroyed,
946 init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
948 NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (initable);
949 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
950 GDBusConnection *connection = NULL;
953 gboolean success = FALSE;
955 if (!priv->dbus_service_name) {
956 g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
957 _("No service name specified"));
961 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
965 proxy = g_dbus_proxy_new_sync (connection,
966 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
967 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
976 ret = g_dbus_proxy_call_sync (proxy,
978 g_variant_new ("(su)", priv->dbus_service_name, 0),
979 G_DBUS_CALL_FLAGS_NONE, -1,
981 g_object_unref (proxy);
984 g_dbus_error_strip_remote_error (*error);
987 g_variant_unref (ret);
989 priv->dbus_vpn_plugin_old = nmdbus_vpn_plugin_skeleton_new ();
990 if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_vpn_plugin_old),
992 NM_VPN_DBUS_PLUGIN_PATH,
996 _nm_dbus_bind_properties (plugin, priv->dbus_vpn_plugin_old);
997 _nm_dbus_bind_methods (plugin, priv->dbus_vpn_plugin_old,
998 "Connect", impl_vpn_plugin_old_connect,
999 "ConnectInteractive", impl_vpn_plugin_old_connect_interactive,
1000 "NeedSecrets", impl_vpn_plugin_old_need_secrets,
1001 "NewSecrets", impl_vpn_plugin_old_new_secrets,
1002 "Disconnect", impl_vpn_plugin_old_disconnect,
1003 "SetConfig", impl_vpn_plugin_old_set_config,
1004 "SetIp4Config", impl_vpn_plugin_old_set_ip4_config,
1005 "SetIp6Config", impl_vpn_plugin_old_set_ip6_config,
1006 "SetFailure", impl_vpn_plugin_old_set_failure,
1009 nm_vpn_plugin_old_set_connection (plugin, connection);
1010 nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_INIT);
1015 g_clear_object (&connection);
1021 set_property (GObject *object, guint prop_id,
1022 const GValue *value, GParamSpec *pspec)
1024 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (object);
1027 case PROP_DBUS_SERVICE_NAME:
1028 /* Construct-only */
1029 priv->dbus_service_name = g_value_dup_string (value);
1032 nm_vpn_plugin_old_set_state (NM_VPN_PLUGIN_OLD (object),
1033 (NMVpnServiceState) g_value_get_enum (value));
1036 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1042 get_property (GObject *object, guint prop_id,
1043 GValue *value, GParamSpec *pspec)
1045 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (object);
1048 case PROP_DBUS_SERVICE_NAME:
1049 g_value_set_string (value, priv->dbus_service_name);
1052 g_value_set_enum (value, nm_vpn_plugin_old_get_state (NM_VPN_PLUGIN_OLD (object)));
1055 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1061 dispose (GObject *object)
1063 NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (object);
1064 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
1065 NMVpnServiceState state;
1068 nm_clear_g_source (&priv->fail_stop_id);
1069 nm_clear_g_source (&priv->quit_timer);
1070 nm_clear_g_source (&priv->connect_timer);
1072 state = nm_vpn_plugin_old_get_state (plugin);
1074 if (state == NM_VPN_SERVICE_STATE_STARTED ||
1075 state == NM_VPN_SERVICE_STATE_STARTING)
1076 nm_vpn_plugin_old_disconnect (plugin, &err);
1079 g_warning ("Error disconnecting VPN connection: %s", err->message);
1083 G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->dispose (object);
1087 finalize (GObject *object)
1089 NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (object);
1090 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
1092 nm_vpn_plugin_old_set_connection (plugin, NULL);
1093 g_free (priv->dbus_service_name);
1095 g_clear_pointer (&priv->banner, g_variant_unref);
1096 g_clear_pointer (&priv->tundev, g_variant_unref);
1097 g_clear_pointer (&priv->gateway, g_variant_unref);
1098 g_clear_pointer (&priv->mtu, g_variant_unref);
1100 G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->finalize (object);
1104 state_changed (NMVpnPluginOld *plugin, NMVpnServiceState state)
1106 NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin);
1109 case NM_VPN_SERVICE_STATE_STARTING:
1110 nm_clear_g_source (&priv->quit_timer);
1111 nm_clear_g_source (&priv->fail_stop_id);
1113 case NM_VPN_SERVICE_STATE_STOPPED:
1114 schedule_quit_timer (plugin);
1117 /* Clean up all timers we might have set up. */
1118 nm_clear_g_source (&priv->connect_timer);
1119 nm_clear_g_source (&priv->quit_timer);
1120 nm_clear_g_source (&priv->fail_stop_id);
1126 nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class)
1128 GObjectClass *object_class = G_OBJECT_CLASS (plugin_class);
1130 g_type_class_add_private (object_class, sizeof (NMVpnPluginOldPrivate));
1132 /* virtual methods */
1133 object_class->set_property = set_property;
1134 object_class->get_property = get_property;
1135 object_class->dispose = dispose;
1136 object_class->finalize = finalize;
1138 plugin_class->state_changed = state_changed;
1143 * NMVpnPluginOld:service-name:
1145 * The D-Bus service name of this plugin.
1147 * Deprecated: 1.2: replaced by NMVpnServicePlugin
1149 g_object_class_install_property
1150 (object_class, PROP_DBUS_SERVICE_NAME,
1151 g_param_spec_string (NM_VPN_PLUGIN_OLD_DBUS_SERVICE_NAME, "", "",
1154 G_PARAM_CONSTRUCT_ONLY |
1155 G_PARAM_STATIC_STRINGS));
1158 * NMVpnPluginOld:state:
1160 * The state of the plugin.
1162 * Deprecated: 1.2: replaced by NMVpnServicePlugin
1164 g_object_class_install_property
1165 (object_class, PROP_STATE,
1166 g_param_spec_enum (NM_VPN_PLUGIN_OLD_STATE, "", "",
1167 NM_TYPE_VPN_SERVICE_STATE,
1168 NM_VPN_SERVICE_STATE_INIT,
1170 G_PARAM_STATIC_STRINGS));
1173 signals[STATE_CHANGED] =
1174 g_signal_new ("state-changed",
1175 G_OBJECT_CLASS_TYPE (object_class),
1177 G_STRUCT_OFFSET (NMVpnPluginOldClass, state_changed),
1183 signals[SECRETS_REQUIRED] =
1184 g_signal_new ("secrets-required",
1185 G_OBJECT_CLASS_TYPE (object_class),
1189 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRV);
1192 g_signal_new ("config",
1193 G_OBJECT_CLASS_TYPE (object_class),
1195 G_STRUCT_OFFSET (NMVpnPluginOldClass, config),
1201 signals[IP4_CONFIG] =
1202 g_signal_new ("ip4-config",
1203 G_OBJECT_CLASS_TYPE (object_class),
1205 G_STRUCT_OFFSET (NMVpnPluginOldClass, ip4_config),
1211 signals[IP6_CONFIG] =
1212 g_signal_new ("ip6-config",
1213 G_OBJECT_CLASS_TYPE (object_class),
1215 G_STRUCT_OFFSET (NMVpnPluginOldClass, ip6_config),
1221 signals[LOGIN_BANNER] =
1222 g_signal_new ("login-banner",
1223 G_OBJECT_CLASS_TYPE (object_class),
1225 G_STRUCT_OFFSET (NMVpnPluginOldClass, login_banner),
1232 g_signal_new ("failure",
1233 G_OBJECT_CLASS_TYPE (object_class),
1235 G_STRUCT_OFFSET (NMVpnPluginOldClass, failure),
1242 g_signal_new ("quit",
1243 G_OBJECT_CLASS_TYPE (object_class),
1245 G_STRUCT_OFFSET (NMVpnPluginOldClass, quit),
1251 setup_unix_signal_handler ();
1255 nm_vpn_plugin_old_initable_iface_init (GInitableIface *iface)
1257 iface->init = init_sync;