static gboolean impl_vpn_plugin_need_secrets (NMVPNPlugin *plugin, GHashTable *properties, char **setting_name, GError **err) { gboolean ret = FALSE; NMConnection *connection; char *sn = NULL; GError *ns_err = NULL; gboolean needed = FALSE; GError *cnfh_err = NULL; g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE); g_return_val_if_fail (properties != NULL, FALSE); connection = nm_connection_new_from_hash (properties, &cnfh_err); if (!connection) { g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID, "The connection was invalid: '%s' / '%s' invalid: %d.", g_type_name (nm_connection_lookup_setting_type_by_quark (cnfh_err->domain)), cnfh_err->message, cnfh_err->code); g_error_free (cnfh_err); return FALSE; } if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets) { *setting_name = ""; ret = TRUE; goto out; } needed = NM_VPN_PLUGIN_GET_CLASS (plugin)->need_secrets (plugin, connection, &sn, &ns_err); if (ns_err) { *err = g_error_copy (ns_err); g_error_free (ns_err); goto out; } ret = TRUE; if (needed) { /* Push back the quit timer so the VPN plugin doesn't quit in the * middle of asking the user for secrets. */ schedule_quit_timer (plugin); g_assert (sn); *setting_name = g_strdup (sn); } else { /* No secrets required */ *setting_name = g_strdup (""); } out: return ret; }
static gboolean impl_vpn_plugin_new_secrets (NMVPNPlugin *plugin, GHashTable *properties, GError **error) { NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); NMConnection *connection; GError *local = NULL; gboolean success; if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE, "Could not accept new secrets: wrong plugin state %d", priv->state); return FALSE; } connection = nm_connection_new_from_hash (properties, &local); if (!connection) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, "Invalid connection: (%d) %s", local->code, local->message); g_clear_error (&local); return FALSE; } if (!NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets) { g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, "Could not accept new secrets: plugin cannot process interactive secrets"); g_object_unref (connection); return FALSE; } success = NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets (plugin, connection, error); if (success) { /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ connect_timer_start (plugin); } else { /* Stop the plugin from and idle handler so that the NewSecrets * method return gets sent before the STOP StateChanged signal. */ schedule_fail_stop (plugin); } g_object_unref (connection); return success; }
static gboolean _connect_generic (NMVPNPlugin *plugin, GHashTable *properties, GHashTable *details, GError **error) { NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); NMVPNPluginClass *vpn_class = NM_VPN_PLUGIN_GET_CLASS (plugin); NMConnection *connection; gboolean success = FALSE; GError *local = NULL; if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && priv->state != NM_VPN_SERVICE_STATE_INIT) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_WRONG_STATE, "Could not start connection: wrong plugin state %d", priv->state); return FALSE; } connection = nm_connection_new_from_hash (properties, &local); if (!connection) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, "Invalid connection: (%d) %s", local->code, local->message); g_clear_error (&local); return FALSE; } priv->interactive = FALSE; if (details && !vpn_class->connect_interactive) { g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, "Plugin does not implement ConnectInteractive()"); return FALSE; } nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); if (details) { priv->interactive = TRUE; success = vpn_class->connect_interactive (plugin, connection, details, error); } else success = vpn_class->connect (plugin, connection, error); if (success) { /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ connect_timer_start (plugin); } else { /* Stop the plugin from an idle handler so that the Connect * method return gets sent before the STOP StateChanged signal. */ schedule_fail_stop (plugin); } g_object_unref (connection); return success; }
static gboolean nm_vpn_plugin_connect (NMVPNPlugin *plugin, NMConnection *connection, GError **err) { NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); gboolean ret = FALSE; NMVPNServiceState state; g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE); state = nm_vpn_plugin_get_state (plugin); switch (state) { case NM_VPN_SERVICE_STATE_STARTING: g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, "%s", "Could not process the request because the VPN connection is already being started."); break; case NM_VPN_SERVICE_STATE_STARTED: g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, "%s", "Could not process the request because a VPN connection was already active."); break; case NM_VPN_SERVICE_STATE_STOPPING: g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, "%s", "Could not process the request because the VPN connection is being stopped."); break; case NM_VPN_SERVICE_STATE_STOPPED: case NM_VPN_SERVICE_STATE_INIT: nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->connect (plugin, connection, err); if (!ret) { /* Stop the plugin from and idle handler so that the Connect * method return gets sent before the STOP StateChanged signal. */ if (priv->fail_stop_id) g_source_remove (priv->fail_stop_id); priv->fail_stop_id = g_idle_add (fail_stop, plugin); } break; default: g_assert_not_reached (); break; } return ret; }
gboolean nm_vpn_plugin_disconnect (NMVPNPlugin *plugin, GError **err) { gboolean ret = FALSE; NMVPNServiceState state; g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE); state = nm_vpn_plugin_get_state (plugin); switch (state) { case NM_VPN_SERVICE_STATE_STOPPING: g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, "%s", "Could not process the request because the VPN connection is already being stopped."); break; case NM_VPN_SERVICE_STATE_STOPPED: g_set_error (err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, "%s", "Could not process the request because no VPN connection was active."); break; case NM_VPN_SERVICE_STATE_STARTING: case NM_VPN_SERVICE_STATE_STARTED: nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING); ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->disconnect (plugin, err); nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED); break; case NM_VPN_SERVICE_STATE_INIT: ret = TRUE; break; default: g_warning ("Unhandled VPN service state %d", state); g_assert_not_reached (); break; } return ret; }
/** * nm_vpn_plugin_secrets_required: * @plugin: the #NMVPNPlugin * @message: an information message about why secrets are required, if any * @hints: VPN specific secret names for required new secrets * * Called by VPN plugin implementations to signal to NetworkManager that secrets * are required during the connection process. This signal may be used to * request new secrets when the secrets originally provided by NetworkManager * are insufficient, or the VPN process indicates that it needs additional * information to complete the request. * * Since: 0.9.10 */ void nm_vpn_plugin_secrets_required (NMVPNPlugin *plugin, const char *message, const char **hints) { NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin); /* Plugin must be able to accept the new secrets if it calls this method */ g_return_if_fail (NM_VPN_PLUGIN_GET_CLASS (plugin)->new_secrets); /* Plugin cannot call this method if NetworkManager didn't originally call * ConnectInteractive(). */ g_return_if_fail (priv->interactive == TRUE); /* Cancel the connect timer since secrets might take a while. It'll * get restarted when the secrets come back via NewSecrets(). */ nm_clear_g_source (&priv->connect_timer); g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints); }